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

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)