Correctly read PC on halt.
authorTim Newsome <tim@sifive.com>
Tue, 26 Apr 2016 17:22:02 +0000 (10:22 -0700)
committerTim Newsome <tim@sifive.com>
Mon, 23 May 2016 19:12:11 +0000 (12:12 -0700)
riscv/debug_module.cc
riscv/gdbserver.cc

index 75bb3357ea793f2bd587cb0f34900ed0ddf66fd5..2cda77214045fec38c83ae810b0bf26a0495ba00 100644 (file)
@@ -16,6 +16,11 @@ bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes)
 {
   addr = DEBUG_START + addr;
 
+  if (addr >= DEBUG_RAM_START && addr + len <= DEBUG_RAM_END) {
+    memcpy(bytes, raw_page + addr - DEBUG_START, len);
+    return true;
+  }
+
   fprintf(stderr, "ERROR: invalid load from debug module: %ld bytes at 0x%lx\n",
       len, addr);
   return false;
@@ -56,11 +61,15 @@ void debug_module_t::ram_write32(unsigned int index, uint32_t value)
 
 uint32_t debug_module_t::ram_read32(unsigned int index)
 {
-  char* base = raw_page + DEBUG_RAM_START - DEBUG_START + index * 4;
-  return base[0] |
-    (base[1] << 8) |
-    (base[2] << 16) |
-    (base[3] << 24);
+  // It'd be better for raw_page (and all memory) to be unsigned chars, but mem
+  // in sim_t is just chars, so I'm following that convention.
+  unsigned char* base = (unsigned char*)
+    (raw_page + DEBUG_RAM_START - DEBUG_START + index * 4);
+  uint32_t value = ((uint32_t) base[0]) |
+    (((uint32_t) base[1]) << 8) |
+    (((uint32_t) base[2]) << 16) |
+    (((uint32_t) base[3]) << 24);
+  return value;
 }
 
 char* debug_module_t::page(reg_t paddr)
index 738556c2bf7044096aa8308f58f52c083c95839a..a460b67daab55df049059eb2432065c17bb1623b 100644 (file)
 // Functions to generate RISC-V opcodes.
 // TODO: Does this already exist somewhere?
 
-#define S1      3
+// Using regnames.cc as source. The RVG Calling Convention of the 2.0 RISC-V
+// spec says it should be 2 and 3.
+#define S0      8
+#define S1      9
 static uint32_t bits(uint32_t value, unsigned int hi, unsigned int lo) {
   return (value >> lo) & ((1 << (hi+1-lo)) - 1);
 }
@@ -48,7 +51,7 @@ static uint32_t csrsi(unsigned int csr, uint8_t imm) {
 }
 
 static uint32_t csrr(unsigned int rd, unsigned int csr) {
-  return (csr << 20) | (rd << 15) | MATCH_CSRRS;
+  return (csr << 20) | (rd << 7) | MATCH_CSRRS;
 }
 
 static uint32_t sw(unsigned int src, unsigned int base, uint16_t offset)
@@ -176,10 +179,10 @@ void gdbserver_t::halt()
 {
   processor_t *p = sim->get_core(0);
   write_debug_ram(0, csrsi(DCSR_ADDRESS, DCSR_HALT_OFFSET));
-  write_debug_ram(1, csrr(S1, DPC_ADDRESS));
-  write_debug_ram(2, sw(S1, 0, (uint16_t) DEBUG_RAM_START));
-  write_debug_ram(3, csrr(S1, DCSR_ADDRESS));
-  write_debug_ram(4, sw(S1, 0, (uint16_t) DEBUG_RAM_START + 8));
+  write_debug_ram(1, csrr(S0, DPC_ADDRESS));
+  write_debug_ram(2, sw(S0, 0, (uint16_t) DEBUG_RAM_START));
+  write_debug_ram(3, csrr(S0, DCSR_ADDRESS));
+  write_debug_ram(4, sw(S0, 0, (uint16_t) DEBUG_RAM_START + 8));
   write_debug_ram(5, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*5))));
   sim->debug_module.set_interrupt(p->id);
   state = STATE_HALTING;