Serve up a correct dmcontrol register.
[riscv-isa-sim.git] / riscv / debug_module.cc
1 #include <cassert>
2
3 #include "debug_module.h"
4 #include "debug_defines.h"
5 #include "mmu.h"
6
7 #include "debug_rom/debug_rom.h"
8
9 #if 1
10 # define D(x) x
11 #else
12 # define D(x)
13 #endif
14
15 debug_module_t::debug_module_t() :
16 dmcontrol(1 << DMI_DMCONTROL_VERSION_OFFSET |
17 1 << DMI_DMCONTROL_AUTHENTICATED_OFFSET)
18 {
19 }
20
21 bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes)
22 {
23 addr = DEBUG_START + addr;
24
25 if (addr >= DEBUG_RAM_START && addr + len <= DEBUG_RAM_END) {
26 memcpy(bytes, debug_ram + addr - DEBUG_RAM_START, len);
27 return true;
28 }
29
30 if (addr >= DEBUG_ROM_START && addr + len <= DEBUG_ROM_END) {
31 memcpy(bytes, debug_rom_raw + addr - DEBUG_ROM_START, len);
32 return true;
33 }
34
35 fprintf(stderr, "ERROR: invalid load from debug module: %zd bytes at 0x%016"
36 PRIx64 "\n", len, addr);
37 return false;
38 }
39
40 bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes)
41 {
42 addr = DEBUG_START + addr;
43
44 if (addr & (len-1)) {
45 fprintf(stderr, "ERROR: unaligned store to debug module: %zd bytes at 0x%016"
46 PRIx64 "\n", len, addr);
47 return false;
48 }
49
50 if (addr >= DEBUG_RAM_START && addr + len <= DEBUG_RAM_END) {
51 memcpy(debug_ram + addr - DEBUG_RAM_START, bytes, len);
52 return true;
53 } else if (len == 4 && addr == DEBUG_CLEARDEBINT) {
54 clear_interrupt(bytes[0] | (bytes[1] << 8) |
55 (bytes[2] << 16) | (bytes[3] << 24));
56 return true;
57 } else if (len == 4 && addr == DEBUG_SETHALTNOT) {
58 set_halt_notification(bytes[0] | (bytes[1] << 8) |
59 (bytes[2] << 16) | (bytes[3] << 24));
60 return true;
61 }
62
63 fprintf(stderr, "ERROR: invalid store to debug module: %zd bytes at 0x%016"
64 PRIx64 "\n", len, addr);
65 return false;
66 }
67
68 void debug_module_t::ram_write32(unsigned int index, uint32_t value)
69 {
70 char* base = debug_ram + index * 4;
71 base[0] = value & 0xff;
72 base[1] = (value >> 8) & 0xff;
73 base[2] = (value >> 16) & 0xff;
74 base[3] = (value >> 24) & 0xff;
75 }
76
77 uint32_t debug_module_t::ram_read32(unsigned int index)
78 {
79 // It'd be better for raw_page (and all memory) to be unsigned chars, but mem
80 // in sim_t is just chars, so I'm following that convention.
81 unsigned char* base = (unsigned char*) (debug_ram + index * 4);
82 uint32_t value = ((uint32_t) base[0]) |
83 (((uint32_t) base[1]) << 8) |
84 (((uint32_t) base[2]) << 16) |
85 (((uint32_t) base[3]) << 24);
86 return value;
87 }
88
89 bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
90 {
91 D(fprintf(stderr, "dmi_read(0x%x) -> ", address));
92 switch (address) {
93 case DMI_DMCONTROL:
94 *value = dmcontrol;
95 break;
96 default:
97 D(fprintf(stderr, "error\n"));
98 return false;
99 }
100 D(fprintf(stderr, "0x%x\n", *value));
101 return true;
102 }
103
104 bool debug_module_t::dmi_write(unsigned address, uint32_t value)
105 {
106 D(fprintf(stderr, "dmi_write(0x%x, 0x%x)\n", address, value));
107 return false;
108 }