jtag: retire jtag_get/set_end_state()
[openocd.git] / src / target / mips_m4k.c
1 /***************************************************************************
2 * Copyright (C) 2008 by Spencer Oliver *
3 * spen@spen-soft.co.uk *
4 * *
5 * Copyright (C) 2008 by David T.L. Wong *
6 * *
7 * Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com> *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 ***************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "breakpoints.h"
29 #include "mips32.h"
30 #include "mips_m4k.h"
31 #include "mips32_dmaacc.h"
32 #include "target_type.h"
33 #include "register.h"
34
35 int mips_m4k_examine_debug_reason(struct target *target)
36 {
37 uint32_t break_status;
38 int retval;
39
40 if ((target->debug_reason != DBG_REASON_DBGRQ)
41 && (target->debug_reason != DBG_REASON_SINGLESTEP))
42 {
43 /* get info about inst breakpoint support */
44 if ((retval = target_read_u32(target, EJTAG_IBS, &break_status)) != ERROR_OK)
45 return retval;
46 if (break_status & 0x1f)
47 {
48 /* we have halted on a breakpoint */
49 if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK)
50 return retval;
51 target->debug_reason = DBG_REASON_BREAKPOINT;
52 }
53
54 /* get info about data breakpoint support */
55 if ((retval = target_read_u32(target, EJTAG_DBS, &break_status)) != ERROR_OK)
56 return retval;
57 if (break_status & 0x1f)
58 {
59 /* we have halted on a breakpoint */
60 if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK)
61 return retval;
62 target->debug_reason = DBG_REASON_WATCHPOINT;
63 }
64 }
65
66 return ERROR_OK;
67 }
68
69 int mips_m4k_debug_entry(struct target *target)
70 {
71 struct mips32_common *mips32 = target_to_mips32(target);
72 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
73 uint32_t debug_reg;
74
75 /* read debug register */
76 mips_ejtag_read_debug(ejtag_info, &debug_reg);
77
78 /* make sure break unit configured */
79 mips32_configure_break_unit(target);
80
81 /* attempt to find halt reason */
82 mips_m4k_examine_debug_reason(target);
83
84 /* clear single step if active */
85 if (debug_reg & EJTAG_DEBUG_DSS)
86 {
87 /* stopped due to single step - clear step bit */
88 mips_ejtag_config_step(ejtag_info, 0);
89 }
90
91 mips32_save_context(target);
92
93 /* default to mips32 isa, it will be changed below if required */
94 mips32->isa_mode = MIPS32_ISA_MIPS32;
95
96 if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
97 mips32->isa_mode = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1);
98 }
99
100 LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
101 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32),
102 target_state_name(target));
103
104 return ERROR_OK;
105 }
106
107 int mips_m4k_poll(struct target *target)
108 {
109 int retval;
110 struct mips32_common *mips32 = target_to_mips32(target);
111 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
112 uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl;
113
114 /* read ejtag control reg */
115 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
116 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
117
118 /* clear this bit before handling polling
119 * as after reset registers will read zero */
120 if (ejtag_ctrl & EJTAG_CTRL_ROCC)
121 {
122 /* we have detected a reset, clear flag
123 * otherwise ejtag will not work */
124 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
125
126 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
127 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
128 LOG_DEBUG("Reset Detected");
129 }
130
131 /* check for processor halted */
132 if (ejtag_ctrl & EJTAG_CTRL_BRKST)
133 {
134 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
135 {
136 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
137
138 target->state = TARGET_HALTED;
139
140 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
141 return retval;
142
143 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
144 }
145 else if (target->state == TARGET_DEBUG_RUNNING)
146 {
147 target->state = TARGET_HALTED;
148
149 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
150 return retval;
151
152 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
153 }
154 }
155 else
156 {
157 target->state = TARGET_RUNNING;
158 }
159
160 // LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl);
161
162 return ERROR_OK;
163 }
164
165 int mips_m4k_halt(struct target *target)
166 {
167 struct mips32_common *mips32 = target_to_mips32(target);
168 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
169
170 LOG_DEBUG("target->state: %s",
171 target_state_name(target));
172
173 if (target->state == TARGET_HALTED)
174 {
175 LOG_DEBUG("target was already halted");
176 return ERROR_OK;
177 }
178
179 if (target->state == TARGET_UNKNOWN)
180 {
181 LOG_WARNING("target was in unknown state when halt was requested");
182 }
183
184 if (target->state == TARGET_RESET)
185 {
186 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
187 {
188 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
189 return ERROR_TARGET_FAILURE;
190 }
191 else
192 {
193 /* we came here in a reset_halt or reset_init sequence
194 * debug entry was already prepared in mips32_prepare_reset_halt()
195 */
196 target->debug_reason = DBG_REASON_DBGRQ;
197
198 return ERROR_OK;
199 }
200 }
201
202 /* break processor */
203 mips_ejtag_enter_debug(ejtag_info);
204
205 target->debug_reason = DBG_REASON_DBGRQ;
206
207 return ERROR_OK;
208 }
209
210 int mips_m4k_assert_reset(struct target *target)
211 {
212 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
213 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
214 int assert_srst = 1;
215
216 LOG_DEBUG("target->state: %s",
217 target_state_name(target));
218
219 enum reset_types jtag_reset_config = jtag_get_reset_config();
220
221 if (!(jtag_reset_config & RESET_HAS_SRST))
222 assert_srst = 0;
223
224 if (target->reset_halt)
225 {
226 /* use hardware to catch reset */
227 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);
228 }
229 else
230 {
231 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
232 }
233
234 if (assert_srst)
235 {
236 /* here we should issue a srst only, but we may have to assert trst as well */
237 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
238 {
239 jtag_add_reset(1, 1);
240 }
241 else
242 {
243 jtag_add_reset(0, 1);
244 }
245 }
246 else
247 {
248 if (mips_m4k->is_pic32mx)
249 {
250 uint32_t mchip_cmd;
251
252 LOG_DEBUG("Using MTAP reset to reset processor...");
253
254 /* use microchip specific MTAP reset */
255 mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);
256 mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);
257
258 mchip_cmd = MCHP_ASERT_RST;
259 mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
260 mchip_cmd = MCHP_DE_ASSERT_RST;
261 mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
262 mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
263 }
264 else
265 {
266 /* use ejtag reset - not supported by all cores */
267 uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
268 LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
269 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
270 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
271 }
272 }
273
274 target->state = TARGET_RESET;
275 jtag_add_sleep(50000);
276
277 register_cache_invalidate(mips_m4k->mips32.core_cache);
278
279 if (target->reset_halt)
280 {
281 int retval;
282 if ((retval = target_halt(target)) != ERROR_OK)
283 return retval;
284 }
285
286 return ERROR_OK;
287 }
288
289 int mips_m4k_deassert_reset(struct target *target)
290 {
291 LOG_DEBUG("target->state: %s",
292 target_state_name(target));
293
294 /* deassert reset lines */
295 jtag_add_reset(0, 0);
296
297 return ERROR_OK;
298 }
299
300 int mips_m4k_soft_reset_halt(struct target *target)
301 {
302 /* TODO */
303 return ERROR_OK;
304 }
305
306 int mips_m4k_single_step_core(struct target *target)
307 {
308 struct mips32_common *mips32 = target_to_mips32(target);
309 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
310
311 /* configure single step mode */
312 mips_ejtag_config_step(ejtag_info, 1);
313
314 /* disable interrupts while stepping */
315 mips32_enable_interrupts(target, 0);
316
317 /* exit debug mode */
318 mips_ejtag_exit_debug(ejtag_info);
319
320 mips_m4k_debug_entry(target);
321
322 return ERROR_OK;
323 }
324
325 int mips_m4k_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
326 {
327 struct mips32_common *mips32 = target_to_mips32(target);
328 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
329 struct breakpoint *breakpoint = NULL;
330 uint32_t resume_pc;
331
332 if (target->state != TARGET_HALTED)
333 {
334 LOG_WARNING("target not halted");
335 return ERROR_TARGET_NOT_HALTED;
336 }
337
338 if (!debug_execution)
339 {
340 target_free_all_working_areas(target);
341 mips_m4k_enable_breakpoints(target);
342 mips_m4k_enable_watchpoints(target);
343 }
344
345 /* current = 1: continue on current pc, otherwise continue at <address> */
346 if (!current)
347 {
348 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
349 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
350 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
351 }
352
353 if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
354 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode);
355 }
356
357 resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
358
359 mips32_restore_context(target);
360
361 /* the front-end may request us not to handle breakpoints */
362 if (handle_breakpoints)
363 {
364 /* Single step past breakpoint at current address */
365 if ((breakpoint = breakpoint_find(target, resume_pc)))
366 {
367 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
368 mips_m4k_unset_breakpoint(target, breakpoint);
369 mips_m4k_single_step_core(target);
370 mips_m4k_set_breakpoint(target, breakpoint);
371 }
372 }
373
374 /* enable interrupts if we are running */
375 mips32_enable_interrupts(target, !debug_execution);
376
377 /* exit debug mode */
378 mips_ejtag_exit_debug(ejtag_info);
379 target->debug_reason = DBG_REASON_NOTHALTED;
380
381 /* registers are now invalid */
382 register_cache_invalidate(mips32->core_cache);
383
384 if (!debug_execution)
385 {
386 target->state = TARGET_RUNNING;
387 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
388 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
389 }
390 else
391 {
392 target->state = TARGET_DEBUG_RUNNING;
393 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
394 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
395 }
396
397 return ERROR_OK;
398 }
399
400 int mips_m4k_step(struct target *target, int current, uint32_t address, int handle_breakpoints)
401 {
402 /* get pointers to arch-specific information */
403 struct mips32_common *mips32 = target_to_mips32(target);
404 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
405 struct breakpoint *breakpoint = NULL;
406
407 if (target->state != TARGET_HALTED)
408 {
409 LOG_WARNING("target not halted");
410 return ERROR_TARGET_NOT_HALTED;
411 }
412
413 /* current = 1: continue on current pc, otherwise continue at <address> */
414 if (!current)
415 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
416
417 /* the front-end may request us not to handle breakpoints */
418 if (handle_breakpoints) {
419 breakpoint = breakpoint_find(target,
420 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
421 if (breakpoint)
422 mips_m4k_unset_breakpoint(target, breakpoint);
423 }
424
425 /* restore context */
426 mips32_restore_context(target);
427
428 /* configure single step mode */
429 mips_ejtag_config_step(ejtag_info, 1);
430
431 target->debug_reason = DBG_REASON_SINGLESTEP;
432
433 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
434
435 /* disable interrupts while stepping */
436 mips32_enable_interrupts(target, 0);
437
438 /* exit debug mode */
439 mips_ejtag_exit_debug(ejtag_info);
440
441 /* registers are now invalid */
442 register_cache_invalidate(mips32->core_cache);
443
444 if (breakpoint)
445 mips_m4k_set_breakpoint(target, breakpoint);
446
447 LOG_DEBUG("target stepped ");
448
449 mips_m4k_debug_entry(target);
450 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
451
452 return ERROR_OK;
453 }
454
455 void mips_m4k_enable_breakpoints(struct target *target)
456 {
457 struct breakpoint *breakpoint = target->breakpoints;
458
459 /* set any pending breakpoints */
460 while (breakpoint)
461 {
462 if (breakpoint->set == 0)
463 mips_m4k_set_breakpoint(target, breakpoint);
464 breakpoint = breakpoint->next;
465 }
466 }
467
468 int mips_m4k_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
469 {
470 struct mips32_common *mips32 = target_to_mips32(target);
471 struct mips32_comparator * comparator_list = mips32->inst_break_list;
472 int retval;
473
474 if (breakpoint->set)
475 {
476 LOG_WARNING("breakpoint already set");
477 return ERROR_OK;
478 }
479
480 if (breakpoint->type == BKPT_HARD)
481 {
482 int bp_num = 0;
483
484 while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))
485 bp_num++;
486 if (bp_num >= mips32->num_inst_bpoints)
487 {
488 LOG_ERROR("Can not find free FP Comparator(bpid: %d)",
489 breakpoint->unique_id );
490 return ERROR_FAIL;
491 }
492 breakpoint->set = bp_num + 1;
493 comparator_list[bp_num].used = 1;
494 comparator_list[bp_num].bp_value = breakpoint->address;
495 target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value);
496 target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000);
497 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1);
498 LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "",
499 breakpoint->unique_id,
500 bp_num, comparator_list[bp_num].bp_value);
501 }
502 else if (breakpoint->type == BKPT_SOFT)
503 {
504 LOG_DEBUG("bpid: %d", breakpoint->unique_id );
505 if (breakpoint->length == 4)
506 {
507 uint32_t verify = 0xffffffff;
508
509 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
510 breakpoint->orig_instr)) != ERROR_OK)
511 {
512 return retval;
513 }
514 if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK)
515 {
516 return retval;
517 }
518
519 if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK)
520 {
521 return retval;
522 }
523 if (verify != MIPS32_SDBBP)
524 {
525 LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
526 return ERROR_OK;
527 }
528 }
529 else
530 {
531 uint16_t verify = 0xffff;
532
533 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
534 breakpoint->orig_instr)) != ERROR_OK)
535 {
536 return retval;
537 }
538 if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK)
539 {
540 return retval;
541 }
542
543 if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK)
544 {
545 return retval;
546 }
547 if (verify != MIPS16_SDBBP)
548 {
549 LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
550 return ERROR_OK;
551 }
552 }
553
554 breakpoint->set = 20; /* Any nice value but 0 */
555 }
556
557 return ERROR_OK;
558 }
559
560 int mips_m4k_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
561 {
562 /* get pointers to arch-specific information */
563 struct mips32_common *mips32 = target_to_mips32(target);
564 struct mips32_comparator *comparator_list = mips32->inst_break_list;
565 int retval;
566
567 if (!breakpoint->set)
568 {
569 LOG_WARNING("breakpoint not set");
570 return ERROR_OK;
571 }
572
573 if (breakpoint->type == BKPT_HARD)
574 {
575 int bp_num = breakpoint->set - 1;
576 if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints))
577 {
578 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
579 breakpoint->unique_id);
580 return ERROR_OK;
581 }
582 LOG_DEBUG("bpid: %d - releasing hw: %d",
583 breakpoint->unique_id,
584 bp_num );
585 comparator_list[bp_num].used = 0;
586 comparator_list[bp_num].bp_value = 0;
587 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
588
589 }
590 else
591 {
592 /* restore original instruction (kept in target endianness) */
593 LOG_DEBUG("bpid: %d", breakpoint->unique_id);
594 if (breakpoint->length == 4)
595 {
596 uint32_t current_instr;
597
598 /* check that user program has not modified breakpoint instruction */
599 if ((retval = target_read_memory(target, breakpoint->address, 4, 1,
600 (uint8_t*)&current_instr)) != ERROR_OK)
601 {
602 return retval;
603 }
604 if (current_instr == MIPS32_SDBBP)
605 {
606 if ((retval = target_write_memory(target, breakpoint->address, 4, 1,
607 breakpoint->orig_instr)) != ERROR_OK)
608 {
609 return retval;
610 }
611 }
612 }
613 else
614 {
615 uint16_t current_instr;
616
617 /* check that user program has not modified breakpoint instruction */
618 if ((retval = target_read_memory(target, breakpoint->address, 2, 1,
619 (uint8_t*)&current_instr)) != ERROR_OK)
620 {
621 return retval;
622 }
623
624 if (current_instr == MIPS16_SDBBP)
625 {
626 if ((retval = target_write_memory(target, breakpoint->address, 2, 1,
627 breakpoint->orig_instr)) != ERROR_OK)
628 {
629 return retval;
630 }
631 }
632 }
633 }
634 breakpoint->set = 0;
635
636 return ERROR_OK;
637 }
638
639 int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
640 {
641 struct mips32_common *mips32 = target_to_mips32(target);
642
643 if (breakpoint->type == BKPT_HARD)
644 {
645 if (mips32->num_inst_bpoints_avail < 1)
646 {
647 LOG_INFO("no hardware breakpoint available");
648 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
649 }
650
651 mips32->num_inst_bpoints_avail--;
652 }
653
654 mips_m4k_set_breakpoint(target, breakpoint);
655
656 return ERROR_OK;
657 }
658
659 int mips_m4k_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
660 {
661 /* get pointers to arch-specific information */
662 struct mips32_common *mips32 = target_to_mips32(target);
663
664 if (target->state != TARGET_HALTED)
665 {
666 LOG_WARNING("target not halted");
667 return ERROR_TARGET_NOT_HALTED;
668 }
669
670 if (breakpoint->set)
671 {
672 mips_m4k_unset_breakpoint(target, breakpoint);
673 }
674
675 if (breakpoint->type == BKPT_HARD)
676 mips32->num_inst_bpoints_avail++;
677
678 return ERROR_OK;
679 }
680
681 int mips_m4k_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
682 {
683 struct mips32_common *mips32 = target_to_mips32(target);
684 struct mips32_comparator *comparator_list = mips32->data_break_list;
685 int wp_num = 0;
686 /*
687 * watchpoint enabled, ignore all byte lanes in value register
688 * and exclude both load and store accesses from watchpoint
689 * condition evaluation
690 */
691 int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
692 (0xff << EJTAG_DBCn_BLM_SHIFT);
693
694 if (watchpoint->set)
695 {
696 LOG_WARNING("watchpoint already set");
697 return ERROR_OK;
698 }
699
700 while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
701 wp_num++;
702 if (wp_num >= mips32->num_data_bpoints)
703 {
704 LOG_ERROR("Can not find free FP Comparator");
705 return ERROR_FAIL;
706 }
707
708 if (watchpoint->length != 4)
709 {
710 LOG_ERROR("Only watchpoints of length 4 are supported");
711 return ERROR_TARGET_UNALIGNED_ACCESS;
712 }
713
714 if (watchpoint->address % 4)
715 {
716 LOG_ERROR("Watchpoints address should be word aligned");
717 return ERROR_TARGET_UNALIGNED_ACCESS;
718 }
719
720 switch (watchpoint->rw)
721 {
722 case WPT_READ:
723 enable &= ~EJTAG_DBCn_NOLB;
724 break;
725 case WPT_WRITE:
726 enable &= ~EJTAG_DBCn_NOSB;
727 break;
728 case WPT_ACCESS:
729 enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB);
730 break;
731 default:
732 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
733 }
734
735 watchpoint->set = wp_num + 1;
736 comparator_list[wp_num].used = 1;
737 comparator_list[wp_num].bp_value = watchpoint->address;
738 target_write_u32(target, comparator_list[wp_num].reg_address, comparator_list[wp_num].bp_value);
739 target_write_u32(target, comparator_list[wp_num].reg_address + 0x08, 0x00000000);
740 target_write_u32(target, comparator_list[wp_num].reg_address + 0x10, 0x00000000);
741 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, enable);
742 target_write_u32(target, comparator_list[wp_num].reg_address + 0x20, 0);
743 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value);
744
745 return ERROR_OK;
746 }
747
748 int mips_m4k_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
749 {
750 /* get pointers to arch-specific information */
751 struct mips32_common *mips32 = target_to_mips32(target);
752 struct mips32_comparator *comparator_list = mips32->data_break_list;
753
754 if (!watchpoint->set)
755 {
756 LOG_WARNING("watchpoint not set");
757 return ERROR_OK;
758 }
759
760 int wp_num = watchpoint->set - 1;
761 if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints))
762 {
763 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
764 return ERROR_OK;
765 }
766 comparator_list[wp_num].used = 0;
767 comparator_list[wp_num].bp_value = 0;
768 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, 0);
769 watchpoint->set = 0;
770
771 return ERROR_OK;
772 }
773
774 int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
775 {
776 struct mips32_common *mips32 = target_to_mips32(target);
777
778 if (mips32->num_data_bpoints_avail < 1)
779 {
780 LOG_INFO("no hardware watchpoints available");
781 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
782 }
783
784 mips32->num_data_bpoints_avail--;
785
786 mips_m4k_set_watchpoint(target, watchpoint);
787 return ERROR_OK;
788 }
789
790 int mips_m4k_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
791 {
792 /* get pointers to arch-specific information */
793 struct mips32_common *mips32 = target_to_mips32(target);
794
795 if (target->state != TARGET_HALTED)
796 {
797 LOG_WARNING("target not halted");
798 return ERROR_TARGET_NOT_HALTED;
799 }
800
801 if (watchpoint->set)
802 {
803 mips_m4k_unset_watchpoint(target, watchpoint);
804 }
805
806 mips32->num_data_bpoints_avail++;
807
808 return ERROR_OK;
809 }
810
811 void mips_m4k_enable_watchpoints(struct target *target)
812 {
813 struct watchpoint *watchpoint = target->watchpoints;
814
815 /* set any pending watchpoints */
816 while (watchpoint)
817 {
818 if (watchpoint->set == 0)
819 mips_m4k_set_watchpoint(target, watchpoint);
820 watchpoint = watchpoint->next;
821 }
822 }
823
824 int mips_m4k_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
825 {
826 struct mips32_common *mips32 = target_to_mips32(target);
827 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
828
829 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
830
831 if (target->state != TARGET_HALTED)
832 {
833 LOG_WARNING("target not halted");
834 return ERROR_TARGET_NOT_HALTED;
835 }
836
837 /* sanitize arguments */
838 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
839 return ERROR_INVALID_ARGUMENTS;
840
841 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
842 return ERROR_TARGET_UNALIGNED_ACCESS;
843
844 /* if noDMA off, use DMAACC mode for memory read */
845 int retval;
846 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
847 retval = mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
848 else
849 retval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
850 if (ERROR_OK != retval)
851 return retval;
852
853 return ERROR_OK;
854 }
855
856 int mips_m4k_write_memory(struct target *target, uint32_t address, uint32_t size,
857 uint32_t count, uint8_t *buffer)
858 {
859 struct mips32_common *mips32 = target_to_mips32(target);
860 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
861
862 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
863 address, size, count);
864
865 if (target->state != TARGET_HALTED)
866 {
867 LOG_WARNING("target not halted");
868 return ERROR_TARGET_NOT_HALTED;
869 }
870
871 /* sanitize arguments */
872 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
873 return ERROR_INVALID_ARGUMENTS;
874
875 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
876 return ERROR_TARGET_UNALIGNED_ACCESS;
877
878 /* if noDMA off, use DMAACC mode for memory write */
879 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
880 return mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
881 else
882 return mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
883 }
884
885 int mips_m4k_init_target(struct command_context *cmd_ctx, struct target *target)
886 {
887 mips32_build_reg_cache(target);
888
889 return ERROR_OK;
890 }
891
892 int mips_m4k_init_arch_info(struct target *target, struct mips_m4k_common *mips_m4k,
893 struct jtag_tap *tap)
894 {
895 struct mips32_common *mips32 = &mips_m4k->mips32;
896
897 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
898
899 /* initialize mips4k specific info */
900 mips32_init_arch_info(target, mips32, tap);
901 mips32->arch_info = mips_m4k;
902
903 return ERROR_OK;
904 }
905
906 int mips_m4k_target_create(struct target *target, Jim_Interp *interp)
907 {
908 struct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common));
909
910 mips_m4k_init_arch_info(target, mips_m4k, target->tap);
911
912 return ERROR_OK;
913 }
914
915 int mips_m4k_examine(struct target *target)
916 {
917 int retval;
918 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
919 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
920 uint32_t idcode = 0;
921
922 if (!target_was_examined(target))
923 {
924 mips_ejtag_get_idcode(ejtag_info, &idcode);
925 ejtag_info->idcode = idcode;
926
927 if (((idcode >> 1) & 0x7FF) == 0x29)
928 {
929 /* we are using a pic32mx so select ejtag port
930 * as it is not selected by default */
931 mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
932 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
933 mips_m4k->is_pic32mx = true;
934 }
935 }
936
937 /* init rest of ejtag interface */
938 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
939 return retval;
940
941 if ((retval = mips32_examine(target)) != ERROR_OK)
942 return retval;
943
944 return ERROR_OK;
945 }
946
947 int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
948 uint32_t count, uint8_t *buffer)
949 {
950 struct mips32_common *mips32 = target_to_mips32(target);
951 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
952 struct working_area *source;
953 int retval;
954 int write = 1;
955
956 LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count);
957
958 if (target->state != TARGET_HALTED)
959 {
960 LOG_WARNING("target not halted");
961 return ERROR_TARGET_NOT_HALTED;
962 }
963
964 /* check alignment */
965 if (address & 0x3u)
966 return ERROR_TARGET_UNALIGNED_ACCESS;
967
968 /* Get memory for block write handler */
969 retval = target_alloc_working_area(target, MIPS32_FASTDATA_HANDLER_SIZE, &source);
970 if (retval != ERROR_OK)
971 {
972 LOG_WARNING("No working area available, falling back to non-bulk write");
973 return mips_m4k_write_memory(target, address, 4, count, buffer);
974 }
975
976 /* TAP data register is loaded LSB first (little endian) */
977 if (target->endianness == TARGET_BIG_ENDIAN)
978 {
979 uint32_t i, t32;
980 for(i = 0; i < (count * 4); i += 4)
981 {
982 t32 = be_to_h_u32((uint8_t *) &buffer[i]);
983 h_u32_to_le(&buffer[i], t32);
984 }
985 }
986
987 retval = mips32_pracc_fastdata_xfer(ejtag_info, source, write, address,
988 count, (uint32_t*) buffer);
989 if (retval != ERROR_OK)
990 {
991 /* FASTDATA access failed, try normal memory write */
992 LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write");
993 retval = mips_m4k_write_memory(target, address, 4, count, buffer);
994 }
995
996 if (source)
997 target_free_working_area(target, source);
998
999 return retval;
1000 }
1001
1002 struct target_type mips_m4k_target =
1003 {
1004 .name = "mips_m4k",
1005
1006 .poll = mips_m4k_poll,
1007 .arch_state = mips32_arch_state,
1008
1009 .target_request_data = NULL,
1010
1011 .halt = mips_m4k_halt,
1012 .resume = mips_m4k_resume,
1013 .step = mips_m4k_step,
1014
1015 .assert_reset = mips_m4k_assert_reset,
1016 .deassert_reset = mips_m4k_deassert_reset,
1017 .soft_reset_halt = mips_m4k_soft_reset_halt,
1018
1019 .get_gdb_reg_list = mips32_get_gdb_reg_list,
1020
1021 .read_memory = mips_m4k_read_memory,
1022 .write_memory = mips_m4k_write_memory,
1023 .bulk_write_memory = mips_m4k_bulk_write_memory,
1024 .checksum_memory = mips32_checksum_memory,
1025 .blank_check_memory = mips32_blank_check_memory,
1026
1027 .run_algorithm = mips32_run_algorithm,
1028
1029 .add_breakpoint = mips_m4k_add_breakpoint,
1030 .remove_breakpoint = mips_m4k_remove_breakpoint,
1031 .add_watchpoint = mips_m4k_add_watchpoint,
1032 .remove_watchpoint = mips_m4k_remove_watchpoint,
1033
1034 .target_create = mips_m4k_target_create,
1035 .init_target = mips_m4k_init_target,
1036 .examine = mips_m4k_examine,
1037 };

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)