mips32 : Fixed memory byte access
[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 * Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com> *
8 * *
9 * Copyright (C) 2011 by Drasko DRASKOVIC *
10 * drasko.draskovic@gmail.com *
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 * This program is distributed in the hope that it will be useful, *
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20 * GNU General Public License for more details. *
21 * *
22 * You should have received a copy of the GNU General Public License *
23 * along with this program; if not, write to the *
24 * Free Software Foundation, Inc., *
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
26 ***************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "breakpoints.h"
32 #include "mips32.h"
33 #include "mips_m4k.h"
34 #include "mips32_dmaacc.h"
35 #include "target_type.h"
36 #include "register.h"
37
38 static void mips_m4k_enable_breakpoints(struct target *target);
39 static void mips_m4k_enable_watchpoints(struct target *target);
40 static int mips_m4k_set_breakpoint(struct target *target,
41 struct breakpoint *breakpoint);
42 static int mips_m4k_unset_breakpoint(struct target *target,
43 struct breakpoint *breakpoint);
44
45 static int mips_m4k_examine_debug_reason(struct target *target)
46 {
47 uint32_t break_status;
48 int retval;
49
50 if ((target->debug_reason != DBG_REASON_DBGRQ)
51 && (target->debug_reason != DBG_REASON_SINGLESTEP))
52 {
53 /* get info about inst breakpoint support */
54 if ((retval = target_read_u32(target, EJTAG_IBS, &break_status)) != ERROR_OK)
55 return retval;
56 if (break_status & 0x1f)
57 {
58 /* we have halted on a breakpoint */
59 if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK)
60 return retval;
61 target->debug_reason = DBG_REASON_BREAKPOINT;
62 }
63
64 /* get info about data breakpoint support */
65 if ((retval = target_read_u32(target, EJTAG_DBS, &break_status)) != ERROR_OK)
66 return retval;
67 if (break_status & 0x1f)
68 {
69 /* we have halted on a breakpoint */
70 if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK)
71 return retval;
72 target->debug_reason = DBG_REASON_WATCHPOINT;
73 }
74 }
75
76 return ERROR_OK;
77 }
78
79 static int mips_m4k_debug_entry(struct target *target)
80 {
81 struct mips32_common *mips32 = target_to_mips32(target);
82 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
83 uint32_t debug_reg;
84
85 /* read debug register */
86 mips_ejtag_read_debug(ejtag_info, &debug_reg);
87
88 /* make sure break unit configured */
89 mips32_configure_break_unit(target);
90
91 /* attempt to find halt reason */
92 mips_m4k_examine_debug_reason(target);
93
94 /* clear single step if active */
95 if (debug_reg & EJTAG_DEBUG_DSS)
96 {
97 /* stopped due to single step - clear step bit */
98 mips_ejtag_config_step(ejtag_info, 0);
99 }
100
101 mips32_save_context(target);
102
103 /* default to mips32 isa, it will be changed below if required */
104 mips32->isa_mode = MIPS32_ISA_MIPS32;
105
106 if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
107 mips32->isa_mode = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1);
108 }
109
110 LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
111 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32),
112 target_state_name(target));
113
114 return ERROR_OK;
115 }
116
117 static int mips_m4k_poll(struct target *target)
118 {
119 int retval;
120 struct mips32_common *mips32 = target_to_mips32(target);
121 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
122 uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl;
123
124 /* read ejtag control reg */
125 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
126 retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
127 if (retval != ERROR_OK)
128 return retval;
129
130 /* clear this bit before handling polling
131 * as after reset registers will read zero */
132 if (ejtag_ctrl & EJTAG_CTRL_ROCC)
133 {
134 /* we have detected a reset, clear flag
135 * otherwise ejtag will not work */
136 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
137
138 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
139 retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
140 if (retval != ERROR_OK)
141 return retval;
142 LOG_DEBUG("Reset Detected");
143 }
144
145 /* check for processor halted */
146 if (ejtag_ctrl & EJTAG_CTRL_BRKST)
147 {
148 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
149 {
150 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
151
152 target->state = TARGET_HALTED;
153
154 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
155 return retval;
156
157 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
158 }
159 else if (target->state == TARGET_DEBUG_RUNNING)
160 {
161 target->state = TARGET_HALTED;
162
163 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
164 return retval;
165
166 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
167 }
168 }
169 else
170 {
171 target->state = TARGET_RUNNING;
172 }
173
174 // LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl);
175
176 return ERROR_OK;
177 }
178
179 static int mips_m4k_halt(struct target *target)
180 {
181 struct mips32_common *mips32 = target_to_mips32(target);
182 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
183
184 LOG_DEBUG("target->state: %s",
185 target_state_name(target));
186
187 if (target->state == TARGET_HALTED)
188 {
189 LOG_DEBUG("target was already halted");
190 return ERROR_OK;
191 }
192
193 if (target->state == TARGET_UNKNOWN)
194 {
195 LOG_WARNING("target was in unknown state when halt was requested");
196 }
197
198 if (target->state == TARGET_RESET)
199 {
200 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
201 {
202 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
203 return ERROR_TARGET_FAILURE;
204 }
205 else
206 {
207 /* we came here in a reset_halt or reset_init sequence
208 * debug entry was already prepared in mips32_prepare_reset_halt()
209 */
210 target->debug_reason = DBG_REASON_DBGRQ;
211
212 return ERROR_OK;
213 }
214 }
215
216 /* break processor */
217 mips_ejtag_enter_debug(ejtag_info);
218
219 target->debug_reason = DBG_REASON_DBGRQ;
220
221 return ERROR_OK;
222 }
223
224 static int mips_m4k_assert_reset(struct target *target)
225 {
226 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
227 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
228 int assert_srst = 1;
229
230 LOG_DEBUG("target->state: %s",
231 target_state_name(target));
232
233 enum reset_types jtag_reset_config = jtag_get_reset_config();
234
235 if (!(jtag_reset_config & RESET_HAS_SRST))
236 assert_srst = 0;
237
238 if (target->reset_halt)
239 {
240 /* use hardware to catch reset */
241 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);
242 }
243 else
244 {
245 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
246 }
247
248 if (assert_srst)
249 {
250 /* here we should issue a srst only, but we may have to assert trst as well */
251 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
252 {
253 jtag_add_reset(1, 1);
254 }
255 else
256 {
257 jtag_add_reset(0, 1);
258 }
259 }
260 else
261 {
262 if (mips_m4k->is_pic32mx)
263 {
264 LOG_DEBUG("Using MTAP reset to reset processor...");
265
266 /* use microchip specific MTAP reset */
267 mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);
268 mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);
269
270 mips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST);
271 mips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST);
272 mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
273 }
274 else
275 {
276 /* use ejtag reset - not supported by all cores */
277 uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
278 LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
279 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
280 mips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl);
281 }
282 }
283
284 target->state = TARGET_RESET;
285 jtag_add_sleep(50000);
286
287 register_cache_invalidate(mips_m4k->mips32.core_cache);
288
289 if (target->reset_halt)
290 {
291 int retval;
292 if ((retval = target_halt(target)) != ERROR_OK)
293 return retval;
294 }
295
296 return ERROR_OK;
297 }
298
299 static int mips_m4k_deassert_reset(struct target *target)
300 {
301 LOG_DEBUG("target->state: %s",
302 target_state_name(target));
303
304 /* deassert reset lines */
305 jtag_add_reset(0, 0);
306
307 return ERROR_OK;
308 }
309
310 static int mips_m4k_soft_reset_halt(struct target *target)
311 {
312 /* TODO */
313 return ERROR_OK;
314 }
315
316 static int mips_m4k_single_step_core(struct target *target)
317 {
318 struct mips32_common *mips32 = target_to_mips32(target);
319 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
320
321 /* configure single step mode */
322 mips_ejtag_config_step(ejtag_info, 1);
323
324 /* disable interrupts while stepping */
325 mips32_enable_interrupts(target, 0);
326
327 /* exit debug mode */
328 mips_ejtag_exit_debug(ejtag_info);
329
330 mips_m4k_debug_entry(target);
331
332 return ERROR_OK;
333 }
334
335 static int mips_m4k_resume(struct target *target, int current,
336 uint32_t address, int handle_breakpoints, int debug_execution)
337 {
338 struct mips32_common *mips32 = target_to_mips32(target);
339 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
340 struct breakpoint *breakpoint = NULL;
341 uint32_t resume_pc;
342
343 if (target->state != TARGET_HALTED)
344 {
345 LOG_WARNING("target not halted");
346 return ERROR_TARGET_NOT_HALTED;
347 }
348
349 if (!debug_execution)
350 {
351 target_free_all_working_areas(target);
352 mips_m4k_enable_breakpoints(target);
353 mips_m4k_enable_watchpoints(target);
354 }
355
356 /* current = 1: continue on current pc, otherwise continue at <address> */
357 if (!current)
358 {
359 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
360 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
361 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
362 }
363
364 if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
365 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode);
366 }
367
368 resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
369
370 mips32_restore_context(target);
371
372 /* the front-end may request us not to handle breakpoints */
373 if (handle_breakpoints)
374 {
375 /* Single step past breakpoint at current address */
376 if ((breakpoint = breakpoint_find(target, resume_pc)))
377 {
378 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
379 mips_m4k_unset_breakpoint(target, breakpoint);
380 mips_m4k_single_step_core(target);
381 mips_m4k_set_breakpoint(target, breakpoint);
382 }
383 }
384
385 /* enable interrupts if we are running */
386 mips32_enable_interrupts(target, !debug_execution);
387
388 /* exit debug mode */
389 mips_ejtag_exit_debug(ejtag_info);
390 target->debug_reason = DBG_REASON_NOTHALTED;
391
392 /* registers are now invalid */
393 register_cache_invalidate(mips32->core_cache);
394
395 if (!debug_execution)
396 {
397 target->state = TARGET_RUNNING;
398 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
399 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
400 }
401 else
402 {
403 target->state = TARGET_DEBUG_RUNNING;
404 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
405 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
406 }
407
408 return ERROR_OK;
409 }
410
411 static int mips_m4k_step(struct target *target, int current,
412 uint32_t address, int handle_breakpoints)
413 {
414 /* get pointers to arch-specific information */
415 struct mips32_common *mips32 = target_to_mips32(target);
416 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
417 struct breakpoint *breakpoint = NULL;
418
419 if (target->state != TARGET_HALTED)
420 {
421 LOG_WARNING("target not halted");
422 return ERROR_TARGET_NOT_HALTED;
423 }
424
425 /* current = 1: continue on current pc, otherwise continue at <address> */
426 if (!current)
427 {
428 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
429 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
430 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
431 }
432
433 /* the front-end may request us not to handle breakpoints */
434 if (handle_breakpoints) {
435 breakpoint = breakpoint_find(target,
436 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
437 if (breakpoint)
438 mips_m4k_unset_breakpoint(target, breakpoint);
439 }
440
441 /* restore context */
442 mips32_restore_context(target);
443
444 /* configure single step mode */
445 mips_ejtag_config_step(ejtag_info, 1);
446
447 target->debug_reason = DBG_REASON_SINGLESTEP;
448
449 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
450
451 /* disable interrupts while stepping */
452 mips32_enable_interrupts(target, 0);
453
454 /* exit debug mode */
455 mips_ejtag_exit_debug(ejtag_info);
456
457 /* registers are now invalid */
458 register_cache_invalidate(mips32->core_cache);
459
460 if (breakpoint)
461 mips_m4k_set_breakpoint(target, breakpoint);
462
463 LOG_DEBUG("target stepped ");
464
465 mips_m4k_debug_entry(target);
466 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
467
468 return ERROR_OK;
469 }
470
471 static void mips_m4k_enable_breakpoints(struct target *target)
472 {
473 struct breakpoint *breakpoint = target->breakpoints;
474
475 /* set any pending breakpoints */
476 while (breakpoint)
477 {
478 if (breakpoint->set == 0)
479 mips_m4k_set_breakpoint(target, breakpoint);
480 breakpoint = breakpoint->next;
481 }
482 }
483
484 static int mips_m4k_set_breakpoint(struct target *target,
485 struct breakpoint *breakpoint)
486 {
487 struct mips32_common *mips32 = target_to_mips32(target);
488 struct mips32_comparator * comparator_list = mips32->inst_break_list;
489 int retval;
490
491 if (breakpoint->set)
492 {
493 LOG_WARNING("breakpoint already set");
494 return ERROR_OK;
495 }
496
497 if (breakpoint->type == BKPT_HARD)
498 {
499 int bp_num = 0;
500
501 while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))
502 bp_num++;
503 if (bp_num >= mips32->num_inst_bpoints)
504 {
505 LOG_ERROR("Can not find free FP Comparator(bpid: %d)",
506 breakpoint->unique_id );
507 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
508 }
509 breakpoint->set = bp_num + 1;
510 comparator_list[bp_num].used = 1;
511 comparator_list[bp_num].bp_value = breakpoint->address;
512 target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value);
513 target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000);
514 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1);
515 LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "",
516 breakpoint->unique_id,
517 bp_num, comparator_list[bp_num].bp_value);
518 }
519 else if (breakpoint->type == BKPT_SOFT)
520 {
521 LOG_DEBUG("bpid: %d", breakpoint->unique_id );
522 if (breakpoint->length == 4)
523 {
524 uint32_t verify = 0xffffffff;
525
526 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
527 breakpoint->orig_instr)) != ERROR_OK)
528 {
529 return retval;
530 }
531 if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK)
532 {
533 return retval;
534 }
535
536 if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK)
537 {
538 return retval;
539 }
540 if (verify != MIPS32_SDBBP)
541 {
542 LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
543 return ERROR_OK;
544 }
545 }
546 else
547 {
548 uint16_t verify = 0xffff;
549
550 if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
551 breakpoint->orig_instr)) != ERROR_OK)
552 {
553 return retval;
554 }
555 if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK)
556 {
557 return retval;
558 }
559
560 if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK)
561 {
562 return retval;
563 }
564 if (verify != MIPS16_SDBBP)
565 {
566 LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
567 return ERROR_OK;
568 }
569 }
570
571 breakpoint->set = 20; /* Any nice value but 0 */
572 }
573
574 return ERROR_OK;
575 }
576
577 static int mips_m4k_unset_breakpoint(struct target *target,
578 struct breakpoint *breakpoint)
579 {
580 /* get pointers to arch-specific information */
581 struct mips32_common *mips32 = target_to_mips32(target);
582 struct mips32_comparator *comparator_list = mips32->inst_break_list;
583 int retval;
584
585 if (!breakpoint->set)
586 {
587 LOG_WARNING("breakpoint not set");
588 return ERROR_OK;
589 }
590
591 if (breakpoint->type == BKPT_HARD)
592 {
593 int bp_num = breakpoint->set - 1;
594 if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints))
595 {
596 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
597 breakpoint->unique_id);
598 return ERROR_OK;
599 }
600 LOG_DEBUG("bpid: %d - releasing hw: %d",
601 breakpoint->unique_id,
602 bp_num );
603 comparator_list[bp_num].used = 0;
604 comparator_list[bp_num].bp_value = 0;
605 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
606
607 }
608 else
609 {
610 /* restore original instruction (kept in target endianness) */
611 LOG_DEBUG("bpid: %d", breakpoint->unique_id);
612 if (breakpoint->length == 4)
613 {
614 uint32_t current_instr;
615
616 /* check that user program has not modified breakpoint instruction */
617 if ((retval = target_read_memory(target, breakpoint->address, 4, 1,
618 (uint8_t*)&current_instr)) != ERROR_OK)
619 {
620 return retval;
621 }
622
623 /**
624 * target_read_memory() gets us data in _target_ endianess.
625 * If we want to use this data on the host for comparisons with some macros
626 * we must first transform it to _host_ endianess using target_buffer_get_u32().
627 */
628 current_instr = target_buffer_get_u32(target, (uint8_t *)&current_instr);
629
630 if (current_instr == MIPS32_SDBBP)
631 {
632 if ((retval = target_write_memory(target, breakpoint->address, 4, 1,
633 breakpoint->orig_instr)) != ERROR_OK)
634 {
635 return retval;
636 }
637 }
638 }
639 else
640 {
641 uint16_t current_instr;
642
643 /* check that user program has not modified breakpoint instruction */
644 if ((retval = target_read_memory(target, breakpoint->address, 2, 1,
645 (uint8_t*)&current_instr)) != ERROR_OK)
646 {
647 return retval;
648 }
649 current_instr = target_buffer_get_u16(target, (uint8_t *)&current_instr);
650 if (current_instr == MIPS16_SDBBP)
651 {
652 if ((retval = target_write_memory(target, breakpoint->address, 2, 1,
653 breakpoint->orig_instr)) != ERROR_OK)
654 {
655 return retval;
656 }
657 }
658 }
659 }
660 breakpoint->set = 0;
661
662 return ERROR_OK;
663 }
664
665 static int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
666 {
667 struct mips32_common *mips32 = target_to_mips32(target);
668
669 if (breakpoint->type == BKPT_HARD)
670 {
671 if (mips32->num_inst_bpoints_avail < 1)
672 {
673 LOG_INFO("no hardware breakpoint available");
674 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
675 }
676
677 mips32->num_inst_bpoints_avail--;
678 }
679
680 return mips_m4k_set_breakpoint(target, breakpoint);
681 }
682
683 static int mips_m4k_remove_breakpoint(struct target *target,
684 struct breakpoint *breakpoint)
685 {
686 /* get pointers to arch-specific information */
687 struct mips32_common *mips32 = target_to_mips32(target);
688
689 if (target->state != TARGET_HALTED)
690 {
691 LOG_WARNING("target not halted");
692 return ERROR_TARGET_NOT_HALTED;
693 }
694
695 if (breakpoint->set)
696 {
697 mips_m4k_unset_breakpoint(target, breakpoint);
698 }
699
700 if (breakpoint->type == BKPT_HARD)
701 mips32->num_inst_bpoints_avail++;
702
703 return ERROR_OK;
704 }
705
706 static int mips_m4k_set_watchpoint(struct target *target,
707 struct watchpoint *watchpoint)
708 {
709 struct mips32_common *mips32 = target_to_mips32(target);
710 struct mips32_comparator *comparator_list = mips32->data_break_list;
711 int wp_num = 0;
712 /*
713 * watchpoint enabled, ignore all byte lanes in value register
714 * and exclude both load and store accesses from watchpoint
715 * condition evaluation
716 */
717 int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
718 (0xff << EJTAG_DBCn_BLM_SHIFT);
719
720 if (watchpoint->set)
721 {
722 LOG_WARNING("watchpoint already set");
723 return ERROR_OK;
724 }
725
726 while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
727 wp_num++;
728 if (wp_num >= mips32->num_data_bpoints)
729 {
730 LOG_ERROR("Can not find free FP Comparator");
731 return ERROR_FAIL;
732 }
733
734 if (watchpoint->length != 4)
735 {
736 LOG_ERROR("Only watchpoints of length 4 are supported");
737 return ERROR_TARGET_UNALIGNED_ACCESS;
738 }
739
740 if (watchpoint->address % 4)
741 {
742 LOG_ERROR("Watchpoints address should be word aligned");
743 return ERROR_TARGET_UNALIGNED_ACCESS;
744 }
745
746 switch (watchpoint->rw)
747 {
748 case WPT_READ:
749 enable &= ~EJTAG_DBCn_NOLB;
750 break;
751 case WPT_WRITE:
752 enable &= ~EJTAG_DBCn_NOSB;
753 break;
754 case WPT_ACCESS:
755 enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB);
756 break;
757 default:
758 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
759 }
760
761 watchpoint->set = wp_num + 1;
762 comparator_list[wp_num].used = 1;
763 comparator_list[wp_num].bp_value = watchpoint->address;
764 target_write_u32(target, comparator_list[wp_num].reg_address, comparator_list[wp_num].bp_value);
765 target_write_u32(target, comparator_list[wp_num].reg_address + 0x08, 0x00000000);
766 target_write_u32(target, comparator_list[wp_num].reg_address + 0x10, 0x00000000);
767 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, enable);
768 target_write_u32(target, comparator_list[wp_num].reg_address + 0x20, 0);
769 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value);
770
771 return ERROR_OK;
772 }
773
774 static int mips_m4k_unset_watchpoint(struct target *target,
775 struct watchpoint *watchpoint)
776 {
777 /* get pointers to arch-specific information */
778 struct mips32_common *mips32 = target_to_mips32(target);
779 struct mips32_comparator *comparator_list = mips32->data_break_list;
780
781 if (!watchpoint->set)
782 {
783 LOG_WARNING("watchpoint not set");
784 return ERROR_OK;
785 }
786
787 int wp_num = watchpoint->set - 1;
788 if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints))
789 {
790 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
791 return ERROR_OK;
792 }
793 comparator_list[wp_num].used = 0;
794 comparator_list[wp_num].bp_value = 0;
795 target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, 0);
796 watchpoint->set = 0;
797
798 return ERROR_OK;
799 }
800
801 static int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
802 {
803 struct mips32_common *mips32 = target_to_mips32(target);
804
805 if (mips32->num_data_bpoints_avail < 1)
806 {
807 LOG_INFO("no hardware watchpoints available");
808 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
809 }
810
811 mips32->num_data_bpoints_avail--;
812
813 mips_m4k_set_watchpoint(target, watchpoint);
814 return ERROR_OK;
815 }
816
817 static int mips_m4k_remove_watchpoint(struct target *target,
818 struct watchpoint *watchpoint)
819 {
820 /* get pointers to arch-specific information */
821 struct mips32_common *mips32 = target_to_mips32(target);
822
823 if (target->state != TARGET_HALTED)
824 {
825 LOG_WARNING("target not halted");
826 return ERROR_TARGET_NOT_HALTED;
827 }
828
829 if (watchpoint->set)
830 {
831 mips_m4k_unset_watchpoint(target, watchpoint);
832 }
833
834 mips32->num_data_bpoints_avail++;
835
836 return ERROR_OK;
837 }
838
839 static void mips_m4k_enable_watchpoints(struct target *target)
840 {
841 struct watchpoint *watchpoint = target->watchpoints;
842
843 /* set any pending watchpoints */
844 while (watchpoint)
845 {
846 if (watchpoint->set == 0)
847 mips_m4k_set_watchpoint(target, watchpoint);
848 watchpoint = watchpoint->next;
849 }
850 }
851
852 static int mips_m4k_read_memory(struct target *target, uint32_t address,
853 uint32_t size, uint32_t count, uint8_t *buffer)
854 {
855 struct mips32_common *mips32 = target_to_mips32(target);
856 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
857
858 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
859
860 if (target->state != TARGET_HALTED)
861 {
862 LOG_WARNING("target not halted");
863 return ERROR_TARGET_NOT_HALTED;
864 }
865
866 /* sanitize arguments */
867 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
868 return ERROR_INVALID_ARGUMENTS;
869
870 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
871 return ERROR_TARGET_UNALIGNED_ACCESS;
872
873 /* if noDMA off, use DMAACC mode for memory read */
874 int retval;
875 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
876 retval = mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
877 else
878 retval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
879 if (ERROR_OK != retval)
880 return retval;
881
882 /* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */
883 /* endianness, but byte array should represent target endianness */
884 uint32_t i, t32;
885 uint16_t t16;
886 for(i = 0; i < (count*size); i += size)
887 {
888 switch(size)
889 {
890 case 4:
891 t32 = le_to_h_u32(&buffer[i]);
892 target_buffer_set_u32(target,&buffer[i], t32);
893 break;
894 case 2:
895 t16 = le_to_h_u16(&buffer[i]);
896 target_buffer_set_u16(target,&buffer[i], t16);
897 break;
898 }
899 }
900
901 return ERROR_OK;
902 }
903
904 static int mips_m4k_write_memory(struct target *target, uint32_t address,
905 uint32_t size, uint32_t count, const uint8_t *buffer)
906 {
907 struct mips32_common *mips32 = target_to_mips32(target);
908 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
909
910 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
911 address, size, count);
912
913 if (target->state != TARGET_HALTED)
914 {
915 LOG_WARNING("target not halted");
916 return ERROR_TARGET_NOT_HALTED;
917 }
918
919 /* sanitize arguments */
920 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
921 return ERROR_INVALID_ARGUMENTS;
922
923 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
924 return ERROR_TARGET_UNALIGNED_ACCESS;
925
926 /** correct endianess if we have word or hword access */
927 uint8_t *t = NULL;
928 if (size > 1)
929 {
930 /* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */
931 /* endianness, but byte array represents target endianness */
932 t = malloc(count * sizeof(uint32_t));
933 if (t == NULL)
934 {
935 LOG_ERROR("Out of memory");
936 return ERROR_FAIL;
937 }
938
939 uint32_t i, t32;
940 uint16_t t16;
941 for(i = 0; i < (count*size); i += size)
942 {
943 switch(size)
944 {
945 case 4:
946 t32 = target_buffer_get_u32(target,&buffer[i]);
947 h_u32_to_le(&t[i], t32);
948 break;
949 case 2:
950 t16 = target_buffer_get_u16(target,&buffer[i]);
951 h_u16_to_le(&t[i], t16);
952 break;
953 }
954 }
955
956 buffer = t;
957 }
958
959 /* if noDMA off, use DMAACC mode for memory write */
960 int retval;
961 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
962 retval = mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
963 else
964 retval = mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
965
966 if (t != NULL)
967 free(t);
968
969 if (ERROR_OK != retval)
970 return retval;
971
972 return ERROR_OK;
973 }
974
975 static int mips_m4k_init_target(struct command_context *cmd_ctx,
976 struct target *target)
977 {
978 mips32_build_reg_cache(target);
979
980 return ERROR_OK;
981 }
982
983 static int mips_m4k_init_arch_info(struct target *target,
984 struct mips_m4k_common *mips_m4k, struct jtag_tap *tap)
985 {
986 struct mips32_common *mips32 = &mips_m4k->mips32;
987
988 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
989
990 /* initialize mips4k specific info */
991 mips32_init_arch_info(target, mips32, tap);
992 mips32->arch_info = mips_m4k;
993
994 return ERROR_OK;
995 }
996
997 static int mips_m4k_target_create(struct target *target, Jim_Interp *interp)
998 {
999 struct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common));
1000
1001 mips_m4k_init_arch_info(target, mips_m4k, target->tap);
1002
1003 return ERROR_OK;
1004 }
1005
1006 static int mips_m4k_examine(struct target *target)
1007 {
1008 int retval;
1009 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
1010 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
1011 uint32_t idcode = 0;
1012
1013 if (!target_was_examined(target))
1014 {
1015 retval = mips_ejtag_get_idcode(ejtag_info, &idcode);
1016 if (retval != ERROR_OK)
1017 return retval;
1018 ejtag_info->idcode = idcode;
1019
1020 if (((idcode >> 1) & 0x7FF) == 0x29)
1021 {
1022 /* we are using a pic32mx so select ejtag port
1023 * as it is not selected by default */
1024 mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
1025 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
1026 mips_m4k->is_pic32mx = true;
1027 }
1028 }
1029
1030 /* init rest of ejtag interface */
1031 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
1032 return retval;
1033
1034 if ((retval = mips32_examine(target)) != ERROR_OK)
1035 return retval;
1036
1037 return ERROR_OK;
1038 }
1039
1040 static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
1041 uint32_t count, const uint8_t *buffer)
1042 {
1043 struct mips32_common *mips32 = target_to_mips32(target);
1044 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1045 int retval;
1046 int write_t = 1;
1047
1048 LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count);
1049
1050 if (target->state != TARGET_HALTED)
1051 {
1052 LOG_WARNING("target not halted");
1053 return ERROR_TARGET_NOT_HALTED;
1054 }
1055
1056 /* check alignment */
1057 if (address & 0x3u)
1058 return ERROR_TARGET_UNALIGNED_ACCESS;
1059
1060 if (mips32->fast_data_area == NULL)
1061 {
1062 /* Get memory for block write handler
1063 * we preserve this area between calls and gain a speed increase
1064 * of about 3kb/sec when writing flash
1065 * this will be released/nulled by the system when the target is resumed or reset */
1066 retval = target_alloc_working_area(target,
1067 MIPS32_FASTDATA_HANDLER_SIZE,
1068 &mips32->fast_data_area);
1069 if (retval != ERROR_OK)
1070 {
1071 LOG_WARNING("No working area available, falling back to non-bulk write");
1072 return mips_m4k_write_memory(target, address, 4, count, buffer);
1073 }
1074
1075 /* reset fastadata state so the algo get reloaded */
1076 ejtag_info->fast_access_save = -1;
1077 }
1078
1079 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
1080 /* but byte array represents target endianness */
1081 uint8_t * t = NULL;
1082 t = malloc(count * sizeof(uint32_t));
1083 if (t == NULL)
1084 {
1085 LOG_ERROR("Out of memory");
1086 return ERROR_FAIL;
1087 }
1088
1089 uint32_t i, t32;
1090 for(i = 0; i < (count*4); i += 4)
1091 {
1092 t32 = target_buffer_get_u32(target,&buffer[i]);
1093 h_u32_to_le(&t[i], t32);
1094 }
1095
1096 retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,
1097 count, (uint32_t*) (void *)t);
1098
1099 if (t != NULL)
1100 free(t);
1101
1102 if (retval != ERROR_OK)
1103 {
1104 /* FASTDATA access failed, try normal memory write */
1105 LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write");
1106 retval = mips_m4k_write_memory(target, address, 4, count, buffer);
1107 }
1108
1109 return retval;
1110 }
1111
1112 static int mips_m4k_verify_pointer(struct command_context *cmd_ctx,
1113 struct mips_m4k_common *mips_m4k)
1114 {
1115 if (mips_m4k->common_magic != MIPSM4K_COMMON_MAGIC) {
1116 command_print(cmd_ctx, "target is not an MIPS_M4K");
1117 return ERROR_TARGET_INVALID;
1118 }
1119 return ERROR_OK;
1120 }
1121
1122 COMMAND_HANDLER(mips_m4k_handle_cp0_command)
1123 {
1124 int retval;
1125 struct target *target = get_current_target(CMD_CTX);
1126 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
1127 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
1128
1129 retval = mips_m4k_verify_pointer(CMD_CTX, mips_m4k);
1130 if (retval != ERROR_OK)
1131 return retval;
1132
1133 if (target->state != TARGET_HALTED)
1134 {
1135 command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
1136 return ERROR_OK;
1137 }
1138
1139 /* two or more argument, access a single register/select (write if third argument is given) */
1140 if (CMD_ARGC < 2)
1141 {
1142 command_print(CMD_CTX, "command requires more arguments.");
1143 }
1144 else
1145 {
1146 uint32_t cp0_reg, cp0_sel;
1147 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
1148 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
1149
1150 if (CMD_ARGC == 2)
1151 {
1152 uint32_t value;
1153
1154 if ((retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel)) != ERROR_OK)
1155 {
1156 command_print(CMD_CTX,
1157 "couldn't access reg %" PRIi32,
1158 cp0_reg);
1159 return ERROR_OK;
1160 }
1161 if ((retval = jtag_execute_queue()) != ERROR_OK)
1162 {
1163 return retval;
1164 }
1165
1166 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
1167 cp0_reg, cp0_sel, value);
1168 }
1169 else if (CMD_ARGC == 3)
1170 {
1171 uint32_t value;
1172 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
1173 if ((retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel)) != ERROR_OK)
1174 {
1175 command_print(CMD_CTX,
1176 "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
1177 cp0_reg, cp0_sel);
1178 return ERROR_OK;
1179 }
1180 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
1181 cp0_reg, cp0_sel, value);
1182 }
1183 }
1184
1185 return ERROR_OK;
1186 }
1187
1188 static const struct command_registration mips_m4k_exec_command_handlers[] = {
1189 {
1190 .name = "cp0",
1191 .handler = mips_m4k_handle_cp0_command,
1192 .mode = COMMAND_EXEC,
1193 .usage = "regnum [value]",
1194 .help = "display/modify cp0 register",
1195 },
1196 COMMAND_REGISTRATION_DONE
1197 };
1198
1199 const struct command_registration mips_m4k_command_handlers[] = {
1200 {
1201 .chain = mips32_command_handlers,
1202 },
1203 {
1204 .name = "mips_m4k",
1205 .mode = COMMAND_ANY,
1206 .help = "mips_m4k command group",
1207 .chain = mips_m4k_exec_command_handlers,
1208 },
1209 COMMAND_REGISTRATION_DONE
1210 };
1211
1212 struct target_type mips_m4k_target =
1213 {
1214 .name = "mips_m4k",
1215
1216 .poll = mips_m4k_poll,
1217 .arch_state = mips32_arch_state,
1218
1219 .target_request_data = NULL,
1220
1221 .halt = mips_m4k_halt,
1222 .resume = mips_m4k_resume,
1223 .step = mips_m4k_step,
1224
1225 .assert_reset = mips_m4k_assert_reset,
1226 .deassert_reset = mips_m4k_deassert_reset,
1227 .soft_reset_halt = mips_m4k_soft_reset_halt,
1228
1229 .get_gdb_reg_list = mips32_get_gdb_reg_list,
1230
1231 .read_memory = mips_m4k_read_memory,
1232 .write_memory = mips_m4k_write_memory,
1233 .bulk_write_memory = mips_m4k_bulk_write_memory,
1234 .checksum_memory = mips32_checksum_memory,
1235 .blank_check_memory = mips32_blank_check_memory,
1236
1237 .run_algorithm = mips32_run_algorithm,
1238
1239 .add_breakpoint = mips_m4k_add_breakpoint,
1240 .remove_breakpoint = mips_m4k_remove_breakpoint,
1241 .add_watchpoint = mips_m4k_add_watchpoint,
1242 .remove_watchpoint = mips_m4k_remove_watchpoint,
1243
1244 .commands = mips_m4k_command_handlers,
1245 .target_create = mips_m4k_target_create,
1246 .init_target = mips_m4k_init_target,
1247 .examine = mips_m4k_examine,
1248 };

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)