Abstract register read mostly working.
[riscv-isa-sim.git] / riscv / debug_module.h
1 // See LICENSE for license details.
2 #ifndef _RISCV_DEBUG_MODULE_H
3 #define _RISCV_DEBUG_MODULE_H
4
5 #include <set>
6
7 #include "devices.h"
8
9 class sim_t;
10
11 typedef struct {
12 bool haltreq;
13 bool reset;
14 bool dmactive;
15 enum {
16 HARTSTATUS_HALTED,
17 HARTSTATUS_RUNNING,
18 HARTSTATUS_UNAVAILABLE,
19 HARTSTATUS_NOTEXIST
20 } hartstatus;
21 unsigned hartsel;
22 bool authenticated;
23 bool authbusy;
24 enum {
25 AUTHTYPE_NOAUTH,
26 AUTHTYPE_PASSWORD,
27 AUTHTYPE_CHALLENGE
28 } authtype;
29 unsigned version;
30 } dmcontrol_t;
31
32 typedef struct {
33 bool autoexec7;
34 bool autoexec6;
35 bool autoexec5;
36 bool autoexec4;
37 bool autoexec3;
38 bool autoexec2;
39 bool autoexec1;
40 bool autoexec0;
41 enum {
42 CMDERR_NONE = 0,
43 CMDERR_BUSY = 1,
44 CMDERR_NOTSUP = 2,
45 CMDERR_EXCEPTION = 3,
46 CMDERR_HALTRESUME = 4,
47 CMDERR_OTHER = 7
48 } cmderr;
49 bool busy;
50 unsigned datacount;
51 } abstractcs_t;
52
53 class debug_module_data_t : public abstract_device_t
54 {
55 public:
56 debug_module_data_t();
57
58 bool load(reg_t addr, size_t len, uint8_t* bytes);
59 bool store(reg_t addr, size_t len, const uint8_t* bytes);
60
61 uint32_t read32(reg_t addr) const;
62 void write32(reg_t addr, uint32_t value);
63
64 uint8_t data[DEBUG_EXCHANGE_SIZE];
65 };
66
67 class debug_module_t : public abstract_device_t
68 {
69 public:
70 debug_module_t(sim_t *sim);
71
72 void add_device(bus_t *bus);
73
74 bool load(reg_t addr, size_t len, uint8_t* bytes);
75 bool store(reg_t addr, size_t len, const uint8_t* bytes);
76
77 void set_interrupt(uint32_t hartid) {
78 interrupt.insert(hartid);
79 }
80 void clear_interrupt(uint32_t hartid) {
81 interrupt.erase(hartid);
82 }
83 bool get_interrupt(uint32_t hartid) const {
84 return interrupt.find(hartid) != interrupt.end();
85 }
86
87 void set_halt_notification(uint32_t hartid) {
88 halt_notification.insert(hartid);
89 }
90 void clear_halt_notification(uint32_t hartid) {
91 halt_notification.erase(hartid);
92 }
93 bool get_halt_notification(uint32_t hartid) const {
94 return halt_notification.find(hartid) != halt_notification.end();
95 }
96
97 // Debug Module Interface that the debugger (in our case through JTAG DTM)
98 // uses to access the DM.
99 // Return true for success, false for failure.
100 bool dmi_read(unsigned address, uint32_t *value);
101 bool dmi_write(unsigned address, uint32_t value);
102
103 private:
104 sim_t *sim;
105 // Track which interrupts from module to debugger are set.
106 std::set<uint32_t> interrupt;
107 // Track which halt notifications from debugger to module are set.
108 std::set<uint32_t> halt_notification;
109 uint8_t debug_rom_entry[DEBUG_ROM_ENTRY_SIZE];
110 uint8_t debug_rom_code[DEBUG_ROM_CODE_SIZE];
111 uint8_t debug_rom_exception[DEBUG_ROM_EXCEPTION_SIZE];
112 bool halted[1024];
113 debug_module_data_t dmdata;
114
115 void write32(uint8_t *rom, unsigned int index, uint32_t value);
116 uint32_t read32(uint8_t *rom, unsigned int index);
117
118 static const unsigned progsize = 8;
119
120 dmcontrol_t dmcontrol;
121 abstractcs_t abstractcs;
122 uint32_t ibuf[progsize];
123
124 processor_t *current_proc() const;
125 void reset();
126 bool perform_abstract_command(uint32_t command);
127 };
128
129 #endif