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

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)