OpenOCD does a dmi read and gets dummy value back.
[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 #if 1
9 # define D(x) x
10 #else
11 # define D(x)
12 #endif
13
14 bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes)
15 {
16 addr = DEBUG_START + addr;
17
18 if (addr >= DEBUG_RAM_START && addr + len <= DEBUG_RAM_END) {
19 memcpy(bytes, debug_ram + addr - DEBUG_RAM_START, len);
20 return true;
21 }
22
23 if (addr >= DEBUG_ROM_START && addr + len <= DEBUG_ROM_END) {
24 memcpy(bytes, debug_rom_raw + addr - DEBUG_ROM_START, len);
25 return true;
26 }
27
28 fprintf(stderr, "ERROR: invalid load from debug module: %zd bytes at 0x%016"
29 PRIx64 "\n", len, addr);
30 return false;
31 }
32
33 bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes)
34 {
35 addr = DEBUG_START + addr;
36
37 if (addr & (len-1)) {
38 fprintf(stderr, "ERROR: unaligned store to debug module: %zd bytes at 0x%016"
39 PRIx64 "\n", len, addr);
40 return false;
41 }
42
43 if (addr >= DEBUG_RAM_START && addr + len <= DEBUG_RAM_END) {
44 memcpy(debug_ram + addr - DEBUG_RAM_START, bytes, len);
45 return true;
46 } else if (len == 4 && addr == DEBUG_CLEARDEBINT) {
47 clear_interrupt(bytes[0] | (bytes[1] << 8) |
48 (bytes[2] << 16) | (bytes[3] << 24));
49 return true;
50 } else if (len == 4 && addr == DEBUG_SETHALTNOT) {
51 set_halt_notification(bytes[0] | (bytes[1] << 8) |
52 (bytes[2] << 16) | (bytes[3] << 24));
53 return true;
54 }
55
56 fprintf(stderr, "ERROR: invalid store to debug module: %zd bytes at 0x%016"
57 PRIx64 "\n", len, addr);
58 return false;
59 }
60
61 void debug_module_t::ram_write32(unsigned int index, uint32_t value)
62 {
63 char* base = debug_ram + index * 4;
64 base[0] = value & 0xff;
65 base[1] = (value >> 8) & 0xff;
66 base[2] = (value >> 16) & 0xff;
67 base[3] = (value >> 24) & 0xff;
68 }
69
70 uint32_t debug_module_t::ram_read32(unsigned int index)
71 {
72 // It'd be better for raw_page (and all memory) to be unsigned chars, but mem
73 // in sim_t is just chars, so I'm following that convention.
74 unsigned char* base = (unsigned char*) (debug_ram + index * 4);
75 uint32_t value = ((uint32_t) base[0]) |
76 (((uint32_t) base[1]) << 8) |
77 (((uint32_t) base[2]) << 16) |
78 (((uint32_t) base[3]) << 24);
79 return value;
80 }
81
82 uint32_t debug_module_t::dmi_read(unsigned address)
83 {
84 D(fprintf(stderr, "dmi_read(0x%x)\n", address));
85 return 0xfeed;
86 }
87
88 void debug_module_t::dmi_write(unsigned address, uint32_t value)
89 {
90 D(fprintf(stderr, "dmi_write(0x%x, 0x%x)\n", address, value));
91 }