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

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)