mips32: add per-cpu quirks feature
[openocd.git] / src / target / mips32.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2008 by Spencer Oliver *
5 * spen@spen-soft.co.uk *
6 * *
7 * Copyright (C) 2008 by David T.L. Wong *
8 * *
9 * Copyright (C) 2007,2008 Øyvind Harboe *
10 * oyvind.harboe@zylin.com *
11 * *
12 * Copyright (C) 2011 by Drasko DRASKOVIC *
13 * drasko.draskovic@gmail.com *
14 ***************************************************************************/
15
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19
20 #include "mips32.h"
21 #include "mips_cpu.h"
22 #include "breakpoints.h"
23 #include "algorithm.h"
24 #include "register.h"
25
26 static const char *mips_isa_strings[] = {
27 "MIPS32", "MIPS16", "", "MICRO MIPS32",
28 };
29
30 #define MIPS32_GDB_DUMMY_FP_REG 1
31
32 /*
33 * GDB registers
34 * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml
35 */
36 static const struct {
37 unsigned id;
38 const char *name;
39 enum reg_type type;
40 const char *group;
41 const char *feature;
42 int flag;
43 } mips32_regs[] = {
44 { 0, "r0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
45 { 1, "r1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
46 { 2, "r2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
47 { 3, "r3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
48 { 4, "r4", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
49 { 5, "r5", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
50 { 6, "r6", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
51 { 7, "r7", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
52 { 8, "r8", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
53 { 9, "r9", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
54 { 10, "r10", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
55 { 11, "r11", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
56 { 12, "r12", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
57 { 13, "r13", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
58 { 14, "r14", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
59 { 15, "r15", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
60 { 16, "r16", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
61 { 17, "r17", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
62 { 18, "r18", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
63 { 19, "r19", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
64 { 20, "r20", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
65 { 21, "r21", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
66 { 22, "r22", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
67 { 23, "r23", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
68 { 24, "r24", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
69 { 25, "r25", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
70 { 26, "r26", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
71 { 27, "r27", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
72 { 28, "r28", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
73 { 29, "r29", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
74 { 30, "r30", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
75 { 31, "r31", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
76 { 32, "status", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
77 { 33, "lo", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
78 { 34, "hi", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
79 { 35, "badvaddr", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
80 { 36, "cause", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
81 { 37, "pc", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
82
83 { 38, "f0", REG_TYPE_IEEE_SINGLE, NULL,
84 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
85 { 39, "f1", REG_TYPE_IEEE_SINGLE, NULL,
86 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
87 { 40, "f2", REG_TYPE_IEEE_SINGLE, NULL,
88 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
89 { 41, "f3", REG_TYPE_IEEE_SINGLE, NULL,
90 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
91 { 42, "f4", REG_TYPE_IEEE_SINGLE, NULL,
92 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
93 { 43, "f5", REG_TYPE_IEEE_SINGLE, NULL,
94 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
95 { 44, "f6", REG_TYPE_IEEE_SINGLE, NULL,
96 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
97 { 45, "f7", REG_TYPE_IEEE_SINGLE, NULL,
98 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
99 { 46, "f8", REG_TYPE_IEEE_SINGLE, NULL,
100 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
101 { 47, "f9", REG_TYPE_IEEE_SINGLE, NULL,
102 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
103 { 48, "f10", REG_TYPE_IEEE_SINGLE, NULL,
104 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
105 { 49, "f11", REG_TYPE_IEEE_SINGLE, NULL,
106 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
107 { 50, "f12", REG_TYPE_IEEE_SINGLE, NULL,
108 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
109 { 51, "f13", REG_TYPE_IEEE_SINGLE, NULL,
110 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
111 { 52, "f14", REG_TYPE_IEEE_SINGLE, NULL,
112 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
113 { 53, "f15", REG_TYPE_IEEE_SINGLE, NULL,
114 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
115 { 54, "f16", REG_TYPE_IEEE_SINGLE, NULL,
116 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
117 { 55, "f17", REG_TYPE_IEEE_SINGLE, NULL,
118 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
119 { 56, "f18", REG_TYPE_IEEE_SINGLE, NULL,
120 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
121 { 57, "f19", REG_TYPE_IEEE_SINGLE, NULL,
122 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
123 { 58, "f20", REG_TYPE_IEEE_SINGLE, NULL,
124 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
125 { 59, "f21", REG_TYPE_IEEE_SINGLE, NULL,
126 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
127 { 60, "f22", REG_TYPE_IEEE_SINGLE, NULL,
128 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
129 { 61, "f23", REG_TYPE_IEEE_SINGLE, NULL,
130 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
131 { 62, "f24", REG_TYPE_IEEE_SINGLE, NULL,
132 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
133 { 63, "f25", REG_TYPE_IEEE_SINGLE, NULL,
134 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
135 { 64, "f26", REG_TYPE_IEEE_SINGLE, NULL,
136 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
137 { 65, "f27", REG_TYPE_IEEE_SINGLE, NULL,
138 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
139 { 66, "f28", REG_TYPE_IEEE_SINGLE, NULL,
140 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
141 { 67, "f29", REG_TYPE_IEEE_SINGLE, NULL,
142 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
143 { 68, "f30", REG_TYPE_IEEE_SINGLE, NULL,
144 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
145 { 69, "f31", REG_TYPE_IEEE_SINGLE, NULL,
146 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
147 { 70, "fcsr", REG_TYPE_INT, "float",
148 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
149 { 71, "fir", REG_TYPE_INT, "float",
150 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
151 };
152
153
154 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
155
156 static uint8_t mips32_gdb_dummy_fp_value[] = {0, 0, 0, 0};
157
158 static int mips32_get_core_reg(struct reg *reg)
159 {
160 int retval;
161 struct mips32_core_reg *mips32_reg = reg->arch_info;
162 struct target *target = mips32_reg->target;
163 struct mips32_common *mips32_target = target_to_mips32(target);
164
165 if (target->state != TARGET_HALTED)
166 return ERROR_TARGET_NOT_HALTED;
167
168 retval = mips32_target->read_core_reg(target, mips32_reg->num);
169
170 return retval;
171 }
172
173 static int mips32_set_core_reg(struct reg *reg, uint8_t *buf)
174 {
175 struct mips32_core_reg *mips32_reg = reg->arch_info;
176 struct target *target = mips32_reg->target;
177 uint32_t value = buf_get_u32(buf, 0, 32);
178
179 if (target->state != TARGET_HALTED)
180 return ERROR_TARGET_NOT_HALTED;
181
182 buf_set_u32(reg->value, 0, 32, value);
183 reg->dirty = true;
184 reg->valid = true;
185
186 return ERROR_OK;
187 }
188
189 static int mips32_read_core_reg(struct target *target, unsigned int num)
190 {
191 uint32_t reg_value;
192
193 /* get pointers to arch-specific information */
194 struct mips32_common *mips32 = target_to_mips32(target);
195
196 if (num >= MIPS32_NUM_REGS)
197 return ERROR_COMMAND_SYNTAX_ERROR;
198
199 reg_value = mips32->core_regs[num];
200 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
201 mips32->core_cache->reg_list[num].valid = true;
202 mips32->core_cache->reg_list[num].dirty = false;
203
204 return ERROR_OK;
205 }
206
207 static int mips32_write_core_reg(struct target *target, unsigned int num)
208 {
209 uint32_t reg_value;
210
211 /* get pointers to arch-specific information */
212 struct mips32_common *mips32 = target_to_mips32(target);
213
214 if (num >= MIPS32_NUM_REGS)
215 return ERROR_COMMAND_SYNTAX_ERROR;
216
217 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
218 mips32->core_regs[num] = reg_value;
219 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value);
220 mips32->core_cache->reg_list[num].valid = true;
221 mips32->core_cache->reg_list[num].dirty = false;
222
223 return ERROR_OK;
224 }
225
226 int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
227 int *reg_list_size, enum target_register_class reg_class)
228 {
229 /* get pointers to arch-specific information */
230 struct mips32_common *mips32 = target_to_mips32(target);
231 unsigned int i;
232
233 /* include floating point registers */
234 *reg_list_size = MIPS32_NUM_REGS;
235 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
236
237 for (i = 0; i < MIPS32_NUM_REGS; i++)
238 (*reg_list)[i] = &mips32->core_cache->reg_list[i];
239
240 return ERROR_OK;
241 }
242
243 int mips32_save_context(struct target *target)
244 {
245 unsigned int i;
246
247 /* get pointers to arch-specific information */
248 struct mips32_common *mips32 = target_to_mips32(target);
249 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
250
251 /* read core registers */
252 mips32_pracc_read_regs(ejtag_info, mips32->core_regs);
253
254 for (i = 0; i < MIPS32_NUM_REGS; i++) {
255 if (!mips32->core_cache->reg_list[i].valid)
256 mips32->read_core_reg(target, i);
257 }
258
259 return ERROR_OK;
260 }
261
262 int mips32_restore_context(struct target *target)
263 {
264 unsigned int i;
265
266 /* get pointers to arch-specific information */
267 struct mips32_common *mips32 = target_to_mips32(target);
268 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
269
270 for (i = 0; i < MIPS32_NUM_REGS; i++) {
271 if (mips32->core_cache->reg_list[i].dirty)
272 mips32->write_core_reg(target, i);
273 }
274
275 /* write core regs */
276 mips32_pracc_write_regs(ejtag_info, mips32->core_regs);
277
278 return ERROR_OK;
279 }
280
281 int mips32_arch_state(struct target *target)
282 {
283 struct mips32_common *mips32 = target_to_mips32(target);
284
285 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32 "",
286 mips_isa_strings[mips32->isa_mode],
287 debug_reason_name(target),
288 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
289
290 return ERROR_OK;
291 }
292
293 static const struct reg_arch_type mips32_reg_type = {
294 .get = mips32_get_core_reg,
295 .set = mips32_set_core_reg,
296 };
297
298 struct reg_cache *mips32_build_reg_cache(struct target *target)
299 {
300 /* get pointers to arch-specific information */
301 struct mips32_common *mips32 = target_to_mips32(target);
302
303 int num_regs = MIPS32_NUM_REGS;
304 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
305 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
306 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
307 struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);
308 struct reg_feature *feature;
309 int i;
310
311 /* Build the process context cache */
312 cache->name = "mips32 registers";
313 cache->next = NULL;
314 cache->reg_list = reg_list;
315 cache->num_regs = num_regs;
316 (*cache_p) = cache;
317 mips32->core_cache = cache;
318
319 for (i = 0; i < num_regs; i++) {
320 arch_info[i].num = mips32_regs[i].id;
321 arch_info[i].target = target;
322 arch_info[i].mips32_common = mips32;
323
324 reg_list[i].name = mips32_regs[i].name;
325 reg_list[i].size = 32;
326
327 if (mips32_regs[i].flag == MIPS32_GDB_DUMMY_FP_REG) {
328 reg_list[i].value = mips32_gdb_dummy_fp_value;
329 reg_list[i].valid = true;
330 reg_list[i].arch_info = NULL;
331 register_init_dummy(&reg_list[i]);
332 } else {
333 reg_list[i].value = calloc(1, 4);
334 reg_list[i].valid = false;
335 reg_list[i].type = &mips32_reg_type;
336 reg_list[i].arch_info = &arch_info[i];
337
338 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
339 if (reg_list[i].reg_data_type)
340 reg_list[i].reg_data_type->type = mips32_regs[i].type;
341 else
342 LOG_ERROR("unable to allocate reg type list");
343 }
344
345 reg_list[i].dirty = false;
346
347 reg_list[i].group = mips32_regs[i].group;
348 reg_list[i].number = i;
349 reg_list[i].exist = true;
350 reg_list[i].caller_save = true; /* gdb defaults to true */
351
352 feature = calloc(1, sizeof(struct reg_feature));
353 if (feature) {
354 feature->name = mips32_regs[i].feature;
355 reg_list[i].feature = feature;
356 } else
357 LOG_ERROR("unable to allocate feature list");
358 }
359
360 return cache;
361 }
362
363 int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, struct jtag_tap *tap)
364 {
365 target->arch_info = mips32;
366 mips32->common_magic = MIPS32_COMMON_MAGIC;
367 mips32->fast_data_area = NULL;
368 mips32->isa_imp = MIPS32_ONLY; /* default */
369
370 /* has breakpoint/watchpoint unit been scanned */
371 mips32->bp_scanned = 0;
372 mips32->data_break_list = NULL;
373
374 mips32->ejtag_info.tap = tap;
375 mips32->read_core_reg = mips32_read_core_reg;
376 mips32->write_core_reg = mips32_write_core_reg;
377 /* if unknown endianness defaults to little endian, 1 */
378 mips32->ejtag_info.endianness = target->endianness == TARGET_BIG_ENDIAN ? 0 : 1;
379 mips32->ejtag_info.scan_delay = MIPS32_SCAN_DELAY_LEGACY_MODE;
380 mips32->ejtag_info.mode = 0; /* Initial default value */
381 mips32->ejtag_info.isa = 0; /* isa on debug mips32, updated by poll function */
382 mips32->ejtag_info.config_regs = 0; /* no config register read */
383 return ERROR_OK;
384 }
385
386 /* run to exit point. return error if exit point was not reached. */
387 static int mips32_run_and_wait(struct target *target, target_addr_t entry_point,
388 unsigned int timeout_ms, target_addr_t exit_point, struct mips32_common *mips32)
389 {
390 uint32_t pc;
391 int retval;
392 /* This code relies on the target specific resume() and poll()->debug_entry()
393 * sequence to write register values to the processor and the read them back */
394 retval = target_resume(target, 0, entry_point, 0, 1);
395 if (retval != ERROR_OK)
396 return retval;
397
398 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
399 /* If the target fails to halt due to the breakpoint, force a halt */
400 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
401 retval = target_halt(target);
402 if (retval != ERROR_OK)
403 return retval;
404 retval = target_wait_state(target, TARGET_HALTED, 500);
405 if (retval != ERROR_OK)
406 return retval;
407 return ERROR_TARGET_TIMEOUT;
408 }
409
410 pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
411 if (exit_point && (pc != exit_point)) {
412 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
413 return ERROR_TARGET_TIMEOUT;
414 }
415
416 return ERROR_OK;
417 }
418
419 int mips32_run_algorithm(struct target *target, int num_mem_params,
420 struct mem_param *mem_params, int num_reg_params,
421 struct reg_param *reg_params, target_addr_t entry_point,
422 target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
423 {
424 struct mips32_common *mips32 = target_to_mips32(target);
425 struct mips32_algorithm *mips32_algorithm_info = arch_info;
426 enum mips32_isa_mode isa_mode = mips32->isa_mode;
427
428 uint32_t context[MIPS32_NUM_REGS];
429 int retval = ERROR_OK;
430
431 LOG_DEBUG("Running algorithm");
432
433 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
434 * at the exit point */
435
436 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
437 LOG_ERROR("current target isn't a MIPS32 target");
438 return ERROR_TARGET_INVALID;
439 }
440
441 if (target->state != TARGET_HALTED) {
442 LOG_TARGET_ERROR(target, "not halted (run target algo)");
443 return ERROR_TARGET_NOT_HALTED;
444 }
445
446 /* refresh core register cache */
447 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
448 if (!mips32->core_cache->reg_list[i].valid)
449 mips32->read_core_reg(target, i);
450 context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
451 }
452
453 for (int i = 0; i < num_mem_params; i++) {
454 if (mem_params[i].direction == PARAM_IN)
455 continue;
456 retval = target_write_buffer(target, mem_params[i].address,
457 mem_params[i].size, mem_params[i].value);
458 if (retval != ERROR_OK)
459 return retval;
460 }
461
462 for (int i = 0; i < num_reg_params; i++) {
463 if (reg_params[i].direction == PARAM_IN)
464 continue;
465
466 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false);
467
468 if (!reg) {
469 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
470 return ERROR_COMMAND_SYNTAX_ERROR;
471 }
472
473 if (reg->size != reg_params[i].size) {
474 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
475 reg_params[i].reg_name);
476 return ERROR_COMMAND_SYNTAX_ERROR;
477 }
478
479 mips32_set_core_reg(reg, reg_params[i].value);
480 }
481
482 mips32->isa_mode = mips32_algorithm_info->isa_mode;
483
484 retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32);
485
486 if (retval != ERROR_OK)
487 return retval;
488
489 for (int i = 0; i < num_mem_params; i++) {
490 if (mem_params[i].direction != PARAM_OUT) {
491 retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size,
492 mem_params[i].value);
493 if (retval != ERROR_OK)
494 return retval;
495 }
496 }
497
498 for (int i = 0; i < num_reg_params; i++) {
499 if (reg_params[i].direction != PARAM_OUT) {
500 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false);
501 if (!reg) {
502 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
503 return ERROR_COMMAND_SYNTAX_ERROR;
504 }
505
506 if (reg->size != reg_params[i].size) {
507 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
508 reg_params[i].reg_name);
509 return ERROR_COMMAND_SYNTAX_ERROR;
510 }
511
512 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
513 }
514 }
515
516 /* restore everything we saved before */
517 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
518 uint32_t regvalue;
519 regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
520 if (regvalue != context[i]) {
521 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
522 mips32->core_cache->reg_list[i].name, context[i]);
523 buf_set_u32(mips32->core_cache->reg_list[i].value,
524 0, 32, context[i]);
525 mips32->core_cache->reg_list[i].valid = true;
526 mips32->core_cache->reg_list[i].dirty = true;
527 }
528 }
529
530 mips32->isa_mode = isa_mode;
531
532 return ERROR_OK;
533 }
534
535 int mips32_examine(struct target *target)
536 {
537 struct mips32_common *mips32 = target_to_mips32(target);
538
539 if (!target_was_examined(target)) {
540 target_set_examined(target);
541
542 /* we will configure later */
543 mips32->bp_scanned = 0;
544 mips32->num_inst_bpoints = 0;
545 mips32->num_data_bpoints = 0;
546 mips32->num_inst_bpoints_avail = 0;
547 mips32->num_data_bpoints_avail = 0;
548 }
549
550 return ERROR_OK;
551 }
552
553 static int mips32_configure_ibs(struct target *target)
554 {
555 struct mips32_common *mips32 = target_to_mips32(target);
556 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
557 int retval, i;
558 uint32_t bpinfo;
559
560 /* get number of inst breakpoints */
561 retval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo);
562 if (retval != ERROR_OK)
563 return retval;
564
565 mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
566 mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
567 mips32->inst_break_list = calloc(mips32->num_inst_bpoints,
568 sizeof(struct mips32_comparator));
569
570 for (i = 0; i < mips32->num_inst_bpoints; i++)
571 mips32->inst_break_list[i].reg_address =
572 ejtag_info->ejtag_iba0_addr +
573 (ejtag_info->ejtag_iba_step_size * i);
574
575 /* clear IBIS reg */
576 retval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0);
577 return retval;
578 }
579
580 static int mips32_configure_dbs(struct target *target)
581 {
582 struct mips32_common *mips32 = target_to_mips32(target);
583 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
584 int retval, i;
585 uint32_t bpinfo;
586
587 /* get number of data breakpoints */
588 retval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo);
589 if (retval != ERROR_OK)
590 return retval;
591
592 mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
593 mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
594 mips32->data_break_list = calloc(mips32->num_data_bpoints,
595 sizeof(struct mips32_comparator));
596
597 for (i = 0; i < mips32->num_data_bpoints; i++)
598 mips32->data_break_list[i].reg_address =
599 ejtag_info->ejtag_dba0_addr +
600 (ejtag_info->ejtag_dba_step_size * i);
601
602 /* clear DBIS reg */
603 retval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0);
604 return retval;
605 }
606
607 int mips32_configure_break_unit(struct target *target)
608 {
609 /* get pointers to arch-specific information */
610 struct mips32_common *mips32 = target_to_mips32(target);
611 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
612 int retval;
613 uint32_t dcr;
614
615 if (mips32->bp_scanned)
616 return ERROR_OK;
617
618 /* get info about breakpoint support */
619 retval = target_read_u32(target, EJTAG_DCR, &dcr);
620 if (retval != ERROR_OK)
621 return retval;
622
623 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
624 if (ejtag_info->ejtag_version == EJTAG_VERSION_20) {
625 ejtag_info->debug_caps = dcr & EJTAG_DCR_ENM;
626 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NOIB))
627 ejtag_info->debug_caps |= EJTAG_DCR_IB;
628 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NODB))
629 ejtag_info->debug_caps |= EJTAG_DCR_DB;
630 } else
631 /* keep debug caps for later use */
632 ejtag_info->debug_caps = dcr & (EJTAG_DCR_ENM
633 | EJTAG_DCR_IB | EJTAG_DCR_DB);
634
635
636 if (ejtag_info->debug_caps & EJTAG_DCR_IB) {
637 retval = mips32_configure_ibs(target);
638 if (retval != ERROR_OK)
639 return retval;
640 }
641
642 if (ejtag_info->debug_caps & EJTAG_DCR_DB) {
643 retval = mips32_configure_dbs(target);
644 if (retval != ERROR_OK)
645 return retval;
646 }
647
648 /* check if target endianness settings matches debug control register */
649 if (((ejtag_info->debug_caps & EJTAG_DCR_ENM)
650 && (target->endianness == TARGET_LITTLE_ENDIAN)) ||
651 (!(ejtag_info->debug_caps & EJTAG_DCR_ENM)
652 && (target->endianness == TARGET_BIG_ENDIAN)))
653 LOG_WARNING("DCR endianness settings does not match target settings");
654
655 LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints,
656 mips32->num_data_bpoints);
657
658 mips32->bp_scanned = 1;
659
660 return ERROR_OK;
661 }
662
663 int mips32_enable_interrupts(struct target *target, int enable)
664 {
665 int retval;
666 int update = 0;
667 uint32_t dcr;
668
669 /* read debug control register */
670 retval = target_read_u32(target, EJTAG_DCR, &dcr);
671 if (retval != ERROR_OK)
672 return retval;
673
674 if (enable) {
675 if (!(dcr & EJTAG_DCR_INTE)) {
676 /* enable interrupts */
677 dcr |= EJTAG_DCR_INTE;
678 update = 1;
679 }
680 } else {
681 if (dcr & EJTAG_DCR_INTE) {
682 /* disable interrupts */
683 dcr &= ~EJTAG_DCR_INTE;
684 update = 1;
685 }
686 }
687
688 if (update) {
689 retval = target_write_u32(target, EJTAG_DCR, dcr);
690 if (retval != ERROR_OK)
691 return retval;
692 }
693
694 return ERROR_OK;
695 }
696
697 /* read processor identification cp0 register */
698 static int mips32_read_c0_prid(struct target *target)
699 {
700 struct mips32_common *mips32 = target_to_mips32(target);
701 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
702 int retval;
703
704 retval = mips32_cp0_read(ejtag_info, &mips32->prid, 15, 0);
705 if (retval != ERROR_OK) {
706 LOG_ERROR("processor id not available, failed to read cp0 PRId register");
707 mips32->prid = 0;
708 }
709
710 return retval;
711 }
712
713 /*
714 * Detect processor type and apply required quirks.
715 *
716 * NOTE: The proper detection of certain CPUs can become quite complicated.
717 * Please consult the following Linux kernel code when adding new CPUs:
718 * arch/mips/include/asm/cpu.h
719 * arch/mips/kernel/cpu-probe.c
720 */
721 int mips32_cpu_probe(struct target *target)
722 {
723 struct mips32_common *mips32 = target_to_mips32(target);
724 const char *cpu_name = "unknown";
725 int retval;
726
727 if (mips32->prid)
728 return ERROR_OK; /* Already probed once, return early. */
729
730 retval = mips32_read_c0_prid(target);
731 if (retval != ERROR_OK)
732 return retval;
733
734 switch (mips32->prid & PRID_COMP_MASK) {
735 case PRID_COMP_INGENIC_E1:
736 switch (mips32->prid & PRID_IMP_MASK) {
737 case PRID_IMP_XBURST_REV1:
738 cpu_name = "Ingenic XBurst rev1";
739 mips32->cpu_quirks |= EJTAG_QUIRK_PAD_DRET;
740 break;
741 default:
742 break;
743 }
744 break;
745 default:
746 break;
747 }
748
749 LOG_DEBUG("CPU: %s (PRId %08x)", cpu_name, mips32->prid);
750
751 return ERROR_OK;
752 }
753
754 /* read config to config3 cp0 registers and log isa implementation */
755 int mips32_read_config_regs(struct target *target)
756 {
757 struct mips32_common *mips32 = target_to_mips32(target);
758 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
759
760 if (ejtag_info->config_regs == 0)
761 for (int i = 0; i != 4; i++) {
762 int retval = mips32_cp0_read(ejtag_info, &ejtag_info->config[i], 16, i);
763 if (retval != ERROR_OK) {
764 LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32, i);
765 ejtag_info->config_regs = 0;
766 return retval;
767 }
768 ejtag_info->config_regs = i + 1;
769 if ((ejtag_info->config[i] & (1 << 31)) == 0)
770 break; /* no more config registers implemented */
771 }
772 else
773 return ERROR_OK; /* already successfully read */
774
775 LOG_DEBUG("read %"PRIu32" config registers", ejtag_info->config_regs);
776
777 if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
778 mips32->isa_imp = MIPS32_MIPS16;
779 LOG_USER("MIPS32 with MIPS16 support implemented");
780
781 } else if (ejtag_info->config_regs >= 4) { /* config3 implemented */
782 unsigned isa_imp = (ejtag_info->config[3] & MIPS32_CONFIG3_ISA_MASK) >> MIPS32_CONFIG3_ISA_SHIFT;
783 if (isa_imp == 1) {
784 mips32->isa_imp = MMIPS32_ONLY;
785 LOG_USER("MICRO MIPS32 only implemented");
786
787 } else if (isa_imp != 0) {
788 mips32->isa_imp = MIPS32_MMIPS32;
789 LOG_USER("MIPS32 and MICRO MIPS32 implemented");
790 }
791 }
792
793 if (mips32->isa_imp == MIPS32_ONLY) /* initial default value */
794 LOG_USER("MIPS32 only implemented");
795
796 return ERROR_OK;
797 }
798 int mips32_checksum_memory(struct target *target, target_addr_t address,
799 uint32_t count, uint32_t *checksum)
800 {
801 struct working_area *crc_algorithm;
802 struct reg_param reg_params[2];
803 struct mips32_algorithm mips32_info;
804
805 struct mips32_common *mips32 = target_to_mips32(target);
806 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
807
808 /* see contrib/loaders/checksum/mips32.s for src */
809 uint32_t isa = ejtag_info->isa ? 1 : 0;
810
811 uint32_t mips_crc_code[] = {
812 MIPS32_ADDIU(isa, 12, 4, 0), /* addiu $t4, $a0, 0 */
813 MIPS32_ADDIU(isa, 10, 5, 0), /* addiu $t2, $a1, 0 */
814 MIPS32_ADDIU(isa, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
815 MIPS32_BEQ(isa, 0, 0, 0x10 << isa), /* beq $zero, $zero, ncomp */
816 MIPS32_ADDIU(isa, 11, 0, 0), /* addiu $t3, $zero, 0 */
817 /* nbyte: */
818 MIPS32_LB(isa, 5, 0, 12), /* lb $a1, ($t4) */
819 MIPS32_ADDI(isa, 12, 12, 1), /* addi $t4, $t4, 1 */
820 MIPS32_SLL(isa, 5, 5, 24), /* sll $a1, $a1, 24 */
821 MIPS32_LUI(isa, 2, 0x04c1), /* lui $v0, 0x04c1 */
822 MIPS32_XOR(isa, 4, 4, 5), /* xor $a0, $a0, $a1 */
823 MIPS32_ORI(isa, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
824 MIPS32_ADDU(isa, 6, 0, 0), /* addu $a2, $zero, $zero */
825 /* loop */
826 MIPS32_SLL(isa, 8, 4, 1), /* sll $t0, $a0, 1 */
827 MIPS32_ADDIU(isa, 6, 6, 1), /* addiu $a2, $a2, 1 */
828 MIPS32_SLTI(isa, 4, 4, 0), /* slti $a0, $a0, 0 */
829 MIPS32_XOR(isa, 9, 8, 7), /* xor $t1, $t0, $a3 */
830 MIPS32_MOVN(isa, 8, 9, 4), /* movn $t0, $t1, $a0 */
831 MIPS32_SLTI(isa, 3, 6, 8), /* slti $v1, $a2, 8 */
832 MIPS32_BNE(isa, 3, 0, NEG16(7 << isa)), /* bne $v1, $zero, loop */
833 MIPS32_ADDU(isa, 4, 8, 0), /* addu $a0, $t0, $zero */
834 /* ncomp */
835 MIPS32_BNE(isa, 10, 11, NEG16(16 << isa)), /* bne $t2, $t3, nbyte */
836 MIPS32_ADDIU(isa, 11, 11, 1), /* addiu $t3, $t3, 1 */
837 MIPS32_SDBBP(isa),
838 };
839
840 /* make sure we have a working area */
841 if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)
842 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
843
844 pracc_swap16_array(ejtag_info, mips_crc_code, ARRAY_SIZE(mips_crc_code));
845
846 /* convert mips crc code into a buffer in target endianness */
847 uint8_t mips_crc_code_8[sizeof(mips_crc_code)];
848 target_buffer_set_u32_array(target, mips_crc_code_8,
849 ARRAY_SIZE(mips_crc_code), mips_crc_code);
850
851 int retval = target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);
852 if (retval != ERROR_OK)
853 return retval;
854
855 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
856 mips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32; /* run isa as in debug mode */
857
858 init_reg_param(&reg_params[0], "r4", 32, PARAM_IN_OUT);
859 buf_set_u32(reg_params[0].value, 0, 32, address);
860
861 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
862 buf_set_u32(reg_params[1].value, 0, 32, count);
863
864 unsigned int timeout = 20000 * (1 + (count / (1024 * 1024)));
865
866 retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,
867 crc_algorithm->address + (sizeof(mips_crc_code) - 4), timeout, &mips32_info);
868
869 if (retval == ERROR_OK)
870 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
871
872 destroy_reg_param(&reg_params[0]);
873 destroy_reg_param(&reg_params[1]);
874
875 target_free_working_area(target, crc_algorithm);
876
877 return retval;
878 }
879
880 /** Checks whether a memory region is erased. */
881 int mips32_blank_check_memory(struct target *target,
882 struct target_memory_check_block *blocks, int num_blocks,
883 uint8_t erased_value)
884 {
885 struct working_area *erase_check_algorithm;
886 struct reg_param reg_params[3];
887 struct mips32_algorithm mips32_info;
888
889 struct mips32_common *mips32 = target_to_mips32(target);
890 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
891
892 if (erased_value != 0xff) {
893 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for MIPS32",
894 erased_value);
895 return ERROR_FAIL;
896 }
897 uint32_t isa = ejtag_info->isa ? 1 : 0;
898 uint32_t erase_check_code[] = {
899 /* nbyte: */
900 MIPS32_LB(isa, 8, 0, 4), /* lb $t0, ($a0) */
901 MIPS32_AND(isa, 6, 6, 8), /* and $a2, $a2, $t0 */
902 MIPS32_ADDIU(isa, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
903 MIPS32_BNE(isa, 5, 0, NEG16(4 << isa)), /* bne $a1, $zero, nbyte */
904 MIPS32_ADDIU(isa, 4, 4, 1), /* addiu $a0, $a0, 1 */
905 MIPS32_SDBBP(isa) /* sdbbp */
906 };
907
908 /* make sure we have a working area */
909 if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
910 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
911
912 pracc_swap16_array(ejtag_info, erase_check_code, ARRAY_SIZE(erase_check_code));
913
914 /* convert erase check code into a buffer in target endianness */
915 uint8_t erase_check_code_8[sizeof(erase_check_code)];
916 target_buffer_set_u32_array(target, erase_check_code_8,
917 ARRAY_SIZE(erase_check_code), erase_check_code);
918
919 int retval = target_write_buffer(target, erase_check_algorithm->address,
920 sizeof(erase_check_code), erase_check_code_8);
921 if (retval != ERROR_OK)
922 goto cleanup;
923
924 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
925 mips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32;
926
927 init_reg_param(&reg_params[0], "r4", 32, PARAM_OUT);
928 buf_set_u32(reg_params[0].value, 0, 32, blocks[0].address);
929
930 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
931 buf_set_u32(reg_params[1].value, 0, 32, blocks[0].size);
932
933 init_reg_param(&reg_params[2], "r6", 32, PARAM_IN_OUT);
934 buf_set_u32(reg_params[2].value, 0, 32, erased_value);
935
936 retval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address,
937 erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &mips32_info);
938
939 if (retval == ERROR_OK)
940 blocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);
941
942 destroy_reg_param(&reg_params[0]);
943 destroy_reg_param(&reg_params[1]);
944 destroy_reg_param(&reg_params[2]);
945
946 cleanup:
947 target_free_working_area(target, erase_check_algorithm);
948
949 if (retval != ERROR_OK)
950 return retval;
951
952 return 1; /* only one block has been checked */
953 }
954
955 static int mips32_verify_pointer(struct command_invocation *cmd,
956 struct mips32_common *mips32)
957 {
958 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
959 command_print(cmd, "target is not an MIPS32");
960 return ERROR_TARGET_INVALID;
961 }
962 return ERROR_OK;
963 }
964
965 /**
966 * MIPS32 targets expose command interface
967 * to manipulate CP0 registers
968 */
969 COMMAND_HANDLER(mips32_handle_cp0_command)
970 {
971 int retval;
972 struct target *target = get_current_target(CMD_CTX);
973 struct mips32_common *mips32 = target_to_mips32(target);
974 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
975
976
977 retval = mips32_verify_pointer(CMD, mips32);
978 if (retval != ERROR_OK)
979 return retval;
980
981 if (target->state != TARGET_HALTED) {
982 command_print(CMD, "Error: target must be stopped for \"%s\" command", CMD_NAME);
983 return ERROR_TARGET_NOT_HALTED;
984 }
985
986 /* two or more argument, access a single register/select (write if third argument is given) */
987 if (CMD_ARGC < 2)
988 return ERROR_COMMAND_SYNTAX_ERROR;
989 else {
990 uint32_t cp0_reg, cp0_sel;
991 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
992 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
993
994 if (CMD_ARGC == 2) {
995 uint32_t value;
996
997 retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
998 if (retval != ERROR_OK) {
999 command_print(CMD,
1000 "couldn't access reg %" PRIu32,
1001 cp0_reg);
1002 return ERROR_OK;
1003 }
1004 command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
1005 cp0_reg, cp0_sel, value);
1006
1007 } else if (CMD_ARGC == 3) {
1008 uint32_t value;
1009 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
1010 retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
1011 if (retval != ERROR_OK) {
1012 command_print(CMD,
1013 "couldn't access cp0 reg %" PRIu32 ", select %" PRIu32,
1014 cp0_reg, cp0_sel);
1015 return ERROR_OK;
1016 }
1017 command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
1018 cp0_reg, cp0_sel, value);
1019 }
1020 }
1021
1022 return ERROR_OK;
1023 }
1024
1025 COMMAND_HANDLER(mips32_handle_scan_delay_command)
1026 {
1027 struct target *target = get_current_target(CMD_CTX);
1028 struct mips32_common *mips32 = target_to_mips32(target);
1029 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1030
1031 if (CMD_ARGC == 1)
1032 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);
1033 else if (CMD_ARGC > 1)
1034 return ERROR_COMMAND_SYNTAX_ERROR;
1035
1036 command_print(CMD, "scan delay: %d nsec", ejtag_info->scan_delay);
1037 if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {
1038 ejtag_info->mode = 0;
1039 command_print(CMD, "running in legacy mode");
1040 } else {
1041 ejtag_info->mode = 1;
1042 command_print(CMD, "running in fast queued mode");
1043 }
1044
1045 return ERROR_OK;
1046 }
1047
1048 static const struct command_registration mips32_exec_command_handlers[] = {
1049 {
1050 .name = "cp0",
1051 .handler = mips32_handle_cp0_command,
1052 .mode = COMMAND_EXEC,
1053 .usage = "regnum select [value]",
1054 .help = "display/modify cp0 register",
1055 },
1056 {
1057 .name = "scan_delay",
1058 .handler = mips32_handle_scan_delay_command,
1059 .mode = COMMAND_ANY,
1060 .help = "display/set scan delay in nano seconds",
1061 .usage = "[value]",
1062 },
1063 COMMAND_REGISTRATION_DONE
1064 };
1065
1066 const struct command_registration mips32_command_handlers[] = {
1067 {
1068 .name = "mips32",
1069 .mode = COMMAND_ANY,
1070 .help = "mips32 command group",
1071 .usage = "",
1072 .chain = mips32_exec_command_handlers,
1073 },
1074 COMMAND_REGISTRATION_DONE
1075 };

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)