Correctly read PC on halt.
[riscv-isa-sim.git] / riscv / debug_module.cc
1 #include <cassert>
2
3 #include "debug_module.h"
4 #include "mmu.h"
5
6 #include "debug_rom/debug_rom.h"
7
8 debug_module_t::debug_module_t()
9 {
10 /* Copy Debug ROM into the page. */
11 memcpy(raw_page + DEBUG_ROM_START - DEBUG_START,
12 debug_rom_raw, debug_rom_raw_len);
13 }
14
15 bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes)
16 {
17 addr = DEBUG_START + addr;
18
19 if (addr >= DEBUG_RAM_START && addr + len <= DEBUG_RAM_END) {
20 memcpy(bytes, raw_page + addr - DEBUG_START, len);
21 return true;
22 }
23
24 fprintf(stderr, "ERROR: invalid load from debug module: %ld bytes at 0x%lx\n",
25 len, addr);
26 return false;
27 }
28
29 bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes)
30 {
31 addr = DEBUG_START + addr;
32
33 if (addr & (len-1)) {
34 fprintf(stderr, "ERROR: unaligned store to debug module: %ld bytes at 0x%lx\n",
35 len, addr);
36 return false;
37 }
38
39 if (addr >= DEBUG_RAM_START && addr + len <= DEBUG_RAM_END) {
40 memcpy(raw_page + addr - DEBUG_START, bytes, len);
41 return true;
42 } else if (len == 4 && addr == DEBUG_CLEARDEBINT) {
43 clear_interrupt(bytes[0] | (bytes[1] << 8) |
44 (bytes[2] << 16) | (bytes[3] << 24));
45 return true;
46 }
47
48 fprintf(stderr, "ERROR: invalid store to debug module: %ld bytes at 0x%lx\n",
49 len, addr);
50 return false;
51 }
52
53 void debug_module_t::ram_write32(unsigned int index, uint32_t value)
54 {
55 char* base = raw_page + DEBUG_RAM_START - DEBUG_START + index * 4;
56 base[0] = value & 0xff;
57 base[1] = (value >> 8) & 0xff;
58 base[2] = (value >> 16) & 0xff;
59 base[3] = (value >> 24) & 0xff;
60 }
61
62 uint32_t debug_module_t::ram_read32(unsigned int index)
63 {
64 // It'd be better for raw_page (and all memory) to be unsigned chars, but mem
65 // in sim_t is just chars, so I'm following that convention.
66 unsigned char* base = (unsigned char*)
67 (raw_page + DEBUG_RAM_START - DEBUG_START + index * 4);
68 uint32_t value = ((uint32_t) base[0]) |
69 (((uint32_t) base[1]) << 8) |
70 (((uint32_t) base[2]) << 16) |
71 (((uint32_t) base[3]) << 24);
72 return value;
73 }
74
75 char* debug_module_t::page(reg_t paddr)
76 {
77 fprintf(stderr, "dm::page(0x%lx)\n", paddr);
78
79 assert(PGSHIFT == 12);
80
81 if (paddr == (DEBUG_START & PGMASK)) {
82 return raw_page;
83 }
84
85 fprintf(stderr, "ERROR: invalid page to debug module at 0x%lx\n", paddr);
86 return NULL;
87 }