mips32: use 'unsigned int' for CPU register indices
[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, unsigned 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 >= 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, unsigned 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 >= 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 unsigned 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 unsigned 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 unsigned 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/watchpoint 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 retval = ERROR_OK;
350
351 LOG_DEBUG("Running algorithm");
352
353 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
354 * at the exit point */
355
356 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
357 LOG_ERROR("current target isn't a MIPS32 target");
358 return ERROR_TARGET_INVALID;
359 }
360
361 if (target->state != TARGET_HALTED) {
362 LOG_WARNING("target not halted");
363 return ERROR_TARGET_NOT_HALTED;
364 }
365
366 /* refresh core register cache */
367 for (unsigned int i = 0; i < MIPS32NUMCOREREGS; i++) {
368 if (!mips32->core_cache->reg_list[i].valid)
369 mips32->read_core_reg(target, i);
370 context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
371 }
372
373 for (int i = 0; i < num_mem_params; i++) {
374 retval = target_write_buffer(target, mem_params[i].address,
375 mem_params[i].size, mem_params[i].value);
376 if (retval != ERROR_OK)
377 return retval;
378 }
379
380 for (int i = 0; i < num_reg_params; i++) {
381 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
382
383 if (!reg) {
384 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
385 return ERROR_COMMAND_SYNTAX_ERROR;
386 }
387
388 if (reg->size != reg_params[i].size) {
389 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
390 reg_params[i].reg_name);
391 return ERROR_COMMAND_SYNTAX_ERROR;
392 }
393
394 mips32_set_core_reg(reg, reg_params[i].value);
395 }
396
397 mips32->isa_mode = mips32_algorithm_info->isa_mode;
398
399 retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32);
400
401 if (retval != ERROR_OK)
402 return retval;
403
404 for (int i = 0; i < num_mem_params; i++) {
405 if (mem_params[i].direction != PARAM_OUT) {
406 retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size,
407 mem_params[i].value);
408 if (retval != ERROR_OK)
409 return retval;
410 }
411 }
412
413 for (int i = 0; i < num_reg_params; i++) {
414 if (reg_params[i].direction != PARAM_OUT) {
415 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
416 if (!reg) {
417 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
418 return ERROR_COMMAND_SYNTAX_ERROR;
419 }
420
421 if (reg->size != reg_params[i].size) {
422 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
423 reg_params[i].reg_name);
424 return ERROR_COMMAND_SYNTAX_ERROR;
425 }
426
427 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
428 }
429 }
430
431 /* restore everything we saved before */
432 for (unsigned int i = 0; i < MIPS32NUMCOREREGS; i++) {
433 uint32_t regvalue;
434 regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
435 if (regvalue != context[i]) {
436 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
437 mips32->core_cache->reg_list[i].name, context[i]);
438 buf_set_u32(mips32->core_cache->reg_list[i].value,
439 0, 32, context[i]);
440 mips32->core_cache->reg_list[i].valid = 1;
441 mips32->core_cache->reg_list[i].dirty = 1;
442 }
443 }
444
445 mips32->isa_mode = isa_mode;
446
447 return ERROR_OK;
448 }
449
450 int mips32_examine(struct target *target)
451 {
452 struct mips32_common *mips32 = target_to_mips32(target);
453
454 if (!target_was_examined(target)) {
455 target_set_examined(target);
456
457 /* we will configure later */
458 mips32->bp_scanned = 0;
459 mips32->num_inst_bpoints = 0;
460 mips32->num_data_bpoints = 0;
461 mips32->num_inst_bpoints_avail = 0;
462 mips32->num_data_bpoints_avail = 0;
463 }
464
465 return ERROR_OK;
466 }
467
468 static int mips32_configure_ibs(struct target *target)
469 {
470 struct mips32_common *mips32 = target_to_mips32(target);
471 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
472 int retval, i;
473 uint32_t bpinfo;
474
475 /* get number of inst breakpoints */
476 retval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo);
477 if (retval != ERROR_OK)
478 return retval;
479
480 mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
481 mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
482 mips32->inst_break_list = calloc(mips32->num_inst_bpoints,
483 sizeof(struct mips32_comparator));
484
485 for (i = 0; i < mips32->num_inst_bpoints; i++)
486 mips32->inst_break_list[i].reg_address =
487 ejtag_info->ejtag_iba0_addr +
488 (ejtag_info->ejtag_iba_step_size * i);
489
490 /* clear IBIS reg */
491 retval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0);
492 return retval;
493 }
494
495 static int mips32_configure_dbs(struct target *target)
496 {
497 struct mips32_common *mips32 = target_to_mips32(target);
498 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
499 int retval, i;
500 uint32_t bpinfo;
501
502 /* get number of data breakpoints */
503 retval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo);
504 if (retval != ERROR_OK)
505 return retval;
506
507 mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
508 mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
509 mips32->data_break_list = calloc(mips32->num_data_bpoints,
510 sizeof(struct mips32_comparator));
511
512 for (i = 0; i < mips32->num_data_bpoints; i++)
513 mips32->data_break_list[i].reg_address =
514 ejtag_info->ejtag_dba0_addr +
515 (ejtag_info->ejtag_dba_step_size * i);
516
517 /* clear DBIS reg */
518 retval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0);
519 return retval;
520 }
521
522 int mips32_configure_break_unit(struct target *target)
523 {
524 /* get pointers to arch-specific information */
525 struct mips32_common *mips32 = target_to_mips32(target);
526 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
527 int retval;
528 uint32_t dcr;
529
530 if (mips32->bp_scanned)
531 return ERROR_OK;
532
533 /* get info about breakpoint support */
534 retval = target_read_u32(target, EJTAG_DCR, &dcr);
535 if (retval != ERROR_OK)
536 return retval;
537
538 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
539 if (ejtag_info->ejtag_version == EJTAG_VERSION_20) {
540 ejtag_info->debug_caps = dcr & EJTAG_DCR_ENM;
541 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NOIB))
542 ejtag_info->debug_caps |= EJTAG_DCR_IB;
543 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NODB))
544 ejtag_info->debug_caps |= EJTAG_DCR_DB;
545 } else
546 /* keep debug caps for later use */
547 ejtag_info->debug_caps = dcr & (EJTAG_DCR_ENM
548 | EJTAG_DCR_IB | EJTAG_DCR_DB);
549
550
551 if (ejtag_info->debug_caps & EJTAG_DCR_IB) {
552 retval = mips32_configure_ibs(target);
553 if (retval != ERROR_OK)
554 return retval;
555 }
556
557 if (ejtag_info->debug_caps & EJTAG_DCR_DB) {
558 retval = mips32_configure_dbs(target);
559 if (retval != ERROR_OK)
560 return retval;
561 }
562
563 /* check if target endianness settings matches debug control register */
564 if (((ejtag_info->debug_caps & EJTAG_DCR_ENM)
565 && (target->endianness == TARGET_LITTLE_ENDIAN)) ||
566 (!(ejtag_info->debug_caps & EJTAG_DCR_ENM)
567 && (target->endianness == TARGET_BIG_ENDIAN)))
568 LOG_WARNING("DCR endianness settings does not match target settings");
569
570 LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints,
571 mips32->num_data_bpoints);
572
573 mips32->bp_scanned = 1;
574
575 return ERROR_OK;
576 }
577
578 int mips32_enable_interrupts(struct target *target, int enable)
579 {
580 int retval;
581 int update = 0;
582 uint32_t dcr;
583
584 /* read debug control register */
585 retval = target_read_u32(target, EJTAG_DCR, &dcr);
586 if (retval != ERROR_OK)
587 return retval;
588
589 if (enable) {
590 if (!(dcr & EJTAG_DCR_INTE)) {
591 /* enable interrupts */
592 dcr |= EJTAG_DCR_INTE;
593 update = 1;
594 }
595 } else {
596 if (dcr & EJTAG_DCR_INTE) {
597 /* disable interrupts */
598 dcr &= ~EJTAG_DCR_INTE;
599 update = 1;
600 }
601 }
602
603 if (update) {
604 retval = target_write_u32(target, EJTAG_DCR, dcr);
605 if (retval != ERROR_OK)
606 return retval;
607 }
608
609 return ERROR_OK;
610 }
611
612 int mips32_checksum_memory(struct target *target, uint32_t address,
613 uint32_t count, uint32_t *checksum)
614 {
615 struct working_area *crc_algorithm;
616 struct reg_param reg_params[2];
617 struct mips32_algorithm mips32_info;
618
619 /* see contrib/loaders/checksum/mips32.s for src */
620
621 static const uint32_t mips_crc_code[] = {
622 0x248C0000, /* addiu $t4, $a0, 0 */
623 0x24AA0000, /* addiu $t2, $a1, 0 */
624 0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */
625 0x10000010, /* beq $zero, $zero, ncomp */
626 0x240B0000, /* addiu $t3, $zero, 0 */
627 /* nbyte: */
628 0x81850000, /* lb $a1, ($t4) */
629 0x218C0001, /* addi $t4, $t4, 1 */
630 0x00052E00, /* sll $a1, $a1, 24 */
631 0x3C0204C1, /* lui $v0, 0x04c1 */
632 0x00852026, /* xor $a0, $a0, $a1 */
633 0x34471DB7, /* ori $a3, $v0, 0x1db7 */
634 0x00003021, /* addu $a2, $zero, $zero */
635 /* loop: */
636 0x00044040, /* sll $t0, $a0, 1 */
637 0x24C60001, /* addiu $a2, $a2, 1 */
638 0x28840000, /* slti $a0, $a0, 0 */
639 0x01074826, /* xor $t1, $t0, $a3 */
640 0x0124400B, /* movn $t0, $t1, $a0 */
641 0x28C30008, /* slti $v1, $a2, 8 */
642 0x1460FFF9, /* bne $v1, $zero, loop */
643 0x01002021, /* addu $a0, $t0, $zero */
644 /* ncomp: */
645 0x154BFFF0, /* bne $t2, $t3, nbyte */
646 0x256B0001, /* addiu $t3, $t3, 1 */
647 0x7000003F, /* sdbbp */
648 };
649
650 /* make sure we have a working area */
651 if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)
652 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
653
654 /* convert mips crc code into a buffer in target endianness */
655 uint8_t mips_crc_code_8[sizeof(mips_crc_code)];
656 target_buffer_set_u32_array(target, mips_crc_code_8,
657 ARRAY_SIZE(mips_crc_code), mips_crc_code);
658
659 target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);
660
661 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
662 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
663
664 init_reg_param(&reg_params[0], "a0", 32, PARAM_IN_OUT);
665 buf_set_u32(reg_params[0].value, 0, 32, address);
666
667 init_reg_param(&reg_params[1], "a1", 32, PARAM_OUT);
668 buf_set_u32(reg_params[1].value, 0, 32, count);
669
670 int timeout = 20000 * (1 + (count / (1024 * 1024)));
671
672 int retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
673 crc_algorithm->address, crc_algorithm->address + (sizeof(mips_crc_code) - 4), timeout,
674 &mips32_info);
675
676 if (retval == ERROR_OK)
677 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
678
679 destroy_reg_param(&reg_params[0]);
680 destroy_reg_param(&reg_params[1]);
681
682 target_free_working_area(target, crc_algorithm);
683
684 return retval;
685 }
686
687 /** Checks whether a memory region is zeroed. */
688 int mips32_blank_check_memory(struct target *target,
689 uint32_t address, uint32_t count, uint32_t *blank)
690 {
691 struct working_area *erase_check_algorithm;
692 struct reg_param reg_params[3];
693 struct mips32_algorithm mips32_info;
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 erase check code into a buffer in target endianness */
710 uint8_t erase_check_code_8[sizeof(erase_check_code)];
711 target_buffer_set_u32_array(target, erase_check_code_8,
712 ARRAY_SIZE(erase_check_code), erase_check_code);
713
714 target_write_buffer(target, erase_check_algorithm->address, sizeof(erase_check_code), erase_check_code_8);
715
716 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
717 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
718
719 init_reg_param(&reg_params[0], "a0", 32, PARAM_OUT);
720 buf_set_u32(reg_params[0].value, 0, 32, address);
721
722 init_reg_param(&reg_params[1], "a1", 32, PARAM_OUT);
723 buf_set_u32(reg_params[1].value, 0, 32, count);
724
725 init_reg_param(&reg_params[2], "a2", 32, PARAM_IN_OUT);
726 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
727
728 int retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
729 erase_check_algorithm->address,
730 erase_check_algorithm->address + (sizeof(erase_check_code) - 4),
731 10000, &mips32_info);
732
733 if (retval == ERROR_OK)
734 *blank = buf_get_u32(reg_params[2].value, 0, 32);
735
736 destroy_reg_param(&reg_params[0]);
737 destroy_reg_param(&reg_params[1]);
738 destroy_reg_param(&reg_params[2]);
739
740 target_free_working_area(target, erase_check_algorithm);
741
742 return retval;
743 }
744
745 static int mips32_verify_pointer(struct command_context *cmd_ctx,
746 struct mips32_common *mips32)
747 {
748 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
749 command_print(cmd_ctx, "target is not an MIPS32");
750 return ERROR_TARGET_INVALID;
751 }
752 return ERROR_OK;
753 }
754
755 /**
756 * MIPS32 targets expose command interface
757 * to manipulate CP0 registers
758 */
759 COMMAND_HANDLER(mips32_handle_cp0_command)
760 {
761 int retval;
762 struct target *target = get_current_target(CMD_CTX);
763 struct mips32_common *mips32 = target_to_mips32(target);
764 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
765
766
767 retval = mips32_verify_pointer(CMD_CTX, mips32);
768 if (retval != ERROR_OK)
769 return retval;
770
771 if (target->state != TARGET_HALTED) {
772 command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
773 return ERROR_OK;
774 }
775
776 /* two or more argument, access a single register/select (write if third argument is given) */
777 if (CMD_ARGC < 2)
778 return ERROR_COMMAND_SYNTAX_ERROR;
779 else {
780 uint32_t cp0_reg, cp0_sel;
781 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
782 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
783
784 if (CMD_ARGC == 2) {
785 uint32_t value;
786
787 retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
788 if (retval != ERROR_OK) {
789 command_print(CMD_CTX,
790 "couldn't access reg %" PRIi32,
791 cp0_reg);
792 return ERROR_OK;
793 }
794 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
795 cp0_reg, cp0_sel, value);
796
797 } else if (CMD_ARGC == 3) {
798 uint32_t value;
799 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
800 retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
801 if (retval != ERROR_OK) {
802 command_print(CMD_CTX,
803 "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
804 cp0_reg, cp0_sel);
805 return ERROR_OK;
806 }
807 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
808 cp0_reg, cp0_sel, value);
809 }
810 }
811
812 return ERROR_OK;
813 }
814
815 COMMAND_HANDLER(mips32_handle_scan_delay_command)
816 {
817 struct target *target = get_current_target(CMD_CTX);
818 struct mips32_common *mips32 = target_to_mips32(target);
819 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
820
821 if (CMD_ARGC == 1)
822 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);
823 else if (CMD_ARGC > 1)
824 return ERROR_COMMAND_SYNTAX_ERROR;
825
826 command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay);
827 if (ejtag_info->scan_delay >= 2000000) {
828 ejtag_info->mode = 0;
829 command_print(CMD_CTX, "running in legacy mode");
830 } else {
831 ejtag_info->mode = 1;
832 command_print(CMD_CTX, "running in fast queued mode");
833 }
834
835 return ERROR_OK;
836 }
837
838 static const struct command_registration mips32_exec_command_handlers[] = {
839 {
840 .name = "cp0",
841 .handler = mips32_handle_cp0_command,
842 .mode = COMMAND_EXEC,
843 .usage = "regnum select [value]",
844 .help = "display/modify cp0 register",
845 },
846 {
847 .name = "scan_delay",
848 .handler = mips32_handle_scan_delay_command,
849 .mode = COMMAND_ANY,
850 .help = "display/set scan delay in nano seconds",
851 .usage = "[value]",
852 },
853 COMMAND_REGISTRATION_DONE
854 };
855
856 const struct command_registration mips32_command_handlers[] = {
857 {
858 .name = "mips32",
859 .mode = COMMAND_ANY,
860 .help = "mips32 command group",
861 .usage = "",
862 .chain = mips32_exec_command_handlers,
863 },
864 COMMAND_REGISTRATION_DONE
865 };

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)