diff options
author | Grant Grundler <grundler@parisc-linux.org> | 2005-10-21 22:40:07 -0400 |
---|---|---|
committer | Kyle McMartin <kyle@parisc-linux.org> | 2005-10-21 22:40:07 -0400 |
commit | 896a375623c3643a3f189353e7d4828c48a7fdf8 (patch) | |
tree | bb79535f843110f9b2b199890157fcabb0504b43 | |
parent | b2c1fe81df7471de9f7e2918877ac04ec9cde35f (diff) |
[PARISC] Make sure use of RFI conforms to PA 2.0 and 1.1 arch docs
2.6.12-rc4-pa3 : first pass at making sure use of RFI conforms to
PA 2.0 arch pages F-4 and F-5, PA 1.1 Arch page 3-19 and 3-20.
The discussion revolves around all the rules for clearing PSW Q-bit.
The hard part is meeting all the rules for "relied upon translation".
.align directive is used to guarantee the critical sequence ends more than
8 instructions (32 bytes) from the end of page.
Signed-off-by: Grant Grundler <grundler@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
-rw-r--r-- | arch/parisc/kernel/entry.S | 51 | ||||
-rw-r--r-- | arch/parisc/kernel/head.S | 47 | ||||
-rw-r--r-- | arch/parisc/kernel/pacache.S | 105 | ||||
-rw-r--r-- | arch/parisc/kernel/real2.S | 18 | ||||
-rw-r--r-- | include/asm-parisc/assembly.h | 25 | ||||
-rw-r--r-- | include/asm-parisc/psw.h | 51 | ||||
-rw-r--r-- | include/asm-parisc/tlbflush.h | 9 |
7 files changed, 146 insertions, 160 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index be0f07f2fa58..65a82c2645a7 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -30,9 +30,9 @@ | |||
30 | * - save registers to kernel stack and handle in assembly or C */ | 30 | * - save registers to kernel stack and handle in assembly or C */ |
31 | 31 | ||
32 | 32 | ||
33 | #include <asm/psw.h> | ||
33 | #include <asm/assembly.h> /* for LDREG/STREG defines */ | 34 | #include <asm/assembly.h> /* for LDREG/STREG defines */ |
34 | #include <asm/pgtable.h> | 35 | #include <asm/pgtable.h> |
35 | #include <asm/psw.h> | ||
36 | #include <asm/signal.h> | 36 | #include <asm/signal.h> |
37 | #include <asm/unistd.h> | 37 | #include <asm/unistd.h> |
38 | #include <asm/thread_info.h> | 38 | #include <asm/thread_info.h> |
@@ -67,19 +67,22 @@ | |||
67 | 67 | ||
68 | /* Switch to virtual mapping, trashing only %r1 */ | 68 | /* Switch to virtual mapping, trashing only %r1 */ |
69 | .macro virt_map | 69 | .macro virt_map |
70 | rsm PSW_SM_Q,%r0 | 70 | /* pcxt_ssm_bug */ |
71 | tovirt_r1 %r29 | 71 | rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */ |
72 | mfsp %sr7, %r1 | ||
73 | or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */ | ||
74 | mtsp %r1, %sr3 | ||
75 | mtsp %r0, %sr4 | 72 | mtsp %r0, %sr4 |
76 | mtsp %r0, %sr5 | 73 | mtsp %r0, %sr5 |
74 | mfsp %sr7, %r1 | ||
75 | or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */ | ||
76 | mtsp %r1, %sr3 | ||
77 | tovirt_r1 %r29 | ||
78 | load32 KERNEL_PSW, %r1 | ||
79 | |||
80 | rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */ | ||
77 | mtsp %r0, %sr6 | 81 | mtsp %r0, %sr6 |
78 | mtsp %r0, %sr7 | 82 | mtsp %r0, %sr7 |
79 | load32 KERNEL_PSW, %r1 | ||
80 | mtctl %r1, %cr22 | ||
81 | mtctl %r0, %cr17 /* Clear IIASQ tail */ | 83 | mtctl %r0, %cr17 /* Clear IIASQ tail */ |
82 | mtctl %r0, %cr17 /* Clear IIASQ head */ | 84 | mtctl %r0, %cr17 /* Clear IIASQ head */ |
85 | mtctl %r1, %ipsw | ||
83 | load32 4f, %r1 | 86 | load32 4f, %r1 |
84 | mtctl %r1, %cr18 /* Set IIAOQ tail */ | 87 | mtctl %r1, %cr18 /* Set IIAOQ tail */ |
85 | ldo 4(%r1), %r1 | 88 | ldo 4(%r1), %r1 |
@@ -888,9 +891,6 @@ _switch_to_ret: | |||
888 | * this way, then we will need to copy %sr3 in to PT_SR[3..7], and | 891 | * this way, then we will need to copy %sr3 in to PT_SR[3..7], and |
889 | * adjust IASQ[0..1]. | 892 | * adjust IASQ[0..1]. |
890 | * | 893 | * |
891 | * Note that the following code uses a "relied upon translation". | ||
892 | * See the parisc ACD for details. The ssm is necessary due to a | ||
893 | * PCXT bug. | ||
894 | */ | 894 | */ |
895 | 895 | ||
896 | .align 4096 | 896 | .align 4096 |
@@ -985,24 +985,19 @@ intr_restore: | |||
985 | rest_fp %r1 | 985 | rest_fp %r1 |
986 | rest_general %r29 | 986 | rest_general %r29 |
987 | 987 | ||
988 | /* Create a "relied upon translation" PA 2.0 Arch. F-5 */ | 988 | /* inverse of virt_map */ |
989 | ssm 0,%r0 | 989 | pcxt_ssm_bug |
990 | nop | 990 | rsm PSW_SM_QUIET,%r0 /* prepare for rfi */ |
991 | nop | ||
992 | nop | ||
993 | nop | ||
994 | nop | ||
995 | nop | ||
996 | nop | ||
997 | tophys_r1 %r29 | 991 | tophys_r1 %r29 |
998 | rsm (PSW_SM_Q|PSW_SM_P|PSW_SM_D|PSW_SM_I),%r0 | ||
999 | 992 | ||
1000 | /* Restore space id's and special cr's from PT_REGS | 993 | /* Restore space id's and special cr's from PT_REGS |
1001 | * structure pointed to by r29 */ | 994 | * structure pointed to by r29 |
995 | */ | ||
1002 | rest_specials %r29 | 996 | rest_specials %r29 |
1003 | 997 | ||
1004 | /* Important: Note that rest_stack restores r29 | 998 | /* IMPORTANT: rest_stack restores r29 last (we are using it)! |
1005 | * last (we are using it)! It also restores r1 and r30. */ | 999 | * It also restores r1 and r30. |
1000 | */ | ||
1006 | rest_stack | 1001 | rest_stack |
1007 | 1002 | ||
1008 | rfi | 1003 | rfi |
@@ -1153,15 +1148,17 @@ intr_save: | |||
1153 | 1148 | ||
1154 | CMPIB=,n 6,%r26,skip_save_ior | 1149 | CMPIB=,n 6,%r26,skip_save_ior |
1155 | 1150 | ||
1156 | /* save_specials left ipsw value in r8 for us to test */ | ||
1157 | 1151 | ||
1158 | mfctl %cr20, %r16 /* isr */ | 1152 | mfctl %cr20, %r16 /* isr */ |
1153 | nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */ | ||
1159 | mfctl %cr21, %r17 /* ior */ | 1154 | mfctl %cr21, %r17 /* ior */ |
1160 | 1155 | ||
1156 | |||
1161 | #ifdef __LP64__ | 1157 | #ifdef __LP64__ |
1162 | /* | 1158 | /* |
1163 | * If the interrupted code was running with W bit off (32 bit), | 1159 | * If the interrupted code was running with W bit off (32 bit), |
1164 | * clear the b bits (bits 0 & 1) in the ior. | 1160 | * clear the b bits (bits 0 & 1) in the ior. |
1161 | * save_specials left ipsw value in r8 for us to test. | ||
1165 | */ | 1162 | */ |
1166 | extrd,u,*<> %r8,PSW_W_BIT,1,%r0 | 1163 | extrd,u,*<> %r8,PSW_W_BIT,1,%r0 |
1167 | depdi 0,1,2,%r17 | 1164 | depdi 0,1,2,%r17 |
@@ -1487,10 +1484,10 @@ nadtlb_emulate: | |||
1487 | add,l %r1,%r24,%r1 /* doesn't affect c/b bits */ | 1484 | add,l %r1,%r24,%r1 /* doesn't affect c/b bits */ |
1488 | 1485 | ||
1489 | nadtlb_nullify: | 1486 | nadtlb_nullify: |
1490 | mfctl %cr22,%r8 /* Get ipsw */ | 1487 | mfctl %ipsw,%r8 |
1491 | ldil L%PSW_N,%r9 | 1488 | ldil L%PSW_N,%r9 |
1492 | or %r8,%r9,%r8 /* Set PSW_N */ | 1489 | or %r8,%r9,%r8 /* Set PSW_N */ |
1493 | mtctl %r8,%cr22 | 1490 | mtctl %r8,%ipsw |
1494 | 1491 | ||
1495 | rfir | 1492 | rfir |
1496 | nop | 1493 | nop |
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 28405edf8448..2b8738576ec2 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S | |||
@@ -224,8 +224,6 @@ stext_pdc_ret: | |||
224 | mtctl %r0,%cr12 | 224 | mtctl %r0,%cr12 |
225 | mtctl %r0,%cr13 | 225 | mtctl %r0,%cr13 |
226 | 226 | ||
227 | /* Prepare to RFI! Man all the cannons! */ | ||
228 | |||
229 | /* Initialize the global data pointer */ | 227 | /* Initialize the global data pointer */ |
230 | loadgp | 228 | loadgp |
231 | 229 | ||
@@ -254,46 +252,16 @@ $is_pa20: | |||
254 | $install_iva: | 252 | $install_iva: |
255 | mtctl %r10,%cr14 | 253 | mtctl %r10,%cr14 |
256 | 254 | ||
257 | #ifdef __LP64__ | 255 | b aligned_rfi /* Prepare to RFI! Man all the cannons! */ |
258 | b aligned_rfi | ||
259 | nop | 256 | nop |
260 | 257 | ||
261 | .align 256 | 258 | .align 128 |
262 | aligned_rfi: | 259 | aligned_rfi: |
263 | ssm 0,0 | 260 | pcxt_ssm_bug |
264 | nop /* 1 */ | ||
265 | nop /* 2 */ | ||
266 | nop /* 3 */ | ||
267 | nop /* 4 */ | ||
268 | nop /* 5 */ | ||
269 | nop /* 6 */ | ||
270 | nop /* 7 */ | ||
271 | nop /* 8 */ | ||
272 | #endif | ||
273 | |||
274 | #ifdef __LP64__ /* move to psw.h? */ | ||
275 | #define PSW_BITS PSW_Q+PSW_I+PSW_D+PSW_P+PSW_R | ||
276 | #else | ||
277 | #define PSW_BITS PSW_SM_Q | ||
278 | #endif | ||
279 | |||
280 | $rfi: | ||
281 | /* turn off troublesome PSW bits */ | ||
282 | rsm PSW_BITS,%r0 | ||
283 | 261 | ||
284 | /* kernel PSW: | 262 | rsm PSW_SM_QUIET,%r0 /* off troublesome PSW bits */ |
285 | * - no interruptions except HPMC and TOC (which are handled by PDC) | 263 | /* Don't need NOPs, have 8 compliant insn before rfi */ |
286 | * - Q bit set (IODC / PDC interruptions) | ||
287 | * - big-endian | ||
288 | * - virtually mapped | ||
289 | */ | ||
290 | load32 KERNEL_PSW,%r10 | ||
291 | mtctl %r10,%ipsw | ||
292 | 264 | ||
293 | /* Set the space pointers for the post-RFI world | ||
294 | ** Clear the two-level IIA Space Queue, effectively setting | ||
295 | ** Kernel space. | ||
296 | */ | ||
297 | mtctl %r0,%cr17 /* Clear IIASQ tail */ | 265 | mtctl %r0,%cr17 /* Clear IIASQ tail */ |
298 | mtctl %r0,%cr17 /* Clear IIASQ head */ | 266 | mtctl %r0,%cr17 /* Clear IIASQ head */ |
299 | 267 | ||
@@ -301,8 +269,11 @@ $rfi: | |||
301 | mtctl %r11,%cr18 /* IIAOQ head */ | 269 | mtctl %r11,%cr18 /* IIAOQ head */ |
302 | ldo 4(%r11),%r11 | 270 | ldo 4(%r11),%r11 |
303 | mtctl %r11,%cr18 /* IIAOQ tail */ | 271 | mtctl %r11,%cr18 /* IIAOQ tail */ |
272 | |||
273 | load32 KERNEL_PSW,%r10 | ||
274 | mtctl %r10,%ipsw | ||
304 | 275 | ||
305 | /* Jump to hyperspace */ | 276 | /* Jump through hyperspace to Virt Mode */ |
306 | rfi | 277 | rfi |
307 | nop | 278 | nop |
308 | 279 | ||
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 77e03bc0f935..71ade44c4618 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S | |||
@@ -40,8 +40,8 @@ | |||
40 | .level 2.0 | 40 | .level 2.0 |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #include <asm/assembly.h> | ||
44 | #include <asm/psw.h> | 43 | #include <asm/psw.h> |
44 | #include <asm/assembly.h> | ||
45 | #include <asm/pgtable.h> | 45 | #include <asm/pgtable.h> |
46 | #include <asm/cache.h> | 46 | #include <asm/cache.h> |
47 | 47 | ||
@@ -62,32 +62,23 @@ flush_tlb_all_local: | |||
62 | * to happen in real mode with all interruptions disabled. | 62 | * to happen in real mode with all interruptions disabled. |
63 | */ | 63 | */ |
64 | 64 | ||
65 | /* | 65 | /* pcxt_ssm_bug - relied upon translation! PA 2.0 Arch. F-4 and F-5 */ |
66 | * Once again, we do the rfi dance ... some day we need examine | 66 | rsm PSW_SM_I, %r19 /* save I-bit state */ |
67 | * all of our uses of this type of code and see what can be | 67 | load32 PA(1f), %r1 |
68 | * consolidated. | ||
69 | */ | ||
70 | |||
71 | rsm PSW_SM_I, %r19 /* relied upon translation! PA 2.0 Arch. F-5 */ | ||
72 | nop | 68 | nop |
73 | nop | 69 | nop |
74 | nop | 70 | nop |
75 | nop | 71 | nop |
76 | nop | 72 | nop |
77 | nop | 73 | |
78 | nop | 74 | rsm PSW_SM_Q, %r0 /* prep to load iia queue */ |
79 | |||
80 | rsm PSW_SM_Q, %r0 /* Turn off Q bit to load iia queue */ | ||
81 | ldil L%REAL_MODE_PSW, %r1 | ||
82 | ldo R%REAL_MODE_PSW(%r1), %r1 | ||
83 | mtctl %r1, %cr22 | ||
84 | mtctl %r0, %cr17 /* Clear IIASQ tail */ | 75 | mtctl %r0, %cr17 /* Clear IIASQ tail */ |
85 | mtctl %r0, %cr17 /* Clear IIASQ head */ | 76 | mtctl %r0, %cr17 /* Clear IIASQ head */ |
86 | ldil L%PA(1f), %r1 | ||
87 | ldo R%PA(1f)(%r1), %r1 | ||
88 | mtctl %r1, %cr18 /* IIAOQ head */ | 77 | mtctl %r1, %cr18 /* IIAOQ head */ |
89 | ldo 4(%r1), %r1 | 78 | ldo 4(%r1), %r1 |
90 | mtctl %r1, %cr18 /* IIAOQ tail */ | 79 | mtctl %r1, %cr18 /* IIAOQ tail */ |
80 | load32 REAL_MODE_PSW, %r1 | ||
81 | mtctl %r1, %ipsw | ||
91 | rfi | 82 | rfi |
92 | nop | 83 | nop |
93 | 84 | ||
@@ -178,29 +169,36 @@ fdtonemiddle: /* Loop if LOOP = 1 */ | |||
178 | ADDIB> -1, %r22, fdtoneloop /* Outer loop count decr */ | 169 | ADDIB> -1, %r22, fdtoneloop /* Outer loop count decr */ |
179 | add %r21, %r20, %r20 /* increment space */ | 170 | add %r21, %r20, %r20 /* increment space */ |
180 | 171 | ||
181 | fdtdone: | ||
182 | 172 | ||
183 | /* Switch back to virtual mode */ | 173 | fdtdone: |
174 | /* | ||
175 | * Switch back to virtual mode | ||
176 | */ | ||
177 | /* pcxt_ssm_bug */ | ||
178 | rsm PSW_SM_I, %r0 | ||
179 | load32 2f, %r1 | ||
180 | nop | ||
181 | nop | ||
182 | nop | ||
183 | nop | ||
184 | nop | ||
184 | 185 | ||
185 | rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */ | 186 | rsm PSW_SM_Q, %r0 /* prep to load iia queue */ |
186 | ldil L%KERNEL_PSW, %r1 | ||
187 | ldo R%KERNEL_PSW(%r1), %r1 | ||
188 | or %r1, %r19, %r1 /* Set I bit if set on entry */ | ||
189 | mtctl %r1, %cr22 | ||
190 | mtctl %r0, %cr17 /* Clear IIASQ tail */ | 187 | mtctl %r0, %cr17 /* Clear IIASQ tail */ |
191 | mtctl %r0, %cr17 /* Clear IIASQ head */ | 188 | mtctl %r0, %cr17 /* Clear IIASQ head */ |
192 | ldil L%(2f), %r1 | ||
193 | ldo R%(2f)(%r1), %r1 | ||
194 | mtctl %r1, %cr18 /* IIAOQ head */ | 189 | mtctl %r1, %cr18 /* IIAOQ head */ |
195 | ldo 4(%r1), %r1 | 190 | ldo 4(%r1), %r1 |
196 | mtctl %r1, %cr18 /* IIAOQ tail */ | 191 | mtctl %r1, %cr18 /* IIAOQ tail */ |
192 | load32 KERNEL_PSW, %r1 | ||
193 | or %r1, %r19, %r1 /* I-bit to state on entry */ | ||
194 | mtctl %r1, %ipsw /* restore I-bit (entire PSW) */ | ||
197 | rfi | 195 | rfi |
198 | nop | 196 | nop |
199 | 197 | ||
200 | 2: bv %r0(%r2) | 198 | 2: bv %r0(%r2) |
201 | nop | 199 | nop |
202 | .exit | ||
203 | 200 | ||
201 | .exit | ||
204 | .procend | 202 | .procend |
205 | 203 | ||
206 | .export flush_instruction_cache_local,code | 204 | .export flush_instruction_cache_local,code |
@@ -238,7 +236,7 @@ fioneloop: /* Loop if LOOP = 1 */ | |||
238 | 236 | ||
239 | fisync: | 237 | fisync: |
240 | sync | 238 | sync |
241 | mtsm %r22 | 239 | mtsm %r22 /* restore I-bit */ |
242 | bv %r0(%r2) | 240 | bv %r0(%r2) |
243 | nop | 241 | nop |
244 | .exit | 242 | .exit |
@@ -281,7 +279,7 @@ fdoneloop: /* Loop if LOOP = 1 */ | |||
281 | fdsync: | 279 | fdsync: |
282 | syncdma | 280 | syncdma |
283 | sync | 281 | sync |
284 | mtsm %r22 | 282 | mtsm %r22 /* restore I-bit */ |
285 | bv %r0(%r2) | 283 | bv %r0(%r2) |
286 | nop | 284 | nop |
287 | .exit | 285 | .exit |
@@ -988,11 +986,12 @@ flush_kernel_icache_range_asm: | |||
988 | bv %r0(%r2) | 986 | bv %r0(%r2) |
989 | nop | 987 | nop |
990 | .exit | 988 | .exit |
991 | |||
992 | .procend | 989 | .procend |
993 | 990 | ||
994 | .align 128 | 991 | /* align should cover use of rfi in disable_sr_hashing_asm and |
995 | 992 | * srdis_done. | |
993 | */ | ||
994 | .align 256 | ||
996 | .export disable_sr_hashing_asm,code | 995 | .export disable_sr_hashing_asm,code |
997 | 996 | ||
998 | disable_sr_hashing_asm: | 997 | disable_sr_hashing_asm: |
@@ -1000,28 +999,26 @@ disable_sr_hashing_asm: | |||
1000 | .callinfo NO_CALLS | 999 | .callinfo NO_CALLS |
1001 | .entry | 1000 | .entry |
1002 | 1001 | ||
1003 | /* Switch to real mode */ | 1002 | /* |
1004 | 1003 | * Switch to real mode | |
1005 | ssm 0, %r0 /* relied upon translation! */ | 1004 | */ |
1006 | nop | 1005 | /* pcxt_ssm_bug */ |
1007 | nop | 1006 | rsm PSW_SM_I, %r0 |
1007 | load32 PA(1f), %r1 | ||
1008 | nop | 1008 | nop |
1009 | nop | 1009 | nop |
1010 | nop | 1010 | nop |
1011 | nop | 1011 | nop |
1012 | nop | 1012 | nop |
1013 | 1013 | ||
1014 | rsm (PSW_SM_Q|PSW_SM_I), %r0 /* disable Q&I to load the iia queue */ | 1014 | rsm PSW_SM_Q, %r0 /* prep to load iia queue */ |
1015 | ldil L%REAL_MODE_PSW, %r1 | ||
1016 | ldo R%REAL_MODE_PSW(%r1), %r1 | ||
1017 | mtctl %r1, %cr22 | ||
1018 | mtctl %r0, %cr17 /* Clear IIASQ tail */ | 1015 | mtctl %r0, %cr17 /* Clear IIASQ tail */ |
1019 | mtctl %r0, %cr17 /* Clear IIASQ head */ | 1016 | mtctl %r0, %cr17 /* Clear IIASQ head */ |
1020 | ldil L%PA(1f), %r1 | ||
1021 | ldo R%PA(1f)(%r1), %r1 | ||
1022 | mtctl %r1, %cr18 /* IIAOQ head */ | 1017 | mtctl %r1, %cr18 /* IIAOQ head */ |
1023 | ldo 4(%r1), %r1 | 1018 | ldo 4(%r1), %r1 |
1024 | mtctl %r1, %cr18 /* IIAOQ tail */ | 1019 | mtctl %r1, %cr18 /* IIAOQ tail */ |
1020 | load32 REAL_MODE_PSW, %r1 | ||
1021 | mtctl %r1, %ipsw | ||
1025 | rfi | 1022 | rfi |
1026 | nop | 1023 | nop |
1027 | 1024 | ||
@@ -1053,27 +1050,31 @@ srdis_pcxl: | |||
1053 | 1050 | ||
1054 | srdis_pa20: | 1051 | srdis_pa20: |
1055 | 1052 | ||
1056 | /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+ */ | 1053 | /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */ |
1057 | 1054 | ||
1058 | .word 0x144008bc /* mfdiag %dr2, %r28 */ | 1055 | .word 0x144008bc /* mfdiag %dr2, %r28 */ |
1059 | depdi 0, 54,1, %r28 /* clear DIAG_SPHASH_ENAB (bit 54) */ | 1056 | depdi 0, 54,1, %r28 /* clear DIAG_SPHASH_ENAB (bit 54) */ |
1060 | .word 0x145c1840 /* mtdiag %r28, %dr2 */ | 1057 | .word 0x145c1840 /* mtdiag %r28, %dr2 */ |
1061 | 1058 | ||
1062 | srdis_done: | ||
1063 | 1059 | ||
1060 | srdis_done: | ||
1064 | /* Switch back to virtual mode */ | 1061 | /* Switch back to virtual mode */ |
1062 | rsm PSW_SM_I, %r0 /* prep to load iia queue */ | ||
1063 | load32 2f, %r1 | ||
1064 | nop | ||
1065 | nop | ||
1066 | nop | ||
1067 | nop | ||
1068 | nop | ||
1065 | 1069 | ||
1066 | rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */ | 1070 | rsm PSW_SM_Q, %r0 /* prep to load iia queue */ |
1067 | ldil L%KERNEL_PSW, %r1 | ||
1068 | ldo R%KERNEL_PSW(%r1), %r1 | ||
1069 | mtctl %r1, %cr22 | ||
1070 | mtctl %r0, %cr17 /* Clear IIASQ tail */ | 1071 | mtctl %r0, %cr17 /* Clear IIASQ tail */ |
1071 | mtctl %r0, %cr17 /* Clear IIASQ head */ | 1072 | mtctl %r0, %cr17 /* Clear IIASQ head */ |
1072 | ldil L%(2f), %r1 | ||
1073 | ldo R%(2f)(%r1), %r1 | ||
1074 | mtctl %r1, %cr18 /* IIAOQ head */ | 1073 | mtctl %r1, %cr18 /* IIAOQ head */ |
1075 | ldo 4(%r1), %r1 | 1074 | ldo 4(%r1), %r1 |
1076 | mtctl %r1, %cr18 /* IIAOQ tail */ | 1075 | mtctl %r1, %cr18 /* IIAOQ tail */ |
1076 | load32 KERNEL_PSW, %r1 | ||
1077 | mtctl %r1, %ipsw | ||
1077 | rfi | 1078 | rfi |
1078 | nop | 1079 | nop |
1079 | 1080 | ||
diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 8dd5defb7316..2310fc1b06a9 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S | |||
@@ -7,8 +7,8 @@ | |||
7 | * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com) | 7 | * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com) |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | #include <asm/assembly.h> | ||
11 | #include <asm/psw.h> | 10 | #include <asm/psw.h> |
11 | #include <asm/assembly.h> | ||
12 | 12 | ||
13 | .section .bss | 13 | .section .bss |
14 | .export real_stack | 14 | .export real_stack |
@@ -147,20 +147,17 @@ restore_control_regs: | |||
147 | .text | 147 | .text |
148 | rfi_virt2real: | 148 | rfi_virt2real: |
149 | /* switch to real mode... */ | 149 | /* switch to real mode... */ |
150 | ssm 0,0 /* See "relied upon translation" */ | 150 | rsm PSW_SM_I,%r0 |
151 | nop /* PA 2.0 Arch. F-5 */ | 151 | load32 PA(rfi_v2r_1), %r1 |
152 | nop | ||
153 | nop | ||
154 | nop | 152 | nop |
155 | nop | 153 | nop |
156 | nop | 154 | nop |
157 | nop | 155 | nop |
158 | nop | 156 | nop |
159 | 157 | ||
160 | rsm (PSW_SM_Q|PSW_SM_I),%r0 /* disable Q & I bits to load iia queue */ | 158 | rsm PSW_SM_Q,%r0 /* disable Q & I bits to load iia queue */ |
161 | mtctl %r0, %cr17 /* Clear IIASQ tail */ | 159 | mtctl %r0, %cr17 /* Clear IIASQ tail */ |
162 | mtctl %r0, %cr17 /* Clear IIASQ head */ | 160 | mtctl %r0, %cr17 /* Clear IIASQ head */ |
163 | load32 PA(rfi_v2r_1), %r1 | ||
164 | mtctl %r1, %cr18 /* IIAOQ head */ | 161 | mtctl %r1, %cr18 /* IIAOQ head */ |
165 | ldo 4(%r1), %r1 | 162 | ldo 4(%r1), %r1 |
166 | mtctl %r1, %cr18 /* IIAOQ tail */ | 163 | mtctl %r1, %cr18 /* IIAOQ tail */ |
@@ -184,10 +181,8 @@ rfi_v2r_1: | |||
184 | .text | 181 | .text |
185 | .align 128 | 182 | .align 128 |
186 | rfi_real2virt: | 183 | rfi_real2virt: |
187 | ssm 0,0 /* See "relied upon translation" */ | 184 | rsm PSW_SM_I,%r0 |
188 | nop /* PA 2.0 Arch. F-5 */ | 185 | load32 (rfi_r2v_1), %r1 |
189 | nop | ||
190 | nop | ||
191 | nop | 186 | nop |
192 | nop | 187 | nop |
193 | nop | 188 | nop |
@@ -197,7 +192,6 @@ rfi_real2virt: | |||
197 | rsm PSW_SM_Q,%r0 /* disable Q bit to load iia queue */ | 192 | rsm PSW_SM_Q,%r0 /* disable Q bit to load iia queue */ |
198 | mtctl %r0, %cr17 /* Clear IIASQ tail */ | 193 | mtctl %r0, %cr17 /* Clear IIASQ tail */ |
199 | mtctl %r0, %cr17 /* Clear IIASQ head */ | 194 | mtctl %r0, %cr17 /* Clear IIASQ head */ |
200 | load32 (rfi_r2v_1), %r1 | ||
201 | mtctl %r1, %cr18 /* IIAOQ head */ | 195 | mtctl %r1, %cr18 /* IIAOQ head */ |
202 | ldo 4(%r1), %r1 | 196 | ldo 4(%r1), %r1 |
203 | mtctl %r1, %cr18 /* IIAOQ tail */ | 197 | mtctl %r1, %cr18 /* IIAOQ tail */ |
diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index 30b023411fef..b24a99e3ef9c 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h | |||
@@ -450,5 +450,30 @@ | |||
450 | REST_CR (%cr22, PT_PSW (\regs)) | 450 | REST_CR (%cr22, PT_PSW (\regs)) |
451 | .endm | 451 | .endm |
452 | 452 | ||
453 | |||
454 | /* First step to create a "relied upon translation" | ||
455 | * See PA 2.0 Arch. page F-4 and F-5. | ||
456 | * | ||
457 | * The ssm was originally necessary due to a "PCxT bug". | ||
458 | * But someone decided it needed to be added to the architecture | ||
459 | * and this "feature" went into rev3 of PA-RISC 1.1 Arch Manual. | ||
460 | * It's been carried forward into PA 2.0 Arch as well. :^( | ||
461 | * | ||
462 | * "ssm 0,%r0" is a NOP with side effects (prefetch barrier). | ||
463 | * rsm/ssm prevents the ifetch unit from speculatively fetching | ||
464 | * instructions past this line in the code stream. | ||
465 | * PA 2.0 processor will single step all insn in the same QUAD (4 insn). | ||
466 | */ | ||
467 | .macro pcxt_ssm_bug | ||
468 | rsm PSW_SM_I,%r0 | ||
469 | nop /* 1 */ | ||
470 | nop /* 2 */ | ||
471 | nop /* 3 */ | ||
472 | nop /* 4 */ | ||
473 | nop /* 5 */ | ||
474 | nop /* 6 */ | ||
475 | nop /* 7 */ | ||
476 | .endm | ||
477 | |||
453 | #endif /* __ASSEMBLY__ */ | 478 | #endif /* __ASSEMBLY__ */ |
454 | #endif | 479 | #endif |
diff --git a/include/asm-parisc/psw.h b/include/asm-parisc/psw.h index 51323029f377..4334d6ca2add 100644 --- a/include/asm-parisc/psw.h +++ b/include/asm-parisc/psw.h | |||
@@ -1,4 +1,7 @@ | |||
1 | #ifndef _PARISC_PSW_H | 1 | #ifndef _PARISC_PSW_H |
2 | |||
3 | #include <linux/config.h> | ||
4 | |||
2 | #define PSW_I 0x00000001 | 5 | #define PSW_I 0x00000001 |
3 | #define PSW_D 0x00000002 | 6 | #define PSW_D 0x00000002 |
4 | #define PSW_P 0x00000004 | 7 | #define PSW_P 0x00000004 |
@@ -9,6 +12,16 @@ | |||
9 | #define PSW_G 0x00000040 /* PA1.x only */ | 12 | #define PSW_G 0x00000040 /* PA1.x only */ |
10 | #define PSW_O 0x00000080 /* PA2.0 only */ | 13 | #define PSW_O 0x00000080 /* PA2.0 only */ |
11 | 14 | ||
15 | /* ssm/rsm instructions number PSW_W and PSW_E differently */ | ||
16 | #define PSW_SM_I PSW_I /* Enable External Interrupts */ | ||
17 | #define PSW_SM_D PSW_D | ||
18 | #define PSW_SM_P PSW_P | ||
19 | #define PSW_SM_Q PSW_Q /* Enable Interrupt State Collection */ | ||
20 | #define PSW_SM_R PSW_R /* Enable Recover Counter Trap */ | ||
21 | #define PSW_SM_W 0x200 /* PA2.0 only : Enable Wide Mode */ | ||
22 | |||
23 | #define PSW_SM_QUIET PSW_SM_R+PSW_SM_Q+PSW_SM_P+PSW_SM_D+PSW_SM_I | ||
24 | |||
12 | #define PSW_CB 0x0000ff00 | 25 | #define PSW_CB 0x0000ff00 |
13 | 26 | ||
14 | #define PSW_M 0x00010000 | 27 | #define PSW_M 0x00010000 |
@@ -30,33 +43,21 @@ | |||
30 | #define PSW_Z 0x40000000 /* PA1.x only */ | 43 | #define PSW_Z 0x40000000 /* PA1.x only */ |
31 | #define PSW_Y 0x80000000 /* PA1.x only */ | 44 | #define PSW_Y 0x80000000 /* PA1.x only */ |
32 | 45 | ||
33 | #ifdef __LP64__ | 46 | #ifdef CONFIG_64BIT |
34 | #define PSW_HI_CB 0x000000ff /* PA2.0 only */ | 47 | # define PSW_HI_CB 0x000000ff /* PA2.0 only */ |
35 | #endif | 48 | #endif |
36 | 49 | ||
37 | /* PSW bits to be used with ssm/rsm */ | 50 | #ifdef CONFIG_64BIT |
38 | #define PSW_SM_I 0x1 | 51 | # define USER_PSW_HI_MASK PSW_HI_CB |
39 | #define PSW_SM_D 0x2 | 52 | # define WIDE_PSW PSW_W |
40 | #define PSW_SM_P 0x4 | 53 | #else |
41 | #define PSW_SM_Q 0x8 | 54 | # define WIDE_PSW 0 |
42 | #define PSW_SM_R 0x10 | ||
43 | #define PSW_SM_F 0x20 | ||
44 | #define PSW_SM_G 0x40 | ||
45 | #define PSW_SM_O 0x80 | ||
46 | #define PSW_SM_E 0x100 | ||
47 | #define PSW_SM_W 0x200 | ||
48 | |||
49 | #ifdef __LP64__ | ||
50 | # define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) | ||
51 | # define KERNEL_PSW (PSW_W | PSW_C | PSW_Q | PSW_P | PSW_D) | ||
52 | # define REAL_MODE_PSW (PSW_W | PSW_Q) | ||
53 | # define USER_PSW_MASK (PSW_W | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) | ||
54 | # define USER_PSW_HI_MASK (PSW_HI_CB) | ||
55 | #else | ||
56 | # define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) | ||
57 | # define KERNEL_PSW (PSW_C | PSW_Q | PSW_P | PSW_D) | ||
58 | # define REAL_MODE_PSW (PSW_Q) | ||
59 | # define USER_PSW_MASK (PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) | ||
60 | #endif | 55 | #endif |
61 | 56 | ||
57 | /* Used when setting up for rfi */ | ||
58 | #define KERNEL_PSW (WIDE_PSW | PSW_C | PSW_Q | PSW_P | PSW_D) | ||
59 | #define REAL_MODE_PSW (WIDE_PSW | PSW_Q) | ||
60 | #define USER_PSW_MASK (WIDE_PSW | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) | ||
61 | #define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) | ||
62 | |||
62 | #endif | 63 | #endif |
diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h index eb27b78930e8..efbb2d8625b1 100644 --- a/include/asm-parisc/tlbflush.h +++ b/include/asm-parisc/tlbflush.h | |||
@@ -64,29 +64,26 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, | |||
64 | { | 64 | { |
65 | unsigned long npages; | 65 | unsigned long npages; |
66 | 66 | ||
67 | |||
68 | npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 67 | npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
69 | if (npages >= 512) /* XXX arbitrary, should be tuned */ | 68 | if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */ |
70 | flush_tlb_all(); | 69 | flush_tlb_all(); |
71 | else { | 70 | else { |
72 | 71 | ||
73 | mtsp(vma->vm_mm->context,1); | 72 | mtsp(vma->vm_mm->context,1); |
73 | purge_tlb_start(); | ||
74 | if (split_tlb) { | 74 | if (split_tlb) { |
75 | purge_tlb_start(); | ||
76 | while (npages--) { | 75 | while (npages--) { |
77 | pdtlb(start); | 76 | pdtlb(start); |
78 | pitlb(start); | 77 | pitlb(start); |
79 | start += PAGE_SIZE; | 78 | start += PAGE_SIZE; |
80 | } | 79 | } |
81 | purge_tlb_end(); | ||
82 | } else { | 80 | } else { |
83 | purge_tlb_start(); | ||
84 | while (npages--) { | 81 | while (npages--) { |
85 | pdtlb(start); | 82 | pdtlb(start); |
86 | start += PAGE_SIZE; | 83 | start += PAGE_SIZE; |
87 | } | 84 | } |
88 | purge_tlb_end(); | ||
89 | } | 85 | } |
86 | purge_tlb_end(); | ||
90 | } | 87 | } |
91 | } | 88 | } |
92 | 89 | ||