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

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)