1 /* 2 * Copyright (C) 2009 by David Brownell 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef OPENOCD_TARGET_ARM_DPM_H 19 #define OPENOCD_TARGET_ARM_DPM_H 20 21 /** 22 * @file 23 * This is the interface to the Debug Programmers Model for ARMv6 and 24 * ARMv7 processors. ARMv6 processors (such as ARM11xx implementations) 25 * introduced a model which became part of the ARMv7-AR architecture 26 * which is most familiar through the Cortex-A series parts. While 27 * specific details differ (like how to write the instruction register), 28 * the high level models easily support shared code because those 29 * registers are compatible. 30 */ 31 32 struct dpm_bpwp { 33 unsigned number; 34 uint32_t address; 35 uint32_t control; 36 /* true if hardware state needs flushing */ 37 bool dirty; 38 }; 39 40 struct dpm_bp { 41 struct breakpoint *bp; 42 struct dpm_bpwp bpwp; 43 }; 44 45 struct dpm_wp { 46 struct watchpoint *wp; 47 struct dpm_bpwp bpwp; 48 }; 49 50 /** 51 * This wraps an implementation of DPM primitives. Each interface 52 * provider supplies a structure like this, which is the glue between 53 * upper level code and the lower level hardware access. 54 * 55 * It is a PRELIMINARY AND INCOMPLETE set of primitives, starting with 56 * support for CPU register access. 57 */ 58 struct arm_dpm { 59 struct arm *arm; 60 61 /** Cache of DIDR */ 62 uint64_t didr; 63 64 /** Invoke before a series of instruction operations */ 65 int (*prepare)(struct arm_dpm *dpm); 66 67 /** Invoke after a series of instruction operations */ 68 int (*finish)(struct arm_dpm *dpm); 69 70 /** Runs one instruction. */ 71 int (*instr_execute)(struct arm_dpm *dpm, uint32_t opcode); 72 73 /* WRITE TO CPU */ 74 75 /** Runs one instruction, writing data to DCC before execution. */ 76 int (*instr_write_data_dcc)(struct arm_dpm *dpm, 77 uint32_t opcode, uint32_t data); 78 79 int (*instr_write_data_dcc_64)(struct arm_dpm *dpm, 80 uint32_t opcode, uint64_t data); 81 82 /** Runs one instruction, writing data to R0 before execution. */ 83 int (*instr_write_data_r0)(struct arm_dpm *dpm, 84 uint32_t opcode, uint32_t data); 85 86 /** Runs one instruction, writing data to R0 before execution. */ 87 int (*instr_write_data_r0_64)(struct arm_dpm *dpm, 88 uint32_t opcode, uint64_t data); 89 90 /** Optional core-specific operation invoked after CPSR writes. */ 91 int (*instr_cpsr_sync)(struct arm_dpm *dpm); 92 93 /* READ FROM CPU */ 94 95 /** Runs one instruction, reading data from dcc after execution. */ 96 int (*instr_read_data_dcc)(struct arm_dpm *dpm, 97 uint32_t opcode, uint32_t *data); 98 99 int (*instr_read_data_dcc_64)(struct arm_dpm *dpm, 100 uint32_t opcode, uint64_t *data); 101 102 /** Runs one instruction, reading data from r0 after execution. */ 103 int (*instr_read_data_r0)(struct arm_dpm *dpm, 104 uint32_t opcode, uint32_t *data); 105 106 int (*instr_read_data_r0_64)(struct arm_dpm *dpm, 107 uint32_t opcode, uint64_t *data); 108 109 struct reg *(*arm_reg_current)(struct arm *arm, 110 unsigned regnum); 111 112 /* BREAKPOINT/WATCHPOINT SUPPORT */ 113 114 /** 115 * Enables one breakpoint or watchpoint by writing to the 116 * hardware registers. The specified breakpoint/watchpoint 117 * must currently be disabled. Indices 0..15 are used for 118 * breakpoints; indices 16..31 are for watchpoints. 119 */ 120 int (*bpwp_enable)(struct arm_dpm *dpm, unsigned index_value, 121 uint32_t addr, uint32_t control); 122 123 /** 124 * Disables one breakpoint or watchpoint by clearing its 125 * hardware control registers. Indices are the same ones 126 * accepted by bpwp_enable(). 127 */ 128 int (*bpwp_disable)(struct arm_dpm *dpm, unsigned index_value); 129 130 /* The breakpoint and watchpoint arrays are private to the 131 * DPM infrastructure. There are nbp indices in the dbp 132 * array. There are nwp indices in the dwp array. 133 */ 134 135 unsigned nbp; 136 unsigned nwp; 137 struct dpm_bp *dbp; 138 struct dpm_wp *dwp; 139 140 /** Address of the instruction which triggered a watchpoint. */ 141 target_addr_t wp_pc; 142 143 /** Recent value of DSCR. */ 144 uint32_t dscr; 145 146 /** Recent exception level on armv8 */ 147 unsigned int last_el; 148 149 /* FIXME -- read/write DCSR methods and symbols */ 150 }; 151 152 int arm_dpm_setup(struct arm_dpm *dpm); 153 int arm_dpm_initialize(struct arm_dpm *dpm); 154 155 int arm_dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum); 156 int arm_dpm_read_current_registers(struct arm_dpm *dpm); 157 int arm_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode); 158 159 int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp); 160 161 void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t wfar); 162 163 /* DSCR bits; see ARMv7a arch spec section C10.3.1. 164 * Not all v7 bits are valid in v6. 165 */ 166 #define DSCR_CORE_HALTED (0x1 << 0) 167 #define DSCR_CORE_RESTARTED (0x1 << 1) 168 #define DSCR_ENTRY_MASK (0xF << 2) 169 #define DSCR_STICKY_ABORT_PRECISE (0x1 << 6) 170 #define DSCR_STICKY_ABORT_IMPRECISE (0x1 << 7) 171 #define DSCR_STICKY_UNDEFINED (0x1 << 8) 172 #define DSCR_DBG_NOPWRDWN (0x1 << 9) /* v6 only */ 173 #define DSCR_DBG_ACK (0x1 << 10) 174 #define DSCR_INT_DIS (0x1 << 11) 175 #define DSCR_CP14_USR_COMMS (0x1 << 12) 176 #define DSCR_ITR_EN (0x1 << 13) 177 #define DSCR_HALT_DBG_MODE (0x1 << 14) 178 #define DSCR_MON_DBG_MODE (0x1 << 15) 179 #define DSCR_SEC_PRIV_INVASV_DIS (0x1 << 16) 180 #define DSCR_SEC_PRIV_NINVASV_DIS (0x1 << 17) 181 #define DSCR_NON_SECURE (0x1 << 18) 182 #define DSCR_DSCRD_IMPRECISE_ABORT (0x1 << 19) 183 #define DSCR_EXT_DCC_MASK (0x3 << 20) /* DTR mode */ /* bits 22, 23 are reserved */ 184 #define DSCR_INSTR_COMP (0x1 << 24) 185 #define DSCR_PIPE_ADVANCE (0x1 << 25) 186 #define DSCR_DTRTX_FULL_LATCHED (0x1 << 26) 187 #define DSCR_DTRRX_FULL_LATCHED (0x1 << 27) /* bit 28 is reserved */ 188 #define DSCR_DTR_TX_FULL (0x1 << 29) 189 #define DSCR_DTR_RX_FULL (0x1 << 30) /* bit 31 is reserved */ 190 191 #define DSCR_ENTRY(dscr) ((dscr) & 0x3f) 192 #define DSCR_RUN_MODE(dscr) ((dscr) & 0x03) 193 194 195 /* Methods of entry into debug mode */ 196 #define DSCR_ENTRY_HALT_REQ (0x03) 197 #define DSCR_ENTRY_BREAKPOINT (0x07) 198 #define DSCR_ENTRY_IMPRECISE_WATCHPT (0x0B) 199 #define DSCR_ENTRY_BKPT_INSTR (0x0F) 200 #define DSCR_ENTRY_EXT_DBG_REQ (0x13) 201 #define DSCR_ENTRY_VECT_CATCH (0x17) 202 #define DSCR_ENTRY_D_SIDE_ABORT (0x1B) /* v6 only */ 203 #define DSCR_ENTRY_I_SIDE_ABORT (0x1F) /* v6 only */ 204 #define DSCR_ENTRY_OS_UNLOCK (0x23) 205 #define DSCR_ENTRY_PRECISE_WATCHPT (0x2B) 206 207 /* DTR modes */ 208 #define DSCR_EXT_DCC_NON_BLOCKING (0x0 << 20) 209 #define DSCR_EXT_DCC_STALL_MODE (0x1 << 20) 210 #define DSCR_EXT_DCC_FAST_MODE (0x2 << 20) /* bits 22, 23 are reserved */ 211 212 213 214 215 216 /* DRCR (debug run control register) bits */ 217 #define DRCR_HALT (1 << 0) 218 #define DRCR_RESTART (1 << 1) 219 #define DRCR_CLEAR_EXCEPTIONS (1 << 2) 220 221 void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dcsr); 222 223 /* PRCR (Device Power-down and Reset Control Register) bits */ 224 #define PRCR_DEBUG_NO_POWER_DOWN (1 << 0) 225 #define PRCR_WARM_RESET (1 << 1) 226 #define PRCR_HOLD_NON_DEBUG_RESET (1 << 2) 227 228 /* PRSR (Device Power-down and Reset Status Register) bits */ 229 #define PRSR_POWERUP_STATUS (1 << 0) 230 #define PRSR_STICKY_POWERDOWN_STATUS (1 << 1) 231 #define PRSR_RESET_STATUS (1 << 2) 232 #define PRSR_STICKY_RESET_STATUS (1 << 3) 233 #define PRSR_HALTED (1 << 4) /* v7.1 Debug only */ 234 #define PRSR_OSLK (1 << 5) /* v7.1 Debug only */ 235 #define PRSR_DLK (1 << 6) /* v7.1 Debug only */ 236 237 /* OSLSR (OS Lock Status Register) bits */ 238 #define OSLSR_OSLM0 (1 << 0) 239 #define OSLSR_OSLK (1 << 1) 240 #define OSLSR_nTT (1 << 2) 241 #define OSLSR_OSLM1 (1 << 3) 242 #define OSLSR_OSLM (OSLSR_OSLM0|OSLSR_OSLM1) 243 244 #endif /* OPENOCD_TARGET_ARM_DPM_H */ 245