summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@flint.arm.linux.org.uk>2003-04-27 22:28:25 +0100
committerRussell King <rmk@flint.arm.linux.org.uk>2003-04-27 22:28:25 +0100
commit10eacf1775e168e57c610cfcc7358fa357fbb0d5 (patch)
tree7de1ce64662fb071f5b13cd558f15a91e930302b
parentd7181b4b753c8a5a6893036eeabe431724b21bd0 (diff)
[ARM] Clean up ARM cache handling interfaces (part 1)
This starts to move the ARM cache handling interface towards a purpose-defined rather than functionality-defined interface. This is necessary so we are able to support a wide range of ARM CPUs.
-rw-r--r--arch/arm/mm/consistent.c12
-rw-r--r--include/asm-arm/proc-armv/cache.h84
2 files changed, 46 insertions, 50 deletions
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index d67ce3eb8029..265c8fbe868e 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -161,11 +161,11 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle,
/*
* Invalidate any data that might be lurking in the
- * kernel direct-mapped region.
+ * kernel direct-mapped region for device DMA.
*/
{
unsigned long kaddr = (unsigned long)page_address(page);
- invalidate_dcache_range(kaddr, kaddr + size);
+ dmac_inv_range(kaddr, kaddr + size);
}
/*
@@ -330,7 +330,7 @@ static int __init consistent_init(void)
core_initcall(consistent_init);
/*
- * make an area consistent.
+ * make an area consistent for devices.
*/
void consistent_sync(void *vaddr, size_t size, int direction)
{
@@ -339,13 +339,13 @@ void consistent_sync(void *vaddr, size_t size, int direction)
switch (direction) {
case DMA_FROM_DEVICE: /* invalidate only */
- invalidate_dcache_range(start, end);
+ dmac_inv_range(start, end);
break;
case DMA_TO_DEVICE: /* writeback only */
- clean_dcache_range(start, end);
+ dmac_clean_range(start, end);
break;
case DMA_BIDIRECTIONAL: /* writeback and invalidate */
- flush_dcache_range(start, end);
+ dmac_flush_range(start, end);
break;
default:
BUG();
diff --git a/include/asm-arm/proc-armv/cache.h b/include/asm-arm/proc-armv/cache.h
index 4bc1a79e72d3..ba2bc2972b6d 100644
--- a/include/asm-arm/proc-armv/cache.h
+++ b/include/asm-arm/proc-armv/cache.h
@@ -29,43 +29,54 @@
*/
/*
- * Generic I + D cache
+ * These are private to the dma-mapping API. Do not use directly.
+ * Their sole purpose is to ensure that data held in the cache
+ * is visible to DMA, or data written by DMA to system memory is
+ * visible to the CPU.
*/
-#define flush_cache_all() \
- do { \
- cpu_cache_clean_invalidate_all(); \
- } while (0)
+#define dmac_inv_range cpu_dcache_invalidate_range
+#define dmac_clean_range cpu_dcache_clean_range
+#define dmac_flush_range(_s,_e) cpu_cache_clean_invalidate_range((_s),(_e),0)
-/* This is always called for current->mm */
-#define flush_cache_mm(_mm) \
- do { \
- if ((_mm) == current->active_mm) \
- cpu_cache_clean_invalidate_all(); \
- } while (0)
+/*
+ * Convert calls to our calling convention.
+ */
+#define flush_cache_all() cpu_cache_clean_invalidate_all()
-#define flush_cache_range(_vma,_start,_end) \
- do { \
- if ((_vma)->vm_mm == current->active_mm) \
- cpu_cache_clean_invalidate_range((_start), (_end), 1); \
- } while (0)
+static inline void flush_cache_mm(struct mm_struct *mm)
+{
+ if (current->active_mm == mm)
+ cpu_cache_clean_invalidate_all();
+}
-#define flush_cache_page(_vma,_vmaddr) \
- do { \
- if ((_vma)->vm_mm == current->active_mm) { \
- cpu_cache_clean_invalidate_range((_vmaddr), \
- (_vmaddr) + PAGE_SIZE, \
- ((_vma)->vm_flags & VM_EXEC)); \
- } \
- } while (0)
+static inline void
+flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+ if (current->active_mm == vma->vm_mm)
+ cpu_cache_clean_invalidate_range(start & PAGE_MASK,
+ PAGE_ALIGN(end), vma->vm_flags);
+}
+
+static inline void
+flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr)
+{
+ if (current->active_mm == vma->vm_mm) {
+ unsigned long addr = user_addr & PAGE_MASK;
+ cpu_cache_clean_invalidate_range(addr, addr + PAGE_SIZE,
+ vma->vm_flags & VM_EXEC);
+ }
+}
/*
- * D cache only
+ * Perform necessary cache operations to ensure that data previously
+ * stored within this range of addresses can be executed by the CPU.
*/
+#define flush_icache_range(s,e) cpu_icache_invalidate_range(s,e)
-#define invalidate_dcache_range(_s,_e) cpu_dcache_invalidate_range((_s),(_e))
-#define clean_dcache_range(_s,_e) cpu_dcache_clean_range((_s),(_e))
-#define flush_dcache_range(_s,_e) cpu_cache_clean_invalidate_range((_s),(_e),0)
-
+/*
+ * Perform necessary cache operations to ensure that the TLB will
+ * see data written in the specified area.
+ */
#define clean_dcache_area(start,size) \
cpu_cache_clean_invalidate_range((unsigned long)start, \
((unsigned long)start) + size, 0);
@@ -104,18 +115,3 @@ static inline void flush_dcache_page(struct page *page)
* duplicate cache flushing elsewhere performed by flush_dcache_page().
*/
#define flush_icache_page(vma,page) do { } while (0)
-
-/*
- * I cache coherency stuff.
- *
- * This *is not* just icache. It is to make data written to memory
- * consistent such that instructions fetched from the region are what
- * we expect.
- *
- * This generally means that we have to clean out the Dcache and write
- * buffers, and maybe flush the Icache in the specified range.
- */
-#define flush_icache_range(_s,_e) \
- do { \
- cpu_icache_invalidate_range((_s), (_e)); \
- } while (0)