X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farm_dpm.c;h=bd9c5d1613c7c08257d7131b532c362cd645c823;hb=0a1b7dcfc40385f09b5eb088cd97d6ff25a5816d;hp=434c63e17a4298bb354bcab4da17b1b910dec741;hpb=c2af99d4717837761b6df750e1fe75797c910b23;p=openocd.git diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index 434c63e17a..bd9c5d1613 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -21,12 +21,13 @@ #include "config.h" #endif -#include "armv4_5.h" /* REVISIT to become arm.h */ +#include "arm.h" #include "arm_dpm.h" -#include "jtag.h" +#include #include "register.h" #include "breakpoints.h" #include "target_type.h" +#include "arm_opcodes.h" /** @@ -55,7 +56,9 @@ static int dpm_mrc(struct target *target, int cpnum, if (retval != ERROR_OK) return retval; - LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum, op1, CRn, CRm, op2); + LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum, + (int) op1, (int) CRn, + (int) CRm, (int) op2); /* read coprocessor register into R0; return via DCC */ retval = dpm->instr_read_data_r0(dpm, @@ -78,7 +81,9 @@ static int dpm_mcr(struct target *target, int cpnum, if (retval != ERROR_OK) return retval; - LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum, op1, CRn, CRm, op2); + LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum, + (int) op1, (int) CRn, + (int) CRm, (int) op2); /* read DCC into r0; then write coprocessor register from R0 */ retval = dpm->instr_write_data_r0(dpm, @@ -98,13 +103,13 @@ static int dpm_mcr(struct target *target, int cpnum, /* Toggles between recorded core mode (USR, SVC, etc) and a temporary one. * Routines *must* restore the original mode before returning!! */ -static int dpm_modeswitch(struct arm_dpm *dpm, enum armv4_5_mode mode) +static int dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode) { int retval; uint32_t cpsr; /* restore previous mode */ - if (mode == ARMV4_5_MODE_ANY) + if (mode == ARM_MODE_ANY) cpsr = buf_get_u32(dpm->arm->cpsr->value, 0, 32); /* else force to the specified mode */ @@ -143,14 +148,14 @@ static int dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) * is always right except in those broken-by-intent cases. */ switch (dpm->arm->core_state) { - case ARMV4_5_STATE_ARM: + case ARM_STATE_ARM: value -= 8; break; - case ARMV4_5_STATE_THUMB: + case ARM_STATE_THUMB: case ARM_STATE_THUMB_EE: value -= 4; break; - case ARMV4_5_STATE_JAZELLE: + case ARM_STATE_JAZELLE: /* core-specific ... ? */ LOG_WARNING("Jazelle PC adjustment unknown"); break; @@ -276,6 +281,7 @@ fail: * Writes all modified core registers for all processor modes. In normal * operation this is called on exit from halting debug state. * + * @param dpm: represents the processor * @param bpwp: true ensures breakpoints and watchpoints are set, * false ensures they are cleared */ @@ -324,7 +330,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) retval = dpm->bpwp_disable(dpm, 16 + i); else retval = dpm->bpwp_enable(dpm, 16 + i, - wp->address, dwp->control); + wp->address & ~3, dwp->control); if (retval != ERROR_OK) LOG_ERROR("%s: can't %s HW watchpoint %d", @@ -343,7 +349,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) * actually find anything to do... */ do { - enum armv4_5_mode mode = ARMV4_5_MODE_ANY; + enum arm_mode mode = ARM_MODE_ANY; did_write = false; @@ -365,7 +371,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) /* may need to pick and set a mode */ if (!did_write) { - enum armv4_5_mode tmode; + enum arm_mode tmode; did_write = true; mode = tmode = r->mode; @@ -377,10 +383,10 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) * we "know" core mode is accurate * since we haven't changed it yet */ - if (arm->core_mode == ARMV4_5_MODE_FIQ - && ARMV4_5_MODE_ANY + if (arm->core_mode == ARM_MODE_FIQ + && ARM_MODE_ANY != mode) - tmode = ARMV4_5_MODE_USR; + tmode = ARM_MODE_USR; break; case 16: /* SPSR */ @@ -389,7 +395,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) } /* REVISIT error checks */ - if (tmode != ARMV4_5_MODE_ANY) + if (tmode != ARM_MODE_ANY) retval = dpm_modeswitch(dpm, tmode); } if (r->mode != mode) @@ -407,7 +413,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) * or it's dirty. Must write PC to ensure the return address is * defined, and must not write it before CPSR. */ - retval = dpm_modeswitch(dpm, ARMV4_5_MODE_ANY); + retval = dpm_modeswitch(dpm, ARM_MODE_ANY); arm->cpsr->dirty = false; retval = dpm_write_reg(dpm, &cache->reg_list[15], 15); @@ -422,21 +428,21 @@ done: return retval; } -/* Returns ARMV4_5_MODE_ANY or temporary mode to use while reading the +/* Returns ARM_MODE_ANY or temporary mode to use while reading the * specified register ... works around flakiness from ARM core calls. * Caller already filtered out SPSR access; mode is never MODE_SYS * or MODE_ANY. */ -static enum armv4_5_mode dpm_mapmode(struct arm *arm, - unsigned num, enum armv4_5_mode mode) +static enum arm_mode dpm_mapmode(struct arm *arm, + unsigned num, enum arm_mode mode) { - enum armv4_5_mode amode = arm->core_mode; + enum arm_mode amode = arm->core_mode; /* don't switch if the mode is already correct */ - if (amode == ARMV4_5_MODE_SYS) - amode = ARMV4_5_MODE_USR; + if (amode == ARM_MODE_SYS) + amode = ARM_MODE_USR; if (mode == amode) - return ARMV4_5_MODE_ANY; + return ARM_MODE_ANY; switch (num) { /* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */ @@ -446,7 +452,7 @@ static enum armv4_5_mode dpm_mapmode(struct arm *arm, break; /* r8..r12 aren't shadowed for anything except FIQ */ case 8 ... 12: - if (mode == ARMV4_5_MODE_FIQ) + if (mode == ARM_MODE_FIQ) return mode; break; /* r13/sp, and r14/lr are always shadowed */ @@ -457,7 +463,7 @@ static enum armv4_5_mode dpm_mapmode(struct arm *arm, LOG_WARNING("invalid register #%u", num); break; } - return ARMV4_5_MODE_ANY; + return ARM_MODE_ANY; } @@ -468,7 +474,7 @@ static enum armv4_5_mode dpm_mapmode(struct arm *arm, */ static int arm_dpm_read_core_reg(struct target *target, struct reg *r, - int regnum, enum armv4_5_mode mode) + int regnum, enum arm_mode mode) { struct arm_dpm *dpm = target_to_arm(target)->dpm; int retval; @@ -477,7 +483,7 @@ static int arm_dpm_read_core_reg(struct target *target, struct reg *r, return ERROR_INVALID_ARGUMENTS; if (regnum == 16) { - if (mode != ARMV4_5_MODE_ANY) + if (mode != ARM_MODE_ANY) regnum = 17; } else mode = dpm_mapmode(dpm->arm, regnum, mode); @@ -490,7 +496,7 @@ static int arm_dpm_read_core_reg(struct target *target, struct reg *r, if (retval != ERROR_OK) return retval; - if (mode != ARMV4_5_MODE_ANY) { + if (mode != ARM_MODE_ANY) { retval = dpm_modeswitch(dpm, mode); if (retval != ERROR_OK) goto fail; @@ -499,8 +505,8 @@ static int arm_dpm_read_core_reg(struct target *target, struct reg *r, retval = dpm_read_reg(dpm, r, regnum); /* always clean up, regardless of error */ - if (mode != ARMV4_5_MODE_ANY) - /* (void) */ dpm_modeswitch(dpm, ARMV4_5_MODE_ANY); + if (mode != ARM_MODE_ANY) + /* (void) */ dpm_modeswitch(dpm, ARM_MODE_ANY); fail: /* (void) */ dpm->finish(dpm); @@ -508,7 +514,7 @@ fail: } static int arm_dpm_write_core_reg(struct target *target, struct reg *r, - int regnum, enum armv4_5_mode mode, uint32_t value) + int regnum, enum arm_mode mode, uint32_t value) { struct arm_dpm *dpm = target_to_arm(target)->dpm; int retval; @@ -518,7 +524,7 @@ static int arm_dpm_write_core_reg(struct target *target, struct reg *r, return ERROR_INVALID_ARGUMENTS; if (regnum == 16) { - if (mode != ARMV4_5_MODE_ANY) + if (mode != ARM_MODE_ANY) regnum = 17; } else mode = dpm_mapmode(dpm->arm, regnum, mode); @@ -531,7 +537,7 @@ static int arm_dpm_write_core_reg(struct target *target, struct reg *r, if (retval != ERROR_OK) return retval; - if (mode != ARMV4_5_MODE_ANY) { + if (mode != ARM_MODE_ANY) { retval = dpm_modeswitch(dpm, mode); if (retval != ERROR_OK) goto fail; @@ -540,8 +546,8 @@ static int arm_dpm_write_core_reg(struct target *target, struct reg *r, retval = dpm_write_reg(dpm, r, regnum); /* always clean up, regardless of error */ - if (mode != ARMV4_5_MODE_ANY) - /* (void) */ dpm_modeswitch(dpm, ARMV4_5_MODE_ANY); + if (mode != ARM_MODE_ANY) + /* (void) */ dpm_modeswitch(dpm, ARM_MODE_ANY); fail: /* (void) */ dpm->finish(dpm); @@ -561,7 +567,7 @@ static int arm_dpm_full_context(struct target *target) goto done; do { - enum armv4_5_mode mode = ARMV4_5_MODE_ANY; + enum arm_mode mode = ARM_MODE_ANY; did_read = false; @@ -588,8 +594,8 @@ static int arm_dpm_full_context(struct target *target) /* For R8..R12 when we've entered debug * state in FIQ mode... patch mode. */ - if (mode == ARMV4_5_MODE_ANY) - mode = ARMV4_5_MODE_USR; + if (mode == ARM_MODE_ANY) + mode = ARM_MODE_USR; /* REVISIT error checks */ retval = dpm_modeswitch(dpm, mode); @@ -606,7 +612,7 @@ static int arm_dpm_full_context(struct target *target) } while (did_read); - retval = dpm_modeswitch(dpm, ARMV4_5_MODE_ANY); + retval = dpm_modeswitch(dpm, ARM_MODE_ANY); /* (void) */ dpm->finish(dpm); done: return retval; @@ -739,14 +745,14 @@ static int dpm_remove_watchpoint(struct target *target, struct watchpoint *wp) void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr) { switch (dpm->arm->core_state) { - case ARMV4_5_STATE_ARM: + case ARM_STATE_ARM: addr -= 8; break; - case ARMV4_5_STATE_THUMB: + case ARM_STATE_THUMB: case ARM_STATE_THUMB_EE: addr -= 4; break; - case ARMV4_5_STATE_JAZELLE: + case ARM_STATE_JAZELLE: /* ?? */ break; } @@ -755,6 +761,42 @@ void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr) /*----------------------------------------------------------------------*/ +/* + * Other debug and support utilities + */ + +void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr) +{ + struct target *target = dpm->arm->target; + + dpm->dscr = dscr; + + /* Examine debug reason */ + switch (DSCR_ENTRY(dscr)) { + case 6: /* Data abort (v6 only) */ + case 7: /* Prefetch abort (v6 only) */ + /* FALL THROUGH -- assume a v6 core in abort mode */ + case 0: /* HALT request from debugger */ + case 4: /* EDBGRQ */ + target->debug_reason = DBG_REASON_DBGRQ; + break; + case 1: /* HW breakpoint */ + case 3: /* SW BKPT */ + case 5: /* vector catch */ + target->debug_reason = DBG_REASON_BREAKPOINT; + break; + case 2: /* asynch watchpoint */ + case 10: /* precise watchpoint */ + target->debug_reason = DBG_REASON_WATCHPOINT; + break; + default: + target->debug_reason = DBG_REASON_UNDEFINED; + break; + } +} + +/*----------------------------------------------------------------------*/ + /* * Setup and management support. */ @@ -778,7 +820,7 @@ int arm_dpm_setup(struct arm_dpm *dpm) arm->read_core_reg = arm_dpm_read_core_reg; arm->write_core_reg = arm_dpm_write_core_reg; - cache = armv4_5_build_reg_cache(target, arm); + cache = arm_build_reg_cache(target, arm); if (!cache) return ERROR_FAIL;