Add BCM2835 (as found in Raspberry Pi) interface driver
[openocd.git] / src / target / nds32_v2.c
1 /***************************************************************************
2 * Copyright (C) 2013 Andes Technology *
3 * Hsiangkai Wang <hkwang@andestech.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <helper/time_support.h>
26 #include <helper/binarybuffer.h>
27 #include "breakpoints.h"
28 #include "nds32_insn.h"
29 #include "nds32_reg.h"
30 #include "nds32_edm.h"
31 #include "nds32_cmd.h"
32 #include "nds32_v2.h"
33 #include "nds32_aice.h"
34 #include "target_type.h"
35
36 static int nds32_v2_register_mapping(struct nds32 *nds32, int reg_no)
37 {
38 uint32_t max_level = nds32->max_interrupt_level;
39 uint32_t cur_level = nds32->current_interrupt_level;
40
41 if ((1 <= cur_level) && (cur_level < max_level)) {
42 if (IR0 == reg_no) {
43 LOG_DEBUG("Map PSW to IPSW");
44 return IR1;
45 } else if (PC == reg_no) {
46 LOG_DEBUG("Map PC to IPC");
47 return IR9;
48 }
49 } else if ((2 <= cur_level) && (cur_level < max_level)) {
50 if (R26 == reg_no) {
51 LOG_DEBUG("Mapping P0 to P_P0");
52 return IR12;
53 } else if (R27 == reg_no) {
54 LOG_DEBUG("Mapping P1 to P_P1");
55 return IR13;
56 } else if (IR1 == reg_no) {
57 LOG_DEBUG("Mapping IPSW to P_IPSW");
58 return IR2;
59 } else if (IR4 == reg_no) {
60 LOG_DEBUG("Mapping EVA to P_EVA");
61 return IR5;
62 } else if (IR6 == reg_no) {
63 LOG_DEBUG("Mapping ITYPE to P_ITYPE");
64 return IR7;
65 } else if (IR9 == reg_no) {
66 LOG_DEBUG("Mapping IPC to P_IPC");
67 return IR10;
68 }
69 } else if (cur_level == max_level) {
70 if (PC == reg_no) {
71 LOG_DEBUG("Mapping PC to O_IPC");
72 return IR11;
73 }
74 }
75
76 return reg_no;
77 }
78
79 static int nds32_v2_get_debug_reason(struct nds32 *nds32, uint32_t *reason)
80 {
81 uint32_t val_itype;
82 struct aice_port_s *aice = target_to_aice(nds32->target);
83
84 aice_read_register(aice, IR6, &val_itype);
85
86 *reason = val_itype & 0x0F;
87
88 return ERROR_OK;
89 }
90
91 static int nds32_v2_activate_hardware_breakpoint(struct target *target)
92 {
93 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
94 struct aice_port_s *aice = target_to_aice(target);
95 struct breakpoint *bp;
96 int32_t hbr_index = 0;
97
98 for (bp = target->breakpoints; bp; bp = bp->next) {
99 if (bp->type == BKPT_SOFT) {
100 /* already set at nds32_v2_add_breakpoint() */
101 continue;
102 } else if (bp->type == BKPT_HARD) {
103 /* set address */
104 aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address);
105 /* set mask */
106 aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0);
107 /* set value */
108 aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0);
109
110 if (nds32_v2->nds32.memory.address_translation)
111 /* enable breakpoint (virtual address) */
112 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2);
113 else
114 /* enable breakpoint (physical address) */
115 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA);
116
117 LOG_DEBUG("Add hardware BP %d at %08" PRIx32, hbr_index,
118 bp->address);
119
120 hbr_index++;
121 } else {
122 return ERROR_FAIL;
123 }
124 }
125
126 return ERROR_OK;
127 }
128
129 static int nds32_v2_deactivate_hardware_breakpoint(struct target *target)
130 {
131 struct aice_port_s *aice = target_to_aice(target);
132 struct breakpoint *bp;
133 int32_t hbr_index = 0;
134
135 for (bp = target->breakpoints; bp; bp = bp->next) {
136 if (bp->type == BKPT_SOFT)
137 continue;
138 else if (bp->type == BKPT_HARD)
139 /* disable breakpoint */
140 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0);
141 else
142 return ERROR_FAIL;
143
144 LOG_DEBUG("Remove hardware BP %d at %08" PRIx32, hbr_index,
145 bp->address);
146
147 hbr_index++;
148 }
149
150 return ERROR_OK;
151 }
152
153 static int nds32_v2_activate_hardware_watchpoint(struct target *target)
154 {
155 struct aice_port_s *aice = target_to_aice(target);
156 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
157 struct watchpoint *wp;
158 int32_t wp_num = nds32_v2->next_hbr_index;
159 uint32_t wp_config = 0;
160
161 for (wp = target->watchpoints; wp; wp = wp->next) {
162
163 wp_num--;
164 wp->mask = wp->length - 1;
165 if ((wp->address % wp->length) != 0)
166 wp->mask = (wp->mask << 1) + 1;
167
168 if (wp->rw == WPT_READ)
169 wp_config = 0x3;
170 else if (wp->rw == WPT_WRITE)
171 wp_config = 0x5;
172 else if (wp->rw == WPT_ACCESS)
173 wp_config = 0x7;
174
175 /* set/unset physical address bit of BPCn according to PSW.DT */
176 if (nds32_v2->nds32.memory.address_translation == false)
177 wp_config |= 0x8;
178
179 /* set address */
180 aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num,
181 wp->address - (wp->address % wp->length));
182 /* set mask */
183 aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask);
184 /* enable watchpoint */
185 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config);
186 /* set value */
187 aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0);
188
189 LOG_DEBUG("Add hardware wathcpoint %d at %08" PRIx32 " mask %08" PRIx32, wp_num,
190 wp->address, wp->mask);
191
192 }
193
194 return ERROR_OK;
195 }
196
197 static int nds32_v2_deactivate_hardware_watchpoint(struct target *target)
198 {
199 struct aice_port_s *aice = target_to_aice(target);
200 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
201 int32_t wp_num = nds32_v2->next_hbr_index;
202 struct watchpoint *wp;
203
204 for (wp = target->watchpoints; wp; wp = wp->next) {
205 wp_num--;
206 /* disable watchpoint */
207 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0);
208
209 LOG_DEBUG("Remove hardware wathcpoint %d at %08" PRIx32 " mask %08" PRIx32,
210 wp_num, wp->address, wp->mask);
211 }
212
213 return ERROR_OK;
214 }
215
216 static int nds32_v2_check_interrupt_stack(struct nds32_v2_common *nds32_v2)
217 {
218 struct nds32 *nds32 = &(nds32_v2->nds32);
219 struct aice_port_s *aice = target_to_aice(nds32->target);
220 uint32_t val_ir0;
221 uint32_t val_ir1;
222 uint32_t val_ir2;
223 uint32_t modified_psw;
224
225 /* Save interrupt level */
226 aice_read_register(aice, IR0, &val_ir0); /* get $IR0 directly */
227
228 /* backup $IR0 */
229 nds32_v2->backup_ir0 = val_ir0;
230
231 nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3;
232
233 if (nds32_reach_max_interrupt_level(nds32)) {
234 LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %d. -->",
235 nds32->current_interrupt_level);
236
237 /* decrease interrupt level */
238 modified_psw = val_ir0 - 0x2;
239
240 /* disable GIE, IT, DT, HSS */
241 modified_psw &= (~0x8C1);
242
243 aice_write_register(aice, IR0, modified_psw);
244
245 return ERROR_OK;
246 }
247
248
249 /* There is a case that single step also trigger another interrupt,
250 then HSS bit in psw(ir0) will push to ipsw(ir1).
251 Then hit debug interrupt HSS bit in ipsw(ir1) will push to (p_ipsw)ir2
252 Therefore, HSS bit in p_ipsw(ir2) also need clear.
253
254 Only update $ir2 as current interrupt level is 2, because $ir2 will be random
255 value if the target never reaches interrupt level 2. */
256 if ((nds32->max_interrupt_level == 3) && (nds32->current_interrupt_level == 2)) {
257 aice_read_register(aice, IR2, &val_ir2); /* get $IR2 directly */
258 val_ir2 &= ~(0x01 << 11);
259 aice_write_register(aice, IR2, val_ir2);
260 }
261
262 /* get origianl DT bit and set to current state let debugger has same memory view
263 PSW.IT MUST be turned off. Otherwise, DIM could not operate normally. */
264 aice_read_register(aice, IR1, &val_ir1);
265 modified_psw = val_ir0 | (val_ir1 & 0x80);
266 aice_write_register(aice, IR0, modified_psw);
267
268 return ERROR_OK;
269 }
270
271 static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common *nds32_v2)
272 {
273 struct nds32 *nds32 = &(nds32_v2->nds32);
274 struct aice_port_s *aice = target_to_aice(nds32->target);
275
276 /* restore origin $IR0 */
277 aice_write_register(aice, IR0, nds32_v2->backup_ir0);
278
279 return ERROR_OK;
280 }
281
282 /**
283 * Save processor state. This is called after a HALT instruction
284 * succeeds, and on other occasions the processor enters debug mode
285 * (breakpoint, watchpoint, etc).
286 */
287 static int nds32_v2_debug_entry(struct nds32 *nds32, bool enable_watchpoint)
288 {
289 LOG_DEBUG("nds32_v2_debug_entry");
290
291 jtag_poll_set_enabled(false);
292
293 if (nds32->virtual_hosting)
294 LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported "
295 "under V1/V2 architecture. -->");
296
297 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
298
299 CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32->target));
300
301 if (enable_watchpoint)
302 CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32->target));
303
304 nds32->target->state = TARGET_HALTED;
305 nds32_examine_debug_reason(nds32);
306
307 if (nds32->init_arch_info_after_halted == false) {
308 /* init architecture info according to config registers */
309 CHECK_RETVAL(nds32_config(nds32));
310
311 nds32->init_arch_info_after_halted = true;
312 }
313
314 /* REVISIT entire cache should already be invalid !!! */
315 register_cache_invalidate(nds32->core_cache);
316
317 /* check interrupt level before .full_context(), because
318 * get_mapped_reg needs current_interrupt_level information */
319 nds32_v2_check_interrupt_stack(nds32_v2);
320
321 /* Save registers. */
322 nds32_full_context(nds32);
323
324 return ERROR_OK;
325 }
326
327 /* target request support */
328 static int nds32_v2_target_request_data(struct target *target,
329 uint32_t size, uint8_t *buffer)
330 {
331 /* AndesCore could use DTR register to communicate with OpenOCD
332 * to output messages
333 * Target data will be put in buffer
334 * The format of DTR is as follow
335 * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
336 * target_req_cmd has three possible values:
337 * TARGET_REQ_TRACEMSG
338 * TARGET_REQ_DEBUGMSG
339 * TARGET_REQ_DEBUGCHAR
340 * if size == 0, target will call target_asciimsg(),
341 * else call target_hexmsg()
342 */
343 LOG_WARNING("Not implemented: %s", __func__);
344
345 return ERROR_OK;
346 }
347
348 /**
349 * Restore processor state.
350 */
351 static int nds32_v2_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint)
352 {
353 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
354
355 /* activate all hardware breakpoints */
356 CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
357
358 if (enable_watchpoint) {
359 /* activate all watchpoints */
360 CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
361 }
362
363 /* restore interrupt stack */
364 nds32_v2_restore_interrupt_stack(nds32_v2);
365
366 /* restore PSW, PC, and R0 ... after flushing any modified
367 * registers.
368 */
369 CHECK_RETVAL(nds32_restore_context(nds32->target));
370
371 register_cache_invalidate(nds32->core_cache);
372
373 jtag_poll_set_enabled(true);
374
375 return ERROR_OK;
376 }
377
378 static int nds32_v2_soft_reset_halt(struct target *target)
379 {
380 /* TODO: test it */
381 struct nds32 *nds32 = target_to_nds32(target);
382 struct aice_port_s *aice = target_to_aice(target);
383
384 aice_assert_srst(aice, AICE_SRST);
385
386 /* halt core and set pc to 0x0 */
387 int retval = target_halt(target);
388 if (retval != ERROR_OK)
389 return retval;
390
391 /* start fetching from IVB */
392 uint32_t value_ir3;
393 nds32_get_mapped_reg(nds32, IR3, &value_ir3);
394 nds32_set_mapped_reg(nds32, PC, value_ir3 & 0xFFFF0000);
395
396 return ERROR_OK;
397 }
398
399 static int nds32_v2_deassert_reset(struct target *target)
400 {
401 int retval;
402
403 CHECK_RETVAL(nds32_poll(target));
404
405 if (target->state != TARGET_HALTED) {
406 /* reset only */
407 LOG_WARNING("%s: ran after reset and before halt ...",
408 target_name(target));
409 retval = target_halt(target);
410 if (retval != ERROR_OK)
411 return retval;
412 /* call target_poll() to avoid "Halt timed out" */
413 CHECK_RETVAL(target_poll(target));
414 } else {
415 jtag_poll_set_enabled(false);
416 }
417
418 return ERROR_OK;
419 }
420
421 static int nds32_v2_checksum_memory(struct target *target,
422 uint32_t address, uint32_t count, uint32_t *checksum)
423 {
424 LOG_WARNING("Not implemented: %s", __func__);
425
426 return ERROR_FAIL;
427 }
428
429 static int nds32_v2_add_breakpoint(struct target *target,
430 struct breakpoint *breakpoint)
431 {
432 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
433 struct nds32 *nds32 = &(nds32_v2->nds32);
434 int result;
435
436 if (breakpoint->type == BKPT_HARD) {
437 /* check hardware resource */
438 if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
439 LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
440 "breakpoints/watchpoints! The limit of "
441 "combined hardware breakpoints/watchpoints "
442 "is %d. -->", nds32_v2->n_hbr);
443 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
444 }
445
446 /* update next place to put hardware breakpoint */
447 nds32_v2->next_hbr_index++;
448
449 /* hardware breakpoint insertion occurs before 'continue' actually */
450 return ERROR_OK;
451 } else if (breakpoint->type == BKPT_SOFT) {
452 result = nds32_add_software_breakpoint(target, breakpoint);
453 if (ERROR_OK != result) {
454 /* auto convert to hardware breakpoint if failed */
455 if (nds32->auto_convert_hw_bp) {
456 /* convert to hardware breakpoint */
457 breakpoint->type = BKPT_HARD;
458
459 return nds32_v2_add_breakpoint(target, breakpoint);
460 }
461 }
462
463 return result;
464 } else /* unrecognized breakpoint type */
465 return ERROR_FAIL;
466
467 return ERROR_OK;
468 }
469
470 static int nds32_v2_remove_breakpoint(struct target *target,
471 struct breakpoint *breakpoint)
472 {
473 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
474
475 if (breakpoint->type == BKPT_HARD) {
476 if (nds32_v2->next_hbr_index <= 0)
477 return ERROR_FAIL;
478
479 /* update next place to put hardware breakpoint */
480 nds32_v2->next_hbr_index--;
481
482 /* hardware breakpoint removal occurs after 'halted' actually */
483 return ERROR_OK;
484 } else if (breakpoint->type == BKPT_SOFT) {
485 return nds32_remove_software_breakpoint(target, breakpoint);
486 } else /* unrecognized breakpoint type */
487 return ERROR_FAIL;
488
489 return ERROR_OK;
490 }
491
492 static int nds32_v2_add_watchpoint(struct target *target,
493 struct watchpoint *watchpoint)
494 {
495 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
496
497 /* check hardware resource */
498 if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
499 LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
500 "breakpoints/watchpoints! The limit of "
501 "combined hardware breakpoints/watchpoints is %d. -->", nds32_v2->n_hbr);
502 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
503 }
504
505 /* update next place to put hardware watchpoint */
506 nds32_v2->next_hbr_index++;
507
508 return ERROR_OK;
509 }
510
511 static int nds32_v2_remove_watchpoint(struct target *target,
512 struct watchpoint *watchpoint)
513 {
514 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
515
516 if (nds32_v2->next_hbr_index <= 0)
517 return ERROR_FAIL;
518
519 /* update next place to put hardware breakpoint */
520 nds32_v2->next_hbr_index--;
521
522 return ERROR_OK;
523 }
524
525 static int nds32_v2_get_exception_address(struct nds32 *nds32,
526 uint32_t *address, uint32_t reason)
527 {
528 struct aice_port_s *aice = target_to_aice(nds32->target);
529
530 aice_read_register(aice, IR4, address); /* read $EVA directly */
531
532 /* TODO: hit multiple watchpoints */
533
534 return ERROR_OK;
535 }
536
537 static int nds32_v2_run_algorithm(struct target *target,
538 int num_mem_params,
539 struct mem_param *mem_params,
540 int num_reg_params,
541 struct reg_param *reg_params,
542 uint32_t entry_point,
543 uint32_t exit_point,
544 int timeout_ms,
545 void *arch_info)
546 {
547 LOG_WARNING("Not implemented: %s", __func__);
548
549 return ERROR_FAIL;
550 }
551
552 static int nds32_v2_target_create(struct target *target, Jim_Interp *interp)
553 {
554 struct nds32_v2_common *nds32_v2;
555
556 nds32_v2 = calloc(1, sizeof(*nds32_v2));
557 if (!nds32_v2)
558 return ERROR_FAIL;
559
560 nds32_v2->nds32.register_map = nds32_v2_register_mapping;
561 nds32_v2->nds32.get_debug_reason = nds32_v2_get_debug_reason;
562 nds32_v2->nds32.enter_debug_state = nds32_v2_debug_entry;
563 nds32_v2->nds32.leave_debug_state = nds32_v2_leave_debug_state;
564 nds32_v2->nds32.get_watched_address = nds32_v2_get_exception_address;
565
566 nds32_init_arch_info(target, &(nds32_v2->nds32));
567
568 return ERROR_OK;
569 }
570
571 static int nds32_v2_init_target(struct command_context *cmd_ctx,
572 struct target *target)
573 {
574 /* Initialize anything we can set up without talking to the target */
575
576 struct nds32 *nds32 = target_to_nds32(target);
577
578 nds32_init(nds32);
579
580 return ERROR_OK;
581 }
582
583 /* talk to the target and set things up */
584 static int nds32_v2_examine(struct target *target)
585 {
586 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
587 struct nds32 *nds32 = &(nds32_v2->nds32);
588 struct aice_port_s *aice = target_to_aice(target);
589
590 if (!target_was_examined(target)) {
591 CHECK_RETVAL(nds32_edm_config(nds32));
592
593 if (nds32->reset_halt_as_examine)
594 CHECK_RETVAL(nds32_reset_halt(nds32));
595 }
596
597 uint32_t edm_cfg;
598 aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
599
600 /* get the number of hardware breakpoints */
601 nds32_v2->n_hbr = (edm_cfg & 0x7) + 1;
602
603 nds32_v2->next_hbr_index = 0;
604
605 LOG_INFO("%s: total hardware breakpoint %d", target_name(target),
606 nds32_v2->n_hbr);
607
608 nds32->target->state = TARGET_RUNNING;
609 nds32->target->debug_reason = DBG_REASON_NOTHALTED;
610
611 target_set_examined(target);
612
613 return ERROR_OK;
614 }
615
616 static int nds32_v2_translate_address(struct target *target, uint32_t *address)
617 {
618 struct nds32 *nds32 = target_to_nds32(target);
619 struct nds32_memory *memory = &(nds32->memory);
620 uint32_t physical_address;
621
622 /* Following conditions need to do address translation
623 * 1. BUS mode
624 * 2. CPU mode under maximum interrupt level */
625 if ((NDS_MEMORY_ACC_BUS == memory->access_channel) ||
626 ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
627 nds32_reach_max_interrupt_level(nds32))) {
628 if (ERROR_OK == target->type->virt2phys(target, *address, &physical_address))
629 *address = physical_address;
630 else
631 return ERROR_FAIL;
632 }
633
634 return ERROR_OK;
635 }
636
637 static int nds32_v2_read_buffer(struct target *target, uint32_t address,
638 uint32_t size, uint8_t *buffer)
639 {
640 struct nds32 *nds32 = target_to_nds32(target);
641 struct nds32_memory *memory = &(nds32->memory);
642
643 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
644 (target->state != TARGET_HALTED)) {
645 LOG_WARNING("target was not halted");
646 return ERROR_TARGET_NOT_HALTED;
647 }
648
649 /* BUG: If access range crosses multiple pages, the translation will not correct
650 * for second page or so. */
651
652 nds32_v2_translate_address(target, &address);
653
654 return nds32_read_buffer(target, address, size, buffer);
655 }
656
657 static int nds32_v2_write_buffer(struct target *target, uint32_t address,
658 uint32_t size, const uint8_t *buffer)
659 {
660 struct nds32 *nds32 = target_to_nds32(target);
661 struct nds32_memory *memory = &(nds32->memory);
662
663 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
664 (target->state != TARGET_HALTED)) {
665 LOG_WARNING("target was not halted");
666 return ERROR_TARGET_NOT_HALTED;
667 }
668
669 /* BUG: If access range crosses multiple pages, the translation will not correct
670 * for second page or so. */
671
672 nds32_v2_translate_address(target, &address);
673
674 return nds32_write_buffer(target, address, size, buffer);
675 }
676
677 static int nds32_v2_read_memory(struct target *target, uint32_t address,
678 uint32_t size, uint32_t count, uint8_t *buffer)
679 {
680 struct nds32 *nds32 = target_to_nds32(target);
681 struct nds32_memory *memory = &(nds32->memory);
682
683 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
684 (target->state != TARGET_HALTED)) {
685 LOG_WARNING("target was not halted");
686 return ERROR_TARGET_NOT_HALTED;
687 }
688
689 /* BUG: If access range crosses multiple pages, the translation will not correct
690 * for second page or so. */
691
692 nds32_v2_translate_address(target, &address);
693
694 return nds32_read_memory(target, address, size, count, buffer);
695 }
696
697 static int nds32_v2_write_memory(struct target *target, uint32_t address,
698 uint32_t size, uint32_t count, const uint8_t *buffer)
699 {
700 struct nds32 *nds32 = target_to_nds32(target);
701 struct nds32_memory *memory = &(nds32->memory);
702
703 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
704 (target->state != TARGET_HALTED)) {
705 LOG_WARNING("target was not halted");
706 return ERROR_TARGET_NOT_HALTED;
707 }
708
709 /* BUG: If access range crosses multiple pages, the translation will not correct
710 * for second page or so. */
711
712 nds32_v2_translate_address(target, &address);
713
714 return nds32_write_memory(target, address, size, count, buffer);
715 }
716
717 /** Holds methods for V2 targets. */
718 struct target_type nds32_v2_target = {
719 .name = "nds32_v2",
720
721 .poll = nds32_poll,
722 .arch_state = nds32_arch_state,
723
724 .target_request_data = nds32_v2_target_request_data,
725
726 .halt = nds32_halt,
727 .resume = nds32_resume,
728 .step = nds32_step,
729
730 .assert_reset = nds32_assert_reset,
731 .deassert_reset = nds32_v2_deassert_reset,
732 .soft_reset_halt = nds32_v2_soft_reset_halt,
733
734 /* register access */
735 .get_gdb_reg_list = nds32_get_gdb_reg_list,
736
737 /* memory access */
738 .read_buffer = nds32_v2_read_buffer,
739 .write_buffer = nds32_v2_write_buffer,
740 .read_memory = nds32_v2_read_memory,
741 .write_memory = nds32_v2_write_memory,
742
743 .checksum_memory = nds32_v2_checksum_memory,
744
745 /* breakpoint/watchpoint */
746 .add_breakpoint = nds32_v2_add_breakpoint,
747 .remove_breakpoint = nds32_v2_remove_breakpoint,
748 .add_watchpoint = nds32_v2_add_watchpoint,
749 .remove_watchpoint = nds32_v2_remove_watchpoint,
750
751 /* MMU */
752 .mmu = nds32_mmu,
753 .virt2phys = nds32_virtual_to_physical,
754 .read_phys_memory = nds32_read_phys_memory,
755 .write_phys_memory = nds32_write_phys_memory,
756
757 .run_algorithm = nds32_v2_run_algorithm,
758
759 .commands = nds32_command_handlers,
760 .target_create = nds32_v2_target_create,
761 .init_target = nds32_v2_init_target,
762 .examine = nds32_v2_examine,
763 };

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)