aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/pgtable-bits.h
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2010-02-10 18:12:47 -0500
committerRalf Baechle <ralf@linux-mips.org>2010-02-27 06:53:26 -0500
commit6dd9344cfc41bcc60a01cdc828cb278be7a10e01 (patch)
tree9c62d563eba8f3acfd1c826a63e6999261b06f5a /arch/mips/include/asm/pgtable-bits.h
parent32546f38fab839eee6f62b3f06c2774eade4188a (diff)
MIPS: Implement Read Inhibit/eXecute Inhibit
The SmartMIPS ASE specifies how Read Inhibit (RI) and eXecute Inhibit (XI) bits in the page tables work. The upper two bits of EntryLo{0,1} are RI and XI when the feature is enabled in the PageGrain register. SmartMIPS only covers 32-bit systems. Cavium Octeon+ extends this to 64-bit systems by continuing to place the RI and XI bits in the top of EntryLo even when EntryLo is 64-bits wide. Because we need to carry the RI and XI bits in the PTE, the layout of the PTE is changed. There is a two instruction overhead in the TLB refill hot path to get the EntryLo bits into the proper position. Also the TLB load exception has to probe the TLB to check if RI or XI caused the exception. Also of note is that the layout of the PTE bits is done at compile and runtime rather than statically. In the 32-bit case this allows for the same number of PFN bits as before the patch as the _PAGE_HUGE is not supported in 32-bit kernels (we have _PAGE_NO_EXEC and _PAGE_NO_READ instead of _PAGE_READ and _PAGE_HUGE). The patch is tested on Cavium Octeon+, but should also work on 32-bit systems with the Smart-MIPS ASE. Signed-off-by: David Daney <ddaney@caviumnetworks.com> To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/952/ Patchwork: http://patchwork.linux-mips.org/patch/956/ Patchwork: http://patchwork.linux-mips.org/patch/962/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/include/asm/pgtable-bits.h')
-rw-r--r--arch/mips/include/asm/pgtable-bits.h120
1 files changed, 105 insertions, 15 deletions
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index 1073e6df8621..e9fe7e97ce4c 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -50,7 +50,7 @@
50#define _CACHE_SHIFT 3 50#define _CACHE_SHIFT 3
51#define _CACHE_MASK (7<<3) 51#define _CACHE_MASK (7<<3)
52 52
53#else 53#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
54 54
55#define _PAGE_PRESENT (1<<0) /* implemented in software */ 55#define _PAGE_PRESENT (1<<0) /* implemented in software */
56#define _PAGE_READ (1<<1) /* implemented in software */ 56#define _PAGE_READ (1<<1) /* implemented in software */
@@ -59,8 +59,6 @@
59#define _PAGE_MODIFIED (1<<4) /* implemented in software */ 59#define _PAGE_MODIFIED (1<<4) /* implemented in software */
60#define _PAGE_FILE (1<<4) /* set:pagecache unset:swap */ 60#define _PAGE_FILE (1<<4) /* set:pagecache unset:swap */
61 61
62#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
63
64#define _PAGE_GLOBAL (1<<8) 62#define _PAGE_GLOBAL (1<<8)
65#define _PAGE_VALID (1<<9) 63#define _PAGE_VALID (1<<9)
66#define _PAGE_SILENT_READ (1<<9) /* synonym */ 64#define _PAGE_SILENT_READ (1<<9) /* synonym */
@@ -69,21 +67,113 @@
69#define _CACHE_UNCACHED (1<<11) 67#define _CACHE_UNCACHED (1<<11)
70#define _CACHE_MASK (1<<11) 68#define _CACHE_MASK (1<<11)
71 69
70#else /* 'Normal' r4K case */
71/*
72 * When using the RI/XI bit support, we have 13 bits of flags below
73 * the physical address. The RI/XI bits are placed such that a SRL 5
74 * can strip off the software bits, then a ROTR 2 can move the RI/XI
75 * into bits [63:62]. This also limits physical address to 56 bits,
76 * which is more than we need right now.
77 */
78
79/* implemented in software */
80#define _PAGE_PRESENT_SHIFT (0)
81#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
82/* implemented in software, should be unused if kernel_uses_smartmips_rixi. */
83#define _PAGE_READ_SHIFT (kernel_uses_smartmips_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
84#define _PAGE_READ ({if (kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_READ_SHIFT; })
85/* implemented in software */
86#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1)
87#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
88/* implemented in software */
89#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
90#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
91/* implemented in software */
92#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
93#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
94/* set:pagecache unset:swap */
95#define _PAGE_FILE (_PAGE_MODIFIED)
96
97#ifdef CONFIG_HUGETLB_PAGE
98/* huge tlb page */
99#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
100#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
72#else 101#else
102#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
103#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
104#endif
73 105
74#define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */ 106/* Page cannot be executed */
75#define _PAGE_HUGE (1<<5) /* huge tlb page */ 107#define _PAGE_NO_EXEC_SHIFT (kernel_uses_smartmips_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT)
76#define _PAGE_GLOBAL (1<<6) 108#define _PAGE_NO_EXEC ({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_EXEC_SHIFT; })
77#define _PAGE_VALID (1<<7) 109
78#define _PAGE_SILENT_READ (1<<7) /* synonym */ 110/* Page cannot be read */
79#define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */ 111#define _PAGE_NO_READ_SHIFT (kernel_uses_smartmips_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
80#define _PAGE_SILENT_WRITE (1<<8) 112#define _PAGE_NO_READ ({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_READ_SHIFT; })
81#define _CACHE_SHIFT 9 113
82#define _CACHE_MASK (7<<9) 114#define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1)
115#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
116
117#define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1)
118#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)
119/* synonym */
120#define _PAGE_SILENT_READ (_PAGE_VALID)
121
122/* The MIPS dirty bit */
123#define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1)
124#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT)
125#define _PAGE_SILENT_WRITE (_PAGE_DIRTY)
126
127#define _CACHE_SHIFT (_PAGE_DIRTY_SHIFT + 1)
128#define _CACHE_MASK (7 << _CACHE_SHIFT)
129
130#define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
83 131
84#endif
85#endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */ 132#endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */
86 133
134#ifndef _PFN_SHIFT
135#define _PFN_SHIFT PAGE_SHIFT
136#endif
137#define _PFN_MASK (~((1 << (_PFN_SHIFT)) - 1))
138
139#ifndef _PAGE_NO_READ
140#define _PAGE_NO_READ ({BUG(); 0; })
141#define _PAGE_NO_READ_SHIFT ({BUG(); 0; })
142#endif
143#ifndef _PAGE_NO_EXEC
144#define _PAGE_NO_EXEC ({BUG(); 0; })
145#endif
146#ifndef _PAGE_GLOBAL_SHIFT
147#define _PAGE_GLOBAL_SHIFT ilog2(_PAGE_GLOBAL)
148#endif
149
150
151#ifndef __ASSEMBLY__
152/*
153 * pte_to_entrylo converts a page table entry (PTE) into a Mips
154 * entrylo0/1 value.
155 */
156static inline uint64_t pte_to_entrylo(unsigned long pte_val)
157{
158 if (kernel_uses_smartmips_rixi) {
159 int sa;
160#ifdef CONFIG_32BIT
161 sa = 31 - _PAGE_NO_READ_SHIFT;
162#else
163 sa = 63 - _PAGE_NO_READ_SHIFT;
164#endif
165 /*
166 * C has no way to express that this is a DSRL
167 * _PAGE_NO_EXEC_SHIFT followed by a ROTR 2. Luckily
168 * in the fast path this is done in assembly
169 */
170 return (pte_val >> _PAGE_GLOBAL_SHIFT) |
171 ((pte_val & (_PAGE_NO_EXEC | _PAGE_NO_READ)) << sa);
172 }
173
174 return pte_val >> _PAGE_GLOBAL_SHIFT;
175}
176#endif
87 177
88/* 178/*
89 * Cache attributes 179 * Cache attributes
@@ -130,9 +220,9 @@
130 220
131#endif 221#endif
132 222
133#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) 223#define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ))
134#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) 224#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
135 225
136#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK) 226#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
137 227
138#endif /* _ASM_PGTABLE_BITS_H */ 228#endif /* _ASM_PGTABLE_BITS_H */