]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
arm: implement grub_arch_sync_dma_caches
authorVladimir Serbinenko <phcoder@gmail.com>
Tue, 23 Feb 2016 11:06:00 +0000 (12:06 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Tue, 23 Feb 2016 11:06:00 +0000 (12:06 +0100)
grub-core/kern/arm/cache.c
grub-core/kern/arm/cache_armv7.S

index d3a086abb3a8104174d969e710896ae65a9d9b76..af1c4bbf544f0ebcca5c0f58c847c8dddc1f2e91 100644 (file)
@@ -29,6 +29,8 @@ void grub_arm_clean_dcache_range_armv6 (grub_addr_t start, grub_addr_t end,
                                        grub_addr_t dlinesz);
 void grub_arm_clean_dcache_range_armv7 (grub_addr_t start, grub_addr_t end,
                                        grub_addr_t dlinesz);
+void grub_arm_clean_dcache_range_poc_armv7 (grub_addr_t start, grub_addr_t end,
+                                           grub_addr_t dlinesz);
 void grub_arm_invalidate_icache_range_armv6 (grub_addr_t start, grub_addr_t end,
                                             grub_addr_t dlinesz);
 void grub_arm_invalidate_icache_range_armv7 (grub_addr_t start, grub_addr_t end,
@@ -253,9 +255,35 @@ grub_arch_sync_caches (void *address, grub_size_t len)
 }
 
 void
-grub_arch_sync_dma_caches (void *address, grub_size_t len)
+grub_arch_sync_dma_caches (volatile void *address, grub_size_t len)
 {
-  grub_arch_sync_caches (address, len);
+  grub_addr_t start = (grub_addr_t) address;
+  grub_addr_t end = start + len;
+
+  if (type == ARCH_UNKNOWN)
+    probe_caches ();
+  start = ALIGN_DOWN (start, grub_arch_cache_max_linesz);
+  end = ALIGN_UP (end, grub_arch_cache_max_linesz);
+  switch (type)
+    {
+    case ARCH_ARMV6:
+      grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz);
+      grub_arm_invalidate_icache_range_armv6 (start, end,
+                                             grub_arch_cache_ilinesz);
+      break;
+    case ARCH_ARMV5_WRITE_THROUGH:
+    case ARCH_ARMV6_UNIFIED:
+      grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz);
+      break;
+    case ARCH_ARMV7:
+      grub_arm_clean_dcache_range_poc_armv7 (start, end, grub_arch_cache_dlinesz);
+      grub_arm_invalidate_icache_range_armv7 (start, end,
+                                             grub_arch_cache_ilinesz);
+      break;
+      /* Pacify GCC.  */
+    case ARCH_UNKNOWN:
+      break;
+    }
 }
 
 void
index 1ef2754af8a7612c35c26011fab442dbba074dfd..6ba15708bc77f6ca7e833000ac706bbf102ce7bb 100644 (file)
 # define ISB   isb
 #define ARMV7 1
 
+FUNCTION(grub_arm_clean_dcache_range_poc_armv7)
+       DSB
+       @ Clean data cache for range to point-of-coherence
+1:     cmp     r0, r1
+       bge     2f
+       mcr     p15, 0, r0, c7, c14, 1  @ DCCMVAC
+       add     r0, r0, r2              @ Next line
+       b       1b
+2:     DSB
+       bx      lr
+
+
        @ r0  - CLIDR
        @ r1  - LoC
        @ r2  - current level
@@ -123,4 +135,4 @@ clean_invalidate_dcache:
        pop     {r4-r12, lr}
        bx      lr
 
-#include "cache.S"
\ No newline at end of file
+#include "cache.S"