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 index_t,
444 LOG_DEBUG(
"A8: bpwp enable, vr %08x cr %08x",
445 (
unsigned) vr, (
unsigned) cr);
472 LOG_DEBUG(
"A: bpwp disable, cr %08x", (
unsigned) cr);
484 uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,
495 LOG_DEBUG(
"MRC p%d, %d, r0, c%d, c%d, %d", cpnum,
496 (
int) op1, (
int) crn,
497 (
int) crm, (
int) op2);
509 uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,
520 LOG_DEBUG(
"MCR p%d, %d, r0, c%d, c%d, %d", cpnum,
521 (
int) op1, (
int) crn,
522 (
int) crm, (
int) op2);
543 unsigned int target_el;
551 LOG_DEBUG(
"restoring mode, cpsr = 0x%08"PRIx32, cpsr);
558 switch (cpsr & 0x1f) {
581 target_el = (cpsr >> 2) & 3;
585 LOG_ERROR(
"%s: Invalid target exception level %i", __func__, target_el);
617 LOG_INFO(
"Cannot reach EL %i, SPSR corrupted?", target_el);
656 LOG_DEBUG(
"READ: %s, %16.8llx", r->
name, (
unsigned long long) value_64);
658 LOG_DEBUG(
"READ: %s, %8.8x", r->
name, (
unsigned int) value_64);
660 }
else if (r->
size <= 128) {
661 uint64_t lvalue = 0, hvalue = 0;
662 retval = armv8->
read_reg_u128(armv8, regnum, &lvalue, &hvalue);
671 LOG_DEBUG(
"READ: %s, lvalue=%16.8llx", r->
name, (
unsigned long long) lvalue);
672 LOG_DEBUG(
"READ: %s, hvalue=%16.8llx", r->
name, (
unsigned long long) hvalue);
699 LOG_DEBUG(
"WRITE: %s, %16.8llx", r->
name, (
unsigned long long)value_64);
701 LOG_DEBUG(
"WRITE: %s, %8.8x", r->
name, (
unsigned int)value_64);
703 }
else if (r->
size <= 128) {
704 uint64_t lvalue, hvalue;
713 LOG_DEBUG(
"WRITE: %s, lvalue=%16.8llx", r->
name, (
unsigned long long) lvalue);
714 LOG_DEBUG(
"WRITE: %s, hvalue=%16.8llx", r->
name, (
unsigned long long) hvalue);
772 for (
unsigned int i =
ARMV8_PC; i < cache->num_regs ; i++) {
776 if (!r->exist || r->valid)
827 xp->
dirty = disable =
false;
833 xp->
dirty = disable =
true;
845 disable ?
"disable" :
"enable",
847 (xp->
number < 16) ?
"break" :
"watch",
881 for (
unsigned i = 0; i < dpm->
nbp; i++) {
893 for (
unsigned i = 0; i < dpm->
nwp; i++) {
913 for (
unsigned i = 1; i < cache->
num_regs; i++) {
969 if (regnum < 0 || regnum >= max)
997 if (regnum < 0 || regnum > max)
1041 for (
unsigned i = 0; i < cache->
num_regs; i++) {
1071 (r->
num == 16) ? 17 : r->
num);
1116 control |= (1 << (
addr & 3)) << 5;
1121 control |= (3 << (
addr & 2)) << 5;
1128 control |= 0xf << 5;
1133 LOG_ERROR(
"unsupported {break,watch}point length/alignment");
1147 LOG_DEBUG(
"BPWP: addr %8.8" PRIx32
", control %" PRIx32
", number %d",
1169 for (
unsigned i = 0; i < dpm->
nbp; i++) {
1170 if (!dpm->
dbp[i].
bp) {
1174 dpm->
dbp[i].
bp = bp;
1188 for (
unsigned i = 0; i < dpm->
nbp; i++) {
1189 if (dpm->
dbp[i].
bp == bp) {
1206 struct dpm_wp *dwp = dpm->
dwp + index_t;
1211 LOG_DEBUG(
"watchpoint values and masking not supported");
1245 for (
unsigned i = 0; i < dpm->
nwp; i++) {
1246 if (!dpm->
dwp[i].
wp) {
1262 for (
unsigned i = 0; i < dpm->
nwp; i++) {
1263 if (dpm->
dwp[i].
wp == wp) {
1295 static const int clobbered_regs_by_el[3][5] = {
1301 el = (dpm->
dscr >> 8) & 3;
1305 LOG_ERROR(
"%s: EL %i is invalid, DSCR corrupted?", __func__, el);
1317 LOG_DEBUG(
"Exception taken to EL %i, DLR=0x%016"PRIx64
" DSPSR=0x%08"PRIx32,
1321 for (
int i = 0; i < 5; i++)
1322 cache->
reg_list[clobbered_regs_by_el[el-1][i]].
dirty =
true;
1347 dpm->
last_el = (dscr >> 8) & 3;
1448 dpm->
nbp = 1 + ((dpm->
didr >> 12) & 0xf);
1449 dpm->
dbp = calloc(dpm->
nbp,
sizeof(*dpm->
dbp));
1451 dpm->
nwp = 1 + ((dpm->
didr >> 20) & 0xf);
1452 dpm->
dwp = calloc(dpm->
nwp,
sizeof(*dpm->
dwp));
1454 if (!dpm->
dbp || !dpm->
dwp) {
1460 LOG_INFO(
"%s: hardware has %d breakpoints, %d watchpoints",
1480 for (i = 0; i < dpm->
nbp; i++) {
1484 for (i = 0; i < dpm->
nwp; i++) {
1489 LOG_WARNING(
"%s: can't disable breakpoints and watchpoints",
Holds the interface to ARM cores.
struct reg * armv8_reg_current(struct arm *arm, unsigned regnum)
arm_mode
Represent state of an ARM core.
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.
static struct arm * target_to_arm(struct target *target)
Convert target handle to generic ARM target state handle.
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_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
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 dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
static int armv8_dpm_read_core_reg(struct target *target, struct reg *r, int regnum, enum arm_mode mode)
static int dpmv8_bpwp_disable(struct arm_dpm *dpm, unsigned index_t)
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_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t, struct watchpoint *wp)
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_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; sets the core mode (such as USR or ...
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)
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_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 void buf_set_u64(uint8_t *_buffer, unsigned first, unsigned num, uint64_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned first, unsigned 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 first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 64-bit word.
#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 ...)
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(* finish)(struct arm_dpm *dpm)
Invoke after a series of instruction operations.
int(* bpwp_enable)(struct arm_dpm *dpm, unsigned index_value, uint32_t addr, uint32_t control)
Enables one breakpoint or watchpoint by writing to the hardware registers.
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(* bpwp_disable)(struct arm_dpm *dpm, unsigned index_value)
Disables one breakpoint or watchpoint by clearing its hardware control registers.
struct reg *(* arm_reg_current)(struct arm *arm, unsigned regnum)
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)
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(struct target *target)
Returns the instance-specific name of the specified target.
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE