]> git.sur5r.net Git - openocd/blobdiff - src/target/cortex_a8.c
arm: add error propagation for enable/disable mmu caches
[openocd] / src / target / cortex_a8.c
index 82ce9a18b46efab3d05998f281463479f258cb63..9a9018026d004eb4065a664f71934f87730bfd47 100644 (file)
@@ -58,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);
 
 
 /*
@@ -147,7 +147,9 @@ static int cortex_a8_exec_opcode(struct target *target,
                }
        }
 
-       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;
 
        do
        {
@@ -178,11 +180,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 *)(&regfile[1]), 4*15, address);
+       retval = mem_ap_read_buf_u32(swjdp, (uint8_t *)(&regfile[1]), 4*15, address);
+       if (retval != ERROR_OK)
+               return retval;
        dap_ap_select(swjdp, swjdp_debugap);
 
        return retval;
@@ -203,27 +214,37 @@ 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 */
@@ -262,8 +283,10 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target,
        {
                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)
@@ -273,37 +296,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;
@@ -408,6 +447,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;
@@ -427,6 +468,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,
@@ -442,12 +485,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(
@@ -481,6 +528,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);
 }
@@ -498,12 +547,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);
 }
@@ -788,7 +841,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 */
@@ -916,13 +971,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);
 
@@ -1105,9 +1166,7 @@ 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);
 }
 
 
@@ -1153,12 +1212,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);
@@ -1217,12 +1280,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
        {
@@ -1405,7 +1472,10 @@ static int cortex_a8_read_memory(struct target *target, uint32_t address,
         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;
         }
@@ -1469,6 +1539,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;
                         }
                 }
 
@@ -1485,6 +1557,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;
                         }
                 }
 
@@ -1510,7 +1584,9 @@ static int cortex_a8_write_memory(struct target *target, uint32_t address,
         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;
         }
@@ -1554,6 +1630,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;
@@ -1565,7 +1642,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))
@@ -1574,11 +1653,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);
                }
@@ -1765,12 +1850,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;
@@ -1785,6 +1868,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)
     {
@@ -1793,6 +1878,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
@@ -1805,6 +1892,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)
     {
@@ -1813,6 +1902,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;
     }
     /* finally we don't know whose ttb to use: user or kernel */
     else
@@ -1820,21 +1911,26 @@ static uint32_t cortex_a8_get_ttb(struct target *target)
 
     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)
@@ -1846,24 +1942,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;
@@ -1874,10 +1974,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;
 }