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 unsigned 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
, unsigned 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_TARGET_ERROR(target
, "not halted (run target algo)");
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 unsigned 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
, "Error: target must be stopped for \"%s\" command", CMD_NAME
);
925 return ERROR_TARGET_NOT_HALTED
;
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