diff options
Diffstat (limited to 'arch/arm/mm/proc-macros.S')
-rw-r--r-- | arch/arm/mm/proc-macros.S | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 7d63beaf9745..34261f9486b9 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S | |||
@@ -61,27 +61,37 @@ | |||
61 | .endm | 61 | .endm |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * cache_line_size - get the cache line size from the CSIDR register | 64 | * dcache_line_size - get the minimum D-cache line size from the CTR register |
65 | * (available on ARMv7+). It assumes that the CSSR register was configured | 65 | * on ARMv7. |
66 | * to access the L1 data cache CSIDR. | ||
67 | */ | 66 | */ |
68 | .macro dcache_line_size, reg, tmp | 67 | .macro dcache_line_size, reg, tmp |
69 | mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR | 68 | mrc p15, 0, \tmp, c0, c0, 1 @ read ctr |
70 | and \tmp, \tmp, #7 @ cache line size encoding | 69 | lsr \tmp, \tmp, #16 |
71 | mov \reg, #16 @ size offset | 70 | and \tmp, \tmp, #0xf @ cache line size encoding |
71 | mov \reg, #4 @ bytes per word | ||
72 | mov \reg, \reg, lsl \tmp @ actual cache line size | 72 | mov \reg, \reg, lsl \tmp @ actual cache line size |
73 | .endm | 73 | .endm |
74 | 74 | ||
75 | /* | ||
76 | * icache_line_size - get the minimum I-cache line size from the CTR register | ||
77 | * on ARMv7. | ||
78 | */ | ||
79 | .macro icache_line_size, reg, tmp | ||
80 | mrc p15, 0, \tmp, c0, c0, 1 @ read ctr | ||
81 | and \tmp, \tmp, #0xf @ cache line size encoding | ||
82 | mov \reg, #4 @ bytes per word | ||
83 | mov \reg, \reg, lsl \tmp @ actual cache line size | ||
84 | .endm | ||
75 | 85 | ||
76 | /* | 86 | /* |
77 | * Sanity check the PTE configuration for the code below - which makes | 87 | * Sanity check the PTE configuration for the code below - which makes |
78 | * certain assumptions about how these bits are layed out. | 88 | * certain assumptions about how these bits are laid out. |
79 | */ | 89 | */ |
80 | #ifdef CONFIG_MMU | 90 | #ifdef CONFIG_MMU |
81 | #if L_PTE_SHARED != PTE_EXT_SHARED | 91 | #if L_PTE_SHARED != PTE_EXT_SHARED |
82 | #error PTE shared bit mismatch | 92 | #error PTE shared bit mismatch |
83 | #endif | 93 | #endif |
84 | #if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\ | 94 | #if (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\ |
85 | L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED | 95 | L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED |
86 | #error Invalid Linux PTE bit settings | 96 | #error Invalid Linux PTE bit settings |
87 | #endif | 97 | #endif |
@@ -99,6 +109,10 @@ | |||
99 | * 110x 0 1 0 r/w r/o | 109 | * 110x 0 1 0 r/w r/o |
100 | * 11x0 0 1 0 r/w r/o | 110 | * 11x0 0 1 0 r/w r/o |
101 | * 1111 0 1 1 r/w r/w | 111 | * 1111 0 1 1 r/w r/w |
112 | * | ||
113 | * If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed: | ||
114 | * 110x 1 1 1 r/o r/o | ||
115 | * 11x0 1 1 1 r/o r/o | ||
102 | */ | 116 | */ |
103 | .macro armv6_mt_table pfx | 117 | .macro armv6_mt_table pfx |
104 | \pfx\()_mt_table: | 118 | \pfx\()_mt_table: |
@@ -121,7 +135,7 @@ | |||
121 | .endm | 135 | .endm |
122 | 136 | ||
123 | .macro armv6_set_pte_ext pfx | 137 | .macro armv6_set_pte_ext pfx |
124 | str r1, [r0], #-2048 @ linux version | 138 | str r1, [r0], #2048 @ linux version |
125 | 139 | ||
126 | bic r3, r1, #0x000003fc | 140 | bic r3, r1, #0x000003fc |
127 | bic r3, r3, #PTE_TYPE_MASK | 141 | bic r3, r3, #PTE_TYPE_MASK |
@@ -132,17 +146,20 @@ | |||
132 | and r2, r1, #L_PTE_MT_MASK | 146 | and r2, r1, #L_PTE_MT_MASK |
133 | ldr r2, [ip, r2] | 147 | ldr r2, [ip, r2] |
134 | 148 | ||
135 | tst r1, #L_PTE_WRITE | 149 | eor r1, r1, #L_PTE_DIRTY |
136 | tstne r1, #L_PTE_DIRTY | 150 | tst r1, #L_PTE_DIRTY|L_PTE_RDONLY |
137 | orreq r3, r3, #PTE_EXT_APX | 151 | orrne r3, r3, #PTE_EXT_APX |
138 | 152 | ||
139 | tst r1, #L_PTE_USER | 153 | tst r1, #L_PTE_USER |
140 | orrne r3, r3, #PTE_EXT_AP1 | 154 | orrne r3, r3, #PTE_EXT_AP1 |
155 | #ifdef CONFIG_CPU_USE_DOMAINS | ||
156 | @ allow kernel read/write access to read-only user pages | ||
141 | tstne r3, #PTE_EXT_APX | 157 | tstne r3, #PTE_EXT_APX |
142 | bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 | 158 | bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 |
159 | #endif | ||
143 | 160 | ||
144 | tst r1, #L_PTE_EXEC | 161 | tst r1, #L_PTE_XN |
145 | orreq r3, r3, #PTE_EXT_XN | 162 | orrne r3, r3, #PTE_EXT_XN |
146 | 163 | ||
147 | orr r3, r3, r2 | 164 | orr r3, r3, r2 |
148 | 165 | ||
@@ -170,9 +187,9 @@ | |||
170 | * 1111 0xff r/w r/w | 187 | * 1111 0xff r/w r/w |
171 | */ | 188 | */ |
172 | .macro armv3_set_pte_ext wc_disable=1 | 189 | .macro armv3_set_pte_ext wc_disable=1 |
173 | str r1, [r0], #-2048 @ linux version | 190 | str r1, [r0], #2048 @ linux version |
174 | 191 | ||
175 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY | 192 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
176 | 193 | ||
177 | bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits | 194 | bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits |
178 | bic r2, r2, #PTE_TYPE_MASK | 195 | bic r2, r2, #PTE_TYPE_MASK |
@@ -181,7 +198,7 @@ | |||
181 | tst r3, #L_PTE_USER @ user? | 198 | tst r3, #L_PTE_USER @ user? |
182 | orrne r2, r2, #PTE_SMALL_AP_URO_SRW | 199 | orrne r2, r2, #PTE_SMALL_AP_URO_SRW |
183 | 200 | ||
184 | tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty? | 201 | tst r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty? |
185 | orreq r2, r2, #PTE_SMALL_AP_UNO_SRW | 202 | orreq r2, r2, #PTE_SMALL_AP_UNO_SRW |
186 | 203 | ||
187 | tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? | 204 | tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? |
@@ -193,7 +210,7 @@ | |||
193 | bicne r2, r2, #PTE_BUFFERABLE | 210 | bicne r2, r2, #PTE_BUFFERABLE |
194 | #endif | 211 | #endif |
195 | .endif | 212 | .endif |
196 | str r2, [r0] @ hardware version | 213 | str r2, [r0] @ hardware version |
197 | .endm | 214 | .endm |
198 | 215 | ||
199 | 216 | ||
@@ -213,9 +230,9 @@ | |||
213 | * 1111 11 r/w r/w | 230 | * 1111 11 r/w r/w |
214 | */ | 231 | */ |
215 | .macro xscale_set_pte_ext_prologue | 232 | .macro xscale_set_pte_ext_prologue |
216 | str r1, [r0], #-2048 @ linux version | 233 | str r1, [r0] @ linux version |
217 | 234 | ||
218 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY | 235 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
219 | 236 | ||
220 | bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits | 237 | bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits |
221 | orr r2, r2, #PTE_TYPE_EXT @ extended page | 238 | orr r2, r2, #PTE_TYPE_EXT @ extended page |
@@ -223,7 +240,7 @@ | |||
223 | tst r3, #L_PTE_USER @ user? | 240 | tst r3, #L_PTE_USER @ user? |
224 | orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w | 241 | orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w |
225 | 242 | ||
226 | tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty? | 243 | tst r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty? |
227 | orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w | 244 | orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w |
228 | @ combined with user -> user r/w | 245 | @ combined with user -> user r/w |
229 | .endm | 246 | .endm |
@@ -232,7 +249,7 @@ | |||
232 | tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? | 249 | tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? |
233 | movne r2, #0 @ no -> fault | 250 | movne r2, #0 @ no -> fault |
234 | 251 | ||
235 | str r2, [r0] @ hardware version | 252 | str r2, [r0, #2048]! @ hardware version |
236 | mov ip, #0 | 253 | mov ip, #0 |
237 | mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line | 254 | mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line |
238 | mcr p15, 0, ip, c7, c10, 4 @ data write barrier | 255 | mcr p15, 0, ip, c7, c10, 4 @ data write barrier |