target/cortex_m: cumulate DHCSR sticky bits
[openocd.git] / src / target / armv7a_cache.c
index a049174cbe85b65c028ba351fac34ba8c9f541bf..4078fdde20607c5a2eb9de2e4f5f4ef4a287b289 100644 (file)
@@ -11,6 +11,9 @@
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -67,6 +70,7 @@ static int armv7a_l1_d_cache_flush_level(struct arm_dpm *dpm, struct armv7a_cach
 
        LOG_DEBUG("cl %" PRId32, cl);
        do {
+               keep_alive();
                c_way = size->way;
                do {
                        uint32_t value = (c_index << size->index_shift)
@@ -86,6 +90,7 @@ static int armv7a_l1_d_cache_flush_level(struct arm_dpm *dpm, struct armv7a_cach
        } while (c_index >= 0);
 
  done:
+       keep_alive();
        return retval;
 }
 
@@ -135,7 +140,7 @@ int armv7a_cache_auto_flush_all_data(struct target *target)
                struct target_list *head;
                struct target *curr;
                head = target->head;
-               while (head != (struct target_list *)NULL) {
+               while (head) {
                        curr = head->target;
                        if (curr->state == TARGET_HALTED)
                                retval = armv7a_l1_d_cache_clean_inval_all(curr);
@@ -145,14 +150,15 @@ int armv7a_cache_auto_flush_all_data(struct target *target)
        } else
                retval = armv7a_l1_d_cache_clean_inval_all(target);
 
-       /* do outer cache flushing after inner caches have been flushed */
-       retval = arm7a_l2x_flush_all_data(target);
+       if (retval != ERROR_OK)
+               return retval;
 
-       return retval;
+       /* do outer cache flushing after inner caches have been flushed */
+       return arm7a_l2x_flush_all_data(target);
 }
 
 
-static int armv7a_l1_d_cache_inval_virt(struct target *target, uint32_t virt,
+int armv7a_l1_d_cache_inval_virt(struct target *target, uint32_t virt,
                                        uint32_t size)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
@@ -160,7 +166,7 @@ static int armv7a_l1_d_cache_inval_virt(struct target *target, uint32_t virt,
        struct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache;
        uint32_t linelen = armv7a_cache->dminline;
        uint32_t va_line, va_end;
-       int retval;
+       int retval, i = 0;
 
        retval = armv7a_l1_d_cache_sanity_check(target);
        if (retval != ERROR_OK)
@@ -194,6 +200,8 @@ static int armv7a_l1_d_cache_inval_virt(struct target *target, uint32_t virt,
        }
 
        while (va_line < va_end) {
+               if ((i++ & 0x3f) == 0)
+                       keep_alive();
                /* DCIMVAC - Invalidate data cache line by VA to PoC. */
                retval = dpm->instr_write_data_r0(dpm,
                                ARMV4_5_MCR(15, 0, 0, 7, 6, 1), va_line);
@@ -202,11 +210,13 @@ static int armv7a_l1_d_cache_inval_virt(struct target *target, uint32_t virt,
                va_line += linelen;
        }
 
+       keep_alive();
        dpm->finish(dpm);
        return retval;
 
 done:
        LOG_ERROR("d-cache invalidate failed");
+       keep_alive();
        dpm->finish(dpm);
 
        return retval;
@@ -218,8 +228,9 @@ int armv7a_l1_d_cache_clean_virt(struct target *target, uint32_t virt,
        struct armv7a_common *armv7a = target_to_armv7a(target);
        struct arm_dpm *dpm = armv7a->arm.dpm;
        struct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache;
-       uint32_t i, linelen = armv7a_cache->dminline;
-       int retval;
+       uint32_t linelen = armv7a_cache->dminline;
+       uint32_t va_line, va_end;
+       int retval, i = 0;
 
        retval = armv7a_l1_d_cache_sanity_check(target);
        if (retval != ERROR_OK)
@@ -229,19 +240,27 @@ int armv7a_l1_d_cache_clean_virt(struct target *target, uint32_t virt,
        if (retval != ERROR_OK)
                goto done;
 
-       for (i = 0; i < size; i += linelen) {
-               uint32_t offs = virt + i;
+       va_line = virt & (-linelen);
+       va_end = virt + size;
 
+       while (va_line < va_end) {
+               if ((i++ & 0x3f) == 0)
+                       keep_alive();
                /* DCCMVAC - Data Cache Clean by MVA to PoC */
                retval = dpm->instr_write_data_r0(dpm,
-                               ARMV4_5_MCR(15, 0, 0, 7, 10, 1), offs);
+                               ARMV4_5_MCR(15, 0, 0, 7, 10, 1), va_line);
                if (retval != ERROR_OK)
                        goto done;
+               va_line += linelen;
        }
+
+       keep_alive();
+       dpm->finish(dpm);
        return retval;
 
 done:
        LOG_ERROR("d-cache invalidate failed");
+       keep_alive();
        dpm->finish(dpm);
 
        return retval;
@@ -253,8 +272,9 @@ int armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt,
        struct armv7a_common *armv7a = target_to_armv7a(target);
        struct arm_dpm *dpm = armv7a->arm.dpm;
        struct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache;
-       uint32_t i, linelen = armv7a_cache->dminline;
-       int retval;
+       uint32_t linelen = armv7a_cache->dminline;
+       uint32_t va_line, va_end;
+       int retval, i = 0;
 
        retval = armv7a_l1_d_cache_sanity_check(target);
        if (retval != ERROR_OK)
@@ -264,19 +284,27 @@ int armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt,
        if (retval != ERROR_OK)
                goto done;
 
-       for (i = 0; i < size; i += linelen) {
-               uint32_t offs = virt + i;
+       va_line = virt & (-linelen);
+       va_end = virt + size;
 
+       while (va_line < va_end) {
+               if ((i++ & 0x3f) == 0)
+                       keep_alive();
                /* DCCIMVAC */
                retval = dpm->instr_write_data_r0(dpm,
-                               ARMV4_5_MCR(15, 0, 0, 7, 14, 1), offs);
+                               ARMV4_5_MCR(15, 0, 0, 7, 14, 1), va_line);
                if (retval != ERROR_OK)
                        goto done;
+               va_line += linelen;
        }
+
+       keep_alive();
+       dpm->finish(dpm);
        return retval;
 
 done:
        LOG_ERROR("d-cache invalidate failed");
+       keep_alive();
        dpm->finish(dpm);
 
        return retval;
@@ -328,7 +356,7 @@ int armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt,
                                &armv7a->armv7a_mmu.armv7a_cache;
        uint32_t linelen = armv7a_cache->iminline;
        uint32_t va_line, va_end;
-       int retval;
+       int retval, i = 0;
 
        retval = armv7a_l1_i_cache_sanity_check(target);
        if (retval != ERROR_OK)
@@ -342,6 +370,8 @@ int armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt,
        va_end = virt + size;
 
        while (va_line < va_end) {
+               if ((i++ & 0x3f) == 0)
+                       keep_alive();
                /* ICIMVAU - Invalidate instruction cache by VA to PoU. */
                retval = dpm->instr_write_data_r0(dpm,
                                ARMV4_5_MCR(15, 0, 0, 7, 5, 1), va_line);
@@ -354,10 +384,13 @@ int armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt,
                        goto done;
                va_line += linelen;
        }
+       keep_alive();
+       dpm->finish(dpm);
        return retval;
 
 done:
        LOG_ERROR("i-cache invalidate failed");
+       keep_alive();
        dpm->finish(dpm);
 
        return retval;
@@ -376,7 +409,7 @@ int armv7a_cache_flush_virt(struct target *target, uint32_t virt,
  * We assume that target core was chosen correctly. It means if same data
  * was handled by two cores, other core will loose the changes. Since it
  * is impossible to know (FIXME) which core has correct data, keep in mind
- * that some kind of data lost or korruption is possible.
+ * that some kind of data lost or corruption is possible.
  * Possible scenario:
  *  - core1 loaded and changed data on 0x12345678
  *  - we halted target and modified same data on core0
@@ -398,7 +431,7 @@ COMMAND_HANDLER(arm7a_l1_cache_info_cmd)
        struct target *target = get_current_target(CMD_CTX);
        struct armv7a_common *armv7a = target_to_armv7a(target);
 
-       return armv7a_handle_cache_info_command(CMD_CTX,
+       return armv7a_handle_cache_info_command(CMD,
                        &armv7a->armv7a_mmu.armv7a_cache);
 }
 
@@ -480,7 +513,7 @@ COMMAND_HANDLER(arm7a_cache_disable_auto_cmd)
        struct armv7a_common *armv7a = target_to_armv7a(target);
 
        if (CMD_ARGC == 0) {
-               command_print(CMD_CTX, "auto cache is %s",
+               command_print(CMD, "auto cache is %s",
                        armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled ? "enabled" : "disabled");
                return ERROR_OK;
        }
@@ -539,12 +572,12 @@ static const struct command_registration arm7a_l1_i_cache_commands[] = {
        COMMAND_REGISTRATION_DONE
 };
 
-const struct command_registration arm7a_l1_di_cache_group_handlers[] = {
+static const struct command_registration arm7a_l1_di_cache_group_handlers[] = {
        {
                .name = "info",
                .handler = arm7a_l1_cache_info_cmd,
                .mode = COMMAND_ANY,
-               .help = "print cache realted information",
+               .help = "print cache related information",
                .usage = "",
        },
        {
@@ -564,7 +597,7 @@ const struct command_registration arm7a_l1_di_cache_group_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
-const struct command_registration arm7a_cache_group_handlers[] = {
+static const struct command_registration arm7a_cache_group_handlers[] = {
        {
                .name = "auto",
                .handler = arm7a_cache_disable_auto_cmd,

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)