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/offset.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 33hpux_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 109syscall_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 116end_hpux_gateway_page: 117