This is an automated email from Gerrit. Kamal Dasu (kdasu.k...@gmail.com) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/1601
-- gerrit commit ec21f019cfbabdd4ca76fa088047669556839ab2 Author: Kamal Dasu <kdasu.k...@gmail.com> Date: Thu Aug 29 14:02:19 2013 -0400 cortex_a: Add support for A15 MPCore Added Cortex-A15 support for DAP AHB-AP init code as per ADI V5 spec. Also added changes to make the APB MEM-AP to work with A15. Made the the cortex_a target code generic to work with A8, A9 and A15 single core or multicore implementation. Added armv7a code for os_border calculation to work for known A8, A9 and A15 platforms based on the ARM DDI 0344H, ARM DDI 0407F, ARM DDI 0406C ARMV7A architecture docs. Change-Id: Ib2803ab62588bf40f1ae4b9192b619af31525a1a Signed-off-by: Kamal Dasu <kdasu.k...@gmail.com> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index ce92f4c..1f72e5b 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -63,6 +63,7 @@ * * CoreSight(tm) DAP-Lite TRM, ARM DDI 0316D * Cortex-M3(tm) TRM, ARM DDI 0337G + * Cortex-A15(tm)TRM, ARM DDI 0438C */ #ifdef HAVE_CONFIG_H @@ -924,6 +925,7 @@ int mem_ap_sel_write_buf_u32_noincr(struct adiv5_dap *swjdp, uint8_t ap, #define MEM_CTRL_VLLSX_DBG_ACK (1<<6) #define MEM_CTRL_VLLSX_STAT_ACK (1<<7) + /** * */ @@ -1019,6 +1021,37 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap) return ERROR_OK; } + +/** + * + */ +int dap_syssec_check(struct adiv5_dap *dap) +{ + uint32_t val; + int retval; + + dap_ap_select(dap, 1); + + /* first check mdm-ap id register */ + retval = dap_queue_ap_read(dap, MDM_REG_ID, &val); + if (retval != ERROR_OK) + return retval; + + dap_run(dap); + + if (val == 0x24770002) { + LOG_DEBUG("id matches A15 Type is MEM-AP APB %08X", val); + retval = ERROR_OK; + } else { + retval = dap_syssec_kinetis_mdmap(dap); + } + + dap_ap_select(dap, 0); + + return retval; +} + + /** */ struct dap_syssec_filter { /** */ @@ -1698,7 +1731,13 @@ static int dap_info_command(struct command_context *cmd_ctx, type = "Cortex-A8 Debug"; full = "(Debug Unit)"; break; + case 0x4af: + type = "Cortex-A15 Debug"; + full = "(Debug Unit)"; + break; + default: + LOG_DEBUG("Part number is %x", part_num); type = "-*- unrecognized -*-"; full = ""; break; diff --git a/src/target/armv7a.c b/src/target/armv7a.c index 80d7a6e..998f4a8 100644 --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -88,11 +88,49 @@ done: /* (void) */ dpm->finish(dpm); } + +/* retrieve main id register */ +static int armv7a_read_midr(struct target *target) +{ + int retval = ERROR_FAIL; + struct armv7a_common *armv7a = target_to_armv7a(target); + struct arm_dpm *dpm = armv7a->arm.dpm; + uint32_t midr; + retval = dpm->prepare(dpm); + if (retval != ERROR_OK) + goto done; + /* MRC p15,0,<Rd>,c0,c0,0; read main id register*/ + + retval = dpm->instr_read_data_r0(dpm, + ARMV4_5_MRC(15, 0, 0, 0, 0, 0), + &midr); + if (retval != ERROR_OK) + goto done; + + armv7a->rev = (midr & 0xf); + armv7a->partnum = (midr >> 4) & 0xfff; + armv7a->arch = (midr >> 16) & 0xf; + armv7a->variant = (midr >> 20) & 0xf; + armv7a->implementor = (midr >> 24) & 0xff; + LOG_INFO("%s rev %x partnum %x arch %x variant %x implementor %x", + target->cmd_name, + armv7a->rev, + armv7a->partnum, + armv7a->arch, + armv7a->variant, + armv7a->implementor); + +done: + dpm->finish(dpm); + return retval; +} + static int armv7a_read_ttbcr(struct target *target) { struct armv7a_common *armv7a = target_to_armv7a(target); struct arm_dpm *dpm = armv7a->arm.dpm; uint32_t ttbcr; + uint32_t ttbr0, ttbr1; int retval = dpm->prepare(dpm); if (retval != ERROR_OK) goto done; @@ -102,14 +140,44 @@ static int armv7a_read_ttbcr(struct target *target) &ttbcr); if (retval != ERROR_OK) goto done; + + retval = dpm->instr_read_data_r0(dpm, + ARMV4_5_MRC(15, 0, 0, 2, 0, 0), + &ttbr0); + if (retval != ERROR_OK) + goto done; + + retval = dpm->instr_read_data_r0(dpm, + ARMV4_5_MRC(15, 0, 0, 2, 0, 1), + &ttbr1); + if (retval != ERROR_OK) + goto done; + + LOG_INFO("ttbcr %x ttbr0 %x ttbr1 %x", ttbcr, ttbr0, ttbr1); + armv7a->armv7a_mmu.ttbr1_used = ((ttbcr & 0x7) != 0) ? 1 : 0; - armv7a->armv7a_mmu.ttbr0_mask = 7 << (32 - ((ttbcr & 0x7))); -#if 0 - LOG_INFO("ttb1 %s ,ttb0_mask %x", - armv7a->armv7a_mmu.ttbr1_used ? "used" : "not used", - armv7a->armv7a_mmu.ttbr0_mask); -#endif - if (armv7a->armv7a_mmu.ttbr1_used == 1) { + armv7a->armv7a_mmu.ttbr0_used = ((ttbcr & 0x7) == 0) ? 1 : 0; + armv7a->armv7a_mmu.ttbr0_mask = 0; + + armv7a_read_midr(target); + + if (armv7a->partnum & 0xf) { + /* + * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition), + * document # ARM DDI 0406C + */ + armv7a->armv7a_mmu.ttbr0_mask = 1 << (14 - ((ttbcr & 0x7))); + } else { + /* ARM DDI 0344H , ARM DDI 0407F */ + armv7a->armv7a_mmu.ttbr0_mask = 7 << (32 - ((ttbcr & 0x7))); + } + + LOG_DEBUG("ttbr0 %s ttbr1 %s, ttb0_mask %x", + armv7a->armv7a_mmu.ttbr0_used ? "used" : "not used", + armv7a->armv7a_mmu.ttbr1_used ? "used" : "not used", + armv7a->armv7a_mmu.ttbr0_mask); + + if (armv7a->armv7a_mmu.ttbr0_mask) { LOG_INFO("SVC access above %x", (0xffffffff & armv7a->armv7a_mmu.ttbr0_mask)); armv7a->armv7a_mmu.os_border = 0xffffffff & armv7a->armv7a_mmu.ttbr0_mask; diff --git a/src/target/armv7a.h b/src/target/armv7a.h index 341114b..4341aca 100644 --- a/src/target/armv7a.h +++ b/src/target/armv7a.h @@ -77,6 +77,7 @@ struct armv7a_cache_common { struct armv7a_mmu_common { /* following field mmu working way */ + int32_t ttbr0_used; int32_t ttbr1_used; /* -1 not initialized, 0 no ttbr1 1 ttbr1 used and */ uint32_t ttbr0_mask;/* masked to be used */ uint32_t os_border; @@ -105,6 +106,11 @@ struct armv7a_common { uint8_t cluster_id; uint8_t cpu_id; bool is_armv7r; + uint32_t rev; + uint32_t partnum; + uint32_t arch; + uint32_t variant; + uint32_t implementor; /* cache specific to V7 Memory Management Unit compatible with v4_5*/ struct armv7a_mmu_common armv7a_mmu; diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 4097be0..5993102 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -20,6 +20,9 @@ * Copyright (C) Broadcom 2012 * * ehun...@broadcom.com : Cortex R4 support * * * + * Copyright (C) 2013 Kamal Dasu * + * kdasu.k...@gmail.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -38,6 +41,7 @@ * Cortex-A8(tm) TRM, ARM DDI 0344H * * Cortex-A9(tm) TRM, ARM DDI 0407F * * Cortex-A4(tm) TRM, ARM DDI 0363E * + * Cortex-A15(tm)TRM, ARM DDI 0438C * * * ***************************************************************************/ @@ -163,12 +167,11 @@ static int cortex_a_mmu_modify(struct target *target, int enable) /* * Cortex-A8 Basic debug access, very low level assumes state is saved */ -static int cortex_a_init_debug_access(struct target *target) +static int cortex_a8_init_debug_access(struct target *target) { struct armv7a_common *armv7a = target_to_armv7a(target); struct adiv5_dap *swjdp = armv7a->arm.dap; int retval; - uint32_t dummy; LOG_DEBUG(" "); @@ -184,12 +187,54 @@ static int cortex_a_init_debug_access(struct target *target) 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); + struct adiv5_dap *swjdp = armv7a->arm.dap; + 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_A15_PARTNUM: + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, + armv7a->debug_base + CPUDBG_OSLSR, + &dbg_osreg); + LOG_DEBUG("DBGOSLSR 0x%x ", dbg_osreg); + + if (dbg_osreg & CPUDBG_OSLAR_LK_MASK) + /* Unlocking the DEBUG OS registers for modification */ + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, + armv7a->debug_base + CPUDBG_OSLAR, + 0); + break; + + 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_sel_read_atomic_u32(swjdp, armv7a->debug_ap, - armv7a->debug_base + CPUDBG_PRSR, &dummy); + armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg); + LOG_DEBUG("target->coreid %d DBGPRSR 0x%x ", target->coreid, dbg_osreg); + if (retval != ERROR_OK) return retval; @@ -345,6 +390,16 @@ static int cortex_a_dap_read_coreregister_u32(struct target *target, armv7a->debug_base + CPUDBG_DTRTX, value); LOG_DEBUG("read DCC 0x%08" PRIx32, *value); + /* + * Need to take care of endianess before returning + */ + if (target->endianness == TARGET_LITTLE_ENDIAN) + *value = le_to_h_u32((uint8_t *) value); + else + *value = be_to_h_u32((uint8_t *) value); + + LOG_DEBUG("return DCC 0x%08x", *value); + return retval; } @@ -2386,7 +2441,7 @@ static int cortex_a_examine_first(struct target *target) struct adiv5_dap *swjdp = armv7a->arm.dap; int i; int retval = ERROR_OK; - uint32_t didr, ctypr, ttypr, cpuid; + 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 @@ -2465,6 +2520,37 @@ static int cortex_a_examine_first(struct target *target) 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; + + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, + armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg); + LOG_DEBUG("target->coreid %d DBGPRSR 0x%x ", target->coreid, dbg_osreg); + + 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; + armv7a->arm.core_type = ARM_MODE_MON; retval = cortex_a_dpm_setup(cortex_a, didr); if (retval != ERROR_OK) diff --git a/src/target/cortex_a.h b/src/target/cortex_a.h index 7b56fea..1aad849 100644 --- a/src/target/cortex_a.h +++ b/src/target/cortex_a.h @@ -33,12 +33,20 @@ #include "armv7a.h" #define CORTEX_A_COMMON_MAGIC 0x411fc082 +#define CORTEX_A15_COMMON_MAGIC 0x413fc0f1 + +#define CORTEX_A8_PARTNUM 0x8 +#define CORTEX_A9_PARTNUM 0x9 +#define CORTEX_A15_PARTNUM 0xf +#define CORTEX_A_MIDR_PARTNUM_MASK 0x00000ff0 +#define CORTEX_A_MIDR_PARTNUM_SHIFT 4 #define CPUDBG_CPUID 0xD00 #define CPUDBG_CTYPR 0xD04 #define CPUDBG_TTYPR 0xD0C #define CPUDBG_LOCKACCESS 0xFB0 #define CPUDBG_LOCKSTATUS 0xFB4 +#define CPUDBG_OSLAR_LK_MASK (1 << 1) #define BRP_NORMAL 0 #define BRP_CONTEXT 1 @@ -76,6 +84,11 @@ struct cortex_a_common { /* Use cortex_a_read_regs_through_mem for fast register reads */ int fast_reg_read; + uint32_t cpuid; + uint32_t ctypr; + uint32_t ttypr; + uint32_t didr; + struct armv7a_common armv7a_common; }; -- ------------------------------------------------------------------------------ Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more! Discover the easy way to master current and previous Microsoft technologies and advance your career. Get an incredible 1,500+ hours of step-by-step tutorial videos with LearnDevNow. Subscribe today and save! http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk _______________________________________________ OpenOCD-devel mailing list OpenOCD-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openocd-devel