b84783b1ab0c2113c6b21fc220d53fe0405ed86e
[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 retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
124 if (retval != ERROR_OK)
125 return retval;
126
127 /* clear this bit before handling polling
128 * as after reset registers will read zero */
129 if (ejtag_ctrl & EJTAG_CTRL_ROCC)
130 {
131 /* we have detected a reset, clear flag
132 * otherwise ejtag will not work */
133 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
134
135 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
136 retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
137 if (retval != ERROR_OK)
138 return retval;
139 LOG_DEBUG("Reset Detected");
140 }
141
142 /* check for processor halted */
143 if (ejtag_ctrl & EJTAG_CTRL_BRKST)
144 {
145 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
146 {
147 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
148
149 target->state = TARGET_HALTED;
150
151 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
152 return retval;
153
154 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
155 }
156 else if (target->state == TARGET_DEBUG_RUNNING)
157 {
158 target->state = TARGET_HALTED;
159
160 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
161 return retval;
162
163 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
164 }
165 }
166 else
167 {
168 target->state = TARGET_RUNNING;
169 }
170
171 // LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl);
172
173 return ERROR_OK;
174 }
175
176 static int mips_m4k_halt(struct target *target)
177 {
178 struct mips32_common *mips32 = target_to_mips32(target);
179 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
180
181 LOG_DEBUG("target->state: %s",
182 target_state_name(target));
183
184 if (target->state == TARGET_HALTED)
185 {
186 LOG_DEBUG("target was already halted");
187 return ERROR_OK;
188 }
189
190 if (target->state == TARGET_UNKNOWN)
191 {
192 LOG_WARNING("target was in unknown state when halt was requested");
193 }
194
195 if (target->state == TARGET_RESET)
196 {
197 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
198 {
199 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
200 return ERROR_TARGET_FAILURE;
201 }
202 else
203 {
204 /* we came here in a reset_halt or reset_init sequence
205 * debug entry was already prepared in mips32_prepare_reset_halt()
206 */
207 target->debug_reason = DBG_REASON_DBGRQ;
208
209 return ERROR_OK;
210 }
211 }
212
213 /* break processor */
214 mips_ejtag_enter_debug(ejtag_info);
215
216 target->debug_reason = DBG_REASON_DBGRQ;
217
218 return ERROR_OK;
219 }
220
221 static int mips_m4k_assert_reset(struct target *target)
222 {
223 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
224 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
225 int assert_srst = 1;
226
227 LOG_DEBUG("target->state: %s",
228 target_state_name(target));
229
230 enum reset_types jtag_reset_config = jtag_get_reset_config();
231
232 if (!(jtag_reset_config & RESET_HAS_SRST))
233 assert_srst = 0;
234
235 if (target->reset_halt)
236 {
237 /* use hardware to catch reset */
238 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);
239 }
240 else
241 {
242 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
243 }
244
245 if (assert_srst)
246 {
247 /* here we should issue a srst only, but we may have to assert trst as well */
248 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
249 {
250 jtag_add_reset(1, 1);
251 }
252 else
253 {
254 jtag_add_reset(0, 1);
255 }
256 }
257 else
258 {
259 if (mips_m4k->is_pic32mx)
260 {
261 LOG_DEBUG("Using MTAP reset to reset processor...");
262
263 /* use microchip specific MTAP reset */
264 mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);
265 mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);
266
267 mips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST);
268 mips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST);
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_out(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 {
425 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
426 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
427 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
428 }
429
430 /* the front-end may request us not to handle breakpoints */
431 if (handle_breakpoints) {
432 breakpoint = breakpoint_find(target,
433 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
434 if (breakpoint)
435 mips_m4k_unset_breakpoint(target, breakpoint);
436 }
437
438 /* restore context */
439 mips32_restore_context(target);
440
441 /* configure single step mode */
442 mips_ejtag_config_step(ejtag_info, 1);
443
444 target->debug_reason = DBG_REASON_SINGLESTEP;
445
446 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
447
448 /* disable interrupts while stepping */
449 mips32_enable_interrupts(target, 0);
450
451 /* exit debug mode */
452 mips_ejtag_exit_debug(ejtag_info);
453
454 /* registers are now invalid */
455 register_cache_invalidate(mips32->core_cache);
456
457 if (breakpoint)
458 mips_m4k_set_breakpoint(target, breakpoint);
459
460 LOG_DEBUG("target stepped ");
461
462 mips_m4k_debug_entry(target);
463 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
464
465 return ERROR_OK;
466 }
467
468 static void mips_m4k_enable_breakpoints(struct target *target)
469 {
470 struct breakpoint *breakpoint = target->breakpoints;
471
472 /* set any pending breakpoints */
473 while (breakpoint)
474 {
475 if (breakpoint->set == 0)
476 mips_m4k_set_breakpoint(target, breakpoint);
477 breakpoint = breakpoint->next;
478 }
479 }
480
481 static int mips_m4k_set_breakpoint(struct target *target,
482 struct breakpoint *breakpoint)
483 {
484 struct mips32_common *mips32 = target_to_mips32(target);
485 struct mips32_comparator * comparator_list = mips32->inst_break_list;
486 int retval;
487
488 if (breakpoint->set)
489 {
490 LOG_WARNING("breakpoint already set");
491 return ERROR_OK;
492 }
493
494 if (breakpoint->type == BKPT_HARD)
495 {
496 int bp_num = 0;
497
498 while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))
499 bp_num++;
500 if (bp_num >= mips32->num_inst_bpoints)
501 {
502 LOG_ERROR("Can not find free FP Comparator(bpid: %d)",
503 breakpoint->unique_id );
504 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
505 }
506 breakpoint->set = bp_num + 1;
507 comparator_list[bp_num].used = 1;
508 comparator_list[bp_num].bp_value = breakpoint->address;
509 target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value);
510 target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000);
511 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1);
512 LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "",
513 breakpoint->unique_id,
514 bp_num, comparator_list[bp_num].bp_value);
515 }
516 else if (breakpoint->type == BKPT_SOFT)
517 {
518 LOG_DEBUG("bpid: %d", breakpoint->unique_id );
519 if (breakpoint->length == 4)
520 {
521 uint32_t verify = 0xffffffff;
522
523 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
524 breakpoint->orig_instr)) != ERROR_OK)
525 {
526 return retval;
527 }
528 if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK)
529 {
530 return retval;
531 }
532
533 if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK)
534 {
535 return retval;
536 }
537 if (verify != MIPS32_SDBBP)
538 {
539 LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
540 return ERROR_OK;
541 }
542 }
543 else
544 {
545 uint16_t verify = 0xffff;
546
547 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
548 breakpoint->orig_instr)) != ERROR_OK)
549 {
550 return retval;
551 }
552 if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK)
553 {
554 return retval;
555 }
556
557 if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK)
558 {
559 return retval;
560 }
561 if (verify != MIPS16_SDBBP)
562 {
563 LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
564 return ERROR_OK;
565 }
566 }
567
568 breakpoint->set = 20; /* Any nice value but 0 */
569 }
570
571 return ERROR_OK;
572 }
573
574 static int mips_m4k_unset_breakpoint(struct target *target,
575 struct breakpoint *breakpoint)
576 {
577 /* get pointers to arch-specific information */
578 struct mips32_common *mips32 = target_to_mips32(target);
579 struct mips32_comparator *comparator_list = mips32->inst_break_list;
580 int retval;
581
582 if (!breakpoint->set)
583 {
584 LOG_WARNING("breakpoint not set");
585 return ERROR_OK;
586 }
587
588 if (breakpoint->type == BKPT_HARD)
589 {
590 int bp_num = breakpoint->set - 1;
591 if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints))
592 {
593 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
594 breakpoint->unique_id);
595 return ERROR_OK;
596 }
597 LOG_DEBUG("bpid: %d - releasing hw: %d",
598 breakpoint->unique_id,
599 bp_num );
600 comparator_list[bp_num].used = 0;
601 comparator_list[bp_num].bp_value = 0;
602 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
603
604 }
605 else
606 {
607 /* restore original instruction (kept in target endianness) */
608 LOG_DEBUG("bpid: %d", breakpoint->unique_id);
609 if (breakpoint->length == 4)
610 {
611 uint32_t current_instr;
612
613 /* check that user program has not modified breakpoint instruction */
614 if ((retval = target_read_memory(target, breakpoint->address, 4, 1,
615 (uint8_t*)&current_instr)) != ERROR_OK)
616 {
617 return retval;
618 }
619
620 /**
621 * target_read_memory() gets us data in _target_ endianess.
622 * If we want to use this data on the host for comparisons with some macros
623 * we must first transform it to _host_ endianess using target_buffer_get_u32().
624 */
625 current_instr = target_buffer_get_u32(target, (uint8_t *)&current_instr);
626
627 if (current_instr == MIPS32_SDBBP)
628 {
629 if ((retval = target_write_memory(target, breakpoint->address, 4, 1,
630 breakpoint->orig_instr)) != ERROR_OK)
631 {
632 return retval;
633 }
634 }
635 }
636 else
637 {
638 uint16_t current_instr;
639
640 /* check that user program has not modified breakpoint instruction */
641 if ((retval = target_read_memory(target, breakpoint->address, 2, 1,
642 (uint8_t*)&current_instr)) != ERROR_OK)
643 {
644 return retval;
645 }
646
647 if (current_instr == MIPS16_SDBBP)
648 {
649 if ((retval = target_write_memory(target, breakpoint->address, 2, 1,
650 breakpoint->orig_instr)) != ERROR_OK)
651 {
652 return retval;
653 }
654 }
655 }
656 }
657 breakpoint->set = 0;
658
659 return ERROR_OK;
660 }
661
662 static int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
663 {
664 struct mips32_common *mips32 = target_to_mips32(target);
665
666 if (breakpoint->type == BKPT_HARD)
667 {
668 if (mips32->num_inst_bpoints_avail < 1)
669 {
670 LOG_INFO("no hardware breakpoint available");
671 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
672 }
673
674 mips32->num_inst_bpoints_avail--;
675 }
676
677 return mips_m4k_set_breakpoint(target, breakpoint);
678 }
679
680 static int mips_m4k_remove_breakpoint(struct target *target,
681 struct breakpoint *breakpoint)
682 {
683 /* get pointers to arch-specific information */
684 struct mips32_common *mips32 = target_to_mips32(target);
685
686 if (target->state != TARGET_HALTED)
687 {
688 LOG_WARNING("target not halted");
689 return ERROR_TARGET_NOT_HALTED;
690 }
691
692 if (breakpoint->set)
693 {
694 mips_m4k_unset_breakpoint(target, breakpoint);
695 }
696
697 if (breakpoint->type == BKPT_HARD)
698 mips32->num_inst_bpoints_avail++;
699
700 return ERROR_OK;
701 }
702
703 static int mips_m4k_set_watchpoint(struct target *target,
704 struct watchpoint *watchpoint)
705 {
706 struct mips32_common *mips32 = target_to_mips32(target);
707 struct mips32_comparator *comparator_list = mips32->data_break_list;
708 int wp_num = 0;
709 /*
710 * watchpoint enabled, ignore all byte lanes in value register
711 * and exclude both load and store accesses from watchpoint
712 * condition evaluation
713 */
714 int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
715 (0xff << EJTAG_DBCn_BLM_SHIFT);
716
717 if (watchpoint->set)
718 {
719 LOG_WARNING("watchpoint already set");
720 return ERROR_OK;
721 }
722
723 while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
724 wp_num++;
725 if (wp_num >= mips32->num_data_bpoints)
726 {
727 LOG_ERROR("Can not find free FP Comparator");
728 return ERROR_FAIL;
729 }
730
731 if (watchpoint->length != 4)
732 {
733 LOG_ERROR("Only watchpoints of length 4 are supported");
734 return ERROR_TARGET_UNALIGNED_ACCESS;
735 }
736
737 if (watchpoint->address % 4)
738 {
739 LOG_ERROR("Watchpoints address should be word aligned");
740 return ERROR_TARGET_UNALIGNED_ACCESS;
741 }
742
743 switch (watchpoint->rw)
744 {
745 case WPT_READ:
746 enable &= ~EJTAG_DBCn_NOLB;
747 break;
748 case WPT_WRITE:
749 enable &= ~EJTAG_DBCn_NOSB;
750 break;
751 case WPT_ACCESS:
752 enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB);
753 break;
754 default:
755 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
756 }
757
758 watchpoint->set = wp_num + 1;
759 comparator_list[wp_num].used = 1;
760 comparator_list[wp_num].bp_value = watchpoint->address;
761 target_write_u32(target, comparator_list[wp_num].reg_address, comparator_list[wp_num].bp_value);
762 target_write_u32(target, comparator_list[wp_num].reg_address + 0x08, 0x00000000);
763 target_write_u32(target, comparator_list[wp_num].reg_address + 0x10, 0x00000000);
764 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, enable);
765 target_write_u32(target, comparator_list[wp_num].reg_address + 0x20, 0);
766 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value);
767
768 return ERROR_OK;
769 }
770
771 static int mips_m4k_unset_watchpoint(struct target *target,
772 struct watchpoint *watchpoint)
773 {
774 /* get pointers to arch-specific information */
775 struct mips32_common *mips32 = target_to_mips32(target);
776 struct mips32_comparator *comparator_list = mips32->data_break_list;
777
778 if (!watchpoint->set)
779 {
780 LOG_WARNING("watchpoint not set");
781 return ERROR_OK;
782 }
783
784 int wp_num = watchpoint->set - 1;
785 if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints))
786 {
787 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
788 return ERROR_OK;
789 }
790 comparator_list[wp_num].used = 0;
791 comparator_list[wp_num].bp_value = 0;
792 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, 0);
793 watchpoint->set = 0;
794
795 return ERROR_OK;
796 }
797
798 static int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
799 {
800 struct mips32_common *mips32 = target_to_mips32(target);
801
802 if (mips32->num_data_bpoints_avail < 1)
803 {
804 LOG_INFO("no hardware watchpoints available");
805 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
806 }
807
808 mips32->num_data_bpoints_avail--;
809
810 mips_m4k_set_watchpoint(target, watchpoint);
811 return ERROR_OK;
812 }
813
814 static int mips_m4k_remove_watchpoint(struct target *target,
815 struct watchpoint *watchpoint)
816 {
817 /* get pointers to arch-specific information */
818 struct mips32_common *mips32 = target_to_mips32(target);
819
820 if (target->state != TARGET_HALTED)
821 {
822 LOG_WARNING("target not halted");
823 return ERROR_TARGET_NOT_HALTED;
824 }
825
826 if (watchpoint->set)
827 {
828 mips_m4k_unset_watchpoint(target, watchpoint);
829 }
830
831 mips32->num_data_bpoints_avail++;
832
833 return ERROR_OK;
834 }
835
836 static void mips_m4k_enable_watchpoints(struct target *target)
837 {
838 struct watchpoint *watchpoint = target->watchpoints;
839
840 /* set any pending watchpoints */
841 while (watchpoint)
842 {
843 if (watchpoint->set == 0)
844 mips_m4k_set_watchpoint(target, watchpoint);
845 watchpoint = watchpoint->next;
846 }
847 }
848
849 static int mips_m4k_read_memory(struct target *target, uint32_t address,
850 uint32_t size, uint32_t count, uint8_t *buffer)
851 {
852 struct mips32_common *mips32 = target_to_mips32(target);
853 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
854
855 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
856
857 if (target->state != TARGET_HALTED)
858 {
859 LOG_WARNING("target not halted");
860 return ERROR_TARGET_NOT_HALTED;
861 }
862
863 /* sanitize arguments */
864 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
865 return ERROR_INVALID_ARGUMENTS;
866
867 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
868 return ERROR_TARGET_UNALIGNED_ACCESS;
869
870 /* if noDMA off, use DMAACC mode for memory read */
871 int retval;
872 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
873 retval = mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
874 else
875 retval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
876 if (ERROR_OK != retval)
877 return retval;
878
879 /* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */
880 /* endianness, but byte array should represent target endianness */
881 uint32_t i, t32;
882 uint16_t t16;
883 for(i = 0; i < (count*size); i += size)
884 {
885 switch(size)
886 {
887 case 4:
888 t32 = le_to_h_u32(&buffer[i]);
889 target_buffer_set_u32(target,&buffer[i], t32);
890 break;
891 case 2:
892 t16 = le_to_h_u16(&buffer[i]);
893 target_buffer_set_u16(target,&buffer[i], t16);
894 break;
895 }
896 }
897
898 return ERROR_OK;
899 }
900
901 static int mips_m4k_write_memory(struct target *target, uint32_t address,
902 uint32_t size, uint32_t count, const uint8_t *buffer)
903 {
904 struct mips32_common *mips32 = target_to_mips32(target);
905 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
906
907 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
908 address, size, count);
909
910 if (target->state != TARGET_HALTED)
911 {
912 LOG_WARNING("target not halted");
913 return ERROR_TARGET_NOT_HALTED;
914 }
915
916 /* sanitize arguments */
917 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
918 return ERROR_INVALID_ARGUMENTS;
919
920 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
921 return ERROR_TARGET_UNALIGNED_ACCESS;
922
923 /* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */
924 /* endianness, but byte array represents target endianness */
925 uint8_t * t = NULL;
926 t = malloc(count * sizeof(uint32_t));
927 if (t == NULL)
928 {
929 LOG_ERROR("Out of memory");
930 return ERROR_FAIL;
931 }
932
933 uint32_t i, t32;
934 uint16_t t16;
935 for(i = 0; i < (count*size); i += size)
936 {
937 switch(size)
938 {
939 case 4:
940 t32 = target_buffer_get_u32(target,&buffer[i]);
941 h_u32_to_le(&t[i], t32);
942 break;
943 case 2:
944 t16 = target_buffer_get_u16(target,&buffer[i]);
945 h_u16_to_le(&t[i], t16);
946 break;
947 }
948 }
949 buffer = t;
950
951 /* if noDMA off, use DMAACC mode for memory write */
952 int retval;
953 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
954 retval = mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
955 else
956 retval = mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
957
958 if (t != NULL)
959 free(t);
960
961 if (ERROR_OK != retval)
962 return retval;
963
964 return ERROR_OK;
965 }
966
967 static int mips_m4k_init_target(struct command_context *cmd_ctx,
968 struct target *target)
969 {
970 mips32_build_reg_cache(target);
971
972 return ERROR_OK;
973 }
974
975 static int mips_m4k_init_arch_info(struct target *target,
976 struct mips_m4k_common *mips_m4k, struct jtag_tap *tap)
977 {
978 struct mips32_common *mips32 = &mips_m4k->mips32;
979
980 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
981
982 /* initialize mips4k specific info */
983 mips32_init_arch_info(target, mips32, tap);
984 mips32->arch_info = mips_m4k;
985
986 return ERROR_OK;
987 }
988
989 static int mips_m4k_target_create(struct target *target, Jim_Interp *interp)
990 {
991 struct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common));
992
993 mips_m4k_init_arch_info(target, mips_m4k, target->tap);
994
995 return ERROR_OK;
996 }
997
998 static int mips_m4k_examine(struct target *target)
999 {
1000 int retval;
1001 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
1002 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
1003 uint32_t idcode = 0;
1004
1005 if (!target_was_examined(target))
1006 {
1007 retval = mips_ejtag_get_idcode(ejtag_info, &idcode);
1008 if (retval != ERROR_OK)
1009 return retval;
1010 ejtag_info->idcode = idcode;
1011
1012 if (((idcode >> 1) & 0x7FF) == 0x29)
1013 {
1014 /* we are using a pic32mx so select ejtag port
1015 * as it is not selected by default */
1016 mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
1017 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
1018 mips_m4k->is_pic32mx = true;
1019 }
1020 }
1021
1022 /* init rest of ejtag interface */
1023 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
1024 return retval;
1025
1026 if ((retval = mips32_examine(target)) != ERROR_OK)
1027 return retval;
1028
1029 return ERROR_OK;
1030 }
1031
1032 static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
1033 uint32_t count, const uint8_t *buffer)
1034 {
1035 struct mips32_common *mips32 = target_to_mips32(target);
1036 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1037 int retval;
1038 int write_t = 1;
1039
1040 LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count);
1041
1042 if (target->state != TARGET_HALTED)
1043 {
1044 LOG_WARNING("target not halted");
1045 return ERROR_TARGET_NOT_HALTED;
1046 }
1047
1048 /* check alignment */
1049 if (address & 0x3u)
1050 return ERROR_TARGET_UNALIGNED_ACCESS;
1051
1052 if (mips32->fast_data_area == NULL)
1053 {
1054 /* Get memory for block write handler
1055 * we preserve this area between calls and gain a speed increase
1056 * of about 3kb/sec when writing flash
1057 * this will be released/nulled by the system when the target is resumed or reset */
1058 retval = target_alloc_working_area(target,
1059 MIPS32_FASTDATA_HANDLER_SIZE,
1060 &mips32->fast_data_area);
1061 if (retval != ERROR_OK)
1062 {
1063 LOG_WARNING("No working area available, falling back to non-bulk write");
1064 return mips_m4k_write_memory(target, address, 4, count, buffer);
1065 }
1066
1067 /* reset fastadata state so the algo get reloaded */
1068 ejtag_info->fast_access_save = -1;
1069 }
1070
1071 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
1072 /* but byte array represents target endianness */
1073 uint8_t * t = NULL;
1074 t = malloc(count * sizeof(uint32_t));
1075 if (t == NULL)
1076 {
1077 LOG_ERROR("Out of memory");
1078 return ERROR_FAIL;
1079 }
1080
1081 uint32_t i, t32;
1082 for(i = 0; i < (count*4); i += 4)
1083 {
1084 t32 = target_buffer_get_u32(target,&buffer[i]);
1085 h_u32_to_le(&t[i], t32);
1086 }
1087
1088 retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,
1089 count, (uint32_t*) (void *)t);
1090
1091 if (t != NULL)
1092 free(t);
1093
1094 if (retval != ERROR_OK)
1095 {
1096 /* FASTDATA access failed, try normal memory write */
1097 LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write");
1098 retval = mips_m4k_write_memory(target, address, 4, count, buffer);
1099 }
1100
1101 return retval;
1102 }
1103
1104 struct target_type mips_m4k_target =
1105 {
1106 .name = "mips_m4k",
1107
1108 .poll = mips_m4k_poll,
1109 .arch_state = mips32_arch_state,
1110
1111 .target_request_data = NULL,
1112
1113 .halt = mips_m4k_halt,
1114 .resume = mips_m4k_resume,
1115 .step = mips_m4k_step,
1116
1117 .assert_reset = mips_m4k_assert_reset,
1118 .deassert_reset = mips_m4k_deassert_reset,
1119 .soft_reset_halt = mips_m4k_soft_reset_halt,
1120
1121 .get_gdb_reg_list = mips32_get_gdb_reg_list,
1122
1123 .read_memory = mips_m4k_read_memory,
1124 .write_memory = mips_m4k_write_memory,
1125 .bulk_write_memory = mips_m4k_bulk_write_memory,
1126 .checksum_memory = mips32_checksum_memory,
1127 .blank_check_memory = mips32_blank_check_memory,
1128
1129 .run_algorithm = mips32_run_algorithm,
1130
1131 .add_breakpoint = mips_m4k_add_breakpoint,
1132 .remove_breakpoint = mips_m4k_remove_breakpoint,
1133 .add_watchpoint = mips_m4k_add_watchpoint,
1134 .remove_watchpoint = mips_m4k_remove_watchpoint,
1135
1136 .target_create = mips_m4k_target_create,
1137 .init_target = mips_m4k_init_target,
1138 .examine = mips_m4k_examine,
1139 };

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)