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

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)