diff options
Diffstat (limited to 'src/target/cortex_a.c')
-rw-r--r-- | src/target/cortex_a.c | 121 |
1 files changed, 65 insertions, 56 deletions
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index cc1552d6..27b780e6 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -70,14 +70,6 @@ static int cortex_a8_virt2phys(struct target *target, static int cortex_a8_read_apb_ab_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); -/* - * FIXME do topology discovery using the ROM; don't - * assume this is an OMAP3. Also, allow for multiple ARMv7-A - * cores, with different AP numbering ... don't use a #define - * for these numbers, use per-core armv7a state. - */ -#define swjdp_memoryap 0 -#define swjdp_debugap 1 /* restore cp15_control_reg at resume */ static int cortex_a8_restore_cp15_control_reg(struct target *target) @@ -178,11 +170,11 @@ static int cortex_a8_init_debug_access(struct target *target) /* Unlocking the debug registers for modification * The debugport might be uninitialised so try twice */ - retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55); if (retval != ERROR_OK) { /* try again */ - retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55); if (retval == ERROR_OK) LOG_USER( @@ -192,7 +184,7 @@ static int cortex_a8_init_debug_access(struct target *target) 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, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_PRSR, &dummy); if (retval != ERROR_OK) return retval; @@ -225,7 +217,7 @@ static int cortex_a8_exec_opcode(struct target *target, /* Wait for InstrCompl bit to be set */ long long then = timeval_ms(); while ((dscr & DSCR_INSTR_COMP) == 0) { - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) { LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode); @@ -237,14 +229,14 @@ static int cortex_a8_exec_opcode(struct target *target, } } - retval = mem_ap_sel_write_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_write_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_ITR, opcode); if (retval != ERROR_OK) return retval; then = timeval_ms(); do { - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) { LOG_ERROR("Could not read DSCR register"); @@ -283,7 +275,7 @@ static int cortex_a8_read_regs_through_mem(struct target *target, uint32_t addre if (retval != ERROR_OK) return retval; - retval = mem_ap_sel_read_buf_u32(swjdp, swjdp_memoryap, + retval = mem_ap_sel_read_buf_u32(swjdp, armv7a->memory_ap, (uint8_t *)(®file[1]), 4*15, address); return retval; @@ -335,7 +327,7 @@ static int cortex_a8_dap_read_coreregister_u32(struct target *target, /* Wait for DTRRXfull then read DTRRTX */ long long then = timeval_ms(); while ((dscr & DSCR_DTR_TX_FULL) == 0) { - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) return retval; @@ -345,7 +337,7 @@ static int cortex_a8_dap_read_coreregister_u32(struct target *target, } } - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DTRTX, value); LOG_DEBUG("read DCC 0x%08" PRIx32, *value); @@ -364,7 +356,7 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value); /* Check that DCCRX is not full */ - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) return retval; @@ -382,7 +374,7 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */ LOG_DEBUG("write DCC 0x%08" PRIx32, value); - retval = mem_ap_sel_write_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_write_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DTRRX, value); if (retval != ERROR_OK) return retval; @@ -440,7 +432,7 @@ static int cortex_a8_dap_write_memap_register_u32(struct target *target, struct armv7a_common *armv7a = target_to_armv7a(target); struct adiv5_dap *swjdp = armv7a->arm.dap; - retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap, address, value); + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, address, value); return retval; } @@ -465,7 +457,7 @@ static int cortex_a8_write_dcc(struct cortex_a8_common *a8, uint32_t data) { LOG_DEBUG("write DCC 0x%08" PRIx32, data); return mem_ap_sel_write_u32(a8->armv7a_common.arm.dap, - swjdp_debugap, a8->armv7a_common.debug_base + CPUDBG_DTRRX, data); + a8->armv7a_common.debug_ap, a8->armv7a_common.debug_base + CPUDBG_DTRRX, data); } static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data, @@ -481,7 +473,7 @@ static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data, /* Wait for DTRRXfull */ long long then = timeval_ms(); while ((dscr & DSCR_DTR_TX_FULL) == 0) { - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, a8->armv7a_common.debug_ap, a8->armv7a_common.debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) @@ -492,7 +484,7 @@ static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data, } } - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, a8->armv7a_common.debug_ap, a8->armv7a_common.debug_base + CPUDBG_DTRTX, data); if (retval != ERROR_OK) return retval; @@ -514,7 +506,7 @@ static int cortex_a8_dpm_prepare(struct arm_dpm *dpm) /* set up invariant: INSTR_COMP is set after ever DPM operation */ long long then = timeval_ms(); for (;; ) { - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, a8->armv7a_common.debug_ap, a8->armv7a_common.debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) @@ -802,7 +794,7 @@ static int cortex_a8_poll(struct target *target) target_call_event_callbacks(target, TARGET_EVENT_HALTED); return retval; } - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) return retval; @@ -864,7 +856,7 @@ static int cortex_a8_halt(struct target *target) * Tell the core to be halted by writing DRCR with 0x1 * and then wait for the core to be halted. */ - retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DRCR, DRCR_HALT); if (retval != ERROR_OK) return retval; @@ -872,19 +864,19 @@ static int cortex_a8_halt(struct target *target) /* * enter halting debug mode */ - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) return retval; - retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, dscr | DSCR_HALT_DBG_MODE); if (retval != ERROR_OK) return retval; long long then = timeval_ms(); for (;; ) { - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) return retval; @@ -1010,7 +1002,7 @@ static int cortex_a8_internal_restart(struct target *target) * disable IRQs by default, with optional override... */ - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) return retval; @@ -1018,12 +1010,12 @@ static int cortex_a8_internal_restart(struct target *target) if ((dscr & DSCR_INSTR_COMP) == 0) LOG_ERROR("DSCR InstrCompl must be set before leaving debug!"); - retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, dscr & ~DSCR_ITR_EN); if (retval != ERROR_OK) return retval; - retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DRCR, DRCR_RESTART | DRCR_CLEAR_EXCEPTIONS); if (retval != ERROR_OK) @@ -1031,7 +1023,7 @@ static int cortex_a8_internal_restart(struct target *target) long long then = timeval_ms(); for (;; ) { - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) return retval; @@ -1123,7 +1115,7 @@ static int cortex_a8_debug_entry(struct target *target) LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr); /* REVISIT surely we should not re-read DSCR !! */ - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); if (retval != ERROR_OK) return retval; @@ -1135,7 +1127,7 @@ static int cortex_a8_debug_entry(struct target *target) /* Enable the ITR execution once we are in debug mode */ dscr |= DSCR_ITR_EN; - retval = mem_ap_sel_write_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, dscr); if (retval != ERROR_OK) return retval; @@ -1147,7 +1139,7 @@ static int cortex_a8_debug_entry(struct target *target) if (target->debug_reason == DBG_REASON_WATCHPOINT) { uint32_t wfar; - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_WFAR, &wfar); if (retval != ERROR_OK) @@ -2107,21 +2099,21 @@ static int cortex_a8_read_phys_memory(struct target *target, if (count && buffer) { - if (apsel == swjdp_memoryap) { + if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) { /* read memory through AHB-AP */ switch (size) { case 4: - retval = mem_ap_sel_read_buf_u32(swjdp, swjdp_memoryap, + retval = mem_ap_sel_read_buf_u32(swjdp, armv7a->memory_ap, buffer, 4 * count, address); break; case 2: - retval = mem_ap_sel_read_buf_u16(swjdp, swjdp_memoryap, + retval = mem_ap_sel_read_buf_u16(swjdp, armv7a->memory_ap, buffer, 2 * count, address); break; case 1: - retval = mem_ap_sel_read_buf_u8(swjdp, swjdp_memoryap, + retval = mem_ap_sel_read_buf_u8(swjdp, armv7a->memory_ap, buffer, count, address); break; } @@ -2151,7 +2143,7 @@ static int cortex_a8_read_memory(struct target *target, uint32_t address, /* cortex_a8 handles unaligned memory access */ LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address, size, count); - if (apsel == swjdp_memoryap) { + if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) { retval = cortex_a8_mmu(target, &enabled); if (retval != ERROR_OK) return retval; @@ -2195,21 +2187,21 @@ static int cortex_a8_write_phys_memory(struct target *target, if (count && buffer) { - if (apsel == swjdp_memoryap) { + if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) { /* write memory through AHB-AP */ switch (size) { case 4: - retval = mem_ap_sel_write_buf_u32(swjdp, swjdp_memoryap, + retval = mem_ap_sel_write_buf_u32(swjdp, armv7a->memory_ap, buffer, 4 * count, address); break; case 2: - retval = mem_ap_sel_write_buf_u16(swjdp, swjdp_memoryap, + retval = mem_ap_sel_write_buf_u16(swjdp, armv7a->memory_ap, buffer, 2 * count, address); break; case 1: - retval = mem_ap_sel_write_buf_u8(swjdp, swjdp_memoryap, + retval = mem_ap_sel_write_buf_u8(swjdp, armv7a->memory_ap, buffer, count, address); break; } @@ -2294,7 +2286,7 @@ static int cortex_a8_write_memory(struct target *target, uint32_t address, /* cortex_a8 handles unaligned memory access */ LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address, size, count); - if (apsel == swjdp_memoryap) { + if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) { LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address, size, count); @@ -2349,16 +2341,16 @@ static int cortex_a8_handle_target_request(void *priv) if (target->state == TARGET_RUNNING) { uint32_t request; uint32_t dscr; - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); /* check if we have data */ while ((dscr & DSCR_DTR_TX_FULL) && (retval == ERROR_OK)) { - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DTRTX, &request); if (retval == ERROR_OK) { target_request(target, request); - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap, armv7a->debug_base + CPUDBG_DSCR, &dscr); } } @@ -2387,6 +2379,23 @@ static int cortex_a8_examine_first(struct target *target) 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 */ @@ -2402,33 +2411,33 @@ static int cortex_a8_examine_first(struct target *target) } else armv7a->debug_base = target->dbgbase; - retval = mem_ap_sel_read_atomic_u32(swjdp, swjdp_debugap, + 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, swjdp_debugap, + 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, swjdp_debugap, + 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, swjdp_debugap, + 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, swjdp_debugap, + 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"); @@ -2571,14 +2580,14 @@ static int cortex_a8_virt2phys(struct target *target, struct armv7a_common *armv7a = target_to_armv7a(target); struct adiv5_dap *swjdp = armv7a->arm.dap; uint8_t apsel = swjdp->apsel; - if (apsel == swjdp_memoryap) { + if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) { uint32_t ret; retval = armv7a_mmu_translate_va(target, virt, &ret); if (retval != ERROR_OK) goto done; *phys = ret; - } else {/* use this method if swjdp_memoryap not selected + } else {/* use this method if armv7a->memory_ap not selected * mmu must be enable in order to get a correct translation */ retval = cortex_a8_mmu_modify(target, 1); if (retval != ERROR_OK) |