Add debug module authentication.
[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 unsigned hartsel;
15 bool hartreset;
16 bool dmactive;
17 bool ndmreset;
18 } dmcontrol_t;
19
20 typedef struct {
21 bool impebreak;
22 bool allnonexistant;
23 bool anynonexistant;
24 bool allunavail;
25 bool anyunavail;
26 bool allrunning;
27 bool anyrunning;
28 bool allhalted;
29 bool anyhalted;
30 bool allresumeack;
31 bool anyresumeack;
32 bool authenticated;
33 bool authbusy;
34 bool cfgstrvalid;
35 unsigned version;
36 } dmstatus_t;
37
38 typedef enum cmderr {
39 CMDERR_NONE = 0,
40 CMDERR_BUSY = 1,
41 CMDERR_NOTSUP = 2,
42 CMDERR_EXCEPTION = 3,
43 CMDERR_HALTRESUME = 4,
44 CMDERR_OTHER = 7
45 } cmderr_t;
46
47 typedef struct {
48 bool busy;
49 unsigned datacount;
50 unsigned progbufsize;
51 cmderr_t cmderr;
52 } abstractcs_t;
53
54 typedef struct {
55 unsigned autoexecprogbuf;
56 unsigned autoexecdata;
57 } abstractauto_t;
58
59 typedef struct {
60 unsigned version;
61 bool readonaddr;
62 unsigned sbaccess;
63 bool autoincrement;
64 bool readondata;
65 unsigned error;
66 unsigned asize;
67 bool access128;
68 bool access64;
69 bool access32;
70 bool access16;
71 bool access8;
72 } sbcs_t;
73
74 class debug_module_t : public abstract_device_t
75 {
76 public:
77 /*
78 * If require_authentication is true, then a debugger must authenticate as
79 * follows:
80 * 1. Read a 32-bit value from authdata:
81 * 2. Write the value that was read back, plus one, to authdata.
82 */
83 debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits,
84 bool require_authentication);
85 ~debug_module_t();
86
87 void add_device(bus_t *bus);
88
89 bool load(reg_t addr, size_t len, uint8_t* bytes);
90 bool store(reg_t addr, size_t len, const uint8_t* bytes);
91
92 // Debug Module Interface that the debugger (in our case through JTAG DTM)
93 // uses to access the DM.
94 // Return true for success, false for failure.
95 bool dmi_read(unsigned address, uint32_t *value);
96 bool dmi_write(unsigned address, uint32_t value);
97
98 private:
99 static const unsigned datasize = 2;
100 // Size of program_buffer in 32-bit words, as exposed to the rest of the
101 // world.
102 unsigned progbufsize;
103 // Actual size of the program buffer, which is 1 word bigger than we let on
104 // to implement the implicit ebreak at the end.
105 unsigned program_buffer_bytes;
106 unsigned max_bus_master_bits;
107 bool require_authentication;
108 static const unsigned debug_data_start = 0x380;
109 unsigned debug_progbuf_start;
110
111 static const unsigned debug_abstract_size = 2;
112 unsigned debug_abstract_start;
113
114 static const unsigned hartsellen = 10;
115
116 sim_t *sim;
117
118 uint8_t debug_rom_whereto[4];
119 uint8_t debug_abstract[debug_abstract_size * 4];
120 uint8_t *program_buffer;
121 uint8_t dmdata[datasize * 4];
122
123 bool halted[1024];
124 bool resumeack[1024];
125 uint8_t debug_rom_flags[1024];
126
127 void write32(uint8_t *rom, unsigned int index, uint32_t value);
128 uint32_t read32(uint8_t *rom, unsigned int index);
129
130 void sb_autoincrement();
131 void sb_read();
132 void sb_write();
133 unsigned sb_access_bits();
134
135 dmcontrol_t dmcontrol;
136 dmstatus_t dmstatus;
137 abstractcs_t abstractcs;
138 abstractauto_t abstractauto;
139 uint32_t command;
140
141 sbcs_t sbcs;
142 uint32_t sbaddress[4];
143 uint32_t sbdata[4];
144
145 uint32_t challenge;
146 const uint32_t secret = 1;
147
148 processor_t *current_proc() const;
149 void reset();
150 bool perform_abstract_command();
151 };
152
153 #endif