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
[] = {
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
;
379 /* has breakpoint/watchpoint unit been scanned */
380 mips32
->bp_scanned
= 0;
381 mips32
->data_break_list
= NULL
;
383 mips32
->ejtag_info
.tap
= tap
;
384 mips32
->read_core_reg
= mips32_read_core_reg
;
385 mips32
->write_core_reg
= mips32_write_core_reg
;
386 /* if unknown endianness defaults to little endian, 1 */
387 mips32
->ejtag_info
.endianness
= target
->endianness
== TARGET_BIG_ENDIAN
? 0 : 1;
388 mips32
->ejtag_info
.scan_delay
= MIPS32_SCAN_DELAY_LEGACY_MODE
;
389 mips32
->ejtag_info
.mode
= 0; /* Initial default value */
390 mips32
->ejtag_info
.isa
= 0; /* isa on debug mips32, updated by poll function */
395 /* run to exit point. return error if exit point was not reached. */
396 static int mips32_run_and_wait(struct target
*target
, target_addr_t entry_point
,
397 int timeout_ms
, target_addr_t exit_point
, struct mips32_common
*mips32
)
401 /* This code relies on the target specific resume() and poll()->debug_entry()
402 * sequence to write register values to the processor and the read them back */
403 retval
= target_resume(target
, 0, entry_point
, 0, 1);
404 if (retval
!= ERROR_OK
)
407 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
408 /* If the target fails to halt due to the breakpoint, force a halt */
409 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
410 retval
= target_halt(target
);
411 if (retval
!= ERROR_OK
)
413 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
414 if (retval
!= ERROR_OK
)
416 return ERROR_TARGET_TIMEOUT
;
419 pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32);
420 if (exit_point
&& (pc
!= exit_point
)) {
421 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
422 return ERROR_TARGET_TIMEOUT
;
428 int mips32_run_algorithm(struct target
*target
, int num_mem_params
,
429 struct mem_param
*mem_params
, int num_reg_params
,
430 struct reg_param
*reg_params
, target_addr_t entry_point
,
431 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
433 struct mips32_common
*mips32
= target_to_mips32(target
);
434 struct mips32_algorithm
*mips32_algorithm_info
= arch_info
;
435 enum mips32_isa_mode isa_mode
= mips32
->isa_mode
;
437 uint32_t context
[MIPS32_NUM_REGS
];
438 int retval
= ERROR_OK
;
440 LOG_DEBUG("Running algorithm");
442 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
443 * at the exit point */
445 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
446 LOG_ERROR("current target isn't a MIPS32 target");
447 return ERROR_TARGET_INVALID
;
450 if (target
->state
!= TARGET_HALTED
) {
451 LOG_WARNING("target not halted");
452 return ERROR_TARGET_NOT_HALTED
;
455 /* refresh core register cache */
456 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
457 if (!mips32
->core_cache
->reg_list
[i
].valid
)
458 mips32
->read_core_reg(target
, i
);
459 context
[i
] = buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
462 for (int i
= 0; i
< num_mem_params
; i
++) {
463 retval
= target_write_buffer(target
, mem_params
[i
].address
,
464 mem_params
[i
].size
, mem_params
[i
].value
);
465 if (retval
!= ERROR_OK
)
469 for (int i
= 0; i
< num_reg_params
; i
++) {
470 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, 0);
473 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
474 return ERROR_COMMAND_SYNTAX_ERROR
;
477 if (reg
->size
!= reg_params
[i
].size
) {
478 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
479 reg_params
[i
].reg_name
);
480 return ERROR_COMMAND_SYNTAX_ERROR
;
483 mips32_set_core_reg(reg
, reg_params
[i
].value
);
486 mips32
->isa_mode
= mips32_algorithm_info
->isa_mode
;
488 retval
= mips32_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, mips32
);
490 if (retval
!= ERROR_OK
)
493 for (int i
= 0; i
< num_mem_params
; i
++) {
494 if (mem_params
[i
].direction
!= PARAM_OUT
) {
495 retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
,
496 mem_params
[i
].value
);
497 if (retval
!= ERROR_OK
)
502 for (int i
= 0; i
< num_reg_params
; i
++) {
503 if (reg_params
[i
].direction
!= PARAM_OUT
) {
504 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, 0);
506 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
507 return ERROR_COMMAND_SYNTAX_ERROR
;
510 if (reg
->size
!= reg_params
[i
].size
) {
511 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
512 reg_params
[i
].reg_name
);
513 return ERROR_COMMAND_SYNTAX_ERROR
;
516 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
520 /* restore everything we saved before */
521 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
523 regvalue
= buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
524 if (regvalue
!= context
[i
]) {
525 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
526 mips32
->core_cache
->reg_list
[i
].name
, context
[i
]);
527 buf_set_u32(mips32
->core_cache
->reg_list
[i
].value
,
529 mips32
->core_cache
->reg_list
[i
].valid
= 1;
530 mips32
->core_cache
->reg_list
[i
].dirty
= 1;
534 mips32
->isa_mode
= isa_mode
;
539 int mips32_examine(struct target
*target
)
541 struct mips32_common
*mips32
= target_to_mips32(target
);
543 if (!target_was_examined(target
)) {
544 target_set_examined(target
);
546 /* we will configure later */
547 mips32
->bp_scanned
= 0;
548 mips32
->num_inst_bpoints
= 0;
549 mips32
->num_data_bpoints
= 0;
550 mips32
->num_inst_bpoints_avail
= 0;
551 mips32
->num_data_bpoints_avail
= 0;
557 static int mips32_configure_ibs(struct target
*target
)
559 struct mips32_common
*mips32
= target_to_mips32(target
);
560 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
564 /* get number of inst breakpoints */
565 retval
= target_read_u32(target
, ejtag_info
->ejtag_ibs_addr
, &bpinfo
);
566 if (retval
!= ERROR_OK
)
569 mips32
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
570 mips32
->num_inst_bpoints_avail
= mips32
->num_inst_bpoints
;
571 mips32
->inst_break_list
= calloc(mips32
->num_inst_bpoints
,
572 sizeof(struct mips32_comparator
));
574 for (i
= 0; i
< mips32
->num_inst_bpoints
; i
++)
575 mips32
->inst_break_list
[i
].reg_address
=
576 ejtag_info
->ejtag_iba0_addr
+
577 (ejtag_info
->ejtag_iba_step_size
* i
);
580 retval
= target_write_u32(target
, ejtag_info
->ejtag_ibs_addr
, 0);
584 static int mips32_configure_dbs(struct target
*target
)
586 struct mips32_common
*mips32
= target_to_mips32(target
);
587 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
591 /* get number of data breakpoints */
592 retval
= target_read_u32(target
, ejtag_info
->ejtag_dbs_addr
, &bpinfo
);
593 if (retval
!= ERROR_OK
)
596 mips32
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
597 mips32
->num_data_bpoints_avail
= mips32
->num_data_bpoints
;
598 mips32
->data_break_list
= calloc(mips32
->num_data_bpoints
,
599 sizeof(struct mips32_comparator
));
601 for (i
= 0; i
< mips32
->num_data_bpoints
; i
++)
602 mips32
->data_break_list
[i
].reg_address
=
603 ejtag_info
->ejtag_dba0_addr
+
604 (ejtag_info
->ejtag_dba_step_size
* i
);
607 retval
= target_write_u32(target
, ejtag_info
->ejtag_dbs_addr
, 0);
611 int mips32_configure_break_unit(struct target
*target
)
613 /* get pointers to arch-specific information */
614 struct mips32_common
*mips32
= target_to_mips32(target
);
615 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
619 if (mips32
->bp_scanned
)
622 /* get info about breakpoint support */
623 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
624 if (retval
!= ERROR_OK
)
627 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
628 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
629 ejtag_info
->debug_caps
= dcr
& EJTAG_DCR_ENM
;
630 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NOIB
))
631 ejtag_info
->debug_caps
|= EJTAG_DCR_IB
;
632 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NODB
))
633 ejtag_info
->debug_caps
|= EJTAG_DCR_DB
;
635 /* keep debug caps for later use */
636 ejtag_info
->debug_caps
= dcr
& (EJTAG_DCR_ENM
637 | EJTAG_DCR_IB
| EJTAG_DCR_DB
);
640 if (ejtag_info
->debug_caps
& EJTAG_DCR_IB
) {
641 retval
= mips32_configure_ibs(target
);
642 if (retval
!= ERROR_OK
)
646 if (ejtag_info
->debug_caps
& EJTAG_DCR_DB
) {
647 retval
= mips32_configure_dbs(target
);
648 if (retval
!= ERROR_OK
)
652 /* check if target endianness settings matches debug control register */
653 if (((ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
654 && (target
->endianness
== TARGET_LITTLE_ENDIAN
)) ||
655 (!(ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
656 && (target
->endianness
== TARGET_BIG_ENDIAN
)))
657 LOG_WARNING("DCR endianness settings does not match target settings");
659 LOG_DEBUG("DCR 0x%" PRIx32
" numinst %i numdata %i", dcr
, mips32
->num_inst_bpoints
,
660 mips32
->num_data_bpoints
);
662 mips32
->bp_scanned
= 1;
667 int mips32_enable_interrupts(struct target
*target
, int enable
)
673 /* read debug control register */
674 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
675 if (retval
!= ERROR_OK
)
679 if (!(dcr
& EJTAG_DCR_INTE
)) {
680 /* enable interrupts */
681 dcr
|= EJTAG_DCR_INTE
;
685 if (dcr
& EJTAG_DCR_INTE
) {
686 /* disable interrupts */
687 dcr
&= ~EJTAG_DCR_INTE
;
693 retval
= target_write_u32(target
, EJTAG_DCR
, dcr
);
694 if (retval
!= ERROR_OK
)
701 int mips32_checksum_memory(struct target
*target
, target_addr_t address
,
702 uint32_t count
, uint32_t *checksum
)
704 struct working_area
*crc_algorithm
;
705 struct reg_param reg_params
[2];
706 struct mips32_algorithm mips32_info
;
708 /* see contrib/loaders/checksum/mips32.s for src */
710 static const uint32_t mips_crc_code
[] = {
711 0x248C0000, /* addiu $t4, $a0, 0 */
712 0x24AA0000, /* addiu $t2, $a1, 0 */
713 0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */
714 0x10000010, /* beq $zero, $zero, ncomp */
715 0x240B0000, /* addiu $t3, $zero, 0 */
717 0x81850000, /* lb $a1, ($t4) */
718 0x218C0001, /* addi $t4, $t4, 1 */
719 0x00052E00, /* sll $a1, $a1, 24 */
720 0x3C0204C1, /* lui $v0, 0x04c1 */
721 0x00852026, /* xor $a0, $a0, $a1 */
722 0x34471DB7, /* ori $a3, $v0, 0x1db7 */
723 0x00003021, /* addu $a2, $zero, $zero */
725 0x00044040, /* sll $t0, $a0, 1 */
726 0x24C60001, /* addiu $a2, $a2, 1 */
727 0x28840000, /* slti $a0, $a0, 0 */
728 0x01074826, /* xor $t1, $t0, $a3 */
729 0x0124400B, /* movn $t0, $t1, $a0 */
730 0x28C30008, /* slti $v1, $a2, 8 */
731 0x1460FFF9, /* bne $v1, $zero, loop */
732 0x01002021, /* addu $a0, $t0, $zero */
734 0x154BFFF0, /* bne $t2, $t3, nbyte */
735 0x256B0001, /* addiu $t3, $t3, 1 */
736 0x7000003F, /* sdbbp */
739 /* make sure we have a working area */
740 if (target_alloc_working_area(target
, sizeof(mips_crc_code
), &crc_algorithm
) != ERROR_OK
)
741 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
743 /* convert mips crc code into a buffer in target endianness */
744 uint8_t mips_crc_code_8
[sizeof(mips_crc_code
)];
745 target_buffer_set_u32_array(target
, mips_crc_code_8
,
746 ARRAY_SIZE(mips_crc_code
), mips_crc_code
);
748 target_write_buffer(target
, crc_algorithm
->address
, sizeof(mips_crc_code
), mips_crc_code_8
);
750 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
751 mips32_info
.isa_mode
= MIPS32_ISA_MIPS32
;
753 init_reg_param(®_params
[0], "r4", 32, PARAM_IN_OUT
);
754 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
756 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
757 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
759 int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
761 int retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
,
762 crc_algorithm
->address
, crc_algorithm
->address
+ (sizeof(mips_crc_code
) - 4), timeout
,
765 if (retval
== ERROR_OK
)
766 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
768 destroy_reg_param(®_params
[0]);
769 destroy_reg_param(®_params
[1]);
771 target_free_working_area(target
, crc_algorithm
);
776 /** Checks whether a memory region is erased. */
777 int mips32_blank_check_memory(struct target
*target
,
778 target_addr_t address
, uint32_t count
, uint32_t *blank
, uint8_t erased_value
)
780 struct working_area
*erase_check_algorithm
;
781 struct reg_param reg_params
[3];
782 struct mips32_algorithm mips32_info
;
784 static const uint32_t erase_check_code
[] = {
786 0x80880000, /* lb $t0, ($a0) */
787 0x00C83024, /* and $a2, $a2, $t0 */
788 0x24A5FFFF, /* addiu $a1, $a1, -1 */
789 0x14A0FFFC, /* bne $a1, $zero, nbyte */
790 0x24840001, /* addiu $a0, $a0, 1 */
791 0x7000003F /* sdbbp */
794 if (erased_value
!= 0xff) {
795 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for MIPS32",
800 /* make sure we have a working area */
801 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
802 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
804 /* convert erase check code into a buffer in target endianness */
805 uint8_t erase_check_code_8
[sizeof(erase_check_code
)];
806 target_buffer_set_u32_array(target
, erase_check_code_8
,
807 ARRAY_SIZE(erase_check_code
), erase_check_code
);
809 target_write_buffer(target
, erase_check_algorithm
->address
, sizeof(erase_check_code
), erase_check_code_8
);
811 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
812 mips32_info
.isa_mode
= MIPS32_ISA_MIPS32
;
814 init_reg_param(®_params
[0], "r4", 32, PARAM_OUT
);
815 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
817 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
818 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
820 init_reg_param(®_params
[2], "r6", 32, PARAM_IN_OUT
);
821 buf_set_u32(reg_params
[2].value
, 0, 32, erased_value
);
823 int retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
824 erase_check_algorithm
->address
,
825 erase_check_algorithm
->address
+ (sizeof(erase_check_code
) - 4),
826 10000, &mips32_info
);
828 if (retval
== ERROR_OK
)
829 *blank
= buf_get_u32(reg_params
[2].value
, 0, 32);
831 destroy_reg_param(®_params
[0]);
832 destroy_reg_param(®_params
[1]);
833 destroy_reg_param(®_params
[2]);
835 target_free_working_area(target
, erase_check_algorithm
);
840 static int mips32_verify_pointer(struct command_context
*cmd_ctx
,
841 struct mips32_common
*mips32
)
843 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
844 command_print(cmd_ctx
, "target is not an MIPS32");
845 return ERROR_TARGET_INVALID
;
851 * MIPS32 targets expose command interface
852 * to manipulate CP0 registers
854 COMMAND_HANDLER(mips32_handle_cp0_command
)
857 struct target
*target
= get_current_target(CMD_CTX
);
858 struct mips32_common
*mips32
= target_to_mips32(target
);
859 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
862 retval
= mips32_verify_pointer(CMD_CTX
, mips32
);
863 if (retval
!= ERROR_OK
)
866 if (target
->state
!= TARGET_HALTED
) {
867 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
871 /* two or more argument, access a single register/select (write if third argument is given) */
873 return ERROR_COMMAND_SYNTAX_ERROR
;
875 uint32_t cp0_reg
, cp0_sel
;
876 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
877 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
882 retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
883 if (retval
!= ERROR_OK
) {
884 command_print(CMD_CTX
,
885 "couldn't access reg %" PRIi32
,
889 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
890 cp0_reg
, cp0_sel
, value
);
892 } else if (CMD_ARGC
== 3) {
894 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
895 retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
896 if (retval
!= ERROR_OK
) {
897 command_print(CMD_CTX
,
898 "couldn't access cp0 reg %" PRIi32
", select %" PRIi32
,
902 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
903 cp0_reg
, cp0_sel
, value
);
910 COMMAND_HANDLER(mips32_handle_scan_delay_command
)
912 struct target
*target
= get_current_target(CMD_CTX
);
913 struct mips32_common
*mips32
= target_to_mips32(target
);
914 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
917 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], ejtag_info
->scan_delay
);
918 else if (CMD_ARGC
> 1)
919 return ERROR_COMMAND_SYNTAX_ERROR
;
921 command_print(CMD_CTX
, "scan delay: %d nsec", ejtag_info
->scan_delay
);
922 if (ejtag_info
->scan_delay
>= MIPS32_SCAN_DELAY_LEGACY_MODE
) {
923 ejtag_info
->mode
= 0;
924 command_print(CMD_CTX
, "running in legacy mode");
926 ejtag_info
->mode
= 1;
927 command_print(CMD_CTX
, "running in fast queued mode");
933 static const struct command_registration mips32_exec_command_handlers
[] = {
936 .handler
= mips32_handle_cp0_command
,
937 .mode
= COMMAND_EXEC
,
938 .usage
= "regnum select [value]",
939 .help
= "display/modify cp0 register",
942 .name
= "scan_delay",
943 .handler
= mips32_handle_scan_delay_command
,
945 .help
= "display/set scan delay in nano seconds",
948 COMMAND_REGISTRATION_DONE
951 const struct command_registration mips32_command_handlers
[] = {
955 .help
= "mips32 command group",
957 .chain
= mips32_exec_command_handlers
,
959 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)