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

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)