target/cortex_m: prevent asserting reset if examine is deferred
[openocd.git] / src / target / mips_mips64.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /*
4 * MIPS64 generic target support
5 *
6 * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>
7 * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>
8 * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>
9 *
10 * Based on the work of:
11 * Copyright (C) 2008 by Spencer Oliver
12 * Copyright (C) 2008 by David T.L. Wong
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #include "breakpoints.h"
20 #include "mips32.h"
21 #include "mips64.h"
22 #include "mips_mips64.h"
23 #include "target_type.h"
24 #include "register.h"
25
26 static int mips_mips64_unset_breakpoint(struct target *target,
27 struct breakpoint *breakpoint);
28
29 static uint64_t mips64_extend_sign(uint64_t addr)
30 {
31 if (addr >> 32)
32 return addr;
33 if (addr >> 31)
34 return addr | (ULLONG_MAX << 32);
35 return addr;
36 }
37
38 static int mips_mips64_examine_debug_reason(struct target *target)
39 {
40 if ((target->debug_reason != DBG_REASON_DBGRQ)
41 && (target->debug_reason != DBG_REASON_SINGLESTEP))
42 target->debug_reason = DBG_REASON_BREAKPOINT;
43
44 return ERROR_OK;
45 }
46
47 static int mips_mips64_debug_entry(struct target *target)
48 {
49 struct mips64_common *mips64 = target->arch_info;
50 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
51 struct reg *pc = &mips64->core_cache->reg_list[MIPS64_PC];
52
53 mips64_save_context(target);
54
55 /* make sure stepping disabled, SSt bit in CP0 debug register cleared */
56 mips64_ejtag_config_step(ejtag_info, 0);
57
58 /* make sure break unit configured */
59 mips64_configure_break_unit(target);
60
61 /* attempt to find halt reason */
62 mips_mips64_examine_debug_reason(target);
63
64 LOG_DEBUG("entered debug state at PC 0x%" PRIx64 ", target->state: %s",
65 buf_get_u64(pc->value, 0, 64), target_state_name(target));
66
67 return ERROR_OK;
68 }
69
70 static int mips_mips64_poll(struct target *target)
71 {
72 int retval;
73 struct mips64_common *mips64 = target->arch_info;
74 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
75 uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl;
76
77 /* read ejtag control reg */
78 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
79 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
80
81 /* clear this bit before handling polling
82 * as after reset registers will read zero */
83 if (ejtag_ctrl & EJTAG_CTRL_ROCC) {
84 /* we have detected a reset, clear flag
85 * otherwise ejtag will not work */
86 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
87
88 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
89 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
90 LOG_DEBUG("Reset Detected");
91 }
92
93 /* check for processor halted */
94 if (ejtag_ctrl & EJTAG_CTRL_BRKST) {
95 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) {
96 target->state = TARGET_HALTED;
97 retval = mips_mips64_debug_entry(target);
98 if (retval != ERROR_OK)
99 return retval;
100 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
101 } else if (target->state == TARGET_DEBUG_RUNNING) {
102 target->state = TARGET_HALTED;
103 retval = mips_mips64_debug_entry(target);
104 if (retval != ERROR_OK)
105 return retval;
106
107 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
108 }
109 } else {
110 target->state = TARGET_RUNNING;
111 }
112
113 return ERROR_OK;
114 }
115
116 static int mips_mips64_halt(struct target *target)
117 {
118 struct mips64_common *mips64 = target->arch_info;
119 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
120
121 LOG_DEBUG("target->state: %s",
122 target_state_name(target));
123
124 if (target->state == TARGET_HALTED) {
125 LOG_DEBUG("target was already halted");
126 return ERROR_OK;
127 }
128
129 if (target->state == TARGET_UNKNOWN)
130 LOG_WARNING("target was in unknown state when halt was requested");
131
132 if (target->state == TARGET_RESET) {
133 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {
134 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
135 return ERROR_TARGET_FAILURE;
136 } else {
137 /* we came here in a reset_halt or reset_init sequence
138 * debug entry was already prepared in mips64_prepare_reset_halt()
139 */
140 target->debug_reason = DBG_REASON_DBGRQ;
141
142 return ERROR_OK;
143 }
144 }
145
146 /* break processor */
147 mips_ejtag_enter_debug(ejtag_info);
148
149 target->debug_reason = DBG_REASON_DBGRQ;
150
151 return ERROR_OK;
152 }
153
154 static int mips_mips64_assert_reset(struct target *target)
155 {
156 struct mips64_common *mips64 = target->arch_info;
157 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
158 int retval;
159
160 LOG_DEBUG("target->state: %s",
161 target_state_name(target));
162
163 enum reset_types jtag_reset_config = jtag_get_reset_config();
164 if (!(jtag_reset_config & RESET_HAS_SRST)) {
165 LOG_ERROR("Can't assert SRST");
166 return ERROR_FAIL;
167 }
168
169 if (target->reset_halt)
170 /* use hardware to catch reset */
171 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);
172 else
173 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
174
175 /* here we should issue a srst only, but we may have to assert trst as well */
176 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
177 jtag_add_reset(1, 1);
178 else
179 jtag_add_reset(0, 1);
180
181 target->state = TARGET_RESET;
182 jtag_add_sleep(5000);
183
184 retval = mips64_invalidate_core_regs(target);
185 if (retval != ERROR_OK)
186 return retval;
187
188 if (target->reset_halt) {
189 retval = target_halt(target);
190 if (retval != ERROR_OK)
191 return retval;
192 }
193
194 return ERROR_OK;
195 }
196
197 static int mips_mips64_deassert_reset(struct target *target)
198 {
199 LOG_DEBUG("target->state: %s",
200 target_state_name(target));
201
202 /* deassert reset lines */
203 jtag_add_reset(0, 0);
204
205 return ERROR_OK;
206 }
207
208 static int mips_mips64_single_step_core(struct target *target)
209 {
210 struct mips64_common *mips64 = target->arch_info;
211 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
212 int retval;
213
214 /* configure single step mode */
215 mips64_ejtag_config_step(ejtag_info, 1);
216
217 /* disable interrupts while stepping */
218 retval = mips64_enable_interrupts(target, false);
219 if (retval != ERROR_OK)
220 return retval;
221
222 /* exit debug mode */
223 retval = mips64_ejtag_exit_debug(ejtag_info);
224 if (retval != ERROR_OK)
225 return retval;
226
227 mips_mips64_debug_entry(target);
228
229 return ERROR_OK;
230 }
231
232 /* TODO: HW breakpoints are in EJTAG spec. Should we share it for MIPS32? */
233 static int mips_mips64_set_hwbp(struct target *target, struct breakpoint *bp)
234 {
235 struct mips64_common *mips64 = target->arch_info;
236 struct mips64_comparator *c, *cl = mips64->inst_break_list;
237 uint64_t bp_value;
238 int retval, bp_num = 0;
239
240 while (cl[bp_num].used && (bp_num < mips64->num_inst_bpoints))
241 bp_num++;
242
243 if (bp_num >= mips64->num_inst_bpoints) {
244 LOG_DEBUG("ERROR Can not find free FP Comparator(bpid: %" PRIu32 ")",
245 bp->unique_id);
246 LOG_WARNING("ERROR Can not find free FP Comparator");
247 exit(-1);
248 }
249
250 c = &cl[bp_num];
251 c->used = true;
252 c->bp_value = bp->address;
253 bp_value = bp->address;
254
255 /* Instruction Breakpoint Address n (IBAn) Register */
256 retval = target_write_u64(target, c->reg_address, bp_value);
257 if (retval != ERROR_OK)
258 return retval;
259
260 /* TODO: use defines */
261 /* Instruction Breakpoint Address Mask n (IBMn) Register */
262 retval = target_write_u64(target, c->reg_address + 0x08, 0);
263 if (retval != ERROR_OK)
264 return retval;
265
266 /* Instruction Breakpoint Control n (IBCn) Register */
267 retval = target_write_u64(target, c->reg_address + 0x18, 1);
268 if (retval != ERROR_OK)
269 return retval;
270
271 LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx64, bp->unique_id,
272 bp_num, c->bp_value);
273
274 return ERROR_OK;
275 }
276
277 /* TODO: is it MIPS64 or MIPS32 instruction. If MIPS32, can it be shared with
278 * MIPS32 code? */
279 static int mips_mips64_set_sdbbp(struct target *target, struct breakpoint *bp)
280 {
281 uint32_t verify;
282 int retval;
283
284 retval = target_read_memory(target,
285 bp->address, bp->length, 1,
286 bp->orig_instr);
287 if (retval != ERROR_OK)
288 return retval;
289
290 retval = target_write_u32(target, bp->address, MIPS64_SDBBP);
291 if (retval != ERROR_OK)
292 return retval;
293
294 retval = target_read_u32(target, bp->address, &verify);
295 if (retval != ERROR_OK)
296 return retval;
297
298 if (verify != MIPS64_SDBBP) {
299 LOG_ERROR("Unable to set 32bit breakpoint at address %16" PRIx64,
300 bp->address);
301 retval = ERROR_FAIL;
302 }
303
304 return retval;
305 }
306
307 /* TODO do MIPS64 support MIPS16 instructions? Can it be shared with MIPS32
308 * code? */
309 static int mips_mips16_set_sdbbp(struct target *target, struct breakpoint *bp)
310 {
311 uint32_t isa_req = bp->length & 1;
312 uint16_t verify;
313 int retval;
314
315 retval = target_read_memory(target,
316 bp->address, bp->length, 1,
317 bp->orig_instr);
318 if (retval != ERROR_OK)
319 return retval;
320
321 retval = target_write_u16(target, bp->address, MIPS16_SDBBP(isa_req));
322 if (retval != ERROR_OK)
323 return retval;
324
325 retval = target_read_u16(target, bp->address, &verify);
326 if (retval != ERROR_OK)
327 return retval;
328
329 if (verify != MIPS16_SDBBP(isa_req)) {
330 LOG_ERROR("Unable to set 16bit breakpoint at address %16" PRIx64,
331 bp->address);
332 retval = ERROR_FAIL;
333 }
334
335 return retval;
336 }
337
338 static int mips_mips64_set_breakpoint(struct target *target,
339 struct breakpoint *bp)
340 {
341 int retval;
342
343 if (bp->is_set) {
344 LOG_WARNING("breakpoint already set");
345 return ERROR_OK;
346 }
347
348 if (bp->type == BKPT_HARD) {
349 retval = mips_mips64_set_hwbp(target, bp);
350 } else {
351 LOG_DEBUG("bpid: %" PRIu32, bp->unique_id);
352
353 switch (bp->length) {
354 case MIPS64_SDBBP_SIZE:
355 retval = mips_mips64_set_sdbbp(target, bp);
356 break;
357 case MIPS16_SDBBP_SIZE:
358 retval = mips_mips16_set_sdbbp(target, bp);
359 break;
360 default:
361 retval = ERROR_FAIL;
362 }
363 }
364
365 if (retval != ERROR_OK) {
366 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
367 return retval;
368 }
369
370 bp->is_set = true;
371
372 return ERROR_OK;
373 }
374
375 static int mips_mips64_enable_breakpoints(struct target *target)
376 {
377 struct breakpoint *bp = target->breakpoints;
378 int retval = ERROR_OK;
379
380 /* set any pending breakpoints */
381 while (bp) {
382 if (!bp->is_set) {
383 retval = mips_mips64_set_breakpoint(target, bp);
384 if (retval != ERROR_OK)
385 return retval;
386 }
387 bp = bp->next;
388 }
389
390 return ERROR_OK;
391 }
392
393 /* TODO: HW data breakpoints are in EJTAG spec. Should we share it for MIPS32? */
394 static int mips_mips64_set_watchpoint(struct target *target,
395 struct watchpoint *watchpoint)
396 {
397 uint64_t wp_value;
398 struct mips64_common *mips64 = target->arch_info;
399 struct mips64_comparator *c, *cl = mips64->data_break_list;
400 int retval, wp_num = 0;
401
402 /*
403 * watchpoint enabled, ignore all byte lanes in value register
404 * and exclude both load and store accesses from watchpoint
405 * condition evaluation
406 */
407 int enable = EJTAG_DBCN_NOSB | EJTAG_DBCN_NOLB | EJTAG_DBCN_BE
408 | (0xff << EJTAG_DBCN_BLM_SHIFT);
409
410 if (watchpoint->is_set) {
411 LOG_WARNING("watchpoint already set");
412 return ERROR_OK;
413 }
414
415 while (cl[wp_num].used && (wp_num < mips64->num_data_bpoints))
416 wp_num++;
417
418 if (wp_num >= mips64->num_data_bpoints) {
419 LOG_ERROR("ERROR Can not find free comparator");
420 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
421 }
422
423 if (watchpoint->length != 4) {
424 LOG_ERROR("Only watchpoints of length 4 are supported");
425 return ERROR_TARGET_UNALIGNED_ACCESS;
426 }
427
428 if (watchpoint->address % 4) {
429 LOG_ERROR("Watchpoints address should be word aligned");
430 return ERROR_TARGET_UNALIGNED_ACCESS;
431 }
432
433 switch (watchpoint->rw) {
434 case WPT_READ:
435 enable &= ~EJTAG_DBCN_NOLB;
436 break;
437 case WPT_WRITE:
438 enable &= ~EJTAG_DBCN_NOSB;
439 break;
440 case WPT_ACCESS:
441 enable &= ~(EJTAG_DBCN_NOLB | EJTAG_DBCN_NOSB);
442 break;
443 default:
444 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
445 }
446
447 c = &cl[wp_num];
448 watchpoint_set(watchpoint, wp_num);
449 c->used = true;
450 c->bp_value = watchpoint->address;
451
452 wp_value = watchpoint->address;
453 if (wp_value & 0x80000000)
454 wp_value |= ULLONG_MAX << 32;
455
456 retval = target_write_u64(target, c->reg_address, wp_value);
457 if (retval != ERROR_OK)
458 return retval;
459
460 retval = target_write_u64(target, c->reg_address + 0x08, 0);
461 if (retval != ERROR_OK)
462 return retval;
463
464 retval = target_write_u64(target, c->reg_address + 0x10, 0);
465 if (retval != ERROR_OK)
466 return retval;
467
468 retval = target_write_u64(target, c->reg_address + 0x18, enable);
469 if (retval != ERROR_OK)
470 return retval;
471
472 retval = target_write_u64(target, c->reg_address + 0x20, 0);
473 if (retval != ERROR_OK)
474 return retval;
475
476 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx64 "", wp_num, c->bp_value);
477
478 return ERROR_OK;
479 }
480
481 static int mips_mips64_enable_watchpoints(struct target *target)
482 {
483 struct watchpoint *watchpoint = target->watchpoints;
484 int retval;
485
486 /* set any pending watchpoints */
487 while (watchpoint) {
488 if (!watchpoint->is_set) {
489 retval = mips_mips64_set_watchpoint(target, watchpoint);
490 if (retval != ERROR_OK)
491 return retval;
492 }
493 watchpoint = watchpoint->next;
494 }
495
496 return ERROR_OK;
497 }
498
499 static int mips_mips64_unset_hwbp(struct target *target, struct breakpoint *bp)
500 {
501 struct mips64_common *mips64 = target->arch_info;
502 struct mips64_comparator *comparator_list = mips64->inst_break_list;
503
504 int bp_num = bp->number;
505
506 if (bp_num >= mips64->num_inst_bpoints) {
507 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %" PRIu32 ")",
508 bp->unique_id);
509 return ERROR_OK;
510 }
511
512 LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d", bp->unique_id, bp_num);
513 comparator_list[bp_num].used = false;
514 comparator_list[bp_num].bp_value = 0;
515
516 return target_write_u64(target,
517 comparator_list[bp_num].reg_address + 0x18, 0);
518 }
519
520 static int mips_mips64_unset_sdbbp(struct target *target, struct breakpoint *bp)
521 {
522 uint8_t buf[MIPS64_SDBBP_SIZE];
523 uint32_t instr;
524 int retval;
525
526 retval = target_read_memory(target, bp->address, MIPS64_SDBBP_SIZE, 1,
527 &buf[0]);
528 if (retval != ERROR_OK)
529 return retval;
530
531 instr = target_buffer_get_u32(target, &buf[0]);
532 if (instr != MIPS64_SDBBP)
533 return ERROR_OK;
534
535 return target_write_memory(target, bp->address, MIPS64_SDBBP_SIZE, 1,
536 bp->orig_instr);
537 }
538
539 static int mips_mips16_unset_sdbbp(struct target *target, struct breakpoint *bp)
540 {
541 uint8_t buf[MIPS16_SDBBP_SIZE];
542 uint16_t instr;
543 int retval;
544
545 retval = target_read_memory(target, bp->address, MIPS16_SDBBP_SIZE, 1,
546 &buf[0]);
547 if (retval != ERROR_OK)
548 return retval;
549
550 instr = target_buffer_get_u16(target, &buf[0]);
551 if (instr != MIPS16_SDBBP(bp->length & 1))
552 return ERROR_OK;
553
554 return target_write_memory(target, bp->address, MIPS16_SDBBP_SIZE, 1,
555 bp->orig_instr);
556 }
557
558 static int mips_mips64_unset_breakpoint(struct target *target,
559 struct breakpoint *bp)
560 {
561 /* get pointers to arch-specific information */
562 int retval;
563
564 if (!bp->is_set) {
565 LOG_WARNING("breakpoint not set");
566 return ERROR_OK;
567 }
568
569 if (bp->type == BKPT_HARD) {
570 retval = mips_mips64_unset_hwbp(target, bp);
571 } else {
572 LOG_DEBUG("bpid: %" PRIu32, bp->unique_id);
573
574 switch (bp->length) {
575 case MIPS64_SDBBP_SIZE:
576 retval = mips_mips64_unset_sdbbp(target, bp);
577 break;
578 case MIPS16_SDBBP_SIZE:
579 retval = mips_mips16_unset_sdbbp(target, bp);
580 break;
581 default:
582 retval = ERROR_FAIL;
583 }
584 }
585 if (retval != ERROR_OK) {
586 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
587 return retval;
588 }
589
590 bp->is_set = false;
591
592 return ERROR_OK;
593 }
594
595 static int mips_mips64_resume(struct target *target, int current,
596 uint64_t address, int handle_breakpoints,
597 int debug_execution)
598 {
599 struct mips64_common *mips64 = target->arch_info;
600 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
601 int retval = ERROR_OK;
602 uint64_t resume_pc;
603 struct reg *pc;
604
605 if (mips64->mips64mode32)
606 address = mips64_extend_sign(address);
607
608 if (target->state != TARGET_HALTED) {
609 LOG_TARGET_ERROR(target, "not halted");
610 return ERROR_TARGET_NOT_HALTED;
611 }
612
613 if (!debug_execution) {
614 target_free_all_working_areas(target);
615 retval = mips_mips64_enable_breakpoints(target);
616 if (retval != ERROR_OK)
617 return retval;
618
619 retval = mips_mips64_enable_watchpoints(target);
620 if (retval != ERROR_OK)
621 return retval;
622 }
623
624 pc = &mips64->core_cache->reg_list[MIPS64_PC];
625 /* current = 1: continue on current pc, otherwise continue at <address> */
626 if (!current) {
627 buf_set_u64(pc->value, 0, 64, address);
628 pc->dirty = true;
629 pc->valid = true;
630 }
631
632 resume_pc = buf_get_u64(pc->value, 0, 64);
633
634 retval = mips64_restore_context(target);
635 if (retval != ERROR_OK)
636 return retval;
637
638 /* the front-end may request us not to handle breakpoints */
639 if (handle_breakpoints) {
640 struct breakpoint *bp;
641
642 /* Single step past breakpoint at current address */
643 bp = breakpoint_find(target, (uint64_t) resume_pc);
644 if (bp) {
645 LOG_DEBUG("unset breakpoint at 0x%16.16" PRIx64 "",
646 bp->address);
647 retval = mips_mips64_unset_breakpoint(target, bp);
648 if (retval != ERROR_OK)
649 return retval;
650
651 retval = mips_mips64_single_step_core(target);
652 if (retval != ERROR_OK)
653 return retval;
654
655 retval = mips_mips64_set_breakpoint(target, bp);
656 if (retval != ERROR_OK)
657 return retval;
658 }
659 }
660
661 /* enable interrupts if we are running */
662 retval = mips64_enable_interrupts(target, !debug_execution);
663 if (retval != ERROR_OK)
664 return retval;
665
666 /* exit debug mode */
667 retval = mips64_ejtag_exit_debug(ejtag_info);
668 if (retval != ERROR_OK)
669 return retval;
670
671 target->debug_reason = DBG_REASON_NOTHALTED;
672
673 /* registers are now invalid */
674 retval = mips64_invalidate_core_regs(target);
675 if (retval != ERROR_OK)
676 return retval;
677
678 if (!debug_execution) {
679 target->state = TARGET_RUNNING;
680 retval = target_call_event_callbacks(target,
681 TARGET_EVENT_RESUMED);
682 if (retval != ERROR_OK)
683 return retval;
684
685 LOG_DEBUG("target resumed at 0x%" PRIx64 "", resume_pc);
686 } else {
687 target->state = TARGET_DEBUG_RUNNING;
688 retval = target_call_event_callbacks(target,
689 TARGET_EVENT_DEBUG_RESUMED);
690 if (retval != ERROR_OK)
691 return retval;
692
693 LOG_DEBUG("target debug resumed at 0x%" PRIx64 "", resume_pc);
694 }
695
696 return ERROR_OK;
697 }
698
699 static int mips_mips64_step(struct target *target, int current,
700 uint64_t address, int handle_breakpoints)
701 {
702 struct mips64_common *mips64 = target->arch_info;
703 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
704 struct reg *pc = &mips64->core_cache->reg_list[MIPS64_PC];
705 struct breakpoint *bp = NULL;
706 int retval = ERROR_OK;
707
708 if (target->state != TARGET_HALTED) {
709 LOG_TARGET_ERROR(target, "not halted");
710 return ERROR_TARGET_NOT_HALTED;
711 }
712
713 if (mips64->mips64mode32)
714 address = mips64_extend_sign(address);
715
716 /* current = 1: continue on current pc, otherwise continue at
717 * <address> */
718 if (!current) {
719 buf_set_u64(pc->value, 0, 64, address);
720 pc->dirty = true;
721 pc->valid = true;
722 }
723
724 /* the front-end may request us not to handle breakpoints */
725 if (handle_breakpoints) {
726 bp = breakpoint_find(target, buf_get_u64(pc->value, 0, 64));
727 if (bp) {
728 retval = mips_mips64_unset_breakpoint(target, bp);
729 if (retval != ERROR_OK)
730 return retval;
731 }
732 }
733
734 retval = mips64_restore_context(target);
735 if (retval != ERROR_OK)
736 return retval;
737
738 /* configure single step mode */
739 retval = mips64_ejtag_config_step(ejtag_info, 1);
740 if (retval != ERROR_OK)
741 return retval;
742
743 target->debug_reason = DBG_REASON_SINGLESTEP;
744
745 retval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
746 if (retval != ERROR_OK)
747 return retval;
748
749 /* disable interrupts while stepping */
750 retval = mips64_enable_interrupts(target, false);
751 if (retval != ERROR_OK)
752 return retval;
753
754 /* exit debug mode */
755 retval = mips64_ejtag_exit_debug(ejtag_info);
756 if (retval != ERROR_OK)
757 return retval;
758
759 /* registers are now invalid */
760 retval = mips64_invalidate_core_regs(target);
761 if (retval != ERROR_OK)
762 return retval;
763
764 if (bp) {
765 retval = mips_mips64_set_breakpoint(target, bp);
766 if (retval != ERROR_OK)
767 return retval;
768 }
769
770 LOG_DEBUG("target stepped ");
771
772 retval = mips_mips64_debug_entry(target);
773 if (retval != ERROR_OK)
774 return retval;
775
776 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
777 }
778
779 static int mips_mips64_add_breakpoint(struct target *target,
780 struct breakpoint *bp)
781 {
782 struct mips64_common *mips64 = target->arch_info;
783
784 if (mips64->mips64mode32)
785 bp->address = mips64_extend_sign(bp->address);
786
787 if (bp->type == BKPT_HARD) {
788 if (mips64->num_inst_bpoints_avail < 1) {
789 LOG_INFO("no hardware breakpoint available");
790 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
791 }
792
793 mips64->num_inst_bpoints_avail--;
794 }
795
796 return mips_mips64_set_breakpoint(target, bp);
797 }
798
799 static int mips_mips64_remove_breakpoint(struct target *target,
800 struct breakpoint *bp)
801 {
802 /* get pointers to arch-specific information */
803 struct mips64_common *mips64 = target->arch_info;
804 int retval = ERROR_OK;
805
806 if (target->state != TARGET_HALTED) {
807 LOG_TARGET_ERROR(target, "not halted");
808 return ERROR_TARGET_NOT_HALTED;
809 }
810
811 if (bp->is_set)
812 retval = mips_mips64_unset_breakpoint(target, bp);
813
814 if (bp->type == BKPT_HARD)
815 mips64->num_inst_bpoints_avail++;
816
817 return retval;
818 }
819
820 static int mips_mips64_unset_watchpoint(struct target *target,
821 struct watchpoint *watchpoint)
822 {
823 /* get pointers to arch-specific information */
824 struct mips64_common *mips64 = target->arch_info;
825 struct mips64_comparator *comparator_list = mips64->data_break_list;
826
827 if (!watchpoint->is_set) {
828 LOG_WARNING("watchpoint not set");
829 return ERROR_OK;
830 }
831
832 int wp_num = watchpoint->number;
833 if (wp_num >= mips64->num_data_bpoints) {
834 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
835 return ERROR_OK;
836 }
837 comparator_list[wp_num].used = false;
838 comparator_list[wp_num].bp_value = 0;
839 target_write_u64(target, comparator_list[wp_num].reg_address + 0x18, 0);
840 watchpoint->is_set = false;
841
842 return ERROR_OK;
843 }
844
845 static int mips_mips64_add_watchpoint(struct target *target,
846 struct watchpoint *watchpoint)
847 {
848 struct mips64_common *mips64 = target->arch_info;
849
850 if (mips64->num_data_bpoints_avail < 1) {
851 LOG_INFO("no hardware watchpoints available");
852 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
853 }
854
855 mips64->num_data_bpoints_avail--;
856
857 return mips_mips64_set_watchpoint(target, watchpoint);
858 }
859
860 static int mips_mips64_remove_watchpoint(struct target *target,
861 struct watchpoint *watchpoint)
862 {
863 /* get pointers to arch-specific information */
864 struct mips64_common *mips64 = target->arch_info;
865 int retval = ERROR_OK;
866
867 if (target->state != TARGET_HALTED) {
868 LOG_TARGET_ERROR(target, "not halted");
869 return ERROR_TARGET_NOT_HALTED;
870 }
871
872 if (watchpoint->is_set)
873 retval = mips_mips64_unset_watchpoint(target, watchpoint);
874
875 mips64->num_data_bpoints_avail++;
876
877 return retval;
878 }
879
880 static int mips_mips64_read_memory(struct target *target, uint64_t address,
881 uint32_t size, uint32_t count, uint8_t *buffer)
882 {
883 struct mips64_common *mips64 = target->arch_info;
884 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
885 int retval;
886 void *t;
887
888 if (target->state != TARGET_HALTED) {
889 LOG_TARGET_ERROR(target, "not halted");
890 return ERROR_TARGET_NOT_HALTED;
891 }
892
893 if (mips64->mips64mode32)
894 address = mips64_extend_sign(address);
895
896 /* sanitize arguments */
897 if (((size != 8) && (size != 4) && (size != 2) && (size != 1))
898 || !count || !buffer)
899 return ERROR_COMMAND_ARGUMENT_INVALID;
900
901 if (((size == 8) && (address & 0x7)) || ((size == 4) && (address & 0x3))
902 || ((size == 2) && (address & 0x1)))
903 return ERROR_TARGET_UNALIGNED_ACCESS;
904
905 if (size > 1) {
906 t = calloc(count, size);
907 if (!t) {
908 LOG_ERROR("Out of memory");
909 return ERROR_FAIL;
910 }
911 } else
912 t = buffer;
913
914 LOG_DEBUG("address: 0x%16.16" PRIx64 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
915 address, size, count);
916 retval = mips64_pracc_read_mem(ejtag_info, address, size, count,
917 (void *)t);
918
919 if (retval != ERROR_OK) {
920 LOG_ERROR("mips64_pracc_read_mem filed");
921 goto read_done;
922 }
923
924 switch (size) {
925 case 8:
926 target_buffer_set_u64_array(target, buffer, count, t);
927 break;
928 case 4:
929 target_buffer_set_u32_array(target, buffer, count, t);
930 break;
931 case 2:
932 target_buffer_set_u16_array(target, buffer, count, t);
933 break;
934 }
935
936 read_done:
937 if (size > 1)
938 free(t);
939
940 return retval;
941 }
942
943 static int mips_mips64_bulk_write_memory(struct target *target,
944 target_addr_t address, uint32_t count,
945 const uint8_t *buffer)
946 {
947 struct mips64_common *mips64 = target->arch_info;
948 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
949 struct working_area *fast_data_area;
950 int retval;
951
952 LOG_DEBUG("address: " TARGET_ADDR_FMT ", count: 0x%8.8" PRIx32 "",
953 address, count);
954
955 if (address & 0x7)
956 return ERROR_TARGET_UNALIGNED_ACCESS;
957
958 if (!mips64->fast_data_area) {
959 /* Get memory for block write handler
960 * we preserve this area between calls and gain a speed increase
961 * of about 3kb/sec when writing flash
962 * this will be released/nulled by the system when the target is resumed or reset */
963 retval = target_alloc_working_area(target,
964 MIPS64_FASTDATA_HANDLER_SIZE,
965 &mips64->fast_data_area);
966 if (retval != ERROR_OK) {
967 LOG_ERROR("No working area available");
968 return retval;
969 }
970
971 /* reset fastadata state so the algo get reloaded */
972 ejtag_info->fast_access_save = -1;
973 }
974
975 fast_data_area = mips64->fast_data_area;
976
977 if (address <= fast_data_area->address + fast_data_area->size &&
978 fast_data_area->address <= address + count) {
979 LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area "
980 "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").",
981 fast_data_area->address, address, address + count);
982 LOG_ERROR("Change work-area-phys or load_image address!");
983 return ERROR_FAIL;
984 }
985
986 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
987 /* but byte array represents target endianness */
988 uint64_t *t;
989
990 t = calloc(count, sizeof(uint64_t));
991 if (!t) {
992 LOG_ERROR("Out of memory");
993 return ERROR_FAIL;
994 }
995
996 target_buffer_get_u64_array(target, buffer, count, t);
997
998 retval = mips64_pracc_fastdata_xfer(ejtag_info, mips64->fast_data_area,
999 true, address, count, t);
1000
1001 if (retval != ERROR_OK)
1002 LOG_ERROR("Fastdata access Failed");
1003
1004 free(t);
1005
1006 return retval;
1007 }
1008
1009 static int mips_mips64_write_memory(struct target *target, uint64_t address,
1010 uint32_t size, uint32_t count, const uint8_t *buffer)
1011 {
1012 struct mips64_common *mips64 = target->arch_info;
1013 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
1014 int retval;
1015
1016 if (target->state != TARGET_HALTED) {
1017 LOG_TARGET_ERROR(target, "not halted");
1018 return ERROR_TARGET_NOT_HALTED;
1019 }
1020
1021 if (mips64->mips64mode32)
1022 address = mips64_extend_sign(address);
1023
1024 /* sanitize arguments */
1025 if (((size != 8) && (size != 4) && (size != 2) && (size != 1))
1026 || !count || !buffer)
1027 return ERROR_COMMAND_ARGUMENT_INVALID;
1028
1029 if (((size == 8) && (address & 0x7)) || ((size == 4) && (address & 0x3))
1030 || ((size == 2) && (address & 0x1)))
1031 return ERROR_TARGET_UNALIGNED_ACCESS;
1032
1033
1034
1035 if (size == 8 && count > 8) {
1036 retval = mips_mips64_bulk_write_memory(target, address, count,
1037 buffer);
1038 if (retval == ERROR_OK)
1039 return ERROR_OK;
1040
1041 LOG_WARNING("Falling back to non-bulk write");
1042 }
1043
1044 void *t = NULL;
1045 if (size > 1) {
1046 t = calloc(count, size);
1047 if (!t) {
1048 LOG_ERROR("unable to allocate t for write buffer");
1049 return ERROR_FAIL;
1050 }
1051
1052 switch (size) {
1053 case 8:
1054 target_buffer_get_u64_array(target, buffer, count,
1055 (uint64_t *)t);
1056 break;
1057 case 4:
1058 target_buffer_get_u32_array(target, buffer, count,
1059 (uint32_t *)t);
1060 break;
1061 case 2:
1062 target_buffer_get_u16_array(target, buffer, count,
1063 (uint16_t *)t);
1064 break;
1065 }
1066 buffer = t;
1067 }
1068
1069 LOG_DEBUG("address: 0x%16.16" PRIx64 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
1070 address, size, count);
1071
1072 retval = mips64_pracc_write_mem(ejtag_info, address, size, count,
1073 (void *)buffer);
1074 free(t);
1075
1076 return retval;
1077 }
1078
1079 static int mips_mips64_init_target(struct command_context *cmd_ctx,
1080 struct target *target)
1081 {
1082 return mips64_build_reg_cache(target);
1083 }
1084
1085 static int mips_mips64_target_create(struct target *target, Jim_Interp *interp)
1086 {
1087 struct mips_mips64_common *mips_mips64;
1088 struct mips64_common *mips64;
1089
1090 mips_mips64 = calloc(1, sizeof(*mips_mips64));
1091 if (!mips_mips64) {
1092 LOG_ERROR("unable to allocate mips_mips64");
1093 return ERROR_FAIL;
1094 }
1095
1096 mips_mips64->common_magic = MIPS64_COMMON_MAGIC;
1097
1098 mips64 = &mips_mips64->mips64_common;
1099 mips64->arch_info = mips_mips64;
1100 target->arch_info = mips64;
1101
1102 return mips64_init_arch_info(target, mips64, target->tap);
1103 }
1104
1105 static int mips_mips64_examine(struct target *target)
1106 {
1107 int retval;
1108 struct mips64_common *mips64 = target->arch_info;
1109
1110 retval = mips_ejtag_init(&mips64->ejtag_info);
1111 if (retval != ERROR_OK)
1112 return retval;
1113
1114 return mips64_examine(target);
1115 }
1116
1117 static int mips_mips64_checksum_memory(struct target *target, uint64_t address,
1118 uint32_t size, uint32_t *checksum)
1119 {
1120 return ERROR_FAIL; /* use bulk read method */
1121 }
1122
1123 COMMAND_HANDLER(handle_mips64mode32)
1124 {
1125 struct target *target = get_current_target(CMD_CTX);
1126 struct mips64_common *mips64 = target->arch_info;
1127
1128 if (CMD_ARGC > 0)
1129 COMMAND_PARSE_BOOL(CMD_ARGV[0], mips64->mips64mode32, "on", "off");
1130
1131 if (mips64->mips64mode32)
1132 command_print(CMD, "enabled");
1133 else
1134 command_print(CMD, "disabled");
1135
1136 return ERROR_OK;
1137 }
1138
1139
1140 static const struct command_registration mips64_commands_handlers[] = {
1141 {
1142 .name = "mips64mode32",
1143 .mode = COMMAND_EXEC,
1144 .help = "Enable/disable 32 bit mode",
1145 .usage = "[1|0]",
1146 .handler = handle_mips64mode32
1147 },
1148 COMMAND_REGISTRATION_DONE
1149 };
1150
1151 struct target_type mips_mips64_target = {
1152 .name = "mips_mips64",
1153
1154 .poll = mips_mips64_poll,
1155 .arch_state = mips64_arch_state,
1156
1157 .target_request_data = NULL,
1158
1159 .halt = mips_mips64_halt,
1160 .resume = mips_mips64_resume,
1161 .step = mips_mips64_step,
1162
1163 .assert_reset = mips_mips64_assert_reset,
1164 .deassert_reset = mips_mips64_deassert_reset,
1165 /* TODO: add .soft_reset_halt */
1166
1167 .get_gdb_reg_list = mips64_get_gdb_reg_list,
1168
1169 .read_memory = mips_mips64_read_memory,
1170 .write_memory = mips_mips64_write_memory,
1171 .checksum_memory = mips_mips64_checksum_memory,
1172 .blank_check_memory = NULL,
1173
1174 .run_algorithm = mips64_run_algorithm,
1175
1176 .add_breakpoint = mips_mips64_add_breakpoint,
1177 .remove_breakpoint = mips_mips64_remove_breakpoint,
1178 .add_watchpoint = mips_mips64_add_watchpoint,
1179 .remove_watchpoint = mips_mips64_remove_watchpoint,
1180
1181 .target_create = mips_mips64_target_create,
1182 .init_target = mips_mips64_init_target,
1183 .examine = mips_mips64_examine,
1184
1185 .commands = mips64_commands_handlers,
1186 };

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)