target: fix build with jimtcl 0.79
[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->is_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->is_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->is_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->is_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(watchpoint, wp_num);
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->is_set) {
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
510 int bp_num = bp->number;
511
512 if (bp_num >= mips64->num_inst_bpoints) {
513 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %" PRIu32 ")",
514 bp->unique_id);
515 return ERROR_OK;
516 }
517
518 LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d", bp->unique_id, bp_num);
519 comparator_list[bp_num].used = false;
520 comparator_list[bp_num].bp_value = 0;
521
522 return target_write_u64(target,
523 comparator_list[bp_num].reg_address + 0x18, 0);
524 }
525
526 static int mips_mips64_unset_sdbbp(struct target *target, struct breakpoint *bp)
527 {
528 uint8_t buf[MIPS64_SDBBP_SIZE];
529 uint32_t instr;
530 int retval;
531
532 retval = target_read_memory(target, bp->address, MIPS64_SDBBP_SIZE, 1,
533 &buf[0]);
534 if (retval != ERROR_OK)
535 return retval;
536
537 instr = target_buffer_get_u32(target, &buf[0]);
538 if (instr != MIPS64_SDBBP)
539 return ERROR_OK;
540
541 return target_write_memory(target, bp->address, MIPS64_SDBBP_SIZE, 1,
542 bp->orig_instr);
543 }
544
545 static int mips_mips16_unset_sdbbp(struct target *target, struct breakpoint *bp)
546 {
547 uint8_t buf[MIPS16_SDBBP_SIZE];
548 uint16_t instr;
549 int retval;
550
551 retval = target_read_memory(target, bp->address, MIPS16_SDBBP_SIZE, 1,
552 &buf[0]);
553 if (retval != ERROR_OK)
554 return retval;
555
556 instr = target_buffer_get_u16(target, &buf[0]);
557 if (instr != MIPS16_SDBBP(bp->length & 1))
558 return ERROR_OK;
559
560 return target_write_memory(target, bp->address, MIPS16_SDBBP_SIZE, 1,
561 bp->orig_instr);
562 }
563
564 static int mips_mips64_unset_breakpoint(struct target *target,
565 struct breakpoint *bp)
566 {
567 /* get pointers to arch-specific information */
568 int retval;
569
570 if (!bp->is_set) {
571 LOG_WARNING("breakpoint not set");
572 return ERROR_OK;
573 }
574
575 if (bp->type == BKPT_HARD) {
576 retval = mips_mips64_unset_hwbp(target, bp);
577 } else {
578 LOG_DEBUG("bpid: %" PRIu32, bp->unique_id);
579
580 switch (bp->length) {
581 case MIPS64_SDBBP_SIZE:
582 retval = mips_mips64_unset_sdbbp(target, bp);
583 break;
584 case MIPS16_SDBBP_SIZE:
585 retval = mips_mips16_unset_sdbbp(target, bp);
586 break;
587 default:
588 retval = ERROR_FAIL;
589 }
590 }
591 if (retval != ERROR_OK) {
592 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
593 return retval;
594 }
595
596 bp->is_set = false;
597
598 return ERROR_OK;
599 }
600
601 static int mips_mips64_resume(struct target *target, int current,
602 uint64_t address, int handle_breakpoints,
603 int debug_execution)
604 {
605 struct mips64_common *mips64 = target->arch_info;
606 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
607 int retval = ERROR_OK;
608 uint64_t resume_pc;
609 struct reg *pc;
610
611 if (mips64->mips64mode32)
612 address = mips64_extend_sign(address);
613
614 if (target->state != TARGET_HALTED) {
615 LOG_WARNING("target not halted %d", target->state);
616 return ERROR_TARGET_NOT_HALTED;
617 }
618
619 if (!debug_execution) {
620 target_free_all_working_areas(target);
621 retval = mips_mips64_enable_breakpoints(target);
622 if (retval != ERROR_OK)
623 return retval;
624
625 retval = mips_mips64_enable_watchpoints(target);
626 if (retval != ERROR_OK)
627 return retval;
628 }
629
630 pc = &mips64->core_cache->reg_list[MIPS64_PC];
631 /* current = 1: continue on current pc, otherwise continue at <address> */
632 if (!current) {
633 buf_set_u64(pc->value, 0, 64, address);
634 pc->dirty = 1;
635 pc->valid = 1;
636 }
637
638 resume_pc = buf_get_u64(pc->value, 0, 64);
639
640 retval = mips64_restore_context(target);
641 if (retval != ERROR_OK)
642 return retval;
643
644 /* the front-end may request us not to handle breakpoints */
645 if (handle_breakpoints) {
646 struct breakpoint *bp;
647
648 /* Single step past breakpoint at current address */
649 bp = breakpoint_find(target, (uint64_t) resume_pc);
650 if (bp) {
651 LOG_DEBUG("unset breakpoint at 0x%16.16" PRIx64 "",
652 bp->address);
653 retval = mips_mips64_unset_breakpoint(target, bp);
654 if (retval != ERROR_OK)
655 return retval;
656
657 retval = mips_mips64_single_step_core(target);
658 if (retval != ERROR_OK)
659 return retval;
660
661 retval = mips_mips64_set_breakpoint(target, bp);
662 if (retval != ERROR_OK)
663 return retval;
664 }
665 }
666
667 /* enable interrupts if we are running */
668 retval = mips64_enable_interrupts(target, !debug_execution);
669 if (retval != ERROR_OK)
670 return retval;
671
672 /* exit debug mode */
673 retval = mips64_ejtag_exit_debug(ejtag_info);
674 if (retval != ERROR_OK)
675 return retval;
676
677 target->debug_reason = DBG_REASON_NOTHALTED;
678
679 /* registers are now invalid */
680 retval = mips64_invalidate_core_regs(target);
681 if (retval != ERROR_OK)
682 return retval;
683
684 if (!debug_execution) {
685 target->state = TARGET_RUNNING;
686 retval = target_call_event_callbacks(target,
687 TARGET_EVENT_RESUMED);
688 if (retval != ERROR_OK)
689 return retval;
690
691 LOG_DEBUG("target resumed at 0x%" PRIx64 "", resume_pc);
692 } else {
693 target->state = TARGET_DEBUG_RUNNING;
694 retval = target_call_event_callbacks(target,
695 TARGET_EVENT_DEBUG_RESUMED);
696 if (retval != ERROR_OK)
697 return retval;
698
699 LOG_DEBUG("target debug resumed at 0x%" PRIx64 "", resume_pc);
700 }
701
702 return ERROR_OK;
703 }
704
705 static int mips_mips64_step(struct target *target, int current,
706 uint64_t address, int handle_breakpoints)
707 {
708 struct mips64_common *mips64 = target->arch_info;
709 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
710 struct reg *pc = &mips64->core_cache->reg_list[MIPS64_PC];
711 struct breakpoint *bp = NULL;
712 int retval = ERROR_OK;
713
714 if (target->state != TARGET_HALTED) {
715 LOG_WARNING("target not halted");
716 return ERROR_TARGET_NOT_HALTED;
717 }
718
719 if (mips64->mips64mode32)
720 address = mips64_extend_sign(address);
721
722 /* current = 1: continue on current pc, otherwise continue at
723 * <address> */
724 if (!current) {
725 buf_set_u64(pc->value, 0, 64, address);
726 pc->dirty = 1;
727 pc->valid = 1;
728 }
729
730 /* the front-end may request us not to handle breakpoints */
731 if (handle_breakpoints) {
732 bp = breakpoint_find(target, buf_get_u64(pc->value, 0, 64));
733 if (bp) {
734 retval = mips_mips64_unset_breakpoint(target, bp);
735 if (retval != ERROR_OK)
736 return retval;
737 }
738 }
739
740 retval = mips64_restore_context(target);
741 if (retval != ERROR_OK)
742 return retval;
743
744 /* configure single step mode */
745 retval = mips64_ejtag_config_step(ejtag_info, 1);
746 if (retval != ERROR_OK)
747 return retval;
748
749 target->debug_reason = DBG_REASON_SINGLESTEP;
750
751 retval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
752 if (retval != ERROR_OK)
753 return retval;
754
755 /* disable interrupts while stepping */
756 retval = mips64_enable_interrupts(target, false);
757 if (retval != ERROR_OK)
758 return retval;
759
760 /* exit debug mode */
761 retval = mips64_ejtag_exit_debug(ejtag_info);
762 if (retval != ERROR_OK)
763 return retval;
764
765 /* registers are now invalid */
766 retval = mips64_invalidate_core_regs(target);
767 if (retval != ERROR_OK)
768 return retval;
769
770 if (bp) {
771 retval = mips_mips64_set_breakpoint(target, bp);
772 if (retval != ERROR_OK)
773 return retval;
774 }
775
776 LOG_DEBUG("target stepped ");
777
778 retval = mips_mips64_debug_entry(target);
779 if (retval != ERROR_OK)
780 return retval;
781
782 return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
783 }
784
785 static int mips_mips64_add_breakpoint(struct target *target,
786 struct breakpoint *bp)
787 {
788 struct mips64_common *mips64 = target->arch_info;
789
790 if (mips64->mips64mode32)
791 bp->address = mips64_extend_sign(bp->address);
792
793 if (bp->type == BKPT_HARD) {
794 if (mips64->num_inst_bpoints_avail < 1) {
795 LOG_INFO("no hardware breakpoint available");
796 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
797 }
798
799 mips64->num_inst_bpoints_avail--;
800 }
801
802 return mips_mips64_set_breakpoint(target, bp);
803 }
804
805 static int mips_mips64_remove_breakpoint(struct target *target,
806 struct breakpoint *bp)
807 {
808 /* get pointers to arch-specific information */
809 struct mips64_common *mips64 = target->arch_info;
810 int retval = ERROR_OK;
811
812 if (target->state != TARGET_HALTED) {
813 LOG_WARNING("target not halted");
814 return ERROR_TARGET_NOT_HALTED;
815 }
816
817 if (bp->is_set)
818 retval = mips_mips64_unset_breakpoint(target, bp);
819
820 if (bp->type == BKPT_HARD)
821 mips64->num_inst_bpoints_avail++;
822
823 return retval;
824 }
825
826 static int mips_mips64_unset_watchpoint(struct target *target,
827 struct watchpoint *watchpoint)
828 {
829 /* get pointers to arch-specific information */
830 struct mips64_common *mips64 = target->arch_info;
831 struct mips64_comparator *comparator_list = mips64->data_break_list;
832
833 if (!watchpoint->is_set) {
834 LOG_WARNING("watchpoint not set");
835 return ERROR_OK;
836 }
837
838 int wp_num = watchpoint->number;
839 if (wp_num >= mips64->num_data_bpoints) {
840 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
841 return ERROR_OK;
842 }
843 comparator_list[wp_num].used = false;
844 comparator_list[wp_num].bp_value = 0;
845 target_write_u64(target, comparator_list[wp_num].reg_address + 0x18, 0);
846 watchpoint->is_set = false;
847
848 return ERROR_OK;
849 }
850
851 static int mips_mips64_add_watchpoint(struct target *target,
852 struct watchpoint *watchpoint)
853 {
854 struct mips64_common *mips64 = target->arch_info;
855
856 if (mips64->num_data_bpoints_avail < 1) {
857 LOG_INFO("no hardware watchpoints available");
858 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
859 }
860
861 mips64->num_data_bpoints_avail--;
862
863 return mips_mips64_set_watchpoint(target, watchpoint);
864 }
865
866 static int mips_mips64_remove_watchpoint(struct target *target,
867 struct watchpoint *watchpoint)
868 {
869 /* get pointers to arch-specific information */
870 struct mips64_common *mips64 = target->arch_info;
871 int retval = ERROR_OK;
872
873 if (target->state != TARGET_HALTED) {
874 LOG_WARNING("target not halted");
875 return ERROR_TARGET_NOT_HALTED;
876 }
877
878 if (watchpoint->is_set)
879 retval = mips_mips64_unset_watchpoint(target, watchpoint);
880
881 mips64->num_data_bpoints_avail++;
882
883 return retval;
884 }
885
886 static int mips_mips64_read_memory(struct target *target, uint64_t address,
887 uint32_t size, uint32_t count, uint8_t *buffer)
888 {
889 struct mips64_common *mips64 = target->arch_info;
890 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
891 int retval;
892 void *t;
893
894 if (target->state != TARGET_HALTED) {
895 LOG_WARNING("target not halted %d", target->state);
896 return ERROR_TARGET_NOT_HALTED;
897 }
898
899 if (mips64->mips64mode32)
900 address = mips64_extend_sign(address);
901
902 /* sanitize arguments */
903 if (((size != 8) && (size != 4) && (size != 2) && (size != 1))
904 || !count || !buffer)
905 return ERROR_COMMAND_ARGUMENT_INVALID;
906
907 if (((size == 8) && (address & 0x7)) || ((size == 4) && (address & 0x3))
908 || ((size == 2) && (address & 0x1)))
909 return ERROR_TARGET_UNALIGNED_ACCESS;
910
911 if (size > 1) {
912 t = calloc(count, size);
913 if (!t) {
914 LOG_ERROR("Out of memory");
915 return ERROR_FAIL;
916 }
917 } else
918 t = buffer;
919
920 LOG_DEBUG("address: 0x%16.16" PRIx64 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
921 address, size, count);
922 retval = mips64_pracc_read_mem(ejtag_info, address, size, count,
923 (void *)t);
924
925 if (retval != ERROR_OK) {
926 LOG_ERROR("mips64_pracc_read_mem filed");
927 goto read_done;
928 }
929
930 switch (size) {
931 case 8:
932 target_buffer_set_u64_array(target, buffer, count, t);
933 break;
934 case 4:
935 target_buffer_set_u32_array(target, buffer, count, t);
936 break;
937 case 2:
938 target_buffer_set_u16_array(target, buffer, count, t);
939 break;
940 }
941
942 read_done:
943 if (size > 1)
944 free(t);
945
946 return retval;
947 }
948
949 static int mips_mips64_bulk_write_memory(struct target *target,
950 target_addr_t address, uint32_t count,
951 const uint8_t *buffer)
952 {
953 struct mips64_common *mips64 = target->arch_info;
954 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
955 struct working_area *fast_data_area;
956 int retval;
957
958 LOG_DEBUG("address: " TARGET_ADDR_FMT ", count: 0x%8.8" PRIx32 "",
959 address, count);
960
961 if (address & 0x7)
962 return ERROR_TARGET_UNALIGNED_ACCESS;
963
964 if (!mips64->fast_data_area) {
965 /* Get memory for block write handler
966 * we preserve this area between calls and gain a speed increase
967 * of about 3kb/sec when writing flash
968 * this will be released/nulled by the system when the target is resumed or reset */
969 retval = target_alloc_working_area(target,
970 MIPS64_FASTDATA_HANDLER_SIZE,
971 &mips64->fast_data_area);
972 if (retval != ERROR_OK) {
973 LOG_ERROR("No working area available");
974 return retval;
975 }
976
977 /* reset fastadata state so the algo get reloaded */
978 ejtag_info->fast_access_save = -1;
979 }
980
981 fast_data_area = mips64->fast_data_area;
982
983 if (address <= fast_data_area->address + fast_data_area->size &&
984 fast_data_area->address <= address + count) {
985 LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area "
986 "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").",
987 fast_data_area->address, address, address + count);
988 LOG_ERROR("Change work-area-phys or load_image address!");
989 return ERROR_FAIL;
990 }
991
992 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
993 /* but byte array represents target endianness */
994 uint64_t *t;
995
996 t = calloc(count, sizeof(uint64_t));
997 if (!t) {
998 LOG_ERROR("Out of memory");
999 return ERROR_FAIL;
1000 }
1001
1002 target_buffer_get_u64_array(target, buffer, count, t);
1003
1004 retval = mips64_pracc_fastdata_xfer(ejtag_info, mips64->fast_data_area,
1005 true, address, count, t);
1006
1007 if (retval != ERROR_OK)
1008 LOG_ERROR("Fastdata access Failed");
1009
1010 free(t);
1011
1012 return retval;
1013 }
1014
1015 static int mips_mips64_write_memory(struct target *target, uint64_t address,
1016 uint32_t size, uint32_t count, const uint8_t *buffer)
1017 {
1018 struct mips64_common *mips64 = target->arch_info;
1019 struct mips_ejtag *ejtag_info = &mips64->ejtag_info;
1020 int retval;
1021
1022 if (target->state != TARGET_HALTED) {
1023 LOG_WARNING("target not halted");
1024 return ERROR_TARGET_NOT_HALTED;
1025 }
1026
1027 if (mips64->mips64mode32)
1028 address = mips64_extend_sign(address);
1029
1030 /* sanitize arguments */
1031 if (((size != 8) && (size != 4) && (size != 2) && (size != 1))
1032 || !count || !buffer)
1033 return ERROR_COMMAND_ARGUMENT_INVALID;
1034
1035 if (((size == 8) && (address & 0x7)) || ((size == 4) && (address & 0x3))
1036 || ((size == 2) && (address & 0x1)))
1037 return ERROR_TARGET_UNALIGNED_ACCESS;
1038
1039
1040
1041 if (size == 8 && count > 8) {
1042 retval = mips_mips64_bulk_write_memory(target, address, count,
1043 buffer);
1044 if (retval == ERROR_OK)
1045 return ERROR_OK;
1046
1047 LOG_WARNING("Falling back to non-bulk write");
1048 }
1049
1050 void *t = NULL;
1051 if (size > 1) {
1052 t = calloc(count, size);
1053 if (!t) {
1054 LOG_ERROR("unable to allocate t for write buffer");
1055 return ERROR_FAIL;
1056 }
1057
1058 switch (size) {
1059 case 8:
1060 target_buffer_get_u64_array(target, buffer, count,
1061 (uint64_t *)t);
1062 break;
1063 case 4:
1064 target_buffer_get_u32_array(target, buffer, count,
1065 (uint32_t *)t);
1066 break;
1067 case 2:
1068 target_buffer_get_u16_array(target, buffer, count,
1069 (uint16_t *)t);
1070 break;
1071 }
1072 buffer = t;
1073 }
1074
1075 LOG_DEBUG("address: 0x%16.16" PRIx64 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
1076 address, size, count);
1077
1078 retval = mips64_pracc_write_mem(ejtag_info, address, size, count,
1079 (void *)buffer);
1080 free(t);
1081
1082 return retval;
1083 }
1084
1085 static int mips_mips64_init_target(struct command_context *cmd_ctx,
1086 struct target *target)
1087 {
1088 return mips64_build_reg_cache(target);
1089 }
1090
1091 static int mips_mips64_target_create(struct target *target, Jim_Interp *interp)
1092 {
1093 struct mips_mips64_common *mips_mips64;
1094 struct mips64_common *mips64;
1095
1096 mips_mips64 = calloc(1, sizeof(*mips_mips64));
1097 if (!mips_mips64) {
1098 LOG_ERROR("unable to allocate mips_mips64");
1099 return ERROR_FAIL;
1100 }
1101
1102 mips_mips64->common_magic = MIPS64_COMMON_MAGIC;
1103
1104 mips64 = &mips_mips64->mips64_common;
1105 mips64->arch_info = mips_mips64;
1106 target->arch_info = mips64;
1107
1108 return mips64_init_arch_info(target, mips64, target->tap);
1109 }
1110
1111 static int mips_mips64_examine(struct target *target)
1112 {
1113 int retval;
1114 struct mips64_common *mips64 = target->arch_info;
1115
1116 retval = mips_ejtag_init(&mips64->ejtag_info);
1117 if (retval != ERROR_OK)
1118 return retval;
1119
1120 return mips64_examine(target);
1121 }
1122
1123 static int mips_mips64_checksum_memory(struct target *target, uint64_t address,
1124 uint32_t size, uint32_t *checksum)
1125 {
1126 return ERROR_FAIL; /* use bulk read method */
1127 }
1128
1129 COMMAND_HANDLER(handle_mips64mode32)
1130 {
1131 struct target *target = get_current_target(CMD_CTX);
1132 struct mips64_common *mips64 = target->arch_info;
1133
1134 if (CMD_ARGC > 0)
1135 COMMAND_PARSE_BOOL(CMD_ARGV[0], mips64->mips64mode32, "on", "off");
1136
1137 if (mips64->mips64mode32)
1138 command_print(CMD, "enabled");
1139 else
1140 command_print(CMD, "disabled");
1141
1142 return ERROR_OK;
1143 }
1144
1145
1146 static const struct command_registration mips64_commands_handlers[] = {
1147 {
1148 .name = "mips64mode32",
1149 .mode = COMMAND_EXEC,
1150 .help = "Enable/disable 32 bit mode",
1151 .usage = "[1|0]",
1152 .handler = handle_mips64mode32
1153 },
1154 COMMAND_REGISTRATION_DONE
1155 };
1156
1157 struct target_type mips_mips64_target = {
1158 .name = "mips_mips64",
1159
1160 .poll = mips_mips64_poll,
1161 .arch_state = mips64_arch_state,
1162
1163 .target_request_data = NULL,
1164
1165 .halt = mips_mips64_halt,
1166 .resume = mips_mips64_resume,
1167 .step = mips_mips64_step,
1168
1169 .assert_reset = mips_mips64_assert_reset,
1170 .deassert_reset = mips_mips64_deassert_reset,
1171 .soft_reset_halt = mips_mips64_soft_reset_halt,
1172
1173 .get_gdb_reg_list = mips64_get_gdb_reg_list,
1174
1175 .read_memory = mips_mips64_read_memory,
1176 .write_memory = mips_mips64_write_memory,
1177 .checksum_memory = mips_mips64_checksum_memory,
1178 .blank_check_memory = NULL,
1179
1180 .run_algorithm = mips64_run_algorithm,
1181
1182 .add_breakpoint = mips_mips64_add_breakpoint,
1183 .remove_breakpoint = mips_mips64_remove_breakpoint,
1184 .add_watchpoint = mips_mips64_add_watchpoint,
1185 .remove_watchpoint = mips_mips64_remove_watchpoint,
1186
1187 .target_create = mips_mips64_target_create,
1188 .init_target = mips_mips64_init_target,
1189 .examine = mips_mips64_examine,
1190
1191 .commands = mips64_commands_handlers,
1192 };

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)