aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-xtensa/page.h
diff options
context:
space:
mode:
authorChris Zankel <chris@zankel.net>2007-08-22 13:14:51 -0400
committerChris Zankel <chris@zankel.net>2007-08-27 16:54:16 -0400
commit6656920b0b50beacb6cb64cf55273cbb686e436e (patch)
treedab9fdb81821b455a29779de6ca3306dbdf05dbd /include/asm-xtensa/page.h
parentff6fd469885aafa5ec387babcb6537f3c00d6df0 (diff)
[XTENSA] Add support for cache-aliasing
Add support for processors that have cache-aliasing issues, such as the Stretch S5000 processor. Cache-aliasing means that the size of the cache (for one way) is larger than the page size, thus, a page can end up in several places in cache depending on the virtual to physical translation. The method used here is to map a user page temporarily through the auto-refill way 0 and of of the DTLB. We probably will want to revisit this issue and use a better approach with kmap/kunmap. Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'include/asm-xtensa/page.h')
-rw-r--r--include/asm-xtensa/page.h56
1 files changed, 52 insertions, 4 deletions
diff --git a/include/asm-xtensa/page.h b/include/asm-xtensa/page.h
index 2d6ac21136cf..55ce2c9749a3 100644
--- a/include/asm-xtensa/page.h
+++ b/include/asm-xtensa/page.h
@@ -15,6 +15,7 @@
15 15
16#include <asm/processor.h> 16#include <asm/processor.h>
17#include <asm/types.h> 17#include <asm/types.h>
18#include <asm/cache.h>
18 19
19/* 20/*
20 * Fixed TLB translations in the processor. 21 * Fixed TLB translations in the processor.
@@ -39,6 +40,53 @@
39#define MAX_MEM_PFN XCHAL_KSEG_SIZE 40#define MAX_MEM_PFN XCHAL_KSEG_SIZE
40#define PGTABLE_START 0x80000000 41#define PGTABLE_START 0x80000000
41 42
43/*
44 * Cache aliasing:
45 *
46 * If the cache size for one way is greater than the page size, we have to
47 * deal with cache aliasing. The cache index is wider than the page size:
48 *
49 * | |cache| cache index
50 * | pfn |off| virtual address
51 * |xxxx:X|zzz|
52 * | : | |
53 * | \ / | |
54 * |trans.| |
55 * | / \ | |
56 * |yyyy:Y|zzz| physical address
57 *
58 * When the page number is translated to the physical page address, the lowest
59 * bit(s) (X) that are part of the cache index are also translated (Y).
60 * If this translation changes bit(s) (X), the cache index is also afected,
61 * thus resulting in a different cache line than before.
62 * The kernel does not provide a mechanism to ensure that the page color
63 * (represented by this bit) remains the same when allocated or when pages
64 * are remapped. When user pages are mapped into kernel space, the color of
65 * the page might also change.
66 *
67 * We use the address space VMALLOC_END ... VMALLOC_END + DCACHE_WAY_SIZE * 2
68 * to temporarily map a patch so we can match the color.
69 */
70
71#if DCACHE_WAY_SIZE > PAGE_SIZE
72# define DCACHE_ALIAS_ORDER (DCACHE_WAY_SHIFT - PAGE_SHIFT)
73# define DCACHE_ALIAS_MASK (PAGE_MASK & (DCACHE_WAY_SIZE - 1))
74# define DCACHE_ALIAS(a) (((a) & DCACHE_ALIAS_MASK) >> PAGE_SHIFT)
75# define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0)
76#else
77# define DCACHE_ALIAS_ORDER 0
78#endif
79
80#if ICACHE_WAY_SIZE > PAGE_SIZE
81# define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT)
82# define ICACHE_ALIAS_MASK (PAGE_MASK & (ICACHE_WAY_SIZE - 1))
83# define ICACHE_ALIAS(a) (((a) & ICACHE_ALIAS_MASK) >> PAGE_SHIFT)
84# define ICACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & ICACHE_ALIAS_MASK) == 0)
85#else
86# define ICACHE_ALIAS_ORDER 0
87#endif
88
89
42#ifdef __ASSEMBLY__ 90#ifdef __ASSEMBLY__
43 91
44#define __pgprot(x) (x) 92#define __pgprot(x) (x)
@@ -90,11 +138,11 @@ extern void copy_page(void *to, void *from);
90 * some extra work 138 * some extra work
91 */ 139 */
92 140
93#if (DCACHE_WAY_SIZE > PAGE_SIZE) 141#if DCACHE_WAY_SIZE > PAGE_SIZE
94void clear_user_page(void *addr, unsigned long vaddr, struct page* page); 142extern void clear_user_page(void*, unsigned long, struct page*);
95void copy_user_page(void *to,void* from,unsigned long vaddr,struct page* page); 143extern void copy_user_page(void*, void*, unsigned long, struct page*);
96#else 144#else
97# define clear_user_page(page,vaddr,pg) clear_page(page) 145# define clear_user_page(page, vaddr, pg) clear_page(page)
98# define copy_user_page(to, from, vaddr, pg) copy_page(to, from) 146# define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
99#endif 147#endif
100 148