Oleksandr Tymoshenko <gonzo@bluezbox.com> simple watchpoint support
[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(target_t *target);
36 int mips_m4k_halt(struct target_s *target);
37 int mips_m4k_soft_reset_halt(struct target_s *target);
38 int mips_m4k_resume(struct target_s *target, int current, uint32_t address, int handle_breakpoints, int debug_execution);
39 int mips_m4k_step(struct target_s *target, int current, uint32_t address, int handle_breakpoints);
40 int mips_m4k_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
41 int mips_m4k_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
42 int mips_m4k_register_commands(struct command_context_s *cmd_ctx);
43 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
44 int mips_m4k_quit(void);
45 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp);
46
47 int mips_m4k_examine(struct target_s *target);
48 int mips_m4k_assert_reset(target_t *target);
49 int mips_m4k_deassert_reset(target_t *target);
50 int mips_m4k_checksum_memory(target_t *target, uint32_t address, uint32_t size, uint32_t *checksum);
51
52 target_type_t 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 .register_commands = mips_m4k_register_commands,
85 .target_create = mips_m4k_target_create,
86 .init_target = mips_m4k_init_target,
87 .examine = mips_m4k_examine,
88 .quit = mips_m4k_quit
89 };
90
91 int mips_m4k_examine_debug_reason(target_t *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(target_t *target)
126 {
127 mips32_common_t *mips32 = target->arch_info;
128 mips_ejtag_t *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 Jim_Nvp_value2name_simple(nvp_target_state, target->state)->name);
152
153 return ERROR_OK;
154 }
155
156 int mips_m4k_poll(target_t *target)
157 {
158 int retval;
159 mips32_common_t *mips32 = target->arch_info;
160 mips_ejtag_t *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_s *target)
218 {
219 mips32_common_t *mips32 = target->arch_info;
220 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
221
222 LOG_DEBUG("target->state: %s",
223 Jim_Nvp_value2name_simple(nvp_target_state, target->state)->name);
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(target_t *target)
263 {
264 mips32_common_t *mips32 = target->arch_info;
265 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
266
267 LOG_DEBUG("target->state: %s",
268 Jim_Nvp_value2name_simple(nvp_target_state, target->state)->name);
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 mips32_invalidate_core_regs(target);
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(target_t *target)
325 {
326 LOG_DEBUG("target->state: %s",
327 Jim_Nvp_value2name_simple(nvp_target_state, target->state)->name);
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_s *target)
336 {
337 /* TODO */
338 return ERROR_OK;
339 }
340
341 int mips_m4k_single_step_core(target_t *target)
342 {
343 mips32_common_t *mips32 = target->arch_info;
344 mips_ejtag_t *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_s *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
361 {
362 mips32_common_t *mips32 = target->arch_info;
363 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
364 breakpoint_t *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 mips32_invalidate_core_regs(target);
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_s *target, int current, uint32_t address, int handle_breakpoints)
432 {
433 /* get pointers to arch-specific information */
434 mips32_common_t *mips32 = target->arch_info;
435 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
436 breakpoint_t *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 mips32_invalidate_core_regs(target);
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_s *target)
484 {
485 breakpoint_t *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_s *target, breakpoint_t *breakpoint)
497 {
498 mips32_common_t *mips32 = target->arch_info;
499 mips32_comparator_t * 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_DEBUG("ERROR Can not find free FP Comparator");
517 LOG_WARNING("ERROR Can not find free FP Comparator");
518 exit(-1);
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("bp_num %i bp_value 0x%" PRIx32 "", bp_num, comparator_list[bp_num].bp_value);
527 }
528 else if (breakpoint->type == BKPT_SOFT)
529 {
530 if (breakpoint->length == 4)
531 {
532 uint32_t verify = 0xffffffff;
533
534 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
535 {
536 return retval;
537 }
538 if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK)
539 {
540 return retval;
541 }
542
543 if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK)
544 {
545 return retval;
546 }
547 if (verify != MIPS32_SDBBP)
548 {
549 LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
550 return ERROR_OK;
551 }
552 }
553 else
554 {
555 uint16_t verify = 0xffff;
556
557 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
558 {
559 return retval;
560 }
561 if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK)
562 {
563 return retval;
564 }
565
566 if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK)
567 {
568 return retval;
569 }
570 if (verify != MIPS16_SDBBP)
571 {
572 LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
573 return ERROR_OK;
574 }
575 }
576
577 breakpoint->set = 20; /* Any nice value but 0 */
578 }
579
580 return ERROR_OK;
581 }
582
583 int mips_m4k_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
584 {
585 /* get pointers to arch-specific information */
586 mips32_common_t *mips32 = target->arch_info;
587 mips32_comparator_t * comparator_list = mips32->inst_break_list;
588 int retval;
589
590 if (!breakpoint->set)
591 {
592 LOG_WARNING("breakpoint not set");
593 return ERROR_OK;
594 }
595
596 if (breakpoint->type == BKPT_HARD)
597 {
598 int bp_num = breakpoint->set - 1;
599 if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints))
600 {
601 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
602 return ERROR_OK;
603 }
604 comparator_list[bp_num].used = 0;
605 comparator_list[bp_num].bp_value = 0;
606 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
607 }
608 else
609 {
610 /* restore original instruction (kept in target endianness) */
611 if (breakpoint->length == 4)
612 {
613 uint32_t current_instr;
614
615 /* check that user program has not modified breakpoint instruction */
616 if ((retval = target_read_memory(target, breakpoint->address, 4, 1, (uint8_t*)&current_instr)) != ERROR_OK)
617 {
618 return retval;
619 }
620 if (current_instr == MIPS32_SDBBP)
621 {
622 if ((retval = target_write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
623 {
624 return retval;
625 }
626 }
627 }
628 else
629 {
630 uint16_t current_instr;
631
632 /* check that user program has not modified breakpoint instruction */
633 if ((retval = target_read_memory(target, breakpoint->address, 2, 1, (uint8_t*)&current_instr)) != ERROR_OK)
634 {
635 return retval;
636 }
637
638 if (current_instr == MIPS16_SDBBP)
639 {
640 if ((retval = target_write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
641 {
642 return retval;
643 }
644 }
645 }
646 }
647 breakpoint->set = 0;
648
649 return ERROR_OK;
650 }
651
652 int mips_m4k_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
653 {
654 mips32_common_t *mips32 = target->arch_info;
655
656 if (breakpoint->type == BKPT_HARD)
657 {
658 if (mips32->num_inst_bpoints_avail < 1)
659 {
660 LOG_INFO("no hardware breakpoint available");
661 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
662 }
663
664 mips32->num_inst_bpoints_avail--;
665 }
666
667 mips_m4k_set_breakpoint(target, breakpoint);
668
669 return ERROR_OK;
670 }
671
672 int mips_m4k_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
673 {
674 /* get pointers to arch-specific information */
675 mips32_common_t *mips32 = target->arch_info;
676
677 if (target->state != TARGET_HALTED)
678 {
679 LOG_WARNING("target not halted");
680 return ERROR_TARGET_NOT_HALTED;
681 }
682
683 if (breakpoint->set)
684 {
685 mips_m4k_unset_breakpoint(target, breakpoint);
686 }
687
688 if (breakpoint->type == BKPT_HARD)
689 mips32->num_inst_bpoints_avail++;
690
691 return ERROR_OK;
692 }
693
694 int mips_m4k_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
695 {
696 mips32_common_t *mips32 = target->arch_info;
697 mips32_comparator_t * comparator_list = mips32->data_break_list;
698 int wp_num = 0;
699 /*
700 * watchpoint enabled, ignore all byte lanes in value register
701 * and exclude both load and store accesses from watchpoint
702 * condition evaluation
703 */
704 int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
705 (0xff << EJTAG_DBCn_BLM_SHIFT);
706
707 if (watchpoint->set)
708 {
709 LOG_WARNING("watchpoint already set");
710 return ERROR_OK;
711 }
712
713 while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
714 wp_num++;
715 if (wp_num >= mips32->num_data_bpoints)
716 {
717 LOG_DEBUG("ERROR Can not find free FP Comparator");
718 LOG_WARNING("ERROR Can not find free FP Comparator");
719 exit(-1);
720 }
721
722 if (watchpoint->length != 4)
723 {
724 LOG_ERROR("Only watchpoints of length 4 are supported");
725 return ERROR_TARGET_UNALIGNED_ACCESS;
726 }
727
728 if (watchpoint->address % 4)
729 {
730 LOG_ERROR("Watchpoints address should be word aligned");
731 return ERROR_TARGET_UNALIGNED_ACCESS;
732 }
733
734 switch (watchpoint->rw)
735 {
736 case WPT_READ:
737 enable &= ~EJTAG_DBCn_NOLB;
738 break;
739 case WPT_WRITE:
740 enable &= ~EJTAG_DBCn_NOSB;
741 break;
742 case WPT_ACCESS:
743 enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB);
744 break;
745 default:
746 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
747 }
748
749 watchpoint->set = wp_num + 1;
750 comparator_list[wp_num].used = 1;
751 comparator_list[wp_num].bp_value = watchpoint->address;
752 target_write_u32(target, comparator_list[wp_num].reg_address, comparator_list[wp_num].bp_value);
753 target_write_u32(target, comparator_list[wp_num].reg_address + 0x08, 0x00000000);
754 target_write_u32(target, comparator_list[wp_num].reg_address + 0x10, 0x00000000);
755 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, enable);
756 target_write_u32(target, comparator_list[wp_num].reg_address + 0x20, 0);
757 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value);
758
759 return ERROR_OK;
760 }
761
762 int mips_m4k_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
763 {
764 /* get pointers to arch-specific information */
765 mips32_common_t *mips32 = target->arch_info;
766 mips32_comparator_t * comparator_list = mips32->data_break_list;
767
768 if (!watchpoint->set)
769 {
770 LOG_WARNING("watchpoint not set");
771 return ERROR_OK;
772 }
773
774 int wp_num = watchpoint->set - 1;
775 if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints))
776 {
777 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
778 return ERROR_OK;
779 }
780 comparator_list[wp_num].used = 0;
781 comparator_list[wp_num].bp_value = 0;
782 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, 0);
783 watchpoint->set = 0;
784
785 return ERROR_OK;
786 }
787
788 int mips_m4k_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
789 {
790 mips32_common_t *mips32 = target->arch_info;
791
792 if (mips32->num_data_bpoints_avail < 1)
793 {
794 LOG_INFO("no hardware watchpoints available");
795 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
796 }
797
798 mips32->num_data_bpoints_avail--;
799
800 mips_m4k_set_watchpoint(target, watchpoint);
801 return ERROR_OK;
802 }
803
804 int mips_m4k_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
805 {
806 /* get pointers to arch-specific information */
807 mips32_common_t *mips32 = target->arch_info;
808
809 if (target->state != TARGET_HALTED)
810 {
811 LOG_WARNING("target not halted");
812 return ERROR_TARGET_NOT_HALTED;
813 }
814
815 if (watchpoint->set)
816 {
817 mips_m4k_unset_watchpoint(target, watchpoint);
818 }
819
820 mips32->num_data_bpoints_avail++;
821
822 return ERROR_OK;
823 }
824
825 void mips_m4k_enable_watchpoints(struct target_s *target)
826 {
827 watchpoint_t *watchpoint = target->watchpoints;
828
829 /* set any pending watchpoints */
830 while (watchpoint)
831 {
832 if (watchpoint->set == 0)
833 mips_m4k_set_watchpoint(target, watchpoint);
834 watchpoint = watchpoint->next;
835 }
836 }
837
838 int mips_m4k_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
839 {
840 mips32_common_t *mips32 = target->arch_info;
841 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
842
843 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
844
845 if (target->state != TARGET_HALTED)
846 {
847 LOG_WARNING("target not halted");
848 return ERROR_TARGET_NOT_HALTED;
849 }
850
851 /* sanitize arguments */
852 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
853 return ERROR_INVALID_ARGUMENTS;
854
855 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
856 return ERROR_TARGET_UNALIGNED_ACCESS;
857
858 /* if noDMA off, use DMAACC mode for memory read */
859 int retval;
860 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
861 retval = mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
862 else
863 retval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
864 if (ERROR_OK != retval)
865 return retval;
866
867 /* TAP data register is loaded LSB first (little endian) */
868 if (target->endianness == TARGET_BIG_ENDIAN)
869 {
870 uint32_t i, t32;
871 uint16_t t16;
872
873 for (i = 0; i < (count*size); i += size)
874 {
875 switch (size)
876 {
877 case 4:
878 t32 = le_to_h_u32(&buffer[i]);
879 h_u32_to_be(&buffer[i], t32);
880 break;
881 case 2:
882 t16 = le_to_h_u16(&buffer[i]);
883 h_u16_to_be(&buffer[i], t16);
884 break;
885 }
886 }
887 }
888
889 return ERROR_OK;
890 }
891
892 int mips_m4k_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
893 {
894 mips32_common_t *mips32 = target->arch_info;
895 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
896
897 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
898
899 if (target->state != TARGET_HALTED)
900 {
901 LOG_WARNING("target not halted");
902 return ERROR_TARGET_NOT_HALTED;
903 }
904
905 /* sanitize arguments */
906 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
907 return ERROR_INVALID_ARGUMENTS;
908
909 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
910 return ERROR_TARGET_UNALIGNED_ACCESS;
911
912 /* TAP data register is loaded LSB first (little endian) */
913 if (target->endianness == TARGET_BIG_ENDIAN)
914 {
915 uint32_t i, t32;
916 uint16_t t16;
917
918 for (i = 0; i < (count*size); i += size)
919 {
920 switch (size)
921 {
922 case 4:
923 t32 = be_to_h_u32(&buffer[i]);
924 h_u32_to_le(&buffer[i], t32);
925 break;
926 case 2:
927 t16 = be_to_h_u16(&buffer[i]);
928 h_u16_to_le(&buffer[i], t16);
929 break;
930 }
931 }
932 }
933
934 /* if noDMA off, use DMAACC mode for memory write */
935 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
936 return mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
937 else
938 return mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
939 }
940
941 int mips_m4k_register_commands(struct command_context_s *cmd_ctx)
942 {
943 int retval;
944
945 retval = mips32_register_commands(cmd_ctx);
946 return retval;
947 }
948
949 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
950 {
951 mips32_build_reg_cache(target);
952
953 return ERROR_OK;
954 }
955
956 int mips_m4k_quit(void)
957 {
958 return ERROR_OK;
959 }
960
961 int mips_m4k_init_arch_info(target_t *target, mips_m4k_common_t *mips_m4k, jtag_tap_t *tap)
962 {
963 mips32_common_t *mips32 = &mips_m4k->mips32_common;
964
965 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
966
967 /* initialize mips4k specific info */
968 mips32_init_arch_info(target, mips32, tap);
969 mips32->arch_info = mips_m4k;
970
971 return ERROR_OK;
972 }
973
974 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp)
975 {
976 mips_m4k_common_t *mips_m4k = calloc(1,sizeof(mips_m4k_common_t));
977
978 mips_m4k_init_arch_info(target, mips_m4k, target->tap);
979
980 return ERROR_OK;
981 }
982
983 int mips_m4k_examine(struct target_s *target)
984 {
985 int retval;
986 mips32_common_t *mips32 = target->arch_info;
987 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
988 uint32_t idcode = 0;
989
990 if (!target_was_examined(target))
991 {
992 mips_ejtag_get_idcode(ejtag_info, &idcode);
993 ejtag_info->idcode = idcode;
994
995 if (((idcode >> 1) & 0x7FF) == 0x29)
996 {
997 /* we are using a pic32mx so select ejtag port
998 * as it is not selected by default */
999 mips_ejtag_set_instr(ejtag_info, 0x05, NULL);
1000 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
1001 }
1002 }
1003
1004 /* init rest of ejtag interface */
1005 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
1006 return retval;
1007
1008 if ((retval = mips32_examine(target)) != ERROR_OK)
1009 return retval;
1010
1011 return ERROR_OK;
1012 }
1013
1014 int mips_m4k_bulk_write_memory(target_t *target, uint32_t address, uint32_t count, uint8_t *buffer)
1015 {
1016 return mips_m4k_write_memory(target, address, 4, count, buffer);
1017 }
1018
1019 int mips_m4k_checksum_memory(target_t *target, uint32_t address, uint32_t size, uint32_t *checksum)
1020 {
1021 return ERROR_FAIL; /* use bulk read method */
1022 }

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)