linux/arch/parisc/hpux/gate.S
<<
>>
Prefs
   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/asm-offsets.h>
  13#include <asm/unistd.h>
  14#include <asm/errno.h>
  15#include <linux/linkage.h>
  16
  17        .level  LEVEL
  18        .text
  19
  20        .import hpux_call_table
  21        .import hpux_syscall_exit,code
  22
  23        .align  PAGE_SIZE
  24ENTRY(hpux_gateway_page)
  25        nop
  26#ifdef CONFIG_64BIT
  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 */
  74        STREG   %r0, TASK_PT_ORIG_R28(%r1)     /* don't prohibit restarts */
  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
  95        LDREGX  %r22(%r21), %r21
  96        ldil    L%hpux_syscall_exit,%r2
  97        be      0(%sr7,%r21)
  98        ldo     R%hpux_syscall_exit(%r2),%r2
  99
 100syscall_nosys:
 101        ldil    L%hpux_syscall_exit,%r1
 102        be      R%hpux_syscall_exit(%sr7,%r1)
 103        ldo     -ENOSYS(%r0),%r28
 104ENDPROC(hpux_gateway_page)
 105
 106        .align  PAGE_SIZE
 107ENTRY(end_hpux_gateway_page)
 108