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 "breakpoints.h"
26 #include "nds32_reg.h"
27 #include "nds32_disassembler.h"
29 #include "nds32_aice.h"
30 #include "nds32_v3_common.h"
32 static struct breakpoint syscall_breakpoint
= {
44 static struct nds32_v3_common_callback
*v3_common_callback
;
46 static int nds32_v3_register_mapping(struct nds32
*nds32
, int reg_no
)
54 static int nds32_v3_get_debug_reason(struct nds32
*nds32
, uint32_t *reason
)
57 struct aice_port_s
*aice
= target_to_aice(nds32
->target
);
58 aice_read_debug_reg(aice
, NDS_EDM_SR_EDMSW
, &edmsw
);
60 *reason
= (edmsw
>> 12) & 0x0F;
66 * Save processor state. This is called after a HALT instruction
67 * succeeds, and on other occasions the processor enters debug mode
68 * (breakpoint, watchpoint, etc).
70 static int nds32_v3_debug_entry(struct nds32
*nds32
, bool enable_watchpoint
)
72 LOG_DEBUG("nds32_v3_debug_entry");
74 jtag_poll_set_enabled(false);
76 enum target_state backup_state
= nds32
->target
->state
;
77 nds32
->target
->state
= TARGET_HALTED
;
79 if (nds32
->init_arch_info_after_halted
== false) {
80 /* init architecture info according to config registers */
81 CHECK_RETVAL(nds32_config(nds32
));
83 nds32
->init_arch_info_after_halted
= true;
86 /* REVISIT entire cache should already be invalid !!! */
87 register_cache_invalidate(nds32
->core_cache
);
89 /* deactivate all hardware breakpoints */
90 CHECK_RETVAL(v3_common_callback
->deactivate_hardware_breakpoint(nds32
->target
));
92 if (enable_watchpoint
)
93 CHECK_RETVAL(v3_common_callback
->deactivate_hardware_watchpoint(nds32
->target
));
95 if (nds32
->virtual_hosting
) {
96 if (syscall_breakpoint
.set
) {
97 /** disable virtual hosting */
99 /* remove breakpoint at syscall entry */
100 target_remove_breakpoint(nds32
->target
, &syscall_breakpoint
);
101 syscall_breakpoint
.set
= 0;
104 nds32_get_mapped_reg(nds32
, PC
, &value_pc
);
105 if (value_pc
== syscall_breakpoint
.address
)
106 /** process syscall for virtual hosting */
107 nds32
->hit_syscall
= true;
111 if (ERROR_OK
!= nds32_examine_debug_reason(nds32
)) {
112 nds32
->target
->state
= backup_state
;
114 /* re-activate all hardware breakpoints & watchpoints */
115 CHECK_RETVAL(v3_common_callback
->activate_hardware_breakpoint(nds32
->target
));
117 if (enable_watchpoint
)
118 CHECK_RETVAL(v3_common_callback
->activate_hardware_watchpoint(nds32
->target
));
120 jtag_poll_set_enabled(true);
125 /* Save registers. */
126 nds32_full_context(nds32
);
128 /* check interrupt level */
129 v3_common_callback
->check_interrupt_stack(nds32
);
135 * Restore processor state.
137 static int nds32_v3_leave_debug_state(struct nds32
*nds32
, bool enable_watchpoint
)
139 LOG_DEBUG("nds32_v3_leave_debug_state");
141 struct target
*target
= nds32
->target
;
143 /* activate all hardware breakpoints */
144 CHECK_RETVAL(v3_common_callback
->activate_hardware_breakpoint(target
));
146 if (enable_watchpoint
) {
147 /* activate all watchpoints */
148 CHECK_RETVAL(v3_common_callback
->activate_hardware_watchpoint(target
));
151 /* restore interrupt stack */
152 v3_common_callback
->restore_interrupt_stack(nds32
);
154 /* REVISIT once we start caring about MMU and cache state,
155 * address it here ...
158 /* restore PSW, PC, and R0 ... after flushing any modified
161 CHECK_RETVAL(nds32_restore_context(target
));
163 if (nds32
->virtual_hosting
) {
164 /** enable virtual hosting */
167 uint32_t syscall_address
;
169 /* get syscall entry address */
170 nds32_get_mapped_reg(nds32
, IR3
, &value_ir3
);
171 entry_size
= 0x4 << (((value_ir3
>> 14) & 0x3) << 1);
172 syscall_address
= (value_ir3
& 0xFFFF0000) + entry_size
* 8; /* The index of SYSCALL is 8 */
174 if (nds32
->hit_syscall
) {
175 /* single step to skip syscall entry */
176 /* use IRET to skip syscall */
177 struct aice_port_s
*aice
= target_to_aice(target
);
182 nds32_get_mapped_reg(nds32
, IR6
, &value_ir6
);
183 syscall_id
= (value_ir6
>> 16) & 0x7FFF;
185 if (syscall_id
== NDS32_SYSCALL_EXIT
) {
186 /* If target hits exit syscall, do not use IRET to skip handler. */
189 /* use api->read/write_reg to skip nds32 register cache */
190 uint32_t value_dimbr
;
191 aice_read_debug_reg(aice
, NDS_EDM_SR_DIMBR
, &value_dimbr
);
192 aice_write_register(aice
, IR11
, value_dimbr
+ 0xC);
194 aice_read_register(aice
, IR9
, &value_ir9
);
195 value_ir9
+= 4; /* syscall is always 4 bytes */
196 aice_write_register(aice
, IR9
, value_ir9
);
198 /* backup hardware breakpoint 0 */
199 uint32_t backup_bpa
, backup_bpam
, backup_bpc
;
200 aice_read_debug_reg(aice
, NDS_EDM_SR_BPA0
, &backup_bpa
);
201 aice_read_debug_reg(aice
, NDS_EDM_SR_BPAM0
, &backup_bpam
);
202 aice_read_debug_reg(aice
, NDS_EDM_SR_BPC0
, &backup_bpc
);
204 /* use hardware breakpoint 0 to stop cpu after skipping syscall */
205 aice_write_debug_reg(aice
, NDS_EDM_SR_BPA0
, value_ir9
);
206 aice_write_debug_reg(aice
, NDS_EDM_SR_BPAM0
, 0);
207 aice_write_debug_reg(aice
, NDS_EDM_SR_BPC0
, 0xA);
210 * First IRET is used to quit debug mode.
211 * Second IRET is used to quit current syscall. */
212 uint32_t dim_inst
[4] = {NOP
, NOP
, IRET
, IRET
};
213 aice_execute(aice
, dim_inst
, 4);
215 /* restore origin hardware breakpoint 0 */
216 aice_write_debug_reg(aice
, NDS_EDM_SR_BPA0
, backup_bpa
);
217 aice_write_debug_reg(aice
, NDS_EDM_SR_BPAM0
, backup_bpam
);
218 aice_write_debug_reg(aice
, NDS_EDM_SR_BPC0
, backup_bpc
);
221 nds32
->hit_syscall
= false;
224 /* insert breakpoint at syscall entry */
225 syscall_breakpoint
.address
= syscall_address
;
226 syscall_breakpoint
.type
= BKPT_SOFT
;
227 syscall_breakpoint
.set
= 1;
228 target_add_breakpoint(target
, &syscall_breakpoint
);
232 jtag_poll_set_enabled(true);
237 static int nds32_v3_get_exception_address(struct nds32
*nds32
,
238 uint32_t *address
, uint32_t reason
)
240 LOG_DEBUG("nds32_v3_get_exception_address");
242 struct aice_port_s
*aice
= target_to_aice(nds32
->target
);
243 struct target
*target
= nds32
->target
;
247 uint32_t match_count
;
249 static int32_t number_of_hard_break
;
251 if (number_of_hard_break
== 0) {
252 aice_read_debug_reg(aice
, NDS_EDM_SR_EDM_CFG
, &edm_cfg
);
253 number_of_hard_break
= (edm_cfg
& 0x7) + 1;
256 aice_read_debug_reg(aice
, NDS_EDM_SR_EDMSW
, &edmsw
);
257 /* clear matching bits (write-one-clear) */
258 aice_write_debug_reg(aice
, NDS_EDM_SR_EDMSW
, edmsw
);
259 match_bits
= (edmsw
>> 4) & 0xFF;
261 for (i
= 0 ; i
< number_of_hard_break
; i
++) {
262 if (match_bits
& (1 << i
)) {
263 aice_read_debug_reg(aice
, NDS_EDM_SR_BPA0
+ i
, address
);
268 if (match_count
> 1) { /* multiple hits */
271 } else if (match_count
== 1) {
274 struct nds32_instruction instruction
;
275 struct watchpoint
*wp
;
278 nds32_get_mapped_reg(nds32
, PC
, &val_pc
);
280 if ((NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE
== reason
) ||
281 (NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE
== reason
)) {
282 if (edmsw
& 0x4) /* check EDMSW.IS_16BIT */
288 nds32_read_opcode(nds32
, val_pc
, &opcode
);
289 nds32_evaluate_opcode(nds32
, opcode
, val_pc
, &instruction
);
291 LOG_DEBUG("PC: 0x%08x, access start: 0x%08x, end: 0x%08x", val_pc
,
292 instruction
.access_start
, instruction
.access_end
);
294 /* check if multiple hits in the access range */
295 uint32_t in_range_watch_count
= 0;
296 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
297 if ((instruction
.access_start
<= wp
->address
) &&
298 (wp
->address
< instruction
.access_end
))
299 in_range_watch_count
++;
301 if (in_range_watch_count
> 1) {
302 /* Hit LSMW instruction. */
307 /* dispel false match */
309 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
310 if (((*address
^ wp
->address
) & (~wp
->mask
)) == 0) {
311 uint32_t watch_start
;
314 watch_start
= wp
->address
;
315 watch_end
= wp
->address
+ wp
->length
;
317 if ((watch_end
<= instruction
.access_start
) ||
318 (instruction
.access_end
<= watch_start
))
330 } else if (match_count
== 0) {
331 /* global stop is precise exception */
332 if ((NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP
== reason
) && nds32
->global_stop
) {
333 /* parse instruction to get correct access address */
336 struct nds32_instruction instruction
;
338 nds32_get_mapped_reg(nds32
, PC
, &val_pc
);
339 nds32_read_opcode(nds32
, val_pc
, &opcode
);
340 nds32_evaluate_opcode(nds32
, opcode
, val_pc
, &instruction
);
342 *address
= instruction
.access_start
;
348 *address
= 0xFFFFFFFF;
352 void nds32_v3_common_register_callback(struct nds32_v3_common_callback
*callback
)
354 v3_common_callback
= callback
;
357 /** target_type functions: */
358 /* target request support */
359 int nds32_v3_target_request_data(struct target
*target
,
360 uint32_t size
, uint8_t *buffer
)
362 /* AndesCore could use DTR register to communicate with OpenOCD
364 * Target data will be put in buffer
365 * The format of DTR is as follow
366 * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
367 * target_req_cmd has three possible values:
368 * TARGET_REQ_TRACEMSG
369 * TARGET_REQ_DEBUGMSG
370 * TARGET_REQ_DEBUGCHAR
371 * if size == 0, target will call target_asciimsg(),
372 * else call target_hexmsg()
374 LOG_WARNING("Not implemented: %s", __func__
);
379 int nds32_v3_soft_reset_halt(struct target
*target
)
381 struct aice_port_s
*aice
= target_to_aice(target
);
382 return aice_assert_srst(aice
, AICE_RESET_HOLD
);
385 int nds32_v3_checksum_memory(struct target
*target
,
386 uint32_t address
, uint32_t count
, uint32_t *checksum
)
388 LOG_WARNING("Not implemented: %s", __func__
);
394 * find out which watchpoint hits
395 * get exception address and compare the address to watchpoints
397 int nds32_v3_hit_watchpoint(struct target
*target
,
398 struct watchpoint
**hit_watchpoint
)
400 static struct watchpoint scan_all_watchpoint
;
402 uint32_t exception_address
;
403 struct watchpoint
*wp
;
404 struct nds32
*nds32
= target_to_nds32(target
);
406 exception_address
= nds32
->watched_address
;
408 if (exception_address
== 0xFFFFFFFF)
411 if (exception_address
== 0) {
412 scan_all_watchpoint
.address
= 0;
413 scan_all_watchpoint
.rw
= WPT_WRITE
;
414 scan_all_watchpoint
.next
= 0;
415 scan_all_watchpoint
.unique_id
= 0x5CA8;
417 *hit_watchpoint
= &scan_all_watchpoint
;
421 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
422 if (((exception_address
^ wp
->address
) & (~wp
->mask
)) == 0) {
423 *hit_watchpoint
= wp
;
432 int nds32_v3_target_create_common(struct target
*target
, struct nds32
*nds32
)
434 nds32
->register_map
= nds32_v3_register_mapping
;
435 nds32
->get_debug_reason
= nds32_v3_get_debug_reason
;
436 nds32
->enter_debug_state
= nds32_v3_debug_entry
;
437 nds32
->leave_debug_state
= nds32_v3_leave_debug_state
;
438 nds32
->get_watched_address
= nds32_v3_get_exception_address
;
440 /* Init target->arch_info in nds32_init_arch_info().
441 * After this, user could use target_to_nds32() to get nds32 object */
442 nds32_init_arch_info(target
, nds32
);
447 int nds32_v3_run_algorithm(struct target
*target
,
449 struct mem_param
*mem_params
,
451 struct reg_param
*reg_params
,
452 uint32_t entry_point
,
457 LOG_WARNING("Not implemented: %s", __func__
);
462 int nds32_v3_read_buffer(struct target
*target
, uint32_t address
,
463 uint32_t size
, uint8_t *buffer
)
465 struct nds32
*nds32
= target_to_nds32(target
);
466 struct nds32_memory
*memory
= &(nds32
->memory
);
468 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
469 (target
->state
!= TARGET_HALTED
)) {
470 LOG_WARNING("target was not halted");
471 return ERROR_TARGET_NOT_HALTED
;
474 uint32_t physical_address
;
475 /* BUG: If access range crosses multiple pages, the translation will not correct
476 * for second page or so. */
478 /* When DEX is set to one, hardware will enforce the following behavior without
479 * modifying the corresponding control bits in PSW.
481 * Disable all interrupts
482 * Become superuser mode
484 * Use MMU_CFG.DE as the data access endian
485 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
486 * Disable audio special features
487 * Disable inline function call
489 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
490 * to physical address.
492 if (ERROR_OK
== target
->type
->virt2phys(target
, address
, &physical_address
))
493 address
= physical_address
;
498 struct aice_port_s
*aice
= target_to_aice(target
);
499 /* give arbitrary initial value to avoid warning messages */
500 enum nds_memory_access origin_access_channel
= NDS_MEMORY_ACC_CPU
;
502 if (nds32
->hit_syscall
) {
503 /* Use bus mode to access memory during virtual hosting */
504 origin_access_channel
= memory
->access_channel
;
505 memory
->access_channel
= NDS_MEMORY_ACC_BUS
;
506 aice_memory_access(aice
, NDS_MEMORY_ACC_BUS
);
509 result
= nds32_read_buffer(target
, address
, size
, buffer
);
511 if (nds32
->hit_syscall
) {
512 /* Restore access_channel after virtual hosting */
513 memory
->access_channel
= origin_access_channel
;
514 aice_memory_access(aice
, origin_access_channel
);
520 int nds32_v3_write_buffer(struct target
*target
, uint32_t address
,
521 uint32_t size
, const uint8_t *buffer
)
523 struct nds32
*nds32
= target_to_nds32(target
);
524 struct nds32_memory
*memory
= &(nds32
->memory
);
526 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
527 (target
->state
!= TARGET_HALTED
)) {
528 LOG_WARNING("target was not halted");
529 return ERROR_TARGET_NOT_HALTED
;
532 uint32_t physical_address
;
533 /* BUG: If access range crosses multiple pages, the translation will not correct
534 * for second page or so. */
536 /* When DEX is set to one, hardware will enforce the following behavior without
537 * modifying the corresponding control bits in PSW.
539 * Disable all interrupts
540 * Become superuser mode
542 * Use MMU_CFG.DE as the data access endian
543 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
544 * Disable audio special features
545 * Disable inline function call
547 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
548 * to physical address.
550 if (ERROR_OK
== target
->type
->virt2phys(target
, address
, &physical_address
))
551 address
= physical_address
;
555 if (nds32
->hit_syscall
) {
556 /* Use bus mode to access memory during virtual hosting */
557 struct aice_port_s
*aice
= target_to_aice(target
);
558 enum nds_memory_access origin_access_channel
;
561 origin_access_channel
= memory
->access_channel
;
562 memory
->access_channel
= NDS_MEMORY_ACC_BUS
;
563 aice_memory_access(aice
, NDS_MEMORY_ACC_BUS
);
565 result
= nds32_gdb_fileio_write_memory(nds32
, address
, size
, buffer
);
567 memory
->access_channel
= origin_access_channel
;
568 aice_memory_access(aice
, origin_access_channel
);
573 return nds32_write_buffer(target
, address
, size
, buffer
);
576 int nds32_v3_read_memory(struct target
*target
, uint32_t address
,
577 uint32_t size
, uint32_t count
, uint8_t *buffer
)
579 struct nds32
*nds32
= target_to_nds32(target
);
580 struct nds32_memory
*memory
= &(nds32
->memory
);
582 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
583 (target
->state
!= TARGET_HALTED
)) {
584 LOG_WARNING("target was not halted");
585 return ERROR_TARGET_NOT_HALTED
;
588 uint32_t physical_address
;
589 /* BUG: If access range crosses multiple pages, the translation will not correct
590 * for second page or so. */
592 /* When DEX is set to one, hardware will enforce the following behavior without
593 * modifying the corresponding control bits in PSW.
595 * Disable all interrupts
596 * Become superuser mode
598 * Use MMU_CFG.DE as the data access endian
599 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
600 * Disable audio special features
601 * Disable inline function call
603 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
604 * to physical address.
606 if (ERROR_OK
== target
->type
->virt2phys(target
, address
, &physical_address
))
607 address
= physical_address
;
611 struct aice_port_s
*aice
= target_to_aice(target
);
612 /* give arbitrary initial value to avoid warning messages */
613 enum nds_memory_access origin_access_channel
= NDS_MEMORY_ACC_CPU
;
616 if (nds32
->hit_syscall
) {
617 /* Use bus mode to access memory during virtual hosting */
618 origin_access_channel
= memory
->access_channel
;
619 memory
->access_channel
= NDS_MEMORY_ACC_BUS
;
620 aice_memory_access(aice
, NDS_MEMORY_ACC_BUS
);
623 result
= nds32_read_memory(target
, address
, size
, count
, buffer
);
625 if (nds32
->hit_syscall
) {
626 /* Restore access_channel after virtual hosting */
627 memory
->access_channel
= origin_access_channel
;
628 aice_memory_access(aice
, origin_access_channel
);
634 int nds32_v3_write_memory(struct target
*target
, uint32_t address
,
635 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
637 struct nds32
*nds32
= target_to_nds32(target
);
638 struct nds32_memory
*memory
= &(nds32
->memory
);
640 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
641 (target
->state
!= TARGET_HALTED
)) {
642 LOG_WARNING("target was not halted");
643 return ERROR_TARGET_NOT_HALTED
;
646 uint32_t physical_address
;
647 /* BUG: If access range crosses multiple pages, the translation will not correct
648 * for second page or so. */
650 /* When DEX is set to one, hardware will enforce the following behavior without
651 * modifying the corresponding control bits in PSW.
653 * Disable all interrupts
654 * Become superuser mode
656 * Use MMU_CFG.DE as the data access endian
657 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
658 * Disable audio special features
659 * Disable inline function call
661 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
662 * to physical address.
664 if (ERROR_OK
== target
->type
->virt2phys(target
, address
, &physical_address
))
665 address
= physical_address
;
669 return nds32_write_memory(target
, address
, size
, count
, buffer
);
672 int nds32_v3_init_target(struct command_context
*cmd_ctx
,
673 struct target
*target
)
675 /* Initialize anything we can set up without talking to the target */
676 struct nds32
*nds32
= target_to_nds32(target
);
680 target
->fileio_info
= malloc(sizeof(struct gdb_fileio_info
));
681 target
->fileio_info
->identifier
= NULL
;
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)