Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 137437
b: refs/heads/master
c: 1bb7726
h: refs/heads/master
i:
  137435: 91ddf71
v: v3
  • Loading branch information
Nicolas Pitre committed Mar 16, 2009
1 parent 3c5abaf commit 5cbdb5f
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 58edb515724f9e63e569536d01ac8d8f8ddb367a
refs/heads/master: 1bb772679ffb0ba1ff1d40d8c6b855ab029f177d
1 change: 1 addition & 0 deletions trunk/arch/arm/include/asm/kmap_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum km_type {
KM_IRQ1,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_L2_CACHE,
KM_TYPE_NR
};

Expand Down
54 changes: 37 additions & 17 deletions trunk/arch/arm/mm/cache-feroceon-l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@

#include <linux/init.h>
#include <asm/cacheflush.h>
#include <asm/kmap_types.h>
#include <asm/fixmap.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <plat/cache-feroceon-l2.h>

#include "mm.h"

/*
* Low-level cache maintenance operations.
Expand All @@ -34,14 +38,36 @@
* The range operations require two successive cp15 writes, in
* between which we don't want to be preempted.
*/

static inline unsigned long l2_start_va(unsigned long paddr)
{
#ifdef CONFIG_HIGHMEM
/*
* Let's do our own fixmap stuff in a minimal way here.
* Because range ops can't be done on physical addresses,
* we simply install a virtual mapping for it only for the
* TLB lookup to occur, hence no need to flush the untouched
* memory mapping. This is protected with the disabling of
* interrupts by the caller.
*/
unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0);
local_flush_tlb_kernel_page(vaddr);
return vaddr + (paddr & ~PAGE_MASK);
#else
return __phys_to_virt(paddr);
#endif
}

static inline void l2_clean_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
}

static inline void l2_clean_mva_range(unsigned long start, unsigned long end)
static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
{
unsigned long flags;
unsigned long va_start, va_end, flags;

/*
* Make sure 'start' and 'end' reference the same page, as
Expand All @@ -51,17 +77,14 @@ static inline void l2_clean_mva_range(unsigned long start, unsigned long end)
BUG_ON((start ^ end) >> PAGE_SHIFT);

raw_local_irq_save(flags);
va_start = l2_start_va(start);
va_end = va_start + (end - start);
__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
"mcr p15, 1, %1, c15, c9, 5"
: : "r" (start), "r" (end));
: : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
}

static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
{
l2_clean_mva_range(__phys_to_virt(start), __phys_to_virt(end));
}

static inline void l2_clean_inv_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c15, c10, 3" : : "r" (addr));
Expand All @@ -72,9 +95,9 @@ static inline void l2_inv_pa(unsigned long addr)
__asm__("mcr p15, 1, %0, c15, c11, 3" : : "r" (addr));
}

static inline void l2_inv_mva_range(unsigned long start, unsigned long end)
static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
{
unsigned long flags;
unsigned long va_start, va_end, flags;

/*
* Make sure 'start' and 'end' reference the same page, as
Expand All @@ -84,17 +107,14 @@ static inline void l2_inv_mva_range(unsigned long start, unsigned long end)
BUG_ON((start ^ end) >> PAGE_SHIFT);

raw_local_irq_save(flags);
va_start = l2_start_va(start);
va_end = va_start + (end - start);
__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
"mcr p15, 1, %1, c15, c11, 5"
: : "r" (start), "r" (end));
: : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
}

static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
{
l2_inv_mva_range(__phys_to_virt(start), __phys_to_virt(end));
}


/*
* Linux primitives.
Expand Down

0 comments on commit 5cbdb5f

Please sign in to comment.