Commit | Line | Data |
---|---|---|
1da177e4 LT |
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> | |
0013a854 | 12 | #include <asm/asm-offsets.h> |
1da177e4 LT |
13 | #include <asm/unistd.h> |
14 | #include <asm/errno.h> | |
79793455 | 15 | #include <linux/linkage.h> |
1da177e4 | 16 | |
79793455 | 17 | .level LEVEL |
dfcf753b | 18 | .text |
1da177e4 | 19 | |
1da177e4 LT |
20 | .import hpux_call_table |
21 | .import hpux_syscall_exit,code | |
1da177e4 | 22 | |
873d50e2 | 23 | .align PAGE_SIZE |
79793455 | 24 | ENTRY(hpux_gateway_page) |
1da177e4 | 25 | nop |
79793455 | 26 | #ifdef CONFIG_64BIT |
1da177e4 LT |
27 | #warning NEEDS WORK for 64-bit |
28 | #endif | |
29 | ldw -64(%r30), %r29 ;! 8th argument | |
30 | ldw -60(%r30), %r19 ;! 7th argument | |
31 | ldw -56(%r30), %r20 ;! 6th argument | |
32 | ldw -52(%r30), %r21 ;! 5th argument | |
33 | gate .+8, %r0 /* become privileged */ | |
34 | mtsp %r0,%sr4 /* get kernel space into sr4 */ | |
35 | mtsp %r0,%sr5 /* get kernel space into sr5 */ | |
36 | mtsp %r0,%sr6 /* get kernel space into sr6 */ | |
37 | mfsp %sr7,%r1 /* save user sr7 */ | |
38 | mtsp %r1,%sr3 /* and store it in sr3 */ | |
39 | ||
40 | mtctl %r30,%cr28 | |
41 | mfctl %cr30,%r1 | |
42 | xor %r1,%r30,%r30 /* ye olde xor trick */ | |
43 | xor %r1,%r30,%r1 | |
44 | xor %r1,%r30,%r30 | |
45 | ldo TASK_SZ_ALGN+FRAME_SIZE(%r30),%r30 /* set up kernel stack */ | |
46 | ||
47 | /* N.B.: It is critical that we don't set sr7 to 0 until r30 | |
48 | * contains a valid kernel stack pointer. It is also | |
49 | * critical that we don't start using the kernel stack | |
50 | * until after sr7 has been set to 0. | |
51 | */ | |
52 | ||
53 | mtsp %r0,%sr7 /* get kernel space into sr7 */ | |
54 | STREG %r1,TASK_PT_GR30-TASK_SZ_ALGN-FRAME_SIZE(%r30) /* save usp */ | |
55 | ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr in %r1 */ | |
56 | ||
57 | /* Save some registers for sigcontext and potential task | |
58 | switch (see entry.S for the details of which ones are | |
59 | saved/restored). TASK_PT_PSW is zeroed so we can see whether | |
60 | a process is on a syscall or not. For an interrupt the real | |
61 | PSW value is stored. This is needed for gdb and sys_ptrace. */ | |
62 | STREG %r0, TASK_PT_PSW(%r1) | |
63 | STREG %r2, TASK_PT_GR2(%r1) /* preserve rp */ | |
64 | STREG %r19, TASK_PT_GR19(%r1) /* 7th argument */ | |
65 | STREG %r20, TASK_PT_GR20(%r1) /* 6th argument */ | |
66 | STREG %r21, TASK_PT_GR21(%r1) /* 5th argument */ | |
67 | STREG %r22, TASK_PT_GR22(%r1) /* syscall # */ | |
68 | STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */ | |
69 | STREG %r24, TASK_PT_GR24(%r1) /* 3rd argument */ | |
70 | STREG %r25, TASK_PT_GR25(%r1) /* 2nd argument */ | |
71 | STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */ | |
72 | STREG %r27, TASK_PT_GR27(%r1) /* user dp */ | |
73 | STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */ | |
00df111e | 74 | STREG %r0, TASK_PT_ORIG_R28(%r1) /* don't prohibit restarts */ |
1da177e4 LT |
75 | STREG %r29, TASK_PT_GR29(%r1) /* 8th argument */ |
76 | STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */ | |
77 | ||
78 | ldo TASK_PT_FR0(%r1), %r27 /* save fpregs from the kernel */ | |
79 | save_fp %r27 /* or potential task switch */ | |
80 | ||
81 | mfctl %cr11, %r27 /* i.e. SAR */ | |
82 | STREG %r27, TASK_PT_SAR(%r1) | |
83 | ||
84 | loadgp | |
85 | ||
86 | stw %r21, -52(%r30) ;! 5th argument | |
87 | stw %r20, -56(%r30) ;! 6th argument | |
88 | stw %r19, -60(%r30) ;! 7th argument | |
89 | stw %r29, -64(%r30) ;! 8th argument | |
90 | ||
91 | ldil L%hpux_call_table, %r21 | |
92 | ldo R%hpux_call_table(%r21), %r21 | |
93 | comiclr,>>= __NR_HPUX_syscalls, %r22, %r0 | |
94 | b,n syscall_nosys | |
79793455 | 95 | LDREGX %r22(%r21), %r21 |
1da177e4 LT |
96 | ldil L%hpux_syscall_exit,%r2 |
97 | be 0(%sr7,%r21) | |
98 | ldo R%hpux_syscall_exit(%r2),%r2 | |
99 | ||
100 | syscall_nosys: | |
101 | ldil L%hpux_syscall_exit,%r1 | |
102 | be R%hpux_syscall_exit(%sr7,%r1) | |
103 | ldo -ENOSYS(%r0),%r28 | |
79793455 | 104 | ENDPROC(hpux_gateway_page) |
1da177e4 | 105 | |
873d50e2 | 106 | .align PAGE_SIZE |
79793455 | 107 | ENTRY(end_hpux_gateway_page) |