1 /***************************************************************************
2 * Copyright (C) 2008 by Spencer Oliver *
3 * spen@spen-soft.co.uk *
5 * Copyright (C) 2008 by David T.L. Wong *
7 * Copyright (C) 2007,2008 Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
10 * Copyright (C) 2011 by Drasko DRASKOVIC *
11 * drasko.draskovic@gmail.com *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
25 ***************************************************************************/
32 #include "breakpoints.h"
33 #include "algorithm.h"
36 static const char *mips_isa_strings
[] = {
37 "MIPS32", "MIPS16", "", "MICRO MIPS32",
40 #define MIPS32_GDB_DUMMY_FP_REG 1
44 * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml
54 { 0, "r0", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
55 { 1, "r1", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
56 { 2, "r2", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
57 { 3, "r3", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
58 { 4, "r4", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
59 { 5, "r5", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
60 { 6, "r6", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
61 { 7, "r7", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
62 { 8, "r8", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
63 { 9, "r9", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
64 { 10, "r10", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
65 { 11, "r11", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
66 { 12, "r12", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
67 { 13, "r13", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
68 { 14, "r14", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
69 { 15, "r15", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
70 { 16, "r16", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
71 { 17, "r17", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
72 { 18, "r18", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
73 { 19, "r19", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
74 { 20, "r20", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
75 { 21, "r21", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
76 { 22, "r22", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
77 { 23, "r23", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
78 { 24, "r24", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
79 { 25, "r25", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
80 { 26, "r26", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
81 { 27, "r27", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
82 { 28, "r28", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
83 { 29, "r29", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
84 { 30, "r30", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
85 { 31, "r31", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
86 { 32, "status", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cp0", 0 },
87 { 33, "lo", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
88 { 34, "hi", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
89 { 35, "badvaddr", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cp0", 0 },
90 { 36, "cause", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cp0", 0 },
91 { 37, "pc", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
93 { 38, "f0", REG_TYPE_IEEE_SINGLE
, NULL
,
94 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
95 { 39, "f1", REG_TYPE_IEEE_SINGLE
, NULL
,
96 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
97 { 40, "f2", REG_TYPE_IEEE_SINGLE
, NULL
,
98 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
99 { 41, "f3", REG_TYPE_IEEE_SINGLE
, NULL
,
100 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
101 { 42, "f4", REG_TYPE_IEEE_SINGLE
, NULL
,
102 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
103 { 43, "f5", REG_TYPE_IEEE_SINGLE
, NULL
,
104 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
105 { 44, "f6", REG_TYPE_IEEE_SINGLE
, NULL
,
106 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
107 { 45, "f7", REG_TYPE_IEEE_SINGLE
, NULL
,
108 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
109 { 46, "f8", REG_TYPE_IEEE_SINGLE
, NULL
,
110 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
111 { 47, "f9", REG_TYPE_IEEE_SINGLE
, NULL
,
112 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
113 { 48, "f10", REG_TYPE_IEEE_SINGLE
, NULL
,
114 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
115 { 49, "f11", REG_TYPE_IEEE_SINGLE
, NULL
,
116 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
117 { 50, "f12", REG_TYPE_IEEE_SINGLE
, NULL
,
118 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
119 { 51, "f13", REG_TYPE_IEEE_SINGLE
, NULL
,
120 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
121 { 52, "f14", REG_TYPE_IEEE_SINGLE
, NULL
,
122 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
123 { 53, "f15", REG_TYPE_IEEE_SINGLE
, NULL
,
124 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
125 { 54, "f16", REG_TYPE_IEEE_SINGLE
, NULL
,
126 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
127 { 55, "f17", REG_TYPE_IEEE_SINGLE
, NULL
,
128 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
129 { 56, "f18", REG_TYPE_IEEE_SINGLE
, NULL
,
130 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
131 { 57, "f19", REG_TYPE_IEEE_SINGLE
, NULL
,
132 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
133 { 58, "f20", REG_TYPE_IEEE_SINGLE
, NULL
,
134 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
135 { 59, "f21", REG_TYPE_IEEE_SINGLE
, NULL
,
136 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
137 { 60, "f22", REG_TYPE_IEEE_SINGLE
, NULL
,
138 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
139 { 61, "f23", REG_TYPE_IEEE_SINGLE
, NULL
,
140 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
141 { 62, "f24", REG_TYPE_IEEE_SINGLE
, NULL
,
142 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
143 { 63, "f25", REG_TYPE_IEEE_SINGLE
, NULL
,
144 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
145 { 64, "f26", REG_TYPE_IEEE_SINGLE
, NULL
,
146 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
147 { 65, "f27", REG_TYPE_IEEE_SINGLE
, NULL
,
148 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
149 { 66, "f28", REG_TYPE_IEEE_SINGLE
, NULL
,
150 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
151 { 67, "f29", REG_TYPE_IEEE_SINGLE
, NULL
,
152 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
153 { 68, "f30", REG_TYPE_IEEE_SINGLE
, NULL
,
154 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
155 { 69, "f31", REG_TYPE_IEEE_SINGLE
, NULL
,
156 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
157 { 70, "fcsr", REG_TYPE_INT
, "float",
158 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
159 { 71, "fir", REG_TYPE_INT
, "float",
160 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG
},
164 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
166 static uint8_t mips32_gdb_dummy_fp_value
[] = {0, 0, 0, 0};
168 static int mips32_get_core_reg(struct reg
*reg
)
171 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
172 struct target
*target
= mips32_reg
->target
;
173 struct mips32_common
*mips32_target
= target_to_mips32(target
);
175 if (target
->state
!= TARGET_HALTED
)
176 return ERROR_TARGET_NOT_HALTED
;
178 retval
= mips32_target
->read_core_reg(target
, mips32_reg
->num
);
183 static int mips32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
185 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
186 struct target
*target
= mips32_reg
->target
;
187 uint32_t value
= buf_get_u32(buf
, 0, 32);
189 if (target
->state
!= TARGET_HALTED
)
190 return ERROR_TARGET_NOT_HALTED
;
192 buf_set_u32(reg
->value
, 0, 32, value
);
199 static int mips32_read_core_reg(struct target
*target
, unsigned int num
)
203 /* get pointers to arch-specific information */
204 struct mips32_common
*mips32
= target_to_mips32(target
);
206 if (num
>= MIPS32_NUM_REGS
)
207 return ERROR_COMMAND_SYNTAX_ERROR
;
209 reg_value
= mips32
->core_regs
[num
];
210 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
211 mips32
->core_cache
->reg_list
[num
].valid
= 1;
212 mips32
->core_cache
->reg_list
[num
].dirty
= 0;
217 static int mips32_write_core_reg(struct target
*target
, unsigned int num
)
221 /* get pointers to arch-specific information */
222 struct mips32_common
*mips32
= target_to_mips32(target
);
224 if (num
>= MIPS32_NUM_REGS
)
225 return ERROR_COMMAND_SYNTAX_ERROR
;
227 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
228 mips32
->core_regs
[num
] = reg_value
;
229 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
230 mips32
->core_cache
->reg_list
[num
].valid
= 1;
231 mips32
->core_cache
->reg_list
[num
].dirty
= 0;
236 int mips32_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
237 int *reg_list_size
, enum target_register_class reg_class
)
239 /* get pointers to arch-specific information */
240 struct mips32_common
*mips32
= target_to_mips32(target
);
243 /* include floating point registers */
244 *reg_list_size
= MIPS32_NUM_REGS
;
245 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
247 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++)
248 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
253 int mips32_save_context(struct target
*target
)
257 /* get pointers to arch-specific information */
258 struct mips32_common
*mips32
= target_to_mips32(target
);
259 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
261 /* read core registers */
262 mips32_pracc_read_regs(ejtag_info
, mips32
->core_regs
);
264 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
265 if (!mips32
->core_cache
->reg_list
[i
].valid
)
266 mips32
->read_core_reg(target
, i
);
272 int mips32_restore_context(struct target
*target
)
276 /* get pointers to arch-specific information */
277 struct mips32_common
*mips32
= target_to_mips32(target
);
278 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
280 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
281 if (mips32
->core_cache
->reg_list
[i
].dirty
)
282 mips32
->write_core_reg(target
, i
);
285 /* write core regs */
286 mips32_pracc_write_regs(ejtag_info
, mips32
->core_regs
);
291 int mips32_arch_state(struct target
*target
)
293 struct mips32_common
*mips32
= target_to_mips32(target
);
295 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32
"",
296 mips_isa_strings
[mips32
->isa_mode
],
297 debug_reason_name(target
),
298 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32));
303 static const struct reg_arch_type mips32_reg_type
= {
304 .get
= mips32_get_core_reg
,
305 .set
= mips32_set_core_reg
,
308 struct reg_cache
*mips32_build_reg_cache(struct target
*target
)
310 /* get pointers to arch-specific information */
311 struct mips32_common
*mips32
= target_to_mips32(target
);
313 int num_regs
= MIPS32_NUM_REGS
;
314 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
315 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
316 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
317 struct mips32_core_reg
*arch_info
= malloc(sizeof(struct mips32_core_reg
) * num_regs
);
318 struct reg_feature
*feature
;
321 /* Build the process context cache */
322 cache
->name
= "mips32 registers";
324 cache
->reg_list
= reg_list
;
325 cache
->num_regs
= num_regs
;
327 mips32
->core_cache
= cache
;
329 for (i
= 0; i
< num_regs
; i
++) {
330 arch_info
[i
].num
= mips32_regs
[i
].id
;
331 arch_info
[i
].target
= target
;
332 arch_info
[i
].mips32_common
= mips32
;
334 reg_list
[i
].name
= mips32_regs
[i
].name
;
335 reg_list
[i
].size
= 32;
337 if (mips32_regs
[i
].flag
== MIPS32_GDB_DUMMY_FP_REG
) {
338 reg_list
[i
].value
= mips32_gdb_dummy_fp_value
;
339 reg_list
[i
].valid
= 1;
340 reg_list
[i
].arch_info
= NULL
;
341 register_init_dummy(®_list
[i
]);
343 reg_list
[i
].value
= calloc(1, 4);
344 reg_list
[i
].valid
= 0;
345 reg_list
[i
].type
= &mips32_reg_type
;
346 reg_list
[i
].arch_info
= &arch_info
[i
];
348 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
349 if (reg_list
[i
].reg_data_type
)
350 reg_list
[i
].reg_data_type
->type
= mips32_regs
[i
].type
;
352 LOG_ERROR("unable to allocate reg type list");
355 reg_list
[i
].dirty
= 0;
357 reg_list
[i
].group
= mips32_regs
[i
].group
;
358 reg_list
[i
].number
= i
;
359 reg_list
[i
].exist
= true;
360 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
362 feature
= calloc(1, sizeof(struct reg_feature
));
364 feature
->name
= mips32_regs
[i
].feature
;
365 reg_list
[i
].feature
= feature
;
367 LOG_ERROR("unable to allocate feature list");
373 int mips32_init_arch_info(struct target
*target
, struct mips32_common
*mips32
, struct jtag_tap
*tap
)
375 target
->arch_info
= mips32
;
376 mips32
->common_magic
= MIPS32_COMMON_MAGIC
;
377 mips32
->fast_data_area
= NULL
;
378 mips32
->isa_imp
= MIPS32_ONLY
; /* default */
380 /* has breakpoint/watchpoint unit been scanned */
381 mips32
->bp_scanned
= 0;
382 mips32
->data_break_list
= NULL
;
384 mips32
->ejtag_info
.tap
= tap
;
385 mips32
->read_core_reg
= mips32_read_core_reg
;
386 mips32
->write_core_reg
= mips32_write_core_reg
;
387 /* if unknown endianness defaults to little endian, 1 */
388 mips32
->ejtag_info
.endianness
= target
->endianness
== TARGET_BIG_ENDIAN
? 0 : 1;
389 mips32
->ejtag_info
.scan_delay
= MIPS32_SCAN_DELAY_LEGACY_MODE
;
390 mips32
->ejtag_info
.mode
= 0; /* Initial default value */
391 mips32
->ejtag_info
.isa
= 0; /* isa on debug mips32, updated by poll function */
392 mips32
->ejtag_info
.config_regs
= 0; /* no config register read */
396 /* run to exit point. return error if exit point was not reached. */
397 static int mips32_run_and_wait(struct target
*target
, target_addr_t entry_point
,
398 int timeout_ms
, target_addr_t exit_point
, struct mips32_common
*mips32
)
402 /* This code relies on the target specific resume() and poll()->debug_entry()
403 * sequence to write register values to the processor and the read them back */
404 retval
= target_resume(target
, 0, entry_point
, 0, 1);
405 if (retval
!= ERROR_OK
)
408 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
409 /* If the target fails to halt due to the breakpoint, force a halt */
410 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
411 retval
= target_halt(target
);
412 if (retval
!= ERROR_OK
)
414 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
415 if (retval
!= ERROR_OK
)
417 return ERROR_TARGET_TIMEOUT
;
420 pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32);
421 if (exit_point
&& (pc
!= exit_point
)) {
422 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
423 return ERROR_TARGET_TIMEOUT
;
429 int mips32_run_algorithm(struct target
*target
, int num_mem_params
,
430 struct mem_param
*mem_params
, int num_reg_params
,
431 struct reg_param
*reg_params
, target_addr_t entry_point
,
432 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
434 struct mips32_common
*mips32
= target_to_mips32(target
);
435 struct mips32_algorithm
*mips32_algorithm_info
= arch_info
;
436 enum mips32_isa_mode isa_mode
= mips32
->isa_mode
;
438 uint32_t context
[MIPS32_NUM_REGS
];
439 int retval
= ERROR_OK
;
441 LOG_DEBUG("Running algorithm");
443 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
444 * at the exit point */
446 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
447 LOG_ERROR("current target isn't a MIPS32 target");
448 return ERROR_TARGET_INVALID
;
451 if (target
->state
!= TARGET_HALTED
) {
452 LOG_WARNING("target not halted");
453 return ERROR_TARGET_NOT_HALTED
;
456 /* refresh core register cache */
457 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
458 if (!mips32
->core_cache
->reg_list
[i
].valid
)
459 mips32
->read_core_reg(target
, i
);
460 context
[i
] = buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
463 for (int i
= 0; i
< num_mem_params
; i
++) {
464 retval
= target_write_buffer(target
, mem_params
[i
].address
,
465 mem_params
[i
].size
, mem_params
[i
].value
);
466 if (retval
!= ERROR_OK
)
470 for (int i
= 0; i
< num_reg_params
; i
++) {
471 if (reg_params
[i
].direction
== PARAM_IN
)
474 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, 0);
477 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
478 return ERROR_COMMAND_SYNTAX_ERROR
;
481 if (reg
->size
!= reg_params
[i
].size
) {
482 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
483 reg_params
[i
].reg_name
);
484 return ERROR_COMMAND_SYNTAX_ERROR
;
487 mips32_set_core_reg(reg
, reg_params
[i
].value
);
490 mips32
->isa_mode
= mips32_algorithm_info
->isa_mode
;
492 retval
= mips32_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, mips32
);
494 if (retval
!= ERROR_OK
)
497 for (int i
= 0; i
< num_mem_params
; i
++) {
498 if (mem_params
[i
].direction
!= PARAM_OUT
) {
499 retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
,
500 mem_params
[i
].value
);
501 if (retval
!= ERROR_OK
)
506 for (int i
= 0; i
< num_reg_params
; i
++) {
507 if (reg_params
[i
].direction
!= PARAM_OUT
) {
508 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, 0);
510 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
511 return ERROR_COMMAND_SYNTAX_ERROR
;
514 if (reg
->size
!= reg_params
[i
].size
) {
515 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
516 reg_params
[i
].reg_name
);
517 return ERROR_COMMAND_SYNTAX_ERROR
;
520 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
524 /* restore everything we saved before */
525 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
527 regvalue
= buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
528 if (regvalue
!= context
[i
]) {
529 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
530 mips32
->core_cache
->reg_list
[i
].name
, context
[i
]);
531 buf_set_u32(mips32
->core_cache
->reg_list
[i
].value
,
533 mips32
->core_cache
->reg_list
[i
].valid
= 1;
534 mips32
->core_cache
->reg_list
[i
].dirty
= 1;
538 mips32
->isa_mode
= isa_mode
;
543 int mips32_examine(struct target
*target
)
545 struct mips32_common
*mips32
= target_to_mips32(target
);
547 if (!target_was_examined(target
)) {
548 target_set_examined(target
);
550 /* we will configure later */
551 mips32
->bp_scanned
= 0;
552 mips32
->num_inst_bpoints
= 0;
553 mips32
->num_data_bpoints
= 0;
554 mips32
->num_inst_bpoints_avail
= 0;
555 mips32
->num_data_bpoints_avail
= 0;
561 static int mips32_configure_ibs(struct target
*target
)
563 struct mips32_common
*mips32
= target_to_mips32(target
);
564 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
568 /* get number of inst breakpoints */
569 retval
= target_read_u32(target
, ejtag_info
->ejtag_ibs_addr
, &bpinfo
);
570 if (retval
!= ERROR_OK
)
573 mips32
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
574 mips32
->num_inst_bpoints_avail
= mips32
->num_inst_bpoints
;
575 mips32
->inst_break_list
= calloc(mips32
->num_inst_bpoints
,
576 sizeof(struct mips32_comparator
));
578 for (i
= 0; i
< mips32
->num_inst_bpoints
; i
++)
579 mips32
->inst_break_list
[i
].reg_address
=
580 ejtag_info
->ejtag_iba0_addr
+
581 (ejtag_info
->ejtag_iba_step_size
* i
);
584 retval
= target_write_u32(target
, ejtag_info
->ejtag_ibs_addr
, 0);
588 static int mips32_configure_dbs(struct target
*target
)
590 struct mips32_common
*mips32
= target_to_mips32(target
);
591 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
595 /* get number of data breakpoints */
596 retval
= target_read_u32(target
, ejtag_info
->ejtag_dbs_addr
, &bpinfo
);
597 if (retval
!= ERROR_OK
)
600 mips32
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
601 mips32
->num_data_bpoints_avail
= mips32
->num_data_bpoints
;
602 mips32
->data_break_list
= calloc(mips32
->num_data_bpoints
,
603 sizeof(struct mips32_comparator
));
605 for (i
= 0; i
< mips32
->num_data_bpoints
; i
++)
606 mips32
->data_break_list
[i
].reg_address
=
607 ejtag_info
->ejtag_dba0_addr
+
608 (ejtag_info
->ejtag_dba_step_size
* i
);
611 retval
= target_write_u32(target
, ejtag_info
->ejtag_dbs_addr
, 0);
615 int mips32_configure_break_unit(struct target
*target
)
617 /* get pointers to arch-specific information */
618 struct mips32_common
*mips32
= target_to_mips32(target
);
619 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
623 if (mips32
->bp_scanned
)
626 /* get info about breakpoint support */
627 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
628 if (retval
!= ERROR_OK
)
631 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
632 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
633 ejtag_info
->debug_caps
= dcr
& EJTAG_DCR_ENM
;
634 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NOIB
))
635 ejtag_info
->debug_caps
|= EJTAG_DCR_IB
;
636 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NODB
))
637 ejtag_info
->debug_caps
|= EJTAG_DCR_DB
;
639 /* keep debug caps for later use */
640 ejtag_info
->debug_caps
= dcr
& (EJTAG_DCR_ENM
641 | EJTAG_DCR_IB
| EJTAG_DCR_DB
);
644 if (ejtag_info
->debug_caps
& EJTAG_DCR_IB
) {
645 retval
= mips32_configure_ibs(target
);
646 if (retval
!= ERROR_OK
)
650 if (ejtag_info
->debug_caps
& EJTAG_DCR_DB
) {
651 retval
= mips32_configure_dbs(target
);
652 if (retval
!= ERROR_OK
)
656 /* check if target endianness settings matches debug control register */
657 if (((ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
658 && (target
->endianness
== TARGET_LITTLE_ENDIAN
)) ||
659 (!(ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
660 && (target
->endianness
== TARGET_BIG_ENDIAN
)))
661 LOG_WARNING("DCR endianness settings does not match target settings");
663 LOG_DEBUG("DCR 0x%" PRIx32
" numinst %i numdata %i", dcr
, mips32
->num_inst_bpoints
,
664 mips32
->num_data_bpoints
);
666 mips32
->bp_scanned
= 1;
671 int mips32_enable_interrupts(struct target
*target
, int enable
)
677 /* read debug control register */
678 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
679 if (retval
!= ERROR_OK
)
683 if (!(dcr
& EJTAG_DCR_INTE
)) {
684 /* enable interrupts */
685 dcr
|= EJTAG_DCR_INTE
;
689 if (dcr
& EJTAG_DCR_INTE
) {
690 /* disable interrupts */
691 dcr
&= ~EJTAG_DCR_INTE
;
697 retval
= target_write_u32(target
, EJTAG_DCR
, dcr
);
698 if (retval
!= ERROR_OK
)
705 /* read config to config3 cp0 registers and log isa implementation */
706 int mips32_read_config_regs(struct target
*target
)
708 struct mips32_common
*mips32
= target_to_mips32(target
);
709 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
711 if (ejtag_info
->config_regs
== 0)
712 for (int i
= 0; i
!= 4; i
++) {
713 int retval
= mips32_cp0_read(ejtag_info
, &ejtag_info
->config
[i
], 16, i
);
714 if (retval
!= ERROR_OK
) {
715 LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32
, i
);
716 ejtag_info
->config_regs
= 0;
719 ejtag_info
->config_regs
= i
+ 1;
720 if ((ejtag_info
->config
[i
] & (1 << 31)) == 0)
721 break; /* no more config registers implemented */
724 return ERROR_OK
; /* already succesfully read */
726 LOG_DEBUG("read %"PRId32
" config registers", ejtag_info
->config_regs
);
728 if (ejtag_info
->impcode
& EJTAG_IMP_MIPS16
) {
729 mips32
->isa_imp
= MIPS32_MIPS16
;
730 LOG_USER("MIPS32 with MIPS16 support implemented");
732 } else if (ejtag_info
->config_regs
>= 4) { /* config3 implemented */
733 unsigned isa_imp
= (ejtag_info
->config
[3] & MIPS32_CONFIG3_ISA_MASK
) >> MIPS32_CONFIG3_ISA_SHIFT
;
735 mips32
->isa_imp
= MMIPS32_ONLY
;
736 LOG_USER("MICRO MIPS32 only implemented");
738 } else if (isa_imp
!= 0) {
739 mips32
->isa_imp
= MIPS32_MMIPS32
;
740 LOG_USER("MIPS32 and MICRO MIPS32 implemented");
744 if (mips32
->isa_imp
== MIPS32_ONLY
) /* initial default value */
745 LOG_USER("MIPS32 only implemented");
749 int mips32_checksum_memory(struct target
*target
, target_addr_t address
,
750 uint32_t count
, uint32_t *checksum
)
752 struct working_area
*crc_algorithm
;
753 struct reg_param reg_params
[2];
754 struct mips32_algorithm mips32_info
;
756 struct mips32_common
*mips32
= target_to_mips32(target
);
757 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
759 /* see contrib/loaders/checksum/mips32.s for src */
760 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
762 uint32_t mips_crc_code
[] = {
763 MIPS32_ADDIU(isa
, 12, 4, 0), /* addiu $t4, $a0, 0 */
764 MIPS32_ADDIU(isa
, 10, 5, 0), /* addiu $t2, $a1, 0 */
765 MIPS32_ADDIU(isa
, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
766 MIPS32_BEQ(isa
, 0, 0, 0x10 << isa
), /* beq $zero, $zero, ncomp */
767 MIPS32_ADDIU(isa
, 11, 0, 0), /* addiu $t3, $zero, 0 */
769 MIPS32_LB(isa
, 5, 0, 12), /* lb $a1, ($t4) */
770 MIPS32_ADDI(isa
, 12, 12, 1), /* addi $t4, $t4, 1 */
771 MIPS32_SLL(isa
, 5, 5, 24), /* sll $a1, $a1, 24 */
772 MIPS32_LUI(isa
, 2, 0x04c1), /* lui $v0, 0x04c1 */
773 MIPS32_XOR(isa
, 4, 4, 5), /* xor $a0, $a0, $a1 */
774 MIPS32_ORI(isa
, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
775 MIPS32_ADDU(isa
, 6, 0, 0), /* addu $a2, $zero, $zero */
777 MIPS32_SLL(isa
, 8, 4, 1), /* sll $t0, $a0, 1 */
778 MIPS32_ADDIU(isa
, 6, 6, 1), /* addiu $a2, $a2, 1 */
779 MIPS32_SLTI(isa
, 4, 4, 0), /* slti $a0, $a0, 0 */
780 MIPS32_XOR(isa
, 9, 8, 7), /* xor $t1, $t0, $a3 */
781 MIPS32_MOVN(isa
, 8, 9, 4), /* movn $t0, $t1, $a0 */
782 MIPS32_SLTI(isa
, 3, 6, 8), /* slti $v1, $a2, 8 */
783 MIPS32_BNE(isa
, 3, 0, NEG16(7 << isa
)), /* bne $v1, $zero, loop */
784 MIPS32_ADDU(isa
, 4, 8, 0), /* addu $a0, $t0, $zero */
786 MIPS32_BNE(isa
, 10, 11, NEG16(16 << isa
)), /* bne $t2, $t3, nbyte */
787 MIPS32_ADDIU(isa
, 11, 11, 1), /* addiu $t3, $t3, 1 */
791 /* make sure we have a working area */
792 if (target_alloc_working_area(target
, sizeof(mips_crc_code
), &crc_algorithm
) != ERROR_OK
)
793 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
795 pracc_swap16_array(ejtag_info
, mips_crc_code
, ARRAY_SIZE(mips_crc_code
));
797 /* convert mips crc code into a buffer in target endianness */
798 uint8_t mips_crc_code_8
[sizeof(mips_crc_code
)];
799 target_buffer_set_u32_array(target
, mips_crc_code_8
,
800 ARRAY_SIZE(mips_crc_code
), mips_crc_code
);
802 int retval
= target_write_buffer(target
, crc_algorithm
->address
, sizeof(mips_crc_code
), mips_crc_code_8
);
803 if (retval
!= ERROR_OK
)
806 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
807 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
; /* run isa as in debug mode */
809 init_reg_param(®_params
[0], "r4", 32, PARAM_IN_OUT
);
810 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
812 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
813 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
815 int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
817 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
, crc_algorithm
->address
,
818 crc_algorithm
->address
+ (sizeof(mips_crc_code
) - 4), timeout
, &mips32_info
);
820 if (retval
== ERROR_OK
)
821 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
823 destroy_reg_param(®_params
[0]);
824 destroy_reg_param(®_params
[1]);
826 target_free_working_area(target
, crc_algorithm
);
831 /** Checks whether a memory region is erased. */
832 int mips32_blank_check_memory(struct target
*target
,
833 struct target_memory_check_block
*blocks
, int num_blocks
,
834 uint8_t erased_value
)
836 struct working_area
*erase_check_algorithm
;
837 struct reg_param reg_params
[3];
838 struct mips32_algorithm mips32_info
;
840 struct mips32_common
*mips32
= target_to_mips32(target
);
841 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
843 if (erased_value
!= 0xff) {
844 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for MIPS32",
848 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
849 uint32_t erase_check_code
[] = {
851 MIPS32_LB(isa
, 8, 0, 4), /* lb $t0, ($a0) */
852 MIPS32_AND(isa
, 6, 6, 8), /* and $a2, $a2, $t0 */
853 MIPS32_ADDIU(isa
, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
854 MIPS32_BNE(isa
, 5, 0, NEG16(4 << isa
)), /* bne $a1, $zero, nbyte */
855 MIPS32_ADDIU(isa
, 4, 4, 1), /* addiu $a0, $a0, 1 */
856 MIPS32_SDBBP(isa
) /* sdbbp */
859 /* make sure we have a working area */
860 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
861 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
863 pracc_swap16_array(ejtag_info
, erase_check_code
, ARRAY_SIZE(erase_check_code
));
865 /* convert erase check code into a buffer in target endianness */
866 uint8_t erase_check_code_8
[sizeof(erase_check_code
)];
867 target_buffer_set_u32_array(target
, erase_check_code_8
,
868 ARRAY_SIZE(erase_check_code
), erase_check_code
);
870 int retval
= target_write_buffer(target
, erase_check_algorithm
->address
,
871 sizeof(erase_check_code
), erase_check_code_8
);
872 if (retval
!= ERROR_OK
)
875 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
876 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
;
878 init_reg_param(®_params
[0], "r4", 32, PARAM_OUT
);
879 buf_set_u32(reg_params
[0].value
, 0, 32, blocks
[0].address
);
881 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
882 buf_set_u32(reg_params
[1].value
, 0, 32, blocks
[0].size
);
884 init_reg_param(®_params
[2], "r6", 32, PARAM_IN_OUT
);
885 buf_set_u32(reg_params
[2].value
, 0, 32, erased_value
);
887 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
, erase_check_algorithm
->address
,
888 erase_check_algorithm
->address
+ (sizeof(erase_check_code
) - 4), 10000, &mips32_info
);
890 if (retval
== ERROR_OK
)
891 blocks
[0].result
= buf_get_u32(reg_params
[2].value
, 0, 32);
893 destroy_reg_param(®_params
[0]);
894 destroy_reg_param(®_params
[1]);
895 destroy_reg_param(®_params
[2]);
898 target_free_working_area(target
, erase_check_algorithm
);
900 if (retval
!= ERROR_OK
)
903 return 1; /* only one block has been checked */
906 static int mips32_verify_pointer(struct command_context
*cmd_ctx
,
907 struct mips32_common
*mips32
)
909 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
910 command_print(cmd_ctx
, "target is not an MIPS32");
911 return ERROR_TARGET_INVALID
;
917 * MIPS32 targets expose command interface
918 * to manipulate CP0 registers
920 COMMAND_HANDLER(mips32_handle_cp0_command
)
923 struct target
*target
= get_current_target(CMD_CTX
);
924 struct mips32_common
*mips32
= target_to_mips32(target
);
925 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
928 retval
= mips32_verify_pointer(CMD_CTX
, mips32
);
929 if (retval
!= ERROR_OK
)
932 if (target
->state
!= TARGET_HALTED
) {
933 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
937 /* two or more argument, access a single register/select (write if third argument is given) */
939 return ERROR_COMMAND_SYNTAX_ERROR
;
941 uint32_t cp0_reg
, cp0_sel
;
942 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
943 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
948 retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
949 if (retval
!= ERROR_OK
) {
950 command_print(CMD_CTX
,
951 "couldn't access reg %" PRIi32
,
955 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
956 cp0_reg
, cp0_sel
, value
);
958 } else if (CMD_ARGC
== 3) {
960 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
961 retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
962 if (retval
!= ERROR_OK
) {
963 command_print(CMD_CTX
,
964 "couldn't access cp0 reg %" PRIi32
", select %" PRIi32
,
968 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
969 cp0_reg
, cp0_sel
, value
);
976 COMMAND_HANDLER(mips32_handle_scan_delay_command
)
978 struct target
*target
= get_current_target(CMD_CTX
);
979 struct mips32_common
*mips32
= target_to_mips32(target
);
980 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
983 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], ejtag_info
->scan_delay
);
984 else if (CMD_ARGC
> 1)
985 return ERROR_COMMAND_SYNTAX_ERROR
;
987 command_print(CMD_CTX
, "scan delay: %d nsec", ejtag_info
->scan_delay
);
988 if (ejtag_info
->scan_delay
>= MIPS32_SCAN_DELAY_LEGACY_MODE
) {
989 ejtag_info
->mode
= 0;
990 command_print(CMD_CTX
, "running in legacy mode");
992 ejtag_info
->mode
= 1;
993 command_print(CMD_CTX
, "running in fast queued mode");
999 static const struct command_registration mips32_exec_command_handlers
[] = {
1002 .handler
= mips32_handle_cp0_command
,
1003 .mode
= COMMAND_EXEC
,
1004 .usage
= "regnum select [value]",
1005 .help
= "display/modify cp0 register",
1008 .name
= "scan_delay",
1009 .handler
= mips32_handle_scan_delay_command
,
1010 .mode
= COMMAND_ANY
,
1011 .help
= "display/set scan delay in nano seconds",
1014 COMMAND_REGISTRATION_DONE
1017 const struct command_registration mips32_command_handlers
[] = {
1020 .mode
= COMMAND_ANY
,
1021 .help
= "mips32 command group",
1023 .chain
= mips32_exec_command_handlers
,
1025 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)