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

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)