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 /arch/parisc/kernel/entry.S | |
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>
Diffstat (limited to 'arch/parisc/kernel/entry.S')
-rw-r--r-- | arch/parisc/kernel/entry.S | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index be0f07f2fa5..65a82c2645a 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 |