diff options
Diffstat (limited to 'src/target/cortex_a.c')
-rw-r--r-- | src/target/cortex_a.c | 166 |
1 files changed, 47 insertions, 119 deletions
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 256edbc..1f51c4e 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -198,77 +198,15 @@ static int cortex_a_mmu_modify(struct target *target, int enable) /* * Cortex-A Basic debug access, very low level assumes state is saved */ -static int cortex_a8_init_debug_access(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - int retval; - - LOG_DEBUG(" "); - - /* Unlocking the debug registers for modification - * The debugport might be uninitialised so try twice */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55); - if (retval != ERROR_OK) { - /* try again */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55); - if (retval == ERROR_OK) - LOG_USER( - "Locking debug access failed on first, but succeeded on second try."); - } - - return retval; -} - -/* - * Cortex-A Basic debug access, very low level assumes state is saved - */ static int cortex_a_init_debug_access(struct target *target) { struct armv7a_common *armv7a = target_to_armv7a(target); int retval; - uint32_t dbg_osreg; - uint32_t cortex_part_num; - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - - LOG_DEBUG(" "); - cortex_part_num = (cortex_a->cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> - CORTEX_A_MIDR_PARTNUM_SHIFT; - - switch (cortex_part_num) { - case CORTEX_A7_PARTNUM: - case CORTEX_A15_PARTNUM: - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_OSLSR, - &dbg_osreg); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("DBGOSLSR 0x%" PRIx32, dbg_osreg); - - if (dbg_osreg & CPUDBG_OSLAR_LK_MASK) - /* Unlocking the DEBUG OS registers for modification */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_OSLAR, - 0); - break; - - case CORTEX_A5_PARTNUM: - case CORTEX_A8_PARTNUM: - case CORTEX_A9_PARTNUM: - default: - retval = cortex_a8_init_debug_access(target); - } - - if (retval != ERROR_OK) - return retval; - /* Clear Sticky Power Down status Bit in PRSR to enable access to - the registers in the Core Power Domain */ - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg); - LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR 0x%" PRIx32, target->coreid, dbg_osreg); + /* lock memory-mapped access to debug registers to prevent + * software interference */ + retval = mem_ap_write_atomic_u32(armv7a->debug_ap, + armv7a->debug_base + CPUDBG_LOCKACCESS, 0); if (retval != ERROR_OK) return retval; @@ -2981,7 +2919,7 @@ static int cortex_a_examine_first(struct target *target) int i; int retval = ERROR_OK; - uint32_t didr, ctypr, ttypr, cpuid, dbg_osreg; + uint32_t didr, cpuid, dbg_osreg; retval = dap_dp_init(swjdp); if (retval != ERROR_OK) { @@ -3043,79 +2981,69 @@ static int cortex_a_examine_first(struct target *target) armv7a->debug_base = target->dbgbase; retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_CPUID, &cpuid); - if (retval != ERROR_OK) - return retval; - - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_CPUID, &cpuid); - if (retval != ERROR_OK) { - LOG_DEBUG("Examine %s failed", "CPUID"); - return retval; - } - - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_CTYPR, &ctypr); - if (retval != ERROR_OK) { - LOG_DEBUG("Examine %s failed", "CTYPR"); - return retval; - } - - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_TTYPR, &ttypr); + armv7a->debug_base + CPUDBG_DIDR, &didr); if (retval != ERROR_OK) { - LOG_DEBUG("Examine %s failed", "TTYPR"); + LOG_DEBUG("Examine %s failed", "DIDR"); return retval; } retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DIDR, &didr); + armv7a->debug_base + CPUDBG_CPUID, &cpuid); if (retval != ERROR_OK) { - LOG_DEBUG("Examine %s failed", "DIDR"); + LOG_DEBUG("Examine %s failed", "CPUID"); return retval; } - LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid); - LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr); - LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr); LOG_DEBUG("didr = 0x%08" PRIx32, didr); + LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid); - cortex_a->cpuid = cpuid; - cortex_a->ctypr = ctypr; - cortex_a->ttypr = ttypr; cortex_a->didr = didr; + cortex_a->cpuid = cpuid; - /* Unlocking the debug registers */ - if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT == - CORTEX_A15_PARTNUM) { - - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_OSLAR, - 0); - - if (retval != ERROR_OK) - return retval; + retval = mem_ap_read_atomic_u32(armv7a->debug_ap, + armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR 0x%" PRIx32, target->coreid, dbg_osreg); + if ((dbg_osreg & PRSR_POWERUP_STATUS) == 0) { + LOG_ERROR("target->coreid %" PRId32 " powered down!", target->coreid); + target->state = TARGET_UNKNOWN; /* TARGET_NO_POWER? */ + return ERROR_TARGET_INIT_FAILED; } - /* Unlocking the debug registers */ - if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT == - CORTEX_A7_PARTNUM) { - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_OSLAR, - 0); + if (dbg_osreg & PRSR_STICKY_RESET_STATUS) + LOG_DEBUG("target->coreid %" PRId32 " was reset!", target->coreid); - if (retval != ERROR_OK) - return retval; - - } + /* Read DBGOSLSR and check if OSLK is implemented */ retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg); - + armv7a->debug_base + CPUDBG_OSLSR, &dbg_osreg); if (retval != ERROR_OK) return retval; + LOG_DEBUG("target->coreid %" PRId32 " DBGOSLSR 0x%" PRIx32, target->coreid, dbg_osreg); - LOG_DEBUG("target->coreid %" PRId32 " DBGPRSR 0x%" PRIx32, target->coreid, dbg_osreg); + /* check if OS Lock is implemented */ + if ((dbg_osreg & OSLSR_OSLM) == OSLSR_OSLM0 || (dbg_osreg & OSLSR_OSLM) == OSLSR_OSLM1) { + /* check if OS Lock is set */ + if (dbg_osreg & OSLSR_OSLK) { + LOG_DEBUG("target->coreid %" PRId32 " OSLock set! Trying to unlock", target->coreid); + + retval = mem_ap_write_atomic_u32(armv7a->debug_ap, + armv7a->debug_base + CPUDBG_OSLAR, + 0); + if (retval == ERROR_OK) + retval = mem_ap_read_atomic_u32(armv7a->debug_ap, + armv7a->debug_base + CPUDBG_OSLSR, &dbg_osreg); + + /* if we fail to access the register or cannot reset the OSLK bit, bail out */ + if (retval != ERROR_OK || (dbg_osreg & OSLSR_OSLK) != 0) { + LOG_ERROR("target->coreid %" PRId32 " OSLock sticky, core not powered?", + target->coreid); + target->state = TARGET_UNKNOWN; /* TARGET_NO_POWER? */ + return ERROR_TARGET_INIT_FAILED; + } + } + } armv7a->arm.core_type = ARM_MODE_MON; |