John McCarthy <jgmcc@magma.ca> cleans up the usage of the
[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 "jtag.h"
30 #include "log.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34
35 /* cli handling */
36
37 /* forward declarations */
38 int mips_m4k_poll(target_t *target);
39 int mips_m4k_halt(struct target_s *target);
40 int mips_m4k_soft_reset_halt(struct target_s *target);
41 int mips_m4k_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution);
42 int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_breakpoints);
43 int mips_m4k_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
44 int mips_m4k_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
45 int mips_m4k_register_commands(struct command_context_s *cmd_ctx);
46 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
47 int mips_m4k_quit(void);
48 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp);
49
50 int mips_m4k_examine(struct target_s *target);
51 int mips_m4k_assert_reset(target_t *target);
52 int mips_m4k_deassert_reset(target_t *target);
53
54 target_type_t mips_m4k_target =
55 {
56 .name = "mips_m4k",
57
58 .poll = mips_m4k_poll,
59 .arch_state = mips32_arch_state,
60
61 .target_request_data = NULL,
62
63 .halt = mips_m4k_halt,
64 .resume = mips_m4k_resume,
65 .step = mips_m4k_step,
66
67 .assert_reset = mips_m4k_assert_reset,
68 .deassert_reset = mips_m4k_deassert_reset,
69 .soft_reset_halt = mips_m4k_soft_reset_halt,
70
71 .get_gdb_reg_list = mips32_get_gdb_reg_list,
72
73 .read_memory = mips_m4k_read_memory,
74 .write_memory = mips_m4k_write_memory,
75 .bulk_write_memory = mips_m4k_bulk_write_memory,
76 .checksum_memory = NULL,
77 .blank_check_memory = NULL,
78
79 .run_algorithm = mips32_run_algorithm,
80
81 .add_breakpoint = mips_m4k_add_breakpoint,
82 .remove_breakpoint = mips_m4k_remove_breakpoint,
83 .add_watchpoint = mips_m4k_add_watchpoint,
84 .remove_watchpoint = mips_m4k_remove_watchpoint,
85
86 .register_commands = mips_m4k_register_commands,
87 .target_create = mips_m4k_target_create,
88 .init_target = mips_m4k_init_target,
89 .examine = mips_m4k_examine,
90 .quit = mips_m4k_quit
91 };
92
93 int mips_m4k_debug_entry(target_t *target)
94 {
95 u32 debug_reg;
96 mips32_common_t *mips32 = target->arch_info;
97 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
98
99 /* read debug register */
100 mips_ejtag_read_debug(ejtag_info, &debug_reg);
101
102 if ((target->debug_reason != DBG_REASON_DBGRQ)
103 && (target->debug_reason != DBG_REASON_SINGLESTEP))
104 {
105 // if (cortex_m3->nvic_dfsr & DFSR_BKPT)
106 // {
107 // target->debug_reason = DBG_REASON_BREAKPOINT;
108 // if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
109 // target->debug_reason = DBG_REASON_WPTANDBKPT;
110 // }
111 // else if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
112 // target->debug_reason = DBG_REASON_WATCHPOINT;
113 }
114
115 if (debug_reg & EJTAG_DEBUG_DSS)
116 {
117 /* stopped due to single step - clear step bit */
118 mips_ejtag_config_step(ejtag_info, 0);
119 }
120
121 mips32_save_context(target);
122
123 LOG_DEBUG("entered debug state at PC 0x%x, target->state: %s",
124 *(u32*)(mips32->core_cache->reg_list[MIPS32_PC].value),
125 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
126
127 return ERROR_OK;
128 }
129
130 int mips_m4k_poll(target_t *target)
131 {
132 int retval;
133 mips32_common_t *mips32 = target->arch_info;
134 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
135 u32 ejtag_ctrl = ejtag_info->ejtag_ctrl;
136
137 /* read ejtag control reg */
138 jtag_add_end_state(TAP_RTI);
139 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
140 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
141
142 if (ejtag_ctrl & EJTAG_CTRL_BRKST)
143 {
144 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
145 {
146 jtag_add_end_state(TAP_RTI);
147 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
148
149 target->state = TARGET_HALTED;
150
151 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
152 return retval;
153
154 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
155 }
156 else if (target->state == TARGET_DEBUG_RUNNING)
157 {
158 target->state = TARGET_HALTED;
159
160 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
161 return retval;
162
163 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
164 }
165 }
166 else
167 {
168 target->state = TARGET_RUNNING;
169 }
170
171 if (ejtag_ctrl & EJTAG_CTRL_ROCC)
172 {
173 /* we have detected a reset, clear flag
174 * otherwise ejtag will not work */
175 jtag_add_end_state(TAP_RTI);
176 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
177
178 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
179 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
180 LOG_DEBUG("Reset Detected");
181 }
182
183 // LOG_DEBUG("ctrl=0x%08X", ejtag_ctrl);
184
185 return ERROR_OK;
186 }
187
188 int mips_m4k_halt(struct target_s *target)
189 {
190 mips32_common_t *mips32 = target->arch_info;
191 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
192
193 LOG_DEBUG("target->state: %s",
194 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
195
196 if (target->state == TARGET_HALTED)
197 {
198 LOG_DEBUG("target was already halted");
199 return ERROR_OK;
200 }
201
202 if (target->state == TARGET_UNKNOWN)
203 {
204 LOG_WARNING("target was in unknown state when halt was requested");
205 }
206
207 if (target->state == TARGET_RESET)
208 {
209 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
210 {
211 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
212 return ERROR_TARGET_FAILURE;
213 }
214 else
215 {
216 /* we came here in a reset_halt or reset_init sequence
217 * debug entry was already prepared in mips32_prepare_reset_halt()
218 */
219 target->debug_reason = DBG_REASON_DBGRQ;
220
221 return ERROR_OK;
222 }
223 }
224
225 /* break processor */
226 mips_ejtag_enter_debug(ejtag_info);
227
228 target->debug_reason = DBG_REASON_DBGRQ;
229
230 return ERROR_OK;
231 }
232
233 int mips_m4k_assert_reset(target_t *target)
234 {
235 mips32_common_t *mips32 = target->arch_info;
236 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
237
238 LOG_DEBUG("target->state: %s",
239 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
240
241 if (!(jtag_reset_config & RESET_HAS_SRST))
242 {
243 LOG_ERROR("Can't assert SRST");
244 return ERROR_FAIL;
245 }
246
247 if (target->reset_halt)
248 {
249 /* use hardware to catch reset */
250 jtag_add_end_state(TAP_RTI);
251 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT, NULL);
252 }
253 else
254 {
255 jtag_add_end_state(TAP_RTI);
256 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
257 }
258
259 /* here we should issue a srst only, but we may have to assert trst as well */
260 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
261 {
262 jtag_add_reset(1, 1);
263 }
264 else
265 {
266 jtag_add_reset(0, 1);
267 }
268
269 target->state = TARGET_RESET;
270 jtag_add_sleep(50000);
271
272 mips32_invalidate_core_regs(target);
273
274 if (target->reset_halt)
275 {
276 int retval;
277 if ((retval = target_halt(target))!=ERROR_OK)
278 return retval;
279 }
280
281
282 return ERROR_OK;
283 }
284
285 int mips_m4k_deassert_reset(target_t *target)
286 {
287 LOG_DEBUG("target->state: %s",
288 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
289
290 /* deassert reset lines */
291 jtag_add_reset(0, 0);
292
293 return ERROR_OK;
294 }
295
296 int mips_m4k_soft_reset_halt(struct target_s *target)
297 {
298 /* TODO */
299 return ERROR_OK;
300 }
301
302 int mips_m4k_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
303 {
304 mips32_common_t *mips32 = target->arch_info;
305 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
306 breakpoint_t *breakpoint = NULL;
307 u32 resume_pc;
308
309 if (target->state != TARGET_HALTED)
310 {
311 LOG_WARNING("target not halted");
312 return ERROR_TARGET_NOT_HALTED;
313 }
314
315 if (!debug_execution)
316 {
317 target_free_all_working_areas(target);
318 mips_m4k_enable_breakpoints(target);
319 mips_m4k_enable_watchpoints(target);
320 }
321
322 /* current = 1: continue on current pc, otherwise continue at <address> */
323 if (!current)
324 {
325 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
326 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
327 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
328 }
329
330 resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
331
332 mips32_restore_context(target);
333
334 /* the front-end may request us not to handle breakpoints */
335 if (handle_breakpoints)
336 {
337 /* Single step past breakpoint at current address */
338 if ((breakpoint = breakpoint_find(target, resume_pc)))
339 {
340 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
341 mips_m4k_unset_breakpoint(target, breakpoint);
342 //mips_m4k_single_step_core(target);
343 mips_m4k_set_breakpoint(target, breakpoint);
344 }
345 }
346
347 /* exit debug mode - enable interrupts if required */
348 mips_ejtag_exit_debug(ejtag_info, !debug_execution);
349
350 /* registers are now invalid */
351 mips32_invalidate_core_regs(target);
352
353 if (!debug_execution)
354 {
355 target->state = TARGET_RUNNING;
356 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
357 LOG_DEBUG("target resumed at 0x%x", resume_pc);
358 }
359 else
360 {
361 target->state = TARGET_DEBUG_RUNNING;
362 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
363 LOG_DEBUG("target debug resumed at 0x%x", resume_pc);
364 }
365
366 return ERROR_OK;
367 }
368
369 int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
370 {
371 /* get pointers to arch-specific information */
372 mips32_common_t *mips32 = target->arch_info;
373 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
374 breakpoint_t *breakpoint = NULL;
375
376 if (target->state != TARGET_HALTED)
377 {
378 LOG_WARNING("target not halted");
379 return ERROR_TARGET_NOT_HALTED;
380 }
381
382 /* current = 1: continue on current pc, otherwise continue at <address> */
383 if (!current)
384 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
385
386 /* the front-end may request us not to handle breakpoints */
387 if (handle_breakpoints)
388 if ((breakpoint = breakpoint_find(target, buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32))))
389 mips_m4k_unset_breakpoint(target, breakpoint);
390
391 /* restore context */
392 mips32_restore_context(target);
393
394 /* configure single step mode */
395 mips_ejtag_config_step(ejtag_info, 1);
396
397 target->debug_reason = DBG_REASON_SINGLESTEP;
398
399 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
400
401 /* exit debug mode */
402 mips_ejtag_exit_debug(ejtag_info, 1);
403
404 /* registers are now invalid */
405 mips32_invalidate_core_regs(target);
406
407 if (breakpoint)
408 mips_m4k_set_breakpoint(target, breakpoint);
409
410 LOG_DEBUG("target stepped ");
411
412 mips_m4k_debug_entry(target);
413 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
414
415 return ERROR_OK;
416 }
417
418 void mips_m4k_enable_breakpoints(struct target_s *target)
419 {
420 breakpoint_t *breakpoint = target->breakpoints;
421
422 /* set any pending breakpoints */
423 while (breakpoint)
424 {
425 if (breakpoint->set == 0)
426 mips_m4k_set_breakpoint(target, breakpoint);
427 breakpoint = breakpoint->next;
428 }
429 }
430
431 int mips_m4k_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
432 {
433 /* TODO */
434 return ERROR_OK;
435 }
436
437 int mips_m4k_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
438 {
439 /* TODO */
440 return ERROR_OK;
441 }
442
443 int mips_m4k_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
444 {
445 /* TODO */
446 return ERROR_OK;
447 }
448
449 int mips_m4k_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
450 {
451 /* TODO */
452 return ERROR_OK;
453 }
454
455 int mips_m4k_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
456 {
457 /* TODO */
458 return ERROR_OK;
459 }
460
461 int mips_m4k_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
462 {
463 /* TODO */
464 return ERROR_OK;
465 }
466
467 int mips_m4k_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
468 {
469 /* TODO */
470 return ERROR_OK;
471 }
472
473 int mips_m4k_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
474 {
475 /* TODO */
476 return ERROR_OK;
477 }
478
479 void mips_m4k_enable_watchpoints(struct target_s *target)
480 {
481 watchpoint_t *watchpoint = target->watchpoints;
482
483 /* set any pending watchpoints */
484 while (watchpoint)
485 {
486 if (watchpoint->set == 0)
487 mips_m4k_set_watchpoint(target, watchpoint);
488 watchpoint = watchpoint->next;
489 }
490 }
491
492 int mips_m4k_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
493 {
494 mips32_common_t *mips32 = target->arch_info;
495 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
496
497 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
498
499 if (target->state != TARGET_HALTED)
500 {
501 LOG_WARNING("target not halted");
502 return ERROR_TARGET_NOT_HALTED;
503 }
504
505 /* sanitize arguments */
506 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
507 return ERROR_INVALID_ARGUMENTS;
508
509 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
510 return ERROR_TARGET_UNALIGNED_ACCESS;
511
512 switch (size)
513 {
514 case 4:
515 case 2:
516 case 1:
517 /* if noDMA off, use DMAACC mode for memory read */
518 if(ejtag_info->impcode & (1<<14))
519 return mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
520 else
521 return mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
522 default:
523 LOG_ERROR("BUG: we shouldn't get here");
524 exit(-1);
525 break;
526 }
527
528 return ERROR_OK;
529 }
530
531 int mips_m4k_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
532 {
533 mips32_common_t *mips32 = target->arch_info;
534 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
535
536 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
537
538 if (target->state != TARGET_HALTED)
539 {
540 LOG_WARNING("target not halted");
541 return ERROR_TARGET_NOT_HALTED;
542 }
543
544 /* sanitize arguments */
545 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
546 return ERROR_INVALID_ARGUMENTS;
547
548 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
549 return ERROR_TARGET_UNALIGNED_ACCESS;
550
551 switch (size)
552 {
553 case 4:
554 case 2:
555 case 1:
556 /* if noDMA off, use DMAACC mode for memory write */
557 if(ejtag_info->impcode & (1<<14))
558 mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
559 else
560 mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
561 break;
562 default:
563 LOG_ERROR("BUG: we shouldn't get here");
564 exit(-1);
565 break;
566 }
567
568 return ERROR_OK;
569 }
570
571 int mips_m4k_register_commands(struct command_context_s *cmd_ctx)
572 {
573 int retval;
574
575 retval = mips32_register_commands(cmd_ctx);
576 return retval;
577 }
578
579 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
580 {
581 mips32_build_reg_cache(target);
582
583 return ERROR_OK;
584 }
585
586 int mips_m4k_quit(void)
587 {
588 return ERROR_OK;
589 }
590
591 int mips_m4k_init_arch_info(target_t *target, mips_m4k_common_t *mips_m4k, int chain_pos, const char *variant)
592 {
593 mips32_common_t *mips32 = &mips_m4k->mips32_common;
594
595 if (variant)
596 {
597 mips_m4k->variant = strdup(variant);
598 }
599 else
600 {
601 mips_m4k->variant = strdup("");
602 }
603
604 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
605
606 /* initialize mips4k specific info */
607 mips32_init_arch_info(target, mips32, chain_pos, variant);
608 mips32->arch_info = mips_m4k;
609
610 return ERROR_OK;
611 }
612
613 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp)
614 {
615 mips_m4k_common_t *mips_m4k = calloc(1,sizeof(mips_m4k_common_t));
616
617 mips_m4k_init_arch_info(target, mips_m4k, target->chain_position, target->variant);
618
619 return ERROR_OK;
620 }
621
622 int mips_m4k_examine(struct target_s *target)
623 {
624 int retval;
625 mips32_common_t *mips32 = target->arch_info;
626 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
627 u32 idcode = 0;
628
629 target->type->examined = 1;
630
631 mips_ejtag_get_idcode(ejtag_info, &idcode, NULL);
632
633 if (((idcode >> 1) & 0x7FF) == 0x29)
634 {
635 /* we are using a pic32mx so select ejtag port
636 * as it is not selected by default */
637 mips_ejtag_set_instr(ejtag_info, 0x05, NULL);
638 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
639 }
640
641 /* init rest of ejtag interface */
642 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
643 return retval;
644
645 return ERROR_OK;
646 }
647
648 int mips_m4k_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
649 {
650 return mips_m4k_write_memory(target, address, 4, count, buffer);
651 }

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)