| /* |
| * Copyright (C) 2004-2006 Atmel Corporation |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| #ifndef __ASM_AVR32_CACHEFLUSH_H |
| #define __ASM_AVR32_CACHEFLUSH_H |
| |
| /* Keep includes the same across arches. */ |
| #include <linux/mm.h> |
| |
| #define CACHE_OP_ICACHE_INVALIDATE 0x01 |
| #define CACHE_OP_DCACHE_INVALIDATE 0x0b |
| #define CACHE_OP_DCACHE_CLEAN 0x0c |
| #define CACHE_OP_DCACHE_CLEAN_INVAL 0x0d |
| |
| /* |
| * Invalidate any cacheline containing virtual address vaddr without |
| * writing anything back to memory. |
| * |
| * Note that this function may corrupt unrelated data structures when |
| * applied on buffers that are not cacheline aligned in both ends. |
| */ |
| static inline void invalidate_dcache_line(void *vaddr) |
| { |
| asm volatile("cache %0[0], %1" |
| : |
| : "r"(vaddr), "n"(CACHE_OP_DCACHE_INVALIDATE) |
| : "memory"); |
| } |
| |
| /* |
| * Make sure any cacheline containing virtual address vaddr is written |
| * to memory. |
| */ |
| static inline void clean_dcache_line(void *vaddr) |
| { |
| asm volatile("cache %0[0], %1" |
| : |
| : "r"(vaddr), "n"(CACHE_OP_DCACHE_CLEAN) |
| : "memory"); |
| } |
| |
| /* |
| * Make sure any cacheline containing virtual address vaddr is written |
| * to memory and then invalidate it. |
| */ |
| static inline void flush_dcache_line(void *vaddr) |
| { |
| asm volatile("cache %0[0], %1" |
| : |
| : "r"(vaddr), "n"(CACHE_OP_DCACHE_CLEAN_INVAL) |
| : "memory"); |
| } |
| |
| /* |
| * Invalidate any instruction cacheline containing virtual address |
| * vaddr. |
| */ |
| static inline void invalidate_icache_line(void *vaddr) |
| { |
| asm volatile("cache %0[0], %1" |
| : |
| : "r"(vaddr), "n"(CACHE_OP_ICACHE_INVALIDATE) |
| : "memory"); |
| } |
| |
| /* |
| * Applies the above functions on all lines that are touched by the |
| * specified virtual address range. |
| */ |
| void invalidate_dcache_region(void *start, size_t len); |
| void clean_dcache_region(void *start, size_t len); |
| void flush_dcache_region(void *start, size_t len); |
| void invalidate_icache_region(void *start, size_t len); |
| |
| /* |
| * Make sure any pending writes are completed before continuing. |
| */ |
| #define flush_write_buffer() asm volatile("sync 0" : : : "memory") |
| |
| /* |
| * The following functions are called when a virtual mapping changes. |
| * We do not need to flush anything in this case. |
| */ |
| #define flush_cache_all() do { } while (0) |
| #define flush_cache_mm(mm) do { } while (0) |
| #define flush_cache_dup_mm(mm) do { } while (0) |
| #define flush_cache_range(vma, start, end) do { } while (0) |
| #define flush_cache_page(vma, vmaddr, pfn) do { } while (0) |
| #define flush_cache_vmap(start, end) do { } while (0) |
| #define flush_cache_vunmap(start, end) do { } while (0) |
| |
| /* |
| * I think we need to implement this one to be able to reliably |
| * execute pages from RAMDISK. However, if we implement the |
| * flush_dcache_*() functions, it might not be needed anymore. |
| * |
| * #define flush_icache_page(vma, page) do { } while (0) |
| */ |
| extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); |
| |
| /* |
| * These are (I think) related to D-cache aliasing. We might need to |
| * do something here, but only for certain configurations. No such |
| * configurations exist at this time. |
| */ |
| #define flush_dcache_page(page) do { } while (0) |
| #define flush_dcache_mmap_lock(page) do { } while (0) |
| #define flush_dcache_mmap_unlock(page) do { } while (0) |
| |
| /* |
| * These are for I/D cache coherency. In this case, we do need to |
| * flush with all configurations. |
| */ |
| extern void flush_icache_range(unsigned long start, unsigned long end); |
| |
| extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page, |
| unsigned long vaddr, void *dst, const void *src, |
| unsigned long len); |
| |
| static inline void copy_from_user_page(struct vm_area_struct *vma, |
| struct page *page, unsigned long vaddr, void *dst, |
| const void *src, unsigned long len) |
| { |
| memcpy(dst, src, len); |
| } |
| |
| #endif /* __ASM_AVR32_CACHEFLUSH_H */ |