21ff0ba94da1f1b569c86adcdf4c4bad8c2b21a8
[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 uint32_t mchip_cmd;
258
259 LOG_DEBUG("Using MTAP reset to reset processor...");
260
261 /* use microchip specific MTAP reset */
262 mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);
263 mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);
264
265 mchip_cmd = MCHP_ASERT_RST;
266 mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
267 mchip_cmd = MCHP_DE_ASSERT_RST;
268 mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
269 mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
270 }
271 else
272 {
273 /* use ejtag reset - not supported by all cores */
274 uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
275 LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
276 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
277 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
278 }
279 }
280
281 target->state = TARGET_RESET;
282 jtag_add_sleep(50000);
283
284 register_cache_invalidate(mips_m4k->mips32.core_cache);
285
286 if (target->reset_halt)
287 {
288 int retval;
289 if ((retval = target_halt(target)) != ERROR_OK)
290 return retval;
291 }
292
293 return ERROR_OK;
294 }
295
296 static int mips_m4k_deassert_reset(struct target *target)
297 {
298 LOG_DEBUG("target->state: %s",
299 target_state_name(target));
300
301 /* deassert reset lines */
302 jtag_add_reset(0, 0);
303
304 return ERROR_OK;
305 }
306
307 static int mips_m4k_soft_reset_halt(struct target *target)
308 {
309 /* TODO */
310 return ERROR_OK;
311 }
312
313 static int mips_m4k_single_step_core(struct target *target)
314 {
315 struct mips32_common *mips32 = target_to_mips32(target);
316 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
317
318 /* configure single step mode */
319 mips_ejtag_config_step(ejtag_info, 1);
320
321 /* disable interrupts while stepping */
322 mips32_enable_interrupts(target, 0);
323
324 /* exit debug mode */
325 mips_ejtag_exit_debug(ejtag_info);
326
327 mips_m4k_debug_entry(target);
328
329 return ERROR_OK;
330 }
331
332 static int mips_m4k_resume(struct target *target, int current,
333 uint32_t address, int handle_breakpoints, int debug_execution)
334 {
335 struct mips32_common *mips32 = target_to_mips32(target);
336 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
337 struct breakpoint *breakpoint = NULL;
338 uint32_t resume_pc;
339
340 if (target->state != TARGET_HALTED)
341 {
342 LOG_WARNING("target not halted");
343 return ERROR_TARGET_NOT_HALTED;
344 }
345
346 if (!debug_execution)
347 {
348 target_free_all_working_areas(target);
349 mips_m4k_enable_breakpoints(target);
350 mips_m4k_enable_watchpoints(target);
351 }
352
353 /* current = 1: continue on current pc, otherwise continue at <address> */
354 if (!current)
355 {
356 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
357 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
358 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
359 }
360
361 if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
362 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode);
363 }
364
365 resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
366
367 mips32_restore_context(target);
368
369 /* the front-end may request us not to handle breakpoints */
370 if (handle_breakpoints)
371 {
372 /* Single step past breakpoint at current address */
373 if ((breakpoint = breakpoint_find(target, resume_pc)))
374 {
375 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
376 mips_m4k_unset_breakpoint(target, breakpoint);
377 mips_m4k_single_step_core(target);
378 mips_m4k_set_breakpoint(target, breakpoint);
379 }
380 }
381
382 /* enable interrupts if we are running */
383 mips32_enable_interrupts(target, !debug_execution);
384
385 /* exit debug mode */
386 mips_ejtag_exit_debug(ejtag_info);
387 target->debug_reason = DBG_REASON_NOTHALTED;
388
389 /* registers are now invalid */
390 register_cache_invalidate(mips32->core_cache);
391
392 if (!debug_execution)
393 {
394 target->state = TARGET_RUNNING;
395 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
396 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
397 }
398 else
399 {
400 target->state = TARGET_DEBUG_RUNNING;
401 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
402 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
403 }
404
405 return ERROR_OK;
406 }
407
408 static int mips_m4k_step(struct target *target, int current,
409 uint32_t address, int handle_breakpoints)
410 {
411 /* get pointers to arch-specific information */
412 struct mips32_common *mips32 = target_to_mips32(target);
413 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
414 struct breakpoint *breakpoint = NULL;
415
416 if (target->state != TARGET_HALTED)
417 {
418 LOG_WARNING("target not halted");
419 return ERROR_TARGET_NOT_HALTED;
420 }
421
422 /* current = 1: continue on current pc, otherwise continue at <address> */
423 if (!current)
424 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
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_FAIL;
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 mips_m4k_set_breakpoint(target, breakpoint);
666
667 return ERROR_OK;
668 }
669
670 static int mips_m4k_remove_breakpoint(struct target *target,
671 struct breakpoint *breakpoint)
672 {
673 /* get pointers to arch-specific information */
674 struct mips32_common *mips32 = target_to_mips32(target);
675
676 if (target->state != TARGET_HALTED)
677 {
678 LOG_WARNING("target not halted");
679 return ERROR_TARGET_NOT_HALTED;
680 }
681
682 if (breakpoint->set)
683 {
684 mips_m4k_unset_breakpoint(target, breakpoint);
685 }
686
687 if (breakpoint->type == BKPT_HARD)
688 mips32->num_inst_bpoints_avail++;
689
690 return ERROR_OK;
691 }
692
693 static int mips_m4k_set_watchpoint(struct target *target,
694 struct watchpoint *watchpoint)
695 {
696 struct mips32_common *mips32 = target_to_mips32(target);
697 struct mips32_comparator *comparator_list = mips32->data_break_list;
698 int wp_num = 0;
699 /*
700 * watchpoint enabled, ignore all byte lanes in value register
701 * and exclude both load and store accesses from watchpoint
702 * condition evaluation
703 */
704 int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
705 (0xff << EJTAG_DBCn_BLM_SHIFT);
706
707 if (watchpoint->set)
708 {
709 LOG_WARNING("watchpoint already set");
710 return ERROR_OK;
711 }
712
713 while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
714 wp_num++;
715 if (wp_num >= mips32->num_data_bpoints)
716 {
717 LOG_ERROR("Can not find free FP Comparator");
718 return ERROR_FAIL;
719 }
720
721 if (watchpoint->length != 4)
722 {
723 LOG_ERROR("Only watchpoints of length 4 are supported");
724 return ERROR_TARGET_UNALIGNED_ACCESS;
725 }
726
727 if (watchpoint->address % 4)
728 {
729 LOG_ERROR("Watchpoints address should be word aligned");
730 return ERROR_TARGET_UNALIGNED_ACCESS;
731 }
732
733 switch (watchpoint->rw)
734 {
735 case WPT_READ:
736 enable &= ~EJTAG_DBCn_NOLB;
737 break;
738 case WPT_WRITE:
739 enable &= ~EJTAG_DBCn_NOSB;
740 break;
741 case WPT_ACCESS:
742 enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB);
743 break;
744 default:
745 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
746 }
747
748 watchpoint->set = wp_num + 1;
749 comparator_list[wp_num].used = 1;
750 comparator_list[wp_num].bp_value = watchpoint->address;
751 target_write_u32(target, comparator_list[wp_num].reg_address, comparator_list[wp_num].bp_value);
752 target_write_u32(target, comparator_list[wp_num].reg_address + 0x08, 0x00000000);
753 target_write_u32(target, comparator_list[wp_num].reg_address + 0x10, 0x00000000);
754 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, enable);
755 target_write_u32(target, comparator_list[wp_num].reg_address + 0x20, 0);
756 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value);
757
758 return ERROR_OK;
759 }
760
761 static int mips_m4k_unset_watchpoint(struct target *target,
762 struct watchpoint *watchpoint)
763 {
764 /* get pointers to arch-specific information */
765 struct mips32_common *mips32 = target_to_mips32(target);
766 struct mips32_comparator *comparator_list = mips32->data_break_list;
767
768 if (!watchpoint->set)
769 {
770 LOG_WARNING("watchpoint not set");
771 return ERROR_OK;
772 }
773
774 int wp_num = watchpoint->set - 1;
775 if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints))
776 {
777 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
778 return ERROR_OK;
779 }
780 comparator_list[wp_num].used = 0;
781 comparator_list[wp_num].bp_value = 0;
782 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, 0);
783 watchpoint->set = 0;
784
785 return ERROR_OK;
786 }
787
788 static int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
789 {
790 struct mips32_common *mips32 = target_to_mips32(target);
791
792 if (mips32->num_data_bpoints_avail < 1)
793 {
794 LOG_INFO("no hardware watchpoints available");
795 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
796 }
797
798 mips32->num_data_bpoints_avail--;
799
800 mips_m4k_set_watchpoint(target, watchpoint);
801 return ERROR_OK;
802 }
803
804 static int mips_m4k_remove_watchpoint(struct target *target,
805 struct watchpoint *watchpoint)
806 {
807 /* get pointers to arch-specific information */
808 struct mips32_common *mips32 = target_to_mips32(target);
809
810 if (target->state != TARGET_HALTED)
811 {
812 LOG_WARNING("target not halted");
813 return ERROR_TARGET_NOT_HALTED;
814 }
815
816 if (watchpoint->set)
817 {
818 mips_m4k_unset_watchpoint(target, watchpoint);
819 }
820
821 mips32->num_data_bpoints_avail++;
822
823 return ERROR_OK;
824 }
825
826 static void mips_m4k_enable_watchpoints(struct target *target)
827 {
828 struct watchpoint *watchpoint = target->watchpoints;
829
830 /* set any pending watchpoints */
831 while (watchpoint)
832 {
833 if (watchpoint->set == 0)
834 mips_m4k_set_watchpoint(target, watchpoint);
835 watchpoint = watchpoint->next;
836 }
837 }
838
839 static int mips_m4k_read_memory(struct target *target, uint32_t address,
840 uint32_t size, uint32_t count, uint8_t *buffer)
841 {
842 struct mips32_common *mips32 = target_to_mips32(target);
843 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
844
845 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
846
847 if (target->state != TARGET_HALTED)
848 {
849 LOG_WARNING("target not halted");
850 return ERROR_TARGET_NOT_HALTED;
851 }
852
853 /* sanitize arguments */
854 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
855 return ERROR_INVALID_ARGUMENTS;
856
857 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
858 return ERROR_TARGET_UNALIGNED_ACCESS;
859
860 /* if noDMA off, use DMAACC mode for memory read */
861 int retval;
862 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
863 retval = mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
864 else
865 retval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
866 if (ERROR_OK != retval)
867 return retval;
868
869 return ERROR_OK;
870 }
871
872 static int mips_m4k_write_memory(struct target *target, uint32_t address,
873 uint32_t size, uint32_t count, uint8_t *buffer)
874 {
875 struct mips32_common *mips32 = target_to_mips32(target);
876 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
877
878 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
879 address, size, count);
880
881 if (target->state != TARGET_HALTED)
882 {
883 LOG_WARNING("target not halted");
884 return ERROR_TARGET_NOT_HALTED;
885 }
886
887 /* sanitize arguments */
888 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
889 return ERROR_INVALID_ARGUMENTS;
890
891 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
892 return ERROR_TARGET_UNALIGNED_ACCESS;
893
894 /* if noDMA off, use DMAACC mode for memory write */
895 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
896 return mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
897 else
898 return mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
899 }
900
901 static int mips_m4k_init_target(struct command_context *cmd_ctx,
902 struct target *target)
903 {
904 mips32_build_reg_cache(target);
905
906 return ERROR_OK;
907 }
908
909 static int mips_m4k_init_arch_info(struct target *target,
910 struct mips_m4k_common *mips_m4k, struct jtag_tap *tap)
911 {
912 struct mips32_common *mips32 = &mips_m4k->mips32;
913
914 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
915
916 /* initialize mips4k specific info */
917 mips32_init_arch_info(target, mips32, tap);
918 mips32->arch_info = mips_m4k;
919
920 return ERROR_OK;
921 }
922
923 static int mips_m4k_target_create(struct target *target, Jim_Interp *interp)
924 {
925 struct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common));
926
927 mips_m4k_init_arch_info(target, mips_m4k, target->tap);
928
929 return ERROR_OK;
930 }
931
932 static int mips_m4k_examine(struct target *target)
933 {
934 int retval;
935 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
936 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
937 uint32_t idcode = 0;
938
939 if (!target_was_examined(target))
940 {
941 mips_ejtag_get_idcode(ejtag_info, &idcode);
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, uint8_t *buffer)
966 {
967 struct mips32_common *mips32 = target_to_mips32(target);
968 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
969 struct working_area *source;
970 int retval;
971 int write_t = 1;
972
973 LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count);
974
975 if (target->state != TARGET_HALTED)
976 {
977 LOG_WARNING("target not halted");
978 return ERROR_TARGET_NOT_HALTED;
979 }
980
981 /* check alignment */
982 if (address & 0x3u)
983 return ERROR_TARGET_UNALIGNED_ACCESS;
984
985 /* Get memory for block write handler */
986 retval = target_alloc_working_area(target, MIPS32_FASTDATA_HANDLER_SIZE, &source);
987 if (retval != ERROR_OK)
988 {
989 LOG_WARNING("No working area available, falling back to non-bulk write");
990 return mips_m4k_write_memory(target, address, 4, count, buffer);
991 }
992
993 /* TAP data register is loaded LSB first (little endian) */
994 if (target->endianness == TARGET_BIG_ENDIAN)
995 {
996 uint32_t i, t32;
997 for(i = 0; i < (count * 4); i += 4)
998 {
999 t32 = be_to_h_u32((uint8_t *) &buffer[i]);
1000 h_u32_to_le(&buffer[i], t32);
1001 }
1002 }
1003
1004 retval = mips32_pracc_fastdata_xfer(ejtag_info, source, write_t, address,
1005 count, (uint32_t*) buffer);
1006 if (retval != ERROR_OK)
1007 {
1008 /* FASTDATA access failed, try normal memory write */
1009 LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write");
1010 retval = mips_m4k_write_memory(target, address, 4, count, buffer);
1011 }
1012
1013 if (source)
1014 target_free_working_area(target, source);
1015
1016 return retval;
1017 }
1018
1019 struct target_type mips_m4k_target =
1020 {
1021 .name = "mips_m4k",
1022
1023 .poll = mips_m4k_poll,
1024 .arch_state = mips32_arch_state,
1025
1026 .target_request_data = NULL,
1027
1028 .halt = mips_m4k_halt,
1029 .resume = mips_m4k_resume,
1030 .step = mips_m4k_step,
1031
1032 .assert_reset = mips_m4k_assert_reset,
1033 .deassert_reset = mips_m4k_deassert_reset,
1034 .soft_reset_halt = mips_m4k_soft_reset_halt,
1035
1036 .get_gdb_reg_list = mips32_get_gdb_reg_list,
1037
1038 .read_memory = mips_m4k_read_memory,
1039 .write_memory = mips_m4k_write_memory,
1040 .bulk_write_memory = mips_m4k_bulk_write_memory,
1041 .checksum_memory = mips32_checksum_memory,
1042 .blank_check_memory = mips32_blank_check_memory,
1043
1044 .run_algorithm = mips32_run_algorithm,
1045
1046 .add_breakpoint = mips_m4k_add_breakpoint,
1047 .remove_breakpoint = mips_m4k_remove_breakpoint,
1048 .add_watchpoint = mips_m4k_add_watchpoint,
1049 .remove_watchpoint = mips_m4k_remove_watchpoint,
1050
1051 .target_create = mips_m4k_target_create,
1052 .init_target = mips_m4k_init_target,
1053 .examine = mips_m4k_examine,
1054 };

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)