Add RISC-V support.
[openocd.git] / src / target / nds32_v2.c
blob29489a0341c6ff707eb1e2420c46868eaf495acb
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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
23 #include <helper/time_support.h>
24 #include <helper/binarybuffer.h>
25 #include "breakpoints.h"
26 #include "nds32_insn.h"
27 #include "nds32_reg.h"
28 #include "nds32_edm.h"
29 #include "nds32_cmd.h"
30 #include "nds32_v2.h"
31 #include "nds32_aice.h"
32 #include "target_type.h"
34 static int nds32_v2_register_mapping(struct nds32 *nds32, int reg_no)
36 uint32_t max_level = nds32->max_interrupt_level;
37 uint32_t cur_level = nds32->current_interrupt_level;
39 if ((1 <= cur_level) && (cur_level < max_level)) {
40 if (IR0 == reg_no) {
41 LOG_DEBUG("Map PSW to IPSW");
42 return IR1;
43 } else if (PC == reg_no) {
44 LOG_DEBUG("Map PC to IPC");
45 return IR9;
47 } else if ((2 <= cur_level) && (cur_level < max_level)) {
48 if (R26 == reg_no) {
49 LOG_DEBUG("Mapping P0 to P_P0");
50 return IR12;
51 } else if (R27 == reg_no) {
52 LOG_DEBUG("Mapping P1 to P_P1");
53 return IR13;
54 } else if (IR1 == reg_no) {
55 LOG_DEBUG("Mapping IPSW to P_IPSW");
56 return IR2;
57 } else if (IR4 == reg_no) {
58 LOG_DEBUG("Mapping EVA to P_EVA");
59 return IR5;
60 } else if (IR6 == reg_no) {
61 LOG_DEBUG("Mapping ITYPE to P_ITYPE");
62 return IR7;
63 } else if (IR9 == reg_no) {
64 LOG_DEBUG("Mapping IPC to P_IPC");
65 return IR10;
67 } else if (cur_level == max_level) {
68 if (PC == reg_no) {
69 LOG_DEBUG("Mapping PC to O_IPC");
70 return IR11;
74 return reg_no;
77 static int nds32_v2_get_debug_reason(struct nds32 *nds32, uint32_t *reason)
79 uint32_t val_itype;
80 struct aice_port_s *aice = target_to_aice(nds32->target);
82 aice_read_register(aice, IR6, &val_itype);
84 *reason = val_itype & 0x0F;
86 return ERROR_OK;
89 static int nds32_v2_activate_hardware_breakpoint(struct target *target)
91 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
92 struct aice_port_s *aice = target_to_aice(target);
93 struct breakpoint *bp;
94 int32_t hbr_index = 0;
96 for (bp = target->breakpoints; bp; bp = bp->next) {
97 if (bp->type == BKPT_SOFT) {
98 /* already set at nds32_v2_add_breakpoint() */
99 continue;
100 } else if (bp->type == BKPT_HARD) {
101 /* set address */
102 aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address);
103 /* set mask */
104 aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0);
105 /* set value */
106 aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0);
108 if (nds32_v2->nds32.memory.address_translation)
109 /* enable breakpoint (virtual address) */
110 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2);
111 else
112 /* enable breakpoint (physical address) */
113 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA);
115 LOG_DEBUG("Add hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
116 bp->address);
118 hbr_index++;
119 } else {
120 return ERROR_FAIL;
124 return ERROR_OK;
127 static int nds32_v2_deactivate_hardware_breakpoint(struct target *target)
129 struct aice_port_s *aice = target_to_aice(target);
130 struct breakpoint *bp;
131 int32_t hbr_index = 0;
133 for (bp = target->breakpoints; bp; bp = bp->next) {
134 if (bp->type == BKPT_SOFT)
135 continue;
136 else if (bp->type == BKPT_HARD)
137 /* disable breakpoint */
138 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0);
139 else
140 return ERROR_FAIL;
142 LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index,
143 bp->address);
145 hbr_index++;
148 return ERROR_OK;
151 static int nds32_v2_activate_hardware_watchpoint(struct target *target)
153 struct aice_port_s *aice = target_to_aice(target);
154 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
155 struct watchpoint *wp;
156 int32_t wp_num = nds32_v2->next_hbr_index;
157 uint32_t wp_config = 0;
159 for (wp = target->watchpoints; wp; wp = wp->next) {
161 wp_num--;
162 wp->mask = wp->length - 1;
163 if ((wp->address % wp->length) != 0)
164 wp->mask = (wp->mask << 1) + 1;
166 if (wp->rw == WPT_READ)
167 wp_config = 0x3;
168 else if (wp->rw == WPT_WRITE)
169 wp_config = 0x5;
170 else if (wp->rw == WPT_ACCESS)
171 wp_config = 0x7;
173 /* set/unset physical address bit of BPCn according to PSW.DT */
174 if (nds32_v2->nds32.memory.address_translation == false)
175 wp_config |= 0x8;
177 /* set address */
178 aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num,
179 wp->address - (wp->address % wp->length));
180 /* set mask */
181 aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask);
182 /* enable watchpoint */
183 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config);
184 /* set value */
185 aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0);
187 LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32, wp_num,
188 wp->address, wp->mask);
192 return ERROR_OK;
195 static int nds32_v2_deactivate_hardware_watchpoint(struct target *target)
197 struct aice_port_s *aice = target_to_aice(target);
198 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
199 int32_t wp_num = nds32_v2->next_hbr_index;
200 struct watchpoint *wp;
202 for (wp = target->watchpoints; wp; wp = wp->next) {
203 wp_num--;
204 /* disable watchpoint */
205 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0);
207 LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32,
208 wp_num, wp->address, wp->mask);
211 return ERROR_OK;
214 static int nds32_v2_check_interrupt_stack(struct nds32_v2_common *nds32_v2)
216 struct nds32 *nds32 = &(nds32_v2->nds32);
217 struct aice_port_s *aice = target_to_aice(nds32->target);
218 uint32_t val_ir0;
219 uint32_t val_ir1;
220 uint32_t val_ir2;
221 uint32_t modified_psw;
223 /* Save interrupt level */
224 aice_read_register(aice, IR0, &val_ir0); /* get $IR0 directly */
226 /* backup $IR0 */
227 nds32_v2->backup_ir0 = val_ir0;
229 nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3;
231 if (nds32_reach_max_interrupt_level(nds32)) {
232 LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->",
233 nds32->current_interrupt_level);
235 /* decrease interrupt level */
236 modified_psw = val_ir0 - 0x2;
238 /* disable GIE, IT, DT, HSS */
239 modified_psw &= (~0x8C1);
241 aice_write_register(aice, IR0, modified_psw);
243 return ERROR_OK;
246 /* There is a case that single step also trigger another interrupt,
247 then HSS bit in psw(ir0) will push to ipsw(ir1).
248 Then hit debug interrupt HSS bit in ipsw(ir1) will push to (p_ipsw)ir2
249 Therefore, HSS bit in p_ipsw(ir2) also need clear.
251 Only update $ir2 as current interrupt level is 2, because $ir2 will be random
252 value if the target never reaches interrupt level 2. */
253 if ((nds32->max_interrupt_level == 3) && (nds32->current_interrupt_level == 2)) {
254 aice_read_register(aice, IR2, &val_ir2); /* get $IR2 directly */
255 val_ir2 &= ~(0x01 << 11);
256 aice_write_register(aice, IR2, val_ir2);
259 /* get origianl DT bit and set to current state let debugger has same memory view
260 PSW.IT MUST be turned off. Otherwise, DIM could not operate normally. */
261 aice_read_register(aice, IR1, &val_ir1);
262 modified_psw = val_ir0 | (val_ir1 & 0x80);
263 aice_write_register(aice, IR0, modified_psw);
265 return ERROR_OK;
268 static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common *nds32_v2)
270 struct nds32 *nds32 = &(nds32_v2->nds32);
271 struct aice_port_s *aice = target_to_aice(nds32->target);
273 /* restore origin $IR0 */
274 aice_write_register(aice, IR0, nds32_v2->backup_ir0);
276 return ERROR_OK;
280 * Save processor state. This is called after a HALT instruction
281 * succeeds, and on other occasions the processor enters debug mode
282 * (breakpoint, watchpoint, etc).
284 static int nds32_v2_debug_entry(struct nds32 *nds32, bool enable_watchpoint)
286 LOG_DEBUG("nds32_v2_debug_entry");
288 if (nds32->virtual_hosting)
289 LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported "
290 "under V1/V2 architecture. -->");
292 enum target_state backup_state = nds32->target->state;
293 nds32->target->state = TARGET_HALTED;
295 if (nds32->init_arch_info_after_halted == false) {
296 /* init architecture info according to config registers */
297 CHECK_RETVAL(nds32_config(nds32));
299 nds32->init_arch_info_after_halted = true;
302 /* REVISIT entire cache should already be invalid !!! */
303 register_cache_invalidate(nds32->core_cache);
305 /* deactivate all hardware breakpoints */
306 CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32->target));
308 if (enable_watchpoint)
309 CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32->target));
311 if (ERROR_OK != nds32_examine_debug_reason(nds32)) {
312 nds32->target->state = backup_state;
314 /* re-activate all hardware breakpoints & watchpoints */
315 CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
317 if (enable_watchpoint) {
318 /* activate all watchpoints */
319 CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
322 return ERROR_FAIL;
325 /* check interrupt level before .full_context(), because
326 * get_mapped_reg() in nds32_full_context() needs current_interrupt_level
327 * information */
328 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
329 nds32_v2_check_interrupt_stack(nds32_v2);
331 /* Save registers. */
332 nds32_full_context(nds32);
334 return ERROR_OK;
337 /* target request support */
338 static int nds32_v2_target_request_data(struct target *target,
339 uint32_t size, uint8_t *buffer)
341 /* AndesCore could use DTR register to communicate with OpenOCD
342 * to output messages
343 * Target data will be put in buffer
344 * The format of DTR is as follow
345 * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
346 * target_req_cmd has three possible values:
347 * TARGET_REQ_TRACEMSG
348 * TARGET_REQ_DEBUGMSG
349 * TARGET_REQ_DEBUGCHAR
350 * if size == 0, target will call target_asciimsg(),
351 * else call target_hexmsg()
353 LOG_WARNING("Not implemented: %s", __func__);
355 return ERROR_OK;
359 * Restore processor state.
361 static int nds32_v2_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint)
363 LOG_DEBUG("nds32_v2_leave_debug_state");
365 struct target *target = nds32->target;
367 /* activate all hardware breakpoints */
368 CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
370 if (enable_watchpoint) {
371 /* activate all watchpoints */
372 CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
375 /* restore interrupt stack */
376 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
377 nds32_v2_restore_interrupt_stack(nds32_v2);
379 /* restore PSW, PC, and R0 ... after flushing any modified
380 * registers.
382 CHECK_RETVAL(nds32_restore_context(target));
384 register_cache_invalidate(nds32->core_cache);
386 return ERROR_OK;
389 static int nds32_v2_deassert_reset(struct target *target)
391 int retval;
393 CHECK_RETVAL(nds32_poll(target));
395 if (target->state != TARGET_HALTED) {
396 /* reset only */
397 LOG_WARNING("%s: ran after reset and before halt ...",
398 target_name(target));
399 retval = target_halt(target);
400 if (retval != ERROR_OK)
401 return retval;
404 return ERROR_OK;
407 static int nds32_v2_checksum_memory(struct target *target,
408 target_addr_t address, uint32_t count, uint32_t *checksum)
410 LOG_WARNING("Not implemented: %s", __func__);
412 return ERROR_FAIL;
415 static int nds32_v2_add_breakpoint(struct target *target,
416 struct breakpoint *breakpoint)
418 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
419 struct nds32 *nds32 = &(nds32_v2->nds32);
420 int result;
422 if (breakpoint->type == BKPT_HARD) {
423 /* check hardware resource */
424 if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
425 LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
426 "breakpoints/watchpoints! The limit of "
427 "combined hardware breakpoints/watchpoints "
428 "is %" PRId32 ". -->", nds32_v2->n_hbr);
429 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
432 /* update next place to put hardware breakpoint */
433 nds32_v2->next_hbr_index++;
435 /* hardware breakpoint insertion occurs before 'continue' actually */
436 return ERROR_OK;
437 } else if (breakpoint->type == BKPT_SOFT) {
438 result = nds32_add_software_breakpoint(target, breakpoint);
439 if (ERROR_OK != result) {
440 /* auto convert to hardware breakpoint if failed */
441 if (nds32->auto_convert_hw_bp) {
442 /* convert to hardware breakpoint */
443 breakpoint->type = BKPT_HARD;
445 return nds32_v2_add_breakpoint(target, breakpoint);
449 return result;
450 } else /* unrecognized breakpoint type */
451 return ERROR_FAIL;
453 return ERROR_OK;
456 static int nds32_v2_remove_breakpoint(struct target *target,
457 struct breakpoint *breakpoint)
459 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
461 if (breakpoint->type == BKPT_HARD) {
462 if (nds32_v2->next_hbr_index <= 0)
463 return ERROR_FAIL;
465 /* update next place to put hardware breakpoint */
466 nds32_v2->next_hbr_index--;
468 /* hardware breakpoint removal occurs after 'halted' actually */
469 return ERROR_OK;
470 } else if (breakpoint->type == BKPT_SOFT) {
471 return nds32_remove_software_breakpoint(target, breakpoint);
472 } else /* unrecognized breakpoint type */
473 return ERROR_FAIL;
475 return ERROR_OK;
478 static int nds32_v2_add_watchpoint(struct target *target,
479 struct watchpoint *watchpoint)
481 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
483 /* check hardware resource */
484 if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
485 LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
486 "breakpoints/watchpoints! The limit of "
487 "combined hardware breakpoints/watchpoints is %" PRId32 ". -->", nds32_v2->n_hbr);
488 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
491 /* update next place to put hardware watchpoint */
492 nds32_v2->next_hbr_index++;
494 return ERROR_OK;
497 static int nds32_v2_remove_watchpoint(struct target *target,
498 struct watchpoint *watchpoint)
500 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
502 if (nds32_v2->next_hbr_index <= 0)
503 return ERROR_FAIL;
505 /* update next place to put hardware breakpoint */
506 nds32_v2->next_hbr_index--;
508 return ERROR_OK;
511 static int nds32_v2_get_exception_address(struct nds32 *nds32,
512 uint32_t *address, uint32_t reason)
514 struct aice_port_s *aice = target_to_aice(nds32->target);
516 aice_read_register(aice, IR4, address); /* read $EVA directly */
518 /* TODO: hit multiple watchpoints */
520 return ERROR_OK;
524 * find out which watchpoint hits
525 * get exception address and compare the address to watchpoints
527 static int nds32_v2_hit_watchpoint(struct target *target,
528 struct watchpoint **hit_watchpoint)
530 uint32_t exception_address;
531 struct watchpoint *wp;
532 static struct watchpoint scan_all_watchpoint;
533 struct nds32 *nds32 = target_to_nds32(target);
535 scan_all_watchpoint.address = 0;
536 scan_all_watchpoint.rw = WPT_WRITE;
537 scan_all_watchpoint.next = 0;
538 scan_all_watchpoint.unique_id = 0x5CA8;
540 exception_address = nds32->watched_address;
542 if (exception_address == 0) {
543 /* send watch:0 to tell GDB to do software scan for hitting multiple watchpoints */
544 *hit_watchpoint = &scan_all_watchpoint;
545 return ERROR_OK;
548 for (wp = target->watchpoints; wp; wp = wp->next) {
549 if (((exception_address ^ wp->address) & (~wp->mask)) == 0) {
550 /* TODO: dispel false match */
551 *hit_watchpoint = wp;
552 return ERROR_OK;
556 return ERROR_FAIL;
559 static int nds32_v2_run_algorithm(struct target *target,
560 int num_mem_params,
561 struct mem_param *mem_params,
562 int num_reg_params,
563 struct reg_param *reg_params,
564 target_addr_t entry_point,
565 target_addr_t exit_point,
566 int timeout_ms,
567 void *arch_info)
569 LOG_WARNING("Not implemented: %s", __func__);
571 return ERROR_FAIL;
574 static int nds32_v2_target_create(struct target *target, Jim_Interp *interp)
576 struct nds32_v2_common *nds32_v2;
578 nds32_v2 = calloc(1, sizeof(*nds32_v2));
579 if (!nds32_v2)
580 return ERROR_FAIL;
582 nds32_v2->nds32.register_map = nds32_v2_register_mapping;
583 nds32_v2->nds32.get_debug_reason = nds32_v2_get_debug_reason;
584 nds32_v2->nds32.enter_debug_state = nds32_v2_debug_entry;
585 nds32_v2->nds32.leave_debug_state = nds32_v2_leave_debug_state;
586 nds32_v2->nds32.get_watched_address = nds32_v2_get_exception_address;
588 nds32_init_arch_info(target, &(nds32_v2->nds32));
590 return ERROR_OK;
593 static int nds32_v2_init_target(struct command_context *cmd_ctx,
594 struct target *target)
596 /* Initialize anything we can set up without talking to the target */
598 struct nds32 *nds32 = target_to_nds32(target);
600 nds32_init(nds32);
602 return ERROR_OK;
605 /* talk to the target and set things up */
606 static int nds32_v2_examine(struct target *target)
608 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
609 struct nds32 *nds32 = &(nds32_v2->nds32);
610 struct aice_port_s *aice = target_to_aice(target);
612 if (!target_was_examined(target)) {
613 CHECK_RETVAL(nds32_edm_config(nds32));
615 if (nds32->reset_halt_as_examine)
616 CHECK_RETVAL(nds32_reset_halt(nds32));
619 uint32_t edm_cfg;
620 aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
622 /* get the number of hardware breakpoints */
623 nds32_v2->n_hbr = (edm_cfg & 0x7) + 1;
625 nds32_v2->next_hbr_index = 0;
627 LOG_INFO("%s: total hardware breakpoint %" PRId32, target_name(target),
628 nds32_v2->n_hbr);
630 nds32->target->state = TARGET_RUNNING;
631 nds32->target->debug_reason = DBG_REASON_NOTHALTED;
633 target_set_examined(target);
635 return ERROR_OK;
638 static int nds32_v2_translate_address(struct target *target, target_addr_t *address)
640 struct nds32 *nds32 = target_to_nds32(target);
641 struct nds32_memory *memory = &(nds32->memory);
642 target_addr_t physical_address;
644 /* Following conditions need to do address translation
645 * 1. BUS mode
646 * 2. CPU mode under maximum interrupt level */
647 if ((NDS_MEMORY_ACC_BUS == memory->access_channel) ||
648 ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
649 nds32_reach_max_interrupt_level(nds32))) {
650 if (ERROR_OK == target->type->virt2phys(target, *address, &physical_address))
651 *address = physical_address;
652 else
653 return ERROR_FAIL;
656 return ERROR_OK;
659 static int nds32_v2_read_buffer(struct target *target, target_addr_t address,
660 uint32_t size, uint8_t *buffer)
662 struct nds32 *nds32 = target_to_nds32(target);
663 struct nds32_memory *memory = &(nds32->memory);
665 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
666 (target->state != TARGET_HALTED)) {
667 LOG_WARNING("target was not halted");
668 return ERROR_TARGET_NOT_HALTED;
671 /* BUG: If access range crosses multiple pages, the translation will not correct
672 * for second page or so. */
674 nds32_v2_translate_address(target, &address);
676 return nds32_read_buffer(target, address, size, buffer);
679 static int nds32_v2_write_buffer(struct target *target, target_addr_t address,
680 uint32_t size, const uint8_t *buffer)
682 struct nds32 *nds32 = target_to_nds32(target);
683 struct nds32_memory *memory = &(nds32->memory);
685 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
686 (target->state != TARGET_HALTED)) {
687 LOG_WARNING("target was not halted");
688 return ERROR_TARGET_NOT_HALTED;
691 /* BUG: If access range crosses multiple pages, the translation will not correct
692 * for second page or so. */
694 nds32_v2_translate_address(target, &address);
696 return nds32_write_buffer(target, address, size, buffer);
699 static int nds32_v2_read_memory(struct target *target, target_addr_t address,
700 uint32_t size, uint32_t count, uint8_t *buffer)
702 struct nds32 *nds32 = target_to_nds32(target);
703 struct nds32_memory *memory = &(nds32->memory);
705 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
706 (target->state != TARGET_HALTED)) {
707 LOG_WARNING("target was not halted");
708 return ERROR_TARGET_NOT_HALTED;
711 /* BUG: If access range crosses multiple pages, the translation will not correct
712 * for second page or so. */
714 nds32_v2_translate_address(target, &address);
716 return nds32_read_memory(target, address, size, count, buffer);
719 static int nds32_v2_write_memory(struct target *target, target_addr_t address,
720 uint32_t size, uint32_t count, const uint8_t *buffer)
722 struct nds32 *nds32 = target_to_nds32(target);
723 struct nds32_memory *memory = &(nds32->memory);
725 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
726 (target->state != TARGET_HALTED)) {
727 LOG_WARNING("target was not halted");
728 return ERROR_TARGET_NOT_HALTED;
731 /* BUG: If access range crosses multiple pages, the translation will not correct
732 * for second page or so. */
734 nds32_v2_translate_address(target, &address);
736 return nds32_write_memory(target, address, size, count, buffer);
739 /** Holds methods for V2 targets. */
740 struct target_type nds32_v2_target = {
741 .name = "nds32_v2",
743 .poll = nds32_poll,
744 .arch_state = nds32_arch_state,
746 .target_request_data = nds32_v2_target_request_data,
748 .halt = nds32_halt,
749 .resume = nds32_resume,
750 .step = nds32_step,
752 .assert_reset = nds32_assert_reset,
753 .deassert_reset = nds32_v2_deassert_reset,
755 /* register access */
756 .get_gdb_reg_list = nds32_get_gdb_reg_list,
758 /* memory access */
759 .read_buffer = nds32_v2_read_buffer,
760 .write_buffer = nds32_v2_write_buffer,
761 .read_memory = nds32_v2_read_memory,
762 .write_memory = nds32_v2_write_memory,
764 .checksum_memory = nds32_v2_checksum_memory,
766 /* breakpoint/watchpoint */
767 .add_breakpoint = nds32_v2_add_breakpoint,
768 .remove_breakpoint = nds32_v2_remove_breakpoint,
769 .add_watchpoint = nds32_v2_add_watchpoint,
770 .remove_watchpoint = nds32_v2_remove_watchpoint,
771 .hit_watchpoint = nds32_v2_hit_watchpoint,
773 /* MMU */
774 .mmu = nds32_mmu,
775 .virt2phys = nds32_virtual_to_physical,
776 .read_phys_memory = nds32_read_phys_memory,
777 .write_phys_memory = nds32_write_phys_memory,
779 .run_algorithm = nds32_v2_run_algorithm,
781 .commands = nds32_command_handlers,
782 .target_create = nds32_v2_target_create,
783 .init_target = nds32_v2_init_target,
784 .examine = nds32_v2_examine,