static int cortex_a_examine_first(struct target *target)
{
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
struct adiv5_dap *swjdp = armv7a->arm.dap;
int i;
int retval = ERROR_OK;
uint32_t didr, ctypr, ttypr, cpuid, dbg_osreg;
/* We do one extra read to ensure DAP is configured,
- we call ahbap_debugport_init(swjdp) instead
*/
retval = ahbap_debugport_init(swjdp);
if (retval != ERROR_OK)
return retval;
/* Search for the APB-AB - it is needed for access to debug registers */
retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap);
if (retval != ERROR_OK) {
LOG_ERROR(“Could not find APB-AP for debug access”);
return retval;
}
/* Search for the AHB-AB */
retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7a->memory_ap);
if (retval != ERROR_OK)
{
/* AHB-AP not found - use APB-AP */
LOG_DEBUG(“Could not find AHB-AP - using APB-AP for memory access”);
armv7a->memory_ap_available = false;
}
else
{
armv7a->memory_ap_available = true;
}
if (!target->dbgbase_set) {
uint32_t dbgbase;
/* Get ROM Table base */
uint32_t apid;
int32_t coreidx = target->coreid;
LOG_DEBUG(“%s’s dbgbase is not set, trying to detect using the ROM table”,
target->cmd_name);
retval = dap_get_debugbase(swjdp, 1, &dbgbase, &apid);
if (retval != ERROR_OK)
return retval;
/* Lookup 0x15 – Processor DAP */
retval = dap_lookup_cs_component(swjdp, 1, dbgbase, 0x15,
&armv7a->debug_base, &coreidx);
if (retval != ERROR_OK) {
LOG_ERROR(“Can’t detect %s’s dbgbase from the ROM table; you need to specify it explicitly.”,
target->cmd_name);
return retval;
}
LOG_DEBUG(“Detected core %” PRId32 " dbgbase: %08" PRIx32,
coreidx, armv7a->debug_base);
} else
armv7a->debug_base = target->dbgbase;
retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_CPUID, &cpuid);
if (retval != ERROR_OK)
return retval;
retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_CPUID, &cpuid);
if (retval != ERROR_OK) {
LOG_DEBUG(“Examine %s failed”, “CPUID”);
return retval;
}
retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_CTYPR, &ctypr);
if (retval != ERROR_OK) {
LOG_DEBUG(“Examine %s failed”, “CTYPR”);
return retval;
}
retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_TTYPR, &ttypr);
if (retval != ERROR_OK) {
LOG_DEBUG(“Examine %s failed”, “TTYPR”);
return retval;
}
retval = mem_ap_sel_read_atomic_u32(swjdp,
armv7a->debug_ap,
armv7a->debug_base + CPUDBG_DIDR,
&didr);
if (retval != ERROR_OK)
{
LOG_DEBUG(“Examine %s failed”, “DIDR”);
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);
cortex_a->cpuid = cpuid;
cortex_a->ctypr = ctypr;
cortex_a->ttypr = ttypr;
cortex_a->didr = didr;
/* Unlocking the debug registers */
if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT ==
CORTEX_A15_PARTNUM) {
retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_OSLAR,
0);
if (retval != ERROR_OK)
return retval;
}
/* Unlocking the debug registers */
if ((cpuid & CORTEX_A_MIDR_PARTNUM_MASK) >> CORTEX_A_MIDR_PARTNUM_SHIFT ==
CORTEX_A7_PARTNUM) {
retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
armv7a->debug_base + CPUDBG_OSLAR,
0);
if (retval != ERROR_OK)
return retval;
}
retval = mem_ap_sel_read_atomic_u32(swjdp, 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);
armv7a->arm.core_type = ARM_MODE_MON;
retval = cortex_a_dpm_setup(cortex_a, didr);
if (retval != ERROR_OK)
return retval;
/* Setup Breakpoint Register Pairs */
cortex_a->brp_num = ((didr >> 24) & 0x0F) + 1;
cortex_a->brp_num_context = ((didr >> 20) & 0x0F) + 1;
cortex_a->brp_num_available = cortex_a->brp_num;
free(cortex_a->brp_list);
cortex_a->brp_list = calloc(cortex_a->brp_num, sizeof(struct cortex_a_brp));
/* cortex_a->brb_enabled = ???; */
for (i = 0; i < cortex_a->brp_num; i++)
{
cortex_a->brp_list*.used = 0;*
- if (i < (cortex_a->brp_num-cortex_a->brp_num_context))*
cortex_a->brp_list.type = BRP_NORMAL;
* else*
cortex_a->brp_list.type = BRP_CONTEXT;
cortex_a->brp_list.value = 0;
cortex_a->brp_list.control = 0;
cortex_a->brp_list.BRPn = i;
* }*
* LOG_DEBUG(“Configured %i hw breakpoints”, cortex_a->brp_num);
_//////////////////////////////////////////////////////////////////////////////////////_
cortex_a->wrp_num = ((didr >> 28) & 0x0F) + 1;
cortex_a->wrp_num_available = cortex_a->wrp_num;
free(cortex_a->wrp_list);
cortex_a->wrp_list = calloc(cortex_a->wrp_num, sizeof(struct cortex_a_wrp));
for (i = 0; i < cortex_a->wrp_num; i++)
_ {_
cortex_a->wrp_list.used = 0;
cortex_a->wrp_list.value = 0;
cortex_a->wrp_list.control = 0;
cortex_a->wrp_list.WRPn = i;
_ }_
LOG_DEBUG(“Configured %i hw watchpoints”, cortex_a->wrp_num);
target_set_examined(target);
return ERROR_OK;
_}*_