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

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)