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

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)