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