1/* $Id: entry64.S,v 1.6 2000/01/12 02:59:26 davem Exp $ 2 * entry64.S: Solaris syscall emulation entry point. 3 * 4 * Copyright (C) 1996,1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 5 * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) 6 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) 7 */ 8 9#include <linux/errno.h> 10 11#include <asm/head.h> 12#include <asm/asi.h> 13#include <asm/smp.h> 14#include <asm/ptrace.h> 15#include <asm/page.h> 16#include <asm/signal.h> 17#include <asm/pgtable.h> 18#include <asm/processor.h> 19 20#include "conv.h" 21 22#define NR_SYSCALLS 256 23 24 .text 25solaris_syscall_trace: 26 call syscall_trace 27 nop 28 srl %i0, 0, %o0 29 mov %i4, %o4 30 srl %i1, 0, %o1 31 mov %i5, %o5 32 andcc %l3, 1, %g0 33 be,pt %icc, 2f 34 srl %i2, 0, %o2 35 b,pt %xcc, 2f 36 add %sp, PTREGS_OFF, %o0 37 38solaris_sucks: 39/* Solaris is a big system which needs to be able to do all the things 40 * in Inf+1 different ways */ 41 add %i6, 0x5c, %o0 42 mov %i0, %g1 43 mov %i1, %i0 44 mov %i2, %i1 45 srl %o0, 0, %o0 46 mov %i3, %i2 47 movrz %g1, 256, %g1 /* Ensure we don't loop forever */ 48 mov %i4, %i3 49 mov %i5, %i4 50 ba,pt %xcc, solaris_sparc_syscall 51exen: lduwa [%o0] ASI_S, %i5 52 53exenf: ba,pt %xcc, solaris_sparc_syscall 54 clr %i5 55 56/* For shared binaries, binfmt_elf32 already sets up personality 57 and exec_domain. This is to handle static binaries as well */ 58solaris_reg: 59 call solaris_register 60 nop 61 ba,pt %xcc, 1f 62 mov %i4, %o4 63 64linux_syscall_for_solaris: 65 sll %l3, 2, %l4 66 ba,pt %xcc, 10f 67 lduw [%l6 + %l4], %l3 68 69 /* Solaris system calls enter here... */ 70 .align 32 71 .globl solaris_sparc_syscall 72solaris_sparc_syscall: 73 ldub [%g6 + AOFF_task_personality + ASIZ_task_personality - 1], %l0 74 cmp %g1, 255 75 bg,pn %icc, solaris_unimplemented 76 srl %g1, 0, %g1 77 sethi %hi(solaris_sys_table), %l7 78 brz,pn %g1, solaris_sucks 79 mov %i4, %o4 80 sll %g1, 2, %l4 81 cmp %l0, 1 82 bne,pn %icc, solaris_reg 831: srl %i0, 0, %o0 84 lduw [%l7 + %l4], %l3 85 srl %i1, 0, %o1 86 ldx [%g6 + AOFF_task_flags], %l5 87 cmp %l3, NR_SYSCALLS 88 bleu,a,pn %xcc, linux_syscall_for_solaris 89 sethi %hi(sys_call_table32), %l6 90 andcc %l3, 1, %g0 91 bne,a,pn %icc, 10f 92 add %sp, PTREGS_OFF, %o0 9310: srl %i2, 0, %o2 94 mov %i5, %o5 95 andn %l3, 3, %l7 96 andcc %l5, 0x20, %g0 97 bne,pn %icc, solaris_syscall_trace 98 mov %i0, %l5 992: call %l7 100 srl %i3, 0, %o3 101ret_from_solaris: 102 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] 103 ldx [%g6 + AOFF_task_flags], %l6 104 sra %o0, 0, %o0 105 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 106 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 107 cmp %o0, -ENOIOCTLCMD 108 sllx %g2, 32, %g2 109 bgeu,pn %xcc, 1f 110 andcc %l6, 0x20, %l6 111 112 /* System call success, clear Carry condition code. */ 113 andn %g3, %g2, %g3 114 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] 115 bne,pn %icc, solaris_syscall_trace2 116 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 117 andcc %l1, 1, %g0 118 bne,pn %icc, 2f 119 clr %l6 120 add %l1, 0x4, %l2 121 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc 122 call rtrap 123 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4 124 125 /* When tnpc & 1, this comes from setcontext and we don't want to advance pc */ 1262: andn %l1, 3, %l1 127 call rtrap 128 stx %l1, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc&~3 129 1301: 131 /* System call failure, set Carry condition code. 132 * Also, get abs(errno) to return to the process. 133 */ 134 sub %g0, %o0, %o0 135 or %g3, %g2, %g3 136 cmp %o0, ERANGE /* 0-ERANGE are identity mapped */ 137 bleu,pt %icc, 1f 138 cmp %o0, EMEDIUMTYPE 139 bgu,pn %icc, 1f 140 sethi %hi(solaris_err_table), %l6 141 sll %o0, 2, %o0 142 or %l6, %lo(solaris_err_table), %l6 143 ldsw [%l6 + %o0], %o0 1441: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] 145 mov 1, %l6 146 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] 147 bne,pn %icc, solaris_syscall_trace2 148 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 149 andcc %l1, 1, %g0 150 bne,pn %icc, 2b 151 add %l1, 0x4, %l2 152 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc 153 call rtrap 154 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4 155 156solaris_syscall_trace2: 157 call syscall_trace 158 add %l1, 0x4, %l2 /* npc = npc+4 */ 159 andcc %l1, 1, %g0 160 bne,pn %icc, 2b 161 nop 162 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] 163 call rtrap 164 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] 165 166 /* This one is tricky, so that's why we do it in assembly */ 167 .globl solaris_sigsuspend 168solaris_sigsuspend: 169 call do_sol_sigsuspend 170 nop 171 brlz,pn %o0, ret_from_solaris 172 nop 173 call sys_sigsuspend 174 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] 175 176 .globl solaris_getpid 177solaris_getpid: 178 call sys_getppid /* This is tricky, so don't do it in assembly */ 179 nop 180 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1] 181 b,pt %xcc, ret_from_solaris 182 lduw [%g6 + AOFF_task_pid], %o0 183 184 .globl solaris_getuid 185solaris_getuid: 186 lduw [%g6 + AOFF_task_euid], %o1 187 lduw [%g6 + AOFF_task_uid], %o0 188 b,pt %xcc, ret_from_solaris 189 stx %o1, [%sp + PTREGS_OFF + PT_V9_I1] 190 191 .globl solaris_getgid 192solaris_getgid: 193 lduw [%g6 + AOFF_task_egid], %o1 194 lduw [%g6 + AOFF_task_gid], %o0 195 b,pt %xcc, ret_from_solaris 196 stx %o1, [%sp + PTREGS_OFF + PT_V9_I1] 197 198 .globl solaris_unimplemented 199solaris_unimplemented: 200 call do_sol_unimplemented 201 add %sp, PTREGS_OFF, %o0 202 ba,pt %xcc, ret_from_solaris 203 nop 204 205 .section __ex_table,#alloc 206 .align 4 207 .word exen, exenf 208 209