23 #define T32_FMTITR(instr) (((instr & 0x0000FFFF) << 16) | ((instr & 0xFFFF0000) >> 16))
43 int el = (dpm->
dscr >> 8) & 0x3;
44 int rw = (dpm->
dscr >> 10) & 0xF;
92 LOG_ERROR(
"Timeout waiting for read dcc");
128 LOG_ERROR(
"Timeout waiting for DTR_TX_FULL, dscr = 0x%08" PRIx32, dscr);
145 *data = *(uint32_t *)data | (uint64_t)higher << 32;
170 LOG_ERROR(
"Timeout waiting for dpm prepare");
180 LOG_ERROR(
"DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
198 uint32_t opcode, uint32_t *p_dscr)
213 LOG_ERROR(
"Could not read DSCR register, opcode = 0x%08" PRIx32, opcode);
217 LOG_ERROR(
"Timeout waiting for aarch64_exec_opcode");
235 LOG_ERROR(
"Could not read DSCR register");
239 LOG_ERROR(
"Timeout waiting for aarch64_exec_opcode");
268 uint32_t opcode, uint32_t data)
281 uint32_t opcode, uint64_t data)
294 uint32_t opcode, uint32_t data)
313 uint32_t opcode, uint64_t data)
346 uint32_t opcode, uint32_t *data)
360 uint32_t opcode, uint64_t *data)
374 uint32_t opcode, uint32_t *data)
393 uint32_t opcode, uint64_t *data)
420 static int dpmv8_bpwp_enable(
struct arm_dpm *
dpm,
unsigned int index_t,
444 LOG_DEBUG(
"A8: bpwp enable, vr %08" PRIx32
" cr %08" PRIx32, vr, cr);
471 LOG_DEBUG(
"A: bpwp disable, cr %08" PRIx32, cr);
483 uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,
494 LOG_DEBUG(
"MRC p%d, %d, r0, c%d, c%d, %d", cpnum,
495 (
int) op1, (
int) crn,
496 (
int) crm, (
int) op2);
508 uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,
519 LOG_DEBUG(
"MCR p%d, %d, r0, c%d, c%d, %d", cpnum,
520 (
int) op1, (
int) crn,
521 (
int) crm, (
int) op2);
542 unsigned int target_el;
550 LOG_DEBUG(
"restoring mode, cpsr = 0x%08"PRIx32, cpsr);
557 switch (cpsr & 0x1f) {
580 target_el = (cpsr >> 2) & 3;
584 LOG_ERROR(
"%s: Invalid target exception level %i", __func__, target_el);
619 LOG_INFO(
"Cannot reach EL %i, SPSR corrupted?", target_el);
658 LOG_DEBUG(
"READ: %s, %16.8llx", r->
name, (
unsigned long long) value_64);
660 LOG_DEBUG(
"READ: %s, %8.8x", r->
name, (
unsigned int) value_64);
662 }
else if (r->
size <= 128) {
663 uint64_t lvalue = 0, hvalue = 0;
664 retval = armv8->
read_reg_u128(armv8, regnum, &lvalue, &hvalue);
673 LOG_DEBUG(
"READ: %s, lvalue=%16.8llx", r->
name, (
unsigned long long) lvalue);
674 LOG_DEBUG(
"READ: %s, hvalue=%16.8llx", r->
name, (
unsigned long long) hvalue);
701 LOG_DEBUG(
"WRITE: %s, %16.8llx", r->
name, (
unsigned long long)value_64);
703 LOG_DEBUG(
"WRITE: %s, %8.8x", r->
name, (
unsigned int)value_64);
705 }
else if (r->
size <= 128) {
706 uint64_t lvalue, hvalue;
715 LOG_DEBUG(
"WRITE: %s, lvalue=%16.8llx", r->
name, (
unsigned long long) lvalue);
716 LOG_DEBUG(
"WRITE: %s, hvalue=%16.8llx", r->
name, (
unsigned long long) hvalue);
785 if (!r->exist || r->valid)
836 xp->
dirty = disable =
false;
842 xp->
dirty = disable =
true;
854 disable ?
"disable" :
"enable",
856 (xp->
number < 16) ?
"break" :
"watch",
890 for (
unsigned int i = 0; i < dpm->
nbp; i++) {
902 for (
unsigned int i = 0; i < dpm->
nwp; i++) {
922 for (
unsigned int i = 1; i < cache->
num_regs; i++) {
978 if (regnum < 0 || regnum >= max)
1006 if (regnum < 0 || regnum > max)
1050 for (
unsigned int i = 0; i < cache->
num_regs; i++) {
1080 (r->
num == 16) ? 17 : r->
num);
1125 control |= (1 << (
addr & 3)) << 5;
1130 control |= (3 << (
addr & 2)) << 5;
1137 control |= 0xf << 5;
1142 LOG_ERROR(
"unsupported {break,watch}point length/alignment");
1156 LOG_DEBUG(
"BPWP: addr %8.8" PRIx32
", control %" PRIx32
", number %d",
1178 for (
unsigned int i = 0; i < dpm->
nbp; i++) {
1179 if (!dpm->
dbp[i].
bp) {
1183 dpm->
dbp[i].
bp = bp;
1197 for (
unsigned int i = 0; i < dpm->
nbp; i++) {
1198 if (dpm->
dbp[i].
bp == bp) {
1215 struct dpm_wp *dwp = dpm->
dwp + index_t;
1220 LOG_DEBUG(
"watchpoint values and masking not supported");
1254 for (
unsigned int i = 0; i < dpm->
nwp; i++) {
1255 if (!dpm->
dwp[i].
wp) {
1271 for (
unsigned int i = 0; i < dpm->
nwp; i++) {
1272 if (dpm->
dwp[i].
wp == wp) {
1304 static const int clobbered_regs_by_el[3][5] = {
1310 el = (dpm->
dscr >> 8) & 3;
1314 LOG_ERROR(
"%s: EL %i is invalid, DSCR corrupted?", __func__, el);
1326 LOG_DEBUG(
"Exception taken to EL %i, DLR=0x%016"PRIx64
" DSPSR=0x%08"PRIx32,
1330 for (
int i = 0; i < 5; i++)
1331 cache->
reg_list[clobbered_regs_by_el[el-1][i]].
dirty =
true;
1356 dpm->
last_el = (dscr >> 8) & 3;
1457 dpm->
nbp = 1 + ((dpm->
didr >> 12) & 0xf);
1458 dpm->
dbp = calloc(dpm->
nbp,
sizeof(*dpm->
dbp));
1460 dpm->
nwp = 1 + ((dpm->
didr >> 20) & 0xf);
1461 dpm->
dwp = calloc(dpm->
nwp,
sizeof(*dpm->
dwp));
1463 if (!dpm->
dbp || !dpm->
dwp) {
1469 LOG_INFO(
"%s: hardware has %d breakpoints, %d watchpoints",
1489 for (i = 0; i < dpm->
nbp; i++) {
1493 for (i = 0; i < dpm->
nwp; i++) {
1498 LOG_WARNING(
"%s: can't disable breakpoints and watchpoints",
Holds the interface to ARM cores.
struct reg * armv8_reg_current(struct arm *arm, unsigned int regnum)
arm_mode
Represent state of an ARM core.
static struct arm * target_to_arm(const struct target *target)
Convert target handle to generic ARM target state handle.
arm_state
The PSR "T" and "J" bits define the mode of "classic ARM" cores.
struct reg_cache * armv8_build_reg_cache(struct target *target)
Builds cache of architecturally defined registers.
int mem_ap_read_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t *value)
Asynchronous (queued) read of a word from memory or a system register.
int mem_ap_write_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t value)
Asynchronous (queued) write of a word to memory or a system register.
int mem_ap_read_atomic_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t *value)
Synchronous read of a word from memory or a system register.
int mem_ap_write_atomic_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t value)
Synchronous write of a word to memory or a system register.
#define ARMV4_5_MRC(cp, op1, rd, crn, crm, op2)
#define ARMV4_5_MCR(cp, op1, rd, crn, crm, op2)
void armv8_set_cpsr(struct arm *arm, uint32_t cpsr)
Configures host-side ARM records to reflect the specified CPSR.
void armv8_select_reg_access(struct armv8_common *armv8, bool is_aarch64)
#define CPUV8_DBG_BVR_BASE
#define CPUV8_DBG_WVR_BASE
#define CPUV8_DBG_WCR_BASE
static unsigned int armv8_curel_from_core_mode(enum arm_mode core_mode)
#define CPUV8_DBG_BCR_BASE
static int dpmv8_add_watchpoint(struct target *target, struct watchpoint *wp)
void armv8_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
static int dpmv8_instr_execute(struct arm_dpm *dpm, uint32_t opcode)
static int dpmv8_mcr(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t value)
static int dpmv8_instr_write_data_dcc_64(struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
static int dpmv8_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp, uint32_t addr, uint32_t length)
static int armv8_dpm_read_core_reg(struct target *target, struct reg *r, int regnum, enum arm_mode mode)
static int dpmv8_instr_write_data_r0_64(struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
Writes all modified core registers for all processor modes.
static int dpmv8_add_breakpoint(struct target *target, struct breakpoint *bp)
static int dpmv8_instr_cpsr_sync(struct arm_dpm *dpm)
static int dpmv8_read_dcc_64(struct armv8_common *armv8, uint64_t *data, uint32_t *dscr_p)
static int dpmv8_watchpoint_setup(struct arm_dpm *dpm, unsigned int index_t, struct watchpoint *wp)
static int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned int regnum)
static int dpmv8_instr_read_data_dcc(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
enum arm_state armv8_dpm_get_core_state(struct arm_dpm *dpm)
Get core state from EDSCR, without necessity to retrieve CPSR.
static int dpmv8_dpm_finish(struct arm_dpm *dpm)
static int dpmv8_instr_write_data_dcc(struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
static int dpmv8_write_dcc(struct armv8_common *armv8, uint32_t data)
int armv8_dpm_read_current_registers(struct arm_dpm *dpm)
Read basic registers of the current context: R0 to R15, and CPSR in AArch32 state or R0 to R31,...
static int dpmv8_instr_read_data_r0_64(struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
static int dpmv8_remove_breakpoint(struct target *target, struct breakpoint *bp)
static int dpmv8_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned int regnum)
int armv8_dpm_initialize(struct arm_dpm *dpm)
Reinitializes DPM state at the beginning of a new debug session or after a reset which may have affec...
static int dpmv8_bpwp_disable(struct arm_dpm *dpm, unsigned int index_t)
static int dpmv8_instr_read_data_dcc_64(struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
static int dpmv8_write_dcc_64(struct armv8_common *armv8, uint64_t data)
static int dpmv8_instr_read_data_r0(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
static int dpmv8_read_dcc(struct armv8_common *armv8, uint32_t *data, uint32_t *dscr_p)
int armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)
static int armv8_dpm_write_core_reg(struct target *target, struct reg *r, int regnum, enum arm_mode mode, uint8_t *value)
static int dpmv8_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp, struct dpm_bpwp *xp, bool *set_p)
void armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore)
static int dpmv8_dpm_prepare(struct arm_dpm *dpm)
int armv8_dpm_setup(struct arm_dpm *dpm)
Hooks up this DPM to its associated target; call only once.
static int dpmv8_instr_write_data_r0(struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
static int dpmv8_mrc(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t *value)
static int dpmv8_remove_watchpoint(struct target *target, struct watchpoint *wp)
#define T32_FMTITR(instr)
static int dpmv8_exec_opcode(struct arm_dpm *dpm, uint32_t opcode, uint32_t *p_dscr)
static int armv8_dpm_full_context(struct target *target)
#define DSCRV8_ENTRY_BKPT
#define DSCRV8_ENTRY_HALT_STEP
#define DSCRV8_ENTRY_SW_ACCESS_DBG
#define DSCRV8_ENTRY_RESET_CATCH
#define DSCRV8_ENTRY_HALT_STEP_EXECLU
#define DSCRV8_ENTRY_WATCHPOINT
#define DSCRV8_ENTRY_HALT_STEP_NORMAL
#define DSCRV8_ENTRY_EXT_DEBUG
#define DSCRV8_ENTRY_OS_UNLOCK
#define DSCRV8_ENTRY_EXCEPTION_CATCH
void armv8_select_opcodes(struct armv8_common *armv8, bool state_is_aarch64)
#define ARMV8_MSR_GP(system, rt)
#define ARMV8_MRS(system, rt)
#define ARMV8_MSR_GP_XPSR_T1(r, rn, mask)
#define SYSTEM_DBG_DBGDTR_EL0
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
static uint64_t buf_get_u64(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 64-bit word.
static void buf_set_u64(uint8_t *_buffer, unsigned int first, unsigned int num, uint64_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
#define WATCHPOINT_IGNORE_DATA_VALUE_MASK
#define ERROR_COMMAND_SYNTAX_ERROR
The JTAG interface can be implemented with a software or hardware fifo.
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
target_addr_t addr
Start address to search for the control block.
This wraps an implementation of DPM primitives.
int(* instr_read_data_dcc)(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
Runs one instruction, reading data from dcc after execution.
uint64_t didr
Cache of DIDR.
int(* instr_write_data_r0_64)(struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
Runs one instruction, writing data to R0 before execution.
int(* instr_read_data_dcc_64)(struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
int(* instr_execute)(struct arm_dpm *dpm, uint32_t opcode)
Runs one instruction.
int(* instr_write_data_dcc_64)(struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
int(* instr_write_data_r0)(struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
Runs one instruction, writing data to R0 before execution.
int(* bpwp_enable)(struct arm_dpm *dpm, unsigned int index_value, uint32_t addr, uint32_t control)
Enables one breakpoint or watchpoint by writing to the hardware registers.
int(* finish)(struct arm_dpm *dpm)
Invoke after a series of instruction operations.
unsigned int last_el
Recent exception level on armv8.
int(* instr_write_data_dcc)(struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
Runs one instruction, writing data to DCC before execution.
int(* prepare)(struct arm_dpm *dpm)
Invoke before a series of instruction operations.
int(* instr_read_data_r0)(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
Runs one instruction, reading data from r0 after execution.
int(* instr_read_data_r0_64)(struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
struct reg *(* arm_reg_current)(struct arm *arm, unsigned int regnum)
int(* bpwp_disable)(struct arm_dpm *dpm, unsigned int index_value)
Disables one breakpoint or watchpoint by clearing its hardware control registers.
int(* instr_cpsr_sync)(struct arm_dpm *dpm)
Optional core-specific operation invoked after CPSR writes.
uint32_t dscr
Recent value of DSCR.
Represents a generic ARM core, with standard application registers.
int(* full_context)(struct target *target)
Retrieve all core registers, for display.
int(* mrc)(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t *value)
Read coprocessor register.
enum arm_mode core_mode
Record the current core mode: SVC, USR, or some other mode.
struct reg * cpsr
Handle to the CPSR/xPSR; valid in all core modes.
struct reg * pc
Handle to the PC; valid in all core modes.
int(* write_core_reg)(struct target *target, struct reg *reg, int num, enum arm_mode mode, uint8_t *value)
int(* read_core_reg)(struct target *target, struct reg *reg, int num, enum arm_mode mode)
Retrieve a single core register.
struct reg_cache * core_cache
struct arm_dpm * dpm
Handle for the debug module, if one is present.
int(* mcr)(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t value)
Write coprocessor register.
struct target * target
Backpointer to the target.
enum arm_state core_state
Record the current core state: ARM, Thumb, or otherwise.
int(* read_reg_u64)(struct armv8_common *armv8, int num, uint64_t *value)
int(* write_reg_u128)(struct armv8_common *armv8, int num, uint64_t lvalue, uint64_t hvalue)
struct adiv5_ap * debug_ap
int(* read_reg_u128)(struct armv8_common *armv8, int num, uint64_t *lvalue, uint64_t *hvalue)
int(* write_reg_u64)(struct armv8_common *armv8, int num, uint64_t value)
enum breakpoint_type type
int(* add_breakpoint)(struct target *target, struct breakpoint *breakpoint)
int(* add_watchpoint)(struct target *target, struct watchpoint *watchpoint)
int(* remove_breakpoint)(struct target *target, struct breakpoint *breakpoint)
int(* remove_watchpoint)(struct target *target, struct watchpoint *watchpoint)
enum target_debug_reason debug_reason
struct target_type * type
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE