diff options
Diffstat (limited to 'arch/parisc/hpux/gate.S')
-rw-r--r-- | arch/parisc/hpux/gate.S | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S new file mode 100644 index 000000000000..2680a1c0fa77 --- /dev/null +++ b/arch/parisc/hpux/gate.S | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Linux/PARISC Project (http://www.parisc-linux.org/) | ||
4 | * | ||
5 | * System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai> | ||
6 | * Licensed under the GNU GPL. | ||
7 | * thanks to Philipp Rumpf, Mike Shaver and various others | ||
8 | * sorry about the wall, puffin.. | ||
9 | */ | ||
10 | |||
11 | #include <asm/assembly.h> | ||
12 | #include <asm/offsets.h> | ||
13 | #include <asm/unistd.h> | ||
14 | #include <asm/errno.h> | ||
15 | |||
16 | #ifdef __LP64__ | ||
17 | .level 2.0w | ||
18 | #else | ||
19 | .level 1.1 | ||
20 | #endif | ||
21 | .text | ||
22 | |||
23 | #ifdef __LP64__ | ||
24 | #define FRAME_SIZE 128 | ||
25 | #else | ||
26 | #define FRAME_SIZE 64 | ||
27 | #endif | ||
28 | .import hpux_call_table | ||
29 | .import hpux_syscall_exit,code | ||
30 | .export hpux_gateway_page | ||
31 | |||
32 | .align 4096 | ||
33 | hpux_gateway_page: | ||
34 | nop | ||
35 | #ifdef __LP64__ | ||
36 | #warning NEEDS WORK for 64-bit | ||
37 | #endif | ||
38 | ldw -64(%r30), %r29 ;! 8th argument | ||
39 | ldw -60(%r30), %r19 ;! 7th argument | ||
40 | ldw -56(%r30), %r20 ;! 6th argument | ||
41 | ldw -52(%r30), %r21 ;! 5th argument | ||
42 | gate .+8, %r0 /* become privileged */ | ||
43 | mtsp %r0,%sr4 /* get kernel space into sr4 */ | ||
44 | mtsp %r0,%sr5 /* get kernel space into sr5 */ | ||
45 | mtsp %r0,%sr6 /* get kernel space into sr6 */ | ||
46 | mfsp %sr7,%r1 /* save user sr7 */ | ||
47 | mtsp %r1,%sr3 /* and store it in sr3 */ | ||
48 | |||
49 | mtctl %r30,%cr28 | ||
50 | mfctl %cr30,%r1 | ||
51 | xor %r1,%r30,%r30 /* ye olde xor trick */ | ||
52 | xor %r1,%r30,%r1 | ||
53 | xor %r1,%r30,%r30 | ||
54 | ldo TASK_SZ_ALGN+FRAME_SIZE(%r30),%r30 /* set up kernel stack */ | ||
55 | |||
56 | /* N.B.: It is critical that we don't set sr7 to 0 until r30 | ||
57 | * contains a valid kernel stack pointer. It is also | ||
58 | * critical that we don't start using the kernel stack | ||
59 | * until after sr7 has been set to 0. | ||
60 | */ | ||
61 | |||
62 | mtsp %r0,%sr7 /* get kernel space into sr7 */ | ||
63 | STREG %r1,TASK_PT_GR30-TASK_SZ_ALGN-FRAME_SIZE(%r30) /* save usp */ | ||
64 | ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr in %r1 */ | ||
65 | |||
66 | /* Save some registers for sigcontext and potential task | ||
67 | switch (see entry.S for the details of which ones are | ||
68 | saved/restored). TASK_PT_PSW is zeroed so we can see whether | ||
69 | a process is on a syscall or not. For an interrupt the real | ||
70 | PSW value is stored. This is needed for gdb and sys_ptrace. */ | ||
71 | STREG %r0, TASK_PT_PSW(%r1) | ||
72 | STREG %r2, TASK_PT_GR2(%r1) /* preserve rp */ | ||
73 | STREG %r19, TASK_PT_GR19(%r1) /* 7th argument */ | ||
74 | STREG %r20, TASK_PT_GR20(%r1) /* 6th argument */ | ||
75 | STREG %r21, TASK_PT_GR21(%r1) /* 5th argument */ | ||
76 | STREG %r22, TASK_PT_GR22(%r1) /* syscall # */ | ||
77 | STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */ | ||
78 | STREG %r24, TASK_PT_GR24(%r1) /* 3rd argument */ | ||
79 | STREG %r25, TASK_PT_GR25(%r1) /* 2nd argument */ | ||
80 | STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */ | ||
81 | STREG %r27, TASK_PT_GR27(%r1) /* user dp */ | ||
82 | STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */ | ||
83 | STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */ | ||
84 | STREG %r29, TASK_PT_GR29(%r1) /* 8th argument */ | ||
85 | STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */ | ||
86 | |||
87 | ldo TASK_PT_FR0(%r1), %r27 /* save fpregs from the kernel */ | ||
88 | save_fp %r27 /* or potential task switch */ | ||
89 | |||
90 | mfctl %cr11, %r27 /* i.e. SAR */ | ||
91 | STREG %r27, TASK_PT_SAR(%r1) | ||
92 | |||
93 | loadgp | ||
94 | |||
95 | stw %r21, -52(%r30) ;! 5th argument | ||
96 | stw %r20, -56(%r30) ;! 6th argument | ||
97 | stw %r19, -60(%r30) ;! 7th argument | ||
98 | stw %r29, -64(%r30) ;! 8th argument | ||
99 | |||
100 | ldil L%hpux_call_table, %r21 | ||
101 | ldo R%hpux_call_table(%r21), %r21 | ||
102 | comiclr,>>= __NR_HPUX_syscalls, %r22, %r0 | ||
103 | b,n syscall_nosys | ||
104 | ldwx,s %r22(%r21), %r21 | ||
105 | ldil L%hpux_syscall_exit,%r2 | ||
106 | be 0(%sr7,%r21) | ||
107 | ldo R%hpux_syscall_exit(%r2),%r2 | ||
108 | |||
109 | syscall_nosys: | ||
110 | ldil L%hpux_syscall_exit,%r1 | ||
111 | be R%hpux_syscall_exit(%sr7,%r1) | ||
112 | ldo -ENOSYS(%r0),%r28 | ||
113 | |||
114 | .align 4096 | ||
115 | .export end_hpux_gateway_page | ||
116 | end_hpux_gateway_page: | ||