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

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)