- merged mips target into svn trunk
[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 command_context_s *cmd_ctx, 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 return ERROR_OK;
270 }
271
272 int mips_m4k_deassert_reset(target_t *target)
273 {
274 LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
275
276 /* deassert reset lines */
277 jtag_add_reset(0, 0);
278
279 return ERROR_OK;
280 }
281
282 int mips_m4k_soft_reset_halt(struct target_s *target)
283 {
284 /* TODO */
285 return ERROR_OK;
286 }
287
288 int mips_m4k_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
289 {
290 mips32_common_t *mips32 = target->arch_info;
291 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
292 breakpoint_t *breakpoint = NULL;
293 u32 resume_pc;
294
295 if (target->state != TARGET_HALTED)
296 {
297 LOG_WARNING("target not halted");
298 return ERROR_TARGET_NOT_HALTED;
299 }
300
301 if (!debug_execution)
302 {
303 target_free_all_working_areas(target);
304 mips_m4k_enable_breakpoints(target);
305 mips_m4k_enable_watchpoints(target);
306 }
307
308 /* current = 1: continue on current pc, otherwise continue at <address> */
309 if (!current)
310 {
311 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
312 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
313 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
314 }
315
316 resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
317
318 mips32_restore_context(target);
319
320 /* the front-end may request us not to handle breakpoints */
321 if (handle_breakpoints)
322 {
323 /* Single step past breakpoint at current address */
324 if ((breakpoint = breakpoint_find(target, resume_pc)))
325 {
326 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
327 mips_m4k_unset_breakpoint(target, breakpoint);
328 //mips_m4k_single_step_core(target);
329 mips_m4k_set_breakpoint(target, breakpoint);
330 }
331 }
332
333 /* exit debug mode - enable interrupts if required */
334 mips_ejtag_exit_debug(ejtag_info, !debug_execution);
335
336 /* registers are now invalid */
337 mips32_invalidate_core_regs(target);
338
339 if (!debug_execution)
340 {
341 target->state = TARGET_RUNNING;
342 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
343 LOG_DEBUG("target resumed at 0x%x", resume_pc);
344 }
345 else
346 {
347 target->state = TARGET_DEBUG_RUNNING;
348 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
349 LOG_DEBUG("target debug resumed at 0x%x", resume_pc);
350 }
351
352 return ERROR_OK;
353 }
354
355 int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
356 {
357 /* get pointers to arch-specific information */
358 mips32_common_t *mips32 = target->arch_info;
359 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
360 breakpoint_t *breakpoint = NULL;
361
362 if (target->state != TARGET_HALTED)
363 {
364 LOG_WARNING("target not halted");
365 return ERROR_TARGET_NOT_HALTED;
366 }
367
368 /* current = 1: continue on current pc, otherwise continue at <address> */
369 if (!current)
370 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
371
372 /* the front-end may request us not to handle breakpoints */
373 if (handle_breakpoints)
374 if ((breakpoint = breakpoint_find(target, buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32))))
375 mips_m4k_unset_breakpoint(target, breakpoint);
376
377 /* restore context */
378 mips32_restore_context(target);
379
380 /* configure single step mode */
381 mips_ejtag_config_step(ejtag_info, 1);
382
383 target->debug_reason = DBG_REASON_SINGLESTEP;
384
385 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
386
387 /* exit debug mode */
388 mips_ejtag_exit_debug(ejtag_info, 1);
389
390 /* registers are now invalid */
391 mips32_invalidate_core_regs(target);
392
393 if (breakpoint)
394 mips_m4k_set_breakpoint(target, breakpoint);
395
396 LOG_DEBUG("target stepped ");
397
398 mips_m4k_debug_entry(target);
399 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
400
401 return ERROR_OK;
402 }
403
404 void mips_m4k_enable_breakpoints(struct target_s *target)
405 {
406 breakpoint_t *breakpoint = target->breakpoints;
407
408 /* set any pending breakpoints */
409 while (breakpoint)
410 {
411 if (breakpoint->set == 0)
412 mips_m4k_set_breakpoint(target, breakpoint);
413 breakpoint = breakpoint->next;
414 }
415 }
416
417 int mips_m4k_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
418 {
419 /* TODO */
420 return ERROR_OK;
421 }
422
423 int mips_m4k_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
424 {
425 /* TODO */
426 return ERROR_OK;
427 }
428
429 int mips_m4k_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
430 {
431 /* TODO */
432 return ERROR_OK;
433 }
434
435 int mips_m4k_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
436 {
437 /* TODO */
438 return ERROR_OK;
439 }
440
441 int mips_m4k_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
442 {
443 /* TODO */
444 return ERROR_OK;
445 }
446
447 int mips_m4k_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
448 {
449 /* TODO */
450 return ERROR_OK;
451 }
452
453 int mips_m4k_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
454 {
455 /* TODO */
456 return ERROR_OK;
457 }
458
459 int mips_m4k_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
460 {
461 /* TODO */
462 return ERROR_OK;
463 }
464
465 void mips_m4k_enable_watchpoints(struct target_s *target)
466 {
467 watchpoint_t *watchpoint = target->watchpoints;
468
469 /* set any pending watchpoints */
470 while (watchpoint)
471 {
472 if (watchpoint->set == 0)
473 mips_m4k_set_watchpoint(target, watchpoint);
474 watchpoint = watchpoint->next;
475 }
476 }
477
478 int mips_m4k_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
479 {
480 mips32_common_t *mips32 = target->arch_info;
481 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
482
483 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
484
485 if (target->state != TARGET_HALTED)
486 {
487 LOG_WARNING("target not halted");
488 return ERROR_TARGET_NOT_HALTED;
489 }
490
491 /* sanitize arguments */
492 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
493 return ERROR_INVALID_ARGUMENTS;
494
495 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
496 return ERROR_TARGET_UNALIGNED_ACCESS;
497
498 switch (size)
499 {
500 case 4:
501 case 2:
502 case 1:
503 return mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
504 default:
505 LOG_ERROR("BUG: we shouldn't get here");
506 exit(-1);
507 break;
508 }
509
510 return ERROR_OK;
511 }
512
513 int mips_m4k_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
514 {
515 mips32_common_t *mips32 = target->arch_info;
516 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
517
518 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
519
520 if (target->state != TARGET_HALTED)
521 {
522 LOG_WARNING("target not halted");
523 return ERROR_TARGET_NOT_HALTED;
524 }
525
526 /* sanitize arguments */
527 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
528 return ERROR_INVALID_ARGUMENTS;
529
530 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
531 return ERROR_TARGET_UNALIGNED_ACCESS;
532
533 switch (size)
534 {
535 case 4:
536 case 2:
537 case 1:
538 mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
539 break;
540 default:
541 LOG_ERROR("BUG: we shouldn't get here");
542 exit(-1);
543 break;
544 }
545
546 return ERROR_OK;
547 }
548
549 int mips_m4k_register_commands(struct command_context_s *cmd_ctx)
550 {
551 int retval;
552
553 retval = mips32_register_commands(cmd_ctx);
554 return retval;
555 }
556
557 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
558 {
559 mips32_build_reg_cache(target);
560
561 return ERROR_OK;
562 }
563
564 int mips_m4k_quit()
565 {
566 return ERROR_OK;
567 }
568
569 int mips_m4k_init_arch_info(target_t *target, mips_m4k_common_t *mips_m4k, int chain_pos, char *variant)
570 {
571 mips32_common_t *mips32 = &mips_m4k->mips32_common;
572
573 if (variant)
574 {
575 mips_m4k->variant = strdup(variant);
576 }
577 else
578 {
579 mips_m4k->variant = strdup("");
580 }
581
582 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
583
584 /* initialize mips4k specific info */
585 mips32_init_arch_info(target, mips32, chain_pos, variant);
586 mips32->arch_info = mips_m4k;
587
588 return ERROR_OK;
589 }
590
591 int mips_m4k_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
592 {
593 int chain_pos;
594 char *variant = NULL;
595 mips_m4k_common_t *mips_m4k = malloc(sizeof(mips_m4k_common_t));
596
597 if (argc < 4)
598 {
599 LOG_ERROR("'target mips4k' requires at least one additional argument");
600 exit(-1);
601 }
602
603 chain_pos = strtoul(args[3], NULL, 0);
604
605 if (argc >= 5)
606 variant = args[4];
607
608 mips_m4k_init_arch_info(target, mips_m4k, chain_pos, variant);
609
610 return ERROR_OK;
611 }
612
613 int mips_m4k_examine(struct command_context_s *cmd_ctx, struct target_s *target)
614 {
615 int retval;
616 mips32_common_t *mips32 = target->arch_info;
617 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
618 u32 idcode = 0;
619
620 target->type->examined = 1;
621
622 mips_ejtag_get_idcode(ejtag_info, &idcode, NULL);
623
624 if (((idcode >> 1) & 0x7FF) == 0x29)
625 {
626 /* we are using a pic32mx so select ejtag port
627 * as it is not selected by default */
628 mips_ejtag_set_instr(ejtag_info, 0x05, NULL);
629 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
630 }
631
632 /* init rest of ejtag interface */
633 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
634 return retval;
635
636 return ERROR_OK;
637 }
638
639 int mips_m4k_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
640 {
641 return mips_m4k_write_memory(target, address, 4, count, buffer);
642 }

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)