armv7a: rework automatic flush-on-write handling 27/3027/10
authorMatthias Welwarsky <matthias@welwarsky.de>
Fri, 16 Oct 2015 08:10:02 +0000 (10:10 +0200)
committerPaul Fertser <fercerpav@gmail.com>
Mon, 30 Nov 2015 05:41:58 +0000 (05:41 +0000)
The following changes are implemented:
- Clean&Invalidate the VA range to PoC *before* the write takes place
- Remove SMP handling since DCCIMVA instruction already maintains SMP
  coherence.
- Remove separate Invalidate step

Change-Id: I19fd3cc226d8ecf2937276fc63258b6a26e369a7
Signed-off-by: Matthias Welwarsky <matthias@welwarsky.de>
Reviewed-on: http://openocd.zylin.com/3027
Reviewed-by: Paul Fertser <fercerpav@gmail.com>
Tested-by: jenkins
src/target/armv7a_cache.c
src/target/armv7a_cache.h
src/target/cortex_a.c

index 98474ecb4f97640249dc2d56b5d0f21250db3401..da617b81b1019d5b7b0a9c00cd4d19d42a5d8f6e 100644 (file)
@@ -207,8 +207,7 @@ int armv7a_l1_d_cache_clean_virt(struct target *target, uint32_t virt,
        for (i = 0; i < size; i += linelen) {
                uint32_t offs = virt + i;
 
-               /* FIXME: do we need DCCVAC or DCCVAU */
-               /* FIXME: in both cases it is not enough for i-cache */
+               /* 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);
                if (retval != ERROR_OK)
@@ -339,6 +338,14 @@ done:
        return retval;
 }
 
+int armv7a_cache_flush_virt(struct target *target, uint32_t virt,
+                               uint32_t size)
+{
+       armv7a_l1_d_cache_flush_virt(target, virt, size);
+       armv7a_l2x_cache_flush_virt(target, virt, size);
+
+       return ERROR_OK;
+}
 
 /*
  * We assume that target core was chosen correctly. It means if same data
@@ -354,41 +361,11 @@ int armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt,
                                        uint32_t size)
 {
        struct armv7a_common *armv7a = target_to_armv7a(target);
-       int retval = ERROR_OK;
 
        if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled)
                return ERROR_OK;
 
-       armv7a_l1_d_cache_clean_virt(target, virt, size);
-       armv7a_l2x_cache_flush_virt(target, virt, size);
-
-       if (target->smp) {
-               struct target_list *head;
-               struct target *curr;
-               head = target->head;
-               while (head != (struct target_list *)NULL) {
-                       curr = head->target;
-                       if (curr->state == TARGET_HALTED) {
-                               retval = armv7a_l1_i_cache_inval_all(curr);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                               retval = armv7a_l1_d_cache_inval_virt(target,
-                                               virt, size);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                       }
-                       head = head->next;
-               }
-       } else {
-               retval = armv7a_l1_i_cache_inval_all(target);
-               if (retval != ERROR_OK)
-                       return retval;
-               retval = armv7a_l1_d_cache_inval_virt(target, virt, size);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-
-       return retval;
+       return armv7a_cache_flush_virt(target, virt, size);
 }
 
 COMMAND_HANDLER(arm7a_l1_cache_info_cmd)
index 81995ac3a67383e192444c69b3850ae1d29cdcc7..fbd158b4d5ebe812efe179e6bdbfb4598e77d54a 100644 (file)
@@ -29,7 +29,8 @@ int armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt,
 int armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt,
                                        uint32_t size);
 int armv7a_cache_auto_flush_all_data(struct target *target);
-
+int armv7a_cache_flush_virt(struct target *target, uint32_t virt,
+                               uint32_t size);
 extern const struct command_registration arm7a_cache_command_handlers[];
 
 /* CLIDR cache types */
index f9c927364608a8593e586fc6093a016e06360113..39e59ae7b66819a9c40ac156e620d786ec75f545 100644 (file)
@@ -2754,10 +2754,12 @@ static int cortex_a_write_memory(struct target *target, uint32_t address,
                if (retval != ERROR_OK)
                        return retval;
        }
-       retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
 
+       /* memory writes bypass the caches, must flush before writing */
        armv7a_cache_auto_flush_on_write(target, address, size * count);
 
+       retval = cortex_a_write_apb_ab_memory(target, address, size, count, buffer);
+
        return retval;
 }
 

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)