1 /***************************************************************************
2 * Copyright (C) 2013 Andes Technology *
3 * Hsiangkai Wang <hkwang@andestech.com> *
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. *
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. *
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 ***************************************************************************/
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"
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
)) {
43 LOG_DEBUG("Map PSW to IPSW");
45 } else if (PC
== reg_no
) {
46 LOG_DEBUG("Map PC to IPC");
49 } else if ((2 <= cur_level
) && (cur_level
< max_level
)) {
51 LOG_DEBUG("Mapping P0 to P_P0");
53 } else if (R27
== reg_no
) {
54 LOG_DEBUG("Mapping P1 to P_P1");
56 } else if (IR1
== reg_no
) {
57 LOG_DEBUG("Mapping IPSW to P_IPSW");
59 } else if (IR4
== reg_no
) {
60 LOG_DEBUG("Mapping EVA to P_EVA");
62 } else if (IR6
== reg_no
) {
63 LOG_DEBUG("Mapping ITYPE to P_ITYPE");
65 } else if (IR9
== reg_no
) {
66 LOG_DEBUG("Mapping IPC to P_IPC");
69 } else if (cur_level
== max_level
) {
71 LOG_DEBUG("Mapping PC to O_IPC");
79 static int nds32_v2_get_debug_reason(struct nds32
*nds32
, uint32_t *reason
)
82 struct aice_port_s
*aice
= target_to_aice(nds32
->target
);
84 aice_read_register(aice
, IR6
, &val_itype
);
86 *reason
= val_itype
& 0x0F;
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() */
102 } else if (bp
->type
== BKPT_HARD
) {
104 aice_write_debug_reg(aice
, NDS_EDM_SR_BPA0
+ hbr_index
, bp
->address
);
106 aice_write_debug_reg(aice
, NDS_EDM_SR_BPAM0
+ hbr_index
, 0);
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);
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
,
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
)
138 else if (bp
->type
== BKPT_HARD
)
139 /* disable breakpoint */
140 aice_write_debug_reg(aice
, NDS_EDM_SR_BPC0
+ hbr_index
, 0x0);
144 LOG_DEBUG("Remove hardware BP %d at %08" PRIx32
, hbr_index
,
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
) {
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
)
170 else if (wp
->rw
== WPT_WRITE
)
172 else if (wp
->rw
== WPT_ACCESS
)
175 /* set/unset physical address bit of BPCn according to PSW.DT */
176 if (nds32_v2
->nds32
.memory
.address_translation
== false)
180 aice_write_debug_reg(aice
, NDS_EDM_SR_BPA0
+ wp_num
,
181 wp
->address
- (wp
->address
% wp
->length
));
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
);
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
);
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
) {
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
);
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
);
223 uint32_t modified_psw
;
225 /* Save interrupt level */
226 aice_read_register(aice
, IR0
, &val_ir0
); /* get $IR0 directly */
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
);
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.
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
);
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
);
271 static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common
*nds32_v2
)
273 struct nds32
*nds32
= &(nds32_v2
->nds32
);
274 struct aice_port_s
*aice
= target_to_aice(nds32
->target
);
276 /* restore origin $IR0 */
277 aice_write_register(aice
, IR0
, nds32_v2
->backup_ir0
);
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).
287 static int nds32_v2_debug_entry(struct nds32
*nds32
, bool enable_watchpoint
)
289 LOG_DEBUG("nds32_v2_debug_entry");
291 jtag_poll_set_enabled(false);
293 if (nds32
->virtual_hosting
)
294 LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported "
295 "under V1/V2 architecture. -->");
297 struct nds32_v2_common
*nds32_v2
= target_to_nds32_v2(nds32
->target
);
299 CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32
->target
));
301 if (enable_watchpoint
)
302 CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32
->target
));
304 nds32
->target
->state
= TARGET_HALTED
;
305 nds32_examine_debug_reason(nds32
);
307 if (nds32
->init_arch_info_after_halted
== false) {
308 /* init architecture info according to config registers */
309 CHECK_RETVAL(nds32_config(nds32
));
311 nds32
->init_arch_info_after_halted
= true;
314 /* REVISIT entire cache should already be invalid !!! */
315 register_cache_invalidate(nds32
->core_cache
);
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
);
321 /* Save registers. */
322 nds32_full_context(nds32
);
327 /* target request support */
328 static int nds32_v2_target_request_data(struct target
*target
,
329 uint32_t size
, uint8_t *buffer
)
331 /* AndesCore could use DTR register to communicate with OpenOCD
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()
343 LOG_WARNING("Not implemented: %s", __func__
);
349 * Restore processor state.
351 static int nds32_v2_leave_debug_state(struct nds32
*nds32
, bool enable_watchpoint
)
353 struct nds32_v2_common
*nds32_v2
= target_to_nds32_v2(nds32
->target
);
355 /* activate all hardware breakpoints */
356 CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32
->target
));
358 if (enable_watchpoint
) {
359 /* activate all watchpoints */
360 CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32
->target
));
363 /* restore interrupt stack */
364 nds32_v2_restore_interrupt_stack(nds32_v2
);
366 /* restore PSW, PC, and R0 ... after flushing any modified
369 CHECK_RETVAL(nds32_restore_context(nds32
->target
));
371 register_cache_invalidate(nds32
->core_cache
);
373 jtag_poll_set_enabled(true);
378 static int nds32_v2_soft_reset_halt(struct target
*target
)
381 struct nds32
*nds32
= target_to_nds32(target
);
382 struct aice_port_s
*aice
= target_to_aice(target
);
384 aice_assert_srst(aice
, AICE_SRST
);
386 /* halt core and set pc to 0x0 */
387 int retval
= target_halt(target
);
388 if (retval
!= ERROR_OK
)
391 /* start fetching from IVB */
393 nds32_get_mapped_reg(nds32
, IR3
, &value_ir3
);
394 nds32_set_mapped_reg(nds32
, PC
, value_ir3
& 0xFFFF0000);
399 static int nds32_v2_deassert_reset(struct target
*target
)
403 CHECK_RETVAL(nds32_poll(target
));
405 if (target
->state
!= TARGET_HALTED
) {
407 LOG_WARNING("%s: ran after reset and before halt ...",
408 target_name(target
));
409 retval
= target_halt(target
);
410 if (retval
!= ERROR_OK
)
412 /* call target_poll() to avoid "Halt timed out" */
413 CHECK_RETVAL(target_poll(target
));
415 jtag_poll_set_enabled(false);
421 static int nds32_v2_checksum_memory(struct target
*target
,
422 uint32_t address
, uint32_t count
, uint32_t *checksum
)
424 LOG_WARNING("Not implemented: %s", __func__
);
429 static int nds32_v2_add_breakpoint(struct target
*target
,
430 struct breakpoint
*breakpoint
)
432 struct nds32_v2_common
*nds32_v2
= target_to_nds32_v2(target
);
433 struct nds32
*nds32
= &(nds32_v2
->nds32
);
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
;
446 /* update next place to put hardware breakpoint */
447 nds32_v2
->next_hbr_index
++;
449 /* hardware breakpoint insertion occurs before 'continue' actually */
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
;
459 return nds32_v2_add_breakpoint(target
, breakpoint
);
464 } else /* unrecognized breakpoint type */
470 static int nds32_v2_remove_breakpoint(struct target
*target
,
471 struct breakpoint
*breakpoint
)
473 struct nds32_v2_common
*nds32_v2
= target_to_nds32_v2(target
);
475 if (breakpoint
->type
== BKPT_HARD
) {
476 if (nds32_v2
->next_hbr_index
<= 0)
479 /* update next place to put hardware breakpoint */
480 nds32_v2
->next_hbr_index
--;
482 /* hardware breakpoint removal occurs after 'halted' actually */
484 } else if (breakpoint
->type
== BKPT_SOFT
) {
485 return nds32_remove_software_breakpoint(target
, breakpoint
);
486 } else /* unrecognized breakpoint type */
492 static int nds32_v2_add_watchpoint(struct target
*target
,
493 struct watchpoint
*watchpoint
)
495 struct nds32_v2_common
*nds32_v2
= target_to_nds32_v2(target
);
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
;
505 /* update next place to put hardware watchpoint */
506 nds32_v2
->next_hbr_index
++;
511 static int nds32_v2_remove_watchpoint(struct target
*target
,
512 struct watchpoint
*watchpoint
)
514 struct nds32_v2_common
*nds32_v2
= target_to_nds32_v2(target
);
516 if (nds32_v2
->next_hbr_index
<= 0)
519 /* update next place to put hardware breakpoint */
520 nds32_v2
->next_hbr_index
--;
525 static int nds32_v2_get_exception_address(struct nds32
*nds32
,
526 uint32_t *address
, uint32_t reason
)
528 struct aice_port_s
*aice
= target_to_aice(nds32
->target
);
530 aice_read_register(aice
, IR4
, address
); /* read $EVA directly */
532 /* TODO: hit multiple watchpoints */
538 * find out which watchpoint hits
539 * get exception address and compare the address to watchpoints
541 static int nds32_v2_hit_watchpoint(struct target
*target
,
542 struct watchpoint
**hit_watchpoint
)
544 uint32_t exception_address
;
545 struct watchpoint
*wp
;
546 static struct watchpoint scan_all_watchpoint
;
547 struct nds32
*nds32
= target_to_nds32(target
);
549 scan_all_watchpoint
.address
= 0;
550 scan_all_watchpoint
.rw
= WPT_WRITE
;
551 scan_all_watchpoint
.next
= 0;
552 scan_all_watchpoint
.unique_id
= 0x5CA8;
554 exception_address
= nds32
->watched_address
;
556 if (exception_address
== 0) {
557 /* send watch:0 to tell GDB to do software scan for hitting multiple watchpoints */
558 *hit_watchpoint
= &scan_all_watchpoint
;
562 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
563 if (((exception_address
^ wp
->address
) & (~wp
->mask
)) == 0) {
564 /* TODO: dispel false match */
565 *hit_watchpoint
= wp
;
573 static int nds32_v2_run_algorithm(struct target
*target
,
575 struct mem_param
*mem_params
,
577 struct reg_param
*reg_params
,
578 uint32_t entry_point
,
583 LOG_WARNING("Not implemented: %s", __func__
);
588 static int nds32_v2_target_create(struct target
*target
, Jim_Interp
*interp
)
590 struct nds32_v2_common
*nds32_v2
;
592 nds32_v2
= calloc(1, sizeof(*nds32_v2
));
596 nds32_v2
->nds32
.register_map
= nds32_v2_register_mapping
;
597 nds32_v2
->nds32
.get_debug_reason
= nds32_v2_get_debug_reason
;
598 nds32_v2
->nds32
.enter_debug_state
= nds32_v2_debug_entry
;
599 nds32_v2
->nds32
.leave_debug_state
= nds32_v2_leave_debug_state
;
600 nds32_v2
->nds32
.get_watched_address
= nds32_v2_get_exception_address
;
602 nds32_init_arch_info(target
, &(nds32_v2
->nds32
));
607 static int nds32_v2_init_target(struct command_context
*cmd_ctx
,
608 struct target
*target
)
610 /* Initialize anything we can set up without talking to the target */
612 struct nds32
*nds32
= target_to_nds32(target
);
619 /* talk to the target and set things up */
620 static int nds32_v2_examine(struct target
*target
)
622 struct nds32_v2_common
*nds32_v2
= target_to_nds32_v2(target
);
623 struct nds32
*nds32
= &(nds32_v2
->nds32
);
624 struct aice_port_s
*aice
= target_to_aice(target
);
626 if (!target_was_examined(target
)) {
627 CHECK_RETVAL(nds32_edm_config(nds32
));
629 if (nds32
->reset_halt_as_examine
)
630 CHECK_RETVAL(nds32_reset_halt(nds32
));
634 aice_read_debug_reg(aice
, NDS_EDM_SR_EDM_CFG
, &edm_cfg
);
636 /* get the number of hardware breakpoints */
637 nds32_v2
->n_hbr
= (edm_cfg
& 0x7) + 1;
639 nds32_v2
->next_hbr_index
= 0;
641 LOG_INFO("%s: total hardware breakpoint %d", target_name(target
),
644 nds32
->target
->state
= TARGET_RUNNING
;
645 nds32
->target
->debug_reason
= DBG_REASON_NOTHALTED
;
647 target_set_examined(target
);
652 static int nds32_v2_translate_address(struct target
*target
, uint32_t *address
)
654 struct nds32
*nds32
= target_to_nds32(target
);
655 struct nds32_memory
*memory
= &(nds32
->memory
);
656 uint32_t physical_address
;
658 /* Following conditions need to do address translation
660 * 2. CPU mode under maximum interrupt level */
661 if ((NDS_MEMORY_ACC_BUS
== memory
->access_channel
) ||
662 ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
663 nds32_reach_max_interrupt_level(nds32
))) {
664 if (ERROR_OK
== target
->type
->virt2phys(target
, *address
, &physical_address
))
665 *address
= physical_address
;
673 static int nds32_v2_read_buffer(struct target
*target
, uint32_t address
,
674 uint32_t size
, uint8_t *buffer
)
676 struct nds32
*nds32
= target_to_nds32(target
);
677 struct nds32_memory
*memory
= &(nds32
->memory
);
679 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
680 (target
->state
!= TARGET_HALTED
)) {
681 LOG_WARNING("target was not halted");
682 return ERROR_TARGET_NOT_HALTED
;
685 /* BUG: If access range crosses multiple pages, the translation will not correct
686 * for second page or so. */
688 nds32_v2_translate_address(target
, &address
);
690 return nds32_read_buffer(target
, address
, size
, buffer
);
693 static int nds32_v2_write_buffer(struct target
*target
, uint32_t address
,
694 uint32_t size
, const uint8_t *buffer
)
696 struct nds32
*nds32
= target_to_nds32(target
);
697 struct nds32_memory
*memory
= &(nds32
->memory
);
699 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
700 (target
->state
!= TARGET_HALTED
)) {
701 LOG_WARNING("target was not halted");
702 return ERROR_TARGET_NOT_HALTED
;
705 /* BUG: If access range crosses multiple pages, the translation will not correct
706 * for second page or so. */
708 nds32_v2_translate_address(target
, &address
);
710 return nds32_write_buffer(target
, address
, size
, buffer
);
713 static int nds32_v2_read_memory(struct target
*target
, uint32_t address
,
714 uint32_t size
, uint32_t count
, uint8_t *buffer
)
716 struct nds32
*nds32
= target_to_nds32(target
);
717 struct nds32_memory
*memory
= &(nds32
->memory
);
719 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
720 (target
->state
!= TARGET_HALTED
)) {
721 LOG_WARNING("target was not halted");
722 return ERROR_TARGET_NOT_HALTED
;
725 /* BUG: If access range crosses multiple pages, the translation will not correct
726 * for second page or so. */
728 nds32_v2_translate_address(target
, &address
);
730 return nds32_read_memory(target
, address
, size
, count
, buffer
);
733 static int nds32_v2_write_memory(struct target
*target
, uint32_t address
,
734 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
736 struct nds32
*nds32
= target_to_nds32(target
);
737 struct nds32_memory
*memory
= &(nds32
->memory
);
739 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
740 (target
->state
!= TARGET_HALTED
)) {
741 LOG_WARNING("target was not halted");
742 return ERROR_TARGET_NOT_HALTED
;
745 /* BUG: If access range crosses multiple pages, the translation will not correct
746 * for second page or so. */
748 nds32_v2_translate_address(target
, &address
);
750 return nds32_write_memory(target
, address
, size
, count
, buffer
);
753 /** Holds methods for V2 targets. */
754 struct target_type nds32_v2_target
= {
758 .arch_state
= nds32_arch_state
,
760 .target_request_data
= nds32_v2_target_request_data
,
763 .resume
= nds32_resume
,
766 .assert_reset
= nds32_assert_reset
,
767 .deassert_reset
= nds32_v2_deassert_reset
,
768 .soft_reset_halt
= nds32_v2_soft_reset_halt
,
770 /* register access */
771 .get_gdb_reg_list
= nds32_get_gdb_reg_list
,
774 .read_buffer
= nds32_v2_read_buffer
,
775 .write_buffer
= nds32_v2_write_buffer
,
776 .read_memory
= nds32_v2_read_memory
,
777 .write_memory
= nds32_v2_write_memory
,
779 .checksum_memory
= nds32_v2_checksum_memory
,
781 /* breakpoint/watchpoint */
782 .add_breakpoint
= nds32_v2_add_breakpoint
,
783 .remove_breakpoint
= nds32_v2_remove_breakpoint
,
784 .add_watchpoint
= nds32_v2_add_watchpoint
,
785 .remove_watchpoint
= nds32_v2_remove_watchpoint
,
786 .hit_watchpoint
= nds32_v2_hit_watchpoint
,
790 .virt2phys
= nds32_virtual_to_physical
,
791 .read_phys_memory
= nds32_read_phys_memory
,
792 .write_phys_memory
= nds32_write_phys_memory
,
794 .run_algorithm
= nds32_v2_run_algorithm
,
796 .commands
= nds32_command_handlers
,
797 .target_create
= nds32_v2_target_create
,
798 .init_target
= nds32_v2_init_target
,
799 .examine
= nds32_v2_examine
,