target: fix mem2array/array2mem
[openocd.git] / src / target / nds32_v2.c
blob24f5108ccb2d2b07dedfbd6374985efb8a9726c2
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 ***************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
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"
36 static int nds32_v2_register_mapping(struct nds32 *nds32, int reg_no)
38 uint32_t max_level = nds32->max_interrupt_level;
39 uint32_t cur_level = nds32->current_interrupt_level;
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;
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;
69 } else if (cur_level == max_level) {
70 if (PC == reg_no) {
71 LOG_DEBUG("Mapping PC to O_IPC");
72 return IR11;
76 return reg_no;
79 static int nds32_v2_get_debug_reason(struct nds32 *nds32, uint32_t *reason)
81 uint32_t val_itype;
82 struct aice_port_s *aice = target_to_aice(nds32->target);
84 aice_read_register(aice, IR6, &val_itype);
86 *reason = val_itype & 0x0F;
88 return ERROR_OK;
91 static int nds32_v2_activate_hardware_breakpoint(struct target *target)
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;
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);
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);
117 LOG_DEBUG("Add hardware BP %d at %08" PRIx32, hbr_index,
118 bp->address);
120 hbr_index++;
121 } else {
122 return ERROR_FAIL;
126 return ERROR_OK;
129 static int nds32_v2_deactivate_hardware_breakpoint(struct target *target)
131 struct aice_port_s *aice = target_to_aice(target);
132 struct breakpoint *bp;
133 int32_t hbr_index = 0;
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;
144 LOG_DEBUG("Remove hardware BP %d at %08" PRIx32, hbr_index,
145 bp->address);
147 hbr_index++;
150 return ERROR_OK;
153 static int nds32_v2_activate_hardware_watchpoint(struct target *target)
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;
161 for (wp = target->watchpoints; wp; wp = wp->next) {
163 wp_num--;
164 wp->mask = wp->length - 1;
165 if ((wp->address % wp->length) != 0)
166 wp->mask = (wp->mask << 1) + 1;
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;
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;
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);
189 LOG_DEBUG("Add hardware wathcpoint %d at %08" PRIx32 " mask %08" PRIx32, wp_num,
190 wp->address, wp->mask);
194 return ERROR_OK;
197 static int nds32_v2_deactivate_hardware_watchpoint(struct target *target)
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;
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);
209 LOG_DEBUG("Remove hardware wathcpoint %d at %08" PRIx32 " mask %08" PRIx32,
210 wp_num, wp->address, wp->mask);
213 return ERROR_OK;
216 static int nds32_v2_check_interrupt_stack(struct nds32_v2_common *nds32_v2)
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;
225 /* Save interrupt level */
226 aice_read_register(aice, IR0, &val_ir0); /* get $IR0 directly */
228 /* backup $IR0 */
229 nds32_v2->backup_ir0 = val_ir0;
231 nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3;
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);
237 /* decrease interrupt level */
238 modified_psw = val_ir0 - 0x2;
240 /* disable GIE, IT, DT, HSS */
241 modified_psw &= (~0x8C1);
243 aice_write_register(aice, IR0, modified_psw);
245 return ERROR_OK;
248 /* There is a case that single step also trigger another interrupt,
249 then HSS bit in psw(ir0) will push to ipsw(ir1).
250 Then hit debug interrupt HSS bit in ipsw(ir1) will push to (p_ipsw)ir2
251 Therefore, HSS bit in p_ipsw(ir2) also need clear.
253 Only update $ir2 as current interrupt level is 2, because $ir2 will be random
254 value if the target never reaches interrupt level 2. */
255 if ((nds32->max_interrupt_level == 3) && (nds32->current_interrupt_level == 2)) {
256 aice_read_register(aice, IR2, &val_ir2); /* get $IR2 directly */
257 val_ir2 &= ~(0x01 << 11);
258 aice_write_register(aice, IR2, val_ir2);
261 /* get origianl DT bit and set to current state let debugger has same memory view
262 PSW.IT MUST be turned off. Otherwise, DIM could not operate normally. */
263 aice_read_register(aice, IR1, &val_ir1);
264 modified_psw = val_ir0 | (val_ir1 & 0x80);
265 aice_write_register(aice, IR0, modified_psw);
267 return ERROR_OK;
270 static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common *nds32_v2)
272 struct nds32 *nds32 = &(nds32_v2->nds32);
273 struct aice_port_s *aice = target_to_aice(nds32->target);
275 /* restore origin $IR0 */
276 aice_write_register(aice, IR0, nds32_v2->backup_ir0);
278 return ERROR_OK;
282 * Save processor state. This is called after a HALT instruction
283 * succeeds, and on other occasions the processor enters debug mode
284 * (breakpoint, watchpoint, etc).
286 static int nds32_v2_debug_entry(struct nds32 *nds32, bool enable_watchpoint)
288 LOG_DEBUG("nds32_v2_debug_entry");
290 if (nds32->virtual_hosting)
291 LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported "
292 "under V1/V2 architecture. -->");
294 enum target_state backup_state = nds32->target->state;
295 nds32->target->state = TARGET_HALTED;
297 if (nds32->init_arch_info_after_halted == false) {
298 /* init architecture info according to config registers */
299 CHECK_RETVAL(nds32_config(nds32));
301 nds32->init_arch_info_after_halted = true;
304 /* REVISIT entire cache should already be invalid !!! */
305 register_cache_invalidate(nds32->core_cache);
307 /* deactivate all hardware breakpoints */
308 CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32->target));
310 if (enable_watchpoint)
311 CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32->target));
313 if (ERROR_OK != nds32_examine_debug_reason(nds32)) {
314 nds32->target->state = backup_state;
316 /* re-activate all hardware breakpoints & watchpoints */
317 CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
319 if (enable_watchpoint) {
320 /* activate all watchpoints */
321 CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
324 return ERROR_FAIL;
327 /* check interrupt level before .full_context(), because
328 * get_mapped_reg() in nds32_full_context() needs current_interrupt_level
329 * information */
330 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
331 nds32_v2_check_interrupt_stack(nds32_v2);
333 /* Save registers. */
334 nds32_full_context(nds32);
336 return ERROR_OK;
339 /* target request support */
340 static int nds32_v2_target_request_data(struct target *target,
341 uint32_t size, uint8_t *buffer)
343 /* AndesCore could use DTR register to communicate with OpenOCD
344 * to output messages
345 * Target data will be put in buffer
346 * The format of DTR is as follow
347 * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
348 * target_req_cmd has three possible values:
349 * TARGET_REQ_TRACEMSG
350 * TARGET_REQ_DEBUGMSG
351 * TARGET_REQ_DEBUGCHAR
352 * if size == 0, target will call target_asciimsg(),
353 * else call target_hexmsg()
355 LOG_WARNING("Not implemented: %s", __func__);
357 return ERROR_OK;
361 * Restore processor state.
363 static int nds32_v2_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint)
365 LOG_DEBUG("nds32_v2_leave_debug_state");
367 struct target *target = nds32->target;
369 /* activate all hardware breakpoints */
370 CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
372 if (enable_watchpoint) {
373 /* activate all watchpoints */
374 CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
377 /* restore interrupt stack */
378 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
379 nds32_v2_restore_interrupt_stack(nds32_v2);
381 /* restore PSW, PC, and R0 ... after flushing any modified
382 * registers.
384 CHECK_RETVAL(nds32_restore_context(target));
386 register_cache_invalidate(nds32->core_cache);
388 return ERROR_OK;
391 static int nds32_v2_deassert_reset(struct target *target)
393 int retval;
395 CHECK_RETVAL(nds32_poll(target));
397 if (target->state != TARGET_HALTED) {
398 /* reset only */
399 LOG_WARNING("%s: ran after reset and before halt ...",
400 target_name(target));
401 retval = target_halt(target);
402 if (retval != ERROR_OK)
403 return retval;
406 return ERROR_OK;
409 static int nds32_v2_checksum_memory(struct target *target,
410 uint32_t address, uint32_t count, uint32_t *checksum)
412 LOG_WARNING("Not implemented: %s", __func__);
414 return ERROR_FAIL;
417 static int nds32_v2_add_breakpoint(struct target *target,
418 struct breakpoint *breakpoint)
420 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
421 struct nds32 *nds32 = &(nds32_v2->nds32);
422 int result;
424 if (breakpoint->type == BKPT_HARD) {
425 /* check hardware resource */
426 if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
427 LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
428 "breakpoints/watchpoints! The limit of "
429 "combined hardware breakpoints/watchpoints "
430 "is %d. -->", nds32_v2->n_hbr);
431 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
434 /* update next place to put hardware breakpoint */
435 nds32_v2->next_hbr_index++;
437 /* hardware breakpoint insertion occurs before 'continue' actually */
438 return ERROR_OK;
439 } else if (breakpoint->type == BKPT_SOFT) {
440 result = nds32_add_software_breakpoint(target, breakpoint);
441 if (ERROR_OK != result) {
442 /* auto convert to hardware breakpoint if failed */
443 if (nds32->auto_convert_hw_bp) {
444 /* convert to hardware breakpoint */
445 breakpoint->type = BKPT_HARD;
447 return nds32_v2_add_breakpoint(target, breakpoint);
451 return result;
452 } else /* unrecognized breakpoint type */
453 return ERROR_FAIL;
455 return ERROR_OK;
458 static int nds32_v2_remove_breakpoint(struct target *target,
459 struct breakpoint *breakpoint)
461 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
463 if (breakpoint->type == BKPT_HARD) {
464 if (nds32_v2->next_hbr_index <= 0)
465 return ERROR_FAIL;
467 /* update next place to put hardware breakpoint */
468 nds32_v2->next_hbr_index--;
470 /* hardware breakpoint removal occurs after 'halted' actually */
471 return ERROR_OK;
472 } else if (breakpoint->type == BKPT_SOFT) {
473 return nds32_remove_software_breakpoint(target, breakpoint);
474 } else /* unrecognized breakpoint type */
475 return ERROR_FAIL;
477 return ERROR_OK;
480 static int nds32_v2_add_watchpoint(struct target *target,
481 struct watchpoint *watchpoint)
483 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
485 /* check hardware resource */
486 if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
487 LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
488 "breakpoints/watchpoints! The limit of "
489 "combined hardware breakpoints/watchpoints is %d. -->", nds32_v2->n_hbr);
490 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
493 /* update next place to put hardware watchpoint */
494 nds32_v2->next_hbr_index++;
496 return ERROR_OK;
499 static int nds32_v2_remove_watchpoint(struct target *target,
500 struct watchpoint *watchpoint)
502 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
504 if (nds32_v2->next_hbr_index <= 0)
505 return ERROR_FAIL;
507 /* update next place to put hardware breakpoint */
508 nds32_v2->next_hbr_index--;
510 return ERROR_OK;
513 static int nds32_v2_get_exception_address(struct nds32 *nds32,
514 uint32_t *address, uint32_t reason)
516 struct aice_port_s *aice = target_to_aice(nds32->target);
518 aice_read_register(aice, IR4, address); /* read $EVA directly */
520 /* TODO: hit multiple watchpoints */
522 return ERROR_OK;
526 * find out which watchpoint hits
527 * get exception address and compare the address to watchpoints
529 static int nds32_v2_hit_watchpoint(struct target *target,
530 struct watchpoint **hit_watchpoint)
532 uint32_t exception_address;
533 struct watchpoint *wp;
534 static struct watchpoint scan_all_watchpoint;
535 struct nds32 *nds32 = target_to_nds32(target);
537 scan_all_watchpoint.address = 0;
538 scan_all_watchpoint.rw = WPT_WRITE;
539 scan_all_watchpoint.next = 0;
540 scan_all_watchpoint.unique_id = 0x5CA8;
542 exception_address = nds32->watched_address;
544 if (exception_address == 0) {
545 /* send watch:0 to tell GDB to do software scan for hitting multiple watchpoints */
546 *hit_watchpoint = &scan_all_watchpoint;
547 return ERROR_OK;
550 for (wp = target->watchpoints; wp; wp = wp->next) {
551 if (((exception_address ^ wp->address) & (~wp->mask)) == 0) {
552 /* TODO: dispel false match */
553 *hit_watchpoint = wp;
554 return ERROR_OK;
558 return ERROR_FAIL;
561 static int nds32_v2_run_algorithm(struct target *target,
562 int num_mem_params,
563 struct mem_param *mem_params,
564 int num_reg_params,
565 struct reg_param *reg_params,
566 uint32_t entry_point,
567 uint32_t exit_point,
568 int timeout_ms,
569 void *arch_info)
571 LOG_WARNING("Not implemented: %s", __func__);
573 return ERROR_FAIL;
576 static int nds32_v2_target_create(struct target *target, Jim_Interp *interp)
578 struct nds32_v2_common *nds32_v2;
580 nds32_v2 = calloc(1, sizeof(*nds32_v2));
581 if (!nds32_v2)
582 return ERROR_FAIL;
584 nds32_v2->nds32.register_map = nds32_v2_register_mapping;
585 nds32_v2->nds32.get_debug_reason = nds32_v2_get_debug_reason;
586 nds32_v2->nds32.enter_debug_state = nds32_v2_debug_entry;
587 nds32_v2->nds32.leave_debug_state = nds32_v2_leave_debug_state;
588 nds32_v2->nds32.get_watched_address = nds32_v2_get_exception_address;
590 nds32_init_arch_info(target, &(nds32_v2->nds32));
592 return ERROR_OK;
595 static int nds32_v2_init_target(struct command_context *cmd_ctx,
596 struct target *target)
598 /* Initialize anything we can set up without talking to the target */
600 struct nds32 *nds32 = target_to_nds32(target);
602 nds32_init(nds32);
604 return ERROR_OK;
607 /* talk to the target and set things up */
608 static int nds32_v2_examine(struct target *target)
610 struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
611 struct nds32 *nds32 = &(nds32_v2->nds32);
612 struct aice_port_s *aice = target_to_aice(target);
614 if (!target_was_examined(target)) {
615 CHECK_RETVAL(nds32_edm_config(nds32));
617 if (nds32->reset_halt_as_examine)
618 CHECK_RETVAL(nds32_reset_halt(nds32));
621 uint32_t edm_cfg;
622 aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
624 /* get the number of hardware breakpoints */
625 nds32_v2->n_hbr = (edm_cfg & 0x7) + 1;
627 nds32_v2->next_hbr_index = 0;
629 LOG_INFO("%s: total hardware breakpoint %d", target_name(target),
630 nds32_v2->n_hbr);
632 nds32->target->state = TARGET_RUNNING;
633 nds32->target->debug_reason = DBG_REASON_NOTHALTED;
635 target_set_examined(target);
637 return ERROR_OK;
640 static int nds32_v2_translate_address(struct target *target, uint32_t *address)
642 struct nds32 *nds32 = target_to_nds32(target);
643 struct nds32_memory *memory = &(nds32->memory);
644 uint32_t physical_address;
646 /* Following conditions need to do address translation
647 * 1. BUS mode
648 * 2. CPU mode under maximum interrupt level */
649 if ((NDS_MEMORY_ACC_BUS == memory->access_channel) ||
650 ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
651 nds32_reach_max_interrupt_level(nds32))) {
652 if (ERROR_OK == target->type->virt2phys(target, *address, &physical_address))
653 *address = physical_address;
654 else
655 return ERROR_FAIL;
658 return ERROR_OK;
661 static int nds32_v2_read_buffer(struct target *target, uint32_t address,
662 uint32_t size, uint8_t *buffer)
664 struct nds32 *nds32 = target_to_nds32(target);
665 struct nds32_memory *memory = &(nds32->memory);
667 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
668 (target->state != TARGET_HALTED)) {
669 LOG_WARNING("target was not halted");
670 return ERROR_TARGET_NOT_HALTED;
673 /* BUG: If access range crosses multiple pages, the translation will not correct
674 * for second page or so. */
676 nds32_v2_translate_address(target, &address);
678 return nds32_read_buffer(target, address, size, buffer);
681 static int nds32_v2_write_buffer(struct target *target, uint32_t address,
682 uint32_t size, const uint8_t *buffer)
684 struct nds32 *nds32 = target_to_nds32(target);
685 struct nds32_memory *memory = &(nds32->memory);
687 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
688 (target->state != TARGET_HALTED)) {
689 LOG_WARNING("target was not halted");
690 return ERROR_TARGET_NOT_HALTED;
693 /* BUG: If access range crosses multiple pages, the translation will not correct
694 * for second page or so. */
696 nds32_v2_translate_address(target, &address);
698 return nds32_write_buffer(target, address, size, buffer);
701 static int nds32_v2_read_memory(struct target *target, uint32_t address,
702 uint32_t size, uint32_t count, uint8_t *buffer)
704 struct nds32 *nds32 = target_to_nds32(target);
705 struct nds32_memory *memory = &(nds32->memory);
707 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
708 (target->state != TARGET_HALTED)) {
709 LOG_WARNING("target was not halted");
710 return ERROR_TARGET_NOT_HALTED;
713 /* BUG: If access range crosses multiple pages, the translation will not correct
714 * for second page or so. */
716 nds32_v2_translate_address(target, &address);
718 return nds32_read_memory(target, address, size, count, buffer);
721 static int nds32_v2_write_memory(struct target *target, uint32_t address,
722 uint32_t size, uint32_t count, const uint8_t *buffer)
724 struct nds32 *nds32 = target_to_nds32(target);
725 struct nds32_memory *memory = &(nds32->memory);
727 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
728 (target->state != TARGET_HALTED)) {
729 LOG_WARNING("target was not halted");
730 return ERROR_TARGET_NOT_HALTED;
733 /* BUG: If access range crosses multiple pages, the translation will not correct
734 * for second page or so. */
736 nds32_v2_translate_address(target, &address);
738 return nds32_write_memory(target, address, size, count, buffer);
741 /** Holds methods for V2 targets. */
742 struct target_type nds32_v2_target = {
743 .name = "nds32_v2",
745 .poll = nds32_poll,
746 .arch_state = nds32_arch_state,
748 .target_request_data = nds32_v2_target_request_data,
750 .halt = nds32_halt,
751 .resume = nds32_resume,
752 .step = nds32_step,
754 .assert_reset = nds32_assert_reset,
755 .deassert_reset = nds32_v2_deassert_reset,
757 /* register access */
758 .get_gdb_reg_list = nds32_get_gdb_reg_list,
760 /* memory access */
761 .read_buffer = nds32_v2_read_buffer,
762 .write_buffer = nds32_v2_write_buffer,
763 .read_memory = nds32_v2_read_memory,
764 .write_memory = nds32_v2_write_memory,
766 .checksum_memory = nds32_v2_checksum_memory,
768 /* breakpoint/watchpoint */
769 .add_breakpoint = nds32_v2_add_breakpoint,
770 .remove_breakpoint = nds32_v2_remove_breakpoint,
771 .add_watchpoint = nds32_v2_add_watchpoint,
772 .remove_watchpoint = nds32_v2_remove_watchpoint,
773 .hit_watchpoint = nds32_v2_hit_watchpoint,
775 /* MMU */
776 .mmu = nds32_mmu,
777 .virt2phys = nds32_virtual_to_physical,
778 .read_phys_memory = nds32_read_phys_memory,
779 .write_phys_memory = nds32_write_phys_memory,
781 .run_algorithm = nds32_v2_run_algorithm,
783 .commands = nds32_command_handlers,
784 .target_create = nds32_v2_target_create,
785 .init_target = nds32_v2_init_target,
786 .examine = nds32_v2_examine,