mips: add breakpoint support for EJTAG 2.0
[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 char *mips32_core_reg_list[] = {
39 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
40 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
41 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
42 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra",
43 "status", "lo", "hi", "badvaddr", "cause", "pc"
44 };
45
46 static const char *mips_isa_strings[] = {
47 "MIPS32", "MIPS16e"
48 };
49
50 static struct mips32_core_reg mips32_core_reg_list_arch_info[MIPS32NUMCOREREGS] = {
51 {0, NULL, NULL},
52 {1, NULL, NULL},
53 {2, NULL, NULL},
54 {3, NULL, NULL},
55 {4, NULL, NULL},
56 {5, NULL, NULL},
57 {6, NULL, NULL},
58 {7, NULL, NULL},
59 {8, NULL, NULL},
60 {9, NULL, NULL},
61 {10, NULL, NULL},
62 {11, NULL, NULL},
63 {12, NULL, NULL},
64 {13, NULL, NULL},
65 {14, NULL, NULL},
66 {15, NULL, NULL},
67 {16, NULL, NULL},
68 {17, NULL, NULL},
69 {18, NULL, NULL},
70 {19, NULL, NULL},
71 {20, NULL, NULL},
72 {21, NULL, NULL},
73 {22, NULL, NULL},
74 {23, NULL, NULL},
75 {24, NULL, NULL},
76 {25, NULL, NULL},
77 {26, NULL, NULL},
78 {27, NULL, NULL},
79 {28, NULL, NULL},
80 {29, NULL, NULL},
81 {30, NULL, NULL},
82 {31, NULL, NULL},
83
84 {32, NULL, NULL},
85 {33, NULL, NULL},
86 {34, NULL, NULL},
87 {35, NULL, NULL},
88 {36, NULL, NULL},
89 {37, NULL, NULL},
90 };
91
92 /* number of mips dummy fp regs fp0 - fp31 + fsr and fir
93 * we also add 18 unknown registers to handle gdb requests */
94
95 #define MIPS32NUMFPREGS (34 + 18)
96
97 static uint8_t mips32_gdb_dummy_fp_value[] = {0, 0, 0, 0};
98
99 static struct reg mips32_gdb_dummy_fp_reg = {
100 .name = "GDB dummy floating-point register",
101 .value = mips32_gdb_dummy_fp_value,
102 .dirty = 0,
103 .valid = 1,
104 .size = 32,
105 .arch_info = NULL,
106 };
107
108 static int mips32_get_core_reg(struct reg *reg)
109 {
110 int retval;
111 struct mips32_core_reg *mips32_reg = reg->arch_info;
112 struct target *target = mips32_reg->target;
113 struct mips32_common *mips32_target = target_to_mips32(target);
114
115 if (target->state != TARGET_HALTED)
116 return ERROR_TARGET_NOT_HALTED;
117
118 retval = mips32_target->read_core_reg(target, mips32_reg->num);
119
120 return retval;
121 }
122
123 static int mips32_set_core_reg(struct reg *reg, uint8_t *buf)
124 {
125 struct mips32_core_reg *mips32_reg = reg->arch_info;
126 struct target *target = mips32_reg->target;
127 uint32_t value = buf_get_u32(buf, 0, 32);
128
129 if (target->state != TARGET_HALTED)
130 return ERROR_TARGET_NOT_HALTED;
131
132 buf_set_u32(reg->value, 0, 32, value);
133 reg->dirty = 1;
134 reg->valid = 1;
135
136 return ERROR_OK;
137 }
138
139 static int mips32_read_core_reg(struct target *target, int num)
140 {
141 uint32_t reg_value;
142
143 /* get pointers to arch-specific information */
144 struct mips32_common *mips32 = target_to_mips32(target);
145
146 if ((num < 0) || (num >= MIPS32NUMCOREREGS))
147 return ERROR_COMMAND_SYNTAX_ERROR;
148
149 reg_value = mips32->core_regs[num];
150 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
151 mips32->core_cache->reg_list[num].valid = 1;
152 mips32->core_cache->reg_list[num].dirty = 0;
153
154 return ERROR_OK;
155 }
156
157 static int mips32_write_core_reg(struct target *target, int num)
158 {
159 uint32_t reg_value;
160
161 /* get pointers to arch-specific information */
162 struct mips32_common *mips32 = target_to_mips32(target);
163
164 if ((num < 0) || (num >= MIPS32NUMCOREREGS))
165 return ERROR_COMMAND_SYNTAX_ERROR;
166
167 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
168 mips32->core_regs[num] = reg_value;
169 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value);
170 mips32->core_cache->reg_list[num].valid = 1;
171 mips32->core_cache->reg_list[num].dirty = 0;
172
173 return ERROR_OK;
174 }
175
176 int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size)
177 {
178 /* get pointers to arch-specific information */
179 struct mips32_common *mips32 = target_to_mips32(target);
180 int i;
181
182 /* include floating point registers */
183 *reg_list_size = MIPS32NUMCOREREGS + MIPS32NUMFPREGS;
184 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
185
186 for (i = 0; i < MIPS32NUMCOREREGS; i++)
187 (*reg_list)[i] = &mips32->core_cache->reg_list[i];
188
189 /* add dummy floating points regs */
190 for (i = MIPS32NUMCOREREGS; i < (MIPS32NUMCOREREGS + MIPS32NUMFPREGS); i++)
191 (*reg_list)[i] = &mips32_gdb_dummy_fp_reg;
192
193 return ERROR_OK;
194 }
195
196 int mips32_save_context(struct target *target)
197 {
198 int i;
199
200 /* get pointers to arch-specific information */
201 struct mips32_common *mips32 = target_to_mips32(target);
202 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
203
204 /* read core registers */
205 mips32_pracc_read_regs(ejtag_info, mips32->core_regs);
206
207 for (i = 0; i < MIPS32NUMCOREREGS; i++) {
208 if (!mips32->core_cache->reg_list[i].valid)
209 mips32->read_core_reg(target, i);
210 }
211
212 return ERROR_OK;
213 }
214
215 int mips32_restore_context(struct target *target)
216 {
217 int i;
218
219 /* get pointers to arch-specific information */
220 struct mips32_common *mips32 = target_to_mips32(target);
221 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
222
223 for (i = 0; i < MIPS32NUMCOREREGS; i++) {
224 if (mips32->core_cache->reg_list[i].dirty)
225 mips32->write_core_reg(target, i);
226 }
227
228 /* write core regs */
229 mips32_pracc_write_regs(ejtag_info, mips32->core_regs);
230
231 return ERROR_OK;
232 }
233
234 int mips32_arch_state(struct target *target)
235 {
236 struct mips32_common *mips32 = target_to_mips32(target);
237
238 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32 "",
239 mips_isa_strings[mips32->isa_mode],
240 debug_reason_name(target),
241 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
242
243 return ERROR_OK;
244 }
245
246 static const struct reg_arch_type mips32_reg_type = {
247 .get = mips32_get_core_reg,
248 .set = mips32_set_core_reg,
249 };
250
251 struct reg_cache *mips32_build_reg_cache(struct target *target)
252 {
253 /* get pointers to arch-specific information */
254 struct mips32_common *mips32 = target_to_mips32(target);
255
256 int num_regs = MIPS32NUMCOREREGS;
257 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
258 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
259 struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
260 struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);
261 int i;
262
263 register_init_dummy(&mips32_gdb_dummy_fp_reg);
264
265 /* Build the process context cache */
266 cache->name = "mips32 registers";
267 cache->next = NULL;
268 cache->reg_list = reg_list;
269 cache->num_regs = num_regs;
270 (*cache_p) = cache;
271 mips32->core_cache = cache;
272
273 for (i = 0; i < num_regs; i++) {
274 arch_info[i] = mips32_core_reg_list_arch_info[i];
275 arch_info[i].target = target;
276 arch_info[i].mips32_common = mips32;
277 reg_list[i].name = mips32_core_reg_list[i];
278 reg_list[i].size = 32;
279 reg_list[i].value = calloc(1, 4);
280 reg_list[i].dirty = 0;
281 reg_list[i].valid = 0;
282 reg_list[i].type = &mips32_reg_type;
283 reg_list[i].arch_info = &arch_info[i];
284 }
285
286 return cache;
287 }
288
289 int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, struct jtag_tap *tap)
290 {
291 target->arch_info = mips32;
292 mips32->common_magic = MIPS32_COMMON_MAGIC;
293 mips32->fast_data_area = NULL;
294
295 /* has breakpoint/watchpint unit been scanned */
296 mips32->bp_scanned = 0;
297 mips32->data_break_list = NULL;
298
299 mips32->ejtag_info.tap = tap;
300 mips32->read_core_reg = mips32_read_core_reg;
301 mips32->write_core_reg = mips32_write_core_reg;
302
303 mips32->ejtag_info.scan_delay = 2000000; /* Initial default value */
304 mips32->ejtag_info.mode = 0; /* Initial default value */
305
306 return ERROR_OK;
307 }
308
309 /* run to exit point. return error if exit point was not reached. */
310 static int mips32_run_and_wait(struct target *target, uint32_t entry_point,
311 int timeout_ms, uint32_t exit_point, struct mips32_common *mips32)
312 {
313 uint32_t pc;
314 int retval;
315 /* This code relies on the target specific resume() and poll()->debug_entry()
316 * sequence to write register values to the processor and the read them back */
317 retval = target_resume(target, 0, entry_point, 0, 1);
318 if (retval != ERROR_OK)
319 return retval;
320
321 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
322 /* If the target fails to halt due to the breakpoint, force a halt */
323 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
324 retval = target_halt(target);
325 if (retval != ERROR_OK)
326 return retval;
327 retval = target_wait_state(target, TARGET_HALTED, 500);
328 if (retval != ERROR_OK)
329 return retval;
330 return ERROR_TARGET_TIMEOUT;
331 }
332
333 pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
334 if (exit_point && (pc != exit_point)) {
335 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
336 return ERROR_TARGET_TIMEOUT;
337 }
338
339 return ERROR_OK;
340 }
341
342 int mips32_run_algorithm(struct target *target, int num_mem_params,
343 struct mem_param *mem_params, int num_reg_params,
344 struct reg_param *reg_params, uint32_t entry_point,
345 uint32_t exit_point, int timeout_ms, void *arch_info)
346 {
347 struct mips32_common *mips32 = target_to_mips32(target);
348 struct mips32_algorithm *mips32_algorithm_info = arch_info;
349 enum mips32_isa_mode isa_mode = mips32->isa_mode;
350
351 uint32_t context[MIPS32NUMCOREREGS];
352 int i;
353 int retval = ERROR_OK;
354
355 LOG_DEBUG("Running algorithm");
356
357 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
358 * at the exit point */
359
360 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
361 LOG_ERROR("current target isn't a MIPS32 target");
362 return ERROR_TARGET_INVALID;
363 }
364
365 if (target->state != TARGET_HALTED) {
366 LOG_WARNING("target not halted");
367 return ERROR_TARGET_NOT_HALTED;
368 }
369
370 /* refresh core register cache */
371 for (i = 0; i < MIPS32NUMCOREREGS; i++) {
372 if (!mips32->core_cache->reg_list[i].valid)
373 mips32->read_core_reg(target, i);
374 context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
375 }
376
377 for (i = 0; i < num_mem_params; i++) {
378 retval = target_write_buffer(target, mem_params[i].address,
379 mem_params[i].size, mem_params[i].value);
380 if (retval != ERROR_OK)
381 return retval;
382 }
383
384 for (i = 0; i < num_reg_params; i++) {
385 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
386
387 if (!reg) {
388 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
389 return ERROR_COMMAND_SYNTAX_ERROR;
390 }
391
392 if (reg->size != reg_params[i].size) {
393 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
394 reg_params[i].reg_name);
395 return ERROR_COMMAND_SYNTAX_ERROR;
396 }
397
398 mips32_set_core_reg(reg, reg_params[i].value);
399 }
400
401 mips32->isa_mode = mips32_algorithm_info->isa_mode;
402
403 retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32);
404
405 if (retval != ERROR_OK)
406 return retval;
407
408 for (i = 0; i < num_mem_params; i++) {
409 if (mem_params[i].direction != PARAM_OUT) {
410 retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size,
411 mem_params[i].value);
412 if (retval != ERROR_OK)
413 return retval;
414 }
415 }
416
417 for (i = 0; i < num_reg_params; i++) {
418 if (reg_params[i].direction != PARAM_OUT) {
419 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
420 if (!reg) {
421 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
422 return ERROR_COMMAND_SYNTAX_ERROR;
423 }
424
425 if (reg->size != reg_params[i].size) {
426 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
427 reg_params[i].reg_name);
428 return ERROR_COMMAND_SYNTAX_ERROR;
429 }
430
431 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
432 }
433 }
434
435 /* restore everything we saved before */
436 for (i = 0; i < MIPS32NUMCOREREGS; i++) {
437 uint32_t regvalue;
438 regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
439 if (regvalue != context[i]) {
440 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
441 mips32->core_cache->reg_list[i].name, context[i]);
442 buf_set_u32(mips32->core_cache->reg_list[i].value,
443 0, 32, context[i]);
444 mips32->core_cache->reg_list[i].valid = 1;
445 mips32->core_cache->reg_list[i].dirty = 1;
446 }
447 }
448
449 mips32->isa_mode = isa_mode;
450
451 return ERROR_OK;
452 }
453
454 int mips32_examine(struct target *target)
455 {
456 struct mips32_common *mips32 = target_to_mips32(target);
457
458 if (!target_was_examined(target)) {
459 target_set_examined(target);
460
461 /* we will configure later */
462 mips32->bp_scanned = 0;
463 mips32->num_inst_bpoints = 0;
464 mips32->num_data_bpoints = 0;
465 mips32->num_inst_bpoints_avail = 0;
466 mips32->num_data_bpoints_avail = 0;
467 }
468
469 return ERROR_OK;
470 }
471
472 static int mips32_configure_ibs(struct target *target)
473 {
474 struct mips32_common *mips32 = target_to_mips32(target);
475 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
476 int retval, i;
477 uint32_t bpinfo;
478
479 /* get number of inst breakpoints */
480 retval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo);
481 if (retval != ERROR_OK)
482 return retval;
483
484 mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
485 mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
486 mips32->inst_break_list = calloc(mips32->num_inst_bpoints,
487 sizeof(struct mips32_comparator));
488
489 for (i = 0; i < mips32->num_inst_bpoints; i++)
490 mips32->inst_break_list[i].reg_address =
491 ejtag_info->ejtag_iba0_addr +
492 (ejtag_info->ejtag_iba_step_size * i);
493
494 /* clear IBIS reg */
495 retval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0);
496 return retval;
497 }
498
499 static int mips32_configure_dbs(struct target *target)
500 {
501 struct mips32_common *mips32 = target_to_mips32(target);
502 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
503 int retval, i;
504 uint32_t bpinfo;
505
506 /* get number of data breakpoints */
507 retval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo);
508 if (retval != ERROR_OK)
509 return retval;
510
511 mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
512 mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
513 mips32->data_break_list = calloc(mips32->num_data_bpoints,
514 sizeof(struct mips32_comparator));
515
516 for (i = 0; i < mips32->num_data_bpoints; i++)
517 mips32->data_break_list[i].reg_address =
518 ejtag_info->ejtag_dba0_addr +
519 (ejtag_info->ejtag_dba_step_size * i);
520
521 /* clear DBIS reg */
522 retval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0);
523 return retval;
524 }
525
526 int mips32_configure_break_unit(struct target *target)
527 {
528 /* get pointers to arch-specific information */
529 struct mips32_common *mips32 = target_to_mips32(target);
530 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
531 int retval;
532 uint32_t dcr;
533
534 if (mips32->bp_scanned)
535 return ERROR_OK;
536
537 /* get info about breakpoint support */
538 retval = target_read_u32(target, EJTAG_DCR, &dcr);
539 if (retval != ERROR_OK)
540 return retval;
541
542 /* EJTAG 2.0 does not specify EJTAG_DCR_IB and EJTAG_DCR_DB bits,
543 * assume IB and DB registers are always present. */
544 if (ejtag_info->ejtag_version == EJTAG_VERSION_20)
545 dcr |= EJTAG_DCR_IB | EJTAG_DCR_DB;
546
547 if (dcr & EJTAG_DCR_IB) {
548 retval = mips32_configure_ibs(target);
549 if (retval != ERROR_OK)
550 return retval;
551 }
552
553 if (dcr & EJTAG_DCR_DB) {
554 retval = mips32_configure_dbs(target);
555 if (retval != ERROR_OK)
556 return retval;
557 }
558
559 /* check if target endianness settings matches debug control register */
560 if (((dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_LITTLE_ENDIAN)) ||
561 (!(dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_BIG_ENDIAN)))
562 LOG_WARNING("DCR endianness settings does not match target settings");
563
564 LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints,
565 mips32->num_data_bpoints);
566
567 mips32->bp_scanned = 1;
568
569 return ERROR_OK;
570 }
571
572 int mips32_enable_interrupts(struct target *target, int enable)
573 {
574 int retval;
575 int update = 0;
576 uint32_t dcr;
577
578 /* read debug control register */
579 retval = target_read_u32(target, EJTAG_DCR, &dcr);
580 if (retval != ERROR_OK)
581 return retval;
582
583 if (enable) {
584 if (!(dcr & EJTAG_DCR_INTE)) {
585 /* enable interrupts */
586 dcr |= EJTAG_DCR_INTE;
587 update = 1;
588 }
589 } else {
590 if (dcr & EJTAG_DCR_INTE) {
591 /* disable interrupts */
592 dcr &= ~EJTAG_DCR_INTE;
593 update = 1;
594 }
595 }
596
597 if (update) {
598 retval = target_write_u32(target, EJTAG_DCR, dcr);
599 if (retval != ERROR_OK)
600 return retval;
601 }
602
603 return ERROR_OK;
604 }
605
606 int mips32_checksum_memory(struct target *target, uint32_t address,
607 uint32_t count, uint32_t *checksum)
608 {
609 struct working_area *crc_algorithm;
610 struct reg_param reg_params[2];
611 struct mips32_algorithm mips32_info;
612 int retval;
613 uint32_t i;
614
615 /* see contib/loaders/checksum/mips32.s for src */
616
617 static const uint32_t mips_crc_code[] = {
618 0x248C0000, /* addiu $t4, $a0, 0 */
619 0x24AA0000, /* addiu $t2, $a1, 0 */
620 0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */
621 0x10000010, /* beq $zero, $zero, ncomp */
622 0x240B0000, /* addiu $t3, $zero, 0 */
623 /* nbyte: */
624 0x81850000, /* lb $a1, ($t4) */
625 0x218C0001, /* addi $t4, $t4, 1 */
626 0x00052E00, /* sll $a1, $a1, 24 */
627 0x3C0204C1, /* lui $v0, 0x04c1 */
628 0x00852026, /* xor $a0, $a0, $a1 */
629 0x34471DB7, /* ori $a3, $v0, 0x1db7 */
630 0x00003021, /* addu $a2, $zero, $zero */
631 /* loop: */
632 0x00044040, /* sll $t0, $a0, 1 */
633 0x24C60001, /* addiu $a2, $a2, 1 */
634 0x28840000, /* slti $a0, $a0, 0 */
635 0x01074826, /* xor $t1, $t0, $a3 */
636 0x0124400B, /* movn $t0, $t1, $a0 */
637 0x28C30008, /* slti $v1, $a2, 8 */
638 0x1460FFF9, /* bne $v1, $zero, loop */
639 0x01002021, /* addu $a0, $t0, $zero */
640 /* ncomp: */
641 0x154BFFF0, /* bne $t2, $t3, nbyte */
642 0x256B0001, /* addiu $t3, $t3, 1 */
643 0x7000003F, /* sdbbp */
644 };
645
646 /* make sure we have a working area */
647 if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)
648 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
649
650 /* convert flash writing code into a buffer in target endianness */
651 for (i = 0; i < ARRAY_SIZE(mips_crc_code); i++)
652 target_write_u32(target, crc_algorithm->address + i*sizeof(uint32_t), mips_crc_code[i]);
653
654 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
655 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
656
657 init_reg_param(&reg_params[0], "a0", 32, PARAM_IN_OUT);
658 buf_set_u32(reg_params[0].value, 0, 32, address);
659
660 init_reg_param(&reg_params[1], "a1", 32, PARAM_OUT);
661 buf_set_u32(reg_params[1].value, 0, 32, count);
662
663 int timeout = 20000 * (1 + (count / (1024 * 1024)));
664
665 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
666 crc_algorithm->address, crc_algorithm->address + (sizeof(mips_crc_code)-4), timeout,
667 &mips32_info);
668 if (retval != ERROR_OK) {
669 destroy_reg_param(&reg_params[0]);
670 destroy_reg_param(&reg_params[1]);
671 target_free_working_area(target, crc_algorithm);
672 return retval;
673 }
674
675 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
676
677 destroy_reg_param(&reg_params[0]);
678 destroy_reg_param(&reg_params[1]);
679
680 target_free_working_area(target, crc_algorithm);
681
682 return ERROR_OK;
683 }
684
685 /** Checks whether a memory region is zeroed. */
686 int mips32_blank_check_memory(struct target *target,
687 uint32_t address, uint32_t count, uint32_t *blank)
688 {
689 struct working_area *erase_check_algorithm;
690 struct reg_param reg_params[3];
691 struct mips32_algorithm mips32_info;
692 int retval;
693 uint32_t i;
694
695 static const uint32_t erase_check_code[] = {
696 /* nbyte: */
697 0x80880000, /* lb $t0, ($a0) */
698 0x00C83024, /* and $a2, $a2, $t0 */
699 0x24A5FFFF, /* addiu $a1, $a1, -1 */
700 0x14A0FFFC, /* bne $a1, $zero, nbyte */
701 0x24840001, /* addiu $a0, $a0, 1 */
702 0x7000003F /* sdbbp */
703 };
704
705 /* make sure we have a working area */
706 if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
707 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
708
709 /* convert flash writing code into a buffer in target endianness */
710 for (i = 0; i < ARRAY_SIZE(erase_check_code); i++) {
711 target_write_u32(target, erase_check_algorithm->address + i*sizeof(uint32_t),
712 erase_check_code[i]);
713 }
714
715 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
716 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
717
718 init_reg_param(&reg_params[0], "a0", 32, PARAM_OUT);
719 buf_set_u32(reg_params[0].value, 0, 32, address);
720
721 init_reg_param(&reg_params[1], "a1", 32, PARAM_OUT);
722 buf_set_u32(reg_params[1].value, 0, 32, count);
723
724 init_reg_param(&reg_params[2], "a2", 32, PARAM_IN_OUT);
725 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
726
727 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
728 erase_check_algorithm->address,
729 erase_check_algorithm->address + (sizeof(erase_check_code)-4),
730 10000, &mips32_info);
731 if (retval != ERROR_OK) {
732 destroy_reg_param(&reg_params[0]);
733 destroy_reg_param(&reg_params[1]);
734 destroy_reg_param(&reg_params[2]);
735 target_free_working_area(target, erase_check_algorithm);
736 return retval;
737 }
738
739 *blank = buf_get_u32(reg_params[2].value, 0, 32);
740
741 destroy_reg_param(&reg_params[0]);
742 destroy_reg_param(&reg_params[1]);
743 destroy_reg_param(&reg_params[2]);
744
745 target_free_working_area(target, erase_check_algorithm);
746
747 return ERROR_OK;
748 }
749
750 static int mips32_verify_pointer(struct command_context *cmd_ctx,
751 struct mips32_common *mips32)
752 {
753 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
754 command_print(cmd_ctx, "target is not an MIPS32");
755 return ERROR_TARGET_INVALID;
756 }
757 return ERROR_OK;
758 }
759
760 /**
761 * MIPS32 targets expose command interface
762 * to manipulate CP0 registers
763 */
764 COMMAND_HANDLER(mips32_handle_cp0_command)
765 {
766 int retval;
767 struct target *target = get_current_target(CMD_CTX);
768 struct mips32_common *mips32 = target_to_mips32(target);
769 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
770
771
772 retval = mips32_verify_pointer(CMD_CTX, mips32);
773 if (retval != ERROR_OK)
774 return retval;
775
776 if (target->state != TARGET_HALTED) {
777 command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
778 return ERROR_OK;
779 }
780
781 /* two or more argument, access a single register/select (write if third argument is given) */
782 if (CMD_ARGC < 2)
783 return ERROR_COMMAND_SYNTAX_ERROR;
784 else {
785 uint32_t cp0_reg, cp0_sel;
786 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
787 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
788
789 if (CMD_ARGC == 2) {
790 uint32_t value;
791
792 retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
793 if (retval != ERROR_OK) {
794 command_print(CMD_CTX,
795 "couldn't access reg %" PRIi32,
796 cp0_reg);
797 return ERROR_OK;
798 }
799 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
800 cp0_reg, cp0_sel, value);
801
802 } else if (CMD_ARGC == 3) {
803 uint32_t value;
804 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
805 retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
806 if (retval != ERROR_OK) {
807 command_print(CMD_CTX,
808 "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
809 cp0_reg, cp0_sel);
810 return ERROR_OK;
811 }
812 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
813 cp0_reg, cp0_sel, value);
814 }
815 }
816
817 return ERROR_OK;
818 }
819
820 COMMAND_HANDLER(mips32_handle_scan_delay_command)
821 {
822 struct target *target = get_current_target(CMD_CTX);
823 struct mips32_common *mips32 = target_to_mips32(target);
824 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
825
826 if (CMD_ARGC == 1)
827 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], ejtag_info->scan_delay);
828 else if (CMD_ARGC > 1)
829 return ERROR_COMMAND_SYNTAX_ERROR;
830
831 command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay);
832 if (ejtag_info->scan_delay >= 2000000) {
833 ejtag_info->mode = 0;
834 command_print(CMD_CTX, "running in legacy mode");
835 } else {
836 ejtag_info->mode = 1;
837 command_print(CMD_CTX, "running in fast queued mode");
838 }
839
840 return ERROR_OK;
841 }
842
843 static const struct command_registration mips32_exec_command_handlers[] = {
844 {
845 .name = "cp0",
846 .handler = mips32_handle_cp0_command,
847 .mode = COMMAND_EXEC,
848 .usage = "regnum select [value]",
849 .help = "display/modify cp0 register",
850 },
851 {
852 .name = "scan_delay",
853 .handler = mips32_handle_scan_delay_command,
854 .mode = COMMAND_ANY,
855 .help = "display/set scan delay in nano seconds",
856 .usage = "[value]",
857 },
858 COMMAND_REGISTRATION_DONE
859 };
860
861 const struct command_registration mips32_command_handlers[] = {
862 {
863 .name = "mips32",
864 .mode = COMMAND_ANY,
865 .help = "mips32 command group",
866 .usage = "",
867 .chain = mips32_exec_command_handlers,
868 },
869 COMMAND_REGISTRATION_DONE
870 };

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)