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

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)