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

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)