We currently only have dma_alloc_writecombine() for aarch32. Implement it for aarch64 as it is useful for mapping framebuffer memory. Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- arch/arm/cpu/mmu_64.c | 11 ++++++++++- arch/arm/cpu/mmu_64.h | 15 ++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c index 7c7834201b..7854f71f4c 100644 --- a/arch/arm/cpu/mmu_64.c +++ b/arch/arm/cpu/mmu_64.c @@ -24,6 +24,8 @@ #include "mmu_64.h" +#define ARCH_MAP_WRITECOMBINE ((unsigned)-1) + static uint64_t *get_ttb(void) { return (uint64_t *)get_ttbr(current_el()); @@ -172,9 +174,11 @@ static unsigned long get_pte_attrs(unsigned flags) case MAP_CACHED: return CACHED_MEM; case MAP_UNCACHED: - return attrs_uncached_mem(); + return attrs_xn() | UNCACHED_MEM; case MAP_FAULT: return 0x0; + case ARCH_MAP_WRITECOMBINE: + return attrs_xn() | MEM_ALLOC_WRITECOMBINE; default: return ~0UL; } @@ -295,6 +299,11 @@ void dma_flush_range(void *ptr, size_t size) v8_flush_dcache_range(start, end); } +void *dma_alloc_writecombine(size_t size, dma_addr_t *dma_handle) +{ + return dma_alloc_map(size, dma_handle, ARCH_MAP_WRITECOMBINE); +} + static void init_range(size_t total_level0_tables) { uint64_t *ttb = get_ttb(); diff --git a/arch/arm/cpu/mmu_64.h b/arch/arm/cpu/mmu_64.h index e3959e4407..d3c39dabb5 100644 --- a/arch/arm/cpu/mmu_64.h +++ b/arch/arm/cpu/mmu_64.h @@ -8,22 +8,19 @@ #define UNCACHED_MEM (PTE_BLOCK_MEMTYPE(MT_DEVICE_nGnRnE) | \ PTE_BLOCK_OUTER_SHARE | \ PTE_BLOCK_AF) +#define MEM_ALLOC_WRITECOMBINE (PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | \ + PTE_BLOCK_OUTER_SHARE | \ + PTE_BLOCK_AF) -static inline unsigned long attrs_uncached_mem(void) +static inline unsigned long attrs_xn(void) { - unsigned long attrs = UNCACHED_MEM; - switch (current_el()) { case 3: case 2: - attrs |= PTE_BLOCK_UXN; - break; + return PTE_BLOCK_UXN; default: - attrs |= PTE_BLOCK_UXN | PTE_BLOCK_PXN; - break; + return PTE_BLOCK_UXN | PTE_BLOCK_PXN; } - - return attrs; } /* -- 2.39.5