1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2008 by Spencer Oliver *
5 * spen@spen-soft.co.uk *
7 * Copyright (C) 2008 by David T.L. Wong *
9 * Copyright (C) 2007,2008 Øyvind Harboe *
10 * oyvind.harboe@zylin.com *
12 * Copyright (C) 2011 by Drasko DRASKOVIC *
13 * drasko.draskovic@gmail.com *
14 ***************************************************************************/
21 #include "breakpoints.h"
22 #include "algorithm.h"
25 static const char *mips_isa_strings
[] = {
26 "MIPS32", "MIPS16", "", "MICRO MIPS32",
29 #define MIPS32_GDB_DUMMY_FP_REG 1
33 * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml
43 { 0, "r0", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
44 { 1, "r1", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
45 { 2, "r2", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
46 { 3, "r3", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
47 { 4, "r4", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
48 { 5, "r5", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
49 { 6, "r6", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
50 { 7, "r7", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
51 { 8, "r8", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
52 { 9, "r9", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
53 { 10, "r10", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
54 { 11, "r11", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
55 { 12, "r12", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
56 { 13, "r13", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
57 { 14, "r14", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
58 { 15, "r15", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
59 { 16, "r16", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
60 { 17, "r17", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
61 { 18, "r18", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
62 { 19, "r19", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
63 { 20, "r20", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
64 { 21, "r21", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
65 { 22, "r22", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
66 { 23, "r23", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
67 { 24, "r24", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
68 { 25, "r25", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
69 { 26, "r26", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
70 { 27, "r27", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
71 { 28, "r28", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
72 { 29, "r29", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
73 { 30, "r30", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
74 { 31, "r31", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
75 { 32, "status", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cp0", 0 },
76 { 33, "lo", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
77 { 34, "hi", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
78 { 35, "badvaddr", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cp0", 0 },
79 { 36, "cause", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cp0", 0 },
80 { 37, "pc", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
82 { 38, "f0", REG_TYPE_IEEE_SINGLE
, NULL
,
83 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
84 { 39, "f1", REG_TYPE_IEEE_SINGLE
, NULL
,
85 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
86 { 40, "f2", REG_TYPE_IEEE_SINGLE
, NULL
,
87 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
88 { 41, "f3", REG_TYPE_IEEE_SINGLE
, NULL
,
89 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
90 { 42, "f4", REG_TYPE_IEEE_SINGLE
, NULL
,
91 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
92 { 43, "f5", REG_TYPE_IEEE_SINGLE
, NULL
,
93 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
94 { 44, "f6", REG_TYPE_IEEE_SINGLE
, NULL
,
95 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
96 { 45, "f7", REG_TYPE_IEEE_SINGLE
, NULL
,
97 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
98 { 46, "f8", REG_TYPE_IEEE_SINGLE
, NULL
,
99 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
100 { 47, "f9", REG_TYPE_IEEE_SINGLE
, NULL
,
101 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
102 { 48, "f10", REG_TYPE_IEEE_SINGLE
, NULL
,
103 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
104 { 49, "f11", REG_TYPE_IEEE_SINGLE
, NULL
,
105 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
106 { 50, "f12", REG_TYPE_IEEE_SINGLE
, NULL
,
107 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
108 { 51, "f13", REG_TYPE_IEEE_SINGLE
, NULL
,
109 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
110 { 52, "f14", REG_TYPE_IEEE_SINGLE
, NULL
,
111 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
112 { 53, "f15", REG_TYPE_IEEE_SINGLE
, NULL
,
113 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
114 { 54, "f16", REG_TYPE_IEEE_SINGLE
, NULL
,
115 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
116 { 55, "f17", REG_TYPE_IEEE_SINGLE
, NULL
,
117 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
118 { 56, "f18", REG_TYPE_IEEE_SINGLE
, NULL
,
119 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
120 { 57, "f19", REG_TYPE_IEEE_SINGLE
, NULL
,
121 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
122 { 58, "f20", REG_TYPE_IEEE_SINGLE
, NULL
,
123 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
124 { 59, "f21", REG_TYPE_IEEE_SINGLE
, NULL
,
125 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
126 { 60, "f22", REG_TYPE_IEEE_SINGLE
, NULL
,
127 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
128 { 61, "f23", REG_TYPE_IEEE_SINGLE
, NULL
,
129 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
130 { 62, "f24", REG_TYPE_IEEE_SINGLE
, NULL
,
131 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
132 { 63, "f25", REG_TYPE_IEEE_SINGLE
, NULL
,
133 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
134 { 64, "f26", REG_TYPE_IEEE_SINGLE
, NULL
,
135 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
136 { 65, "f27", REG_TYPE_IEEE_SINGLE
, NULL
,
137 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
138 { 66, "f28", REG_TYPE_IEEE_SINGLE
, NULL
,
139 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
140 { 67, "f29", REG_TYPE_IEEE_SINGLE
, NULL
,
141 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
142 { 68, "f30", REG_TYPE_IEEE_SINGLE
, NULL
,
143 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
144 { 69, "f31", REG_TYPE_IEEE_SINGLE
, NULL
,
145 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
146 { 70, "fcsr", REG_TYPE_INT
, "float",
147 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
148 { 71, "fir", REG_TYPE_INT
, "float",
149 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
153 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
155 static uint8_t mips32_gdb_dummy_fp_value
[] = {0, 0, 0, 0};
157 static int mips32_get_core_reg(struct reg
*reg
)
160 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
161 struct target
*target
= mips32_reg
->target
;
162 struct mips32_common
*mips32_target
= target_to_mips32(target
);
164 if (target
->state
!= TARGET_HALTED
)
165 return ERROR_TARGET_NOT_HALTED
;
167 retval
= mips32_target
->read_core_reg(target
, mips32_reg
->num
);
172 static int mips32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
174 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
175 struct target
*target
= mips32_reg
->target
;
176 uint32_t value
= buf_get_u32(buf
, 0, 32);
178 if (target
->state
!= TARGET_HALTED
)
179 return ERROR_TARGET_NOT_HALTED
;
181 buf_set_u32(reg
->value
, 0, 32, value
);
188 static int mips32_read_core_reg(struct target
*target
, unsigned int num
)
192 /* get pointers to arch-specific information */
193 struct mips32_common
*mips32
= target_to_mips32(target
);
195 if (num
>= MIPS32_NUM_REGS
)
196 return ERROR_COMMAND_SYNTAX_ERROR
;
198 reg_value
= mips32
->core_regs
[num
];
199 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
200 mips32
->core_cache
->reg_list
[num
].valid
= true;
201 mips32
->core_cache
->reg_list
[num
].dirty
= false;
206 static int mips32_write_core_reg(struct target
*target
, unsigned int num
)
210 /* get pointers to arch-specific information */
211 struct mips32_common
*mips32
= target_to_mips32(target
);
213 if (num
>= MIPS32_NUM_REGS
)
214 return ERROR_COMMAND_SYNTAX_ERROR
;
216 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
217 mips32
->core_regs
[num
] = reg_value
;
218 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
219 mips32
->core_cache
->reg_list
[num
].valid
= true;
220 mips32
->core_cache
->reg_list
[num
].dirty
= false;
225 int mips32_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
226 int *reg_list_size
, enum target_register_class reg_class
)
228 /* get pointers to arch-specific information */
229 struct mips32_common
*mips32
= target_to_mips32(target
);
232 /* include floating point registers */
233 *reg_list_size
= MIPS32_NUM_REGS
;
234 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
236 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++)
237 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
242 int mips32_save_context(struct target
*target
)
246 /* get pointers to arch-specific information */
247 struct mips32_common
*mips32
= target_to_mips32(target
);
248 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
250 /* read core registers */
251 mips32_pracc_read_regs(ejtag_info
, mips32
->core_regs
);
253 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
254 if (!mips32
->core_cache
->reg_list
[i
].valid
)
255 mips32
->read_core_reg(target
, i
);
261 int mips32_restore_context(struct target
*target
)
265 /* get pointers to arch-specific information */
266 struct mips32_common
*mips32
= target_to_mips32(target
);
267 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
269 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
270 if (mips32
->core_cache
->reg_list
[i
].dirty
)
271 mips32
->write_core_reg(target
, i
);
274 /* write core regs */
275 mips32_pracc_write_regs(ejtag_info
, mips32
->core_regs
);
280 int mips32_arch_state(struct target
*target
)
282 struct mips32_common
*mips32
= target_to_mips32(target
);
284 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32
"",
285 mips_isa_strings
[mips32
->isa_mode
],
286 debug_reason_name(target
),
287 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32));
292 static const struct reg_arch_type mips32_reg_type
= {
293 .get
= mips32_get_core_reg
,
294 .set
= mips32_set_core_reg
,
297 struct reg_cache
*mips32_build_reg_cache(struct target
*target
)
299 /* get pointers to arch-specific information */
300 struct mips32_common
*mips32
= target_to_mips32(target
);
302 int num_regs
= MIPS32_NUM_REGS
;
303 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
304 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
305 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
306 struct mips32_core_reg
*arch_info
= malloc(sizeof(struct mips32_core_reg
) * num_regs
);
307 struct reg_feature
*feature
;
310 /* Build the process context cache */
311 cache
->name
= "mips32 registers";
313 cache
->reg_list
= reg_list
;
314 cache
->num_regs
= num_regs
;
316 mips32
->core_cache
= cache
;
318 for (i
= 0; i
< num_regs
; i
++) {
319 arch_info
[i
].num
= mips32_regs
[i
].id
;
320 arch_info
[i
].target
= target
;
321 arch_info
[i
].mips32_common
= mips32
;
323 reg_list
[i
].name
= mips32_regs
[i
].name
;
324 reg_list
[i
].size
= 32;
326 if (mips32_regs
[i
].flag
== MIPS32_GDB_DUMMY_FP_REG
) {
327 reg_list
[i
].value
= mips32_gdb_dummy_fp_value
;
328 reg_list
[i
].valid
= true;
329 reg_list
[i
].arch_info
= NULL
;
330 register_init_dummy(®_list
[i
]);
332 reg_list
[i
].value
= calloc(1, 4);
333 reg_list
[i
].valid
= false;
334 reg_list
[i
].type
= &mips32_reg_type
;
335 reg_list
[i
].arch_info
= &arch_info
[i
];
337 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
338 if (reg_list
[i
].reg_data_type
)
339 reg_list
[i
].reg_data_type
->type
= mips32_regs
[i
].type
;
341 LOG_ERROR("unable to allocate reg type list");
344 reg_list
[i
].dirty
= false;
346 reg_list
[i
].group
= mips32_regs
[i
].group
;
347 reg_list
[i
].number
= i
;
348 reg_list
[i
].exist
= true;
349 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
351 feature
= calloc(1, sizeof(struct reg_feature
));
353 feature
->name
= mips32_regs
[i
].feature
;
354 reg_list
[i
].feature
= feature
;
356 LOG_ERROR("unable to allocate feature list");
362 int mips32_init_arch_info(struct target
*target
, struct mips32_common
*mips32
, struct jtag_tap
*tap
)
364 target
->arch_info
= mips32
;
365 mips32
->common_magic
= MIPS32_COMMON_MAGIC
;
366 mips32
->fast_data_area
= NULL
;
367 mips32
->isa_imp
= MIPS32_ONLY
; /* default */
369 /* has breakpoint/watchpoint unit been scanned */
370 mips32
->bp_scanned
= 0;
371 mips32
->data_break_list
= NULL
;
373 mips32
->ejtag_info
.tap
= tap
;
374 mips32
->read_core_reg
= mips32_read_core_reg
;
375 mips32
->write_core_reg
= mips32_write_core_reg
;
376 /* if unknown endianness defaults to little endian, 1 */
377 mips32
->ejtag_info
.endianness
= target
->endianness
== TARGET_BIG_ENDIAN
? 0 : 1;
378 mips32
->ejtag_info
.scan_delay
= MIPS32_SCAN_DELAY_LEGACY_MODE
;
379 mips32
->ejtag_info
.mode
= 0; /* Initial default value */
380 mips32
->ejtag_info
.isa
= 0; /* isa on debug mips32, updated by poll function */
381 mips32
->ejtag_info
.config_regs
= 0; /* no config register read */
385 /* run to exit point. return error if exit point was not reached. */
386 static int mips32_run_and_wait(struct target
*target
, target_addr_t entry_point
,
387 int timeout_ms
, target_addr_t exit_point
, struct mips32_common
*mips32
)
391 /* This code relies on the target specific resume() and poll()->debug_entry()
392 * sequence to write register values to the processor and the read them back */
393 retval
= target_resume(target
, 0, entry_point
, 0, 1);
394 if (retval
!= ERROR_OK
)
397 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
398 /* If the target fails to halt due to the breakpoint, force a halt */
399 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
400 retval
= target_halt(target
);
401 if (retval
!= ERROR_OK
)
403 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
404 if (retval
!= ERROR_OK
)
406 return ERROR_TARGET_TIMEOUT
;
409 pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32);
410 if (exit_point
&& (pc
!= exit_point
)) {
411 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
412 return ERROR_TARGET_TIMEOUT
;
418 int mips32_run_algorithm(struct target
*target
, int num_mem_params
,
419 struct mem_param
*mem_params
, int num_reg_params
,
420 struct reg_param
*reg_params
, target_addr_t entry_point
,
421 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
423 struct mips32_common
*mips32
= target_to_mips32(target
);
424 struct mips32_algorithm
*mips32_algorithm_info
= arch_info
;
425 enum mips32_isa_mode isa_mode
= mips32
->isa_mode
;
427 uint32_t context
[MIPS32_NUM_REGS
];
428 int retval
= ERROR_OK
;
430 LOG_DEBUG("Running algorithm");
432 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
433 * at the exit point */
435 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
436 LOG_ERROR("current target isn't a MIPS32 target");
437 return ERROR_TARGET_INVALID
;
440 if (target
->state
!= TARGET_HALTED
) {
441 LOG_WARNING("target not halted");
442 return ERROR_TARGET_NOT_HALTED
;
445 /* refresh core register cache */
446 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
447 if (!mips32
->core_cache
->reg_list
[i
].valid
)
448 mips32
->read_core_reg(target
, i
);
449 context
[i
] = buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
452 for (int i
= 0; i
< num_mem_params
; i
++) {
453 if (mem_params
[i
].direction
== PARAM_IN
)
455 retval
= target_write_buffer(target
, mem_params
[i
].address
,
456 mem_params
[i
].size
, mem_params
[i
].value
);
457 if (retval
!= ERROR_OK
)
461 for (int i
= 0; i
< num_reg_params
; i
++) {
462 if (reg_params
[i
].direction
== PARAM_IN
)
465 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
468 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
469 return ERROR_COMMAND_SYNTAX_ERROR
;
472 if (reg
->size
!= reg_params
[i
].size
) {
473 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
474 reg_params
[i
].reg_name
);
475 return ERROR_COMMAND_SYNTAX_ERROR
;
478 mips32_set_core_reg(reg
, reg_params
[i
].value
);
481 mips32
->isa_mode
= mips32_algorithm_info
->isa_mode
;
483 retval
= mips32_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, mips32
);
485 if (retval
!= ERROR_OK
)
488 for (int i
= 0; i
< num_mem_params
; i
++) {
489 if (mem_params
[i
].direction
!= PARAM_OUT
) {
490 retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
,
491 mem_params
[i
].value
);
492 if (retval
!= ERROR_OK
)
497 for (int i
= 0; i
< num_reg_params
; i
++) {
498 if (reg_params
[i
].direction
!= PARAM_OUT
) {
499 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
501 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
502 return ERROR_COMMAND_SYNTAX_ERROR
;
505 if (reg
->size
!= reg_params
[i
].size
) {
506 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
507 reg_params
[i
].reg_name
);
508 return ERROR_COMMAND_SYNTAX_ERROR
;
511 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
515 /* restore everything we saved before */
516 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
518 regvalue
= buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
519 if (regvalue
!= context
[i
]) {
520 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
521 mips32
->core_cache
->reg_list
[i
].name
, context
[i
]);
522 buf_set_u32(mips32
->core_cache
->reg_list
[i
].value
,
524 mips32
->core_cache
->reg_list
[i
].valid
= true;
525 mips32
->core_cache
->reg_list
[i
].dirty
= true;
529 mips32
->isa_mode
= isa_mode
;
534 int mips32_examine(struct target
*target
)
536 struct mips32_common
*mips32
= target_to_mips32(target
);
538 if (!target_was_examined(target
)) {
539 target_set_examined(target
);
541 /* we will configure later */
542 mips32
->bp_scanned
= 0;
543 mips32
->num_inst_bpoints
= 0;
544 mips32
->num_data_bpoints
= 0;
545 mips32
->num_inst_bpoints_avail
= 0;
546 mips32
->num_data_bpoints_avail
= 0;
552 static int mips32_configure_ibs(struct target
*target
)
554 struct mips32_common
*mips32
= target_to_mips32(target
);
555 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
559 /* get number of inst breakpoints */
560 retval
= target_read_u32(target
, ejtag_info
->ejtag_ibs_addr
, &bpinfo
);
561 if (retval
!= ERROR_OK
)
564 mips32
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
565 mips32
->num_inst_bpoints_avail
= mips32
->num_inst_bpoints
;
566 mips32
->inst_break_list
= calloc(mips32
->num_inst_bpoints
,
567 sizeof(struct mips32_comparator
));
569 for (i
= 0; i
< mips32
->num_inst_bpoints
; i
++)
570 mips32
->inst_break_list
[i
].reg_address
=
571 ejtag_info
->ejtag_iba0_addr
+
572 (ejtag_info
->ejtag_iba_step_size
* i
);
575 retval
= target_write_u32(target
, ejtag_info
->ejtag_ibs_addr
, 0);
579 static int mips32_configure_dbs(struct target
*target
)
581 struct mips32_common
*mips32
= target_to_mips32(target
);
582 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
586 /* get number of data breakpoints */
587 retval
= target_read_u32(target
, ejtag_info
->ejtag_dbs_addr
, &bpinfo
);
588 if (retval
!= ERROR_OK
)
591 mips32
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
592 mips32
->num_data_bpoints_avail
= mips32
->num_data_bpoints
;
593 mips32
->data_break_list
= calloc(mips32
->num_data_bpoints
,
594 sizeof(struct mips32_comparator
));
596 for (i
= 0; i
< mips32
->num_data_bpoints
; i
++)
597 mips32
->data_break_list
[i
].reg_address
=
598 ejtag_info
->ejtag_dba0_addr
+
599 (ejtag_info
->ejtag_dba_step_size
* i
);
602 retval
= target_write_u32(target
, ejtag_info
->ejtag_dbs_addr
, 0);
606 int mips32_configure_break_unit(struct target
*target
)
608 /* get pointers to arch-specific information */
609 struct mips32_common
*mips32
= target_to_mips32(target
);
610 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
614 if (mips32
->bp_scanned
)
617 /* get info about breakpoint support */
618 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
619 if (retval
!= ERROR_OK
)
622 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
623 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
624 ejtag_info
->debug_caps
= dcr
& EJTAG_DCR_ENM
;
625 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NOIB
))
626 ejtag_info
->debug_caps
|= EJTAG_DCR_IB
;
627 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NODB
))
628 ejtag_info
->debug_caps
|= EJTAG_DCR_DB
;
630 /* keep debug caps for later use */
631 ejtag_info
->debug_caps
= dcr
& (EJTAG_DCR_ENM
632 | EJTAG_DCR_IB
| EJTAG_DCR_DB
);
635 if (ejtag_info
->debug_caps
& EJTAG_DCR_IB
) {
636 retval
= mips32_configure_ibs(target
);
637 if (retval
!= ERROR_OK
)
641 if (ejtag_info
->debug_caps
& EJTAG_DCR_DB
) {
642 retval
= mips32_configure_dbs(target
);
643 if (retval
!= ERROR_OK
)
647 /* check if target endianness settings matches debug control register */
648 if (((ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
649 && (target
->endianness
== TARGET_LITTLE_ENDIAN
)) ||
650 (!(ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
651 && (target
->endianness
== TARGET_BIG_ENDIAN
)))
652 LOG_WARNING("DCR endianness settings does not match target settings");
654 LOG_DEBUG("DCR 0x%" PRIx32
" numinst %i numdata %i", dcr
, mips32
->num_inst_bpoints
,
655 mips32
->num_data_bpoints
);
657 mips32
->bp_scanned
= 1;
662 int mips32_enable_interrupts(struct target
*target
, int enable
)
668 /* read debug control register */
669 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
670 if (retval
!= ERROR_OK
)
674 if (!(dcr
& EJTAG_DCR_INTE
)) {
675 /* enable interrupts */
676 dcr
|= EJTAG_DCR_INTE
;
680 if (dcr
& EJTAG_DCR_INTE
) {
681 /* disable interrupts */
682 dcr
&= ~EJTAG_DCR_INTE
;
688 retval
= target_write_u32(target
, EJTAG_DCR
, dcr
);
689 if (retval
!= ERROR_OK
)
696 /* read config to config3 cp0 registers and log isa implementation */
697 int mips32_read_config_regs(struct target
*target
)
699 struct mips32_common
*mips32
= target_to_mips32(target
);
700 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
702 if (ejtag_info
->config_regs
== 0)
703 for (int i
= 0; i
!= 4; i
++) {
704 int retval
= mips32_cp0_read(ejtag_info
, &ejtag_info
->config
[i
], 16, i
);
705 if (retval
!= ERROR_OK
) {
706 LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32
, i
);
707 ejtag_info
->config_regs
= 0;
710 ejtag_info
->config_regs
= i
+ 1;
711 if ((ejtag_info
->config
[i
] & (1 << 31)) == 0)
712 break; /* no more config registers implemented */
715 return ERROR_OK
; /* already successfully read */
717 LOG_DEBUG("read %"PRIu32
" config registers", ejtag_info
->config_regs
);
719 if (ejtag_info
->impcode
& EJTAG_IMP_MIPS16
) {
720 mips32
->isa_imp
= MIPS32_MIPS16
;
721 LOG_USER("MIPS32 with MIPS16 support implemented");
723 } else if (ejtag_info
->config_regs
>= 4) { /* config3 implemented */
724 unsigned isa_imp
= (ejtag_info
->config
[3] & MIPS32_CONFIG3_ISA_MASK
) >> MIPS32_CONFIG3_ISA_SHIFT
;
726 mips32
->isa_imp
= MMIPS32_ONLY
;
727 LOG_USER("MICRO MIPS32 only implemented");
729 } else if (isa_imp
!= 0) {
730 mips32
->isa_imp
= MIPS32_MMIPS32
;
731 LOG_USER("MIPS32 and MICRO MIPS32 implemented");
735 if (mips32
->isa_imp
== MIPS32_ONLY
) /* initial default value */
736 LOG_USER("MIPS32 only implemented");
740 int mips32_checksum_memory(struct target
*target
, target_addr_t address
,
741 uint32_t count
, uint32_t *checksum
)
743 struct working_area
*crc_algorithm
;
744 struct reg_param reg_params
[2];
745 struct mips32_algorithm mips32_info
;
747 struct mips32_common
*mips32
= target_to_mips32(target
);
748 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
750 /* see contrib/loaders/checksum/mips32.s for src */
751 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
753 uint32_t mips_crc_code
[] = {
754 MIPS32_ADDIU(isa
, 12, 4, 0), /* addiu $t4, $a0, 0 */
755 MIPS32_ADDIU(isa
, 10, 5, 0), /* addiu $t2, $a1, 0 */
756 MIPS32_ADDIU(isa
, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
757 MIPS32_BEQ(isa
, 0, 0, 0x10 << isa
), /* beq $zero, $zero, ncomp */
758 MIPS32_ADDIU(isa
, 11, 0, 0), /* addiu $t3, $zero, 0 */
760 MIPS32_LB(isa
, 5, 0, 12), /* lb $a1, ($t4) */
761 MIPS32_ADDI(isa
, 12, 12, 1), /* addi $t4, $t4, 1 */
762 MIPS32_SLL(isa
, 5, 5, 24), /* sll $a1, $a1, 24 */
763 MIPS32_LUI(isa
, 2, 0x04c1), /* lui $v0, 0x04c1 */
764 MIPS32_XOR(isa
, 4, 4, 5), /* xor $a0, $a0, $a1 */
765 MIPS32_ORI(isa
, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
766 MIPS32_ADDU(isa
, 6, 0, 0), /* addu $a2, $zero, $zero */
768 MIPS32_SLL(isa
, 8, 4, 1), /* sll $t0, $a0, 1 */
769 MIPS32_ADDIU(isa
, 6, 6, 1), /* addiu $a2, $a2, 1 */
770 MIPS32_SLTI(isa
, 4, 4, 0), /* slti $a0, $a0, 0 */
771 MIPS32_XOR(isa
, 9, 8, 7), /* xor $t1, $t0, $a3 */
772 MIPS32_MOVN(isa
, 8, 9, 4), /* movn $t0, $t1, $a0 */
773 MIPS32_SLTI(isa
, 3, 6, 8), /* slti $v1, $a2, 8 */
774 MIPS32_BNE(isa
, 3, 0, NEG16(7 << isa
)), /* bne $v1, $zero, loop */
775 MIPS32_ADDU(isa
, 4, 8, 0), /* addu $a0, $t0, $zero */
777 MIPS32_BNE(isa
, 10, 11, NEG16(16 << isa
)), /* bne $t2, $t3, nbyte */
778 MIPS32_ADDIU(isa
, 11, 11, 1), /* addiu $t3, $t3, 1 */
782 /* make sure we have a working area */
783 if (target_alloc_working_area(target
, sizeof(mips_crc_code
), &crc_algorithm
) != ERROR_OK
)
784 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
786 pracc_swap16_array(ejtag_info
, mips_crc_code
, ARRAY_SIZE(mips_crc_code
));
788 /* convert mips crc code into a buffer in target endianness */
789 uint8_t mips_crc_code_8
[sizeof(mips_crc_code
)];
790 target_buffer_set_u32_array(target
, mips_crc_code_8
,
791 ARRAY_SIZE(mips_crc_code
), mips_crc_code
);
793 int retval
= target_write_buffer(target
, crc_algorithm
->address
, sizeof(mips_crc_code
), mips_crc_code_8
);
794 if (retval
!= ERROR_OK
)
797 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
798 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
; /* run isa as in debug mode */
800 init_reg_param(®_params
[0], "r4", 32, PARAM_IN_OUT
);
801 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
803 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
804 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
806 int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
808 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
, crc_algorithm
->address
,
809 crc_algorithm
->address
+ (sizeof(mips_crc_code
) - 4), timeout
, &mips32_info
);
811 if (retval
== ERROR_OK
)
812 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
814 destroy_reg_param(®_params
[0]);
815 destroy_reg_param(®_params
[1]);
817 target_free_working_area(target
, crc_algorithm
);
822 /** Checks whether a memory region is erased. */
823 int mips32_blank_check_memory(struct target
*target
,
824 struct target_memory_check_block
*blocks
, int num_blocks
,
825 uint8_t erased_value
)
827 struct working_area
*erase_check_algorithm
;
828 struct reg_param reg_params
[3];
829 struct mips32_algorithm mips32_info
;
831 struct mips32_common
*mips32
= target_to_mips32(target
);
832 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
834 if (erased_value
!= 0xff) {
835 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for MIPS32",
839 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
840 uint32_t erase_check_code
[] = {
842 MIPS32_LB(isa
, 8, 0, 4), /* lb $t0, ($a0) */
843 MIPS32_AND(isa
, 6, 6, 8), /* and $a2, $a2, $t0 */
844 MIPS32_ADDIU(isa
, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
845 MIPS32_BNE(isa
, 5, 0, NEG16(4 << isa
)), /* bne $a1, $zero, nbyte */
846 MIPS32_ADDIU(isa
, 4, 4, 1), /* addiu $a0, $a0, 1 */
847 MIPS32_SDBBP(isa
) /* sdbbp */
850 /* make sure we have a working area */
851 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
852 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
854 pracc_swap16_array(ejtag_info
, erase_check_code
, ARRAY_SIZE(erase_check_code
));
856 /* convert erase check code into a buffer in target endianness */
857 uint8_t erase_check_code_8
[sizeof(erase_check_code
)];
858 target_buffer_set_u32_array(target
, erase_check_code_8
,
859 ARRAY_SIZE(erase_check_code
), erase_check_code
);
861 int retval
= target_write_buffer(target
, erase_check_algorithm
->address
,
862 sizeof(erase_check_code
), erase_check_code_8
);
863 if (retval
!= ERROR_OK
)
866 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
867 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
;
869 init_reg_param(®_params
[0], "r4", 32, PARAM_OUT
);
870 buf_set_u32(reg_params
[0].value
, 0, 32, blocks
[0].address
);
872 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
873 buf_set_u32(reg_params
[1].value
, 0, 32, blocks
[0].size
);
875 init_reg_param(®_params
[2], "r6", 32, PARAM_IN_OUT
);
876 buf_set_u32(reg_params
[2].value
, 0, 32, erased_value
);
878 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
, erase_check_algorithm
->address
,
879 erase_check_algorithm
->address
+ (sizeof(erase_check_code
) - 4), 10000, &mips32_info
);
881 if (retval
== ERROR_OK
)
882 blocks
[0].result
= buf_get_u32(reg_params
[2].value
, 0, 32);
884 destroy_reg_param(®_params
[0]);
885 destroy_reg_param(®_params
[1]);
886 destroy_reg_param(®_params
[2]);
889 target_free_working_area(target
, erase_check_algorithm
);
891 if (retval
!= ERROR_OK
)
894 return 1; /* only one block has been checked */
897 static int mips32_verify_pointer(struct command_invocation
*cmd
,
898 struct mips32_common
*mips32
)
900 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
901 command_print(cmd
, "target is not an MIPS32");
902 return ERROR_TARGET_INVALID
;
908 * MIPS32 targets expose command interface
909 * to manipulate CP0 registers
911 COMMAND_HANDLER(mips32_handle_cp0_command
)
914 struct target
*target
= get_current_target(CMD_CTX
);
915 struct mips32_common
*mips32
= target_to_mips32(target
);
916 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
919 retval
= mips32_verify_pointer(CMD
, mips32
);
920 if (retval
!= ERROR_OK
)
923 if (target
->state
!= TARGET_HALTED
) {
924 command_print(CMD
, "target must be stopped for \"%s\" command", CMD_NAME
);
928 /* two or more argument, access a single register/select (write if third argument is given) */
930 return ERROR_COMMAND_SYNTAX_ERROR
;
932 uint32_t cp0_reg
, cp0_sel
;
933 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
934 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
939 retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
940 if (retval
!= ERROR_OK
) {
942 "couldn't access reg %" PRIu32
,
946 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
947 cp0_reg
, cp0_sel
, value
);
949 } else if (CMD_ARGC
== 3) {
951 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
952 retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
953 if (retval
!= ERROR_OK
) {
955 "couldn't access cp0 reg %" PRIu32
", select %" PRIu32
,
959 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
960 cp0_reg
, cp0_sel
, value
);
967 COMMAND_HANDLER(mips32_handle_scan_delay_command
)
969 struct target
*target
= get_current_target(CMD_CTX
);
970 struct mips32_common
*mips32
= target_to_mips32(target
);
971 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
974 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], ejtag_info
->scan_delay
);
975 else if (CMD_ARGC
> 1)
976 return ERROR_COMMAND_SYNTAX_ERROR
;
978 command_print(CMD
, "scan delay: %d nsec", ejtag_info
->scan_delay
);
979 if (ejtag_info
->scan_delay
>= MIPS32_SCAN_DELAY_LEGACY_MODE
) {
980 ejtag_info
->mode
= 0;
981 command_print(CMD
, "running in legacy mode");
983 ejtag_info
->mode
= 1;
984 command_print(CMD
, "running in fast queued mode");
990 static const struct command_registration mips32_exec_command_handlers
[] = {
993 .handler
= mips32_handle_cp0_command
,
994 .mode
= COMMAND_EXEC
,
995 .usage
= "regnum select [value]",
996 .help
= "display/modify cp0 register",
999 .name
= "scan_delay",
1000 .handler
= mips32_handle_scan_delay_command
,
1001 .mode
= COMMAND_ANY
,
1002 .help
= "display/set scan delay in nano seconds",
1005 COMMAND_REGISTRATION_DONE
1008 const struct command_registration mips32_command_handlers
[] = {
1011 .mode
= COMMAND_ANY
,
1012 .help
= "mips32 command group",
1014 .chain
= mips32_exec_command_handlers
,
1016 COMMAND_REGISTRATION_DONE
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)