mips: fix reading uint32 and uint16 when running on big endian host
[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 void * t = buffer;
874
875 /* if noDMA off, use DMAACC mode for memory read */
876 int retval;
877 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
878 retval = mips32_pracc_read_mem(ejtag_info, address, size, count, t);
879 else
880 retval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, t);
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 if (ERROR_OK == retval)
885 {
886 switch(size)
887 {
888 case 4:
889 target_buffer_set_u32_array(target,buffer,count,t);
890 break;
891 case 2:
892 target_buffer_set_u16_array(target,buffer,count,t);
893 break;
894 }
895 }
896
897 return retval;
898 }
899
900 static int mips_m4k_write_memory(struct target *target, uint32_t address,
901 uint32_t size, uint32_t count, const uint8_t *buffer)
902 {
903 struct mips32_common *mips32 = target_to_mips32(target);
904 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
905
906 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
907 address, size, count);
908
909 if (target->state != TARGET_HALTED)
910 {
911 LOG_WARNING("target not halted");
912 return ERROR_TARGET_NOT_HALTED;
913 }
914
915 /* sanitize arguments */
916 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
917 return ERROR_INVALID_ARGUMENTS;
918
919 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
920 return ERROR_TARGET_UNALIGNED_ACCESS;
921
922 /** correct endianess if we have word or hword access */
923 void *t = NULL;
924 if (size > 1)
925 {
926 /* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */
927 /* endianness, but byte array represents target endianness */
928 t = malloc(count * size * sizeof(uint8_t));
929 if (t == NULL)
930 {
931 LOG_ERROR("Out of memory");
932 return ERROR_FAIL;
933 }
934
935 switch(size)
936 {
937 case 4:
938 target_buffer_get_u32_array(target,buffer,count,(uint32_t*)t);
939 break;
940 case 2:
941 target_buffer_get_u16_array(target,buffer,count,(uint16_t*)t);
942 break;
943 }
944 buffer = t;
945 }
946
947 /* if noDMA off, use DMAACC mode for memory write */
948 int retval;
949 if (ejtag_info->impcode & EJTAG_IMP_NODMA)
950 retval = mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
951 else
952 retval = mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
953
954 if (t != NULL)
955 free(t);
956
957 if (ERROR_OK != retval)
958 return retval;
959
960 return ERROR_OK;
961 }
962
963 static int mips_m4k_init_target(struct command_context *cmd_ctx,
964 struct target *target)
965 {
966 mips32_build_reg_cache(target);
967
968 return ERROR_OK;
969 }
970
971 static int mips_m4k_init_arch_info(struct target *target,
972 struct mips_m4k_common *mips_m4k, struct jtag_tap *tap)
973 {
974 struct mips32_common *mips32 = &mips_m4k->mips32;
975
976 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
977
978 /* initialize mips4k specific info */
979 mips32_init_arch_info(target, mips32, tap);
980 mips32->arch_info = mips_m4k;
981
982 return ERROR_OK;
983 }
984
985 static int mips_m4k_target_create(struct target *target, Jim_Interp *interp)
986 {
987 struct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common));
988
989 mips_m4k_init_arch_info(target, mips_m4k, target->tap);
990
991 return ERROR_OK;
992 }
993
994 static int mips_m4k_examine(struct target *target)
995 {
996 int retval;
997 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
998 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
999 uint32_t idcode = 0;
1000
1001 if (!target_was_examined(target))
1002 {
1003 retval = mips_ejtag_get_idcode(ejtag_info, &idcode);
1004 if (retval != ERROR_OK)
1005 return retval;
1006 ejtag_info->idcode = idcode;
1007
1008 if (((idcode >> 1) & 0x7FF) == 0x29)
1009 {
1010 /* we are using a pic32mx so select ejtag port
1011 * as it is not selected by default */
1012 mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
1013 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
1014 mips_m4k->is_pic32mx = true;
1015 }
1016 }
1017
1018 /* init rest of ejtag interface */
1019 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
1020 return retval;
1021
1022 if ((retval = mips32_examine(target)) != ERROR_OK)
1023 return retval;
1024
1025 return ERROR_OK;
1026 }
1027
1028 static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
1029 uint32_t count, const uint8_t *buffer)
1030 {
1031 struct mips32_common *mips32 = target_to_mips32(target);
1032 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1033 int retval;
1034 int write_t = 1;
1035
1036 LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count);
1037
1038 if (target->state != TARGET_HALTED)
1039 {
1040 LOG_WARNING("target not halted");
1041 return ERROR_TARGET_NOT_HALTED;
1042 }
1043
1044 /* check alignment */
1045 if (address & 0x3u)
1046 return ERROR_TARGET_UNALIGNED_ACCESS;
1047
1048 if (mips32->fast_data_area == NULL)
1049 {
1050 /* Get memory for block write handler
1051 * we preserve this area between calls and gain a speed increase
1052 * of about 3kb/sec when writing flash
1053 * this will be released/nulled by the system when the target is resumed or reset */
1054 retval = target_alloc_working_area(target,
1055 MIPS32_FASTDATA_HANDLER_SIZE,
1056 &mips32->fast_data_area);
1057 if (retval != ERROR_OK)
1058 {
1059 LOG_WARNING("No working area available, falling back to non-bulk write");
1060 return mips_m4k_write_memory(target, address, 4, count, buffer);
1061 }
1062
1063 /* reset fastadata state so the algo get reloaded */
1064 ejtag_info->fast_access_save = -1;
1065 }
1066
1067 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
1068 /* but byte array represents target endianness */
1069 uint32_t *t = NULL;
1070 t = malloc(count * sizeof(uint32_t));
1071 if (t == NULL)
1072 {
1073 LOG_ERROR("Out of memory");
1074 return ERROR_FAIL;
1075 }
1076
1077 target_buffer_get_u32_array(target,buffer,count,t);
1078
1079 retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,
1080 count, t);
1081
1082 if (t != NULL)
1083 free(t);
1084
1085 if (retval != ERROR_OK)
1086 {
1087 /* FASTDATA access failed, try normal memory write */
1088 LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write");
1089 retval = mips_m4k_write_memory(target, address, 4, count, buffer);
1090 }
1091
1092 return retval;
1093 }
1094
1095 static int mips_m4k_verify_pointer(struct command_context *cmd_ctx,
1096 struct mips_m4k_common *mips_m4k)
1097 {
1098 if (mips_m4k->common_magic != MIPSM4K_COMMON_MAGIC) {
1099 command_print(cmd_ctx, "target is not an MIPS_M4K");
1100 return ERROR_TARGET_INVALID;
1101 }
1102 return ERROR_OK;
1103 }
1104
1105 COMMAND_HANDLER(mips_m4k_handle_cp0_command)
1106 {
1107 int retval;
1108 struct target *target = get_current_target(CMD_CTX);
1109 struct mips_m4k_common *mips_m4k = target_to_m4k(target);
1110 struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
1111
1112 retval = mips_m4k_verify_pointer(CMD_CTX, mips_m4k);
1113 if (retval != ERROR_OK)
1114 return retval;
1115
1116 if (target->state != TARGET_HALTED)
1117 {
1118 command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
1119 return ERROR_OK;
1120 }
1121
1122 /* two or more argument, access a single register/select (write if third argument is given) */
1123 if (CMD_ARGC < 2)
1124 {
1125 command_print(CMD_CTX, "command requires more arguments.");
1126 }
1127 else
1128 {
1129 uint32_t cp0_reg, cp0_sel;
1130 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
1131 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
1132
1133 if (CMD_ARGC == 2)
1134 {
1135 uint32_t value;
1136
1137 if ((retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel)) != ERROR_OK)
1138 {
1139 command_print(CMD_CTX,
1140 "couldn't access reg %" PRIi32,
1141 cp0_reg);
1142 return ERROR_OK;
1143 }
1144 if ((retval = jtag_execute_queue()) != ERROR_OK)
1145 {
1146 return retval;
1147 }
1148
1149 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
1150 cp0_reg, cp0_sel, value);
1151 }
1152 else if (CMD_ARGC == 3)
1153 {
1154 uint32_t value;
1155 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
1156 if ((retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel)) != ERROR_OK)
1157 {
1158 command_print(CMD_CTX,
1159 "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
1160 cp0_reg, cp0_sel);
1161 return ERROR_OK;
1162 }
1163 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
1164 cp0_reg, cp0_sel, value);
1165 }
1166 }
1167
1168 return ERROR_OK;
1169 }
1170
1171 static const struct command_registration mips_m4k_exec_command_handlers[] = {
1172 {
1173 .name = "cp0",
1174 .handler = mips_m4k_handle_cp0_command,
1175 .mode = COMMAND_EXEC,
1176 .usage = "regnum [value]",
1177 .help = "display/modify cp0 register",
1178 },
1179 COMMAND_REGISTRATION_DONE
1180 };
1181
1182 const struct command_registration mips_m4k_command_handlers[] = {
1183 {
1184 .chain = mips32_command_handlers,
1185 },
1186 {
1187 .name = "mips_m4k",
1188 .mode = COMMAND_ANY,
1189 .help = "mips_m4k command group",
1190 .chain = mips_m4k_exec_command_handlers,
1191 },
1192 COMMAND_REGISTRATION_DONE
1193 };
1194
1195 struct target_type mips_m4k_target =
1196 {
1197 .name = "mips_m4k",
1198
1199 .poll = mips_m4k_poll,
1200 .arch_state = mips32_arch_state,
1201
1202 .target_request_data = NULL,
1203
1204 .halt = mips_m4k_halt,
1205 .resume = mips_m4k_resume,
1206 .step = mips_m4k_step,
1207
1208 .assert_reset = mips_m4k_assert_reset,
1209 .deassert_reset = mips_m4k_deassert_reset,
1210 .soft_reset_halt = mips_m4k_soft_reset_halt,
1211
1212 .get_gdb_reg_list = mips32_get_gdb_reg_list,
1213
1214 .read_memory = mips_m4k_read_memory,
1215 .write_memory = mips_m4k_write_memory,
1216 .bulk_write_memory = mips_m4k_bulk_write_memory,
1217 .checksum_memory = mips32_checksum_memory,
1218 .blank_check_memory = mips32_blank_check_memory,
1219
1220 .run_algorithm = mips32_run_algorithm,
1221
1222 .add_breakpoint = mips_m4k_add_breakpoint,
1223 .remove_breakpoint = mips_m4k_remove_breakpoint,
1224 .add_watchpoint = mips_m4k_add_watchpoint,
1225 .remove_watchpoint = mips_m4k_remove_watchpoint,
1226
1227 .commands = mips_m4k_command_handlers,
1228 .target_create = mips_m4k_target_create,
1229 .init_target = mips_m4k_init_target,
1230 .examine = mips_m4k_examine,
1231 };

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)