pseudo inst,util: Add optional key to initparam pseudo instruction
authorGabor Dozsa <gabor.dozsa@arm.com>
Thu, 7 Jan 2016 22:33:47 +0000 (16:33 -0600)
committerGabor Dozsa <gabor.dozsa@arm.com>
Thu, 7 Jan 2016 22:33:47 +0000 (16:33 -0600)
The key parameter can be used to read out various config parameters from
within the simulated software.

src/arch/alpha/isa/decoder.isa
src/arch/arm/isa/insts/m5ops.isa
src/arch/x86/isa/decoder/two_byte_opcodes.isa
src/sim/pseudo_inst.cc
src/sim/pseudo_inst.hh
util/m5/m5.c
util/m5/m5op.h

index e61bb43ff6a12d30d48854051d13687771a6fd73..a114afaea72e96f5917b5e7e07050a87793c21ad 100644 (file)
@@ -982,7 +982,7 @@ decode OPCODE default Unknown::unknown() {
                 PseudoInst::loadsymbol(xc->tcBase());
             }}, No_OpClass, IsNonSpeculative);
             0x30: initparam({{
-                Ra = PseudoInst::initParam(xc->tcBase());
+                Ra = PseudoInst::initParam(xc->tcBase(), R16, R17);
             }});
             0x40: resetstats({{
                 PseudoInst::resetstats(xc->tcBase(), R16, R17);
index e18d0682c65c4a4a35136676329b23ec4b1997d1..efe88c73a1034b55ff06b342c6b89eeaea7c425b 100644 (file)
@@ -276,13 +276,14 @@ let {{
     exec_output += PredOpExecute.subst(loadsymbolIop)
 
     initparamCode = '''
-    uint64_t ip_val  = PseudoInst::initParam(xc->tcBase());
+    uint64_t ip_val = PseudoInst::initParam(xc->tcBase(), join32to64(R1, R0),
+                                            join32to64(R3, R2));
     R0 = bits(ip_val, 31, 0);
     R1 = bits(ip_val, 63, 32);
     '''
 
     initparamCode64 = '''
-    X0 = PseudoInst::initParam(xc->tcBase());
+    X0 = PseudoInst::initParam(xc->tcBase(), X0, X1);
     '''
 
     initparamIop = InstObjParams("initparam", "Initparam", "PredOp",
index 4a21e2900761210a3e83cbda3ac19f967a3fa321..01e8e9b0ce88b584c213b204411de993e4c09c8d 100644 (file)
                         PseudoInst::m5fail(xc->tcBase(), Rdi, Rsi);
                     }}, IsNonSpeculative);
                     0x30: m5initparam({{
-                        Rax = PseudoInst::initParam(xc->tcBase());
+                        Rax = PseudoInst::initParam(xc->tcBase(), Rdi, Rsi);
                     }}, IsNonSpeculative);
                     0x31: m5loadsymbol({{
                         PseudoInst::loadsymbol(xc->tcBase());
index 260ffec6e05767291c1d1a6a958bca53f581854a..0f7de0c3a74bf1b47f61faed792d946ca492efe5 100644 (file)
@@ -141,7 +141,7 @@ pseudoInst(ThreadContext *tc, uint8_t func, uint8_t subfunc)
         break;
 
       case 0x30: // initparam_func
-        return initParam(tc);
+        return initParam(tc, args[0], args[1]);
 
       case 0x31: // loadsymbol_func
         loadsymbol(tc);
@@ -440,15 +440,43 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
 }
 
 uint64_t
-initParam(ThreadContext *tc)
+initParam(ThreadContext *tc, uint64_t key_str1, uint64_t key_str2)
 {
-    DPRINTF(PseudoInst, "PseudoInst::initParam()\n");
+    DPRINTF(PseudoInst, "PseudoInst::initParam() key:%s%s\n", (char *)&key_str1,
+            (char *)&key_str2);
     if (!FullSystem) {
         panicFsOnlyPseudoInst("initParam");
         return 0;
     }
 
-    return tc->getCpuPtr()->system->init_param;
+    // The key parameter string is passed in via two 64-bit registers. We copy
+    // out the characters from the 64-bit integer variables here and concatenate
+    // them in the key_str character buffer
+    const int len = 2 * sizeof(uint64_t) + 1;
+    char key_str[len];
+    memset(key_str, '\0', len);
+    if (key_str1 == 0) {
+        assert(key_str2 == 0);
+    } else {
+        strncpy(key_str, (char *)&key_str1, sizeof(uint64_t));
+    }
+
+    if (strlen(key_str) == sizeof(uint64_t)) {
+        strncpy(key_str + sizeof(uint64_t), (char *)&key_str2,
+                sizeof(uint64_t));
+    } else {
+        assert(key_str2 == 0);
+    }
+
+    // Compare the key parameter with the known values to select the return
+    // value
+    uint64_t val;
+    if (strlen(key_str) == 0) {
+        val = tc->getCpuPtr()->system->init_param;
+    } else {
+        panic("Unknown key for initparam pseudo instruction");
+    }
+    return val;
 }
 
 
index b6e32847a9e0df59f9e6cd3f277cd434d2e37197..5f0b700c6a97410e205d05c97aff02f9098d10a7 100644 (file)
@@ -75,7 +75,7 @@ uint64_t writefile(ThreadContext *tc, Addr vaddr, uint64_t len,
     uint64_t offset, Addr filenameAddr);
 void loadsymbol(ThreadContext *xc);
 void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr);
-uint64_t initParam(ThreadContext *xc);
+uint64_t initParam(ThreadContext *xc, uint64_t key_str1, uint64_t key_str2);
 uint64_t rpns(ThreadContext *tc);
 void wakeCPU(ThreadContext *tc, uint64_t cpuid);
 void m5exit(ThreadContext *tc, Tick delay);
index 2fd2d15907aea1f6cb377310e52bdf55ab9723cf..522268410ba9e16d1f89200a16a20f1128e047b2 100644 (file)
@@ -83,6 +83,27 @@ parse_int_args(int argc, char *argv[], uint64_t ints[], int len)
 #undef strto64
 }
 
+void
+parse_str_args_to_regs(int argc, char *argv[], uint64_t regs[], int len)
+{
+    if (argc > 1 || strlen(argv[0]) > len * sizeof(uint64_t))
+        usage();
+
+    int i;
+    for (i = 0; i < len; i++)
+        regs[i] = 0;
+
+    if (argc == 0)
+        return;
+
+    int n;
+    for (n = 0, i = 0; i < len && n < strlen(argv[0]); n++) {
+        *((char *)(&regs[i]) + (n % 8)) = argv[0][n];
+        if ((n % 8) == 7)
+            i++;
+    }
+}
+
 int
 read_file(int dest_fid)
 {
@@ -233,10 +254,12 @@ do_load_symbol(int argc, char *argv[])
 void
 do_initparam(int argc, char *argv[])
 {
-    if (argc != 0)
+    if (argc > 1)
         usage();
 
-    uint64_t val = m5_initparam();
+    uint64_t key_str[2];
+    parse_str_args_to_regs(argc, argv, key_str, 2);
+    uint64_t val = m5_initparam(key_str[0], key_str[1]);
     printf("%"PRIu64, val);
 }
 
@@ -246,7 +269,7 @@ do_sw99param(int argc, char *argv[])
     if (argc != 0)
         usage();
 
-    uint64_t param = m5_initparam();
+    uint64_t param = m5_initparam(0, 0);
 
     // run-time, rampup-time, rampdown-time, warmup-time, connections
     printf("%"PRId64" %"PRId64" %"PRId64" %"PRId64" %"PRId64,
@@ -298,7 +321,7 @@ struct MainFunc mainfuncs[] = {
     { "execfile",       do_exec_file,        "" },
     { "checkpoint",     do_checkpoint,       "[delay [period]]" },
     { "loadsymbol",     do_load_symbol,      "<address> <symbol>" },
-    { "initparam",      do_initparam,        "" },
+    { "initparam",      do_initparam,        "[key] // key must be shorter than 16 chars" },
     { "sw99param",      do_sw99param,        "" },
 #ifdef linux
     { "pin",            do_pin,              "<cpu> <program> [args ...]" }
index 9df9a7429f6aca7c5476a20197ee074d28b765f7..34dabce019aa4606a155e72cd8aa9ed1519f9df8 100644 (file)
@@ -48,7 +48,7 @@ void wakeCPU(uint64_t cpuid);
 
 void m5_exit(uint64_t ns_delay);
 void m5_fail(uint64_t ns_delay, uint64_t code);
-uint64_t m5_initparam(void);
+uint64_t m5_initparam(uint64_t key_str1, uint64_t key_str2);
 void m5_checkpoint(uint64_t ns_delay, uint64_t ns_period);
 void m5_reset_stats(uint64_t ns_delay, uint64_t ns_period);
 void m5_dump_stats(uint64_t ns_delay, uint64_t ns_period);