OpenOCD
armv8_dpm.c File Reference

Implements various ARM DPM operations using architectural debug registers. More...

Include dependency graph for armv8_dpm.c:

Go to the source code of this file.

Macros

#define T32_FMTITR(instr)   (((instr & 0x0000FFFF) << 16) | ((instr & 0xFFFF0000) >> 16))
 

Functions

static int armv8_dpm_full_context (struct target *target)
 
enum arm_state armv8_dpm_get_core_state (struct arm_dpm *dpm)
 Get core state from EDSCR, without necessity to retrieve CPSR. More...
 
void armv8_dpm_handle_exception (struct arm_dpm *dpm, bool do_restore)
 
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 affected the debug module. More...
 
int armv8_dpm_modeswitch (struct arm_dpm *dpm, enum arm_mode mode)
 
static int armv8_dpm_read_core_reg (struct target *target, struct reg *r, int regnum, enum arm_mode mode)
 
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 IRQ) and state (such as ARM or Thumb). More...
 
void armv8_dpm_report_dscr (struct arm_dpm *dpm, uint32_t dscr)
 
int armv8_dpm_setup (struct arm_dpm *dpm)
 Hooks up this DPM to its associated target; call only once. More...
 
static int armv8_dpm_write_core_reg (struct target *target, struct reg *r, int regnum, enum arm_mode mode, uint8_t *value)
 
int armv8_dpm_write_dirty_registers (struct arm_dpm *dpm, bool bpwp)
 Writes all modified core registers for all processor modes. More...
 
static int dpmv8_add_breakpoint (struct target *target, struct breakpoint *bp)
 
static int dpmv8_add_watchpoint (struct target *target, struct watchpoint *wp)
 
static int dpmv8_bpwp_disable (struct arm_dpm *dpm, unsigned index_t)
 
static int dpmv8_bpwp_setup (struct arm_dpm *dpm, struct dpm_bpwp *xp, uint32_t addr, uint32_t length)
 
static int dpmv8_dpm_finish (struct arm_dpm *dpm)
 
static int dpmv8_dpm_prepare (struct arm_dpm *dpm)
 
static int dpmv8_exec_opcode (struct arm_dpm *dpm, uint32_t opcode, uint32_t *p_dscr)
 
static int dpmv8_instr_cpsr_sync (struct arm_dpm *dpm)
 
static int dpmv8_instr_execute (struct arm_dpm *dpm, uint32_t opcode)
 
static int dpmv8_instr_read_data_dcc (struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
 
static int dpmv8_instr_read_data_dcc_64 (struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
 
static int dpmv8_instr_read_data_r0 (struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
 
static int dpmv8_instr_read_data_r0_64 (struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
 
static int dpmv8_instr_write_data_dcc (struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
 
static int dpmv8_instr_write_data_dcc_64 (struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
 
static int dpmv8_instr_write_data_r0 (struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
 
static int dpmv8_instr_write_data_r0_64 (struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
 
static int dpmv8_maybe_update_bpwp (struct arm_dpm *dpm, bool bpwp, struct dpm_bpwp *xp, bool *set_p)
 
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_mrc (struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t *value)
 
static int dpmv8_read_dcc (struct armv8_common *armv8, uint32_t *data, uint32_t *dscr_p)
 
static int dpmv8_read_dcc_64 (struct armv8_common *armv8, uint64_t *data, uint32_t *dscr_p)
 
static int dpmv8_read_reg (struct arm_dpm *dpm, struct reg *r, unsigned regnum)
 
static int dpmv8_remove_breakpoint (struct target *target, struct breakpoint *bp)
 
static int dpmv8_remove_watchpoint (struct target *target, struct watchpoint *wp)
 
static int dpmv8_watchpoint_setup (struct arm_dpm *dpm, unsigned index_t, struct watchpoint *wp)
 
static int dpmv8_write_dcc (struct armv8_common *armv8, uint32_t data)
 
static int dpmv8_write_dcc_64 (struct armv8_common *armv8, uint64_t data)
 
static int dpmv8_write_reg (struct arm_dpm *dpm, struct reg *r, unsigned regnum)
 

Detailed Description

Implements various ARM DPM operations using architectural debug registers.

These routines layer over core-specific communication methods to cope with implementation differences between cores like ARM1136 and Cortex-A8.

The "Debug Programmers' Model" (DPM) for ARMv6 and ARMv7 is defined by Part C (Debug Architecture) of the ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition (ARM DDI 0406B). In OpenOCD, DPM operations are abstracted through internal programming interfaces to share code and to minimize needless differences in debug behavior between cores.

Definition in file armv8_dpm.c.

Macro Definition Documentation

◆ T32_FMTITR

#define T32_FMTITR (   instr)    (((instr & 0x0000FFFF) << 16) | ((instr & 0xFFFF0000) >> 16))

Definition at line 23 of file armv8_dpm.c.

Function Documentation

◆ armv8_dpm_full_context()

◆ armv8_dpm_get_core_state()

enum arm_state armv8_dpm_get_core_state ( struct arm_dpm dpm)

Get core state from EDSCR, without necessity to retrieve CPSR.

Definition at line 1 of file armv8_dpm.c.

Referenced by aarch64_debug_entry(), aarch64_set_breakpoint(), armv8_dpm_handle_exception(), armv8_dpm_modeswitch(), and dpmv8_exec_opcode().

◆ armv8_dpm_handle_exception()

◆ armv8_dpm_initialize()

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 affected the debug module.

Definition at line 1474 of file armv8_dpm.c.

References arm_dpm::arm, dpm_bp::bpwp, dpm_wp::bpwp, arm_dpm::bpwp_disable, arm_dpm::dbp, arm_dpm::dwp, ERROR_OK, LOG_WARNING, arm_dpm::nbp, dpm_bpwp::number, arm_dpm::nwp, arm::target, and target_name().

Referenced by aarch64_dpm_setup().

◆ armv8_dpm_modeswitch()

◆ armv8_dpm_read_core_reg()

static int armv8_dpm_read_core_reg ( struct target target,
struct reg r,
int  regnum,
enum arm_mode  mode 
)
static

◆ armv8_dpm_read_current_registers()

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 IRQ) and state (such as ARM or Thumb).

In normal operation this is called on entry to halting debug state, possibly after some other operations supporting restore of debug state or making sure the CPU is fully idle (drain write buffer, etc).

Definition at line 731 of file armv8_dpm.c.

References arm::arch_info, arm_dpm::arm, ARM_MODE_ANY, ARM_MODE_SYS, armv8_curel_from_core_mode(), ARMV8_FPCR, ARMV8_PC, ARMV8_R0, ARMV8_R1, armv8_reg_current(), armv8_set_cpsr(), ARMV8_SPSR_EL1, ARMV8_V0, arm::core_cache, arm::core_mode, arm::dpm, armv8_common::dpm, dpmv8_read_reg(), ERROR_OK, arm_dpm::finish, arm_dpm::instr_read_data_r0, arm_dpm::last_el, arm_reg::mode, arm_dpm::prepare, READ_REG_DSPSR, and reg_cache::reg_list.

Referenced by aarch64_debug_entry().

◆ armv8_dpm_report_dscr()

◆ armv8_dpm_setup()

int armv8_dpm_setup ( struct arm_dpm dpm)

Hooks up this DPM to its associated target; call only once.

This wraps an implementation of DPM primitives.

Initially this only covers the register cache.

Oh, and watchpoints. Yeah.

Definition at line 1392 of file armv8_dpm.c.

References target_type::add_breakpoint, target_type::add_watchpoint, arm_dpm::arm, arm_dpm::arm_reg_current, armv8_build_reg_cache(), armv8_dpm_full_context(), armv8_dpm_read_core_reg(), armv8_dpm_write_core_reg(), armv8_reg_current(), arm_dpm::bpwp_disable, arm::core_cache, arm_dpm::dbp, arm_dpm::didr, arm::dpm, dpmv8_add_breakpoint(), dpmv8_add_watchpoint(), dpmv8_bpwp_disable(), dpmv8_dpm_finish(), dpmv8_dpm_prepare(), dpmv8_instr_cpsr_sync(), dpmv8_instr_execute(), dpmv8_instr_read_data_dcc(), dpmv8_instr_read_data_dcc_64(), dpmv8_instr_read_data_r0(), dpmv8_instr_read_data_r0_64(), dpmv8_instr_write_data_dcc(), dpmv8_instr_write_data_dcc_64(), dpmv8_instr_write_data_r0(), dpmv8_instr_write_data_r0_64(), dpmv8_mcr(), dpmv8_mrc(), dpmv8_remove_breakpoint(), dpmv8_remove_watchpoint(), arm_dpm::dwp, ERROR_FAIL, ERROR_OK, arm_dpm::finish, arm::full_context, arm_dpm::instr_cpsr_sync, arm_dpm::instr_execute, arm_dpm::instr_read_data_dcc, arm_dpm::instr_read_data_dcc_64, arm_dpm::instr_read_data_r0, arm_dpm::instr_read_data_r0_64, arm_dpm::instr_write_data_dcc, arm_dpm::instr_write_data_dcc_64, arm_dpm::instr_write_data_r0, arm_dpm::instr_write_data_r0_64, LOG_INFO, arm::mcr, arm::mrc, arm_dpm::nbp, arm_dpm::nwp, arm_dpm::prepare, arm::read_core_reg, target_type::remove_breakpoint, target_type::remove_watchpoint, arm::target, target_name(), target::type, and arm::write_core_reg.

Referenced by aarch64_dpm_setup().

◆ armv8_dpm_write_core_reg()

static int armv8_dpm_write_core_reg ( struct target target,
struct reg r,
int  regnum,
enum arm_mode  mode,
uint8_t *  value 
)
static

◆ armv8_dpm_write_dirty_registers()

int armv8_dpm_write_dirty_registers ( struct arm_dpm dpm,
bool  bpwp 
)

Writes all modified core registers for all processor modes.

In normal operation this is called on exit from halting debug state.

Parameters
dpmrepresents the processor
bpwptrue ensures breakpoints and watchpoints are set, false ensures they are cleared

Definition at line 863 of file armv8_dpm.c.

References target_type::add_breakpoint, reg::arch_info, arm_dpm::arm, ARM_MODE_ANY, armv8_curel_from_core_mode(), armv8_dpm_modeswitch(), ARMV8_PC, ARMV8_XPSR, dpm_bp::bp, dpm_bp::bpwp, dpm_wp::bpwp, arm::core_cache, arm_dpm::dbp, reg::dirty, arm::dpm, dpmv8_add_breakpoint(), dpmv8_maybe_update_bpwp(), dpmv8_write_reg(), arm_dpm::dwp, ERROR_OK, reg::exist, arm_dpm::finish, arm_dpm::instr_cpsr_sync, breakpoint::is_set, watchpoint::is_set, arm_dpm::last_el, arm_reg::mode, arm_dpm::nbp, NULL, reg_cache::num_regs, arm_dpm::nwp, arm_dpm::prepare, reg_cache::reg_list, arm::target, target::type, reg::valid, and dpm_wp::wp.

Referenced by aarch64_restore_context().

◆ dpmv8_add_breakpoint()

◆ dpmv8_add_watchpoint()

static int dpmv8_add_watchpoint ( struct target target,
struct watchpoint wp 
)
static

◆ dpmv8_bpwp_disable()

static int dpmv8_bpwp_disable ( struct arm_dpm dpm,
unsigned  index_t 
)
static

◆ dpmv8_bpwp_setup()

static int dpmv8_bpwp_setup ( struct arm_dpm dpm,
struct dpm_bpwp xp,
uint32_t  addr,
uint32_t  length 
)
static

◆ dpmv8_dpm_finish()

static int dpmv8_dpm_finish ( struct arm_dpm dpm)
static

Definition at line 191 of file armv8_dpm.c.

References ERROR_OK.

Referenced by armv8_dpm_setup().

◆ dpmv8_dpm_prepare()

◆ dpmv8_exec_opcode()

◆ dpmv8_instr_cpsr_sync()

static int dpmv8_instr_cpsr_sync ( struct arm_dpm dpm)
static

◆ dpmv8_instr_execute()

static int dpmv8_instr_execute ( struct arm_dpm dpm,
uint32_t  opcode 
)
static

Definition at line 262 of file armv8_dpm.c.

References armv8_common::dpm, dpmv8_exec_opcode(), and NULL.

Referenced by armv8_dpm_setup().

◆ dpmv8_instr_read_data_dcc()

static int dpmv8_instr_read_data_dcc ( struct arm_dpm dpm,
uint32_t  opcode,
uint32_t *  data 
)
static

◆ dpmv8_instr_read_data_dcc_64()

static int dpmv8_instr_read_data_dcc_64 ( struct arm_dpm dpm,
uint32_t  opcode,
uint64_t *  data 
)
static

◆ dpmv8_instr_read_data_r0()

static int dpmv8_instr_read_data_r0 ( struct arm_dpm dpm,
uint32_t  opcode,
uint32_t *  data 
)
static

◆ dpmv8_instr_read_data_r0_64()

static int dpmv8_instr_read_data_r0_64 ( struct arm_dpm dpm,
uint32_t  opcode,
uint64_t *  data 
)
static

◆ dpmv8_instr_write_data_dcc()

static int dpmv8_instr_write_data_dcc ( struct arm_dpm dpm,
uint32_t  opcode,
uint32_t  data 
)
static

◆ dpmv8_instr_write_data_dcc_64()

static int dpmv8_instr_write_data_dcc_64 ( struct arm_dpm dpm,
uint32_t  opcode,
uint64_t  data 
)
static

◆ dpmv8_instr_write_data_r0()

static int dpmv8_instr_write_data_r0 ( struct arm_dpm dpm,
uint32_t  opcode,
uint32_t  data 
)
static

◆ dpmv8_instr_write_data_r0_64()

static int dpmv8_instr_write_data_r0_64 ( struct arm_dpm dpm,
uint32_t  opcode,
uint64_t  data 
)
static

◆ dpmv8_maybe_update_bpwp()

static int dpmv8_maybe_update_bpwp ( struct arm_dpm dpm,
bool  bpwp,
struct dpm_bpwp xp,
bool *  set_p 
)
static

◆ dpmv8_mcr()

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

◆ dpmv8_mrc()

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

◆ dpmv8_read_dcc()

static int dpmv8_read_dcc ( struct armv8_common armv8,
uint32_t *  data,
uint32_t *  dscr_p 
)
static

◆ dpmv8_read_dcc_64()

static int dpmv8_read_dcc_64 ( struct armv8_common armv8,
uint64_t *  data,
uint32_t *  dscr_p 
)
static

◆ dpmv8_read_reg()

◆ dpmv8_remove_breakpoint()

static int dpmv8_remove_breakpoint ( struct target target,
struct breakpoint bp 
)
static

◆ dpmv8_remove_watchpoint()

static int dpmv8_remove_watchpoint ( struct target target,
struct watchpoint wp 
)
static

◆ dpmv8_watchpoint_setup()

static int dpmv8_watchpoint_setup ( struct arm_dpm dpm,
unsigned  index_t,
struct watchpoint wp 
)
static

◆ dpmv8_write_dcc()

static int dpmv8_write_dcc ( struct armv8_common armv8,
uint32_t  data 
)
static

◆ dpmv8_write_dcc_64()

static int dpmv8_write_dcc_64 ( struct armv8_common armv8,
uint64_t  data 
)
static

◆ dpmv8_write_reg()

static int dpmv8_write_reg ( struct arm_dpm dpm,
struct reg r,
unsigned  regnum 
)
static