aboutsummaryrefslogtreecommitdiff
path: root/src/target/cortex_a.c
diff options
context:
space:
mode:
authorMatthias Welwarsky <matthias.welwarsky@sysgo.com>2016-11-23 10:15:50 +0100
committerPaul Fertser <fercerpav@gmail.com>2016-12-08 12:25:35 +0000
commit0a2f1b29e678c97c7981090f769e841cbd583442 (patch)
tree432a69e74e48c8e6dbe96194c348d3d0e9d81ccc /src/target/cortex_a.c
parent53a936afc0092f4a65975d35bab0e10944fad3db (diff)
cortex_a: remove partnum magic from arp_examine and dbginit
Depending on the Debug implementation the "OS Lock" feature might be implemented or not. It is not actually depending on the part number of the implemented ARM core but on the DBGOSLSR.OSLM bits. This patch removes querying the part number and implements proper parsing of OSLM. Result is a more generic approach that will work out-of-box on more devices. Change-Id: I79e052869c2f9af1d7fdedef42faddb7292e7332 Signed-off-by: Matthias Welwarsky <matthias@welwarsky.de> Reviewed-on: http://openocd.zylin.com/3213 Tested-by: jenkins Reviewed-by: Paul Fertser <fercerpav@gmail.com>
Diffstat (limited to 'src/target/cortex_a.c')
-rw-r--r--src/target/cortex_a.c166
1 files changed, 47 insertions, 119 deletions
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 256edbca..1f51c4e7 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;