root/arch/sparc/kernel/sclow.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /* sclow.S: Low level special syscall handling.
   2  *          Basically these are cases where we can completely
   3  *          handle the system call without saving any state
   4  *          because we know that the process will not sleep.
   5  *
   6  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
   7  */
   8 
   9 #include <asm/cprefix.h>
  10 #include <asm/ptrace.h>
  11 #include <asm/errno.h>
  12 #include <asm/winmacro.h>
  13 #include <asm/psr.h>
  14 
  15 #define CC_AND_RETT  \
  16         set     PSR_C, %l4; \
  17         andn    %l0, %l4, %l4; \
  18         wr      %l4, 0x0, %psr; \
  19         nop; nop; nop; \
  20         jmp     %l2; \
  21         rett    %l2 + 4;
  22 
  23 #define SC_AND_RETT  \
  24         set     PSR_C, %l4; \
  25         or      %l0, %l4, %l4; \
  26         wr      %l4, 0x0, %psr; \
  27         nop; nop; nop; \
  28         jmp     %l2; \
  29         rett    %l2 + 4;
  30 
  31 #define LABEL(func)  CONCAT(func, _low)
  32 
  33         .globl  LABEL(sunosnop)
  34 LABEL(sunosnop):
  35         CC_AND_RETT
  36 
  37         .globl  LABEL(sunosgetpid)
  38 LABEL(sunosgetpid):
  39         LOAD_CURRENT(l4, l5)
  40         ld      [%l4 + 108], %i0
  41         ld      [%l4 + 256], %l5
  42         ld      [%l5 + 108], %i1
  43         CC_AND_RETT
  44 
  45         .globl  LABEL(sunosgetuid)
  46 LABEL(sunosgetuid):
  47         LOAD_CURRENT(l4, l5)
  48         lduh    [%l4 + 280], %i0
  49         lduh    [%l4 + 282], %i1
  50         CC_AND_RETT
  51 
  52         .globl  LABEL(sunosgetgid)
  53 LABEL(sunosgetgid):
  54         LOAD_CURRENT(l4, l5)
  55         lduh    [%l4 + 288], %i0
  56         lduh    [%l4 + 290], %i1
  57         CC_AND_RETT
  58 
  59         .globl  LABEL(sunosmctl)
  60 LABEL(sunosmctl):
  61         mov     0, %i0
  62         CC_AND_RETT
  63 
  64         .globl  LABEL(sunosgdtsize)
  65 LABEL(sunosgdtsize):    
  66         mov     256, %i0
  67         CC_AND_RETT
  68 
  69         .globl  LABEL(sunossblock)
  70 LABEL(sunossblock):
  71         LOAD_CURRENT(l4, l5)
  72         set     -65793, %l5
  73         and     %i0, %l5, %l5
  74         ld      [%l4 + TASK_BLOCKED], %i0
  75         or      %i0, %l5, %l5
  76         st      %l5, [%l4 + TASK_BLOCKED]
  77         CC_AND_RETT
  78 
  79         .globl  LABEL(sunossmask)
  80 LABEL(sunossmask):
  81         LOAD_CURRENT(l4, l5)
  82         set     -65793, %l5
  83         and     %i0, %l5, %l5
  84         ld      [%l4 + TASK_BLOCKED], %i0
  85         st      %l5, [%l4 + TASK_BLOCKED]
  86         CC_AND_RETT
  87 
  88         .globl  LABEL(getpagesize)
  89 LABEL(getpagesize):
  90         set     4096, %i0
  91         CC_AND_RETT
  92 
  93         .globl  LABEL(umask)
  94 LABEL(umask):
  95         LOAD_CURRENT(l4, l5)
  96         ld      [%l4 + 1560], %l5
  97         and     %i0, 511, %l4
  98         lduh    [%l5 + 4], %i0
  99         sth     %l4, [%l5 + 4]
 100         CC_AND_RETT
 101 
 102         .globl  LABEL(write)
 103 LABEL(write):
 104         cmp     %i0, 255                /* fd >= NR_OPEN */
 105         bgu,a   write_error_return
 106          mov    EBADF, %i0
 107 
 108         LOAD_CURRENT(l4, l5)
 109         ld      [%l4 + 1564], %l5
 110         sll     %i0, 2, %l6
 111         add     %l5, %l6, %l5
 112         ld      [%l5 + 36], %l6
 113         cmp     %l6, 0                  /* !(file=current->files->fd[fd]) */
 114         be,a    write_error_return
 115          mov    EBADF, %i0      
 116 
 117         ld      [%l6 + 36], %l5
 118         cmp     %l5, 0                  /* !(inode=file->f_inode) */
 119         be,a    write_error_return
 120          mov    EBADF, %i0
 121 
 122         lduh    [%l6], %l5              /* !(file->f_mode & 2) */
 123         andcc   %l5, 2, %g0
 124         be,a    write_error_return
 125          mov    EBADF, %i0
 126 
 127         ld      [%l6 + 40], %l5
 128         cmp     %l5, 0                  /* !file->f_op */
 129         be,a    write_error_return
 130          mov    EINVAL, %i0
 131 
 132         ld      [%l5 + 8], %l5          /* !file->f_op->write */
 133         cmp     %l5, 0
 134         be,a    write_error_return
 135          mov    EINVAL, %i0
 136 
 137         cmp     %i2, 0                  /* count == 0 */
 138         bne     1f
 139          nop
 140 
 141         mov     0, %i0
 142         CC_AND_RETT
 143 
 144 1:
 145         /* See if we can do the optimization... */
 146         ld      [%l6 + 36], %l5
 147         lduh    [%l5 + 16], %l5
 148         srl     %l5, 8, %l6
 149         cmp     %l6, 1                  /* MEM_MAJOR */
 150         bne,a   write_is_too_hard
 151          sethi  %hi(C_LABEL(quick_sys_write)), %l7
 152 
 153         and     %l5, 0xff, %l5
 154         cmp     %l5, 3                  /* NULL_MINOR */
 155         bne,a   write_is_too_hard
 156          sethi  %hi(C_LABEL(quick_sys_write)), %l7
 157 
 158         /* We only optimize for the /dev/null case currently,
 159          * however to stay POSIX4 compliant we must check the
 160          * validity of the passed buffer.  Blowlaris2.x does not
 161          * do this and is therefore not POSIX4 compliant!
 162          * If you are going to optimize for benchmarks, fine,
 163          * but to break behavior of a system call in the process
 164          * is complete brain damage...
 165          */
 166 
 167         /* XXX write verify_area thingy for full POSIX conformance! XXX */
 168 
 169         mov     %i2, %i0
 170         CC_AND_RETT
 171 
 172 write_is_too_hard:
 173         b       syscall_is_too_hard
 174          or     %l7, %lo(C_LABEL(quick_sys_write)), %l7
 175 
 176 write_error_return:
 177         SC_AND_RETT
 178 
 179         /* XXX sys_nice() XXX */
 180         /* XXX sys_setpriority() XXX */
 181         /* XXX sys_getpriority() XXX */
 182         /* XXX sys_setregid() XXX */
 183         /* XXX sys_setgid() XXX */
 184         /* XXX sys_setreuid() XXX */
 185         /* XXX sys_setuid() XXX */
 186         /* XXX sys_setfsuid() XXX */
 187         /* XXX sys_setfsgid() XXX */
 188         /* XXX sys_setpgid() XXX */
 189         /* XXX sys_getpgid() XXX */
 190         /* XXX sys_setsid() XXX */
 191         /* XXX sys_getsid() XXX */

/* [previous][next][first][last][top][bottom][index][help] */