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

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)