X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fcortex_a8.c;h=3c80923fc08e7c0743bd65576303a60e6ba75ec6;hp=ee79d63f793c95c3eac2a1fb0951ba40244676f9;hb=f1f8d9a6c9b1fd35d79627b568faa2409f13311f;hpb=4d238c7f91a73beebe1e71594b19ac39c62ff408 diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c index ee79d63f79..3c80923fc0 100644 --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -11,6 +11,9 @@ * Copyright (C) 2009 by Dirk Behme * * dirk.behme@gmail.com - copy from cortex_m3 * * * + * Copyright (C) 2010 Øyvind Harboe * + * oyvind.harboe@zylin.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 * @@ -55,11 +58,11 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, static int cortex_a8_mmu(struct target *target, int *enabled); static int cortex_a8_virt2phys(struct target *target, uint32_t virt, uint32_t *phys); -static void cortex_a8_disable_mmu_caches(struct target *target, int mmu, +static int cortex_a8_disable_mmu_caches(struct target *target, int mmu, int d_u_cache, int i_cache); -static void cortex_a8_enable_mmu_caches(struct target *target, int mmu, +static int cortex_a8_enable_mmu_caches(struct target *target, int mmu, int d_u_cache, int i_cache); -static uint32_t cortex_a8_get_ttb(struct target *target); +static int cortex_a8_get_ttb(struct target *target, uint32_t *result); /* @@ -70,7 +73,6 @@ static uint32_t cortex_a8_get_ttb(struct target *target); */ #define swjdp_memoryap 0 #define swjdp_debugap 1 -#define OMAP3530_DEBUG_BASE 0x54011000 /* * Cortex-A8 Basic debug access, very low level assumes state is saved @@ -92,6 +94,10 @@ static int cortex_a8_init_debug_access(struct target *target) { /* try again */ retval = mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55); + if (retval == ERROR_OK) + { + LOG_USER("Locking debug access failed on first, but succeeded on second try."); + } } if (retval != ERROR_OK) return retval; @@ -105,7 +111,7 @@ static int cortex_a8_init_debug_access(struct target *target) /* Resync breakpoint registers */ - /* Since this is likley called from init or reset, update targtet state information*/ + /* Since this is likely called from init or reset, update target state information*/ retval = cortex_a8_poll(target); return retval; @@ -129,6 +135,7 @@ static int cortex_a8_exec_opcode(struct target *target, LOG_DEBUG("exec opcode 0x%08" PRIx32, opcode); /* Wait for InstrCompl bit to be set */ + long long then = timeval_ms(); while ((dscr & DSCR_INSTR_COMP) == 0) { retval = mem_ap_read_atomic_u32(swjdp, @@ -138,10 +145,18 @@ static int cortex_a8_exec_opcode(struct target *target, LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode); return retval; } + if (timeval_ms() > then + 1000) + { + LOG_ERROR("Timeout waiting for cortex_a8_exec_opcode"); + return ERROR_FAIL; + } } - mem_ap_write_u32(swjdp, armv7a->debug_base + CPUDBG_ITR, opcode); + retval = mem_ap_write_u32(swjdp, armv7a->debug_base + CPUDBG_ITR, opcode); + if (retval != ERROR_OK) + return retval; + then = timeval_ms(); do { retval = mem_ap_read_atomic_u32(swjdp, @@ -151,6 +166,11 @@ static int cortex_a8_exec_opcode(struct target *target, LOG_ERROR("Could not read DSCR register"); return retval; } + if (timeval_ms() > then + 1000) + { + LOG_ERROR("Timeout waiting for cortex_a8_exec_opcode"); + return ERROR_FAIL; + } } while ((dscr & DSCR_INSTR_COMP) == 0); /* Wait for InstrCompl bit to be set */ @@ -171,11 +191,20 @@ static int cortex_a8_read_regs_through_mem(struct target *target, uint32_t addre struct armv7a_common *armv7a = target_to_armv7a(target); struct adiv5_dap *swjdp = &armv7a->dap; - cortex_a8_dap_read_coreregister_u32(target, regfile, 0); - cortex_a8_dap_write_coreregister_u32(target, address, 0); - cortex_a8_exec_opcode(target, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL); + retval = cortex_a8_dap_read_coreregister_u32(target, regfile, 0); + if (retval != ERROR_OK) + return retval; + retval = cortex_a8_dap_write_coreregister_u32(target, address, 0); + if (retval != ERROR_OK) + return retval; + retval = cortex_a8_exec_opcode(target, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL); + if (retval != ERROR_OK) + return retval; + dap_ap_select(swjdp, swjdp_memoryap); - mem_ap_read_buf_u32(swjdp, (uint8_t *)(®file[1]), 4*15, address); + retval = mem_ap_read_buf_u32(swjdp, (uint8_t *)(®file[1]), 4*15, address); + if (retval != ERROR_OK) + return retval; dap_ap_select(swjdp, swjdp_debugap); return retval; @@ -196,34 +225,52 @@ static int cortex_a8_dap_read_coreregister_u32(struct target *target, if (reg < 15) { /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */ - cortex_a8_exec_opcode(target, + retval = cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, reg, 0, 5, 0), &dscr); + if (retval != ERROR_OK) + return retval; } else if (reg == 15) { /* "MOV r0, r15"; then move r0 to DCCTX */ - cortex_a8_exec_opcode(target, 0xE1A0000F, &dscr); - cortex_a8_exec_opcode(target, + retval = cortex_a8_exec_opcode(target, 0xE1A0000F, &dscr); + if (retval != ERROR_OK) + return retval; + retval = cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0), &dscr); + if (retval != ERROR_OK) + return retval; } else { /* "MRS r0, CPSR" or "MRS r0, SPSR" * then move r0 to DCCTX */ - cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, reg & 1), &dscr); - cortex_a8_exec_opcode(target, + retval = cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, reg & 1), &dscr); + if (retval != ERROR_OK) + return retval; + retval = cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0), &dscr); + if (retval != ERROR_OK) + return retval; } /* Wait for DTRRXfull then read DTRRTX */ + long long then = timeval_ms(); while ((dscr & DSCR_DTR_TX_FULL) == 0) { retval = mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_DSCR, &dscr); + if (retval != ERROR_OK) + return retval; + if (timeval_ms() > then + 1000) + { + LOG_ERROR("Timeout waiting for cortex_a8_exec_opcode"); + return ERROR_FAIL; + } } retval = mem_ap_read_atomic_u32(swjdp, @@ -247,12 +294,16 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, /* Check that DCCRX is not full */ retval = mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_DSCR, &dscr); + if (retval != ERROR_OK) + return retval; if (dscr & DSCR_DTR_RX_FULL) { LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr); /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */ - cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), + retval = cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr); + if (retval != ERROR_OK) + return retval; } if (Rd > 17) @@ -262,37 +313,53 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, LOG_DEBUG("write DCC 0x%08" PRIx32, value); retval = mem_ap_write_u32(swjdp, armv7a->debug_base + CPUDBG_DTRRX, value); + if (retval != ERROR_OK) + return retval; if (Rd < 15) { /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */ - cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0), + retval = cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0), &dscr); + if (retval != ERROR_OK) + return retval; } else if (Rd == 15) { /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 * then "mov r15, r0" */ - cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), + retval = cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr); - cortex_a8_exec_opcode(target, 0xE1A0F000, &dscr); + if (retval != ERROR_OK) + return retval; + retval = cortex_a8_exec_opcode(target, 0xE1A0F000, &dscr); + if (retval != ERROR_OK) + return retval; } else { /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields) */ - cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), + retval = cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr); - cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, Rd & 1), + if (retval != ERROR_OK) + return retval; + retval = cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, Rd & 1), &dscr); + if (retval != ERROR_OK) + return retval; /* "Prefetch flush" after modifying execution status in CPSR */ if (Rd == 16) - cortex_a8_exec_opcode(target, + { + retval = cortex_a8_exec_opcode(target, ARMV4_5_MCR(15, 0, 0, 7, 5, 4), &dscr); + if (retval != ERROR_OK) + return retval; + } } return retval; @@ -344,14 +411,24 @@ static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data, dscr = *dscr_p; /* Wait for DTRRXfull */ + long long then = timeval_ms(); while ((dscr & DSCR_DTR_TX_FULL) == 0) { retval = mem_ap_read_atomic_u32(swjdp, a8->armv7a_common.debug_base + CPUDBG_DSCR, &dscr); + if (retval != ERROR_OK) + return retval; + if (timeval_ms() > then + 1000) + { + LOG_ERROR("Timeout waiting for read dcc"); + return ERROR_FAIL; + } } retval = mem_ap_read_atomic_u32(swjdp, a8->armv7a_common.debug_base + CPUDBG_DTRTX, data); + if (retval != ERROR_OK) + return retval; //LOG_DEBUG("read DCC 0x%08" PRIx32, *data); if (dscr_p) @@ -393,6 +470,8 @@ static int cortex_a8_dpm_prepare(struct arm_dpm *dpm) a8->armv7a_common.armv4_5_common.target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr); + if (retval != ERROR_OK) + return retval; } return retval; @@ -412,6 +491,8 @@ static int cortex_a8_instr_write_data_dcc(struct arm_dpm *dpm, uint32_t dscr = DSCR_INSTR_COMP; retval = cortex_a8_write_dcc(a8, data); + if (retval != ERROR_OK) + return retval; return cortex_a8_exec_opcode( a8->armv7a_common.armv4_5_common.target, @@ -427,12 +508,16 @@ static int cortex_a8_instr_write_data_r0(struct arm_dpm *dpm, int retval; retval = cortex_a8_write_dcc(a8, data); + if (retval != ERROR_OK) + return retval; /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */ retval = cortex_a8_exec_opcode( a8->armv7a_common.armv4_5_common.target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr); + if (retval != ERROR_OK) + return retval; /* then the opcode, taking data from R0 */ retval = cortex_a8_exec_opcode( @@ -466,6 +551,8 @@ static int cortex_a8_instr_read_data_dcc(struct arm_dpm *dpm, a8->armv7a_common.armv4_5_common.target, opcode, &dscr); + if (retval != ERROR_OK) + return retval; return cortex_a8_read_dcc(a8, data, &dscr); } @@ -483,12 +570,16 @@ static int cortex_a8_instr_read_data_r0(struct arm_dpm *dpm, a8->armv7a_common.armv4_5_common.target, opcode, &dscr); + if (retval != ERROR_OK) + return retval; /* write R0 to DCC */ retval = cortex_a8_exec_opcode( a8->armv7a_common.armv4_5_common.target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0), &dscr); + if (retval != ERROR_OK) + return retval; return cortex_a8_read_dcc(a8, data, &dscr); } @@ -773,7 +864,9 @@ static int cortex_a8_resume(struct target *target, int current, armv4_5->pc->dirty = 1; armv4_5->pc->valid = 1; - cortex_a8_restore_context(target, handle_breakpoints); + retval = cortex_a8_restore_context(target, handle_breakpoints); + if (retval != ERROR_OK) + return retval; #if 0 /* the front-end may request us not to handle breakpoints */ @@ -901,13 +994,19 @@ static int cortex_a8_debug_entry(struct target *target) else { dap_ap_select(swjdp, swjdp_memoryap); - cortex_a8_read_regs_through_mem(target, + retval = cortex_a8_read_regs_through_mem(target, regfile_working_area->address, regfile); dap_ap_select(swjdp, swjdp_memoryap); target_free_working_area(target, regfile_working_area); + if (retval != ERROR_OK) + { + return retval; + } /* read Current PSR */ - cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16); + retval = cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16); + if (retval != ERROR_OK) + return retval; dap_ap_select(swjdp, swjdp_debugap); LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr); @@ -956,12 +1055,16 @@ static int cortex_a8_debug_entry(struct target *target) /* Are we in an exception handler */ // armv4_5->exception_number = 0; if (armv7a->post_debug_entry) - armv7a->post_debug_entry(target); + { + retval = armv7a->post_debug_entry(target); + if (retval != ERROR_OK) + return retval; + } return retval; } -static void cortex_a8_post_debug_entry(struct target *target) +static int cortex_a8_post_debug_entry(struct target *target) { struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = &cortex_a8->armv7a_common; @@ -972,6 +1075,8 @@ static void cortex_a8_post_debug_entry(struct target *target) 0, 0, /* op1, op2 */ 1, 0, /* CRn, CRm */ &cortex_a8->cp15_control_reg); + if (retval != ERROR_OK) + return retval; LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a8->cp15_control_reg); if (armv7a->armv4_5_mmu.armv4_5_cache.ctype == -1) @@ -983,6 +1088,8 @@ static void cortex_a8_post_debug_entry(struct target *target) 0, 1, /* op1, op2 */ 0, 0, /* CRn, CRm */ &cache_type_reg); + if (retval != ERROR_OK) + return retval; LOG_DEBUG("cp15 cache type: %8.8x", (unsigned) cache_type_reg); /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */ @@ -997,7 +1104,7 @@ static void cortex_a8_post_debug_entry(struct target *target) armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (cortex_a8->cp15_control_reg & 0x1000U) ? 1 : 0; - + return ERROR_OK; } static int cortex_a8_step(struct target *target, int current, uint32_t address, @@ -1010,8 +1117,6 @@ static int cortex_a8_step(struct target *target, int current, uint32_t address, struct reg *r; int retval; - int timeout = 100; - if (target->state != TARGET_HALTED) { LOG_WARNING("target not halted"); @@ -1056,12 +1161,13 @@ static int cortex_a8_step(struct target *target, int current, uint32_t address, if (retval != ERROR_OK) return retval; + long long then = timeval_ms(); while (target->state != TARGET_HALTED) { retval = cortex_a8_poll(target); if (retval != ERROR_OK) return retval; - if (--timeout == 0) + if (timeval_ms() > then + 1000) { LOG_ERROR("timeout waiting for target halt"); return ERROR_FAIL; @@ -1069,8 +1175,8 @@ static int cortex_a8_step(struct target *target, int current, uint32_t address, } cortex_a8_unset_breakpoint(target, &stepbreakpoint); - if (timeout > 0) - target->debug_reason = DBG_REASON_BREAKPOINT; + + target->debug_reason = DBG_REASON_BREAKPOINT; if (breakpoint) cortex_a8_set_breakpoint(target, breakpoint, 0); @@ -1090,14 +1196,12 @@ static int cortex_a8_restore_context(struct target *target, bool bpwp) if (armv7a->pre_restore_context) armv7a->pre_restore_context(target); - arm_dpm_write_dirty_registers(&armv7a->dpm, bpwp); - - return ERROR_OK; + return arm_dpm_write_dirty_registers(&armv7a->dpm, bpwp); } /* - * Cortex-A8 Breakpoint and watchpoint fuctions + * Cortex-A8 Breakpoint and watchpoint functions */ /* Setup hardware Breakpoint Register Pair */ @@ -1125,7 +1229,7 @@ static int cortex_a8_set_breakpoint(struct target *target, if (brp_i >= cortex_a8->brp_num) { LOG_ERROR("ERROR Can not find free Breakpoint Register Pair"); - return ERROR_FAIL; + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } breakpoint->set = brp_i + 1; if (breakpoint->length == 2) @@ -1138,12 +1242,16 @@ static int cortex_a8_set_breakpoint(struct target *target, brp_list[brp_i].used = 1; brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC); brp_list[brp_i].control = control; - cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base + retval = cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn, brp_list[brp_i].value); - cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base + if (retval != ERROR_OK) + return retval; + retval = cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn, brp_list[brp_i].control); + if (retval != ERROR_OK) + return retval; LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i, brp_list[brp_i].control, brp_list[brp_i].value); @@ -1202,12 +1310,16 @@ static int cortex_a8_unset_breakpoint(struct target *target, struct breakpoint * brp_list[brp_i].used = 0; brp_list[brp_i].value = 0; brp_list[brp_i].control = 0; - cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base + retval = cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn, brp_list[brp_i].control); - cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base + if (retval != ERROR_OK) + return retval; + retval = cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn, brp_list[brp_i].value); + if (retval != ERROR_OK) + return retval; } else { @@ -1247,9 +1359,8 @@ static int cortex_a8_add_breakpoint(struct target *target, if (breakpoint->type == BKPT_HARD) cortex_a8->brp_num_available--; - cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */ - return ERROR_OK; + return cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */ } static int cortex_a8_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) @@ -1257,7 +1368,7 @@ static int cortex_a8_remove_breakpoint(struct target *target, struct breakpoint struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); #if 0 -/* It is perfectly possible to remove brakpoints while the taget is running */ +/* It is perfectly possible to remove breakpoints while the target is running */ if (target->state != TARGET_HALTED) { LOG_WARNING("target not halted"); @@ -1279,7 +1390,7 @@ static int cortex_a8_remove_breakpoint(struct target *target, struct breakpoint /* - * Cortex-A8 Reset fuctions + * Cortex-A8 Reset functions */ static int cortex_a8_assert_reset(struct target *target) @@ -1377,16 +1488,23 @@ static int cortex_a8_read_memory(struct target *target, uint32_t address, { int enabled = 0; uint32_t virt, phys; + int retval; /* cortex_a8 handles unaligned memory access */ // ??? dap_ap_select(swjdp, swjdp_memoryap); LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address, size, count); - cortex_a8_mmu(target, &enabled); + retval = cortex_a8_mmu(target, &enabled); + if (retval != ERROR_OK) + return retval; + if(enabled) { virt = address; - cortex_a8_virt2phys(target, virt, &phys); + retval = cortex_a8_virt2phys(target, virt, &phys); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("Reading at virtual address. Translating v:0x%x to r:0x%x", virt, phys); address = phys; } @@ -1450,6 +1568,8 @@ static int cortex_a8_write_phys_memory(struct target *target, retval = dpm->instr_write_data_r0(dpm, ARMV4_5_MCR(15, 0, 0, 7, 5, 1), cacheline); + if (retval != ERROR_OK) + return retval; } } @@ -1466,6 +1586,8 @@ static int cortex_a8_write_phys_memory(struct target *target, retval = dpm->instr_write_data_r0(dpm, ARMV4_5_MCR(15, 0, 0, 7, 6, 1), cacheline); + if (retval != ERROR_OK) + return retval; } } @@ -1480,15 +1602,20 @@ static int cortex_a8_write_memory(struct target *target, uint32_t address, { int enabled = 0; uint32_t virt, phys; + int retval; // ??? dap_ap_select(swjdp, swjdp_memoryap); LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address, size, count); - cortex_a8_mmu(target, &enabled); + retval = cortex_a8_mmu(target, &enabled); + if (retval != ERROR_OK) + return retval; if(enabled) { virt = address; - cortex_a8_virt2phys(target, virt, &phys); + retval = cortex_a8_virt2phys(target, virt, &phys); + if (retval != ERROR_OK) + return retval; LOG_DEBUG("Writing to virtual address. Translating v:0x%x to r:0x%x", virt, phys); address = phys; } @@ -1532,6 +1659,7 @@ static int cortex_a8_handle_target_request(void *priv) struct target *target = priv; struct armv7a_common *armv7a = target_to_armv7a(target); struct adiv5_dap *swjdp = &armv7a->dap; + int retval; if (!target_was_examined(target)) return ERROR_OK; @@ -1543,7 +1671,9 @@ static int cortex_a8_handle_target_request(void *priv) uint8_t data = 0; uint8_t ctrl = 0; - cortex_a8_dcc_read(swjdp, &data, &ctrl); + retval = cortex_a8_dcc_read(swjdp, &data, &ctrl); + if (retval != ERROR_OK) + return retval; /* check if we have data */ if (ctrl & (1 << 0)) @@ -1552,11 +1682,17 @@ static int cortex_a8_handle_target_request(void *priv) /* we assume target is quick enough */ request = data; - cortex_a8_dcc_read(swjdp, &data, &ctrl); + retval = cortex_a8_dcc_read(swjdp, &data, &ctrl); + if (retval != ERROR_OK) + return retval; request |= (data << 8); - cortex_a8_dcc_read(swjdp, &data, &ctrl); + retval = cortex_a8_dcc_read(swjdp, &data, &ctrl); + if (retval != ERROR_OK) + return retval; request |= (data << 16); - cortex_a8_dcc_read(swjdp, &data, &ctrl); + retval = cortex_a8_dcc_read(swjdp, &data, &ctrl); + if (retval != ERROR_OK) + return retval; request |= (data << 24); target_request(target, request); } @@ -1577,12 +1713,7 @@ static int cortex_a8_examine_first(struct target *target) int i; int retval = ERROR_OK; uint32_t didr, ctypr, ttypr, cpuid; - - /* stop assuming this is an OMAP! */ - LOG_DEBUG("TODO - autoconfigure"); - - /* Here we shall insert a proper ROM Table scan */ - armv7a->debug_base = OMAP3530_DEBUG_BASE; + uint32_t dbgbase, apid; /* We do one extra read to ensure DAP is configured, * we call ahbap_debugport_init(swjdp) instead @@ -1591,6 +1722,17 @@ static int cortex_a8_examine_first(struct target *target) if (retval != ERROR_OK) return retval; + /* Get ROM Table base */ + 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); + if (retval != ERROR_OK) + return retval; + retval = mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_CPUID, &cpuid); if (retval != ERROR_OK) return retval; @@ -1743,12 +1885,10 @@ static int cortex_a8_target_create(struct target *target, Jim_Interp *interp) { struct cortex_a8_common *cortex_a8 = calloc(1, sizeof(struct cortex_a8_common)); - cortex_a8_init_arch_info(target, cortex_a8, target->tap); - - return ERROR_OK; + return cortex_a8_init_arch_info(target, cortex_a8, target->tap); } -static uint32_t cortex_a8_get_ttb(struct target *target) +static int cortex_a8_get_ttb(struct target *target, uint32_t *result) { struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = &cortex_a8->armv7a_common; @@ -1763,6 +1903,8 @@ static uint32_t cortex_a8_get_ttb(struct target *target) 0, 1, /* op1, op2 */ 2, 0, /* CRn, CRm */ &ttb); + if (retval != ERROR_OK) + return retval; } else if(cortex_a8->current_address_mode == ARM_MODE_USR) { @@ -1771,6 +1913,8 @@ static uint32_t cortex_a8_get_ttb(struct target *target) 0, 0, /* op1, op2 */ 2, 0, /* CRn, CRm */ &ttb); + if (retval != ERROR_OK) + return retval; } /* we don't know whose address is: user or kernel we assume that if we are in kernel mode then @@ -1783,6 +1927,8 @@ static uint32_t cortex_a8_get_ttb(struct target *target) 0, 1, /* op1, op2 */ 2, 0, /* CRn, CRm */ &ttb); + if (retval != ERROR_OK) + return retval; } else if(armv7a->armv4_5_common.core_mode == ARM_MODE_USR) { @@ -1791,28 +1937,35 @@ static uint32_t cortex_a8_get_ttb(struct target *target) 0, 0, /* op1, op2 */ 2, 0, /* CRn, CRm */ &ttb); + if (retval != ERROR_OK) + return retval; } - /* finaly we don't know whose ttb to use: user or kernel */ + /* finally we don't know whose ttb to use: user or kernel */ else LOG_ERROR("Don't know how to get ttb for current mode!!!"); ttb &= 0xffffc000; - return ttb; + *result = ttb; + + return ERROR_OK; } -static void cortex_a8_disable_mmu_caches(struct target *target, int mmu, +static int cortex_a8_disable_mmu_caches(struct target *target, int mmu, int d_u_cache, int i_cache) { struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = &cortex_a8->armv7a_common; uint32_t cp15_control; + int retval; /* read cp15 control register */ - armv7a->armv4_5_common.mrc(target, 15, + retval = armv7a->armv4_5_common.mrc(target, 15, 0, 0, /* op1, op2 */ 1, 0, /* CRn, CRm */ &cp15_control); + if (retval != ERROR_OK) + return retval; if (mmu) @@ -1824,24 +1977,28 @@ static void cortex_a8_disable_mmu_caches(struct target *target, int mmu, if (i_cache) cp15_control &= ~0x1000U; - armv7a->armv4_5_common.mcr(target, 15, + retval = armv7a->armv4_5_common.mcr(target, 15, 0, 0, /* op1, op2 */ 1, 0, /* CRn, CRm */ cp15_control); + return retval; } -static void cortex_a8_enable_mmu_caches(struct target *target, int mmu, +static int cortex_a8_enable_mmu_caches(struct target *target, int mmu, int d_u_cache, int i_cache) { struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = &cortex_a8->armv7a_common; uint32_t cp15_control; + int retval; /* read cp15 control register */ - armv7a->armv4_5_common.mrc(target, 15, + retval = armv7a->armv4_5_common.mrc(target, 15, 0, 0, /* op1, op2 */ 1, 0, /* CRn, CRm */ &cp15_control); + if (retval != ERROR_OK) + return retval; if (mmu) cp15_control |= 0x1U; @@ -1852,10 +2009,11 @@ static void cortex_a8_enable_mmu_caches(struct target *target, int mmu, if (i_cache) cp15_control |= 0x1000U; - armv7a->armv4_5_common.mcr(target, 15, + retval = armv7a->armv4_5_common.mcr(target, 15, 0, 0, /* op1, op2 */ 1, 0, /* CRn, CRm */ cp15_control); + return retval; }