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 nds32_v3_common_callback
*v3_common_callback
;
34 static int nds32_v3_register_mapping(struct nds32
*nds32
, int reg_no
)
42 static int nds32_v3_get_debug_reason(struct nds32
*nds32
, uint32_t *reason
)
45 struct aice_port_s
*aice
= target_to_aice(nds32
->target
);
46 aice_read_debug_reg(aice
, NDS_EDM_SR_EDMSW
, &edmsw
);
48 *reason
= (edmsw
>> 12) & 0x0F;
54 * Save processor state. This is called after a HALT instruction
55 * succeeds, and on other occasions the processor enters debug mode
56 * (breakpoint, watchpoint, etc).
58 static int nds32_v3_debug_entry(struct nds32
*nds32
, bool enable_watchpoint
)
60 LOG_DEBUG("nds32_v3_debug_entry");
62 jtag_poll_set_enabled(false);
64 enum target_state backup_state
= nds32
->target
->state
;
65 nds32
->target
->state
= TARGET_HALTED
;
67 if (nds32
->init_arch_info_after_halted
== false) {
68 /* init architecture info according to config registers */
69 CHECK_RETVAL(nds32_config(nds32
));
71 nds32
->init_arch_info_after_halted
= true;
74 /* REVISIT entire cache should already be invalid !!! */
75 register_cache_invalidate(nds32
->core_cache
);
77 /* deactivate all hardware breakpoints */
78 CHECK_RETVAL(v3_common_callback
->deactivate_hardware_breakpoint(nds32
->target
));
80 if (enable_watchpoint
)
81 CHECK_RETVAL(v3_common_callback
->deactivate_hardware_watchpoint(nds32
->target
));
83 if (ERROR_OK
!= nds32_examine_debug_reason(nds32
)) {
84 nds32
->target
->state
= backup_state
;
86 /* re-activate all hardware breakpoints & watchpoints */
87 CHECK_RETVAL(v3_common_callback
->activate_hardware_breakpoint(nds32
->target
));
89 if (enable_watchpoint
)
90 CHECK_RETVAL(v3_common_callback
->activate_hardware_watchpoint(nds32
->target
));
92 jtag_poll_set_enabled(true);
98 nds32_full_context(nds32
);
100 /* check interrupt level */
101 v3_common_callback
->check_interrupt_stack(nds32
);
107 * Restore processor state.
109 static int nds32_v3_leave_debug_state(struct nds32
*nds32
, bool enable_watchpoint
)
111 LOG_DEBUG("nds32_v3_leave_debug_state");
113 struct target
*target
= nds32
->target
;
115 /* activate all hardware breakpoints */
116 CHECK_RETVAL(v3_common_callback
->activate_hardware_breakpoint(target
));
118 if (enable_watchpoint
) {
119 /* activate all watchpoints */
120 CHECK_RETVAL(v3_common_callback
->activate_hardware_watchpoint(target
));
123 /* restore interrupt stack */
124 v3_common_callback
->restore_interrupt_stack(nds32
);
126 /* REVISIT once we start caring about MMU and cache state,
127 * address it here ...
130 /* restore PSW, PC, and R0 ... after flushing any modified
133 CHECK_RETVAL(nds32_restore_context(target
));
136 jtag_poll_set_enabled(true);
141 static int nds32_v3_get_exception_address(struct nds32
*nds32
,
142 uint32_t *address
, uint32_t reason
)
144 LOG_DEBUG("nds32_v3_get_exception_address");
146 struct aice_port_s
*aice
= target_to_aice(nds32
->target
);
147 struct target
*target
= nds32
->target
;
151 uint32_t match_count
;
153 static int32_t number_of_hard_break
;
155 if (number_of_hard_break
== 0) {
156 aice_read_debug_reg(aice
, NDS_EDM_SR_EDM_CFG
, &edm_cfg
);
157 number_of_hard_break
= (edm_cfg
& 0x7) + 1;
160 aice_read_debug_reg(aice
, NDS_EDM_SR_EDMSW
, &edmsw
);
161 /* clear matching bits (write-one-clear) */
162 aice_write_debug_reg(aice
, NDS_EDM_SR_EDMSW
, edmsw
);
163 match_bits
= (edmsw
>> 4) & 0xFF;
165 for (i
= 0 ; i
< number_of_hard_break
; i
++) {
166 if (match_bits
& (1 << i
)) {
167 aice_read_debug_reg(aice
, NDS_EDM_SR_BPA0
+ i
, address
);
172 if (match_count
> 1) { /* multiple hits */
175 } else if (match_count
== 1) {
178 struct nds32_instruction instruction
;
179 struct watchpoint
*wp
;
182 nds32_get_mapped_reg(nds32
, PC
, &val_pc
);
184 if ((NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE
== reason
) ||
185 (NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE
== reason
)) {
186 if (edmsw
& 0x4) /* check EDMSW.IS_16BIT */
192 nds32_read_opcode(nds32
, val_pc
, &opcode
);
193 nds32_evaluate_opcode(nds32
, opcode
, val_pc
, &instruction
);
195 LOG_DEBUG("PC: 0x%08x, access start: 0x%08x, end: 0x%08x", val_pc
,
196 instruction
.access_start
, instruction
.access_end
);
198 /* check if multiple hits in the access range */
199 uint32_t in_range_watch_count
= 0;
200 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
201 if ((instruction
.access_start
<= wp
->address
) &&
202 (wp
->address
< instruction
.access_end
))
203 in_range_watch_count
++;
205 if (in_range_watch_count
> 1) {
206 /* Hit LSMW instruction. */
211 /* dispel false match */
213 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
214 if (((*address
^ wp
->address
) & (~wp
->mask
)) == 0) {
215 uint32_t watch_start
;
218 watch_start
= wp
->address
;
219 watch_end
= wp
->address
+ wp
->length
;
221 if ((watch_end
<= instruction
.access_start
) ||
222 (instruction
.access_end
<= watch_start
))
234 } else if (match_count
== 0) {
235 /* global stop is precise exception */
236 if ((NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP
== reason
) && nds32
->global_stop
) {
237 /* parse instruction to get correct access address */
240 struct nds32_instruction instruction
;
242 nds32_get_mapped_reg(nds32
, PC
, &val_pc
);
243 nds32_read_opcode(nds32
, val_pc
, &opcode
);
244 nds32_evaluate_opcode(nds32
, opcode
, val_pc
, &instruction
);
246 *address
= instruction
.access_start
;
252 *address
= 0xFFFFFFFF;
256 void nds32_v3_common_register_callback(struct nds32_v3_common_callback
*callback
)
258 v3_common_callback
= callback
;
261 /** target_type functions: */
262 /* target request support */
263 int nds32_v3_target_request_data(struct target
*target
,
264 uint32_t size
, uint8_t *buffer
)
266 /* AndesCore could use DTR register to communicate with OpenOCD
268 * Target data will be put in buffer
269 * The format of DTR is as follow
270 * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
271 * target_req_cmd has three possible values:
272 * TARGET_REQ_TRACEMSG
273 * TARGET_REQ_DEBUGMSG
274 * TARGET_REQ_DEBUGCHAR
275 * if size == 0, target will call target_asciimsg(),
276 * else call target_hexmsg()
278 LOG_WARNING("Not implemented: %s", __func__
);
283 int nds32_v3_soft_reset_halt(struct target
*target
)
285 struct aice_port_s
*aice
= target_to_aice(target
);
286 return aice_assert_srst(aice
, AICE_RESET_HOLD
);
289 int nds32_v3_checksum_memory(struct target
*target
,
290 uint32_t address
, uint32_t count
, uint32_t *checksum
)
292 LOG_WARNING("Not implemented: %s", __func__
);
297 int nds32_v3_target_create_common(struct target
*target
, struct nds32
*nds32
)
299 nds32
->register_map
= nds32_v3_register_mapping
;
300 nds32
->get_debug_reason
= nds32_v3_get_debug_reason
;
301 nds32
->enter_debug_state
= nds32_v3_debug_entry
;
302 nds32
->leave_debug_state
= nds32_v3_leave_debug_state
;
303 nds32
->get_watched_address
= nds32_v3_get_exception_address
;
305 /* Init target->arch_info in nds32_init_arch_info().
306 * After this, user could use target_to_nds32() to get nds32 object */
307 nds32_init_arch_info(target
, nds32
);
312 int nds32_v3_run_algorithm(struct target
*target
,
314 struct mem_param
*mem_params
,
316 struct reg_param
*reg_params
,
317 uint32_t entry_point
,
322 LOG_WARNING("Not implemented: %s", __func__
);
327 int nds32_v3_read_buffer(struct target
*target
, uint32_t address
,
328 uint32_t size
, uint8_t *buffer
)
330 struct nds32
*nds32
= target_to_nds32(target
);
331 struct nds32_memory
*memory
= &(nds32
->memory
);
333 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
334 (target
->state
!= TARGET_HALTED
)) {
335 LOG_WARNING("target was not halted");
336 return ERROR_TARGET_NOT_HALTED
;
339 uint32_t physical_address
;
340 /* BUG: If access range crosses multiple pages, the translation will not correct
341 * for second page or so. */
343 /* When DEX is set to one, hardware will enforce the following behavior without
344 * modifying the corresponding control bits in PSW.
346 * Disable all interrupts
347 * Become superuser mode
349 * Use MMU_CFG.DE as the data access endian
350 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
351 * Disable audio special features
352 * Disable inline function call
354 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
355 * to physical address.
357 if (ERROR_OK
== target
->type
->virt2phys(target
, address
, &physical_address
))
358 address
= physical_address
;
362 return nds32_read_buffer(target
, address
, size
, buffer
);
365 int nds32_v3_write_buffer(struct target
*target
, uint32_t address
,
366 uint32_t size
, const uint8_t *buffer
)
368 struct nds32
*nds32
= target_to_nds32(target
);
369 struct nds32_memory
*memory
= &(nds32
->memory
);
371 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
372 (target
->state
!= TARGET_HALTED
)) {
373 LOG_WARNING("target was not halted");
374 return ERROR_TARGET_NOT_HALTED
;
377 uint32_t physical_address
;
378 /* BUG: If access range crosses multiple pages, the translation will not correct
379 * for second page or so. */
381 /* When DEX is set to one, hardware will enforce the following behavior without
382 * modifying the corresponding control bits in PSW.
384 * Disable all interrupts
385 * Become superuser mode
387 * Use MMU_CFG.DE as the data access endian
388 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
389 * Disable audio special features
390 * Disable inline function call
392 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
393 * to physical address.
395 if (ERROR_OK
== target
->type
->virt2phys(target
, address
, &physical_address
))
396 address
= physical_address
;
400 return nds32_write_buffer(target
, address
, size
, buffer
);
403 int nds32_v3_read_memory(struct target
*target
, uint32_t address
,
404 uint32_t size
, uint32_t count
, uint8_t *buffer
)
406 struct nds32
*nds32
= target_to_nds32(target
);
407 struct nds32_memory
*memory
= &(nds32
->memory
);
409 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
410 (target
->state
!= TARGET_HALTED
)) {
411 LOG_WARNING("target was not halted");
412 return ERROR_TARGET_NOT_HALTED
;
415 uint32_t physical_address
;
416 /* BUG: If access range crosses multiple pages, the translation will not correct
417 * for second page or so. */
419 /* When DEX is set to one, hardware will enforce the following behavior without
420 * modifying the corresponding control bits in PSW.
422 * Disable all interrupts
423 * Become superuser mode
425 * Use MMU_CFG.DE as the data access endian
426 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
427 * Disable audio special features
428 * Disable inline function call
430 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
431 * to physical address.
433 if (ERROR_OK
== target
->type
->virt2phys(target
, address
, &physical_address
))
434 address
= physical_address
;
440 result
= nds32_read_memory(target
, address
, size
, count
, buffer
);
445 int nds32_v3_write_memory(struct target
*target
, uint32_t address
,
446 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
448 struct nds32
*nds32
= target_to_nds32(target
);
449 struct nds32_memory
*memory
= &(nds32
->memory
);
451 if ((NDS_MEMORY_ACC_CPU
== memory
->access_channel
) &&
452 (target
->state
!= TARGET_HALTED
)) {
453 LOG_WARNING("target was not halted");
454 return ERROR_TARGET_NOT_HALTED
;
457 uint32_t physical_address
;
458 /* BUG: If access range crosses multiple pages, the translation will not correct
459 * for second page or so. */
461 /* When DEX is set to one, hardware will enforce the following behavior without
462 * modifying the corresponding control bits in PSW.
464 * Disable all interrupts
465 * Become superuser mode
467 * Use MMU_CFG.DE as the data access endian
468 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
469 * Disable audio special features
470 * Disable inline function call
472 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
473 * to physical address.
475 if (ERROR_OK
== target
->type
->virt2phys(target
, address
, &physical_address
))
476 address
= physical_address
;
480 return nds32_write_memory(target
, address
, size
, count
, buffer
);
483 int nds32_v3_init_target(struct command_context
*cmd_ctx
,
484 struct target
*target
)
486 /* Initialize anything we can set up without talking to the target */
487 struct nds32
*nds32
= target_to_nds32(target
);
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)