Lots of RISC-V improvements.
[openocd.git] / src / target / riscv / riscv.h
1 #ifndef RISCV_H
2 #define RISCV_H
3
4 struct riscv_program;
5
6 #include <stdint.h>
7 #include "opcodes.h"
8 #include "gdb_regs.h"
9
10 /* The register cache is statically allocated. */
11 #define RISCV_MAX_HARTS 32
12 #define RISCV_MAX_REGISTERS 5000
13 #define RISCV_MAX_TRIGGERS 32
14 #define RISCV_MAX_HWBPS 16
15
16 #define DEFAULT_COMMAND_TIMEOUT_SEC 2
17 #define DEFAULT_RESET_TIMEOUT_SEC 30
18
19 extern struct target_type riscv011_target;
20 extern struct target_type riscv013_target;
21
22 /*
23 * Definitions shared by code supporting all RISC-V versions.
24 */
25 typedef uint64_t riscv_reg_t;
26 typedef uint32_t riscv_insn_t;
27 typedef uint64_t riscv_addr_t;
28
29 enum riscv_halt_reason {
30 RISCV_HALT_INTERRUPT,
31 RISCV_HALT_BREAKPOINT,
32 RISCV_HALT_SINGLESTEP,
33 RISCV_HALT_TRIGGER,
34 RISCV_HALT_UNKNOWN,
35 RISCV_HALT_ERROR
36 };
37
38 typedef struct {
39 struct target *target;
40 unsigned custom_number;
41 } riscv_reg_info_t;
42
43 typedef struct {
44 unsigned dtm_version;
45
46 struct command_context *cmd_ctx;
47 void *version_specific;
48
49 /* The number of harts on this system. */
50 int hart_count;
51
52 /* The hart that the RTOS thinks is currently being debugged. */
53 int rtos_hartid;
54
55 /* The hart that is currently being debugged. Note that this is
56 * different than the hartid that the RTOS is expected to use. This
57 * one will change all the time, it's more of a global argument to
58 * every function than an actual */
59 int current_hartid;
60
61 /* Enough space to store all the registers we might need to save. */
62 /* FIXME: This should probably be a bunch of register caches. */
63 uint64_t saved_registers[RISCV_MAX_HARTS][RISCV_MAX_REGISTERS];
64 bool valid_saved_registers[RISCV_MAX_HARTS][RISCV_MAX_REGISTERS];
65
66 /* OpenOCD's register cache points into here. This is not per-hart because
67 * we just invalidate the entire cache when we change which hart is
68 * selected. */
69 uint64_t reg_cache_values[RISCV_MAX_REGISTERS];
70
71 /* Single buffer that contains all register names, instead of calling
72 * malloc for each register. Needs to be freed when reg_list is freed. */
73 char *reg_names;
74
75 /* It's possible that each core has a different supported ISA set. */
76 int xlen[RISCV_MAX_HARTS];
77 riscv_reg_t misa[RISCV_MAX_HARTS];
78
79 /* The number of triggers per hart. */
80 unsigned trigger_count[RISCV_MAX_HARTS];
81
82 /* For each physical trigger, contains -1 if the hwbp is available, or the
83 * unique_id of the breakpoint/watchpoint that is using it.
84 * Note that in RTOS mode the triggers are the same across all harts the
85 * target controls, while otherwise only a single hart is controlled. */
86 int trigger_unique_id[RISCV_MAX_HWBPS];
87
88 /* The number of entries in the debug buffer. */
89 int debug_buffer_size[RISCV_MAX_HARTS];
90
91 /* This avoids invalidating the register cache too often. */
92 bool registers_initialized;
93
94 /* This hart contains an implicit ebreak at the end of the program buffer. */
95 bool impebreak;
96
97 bool triggers_enumerated;
98
99 /* Decremented every scan, and when it reaches 0 we clear the learned
100 * delays, causing them to be relearned. Used for testing. */
101 int reset_delays_wait;
102
103 /* Helper functions that target the various RISC-V debug spec
104 * implementations. */
105 int (*get_register)(struct target *target,
106 riscv_reg_t *value, int hid, int rid);
107 int (*set_register)(struct target *, int hartid, int regid,
108 uint64_t value);
109 int (*select_current_hart)(struct target *);
110 bool (*is_halted)(struct target *target);
111 int (*halt_current_hart)(struct target *);
112 int (*resume_current_hart)(struct target *target);
113 int (*step_current_hart)(struct target *target);
114 int (*on_halt)(struct target *target);
115 int (*on_resume)(struct target *target);
116 int (*on_step)(struct target *target);
117 enum riscv_halt_reason (*halt_reason)(struct target *target);
118 int (*write_debug_buffer)(struct target *target, unsigned index,
119 riscv_insn_t d);
120 riscv_insn_t (*read_debug_buffer)(struct target *target, unsigned index);
121 int (*execute_debug_buffer)(struct target *target);
122 int (*dmi_write_u64_bits)(struct target *target);
123 void (*fill_dmi_write_u64)(struct target *target, char *buf, int a, uint64_t d);
124 void (*fill_dmi_read_u64)(struct target *target, char *buf, int a);
125 void (*fill_dmi_nop_u64)(struct target *target, char *buf);
126
127 int (*authdata_read)(struct target *target, uint32_t *value);
128 int (*authdata_write)(struct target *target, uint32_t value);
129
130 int (*dmi_read)(struct target *target, uint32_t *value, uint32_t address);
131 int (*dmi_write)(struct target *target, uint32_t address, uint32_t value);
132
133 int (*test_sba_config_reg)(struct target *target, target_addr_t legal_address,
134 uint32_t num_words, target_addr_t illegal_address, bool run_sbbusyerror_test);
135
136 int (*test_compliance)(struct target *target);
137 } riscv_info_t;
138
139 /* Wall-clock timeout for a command/access. Settable via RISC-V Target commands.*/
140 extern int riscv_command_timeout_sec;
141
142 /* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/
143 extern int riscv_reset_timeout_sec;
144
145 extern bool riscv_prefer_sba;
146
147 /* Everything needs the RISC-V specific info structure, so here's a nice macro
148 * that provides that. */
149 static inline riscv_info_t *riscv_info(const struct target *target) __attribute__((unused));
150 static inline riscv_info_t *riscv_info(const struct target *target)
151 { return target->arch_info; }
152 #define RISCV_INFO(R) riscv_info_t *R = riscv_info(target);
153
154 extern uint8_t ir_dtmcontrol[4];
155 extern struct scan_field select_dtmcontrol;
156 extern uint8_t ir_dbus[4];
157 extern struct scan_field select_dbus;
158 extern uint8_t ir_idcode[4];
159 extern struct scan_field select_idcode;
160
161 /*** OpenOCD Interface */
162 int riscv_openocd_poll(struct target *target);
163
164 int riscv_openocd_halt(struct target *target);
165
166 int riscv_openocd_resume(
167 struct target *target,
168 int current,
169 target_addr_t address,
170 int handle_breakpoints,
171 int debug_execution
172 );
173
174 int riscv_openocd_step(
175 struct target *target,
176 int current,
177 target_addr_t address,
178 int handle_breakpoints
179 );
180
181 int riscv_openocd_assert_reset(struct target *target);
182 int riscv_openocd_deassert_reset(struct target *target);
183
184 /*** RISC-V Interface ***/
185
186 /* Initializes the shared RISC-V structure. */
187 void riscv_info_init(struct target *target, riscv_info_t *r);
188
189 /* Run control, possibly for multiple harts. The _all_harts versions resume
190 * all the enabled harts, which when running in RTOS mode is all the harts on
191 * the system. */
192 int riscv_halt_all_harts(struct target *target);
193 int riscv_halt_one_hart(struct target *target, int hartid);
194 int riscv_resume_all_harts(struct target *target);
195 int riscv_resume_one_hart(struct target *target, int hartid);
196
197 /* Steps the hart that's currently selected in the RTOS, or if there is no RTOS
198 * then the only hart. */
199 int riscv_step_rtos_hart(struct target *target);
200
201 bool riscv_supports_extension(struct target *target, int hartid, char letter);
202
203 /* Returns XLEN for the given (or current) hart. */
204 int riscv_xlen(const struct target *target);
205 int riscv_xlen_of_hart(const struct target *target, int hartid);
206
207 bool riscv_rtos_enabled(const struct target *target);
208
209 /* Sets the current hart, which is the hart that will actually be used when
210 * issuing debug commands. */
211 int riscv_set_current_hartid(struct target *target, int hartid);
212 int riscv_current_hartid(const struct target *target);
213
214 /*** Support functions for the RISC-V 'RTOS', which provides multihart support
215 * without requiring multiple targets. */
216
217 /* When using the RTOS to debug, this selects the hart that is currently being
218 * debugged. This doesn't propogate to the hardware. */
219 void riscv_set_all_rtos_harts(struct target *target);
220 void riscv_set_rtos_hartid(struct target *target, int hartid);
221
222 /* Lists the number of harts in the system, which are assumed to be
223 * concecutive and start with mhartid=0. */
224 int riscv_count_harts(struct target *target);
225
226 /* Returns TRUE if the target has the given register on the given hart. */
227 bool riscv_has_register(struct target *target, int hartid, int regid);
228
229 /* Returns the value of the given register on the given hart. 32-bit registers
230 * are zero extended to 64 bits. */
231 int riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v);
232 int riscv_set_register_on_hart(struct target *target, int hid, enum gdb_regno rid, uint64_t v);
233 int riscv_get_register(struct target *target, riscv_reg_t *value,
234 enum gdb_regno r);
235 int riscv_get_register_on_hart(struct target *target, riscv_reg_t *value,
236 int hartid, enum gdb_regno regid);
237
238 /* Checks the state of the current hart -- "is_halted" checks the actual
239 * on-device register. */
240 bool riscv_is_halted(struct target *target);
241 enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid);
242
243 /* These helper functions let the generic program interface get target-specific
244 * information. */
245 size_t riscv_debug_buffer_size(struct target *target);
246
247 riscv_insn_t riscv_read_debug_buffer(struct target *target, int index);
248 int riscv_write_debug_buffer(struct target *target, int index, riscv_insn_t insn);
249 int riscv_execute_debug_buffer(struct target *target);
250
251 void riscv_fill_dmi_nop_u64(struct target *target, char *buf);
252 void riscv_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t d);
253 void riscv_fill_dmi_read_u64(struct target *target, char *buf, int a);
254 int riscv_dmi_write_u64_bits(struct target *target);
255
256 /* Invalidates the register cache. */
257 void riscv_invalidate_register_cache(struct target *target);
258
259 /* Returns TRUE when a hart is enabled in this target. */
260 bool riscv_hart_enabled(struct target *target, int hartid);
261
262 int riscv_enumerate_triggers(struct target *target);
263
264 int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint);
265 int riscv_remove_breakpoint(struct target *target,
266 struct breakpoint *breakpoint);
267 int riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint);
268 int riscv_remove_watchpoint(struct target *target,
269 struct watchpoint *watchpoint);
270 int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_wp_address);
271
272 int riscv_init_registers(struct target *target);
273
274 void riscv_semihosting_init(struct target *target);
275 int riscv_semihosting(struct target *target, int *retval);
276
277 #endif

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)