command_context_t -> struct command_context
[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 "mips32.h"
27 #include "mips_m4k.h"
28 #include "mips32_dmaacc.h"
29 #include "target_type.h"
30
31
32 /* cli handling */
33
34 /* forward declarations */
35 int mips_m4k_poll(struct target *target);
36 int mips_m4k_halt(struct target *target);
37 int mips_m4k_soft_reset_halt(struct target *target);
38 int mips_m4k_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution);
39 int mips_m4k_step(struct target *target, int current, uint32_t address, int handle_breakpoints);
40 int mips_m4k_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
41 int mips_m4k_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
42 int mips_m4k_register_commands(struct command_context *cmd_ctx);
43 int mips_m4k_init_target(struct command_context *cmd_ctx, struct target *target);
44 int mips_m4k_target_create(struct target *target, Jim_Interp *interp);
45
46 int mips_m4k_examine(struct target *target);
47 int mips_m4k_assert_reset(struct target *target);
48 int mips_m4k_deassert_reset(struct target *target);
49 int mips_m4k_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t *checksum);
50
51 struct target_type mips_m4k_target =
52 {
53 .name = "mips_m4k",
54
55 .poll = mips_m4k_poll,
56 .arch_state = mips32_arch_state,
57
58 .target_request_data = NULL,
59
60 .halt = mips_m4k_halt,
61 .resume = mips_m4k_resume,
62 .step = mips_m4k_step,
63
64 .assert_reset = mips_m4k_assert_reset,
65 .deassert_reset = mips_m4k_deassert_reset,
66 .soft_reset_halt = mips_m4k_soft_reset_halt,
67
68 .get_gdb_reg_list = mips32_get_gdb_reg_list,
69
70 .read_memory = mips_m4k_read_memory,
71 .write_memory = mips_m4k_write_memory,
72 .bulk_write_memory = mips_m4k_bulk_write_memory,
73 .checksum_memory = mips_m4k_checksum_memory,
74 .blank_check_memory = NULL,
75
76 .run_algorithm = mips32_run_algorithm,
77
78 .add_breakpoint = mips_m4k_add_breakpoint,
79 .remove_breakpoint = mips_m4k_remove_breakpoint,
80 .add_watchpoint = mips_m4k_add_watchpoint,
81 .remove_watchpoint = mips_m4k_remove_watchpoint,
82
83 .register_commands = mips_m4k_register_commands,
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 mips32_invalidate_core_regs(target);
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 mips32_invalidate_core_regs(target);
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 mips32_invalidate_core_regs(target);
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_DEBUG("ERROR Can not find free FP Comparator(bpid: %d)",
515 breakpoint->unique_id );
516 LOG_WARNING("ERROR Can not find free FP Comparator");
517 exit(-1);
518 }
519 breakpoint->set = bp_num + 1;
520 comparator_list[bp_num].used = 1;
521 comparator_list[bp_num].bp_value = breakpoint->address;
522 target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value);
523 target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000);
524 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1);
525 LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "",
526 breakpoint->unique_id,
527 bp_num, comparator_list[bp_num].bp_value);
528 }
529 else if (breakpoint->type == BKPT_SOFT)
530 {
531 LOG_DEBUG("bpid: %d", breakpoint->unique_id );
532 if (breakpoint->length == 4)
533 {
534 uint32_t verify = 0xffffffff;
535
536 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
537 {
538 return retval;
539 }
540 if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK)
541 {
542 return retval;
543 }
544
545 if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK)
546 {
547 return retval;
548 }
549 if (verify != MIPS32_SDBBP)
550 {
551 LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
552 return ERROR_OK;
553 }
554 }
555 else
556 {
557 uint16_t verify = 0xffff;
558
559 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
560 {
561 return retval;
562 }
563 if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK)
564 {
565 return retval;
566 }
567
568 if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK)
569 {
570 return retval;
571 }
572 if (verify != MIPS16_SDBBP)
573 {
574 LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
575 return ERROR_OK;
576 }
577 }
578
579 breakpoint->set = 20; /* Any nice value but 0 */
580 }
581
582 return ERROR_OK;
583 }
584
585 int mips_m4k_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
586 {
587 /* get pointers to arch-specific information */
588 struct mips32_common *mips32 = target->arch_info;
589 struct mips32_comparator * comparator_list = mips32->inst_break_list;
590 int retval;
591
592 if (!breakpoint->set)
593 {
594 LOG_WARNING("breakpoint not set");
595 return ERROR_OK;
596 }
597
598 if (breakpoint->type == BKPT_HARD)
599 {
600 int bp_num = breakpoint->set - 1;
601 if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints))
602 {
603 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
604 breakpoint->unique_id);
605 return ERROR_OK;
606 }
607 LOG_DEBUG("bpid: %d - releasing hw: %d",
608 breakpoint->unique_id,
609 bp_num );
610 comparator_list[bp_num].used = 0;
611 comparator_list[bp_num].bp_value = 0;
612 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
613
614 }
615 else
616 {
617 /* restore original instruction (kept in target endianness) */
618 LOG_DEBUG("bpid: %d", breakpoint->unique_id);
619 if (breakpoint->length == 4)
620 {
621 uint32_t current_instr;
622
623 /* check that user program has not modified breakpoint instruction */
624 if ((retval = target_read_memory(target, breakpoint->address, 4, 1, (uint8_t*)&current_instr)) != ERROR_OK)
625 {
626 return retval;
627 }
628 if (current_instr == MIPS32_SDBBP)
629 {
630 if ((retval = target_write_memory(target, breakpoint->address, 4, 1, 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, (uint8_t*)&current_instr)) != ERROR_OK)
642 {
643 return retval;
644 }
645
646 if (current_instr == MIPS16_SDBBP)
647 {
648 if ((retval = target_write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
649 {
650 return retval;
651 }
652 }
653 }
654 }
655 breakpoint->set = 0;
656
657 return ERROR_OK;
658 }
659
660 int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
661 {
662 struct mips32_common *mips32 = target->arch_info;
663
664 if (breakpoint->type == BKPT_HARD)
665 {
666 if (mips32->num_inst_bpoints_avail < 1)
667 {
668 LOG_INFO("no hardware breakpoint available");
669 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
670 }
671
672 mips32->num_inst_bpoints_avail--;
673 }
674
675 mips_m4k_set_breakpoint(target, breakpoint);
676
677 return ERROR_OK;
678 }
679
680 int mips_m4k_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
681 {
682 /* get pointers to arch-specific information */
683 struct mips32_common *mips32 = target->arch_info;
684
685 if (target->state != TARGET_HALTED)
686 {
687 LOG_WARNING("target not halted");
688 return ERROR_TARGET_NOT_HALTED;
689 }
690
691 if (breakpoint->set)
692 {
693 mips_m4k_unset_breakpoint(target, breakpoint);
694 }
695
696 if (breakpoint->type == BKPT_HARD)
697 mips32->num_inst_bpoints_avail++;
698
699 return ERROR_OK;
700 }
701
702 int mips_m4k_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
703 {
704 struct mips32_common *mips32 = target->arch_info;
705 struct mips32_comparator * comparator_list = mips32->data_break_list;
706 int wp_num = 0;
707 /*
708 * watchpoint enabled, ignore all byte lanes in value register
709 * and exclude both load and store accesses from watchpoint
710 * condition evaluation
711 */
712 int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
713 (0xff << EJTAG_DBCn_BLM_SHIFT);
714
715 if (watchpoint->set)
716 {
717 LOG_WARNING("watchpoint already set");
718 return ERROR_OK;
719 }
720
721 while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
722 wp_num++;
723 if (wp_num >= mips32->num_data_bpoints)
724 {
725 LOG_DEBUG("ERROR Can not find free FP Comparator");
726 LOG_WARNING("ERROR Can not find free FP Comparator");
727 exit(-1);
728 }
729
730 if (watchpoint->length != 4)
731 {
732 LOG_ERROR("Only watchpoints of length 4 are supported");
733 return ERROR_TARGET_UNALIGNED_ACCESS;
734 }
735
736 if (watchpoint->address % 4)
737 {
738 LOG_ERROR("Watchpoints address should be word aligned");
739 return ERROR_TARGET_UNALIGNED_ACCESS;
740 }
741
742 switch (watchpoint->rw)
743 {
744 case WPT_READ:
745 enable &= ~EJTAG_DBCn_NOLB;
746 break;
747 case WPT_WRITE:
748 enable &= ~EJTAG_DBCn_NOSB;
749 break;
750 case WPT_ACCESS:
751 enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB);
752 break;
753 default:
754 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
755 }
756
757 watchpoint->set = wp_num + 1;
758 comparator_list[wp_num].used = 1;
759 comparator_list[wp_num].bp_value = watchpoint->address;
760 target_write_u32(target, comparator_list[wp_num].reg_address, comparator_list[wp_num].bp_value);
761 target_write_u32(target, comparator_list[wp_num].reg_address + 0x08, 0x00000000);
762 target_write_u32(target, comparator_list[wp_num].reg_address + 0x10, 0x00000000);
763 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, enable);
764 target_write_u32(target, comparator_list[wp_num].reg_address + 0x20, 0);
765 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value);
766
767 return ERROR_OK;
768 }
769
770 int mips_m4k_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
771 {
772 /* get pointers to arch-specific information */
773 struct mips32_common *mips32 = target->arch_info;
774 struct mips32_comparator * comparator_list = mips32->data_break_list;
775
776 if (!watchpoint->set)
777 {
778 LOG_WARNING("watchpoint not set");
779 return ERROR_OK;
780 }
781
782 int wp_num = watchpoint->set - 1;
783 if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints))
784 {
785 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
786 return ERROR_OK;
787 }
788 comparator_list[wp_num].used = 0;
789 comparator_list[wp_num].bp_value = 0;
790 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, 0);
791 watchpoint->set = 0;
792
793 return ERROR_OK;
794 }
795
796 int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
797 {
798 struct mips32_common *mips32 = target->arch_info;
799
800 if (mips32->num_data_bpoints_avail < 1)
801 {
802 LOG_INFO("no hardware watchpoints available");
803 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
804 }
805
806 mips32->num_data_bpoints_avail--;
807
808 mips_m4k_set_watchpoint(target, watchpoint);
809 return ERROR_OK;
810 }
811
812 int mips_m4k_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
813 {
814 /* get pointers to arch-specific information */
815 struct mips32_common *mips32 = target->arch_info;
816
817 if (target->state != TARGET_HALTED)
818 {
819 LOG_WARNING("target not halted");
820 return ERROR_TARGET_NOT_HALTED;
821 }
822
823 if (watchpoint->set)
824 {
825 mips_m4k_unset_watchpoint(target, watchpoint);
826 }
827
828 mips32->num_data_bpoints_avail++;
829
830 return ERROR_OK;
831 }
832
833 void mips_m4k_enable_watchpoints(struct target *target)
834 {
835 struct watchpoint *watchpoint = target->watchpoints;
836
837 /* set any pending watchpoints */
838 while (watchpoint)
839 {
840 if (watchpoint->set == 0)
841 mips_m4k_set_watchpoint(target, watchpoint);
842 watchpoint = watchpoint->next;
843 }
844 }
845
846 int mips_m4k_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
847 {
848 struct mips32_common *mips32 = target->arch_info;
849 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
850
851 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
852
853 if (target->state != TARGET_HALTED)
854 {
855 LOG_WARNING("target not halted");
856 return ERROR_TARGET_NOT_HALTED;
857 }
858
859 /* sanitize arguments */
860 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
861 return ERROR_INVALID_ARGUMENTS;
862
863 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
864 return ERROR_TARGET_UNALIGNED_ACCESS;
865
866 /* if noDMA off, use DMAACC mode for memory read */
867 int retval;
868 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
869 retval = mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
870 else
871 retval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
872 if (ERROR_OK != retval)
873 return retval;
874
875 return ERROR_OK;
876 }
877
878 int mips_m4k_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
879 {
880 struct mips32_common *mips32 = target->arch_info;
881 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
882
883 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
884
885 if (target->state != TARGET_HALTED)
886 {
887 LOG_WARNING("target not halted");
888 return ERROR_TARGET_NOT_HALTED;
889 }
890
891 /* sanitize arguments */
892 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
893 return ERROR_INVALID_ARGUMENTS;
894
895 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
896 return ERROR_TARGET_UNALIGNED_ACCESS;
897
898 /* if noDMA off, use DMAACC mode for memory write */
899 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
900 return mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
901 else
902 return mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
903 }
904
905 int mips_m4k_register_commands(struct command_context *cmd_ctx)
906 {
907 int retval;
908
909 retval = mips32_register_commands(cmd_ctx);
910 return retval;
911 }
912
913 int mips_m4k_init_target(struct command_context *cmd_ctx, struct target *target)
914 {
915 mips32_build_reg_cache(target);
916
917 return ERROR_OK;
918 }
919
920 int mips_m4k_init_arch_info(struct target *target, struct mips_m4k_common *mips_m4k, struct jtag_tap *tap)
921 {
922 struct mips32_common *mips32 = &mips_m4k->mips32_common;
923
924 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
925
926 /* initialize mips4k specific info */
927 mips32_init_arch_info(target, mips32, tap);
928 mips32->arch_info = mips_m4k;
929
930 return ERROR_OK;
931 }
932
933 int mips_m4k_target_create(struct target *target, Jim_Interp *interp)
934 {
935 struct mips_m4k_common *mips_m4k = calloc(1,sizeof(struct mips_m4k_common));
936
937 mips_m4k_init_arch_info(target, mips_m4k, target->tap);
938
939 return ERROR_OK;
940 }
941
942 int mips_m4k_examine(struct target *target)
943 {
944 int retval;
945 struct mips32_common *mips32 = target->arch_info;
946 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
947 uint32_t idcode = 0;
948
949 if (!target_was_examined(target))
950 {
951 mips_ejtag_get_idcode(ejtag_info, &idcode);
952 ejtag_info->idcode = idcode;
953
954 if (((idcode >> 1) & 0x7FF) == 0x29)
955 {
956 /* we are using a pic32mx so select ejtag port
957 * as it is not selected by default */
958 mips_ejtag_set_instr(ejtag_info, 0x05, NULL);
959 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
960 }
961 }
962
963 /* init rest of ejtag interface */
964 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
965 return retval;
966
967 if ((retval = mips32_examine(target)) != ERROR_OK)
968 return retval;
969
970 return ERROR_OK;
971 }
972
973 int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer)
974 {
975 return mips_m4k_write_memory(target, address, 4, count, buffer);
976 }
977
978 int mips_m4k_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t *checksum)
979 {
980 return ERROR_FAIL; /* use bulk read method */
981 }

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)