0a566c3444175ee8df3f534f48270ecfd7033c8e
[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_register_commands(struct command_context *cmd_ctx);
45 int mips_m4k_init_target(struct command_context *cmd_ctx, struct target *target);
46 int mips_m4k_target_create(struct target *target, Jim_Interp *interp);
47
48 int mips_m4k_examine(struct target *target);
49 int mips_m4k_assert_reset(struct target *target);
50 int mips_m4k_deassert_reset(struct target *target);
51 int mips_m4k_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t *checksum);
52
53 struct target_type mips_m4k_target =
54 {
55 .name = "mips_m4k",
56
57 .poll = mips_m4k_poll,
58 .arch_state = mips32_arch_state,
59
60 .target_request_data = NULL,
61
62 .halt = mips_m4k_halt,
63 .resume = mips_m4k_resume,
64 .step = mips_m4k_step,
65
66 .assert_reset = mips_m4k_assert_reset,
67 .deassert_reset = mips_m4k_deassert_reset,
68 .soft_reset_halt = mips_m4k_soft_reset_halt,
69
70 .get_gdb_reg_list = mips32_get_gdb_reg_list,
71
72 .read_memory = mips_m4k_read_memory,
73 .write_memory = mips_m4k_write_memory,
74 .bulk_write_memory = mips_m4k_bulk_write_memory,
75 .checksum_memory = mips_m4k_checksum_memory,
76 .blank_check_memory = NULL,
77
78 .run_algorithm = mips32_run_algorithm,
79
80 .add_breakpoint = mips_m4k_add_breakpoint,
81 .remove_breakpoint = mips_m4k_remove_breakpoint,
82 .add_watchpoint = mips_m4k_add_watchpoint,
83 .remove_watchpoint = mips_m4k_remove_watchpoint,
84
85 .register_commands = mips_m4k_register_commands,
86 .target_create = mips_m4k_target_create,
87 .init_target = mips_m4k_init_target,
88 .examine = mips_m4k_examine,
89 };
90
91 int mips_m4k_examine_debug_reason(struct target *target)
92 {
93 uint32_t break_status;
94 int retval;
95
96 if ((target->debug_reason != DBG_REASON_DBGRQ)
97 && (target->debug_reason != DBG_REASON_SINGLESTEP))
98 {
99 /* get info about inst breakpoint support */
100 if ((retval = target_read_u32(target, EJTAG_IBS, &break_status)) != ERROR_OK)
101 return retval;
102 if (break_status & 0x1f)
103 {
104 /* we have halted on a breakpoint */
105 if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK)
106 return retval;
107 target->debug_reason = DBG_REASON_BREAKPOINT;
108 }
109
110 /* get info about data breakpoint support */
111 if ((retval = target_read_u32(target, 0xFF302000, &break_status)) != ERROR_OK)
112 return retval;
113 if (break_status & 0x1f)
114 {
115 /* we have halted on a breakpoint */
116 if ((retval = target_write_u32(target, 0xFF302000, 0)) != ERROR_OK)
117 return retval;
118 target->debug_reason = DBG_REASON_WATCHPOINT;
119 }
120 }
121
122 return ERROR_OK;
123 }
124
125 int mips_m4k_debug_entry(struct target *target)
126 {
127 struct mips32_common *mips32 = target->arch_info;
128 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
129 uint32_t debug_reg;
130
131 /* read debug register */
132 mips_ejtag_read_debug(ejtag_info, &debug_reg);
133
134 /* make sure break uit configured */
135 mips32_configure_break_unit(target);
136
137 /* attempt to find halt reason */
138 mips_m4k_examine_debug_reason(target);
139
140 /* clear single step if active */
141 if (debug_reg & EJTAG_DEBUG_DSS)
142 {
143 /* stopped due to single step - clear step bit */
144 mips_ejtag_config_step(ejtag_info, 0);
145 }
146
147 mips32_save_context(target);
148
149 LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
150 *(uint32_t*)(mips32->core_cache->reg_list[MIPS32_PC].value),
151 target_state_name(target));
152
153 return ERROR_OK;
154 }
155
156 int mips_m4k_poll(struct target *target)
157 {
158 int retval;
159 struct mips32_common *mips32 = target->arch_info;
160 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
161 uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl;
162
163 /* read ejtag control reg */
164 jtag_set_end_state(TAP_IDLE);
165 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
166 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
167
168 /* clear this bit before handling polling
169 * as after reset registers will read zero */
170 if (ejtag_ctrl & EJTAG_CTRL_ROCC)
171 {
172 /* we have detected a reset, clear flag
173 * otherwise ejtag will not work */
174 jtag_set_end_state(TAP_IDLE);
175 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
176
177 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
178 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
179 LOG_DEBUG("Reset Detected");
180 }
181
182 /* check for processor halted */
183 if (ejtag_ctrl & EJTAG_CTRL_BRKST)
184 {
185 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
186 {
187 jtag_set_end_state(TAP_IDLE);
188 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
189
190 target->state = TARGET_HALTED;
191
192 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
193 return retval;
194
195 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
196 }
197 else if (target->state == TARGET_DEBUG_RUNNING)
198 {
199 target->state = TARGET_HALTED;
200
201 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
202 return retval;
203
204 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
205 }
206 }
207 else
208 {
209 target->state = TARGET_RUNNING;
210 }
211
212 // LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl);
213
214 return ERROR_OK;
215 }
216
217 int mips_m4k_halt(struct target *target)
218 {
219 struct mips32_common *mips32 = target->arch_info;
220 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
221
222 LOG_DEBUG("target->state: %s",
223 target_state_name(target));
224
225 if (target->state == TARGET_HALTED)
226 {
227 LOG_DEBUG("target was already halted");
228 return ERROR_OK;
229 }
230
231 if (target->state == TARGET_UNKNOWN)
232 {
233 LOG_WARNING("target was in unknown state when halt was requested");
234 }
235
236 if (target->state == TARGET_RESET)
237 {
238 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
239 {
240 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
241 return ERROR_TARGET_FAILURE;
242 }
243 else
244 {
245 /* we came here in a reset_halt or reset_init sequence
246 * debug entry was already prepared in mips32_prepare_reset_halt()
247 */
248 target->debug_reason = DBG_REASON_DBGRQ;
249
250 return ERROR_OK;
251 }
252 }
253
254 /* break processor */
255 mips_ejtag_enter_debug(ejtag_info);
256
257 target->debug_reason = DBG_REASON_DBGRQ;
258
259 return ERROR_OK;
260 }
261
262 int mips_m4k_assert_reset(struct target *target)
263 {
264 struct mips32_common *mips32 = target->arch_info;
265 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
266
267 LOG_DEBUG("target->state: %s",
268 target_state_name(target));
269
270 enum reset_types jtag_reset_config = jtag_get_reset_config();
271 if (!(jtag_reset_config & RESET_HAS_SRST))
272 {
273 LOG_ERROR("Can't assert SRST");
274 return ERROR_FAIL;
275 }
276
277 if (target->reset_halt)
278 {
279 /* use hardware to catch reset */
280 jtag_set_end_state(TAP_IDLE);
281 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT, NULL);
282 }
283 else
284 {
285 jtag_set_end_state(TAP_IDLE);
286 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
287 }
288
289 if (strcmp(target->variant, "ejtag_srst") == 0)
290 {
291 uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
292 LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
293 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
294 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
295 }
296 else
297 {
298 /* here we should issue a srst only, but we may have to assert trst as well */
299 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
300 {
301 jtag_add_reset(1, 1);
302 }
303 else
304 {
305 jtag_add_reset(0, 1);
306 }
307 }
308
309 target->state = TARGET_RESET;
310 jtag_add_sleep(50000);
311
312 register_cache_invalidate(mips32->core_cache);
313
314 if (target->reset_halt)
315 {
316 int retval;
317 if ((retval = target_halt(target)) != ERROR_OK)
318 return retval;
319 }
320
321 return ERROR_OK;
322 }
323
324 int mips_m4k_deassert_reset(struct target *target)
325 {
326 LOG_DEBUG("target->state: %s",
327 target_state_name(target));
328
329 /* deassert reset lines */
330 jtag_add_reset(0, 0);
331
332 return ERROR_OK;
333 }
334
335 int mips_m4k_soft_reset_halt(struct target *target)
336 {
337 /* TODO */
338 return ERROR_OK;
339 }
340
341 int mips_m4k_single_step_core(struct target *target)
342 {
343 struct mips32_common *mips32 = target->arch_info;
344 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
345
346 /* configure single step mode */
347 mips_ejtag_config_step(ejtag_info, 1);
348
349 /* disable interrupts while stepping */
350 mips32_enable_interrupts(target, 0);
351
352 /* exit debug mode */
353 mips_ejtag_exit_debug(ejtag_info);
354
355 mips_m4k_debug_entry(target);
356
357 return ERROR_OK;
358 }
359
360 int mips_m4k_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
361 {
362 struct mips32_common *mips32 = target->arch_info;
363 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
364 struct breakpoint *breakpoint = NULL;
365 uint32_t resume_pc;
366
367 if (target->state != TARGET_HALTED)
368 {
369 LOG_WARNING("target not halted");
370 return ERROR_TARGET_NOT_HALTED;
371 }
372
373 if (!debug_execution)
374 {
375 target_free_all_working_areas(target);
376 mips_m4k_enable_breakpoints(target);
377 mips_m4k_enable_watchpoints(target);
378 }
379
380 /* current = 1: continue on current pc, otherwise continue at <address> */
381 if (!current)
382 {
383 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
384 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
385 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
386 }
387
388 resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
389
390 mips32_restore_context(target);
391
392 /* the front-end may request us not to handle breakpoints */
393 if (handle_breakpoints)
394 {
395 /* Single step past breakpoint at current address */
396 if ((breakpoint = breakpoint_find(target, resume_pc)))
397 {
398 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
399 mips_m4k_unset_breakpoint(target, breakpoint);
400 mips_m4k_single_step_core(target);
401 mips_m4k_set_breakpoint(target, breakpoint);
402 }
403 }
404
405 /* enable interrupts if we are running */
406 mips32_enable_interrupts(target, !debug_execution);
407
408 /* exit debug mode */
409 mips_ejtag_exit_debug(ejtag_info);
410 target->debug_reason = DBG_REASON_NOTHALTED;
411
412 /* registers are now invalid */
413 register_cache_invalidate(mips32->core_cache);
414
415 if (!debug_execution)
416 {
417 target->state = TARGET_RUNNING;
418 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
419 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
420 }
421 else
422 {
423 target->state = TARGET_DEBUG_RUNNING;
424 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
425 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
426 }
427
428 return ERROR_OK;
429 }
430
431 int mips_m4k_step(struct target *target, int current, uint32_t address, int handle_breakpoints)
432 {
433 /* get pointers to arch-specific information */
434 struct mips32_common *mips32 = target->arch_info;
435 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
436 struct breakpoint *breakpoint = NULL;
437
438 if (target->state != TARGET_HALTED)
439 {
440 LOG_WARNING("target not halted");
441 return ERROR_TARGET_NOT_HALTED;
442 }
443
444 /* current = 1: continue on current pc, otherwise continue at <address> */
445 if (!current)
446 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
447
448 /* the front-end may request us not to handle breakpoints */
449 if (handle_breakpoints)
450 if ((breakpoint = breakpoint_find(target, buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32))))
451 mips_m4k_unset_breakpoint(target, breakpoint);
452
453 /* restore context */
454 mips32_restore_context(target);
455
456 /* configure single step mode */
457 mips_ejtag_config_step(ejtag_info, 1);
458
459 target->debug_reason = DBG_REASON_SINGLESTEP;
460
461 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
462
463 /* disable interrupts while stepping */
464 mips32_enable_interrupts(target, 0);
465
466 /* exit debug mode */
467 mips_ejtag_exit_debug(ejtag_info);
468
469 /* registers are now invalid */
470 register_cache_invalidate(mips32->core_cache);
471
472 if (breakpoint)
473 mips_m4k_set_breakpoint(target, breakpoint);
474
475 LOG_DEBUG("target stepped ");
476
477 mips_m4k_debug_entry(target);
478 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
479
480 return ERROR_OK;
481 }
482
483 void mips_m4k_enable_breakpoints(struct target *target)
484 {
485 struct breakpoint *breakpoint = target->breakpoints;
486
487 /* set any pending breakpoints */
488 while (breakpoint)
489 {
490 if (breakpoint->set == 0)
491 mips_m4k_set_breakpoint(target, breakpoint);
492 breakpoint = breakpoint->next;
493 }
494 }
495
496 int mips_m4k_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
497 {
498 struct mips32_common *mips32 = target->arch_info;
499 struct mips32_comparator * comparator_list = mips32->inst_break_list;
500 int retval;
501
502 if (breakpoint->set)
503 {
504 LOG_WARNING("breakpoint already set");
505 return ERROR_OK;
506 }
507
508 if (breakpoint->type == BKPT_HARD)
509 {
510 int bp_num = 0;
511
512 while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))
513 bp_num++;
514 if (bp_num >= mips32->num_inst_bpoints)
515 {
516 LOG_ERROR("Can not find free FP Comparator(bpid: %d)",
517 breakpoint->unique_id );
518 return ERROR_FAIL;
519 }
520 breakpoint->set = bp_num + 1;
521 comparator_list[bp_num].used = 1;
522 comparator_list[bp_num].bp_value = breakpoint->address;
523 target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value);
524 target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000);
525 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1);
526 LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "",
527 breakpoint->unique_id,
528 bp_num, comparator_list[bp_num].bp_value);
529 }
530 else if (breakpoint->type == BKPT_SOFT)
531 {
532 LOG_DEBUG("bpid: %d", breakpoint->unique_id );
533 if (breakpoint->length == 4)
534 {
535 uint32_t verify = 0xffffffff;
536
537 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
538 {
539 return retval;
540 }
541 if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK)
542 {
543 return retval;
544 }
545
546 if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK)
547 {
548 return retval;
549 }
550 if (verify != MIPS32_SDBBP)
551 {
552 LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
553 return ERROR_OK;
554 }
555 }
556 else
557 {
558 uint16_t verify = 0xffff;
559
560 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
561 {
562 return retval;
563 }
564 if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK)
565 {
566 return retval;
567 }
568
569 if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK)
570 {
571 return retval;
572 }
573 if (verify != MIPS16_SDBBP)
574 {
575 LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
576 return ERROR_OK;
577 }
578 }
579
580 breakpoint->set = 20; /* Any nice value but 0 */
581 }
582
583 return ERROR_OK;
584 }
585
586 int mips_m4k_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
587 {
588 /* get pointers to arch-specific information */
589 struct mips32_common *mips32 = target->arch_info;
590 struct mips32_comparator * comparator_list = mips32->inst_break_list;
591 int retval;
592
593 if (!breakpoint->set)
594 {
595 LOG_WARNING("breakpoint not set");
596 return ERROR_OK;
597 }
598
599 if (breakpoint->type == BKPT_HARD)
600 {
601 int bp_num = breakpoint->set - 1;
602 if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints))
603 {
604 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
605 breakpoint->unique_id);
606 return ERROR_OK;
607 }
608 LOG_DEBUG("bpid: %d - releasing hw: %d",
609 breakpoint->unique_id,
610 bp_num );
611 comparator_list[bp_num].used = 0;
612 comparator_list[bp_num].bp_value = 0;
613 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
614
615 }
616 else
617 {
618 /* restore original instruction (kept in target endianness) */
619 LOG_DEBUG("bpid: %d", breakpoint->unique_id);
620 if (breakpoint->length == 4)
621 {
622 uint32_t current_instr;
623
624 /* check that user program has not modified breakpoint instruction */
625 if ((retval = target_read_memory(target, breakpoint->address, 4, 1, (uint8_t*)&current_instr)) != ERROR_OK)
626 {
627 return retval;
628 }
629 if (current_instr == MIPS32_SDBBP)
630 {
631 if ((retval = target_write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
632 {
633 return retval;
634 }
635 }
636 }
637 else
638 {
639 uint16_t current_instr;
640
641 /* check that user program has not modified breakpoint instruction */
642 if ((retval = target_read_memory(target, breakpoint->address, 2, 1, (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, breakpoint->orig_instr)) != ERROR_OK)
650 {
651 return retval;
652 }
653 }
654 }
655 }
656 breakpoint->set = 0;
657
658 return ERROR_OK;
659 }
660
661 int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
662 {
663 struct mips32_common *mips32 = target->arch_info;
664
665 if (breakpoint->type == BKPT_HARD)
666 {
667 if (mips32->num_inst_bpoints_avail < 1)
668 {
669 LOG_INFO("no hardware breakpoint available");
670 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
671 }
672
673 mips32->num_inst_bpoints_avail--;
674 }
675
676 mips_m4k_set_breakpoint(target, breakpoint);
677
678 return ERROR_OK;
679 }
680
681 int mips_m4k_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
682 {
683 /* get pointers to arch-specific information */
684 struct mips32_common *mips32 = target->arch_info;
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 int mips_m4k_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
704 {
705 struct mips32_common *mips32 = target->arch_info;
706 struct mips32_comparator * comparator_list = mips32->data_break_list;
707 int wp_num = 0;
708 /*
709 * watchpoint enabled, ignore all byte lanes in value register
710 * and exclude both load and store accesses from watchpoint
711 * condition evaluation
712 */
713 int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
714 (0xff << EJTAG_DBCn_BLM_SHIFT);
715
716 if (watchpoint->set)
717 {
718 LOG_WARNING("watchpoint already set");
719 return ERROR_OK;
720 }
721
722 while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
723 wp_num++;
724 if (wp_num >= mips32->num_data_bpoints)
725 {
726 LOG_ERROR("Can not find free FP Comparator");
727 return ERROR_FAIL;
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)