libjaylink: Update to latest master branch
[openocd.git] / src / target / cortex_a.c
index 11558b9a6988d6b225869e9126c2d367cc4d37ee..f9ffccd08a4144bd0fb45b2feb6653aa6730632d 100644 (file)
@@ -106,6 +106,7 @@ static int cortex_a_restore_cp15_control_reg(struct target *target)
 static int cortex_a_prep_memaccess(struct target *target, int phys_access)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct cortex_a_common *cortex_a = target_to_cortex_a(target);
        int mmu_enabled = 0;
 
        if (phys_access == 0) {
@@ -113,6 +114,12 @@ static int cortex_a_prep_memaccess(struct target *target, int phys_access)
                cortex_a_mmu(target, &mmu_enabled);
                if (mmu_enabled)
                        cortex_a_mmu_modify(target, 1);
+               if (cortex_a->dacrfixup_mode == CORTEX_A_DACRFIXUP_ON) {
+                       /* overwrite DACR to all-manager */
+                       armv7a->arm.mcr(target, 15,
+                                       0, 0, 3, 0,
+                                       0xFFFFFFFF);
+               }
        } else {
                cortex_a_mmu(target, &mmu_enabled);
                if (mmu_enabled)
@@ -129,8 +136,15 @@ static int cortex_a_prep_memaccess(struct target *target, int phys_access)
 static int cortex_a_post_memaccess(struct target *target, int phys_access)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct cortex_a_common *cortex_a = target_to_cortex_a(target);
 
        if (phys_access == 0) {
+               if (cortex_a->dacrfixup_mode == CORTEX_A_DACRFIXUP_ON) {
+                       /* restore */
+                       armv7a->arm.mcr(target, 15,
+                                       0, 0, 3, 0,
+                                       cortex_a->cp15_dacr_reg);
+               }
                dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
        } else {
                int mmu_enabled = 0;
@@ -285,7 +299,7 @@ static int cortex_a_wait_instrcmpl(struct target *target, uint32_t *dscr, bool f
         * Writes final value of DSCR into *dscr. Pass force to force always
         * reading DSCR at least once. */
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        while ((*dscr & DSCR_INSTR_COMP) == 0 || force) {
                force = false;
                int retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
@@ -328,7 +342,7 @@ static int cortex_a_exec_opcode(struct target *target,
        if (retval != ERROR_OK)
                return retval;
 
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        do {
                retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
@@ -417,7 +431,7 @@ static int cortex_a_dap_read_coreregister_u32(struct target *target,
        }
 
        /* Wait for DTRRXfull then read DTRRTX */
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        while ((dscr & DSCR_DTR_TX_FULL) == 0) {
                retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
@@ -560,7 +574,7 @@ static int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data,
                dscr = *dscr_p;
 
        /* Wait for DTRRXfull */
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        while ((dscr & DSCR_DTR_TX_FULL) == 0) {
                retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
                                a->armv7a_common.debug_base + CPUDBG_DSCR,
@@ -592,7 +606,7 @@ static int cortex_a_dpm_prepare(struct arm_dpm *dpm)
        int retval;
 
        /* set up invariant:  INSTR_COMP is set after ever DPM operation */
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        for (;; ) {
                retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,
                                a->armv7a_common.debug_base + CPUDBG_DSCR,
@@ -960,7 +974,7 @@ static int cortex_a_halt(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        for (;; ) {
                retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
@@ -1040,6 +1054,7 @@ static int cortex_a_internal_restore(struct target *target, int current,
        buf_set_u32(arm->pc->value, 0, 32, resume_pc);
        arm->pc->dirty = 1;
        arm->pc->valid = 1;
+
        /* restore dpm_mode at system halt */
        dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
        /* called it now before restoring context because it uses cpu
@@ -1106,7 +1121,7 @@ static int cortex_a_internal_restart(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        for (;; ) {
                retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
@@ -1336,6 +1351,16 @@ static int cortex_a_post_debug_entry(struct target *target)
                (cortex_a->cp15_control_reg & 0x1000U) ? 1 : 0;
        cortex_a->curr_mode = armv7a->arm.core_mode;
 
+       /* switch to SVC mode to read DACR */
+       dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC);
+       armv7a->arm.mrc(target, 15,
+                       0, 0, 3, 0,
+                       &cortex_a->cp15_dacr_reg);
+
+       LOG_DEBUG("cp15_dacr_reg: %8.8" PRIx32,
+                       cortex_a->cp15_dacr_reg);
+
+       dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);
        return ERROR_OK;
 }
 
@@ -1418,7 +1443,7 @@ static int cortex_a_step(struct target *target, int current, uint32_t address,
        if (retval != ERROR_OK)
                return retval;
 
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        while (target->state != TARGET_HALTED) {
                retval = cortex_a_poll(target);
                if (retval != ERROR_OK)
@@ -1878,6 +1903,8 @@ static int cortex_a_assert_reset(struct target *target)
 
        /* FIXME when halt is requested, make it work somehow... */
 
+       /* This function can be called in "target not examined" state */
+
        /* Issue some kind of warm reset. */
        if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
                target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
@@ -1885,7 +1912,9 @@ static int cortex_a_assert_reset(struct target *target)
                /* REVISIT handle "pulls" cases, if there's
                 * hardware that needs them to work.
                 */
-               jtag_add_reset(0, 1);
+               if (target->reset_halt)
+                       if (jtag_get_reset_config() & RESET_SRST_NO_GATING)
+                               jtag_add_reset(0, 1);
        } else {
                LOG_ERROR("%s: how to reset?", target_name(target));
                return ERROR_FAIL;
@@ -1952,7 +1981,7 @@ static int cortex_a_wait_dscr_bits(struct target *target, uint32_t mask,
 {
        /* Waits until the specified bit(s) of DSCR take on a specified value. */
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        int retval;
 
        while ((*dscr & mask) != value) {
@@ -2280,7 +2309,7 @@ out:
        /* Wait until DTRRX is empty (according to ARMv7-A/-R architecture manual
         * section C8.4.3, checking InstrCmpl_l is not sufficient; one must also
         * check RXfull_l). Most of the time this will be free because RXfull_l
-        * will be cleared immediately and cached in dscr. However, dont do this
+        * will be cleared immediately and cached in dscr. However, don't do this
         * if there is fault, because then the instruction might not have completed
         * successfully. */
        if (!(dscr & DSCR_STICKY_ABORT_PRECISE)) {
@@ -2643,17 +2672,25 @@ static int cortex_a_read_phys_memory(struct target *target,
        uint32_t address, uint32_t size,
        uint32_t count, uint8_t *buffer)
 {
-       int retval = ERROR_COMMAND_SYNTAX_ERROR;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct adiv5_dap *swjdp = armv7a->arm.dap;
+       uint8_t apsel = swjdp->apsel;
+       int retval;
+
+       if (!count || !buffer)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        LOG_DEBUG("Reading memory at real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32,
                address, size, count);
 
-       if (count && buffer) {
-               /* read memory through APB-AP */
-               cortex_a_prep_memaccess(target, 1);
-               retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
-               cortex_a_post_memaccess(target, 1);
-       }
+       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num))
+               return mem_ap_read_buf(armv7a->memory_ap, buffer, size, count, address);
+
+       /* read memory through APB-AP */
+       cortex_a_prep_memaccess(target, 1);
+       retval = cortex_a_read_apb_ab_memory(target, address, size, count, buffer);
+       cortex_a_post_memaccess(target, 1);
+
        return retval;
 }
 
@@ -2720,17 +2757,24 @@ static int cortex_a_write_phys_memory(struct target *target,
        uint32_t address, uint32_t size,
        uint32_t count, const uint8_t *buffer)
 {
-       int retval = ERROR_COMMAND_SYNTAX_ERROR;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct adiv5_dap *swjdp = armv7a->arm.dap;
+       uint8_t apsel = swjdp->apsel;
+       int retval;
+
+       if (!count || !buffer)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        LOG_DEBUG("Writing memory to real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, address,
                size, count);
 
-       if (count && buffer) {
-               /* write memory through APB-AP */
-               cortex_a_prep_memaccess(target, 1);
-               retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
-               cortex_a_post_memaccess(target, 1);
-       }
+       if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num))
+               return mem_ap_write_buf(armv7a->memory_ap, buffer, size, count, address);
+
+       /* write memory through APB-AP */
+       cortex_a_prep_memaccess(target, 1);
+       retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
+       cortex_a_post_memaccess(target, 1);
 
        return retval;
 }
@@ -2883,6 +2927,7 @@ static int cortex_a_handle_target_request(void *priv)
                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
 
                /* check if we have data */
+               int64_t then = timeval_ms();
                while ((dscr & DSCR_DTR_TX_FULL) && (retval == ERROR_OK)) {
                        retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                        armv7a->debug_base + CPUDBG_DTRTX, &request);
@@ -2891,6 +2936,10 @@ static int cortex_a_handle_target_request(void *priv)
                                retval = mem_ap_read_atomic_u32(armv7a->debug_ap,
                                                armv7a->debug_base + CPUDBG_DSCR, &dscr);
                        }
+                       if (timeval_ms() > then + 1000) {
+                               LOG_ERROR("Timeout waiting for dtr tx full");
+                               return ERROR_FAIL;
+                       }
                }
        }
 
@@ -2929,6 +2978,8 @@ static int cortex_a_examine_first(struct target *target)
                return retval;
        }
 
+       armv7a->debug_ap->memaccess_tck = 80;
+
        /* Search for the AHB-AB.
         * REVISIT: We should search for AXI-AP as well and make sure the AP's MEMTYPE says it
         * can access system memory. */
@@ -3072,6 +3123,9 @@ static int cortex_a_examine_first(struct target *target)
 
        LOG_DEBUG("Configured %i hw breakpoints", cortex_a->brp_num);
 
+       /* select debug_ap as default */
+       swjdp->apsel = armv7a->debug_ap->ap_num;
+
        target_set_examined(target);
        return ERROR_OK;
 }
@@ -3117,7 +3171,6 @@ static int cortex_a_init_arch_info(struct target *target,
                tap->dap->tap = tap;
        }
 
-       tap->dap->ap[dap_ap_get_select(tap->dap)].memaccess_tck = 80;
        armv7a->arm.dap = tap->dap;
 
        cortex_a->fast_reg_read = 0;
@@ -3302,17 +3355,14 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
        };
        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)
+               if (n->name == NULL) {
+                       LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]);
                        return ERROR_COMMAND_SYNTAX_ERROR;
-               cortex_a->isrmasking_mode = n->value;
+               }
 
+               cortex_a->isrmasking_mode = n->value;
        }
 
        n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode);
@@ -3321,6 +3371,32 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_cortex_a_dacrfixup_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_dacrfixup_modes[] = {
+               { .name = "off", .value = CORTEX_A_DACRFIXUP_OFF },
+               { .name = "on", .value = CORTEX_A_DACRFIXUP_ON },
+               { .name = NULL, .value = -1 },
+       };
+       const Jim_Nvp *n;
+
+       if (CMD_ARGC > 0) {
+               n = Jim_Nvp_name2value_simple(nvp_dacrfixup_modes, CMD_ARGV[0]);
+               if (n->name == NULL)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               cortex_a->dacrfixup_mode = n->value;
+
+       }
+
+       n = Jim_Nvp_value2name_simple(nvp_dacrfixup_modes, cortex_a->dacrfixup_mode);
+       command_print(CMD_CTX, "cortex_a domain access control fixup %s", n->name);
+
+       return ERROR_OK;
+}
+
 static const struct command_registration cortex_a_exec_command_handlers[] = {
        {
                .name = "cache_info",
@@ -3358,11 +3434,18 @@ static const struct command_registration cortex_a_exec_command_handlers[] = {
        {
                .name = "maskisr",
                .handler = handle_cortex_a_mask_interrupts_command,
-               .mode = COMMAND_EXEC,
+               .mode = COMMAND_ANY,
                .help = "mask cortex_a interrupts",
                .usage = "['on'|'off']",
        },
-
+       {
+               .name = "dacrfixup",
+               .handler = handle_cortex_a_dacrfixup_command,
+               .mode = COMMAND_EXEC,
+               .help = "set domain access control (DACR) to all-manager "
+                       "on memory access",
+               .usage = "['on'|'off']",
+       },
 
        COMMAND_REGISTRATION_DONE
 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)