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

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)