From 07cd46627bd49c5142987ba541b44b5e9f58caa3 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Tue, 23 Feb 2016 12:06:00 +0100 Subject: [PATCH] arm: implement grub_arch_sync_dma_caches --- grub-core/kern/arm/cache.c | 32 ++++++++++++++++++++++++++++++-- grub-core/kern/arm/cache_armv7.S | 14 +++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/grub-core/kern/arm/cache.c b/grub-core/kern/arm/cache.c index d3a086abb..af1c4bbf5 100644 --- a/grub-core/kern/arm/cache.c +++ b/grub-core/kern/arm/cache.c @@ -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 diff --git a/grub-core/kern/arm/cache_armv7.S b/grub-core/kern/arm/cache_armv7.S index 1ef2754af..6ba15708b 100644 --- a/grub-core/kern/arm/cache_armv7.S +++ b/grub-core/kern/arm/cache_armv7.S @@ -33,6 +33,18 @@ # 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" -- 2.47.2