]> git.sur5r.net Git - openocd/blobdiff - src/target/cortex_a.c
cortex_a: remove cache handlers from cortex_a_write_phys_memory
[openocd] / src / target / cortex_a.c
index 207fb811627bd80317045233e03af1150dd8b79a..3da58701d869089b9480a5bc7392312db43c3247 100644 (file)
@@ -1323,9 +1323,33 @@ static int cortex_a_post_debug_entry(struct target *target)
        return ERROR_OK;
 }
 
+int cortex_a_set_dscr_bits(struct target *target, unsigned long bit_mask, unsigned long value)
+{
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct adiv5_dap *swjdp = armv7a->arm.dap;
+       uint32_t dscr;
+
+       /* Read DSCR */
+       int retval = mem_ap_sel_read_atomic_u32(swjdp, armv7a->debug_ap,
+                       armv7a->debug_base + CPUDBG_DSCR, &dscr);
+       if (ERROR_OK != retval)
+               return retval;
+
+       /* clear bitfield */
+       dscr &= ~bit_mask;
+       /* put new value */
+       dscr |= value & bit_mask;
+
+       /* write new DSCR */
+       retval = mem_ap_sel_write_atomic_u32(swjdp, armv7a->debug_ap,
+                       armv7a->debug_base + CPUDBG_DSCR, dscr);
+       return retval;
+}
+
 static int cortex_a_step(struct target *target, int current, uint32_t address,
        int handle_breakpoints)
 {
+       struct cortex_a_common *cortex_a = target_to_cortex_a(target);
        struct armv7a_common *armv7a = target_to_armv7a(target);
        struct arm *arm = &armv7a->arm;
        struct breakpoint *breakpoint = NULL;
@@ -1363,6 +1387,13 @@ static int cortex_a_step(struct target *target, int current, uint32_t address,
        stepbreakpoint.type = BKPT_HARD;
        stepbreakpoint.set = 0;
 
+       /* Disable interrupts during single step if requested */
+       if (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) {
+               retval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, DSCR_INT_DIS);
+               if (ERROR_OK != retval)
+                       return retval;
+       }
+
        /* Break on IVA mismatch */
        cortex_a_set_breakpoint(target, &stepbreakpoint, 0x04);
 
@@ -1385,6 +1416,14 @@ static int cortex_a_step(struct target *target, int current, uint32_t address,
 
        cortex_a_unset_breakpoint(target, &stepbreakpoint);
 
+       /* Re-enable interrupts if they were disabled */
+       if (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) {
+               retval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, 0);
+               if (ERROR_OK != retval)
+                       return retval;
+       }
+
+
        target->debug_reason = DBG_REASON_BREAKPOINT;
 
        if (breakpoint)
@@ -2572,29 +2611,20 @@ static int cortex_a_read_phys_memory(struct target *target,
        uint32_t count, uint8_t *buffer)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        int retval = ERROR_COMMAND_SYNTAX_ERROR;
-       uint8_t apsel = swjdp->apsel;
+
        LOG_DEBUG("Reading memory at real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32,
                address, size, count);
 
        if (count && buffer) {
-
-               if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
-
-                       /* read memory through AHB-AP */
-                       retval = mem_ap_sel_read_buf(swjdp, armv7a->memory_ap, buffer, size, count, address);
-               } else {
-
-                       /* read memory through APB-AP */
-                       if (!armv7a->is_armv7r) {
-                               /*  disable mmu */
-                               retval = cortex_a_mmu_modify(target, 0);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                       }
-                       retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
+               /* read memory through APB-AP */
+               if (!armv7a->is_armv7r) {
+                       /*  disable mmu */
+                       retval = cortex_a_mmu_modify(target, 0);
+                       if (retval != ERROR_OK)
+                               return retval;
                }
+               retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
        }
        return retval;
 }
@@ -2653,84 +2683,19 @@ static int cortex_a_write_phys_memory(struct target *target,
        uint32_t count, const uint8_t *buffer)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       struct adiv5_dap *swjdp = armv7a->arm.dap;
        int retval = ERROR_COMMAND_SYNTAX_ERROR;
-       uint8_t apsel = swjdp->apsel;
 
        LOG_DEBUG("Writing memory to real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
                size, count);
 
        if (count && buffer) {
-
-               if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
-
-                       /* write memory through AHB-AP */
-                       retval = mem_ap_sel_write_buf(swjdp, armv7a->memory_ap, buffer, size, count, address);
-               } else {
-
-                       /* write memory through APB-AP */
-                       if (!armv7a->is_armv7r) {
-                               retval = cortex_a_mmu_modify(target, 0);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                       }
-                       return cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
-               }
-       }
-
-
-       /* REVISIT this op is generic ARMv7-A/R stuff */
-       if (retval == ERROR_OK && target->state == TARGET_HALTED) {
-               struct arm_dpm *dpm = armv7a->arm.dpm;
-
-               retval = dpm->prepare(dpm);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               /* The Cache handling will NOT work with MMU active, the
-                * wrong addresses will be invalidated!
-                *
-                * For both ICache and DCache, walk all cache lines in the
-                * address range. Cortex-A has fixed 64 byte line length.
-                *
-                * REVISIT per ARMv7, these may trigger watchpoints ...
-                */
-
-               /* invalidate I-Cache */
-               if (armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled) {
-                       /* ICIMVAU - Invalidate Cache single entry
-                        * with MVA to PoU
-                        *      MCR p15, 0, r0, c7, c5, 1
-                        */
-                       for (uint32_t cacheline = 0;
-                               cacheline < size * count;
-                               cacheline += 64) {
-                               retval = dpm->instr_write_data_r0(dpm,
-                                               ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
-                                               address + cacheline);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                       }
-               }
-
-               /* invalidate D-Cache */
-               if (armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) {
-                       /* DCIMVAC - Invalidate data Cache line
-                        * with MVA to PoC
-                        *      MCR p15, 0, r0, c7, c6, 1
-                        */
-                       for (uint32_t cacheline = 0;
-                               cacheline < size * count;
-                               cacheline += 64) {
-                               retval = dpm->instr_write_data_r0(dpm,
-                                               ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
-                                               address + cacheline);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                       }
+               /* write memory through APB-AP */
+               if (!armv7a->is_armv7r) {
+                       retval = cortex_a_mmu_modify(target, 0);
+                       if (retval != ERROR_OK)
+                               return retval;
                }
-
-               /* (void) */ dpm->finish(dpm);
+               return cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
        }
 
        return retval;
@@ -2957,9 +2922,13 @@ static int cortex_a_examine_first(struct target *target)
        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;
+
+       /* Avoid recreating the registers cache */
+       if (!target_was_examined(target)) {
+               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;
@@ -3078,6 +3047,16 @@ static int cortex_r4_target_create(struct target *target, Jim_Interp *interp)
        return cortex_a_init_arch_info(target, cortex_a, target->tap);
 }
 
+static void cortex_a_deinit_target(struct target *target)
+{
+       struct cortex_a_common *cortex_a = target_to_cortex_a(target);
+       struct arm_dpm *dpm = &cortex_a->armv7a_common.dpm;
+
+       free(cortex_a->brp_list);
+       free(dpm->dbp);
+       free(dpm->dwp);
+       free(cortex_a);
+}
 
 static int cortex_a_mmu(struct target *target, int *enabled)
 {
@@ -3193,6 +3172,37 @@ COMMAND_HANDLER(cortex_a_handle_smp_gdb_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct cortex_a_common *cortex_a = target_to_cortex_a(target);
+
+       static const Jim_Nvp nvp_maskisr_modes[] = {
+               { .name = "off", .value = CORTEX_A_ISRMASK_OFF },
+               { .name = "on", .value = CORTEX_A_ISRMASK_ON },
+               { .name = NULL, .value = -1 },
+       };
+       const Jim_Nvp *n;
+
+       if (target->state != TARGET_HALTED) {
+               command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+               return ERROR_OK;
+       }
+
+       if (CMD_ARGC > 0) {
+               n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
+               if (n->name == NULL)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               cortex_a->isrmasking_mode = n->value;
+
+       }
+
+       n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode);
+       command_print(CMD_CTX, "cortex_a interrupt mask %s", n->name);
+
+       return ERROR_OK;
+}
+
 static const struct command_registration cortex_a_exec_command_handlers[] = {
        {
                .name = "cache_info",
@@ -3227,6 +3237,13 @@ static const struct command_registration cortex_a_exec_command_handlers[] = {
                .help = "display/fix current core played to gdb",
                .usage = "",
        },
+       {
+               .name = "maskisr",
+               .handler = handle_cortex_a_mask_interrupts_command,
+               .mode = COMMAND_EXEC,
+               .help = "mask cortex_a interrupts",
+               .usage = "['on'|'off']",
+       },
 
 
        COMMAND_REGISTRATION_DONE
@@ -3284,6 +3301,7 @@ struct target_type cortexa_target = {
        .target_create = cortex_a_target_create,
        .init_target = cortex_a_init_target,
        .examine = cortex_a_examine,
+       .deinit_target = cortex_a_deinit_target,
 
        .read_phys_memory = cortex_a_read_phys_memory,
        .write_phys_memory = cortex_a_write_phys_memory,
@@ -3306,6 +3324,13 @@ static const struct command_registration cortex_r4_exec_command_handlers[] = {
                .help = "Initialize core debug",
                .usage = "",
        },
+       {
+               .name = "maskisr",
+               .handler = handle_cortex_a_mask_interrupts_command,
+               .mode = COMMAND_EXEC,
+               .help = "mask cortex_r4 interrupts",
+               .usage = "['on'|'off']",
+       },
 
        COMMAND_REGISTRATION_DONE
 };
@@ -3361,4 +3386,5 @@ struct target_type cortexr4_target = {
        .target_create = cortex_r4_target_create,
        .init_target = cortex_a_init_target,
        .examine = cortex_a_examine,
+       .deinit_target = cortex_a_deinit_target,
 };