mips32: add gdb target description support
[openocd.git] / src / target / mips32.c
1 /***************************************************************************
2 * Copyright (C) 2008 by Spencer Oliver *
3 * spen@spen-soft.co.uk *
4 * *
5 * Copyright (C) 2008 by David T.L. Wong *
6 * *
7 * Copyright (C) 2007,2008 Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
9 * *
10 * Copyright (C) 2011 by Drasko DRASKOVIC *
11 * drasko.draskovic@gmail.com *
12 * *
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. *
17 * *
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. *
22 * *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program; if not, write to the *
25 * Free Software Foundation, Inc., *
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
27 ***************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "mips32.h"
34 #include "breakpoints.h"
35 #include "algorithm.h"
36 #include "register.h"
37
38 static const char *mips_isa_strings[] = {
39 "MIPS32", "MIPS16e"
40 };
41
42 #define MIPS32_GDB_DUMMY_FP_REG 1
43
44 /*
45 * GDB registers
46 * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml
47 */
48 static const struct {
49 unsigned id;
50 const char *name;
51 enum reg_type type;
52 const char *group;
53 const char *feature;
54 int flag;
55 } mips32_regs[] = {
56 { 0, "r0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
57 { 1, "r1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
58 { 2, "r2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
59 { 3, "r3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
60 { 4, "r4", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
61 { 5, "r5", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
62 { 6, "r6", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
63 { 7, "r7", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
64 { 8, "r8", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
65 { 9, "r9", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
66 { 10, "r10", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
67 { 11, "r11", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
68 { 12, "r12", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
69 { 13, "r13", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
70 { 14, "r14", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
71 { 15, "r15", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
72 { 16, "r16", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
73 { 17, "r17", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
74 { 18, "r18", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
75 { 19, "r19", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
76 { 20, "r20", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
77 { 21, "r21", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
78 { 22, "r22", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
79 { 23, "r23", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
80 { 24, "r24", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
81 { 25, "r25", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
82 { 26, "r26", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
83 { 27, "r27", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
84 { 28, "r28", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
85 { 29, "r29", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
86 { 30, "r30", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
87 { 31, "r31", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
88 { 32, "status", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
89 { 33, "lo", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
90 { 34, "hi", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
91 { 35, "badvaddr", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
92 { 36, "cause", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
93 { 37, "pc", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
94
95 { 38, "f0", REG_TYPE_IEEE_SINGLE, NULL,
96 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
97 { 39, "f1", REG_TYPE_IEEE_SINGLE, NULL,
98 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
99 { 40, "f2", REG_TYPE_IEEE_SINGLE, NULL,
100 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
101 { 41, "f3", REG_TYPE_IEEE_SINGLE, NULL,
102 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
103 { 42, "f4", REG_TYPE_IEEE_SINGLE, NULL,
104 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
105 { 43, "f5", REG_TYPE_IEEE_SINGLE, NULL,
106 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
107 { 44, "f6", REG_TYPE_IEEE_SINGLE, NULL,
108 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
109 { 45, "f7", REG_TYPE_IEEE_SINGLE, NULL,
110 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
111 { 46, "f8", REG_TYPE_IEEE_SINGLE, NULL,
112 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
113 { 47, "f9", REG_TYPE_IEEE_SINGLE, NULL,
114 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
115 { 48, "f10", REG_TYPE_IEEE_SINGLE, NULL,
116 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
117 { 49, "f11", REG_TYPE_IEEE_SINGLE, NULL,
118 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
119 { 50, "f12", REG_TYPE_IEEE_SINGLE, NULL,
120 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
121 { 51, "f13", REG_TYPE_IEEE_SINGLE, NULL,
122 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
123 { 52, "f14", REG_TYPE_IEEE_SINGLE, NULL,
124 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
125 { 53, "f15", REG_TYPE_IEEE_SINGLE, NULL,
126 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
127 { 54, "f16", REG_TYPE_IEEE_SINGLE, NULL,
128 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
129 { 55, "f17", REG_TYPE_IEEE_SINGLE, NULL,
130 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
131 { 56, "f18", REG_TYPE_IEEE_SINGLE, NULL,
132 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
133 { 57, "f19", REG_TYPE_IEEE_SINGLE, NULL,
134 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
135 { 58, "f20", REG_TYPE_IEEE_SINGLE, NULL,
136 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
137 { 59, "f21", REG_TYPE_IEEE_SINGLE, NULL,
138 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
139 { 60, "f22", REG_TYPE_IEEE_SINGLE, NULL,
140 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
141 { 61, "f23", REG_TYPE_IEEE_SINGLE, NULL,
142 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
143 { 62, "f24", REG_TYPE_IEEE_SINGLE, NULL,
144 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
145 { 63, "f25", REG_TYPE_IEEE_SINGLE, NULL,
146 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
147 { 64, "f26", REG_TYPE_IEEE_SINGLE, NULL,
148 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
149 { 65, "f27", REG_TYPE_IEEE_SINGLE, NULL,
150 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
151 { 66, "f28", REG_TYPE_IEEE_SINGLE, NULL,
152 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
153 { 67, "f29", REG_TYPE_IEEE_SINGLE, NULL,
154 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
155 { 68, "f30", REG_TYPE_IEEE_SINGLE, NULL,
156 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
157 { 69, "f31", REG_TYPE_IEEE_SINGLE, NULL,
158 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
159 { 70, "fcsr", REG_TYPE_INT, "float",
160 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
161 { 71, "fir", REG_TYPE_INT, "float",
162 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
163 };
164
165
166 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
167
168 static uint8_t mips32_gdb_dummy_fp_value[] = {0, 0, 0, 0};
169
170 static int mips32_get_core_reg(struct reg *reg)
171 {
172 int retval;
173 struct mips32_core_reg *mips32_reg = reg->arch_info;
174 struct target *target = mips32_reg->target;
175 struct mips32_common *mips32_target = target_to_mips32(target);
176
177 if (target->state != TARGET_HALTED)
178 return ERROR_TARGET_NOT_HALTED;
179
180 retval = mips32_target->read_core_reg(target, mips32_reg->num);
181
182 return retval;
183 }
184
185 static int mips32_set_core_reg(struct reg *reg, uint8_t *buf)
186 {
187 struct mips32_core_reg *mips32_reg = reg->arch_info;
188 struct target *target = mips32_reg->target;
189 uint32_t value = buf_get_u32(buf, 0, 32);
190
191 if (target->state != TARGET_HALTED)
192 return ERROR_TARGET_NOT_HALTED;
193
194 buf_set_u32(reg->value, 0, 32, value);
195 reg->dirty = 1;
196 reg->valid = 1;
197
198 return ERROR_OK;
199 }
200
201 static int mips32_read_core_reg(struct target *target, unsigned int num)
202 {
203 uint32_t reg_value;
204
205 /* get pointers to arch-specific information */
206 struct mips32_common *mips32 = target_to_mips32(target);
207
208 if (num >= MIPS32_NUM_REGS)
209 return ERROR_COMMAND_SYNTAX_ERROR;
210
211 reg_value = mips32->core_regs[num];
212 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
213 mips32->core_cache->reg_list[num].valid = 1;
214 mips32->core_cache->reg_list[num].dirty = 0;
215
216 return ERROR_OK;
217 }
218
219 static int mips32_write_core_reg(struct target *target, unsigned int num)
220 {
221 uint32_t reg_value;
222
223 /* get pointers to arch-specific information */
224 struct mips32_common *mips32 = target_to_mips32(target);
225
226 if (num >= MIPS32_NUM_REGS)
227 return ERROR_COMMAND_SYNTAX_ERROR;
228
229 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
230 mips32->core_regs[num] = reg_value;
231 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value);
232 mips32->core_cache->reg_list[num].valid = 1;
233 mips32->core_cache->reg_list[num].dirty = 0;
234
235 return ERROR_OK;
236 }
237
238 int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
239 int *reg_list_size, enum target_register_class reg_class)
240 {
241 /* get pointers to arch-specific information */
242 struct mips32_common *mips32 = target_to_mips32(target);
243 unsigned int i;
244
245 /* include floating point registers */
246 *reg_list_size = MIPS32_NUM_REGS;
247 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
248
249 for (i = 0; i < MIPS32_NUM_REGS; i++)
250 (*reg_list)[i] = &mips32->core_cache->reg_list[i];
251
252 return ERROR_OK;
253 }
254
255 int mips32_save_context(struct target *target)
256 {
257 unsigned int i;
258
259 /* get pointers to arch-specific information */
260 struct mips32_common *mips32 = target_to_mips32(target);
261 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
262
263 /* read core registers */
264 mips32_pracc_read_regs(ejtag_info, mips32->core_regs);
265
266 for (i = 0; i < MIPS32_NUM_REGS; i++) {
267 if (!mips32->core_cache->reg_list[i].valid)
268 mips32->read_core_reg(target, i);
269 }
270
271 return ERROR_OK;
272 }
273
274 int mips32_restore_context(struct target *target)
275 {
276 unsigned int i;
277
278 /* get pointers to arch-specific information */
279 struct mips32_common *mips32 = target_to_mips32(target);
280 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
281
282 for (i = 0; i < MIPS32_NUM_REGS; i++) {
283 if (mips32->core_cache->reg_list[i].dirty)
284 mips32->write_core_reg(target, i);
285 }
286
287 /* write core regs */
288 mips32_pracc_write_regs(ejtag_info, mips32->core_regs);
289
290 return ERROR_OK;
291 }
292
293 int mips32_arch_state(struct target *target)
294 {
295 struct mips32_common *mips32 = target_to_mips32(target);
296
297 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32 "",
298 mips_isa_strings[mips32->isa_mode],
299 debug_reason_name(target),
300 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
301
302 return ERROR_OK;
303 }
304
305 static const struct reg_arch_type mips32_reg_type = {
306 .get = mips32_get_core_reg,
307 .set = mips32_set_core_reg,
308 };
309
310 struct reg_cache *mips32_build_reg_cache(struct target *target)
311 {
312 /* get pointers to arch-specific information */
313 struct mips32_common *mips32 = target_to_mips32(target);
314
315 int num_regs = MIPS32_NUM_REGS;
316 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
317 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
318 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
319 struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);
320 struct reg_feature *feature;
321 int i;
322
323 /* Build the process context cache */
324 cache->name = "mips32 registers";
325 cache->next = NULL;
326 cache->reg_list = reg_list;
327 cache->num_regs = num_regs;
328 (*cache_p) = cache;
329 mips32->core_cache = cache;
330
331 for (i = 0; i < num_regs; i++) {
332 arch_info[i].num = mips32_regs[i].id;
333 arch_info[i].target = target;
334 arch_info[i].mips32_common = mips32;
335
336 reg_list[i].name = mips32_regs[i].name;
337 reg_list[i].size = 32;
338
339 if (mips32_regs[i].flag == MIPS32_GDB_DUMMY_FP_REG) {
340 reg_list[i].value = mips32_gdb_dummy_fp_value;
341 reg_list[i].valid = 1;
342 reg_list[i].arch_info = NULL;
343 register_init_dummy(&reg_list[i]);
344 } else {
345 reg_list[i].value = calloc(1, 4);
346 reg_list[i].valid = 0;
347 reg_list[i].type = &mips32_reg_type;
348 reg_list[i].arch_info = &arch_info[i];
349
350 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
351 if (reg_list[i].reg_data_type)
352 reg_list[i].reg_data_type->type = mips32_regs[i].type;
353 else
354 LOG_ERROR("unable to allocate reg type list");
355 }
356
357 reg_list[i].dirty = 0;
358
359 reg_list[i].group = mips32_regs[i].group;
360 reg_list[i].number = i;
361 reg_list[i].exist = true;
362 reg_list[i].caller_save = true; /* gdb defaults to true */
363
364 feature = calloc(1, sizeof(struct reg_feature));
365 if (feature) {
366 feature->name = mips32_regs[i].feature;
367 reg_list[i].feature = feature;
368 } else
369 LOG_ERROR("unable to allocate feature list");
370 }
371
372 return cache;
373 }
374
375 int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, struct jtag_tap *tap)
376 {
377 target->arch_info = mips32;
378 mips32->common_magic = MIPS32_COMMON_MAGIC;
379 mips32->fast_data_area = NULL;
380
381 /* has breakpoint/watchpoint unit been scanned */
382 mips32->bp_scanned = 0;
383 mips32->data_break_list = NULL;
384
385 mips32->ejtag_info.tap = tap;
386 mips32->read_core_reg = mips32_read_core_reg;
387 mips32->write_core_reg = mips32_write_core_reg;
388
389 mips32->ejtag_info.scan_delay = 2000000; /* Initial default value */
390 mips32->ejtag_info.mode = 0; /* Initial default value */
391
392 return ERROR_OK;
393 }
394
395 /* run to exit point. return error if exit point was not reached. */
396 static int mips32_run_and_wait(struct target *target, uint32_t entry_point,
397 int timeout_ms, uint32_t exit_point, struct mips32_common *mips32)
398 {
399 uint32_t pc;
400 int retval;
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)
405 return retval;
406
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)
412 return retval;
413 retval = target_wait_state(target, TARGET_HALTED, 500);
414 if (retval != ERROR_OK)
415 return retval;
416 return ERROR_TARGET_TIMEOUT;
417 }
418
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;
423 }
424
425 return ERROR_OK;
426 }
427
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, uint32_t entry_point,
431 uint32_t exit_point, int timeout_ms, void *arch_info)
432 {
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;
436
437 uint32_t context[MIPS32_NUM_REGS];
438 int retval = ERROR_OK;
439
440 LOG_DEBUG("Running algorithm");
441
442 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
443 * at the exit point */
444
445 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
446 LOG_ERROR("current target isn't a MIPS32 target");
447 return ERROR_TARGET_INVALID;
448 }
449
450 if (target->state != TARGET_HALTED) {
451 LOG_WARNING("target not halted");
452 return ERROR_TARGET_NOT_HALTED;
453 }
454
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);
460 }
461
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)
466 return retval;
467 }
468
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);
471
472 if (!reg) {
473 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
474 return ERROR_COMMAND_SYNTAX_ERROR;
475 }
476
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;
481 }
482
483 mips32_set_core_reg(reg, reg_params[i].value);
484 }
485
486 mips32->isa_mode = mips32_algorithm_info->isa_mode;
487
488 retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32);
489
490 if (retval != ERROR_OK)
491 return retval;
492
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)
498 return retval;
499 }
500 }
501
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);
505 if (!reg) {
506 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
507 return ERROR_COMMAND_SYNTAX_ERROR;
508 }
509
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;
514 }
515
516 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
517 }
518 }
519
520 /* restore everything we saved before */
521 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
522 uint32_t regvalue;
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,
528 0, 32, context[i]);
529 mips32->core_cache->reg_list[i].valid = 1;
530 mips32->core_cache->reg_list[i].dirty = 1;
531 }
532 }
533
534 mips32->isa_mode = isa_mode;
535
536 return ERROR_OK;
537 }
538
539 int mips32_examine(struct target *target)
540 {
541 struct mips32_common *mips32 = target_to_mips32(target);
542
543 if (!target_was_examined(target)) {
544 target_set_examined(target);
545
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;
552 }
553
554 return ERROR_OK;
555 }
556
557 static int mips32_configure_ibs(struct target *target)
558 {
559 struct mips32_common *mips32 = target_to_mips32(target);
560 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
561 int retval, i;
562 uint32_t bpinfo;
563
564 /* get number of inst breakpoints */
565 retval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo);
566 if (retval != ERROR_OK)
567 return retval;
568
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));
573
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);
578
579 /* clear IBIS reg */
580 retval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0);
581 return retval;
582 }
583
584 static int mips32_configure_dbs(struct target *target)
585 {
586 struct mips32_common *mips32 = target_to_mips32(target);
587 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
588 int retval, i;
589 uint32_t bpinfo;
590
591 /* get number of data breakpoints */
592 retval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo);
593 if (retval != ERROR_OK)
594 return retval;
595
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));
600
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);
605
606 /* clear DBIS reg */
607 retval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0);
608 return retval;
609 }
610
611 int mips32_configure_break_unit(struct target *target)
612 {
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;
616 int retval;
617 uint32_t dcr;
618
619 if (mips32->bp_scanned)
620 return ERROR_OK;
621
622 /* get info about breakpoint support */
623 retval = target_read_u32(target, EJTAG_DCR, &dcr);
624 if (retval != ERROR_OK)
625 return retval;
626
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;
634 } else
635 /* keep debug caps for later use */
636 ejtag_info->debug_caps = dcr & (EJTAG_DCR_ENM
637 | EJTAG_DCR_IB | EJTAG_DCR_DB);
638
639
640 if (ejtag_info->debug_caps & EJTAG_DCR_IB) {
641 retval = mips32_configure_ibs(target);
642 if (retval != ERROR_OK)
643 return retval;
644 }
645
646 if (ejtag_info->debug_caps & EJTAG_DCR_DB) {
647 retval = mips32_configure_dbs(target);
648 if (retval != ERROR_OK)
649 return retval;
650 }
651
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");
658
659 LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints,
660 mips32->num_data_bpoints);
661
662 mips32->bp_scanned = 1;
663
664 return ERROR_OK;
665 }
666
667 int mips32_enable_interrupts(struct target *target, int enable)
668 {
669 int retval;
670 int update = 0;
671 uint32_t dcr;
672
673 /* read debug control register */
674 retval = target_read_u32(target, EJTAG_DCR, &dcr);
675 if (retval != ERROR_OK)
676 return retval;
677
678 if (enable) {
679 if (!(dcr & EJTAG_DCR_INTE)) {
680 /* enable interrupts */
681 dcr |= EJTAG_DCR_INTE;
682 update = 1;
683 }
684 } else {
685 if (dcr & EJTAG_DCR_INTE) {
686 /* disable interrupts */
687 dcr &= ~EJTAG_DCR_INTE;
688 update = 1;
689 }
690 }
691
692 if (update) {
693 retval = target_write_u32(target, EJTAG_DCR, dcr);
694 if (retval != ERROR_OK)
695 return retval;
696 }
697
698 return ERROR_OK;
699 }
700
701 int mips32_checksum_memory(struct target *target, uint32_t address,
702 uint32_t count, uint32_t *checksum)
703 {
704 struct working_area *crc_algorithm;
705 struct reg_param reg_params[2];
706 struct mips32_algorithm mips32_info;
707
708 /* see contrib/loaders/checksum/mips32.s for src */
709
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 */
716 /* nbyte: */
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 */
724 /* loop: */
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 */
733 /* ncomp: */
734 0x154BFFF0, /* bne $t2, $t3, nbyte */
735 0x256B0001, /* addiu $t3, $t3, 1 */
736 0x7000003F, /* sdbbp */
737 };
738
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;
742
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);
747
748 target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);
749
750 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
751 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
752
753 init_reg_param(&reg_params[0], "r4", 32, PARAM_IN_OUT);
754 buf_set_u32(reg_params[0].value, 0, 32, address);
755
756 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
757 buf_set_u32(reg_params[1].value, 0, 32, count);
758
759 int timeout = 20000 * (1 + (count / (1024 * 1024)));
760
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,
763 &mips32_info);
764
765 if (retval == ERROR_OK)
766 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
767
768 destroy_reg_param(&reg_params[0]);
769 destroy_reg_param(&reg_params[1]);
770
771 target_free_working_area(target, crc_algorithm);
772
773 return retval;
774 }
775
776 /** Checks whether a memory region is zeroed. */
777 int mips32_blank_check_memory(struct target *target,
778 uint32_t address, uint32_t count, uint32_t *blank)
779 {
780 struct working_area *erase_check_algorithm;
781 struct reg_param reg_params[3];
782 struct mips32_algorithm mips32_info;
783
784 static const uint32_t erase_check_code[] = {
785 /* nbyte: */
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 */
792 };
793
794 /* make sure we have a working area */
795 if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
796 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
797
798 /* convert erase check code into a buffer in target endianness */
799 uint8_t erase_check_code_8[sizeof(erase_check_code)];
800 target_buffer_set_u32_array(target, erase_check_code_8,
801 ARRAY_SIZE(erase_check_code), erase_check_code);
802
803 target_write_buffer(target, erase_check_algorithm->address, sizeof(erase_check_code), erase_check_code_8);
804
805 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
806 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
807
808 init_reg_param(&reg_params[0], "r4", 32, PARAM_OUT);
809 buf_set_u32(reg_params[0].value, 0, 32, address);
810
811 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
812 buf_set_u32(reg_params[1].value, 0, 32, count);
813
814 init_reg_param(&reg_params[2], "r6", 32, PARAM_IN_OUT);
815 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
816
817 int retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
818 erase_check_algorithm->address,
819 erase_check_algorithm->address + (sizeof(erase_check_code) - 4),
820 10000, &mips32_info);
821
822 if (retval == ERROR_OK)
823 *blank = buf_get_u32(reg_params[2].value, 0, 32);
824
825 destroy_reg_param(&reg_params[0]);
826 destroy_reg_param(&reg_params[1]);
827 destroy_reg_param(&reg_params[2]);
828
829 target_free_working_area(target, erase_check_algorithm);
830
831 return retval;
832 }
833
834 static int mips32_verify_pointer(struct command_context *cmd_ctx,
835 struct mips32_common *mips32)
836 {
837 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
838 command_print(cmd_ctx, "target is not an MIPS32");
839 return ERROR_TARGET_INVALID;
840 }
841 return ERROR_OK;
842 }
843
844 /**
845 * MIPS32 targets expose command interface
846 * to manipulate CP0 registers
847 */
848 COMMAND_HANDLER(mips32_handle_cp0_command)
849 {
850 int retval;
851 struct target *target = get_current_target(CMD_CTX);
852 struct mips32_common *mips32 = target_to_mips32(target);
853 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
854
855
856 retval = mips32_verify_pointer(CMD_CTX, mips32);
857 if (retval != ERROR_OK)
858 return retval;
859
860 if (target->state != TARGET_HALTED) {
861 command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
862 return ERROR_OK;
863 }
864
865 /* two or more argument, access a single register/select (write if third argument is given) */
866 if (CMD_ARGC < 2)
867 return ERROR_COMMAND_SYNTAX_ERROR;
868 else {
869 uint32_t cp0_reg, cp0_sel;
870 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
871 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
872
873 if (CMD_ARGC == 2) {
874 uint32_t value;
875
876 retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
877 if (retval != ERROR_OK) {
878 command_print(CMD_CTX,
879 "couldn't access reg %" PRIi32,
880 cp0_reg);
881 return ERROR_OK;
882 }
883 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
884 cp0_reg, cp0_sel, value);
885
886 } else if (CMD_ARGC == 3) {
887 uint32_t value;
888 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
889 retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
890 if (retval != ERROR_OK) {
891 command_print(CMD_CTX,
892 "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
893 cp0_reg, cp0_sel);
894 return ERROR_OK;
895 }
896 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
897 cp0_reg, cp0_sel, value);
898 }
899 }
900
901 return ERROR_OK;
902 }
903
904 COMMAND_HANDLER(mips32_handle_scan_delay_command)
905 {
906 struct target *target = get_current_target(CMD_CTX);
907 struct mips32_common *mips32 = target_to_mips32(target);
908 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
909
910 if (CMD_ARGC == 1)
911 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);
912 else if (CMD_ARGC > 1)
913 return ERROR_COMMAND_SYNTAX_ERROR;
914
915 command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay);
916 if (ejtag_info->scan_delay >= 2000000) {
917 ejtag_info->mode = 0;
918 command_print(CMD_CTX, "running in legacy mode");
919 } else {
920 ejtag_info->mode = 1;
921 command_print(CMD_CTX, "running in fast queued mode");
922 }
923
924 return ERROR_OK;
925 }
926
927 static const struct command_registration mips32_exec_command_handlers[] = {
928 {
929 .name = "cp0",
930 .handler = mips32_handle_cp0_command,
931 .mode = COMMAND_EXEC,
932 .usage = "regnum select [value]",
933 .help = "display/modify cp0 register",
934 },
935 {
936 .name = "scan_delay",
937 .handler = mips32_handle_scan_delay_command,
938 .mode = COMMAND_ANY,
939 .help = "display/set scan delay in nano seconds",
940 .usage = "[value]",
941 },
942 COMMAND_REGISTRATION_DONE
943 };
944
945 const struct command_registration mips32_command_handlers[] = {
946 {
947 .name = "mips32",
948 .mode = COMMAND_ANY,
949 .help = "mips32 command group",
950 .usage = "",
951 .chain = mips32_exec_command_handlers,
952 },
953 COMMAND_REGISTRATION_DONE
954 };

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)