2 * Copyright (c) 2002, 2003 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/syscall.h>
30 #include <machine/asm.h>
34 * A process performs a syscall by performing an indirect call to the
35 * address stored in ar.k5. The contents of ar.pfs and rp should be
36 * saved prior to the syscall in r9 and r10 respectively. The kernel
37 * will restore these values on return. The value of gp is preserved
38 * across the call. This allows for small enough syscall stubs without
40 * The address in ar.k5 is the start of the EPC gateway page and also
41 * the syscall entry point. The syscall code in the gateway page is
42 * primarily responsible for increasing the privilege level, but will
43 * also make sure we have a reliable psr.
49 * in0-in7 - syscall arguments
52 * r8+r9 - syscall return value(s)
53 * r10 - syscall error flag
54 * ar.pfs - restored from r9
55 * rp - restored from r10
58 * The EPC syscall code defines:
60 * r14 - Kernel memory stack
61 * r15 - Kernel register stack
63 * Also in the gateway page are the signal trampolines. As such, stacks
64 * don't have to be made executable per se. Since debuggers have a need
65 * to know about trampolines, we probably need to define a table of
66 * vectors or something along those lines so that debuggers can get the
67 * information they need and we have the freedom to move code around.
70 .section .text.gateway, "ax"
72 .global ia64_gateway_page
75 mov r14=ar.k7 // Memory stack
76 mov r15=ar.k6 // Register stack
119 ENTRY_NOPROFILE(break_sigtramp, 0)
129 add r16=16+UC_MCONTEXT+MC_SPECIAL,sp
139 st8 [r14]=r17,64 // bspstore
140 (p15) mov ar.bspstore=gp
145 st8 [r15]=r18 // rnat
146 st8 [r14]=r0 // ndirty
151 alloc r14=ar.pfs, 0, 0, 3, 0
157 ld8 r16=[r10],8 // function address
159 ld8 gp=[r10] // function's gp value
170 mov r15=SYS_sigreturn
183 ENTRY_NOPROFILE(epc_sigtramp, 0)
185 ld8 r16=[r10],8 // function address
192 (p15) mov ar.bspstore=gp
197 alloc r14=ar.pfs, 0, 0, 3, 0
203 ld8 gp=[r10] // function's gp value
214 CALLSYS_NOERROR(sigreturn)
216 CALLSYS_NOERROR(exit)
223 ENTRY_NOPROFILE(epc_syscall, 8)
243 add r30=-SIZEOF_TRAPFRAME,r14
269 add r28=FRAME_SYSCALL,r0
273 st8 [r30]=r29,16 // tf_length
274 st8 [r31]=r28,16 // tf_flags
279 st8 [r30]=r20,16 // sp
280 st8 [r31]=r21,16 // unat
285 st8 [r30]=r10,16 // rp (syscall caller)
286 st8 [r31]=r25,16 // pr
291 st8 [r30]=r9,16 // pfs (syscall caller)
292 st8 [r31]=r18,16 // bspstore
297 st8 [r30]=r19,16 // rnat
298 st8 [r31]=r0,16 // __spare
299 dep r11=-1,r11,44,1 // Set psr.bn=1
303 st8 [r30]=r17,16 // tp
304 st8 [r31]=r16,16 // rsc
305 dep r11=-1,r11,32,2 // Set psr.cpl=3
309 st8 [r30]=r22,16 // fpsr
310 st8 [r31]=r11,16 // psr
315 st8 [r30]=r1,16 // gp
316 st8 [r31]=r27,16 // ndirty
321 st8 [r30]=r26,16 // pfs (syscall stub)
322 st8 [r31]=r24,16 // rp (syscall stub)
327 st8 [r30]=r0,80 // ifa
328 st8 [r31]=r0,80 // isr
333 alloc r14=ar.pfs,0,0,8,0
334 st8 [r30]=r8,16 // syscall number (=r15)
340 st8.spill [r31]=r32,16 // arg0 (=r16)
342 st8.spill [r30]=r33,16 // arg1 (=r17)
348 st8.spill [r31]=r34,16 // arg2 (=r18)
350 st8.spill [r30]=r35,16 // arg3 (=r19)
356 st8.spill [r31]=r36,16 // arg4 (=r20)
358 st8.spill [r30]=r37,16 // arg5 (=r21)
364 st8.spill [r31]=r38 // arg6 (=r22)
366 st8.spill [r30]=r39 // arg7 (=r23)
379 br.call.sptk rp=syscall
382 .global epc_syscall_return
387 br.call.sptk rp=do_ast
391 cmp4.eq p15,p0=ERESTART,r8
393 (p15) br.spnt 1b // restart syscall
397 ld8 r14=[r14] // tf_flags
405 (p15) br.spnt exception_restore
409 alloc r31=ar.pfs,0,0,0,0
415 ld8 r31=[r15],24 // tf_length
416 ld8 r16=[r14],16 // sp
421 ld8 r17=[r15],16 // unat (before)
422 ld8 r18=[r14],16 // rp (syscall caller)
427 ld8 r19=[r15],16 // pr
428 ld8 r20=[r14],16 // pfs (syscall caller)
433 ld8 r21=[r15],24 // bspstore
434 ld8 r22=[r14],24 // rnat
439 ld8 r23=[r15],16 // tp
440 ld8 r24=[r14],16 // rsc
445 ld8 r25=[r15],16 // fpsr
446 ld8 r26=[r14],16 // psr
451 ld8 gp=[r15],16 // gp
452 ld8 r27=[r14],16 // ndirty
453 tbit.z p14,p15=r26,34 // p14=ia64, p15=ia32
457 ld8 r28=[r15],56 // pfs (syscall stub)
458 ld8 r29=[r14],56 // rp (syscall stub)
463 ld8 r8=[r15],16 // r8
469 ld8 r9=[r14],40 // r9
470 ld8 r10=[r15],40 // r10
471 (p15) br.spnt epc_syscall_setup_ia32
488 add r14=gw_ret-ia64_gateway_page,r14
489 dep r30=0,r30,0,13 // 8KB aligned.
509 epc_syscall_setup_ia32:
520 dep r30=0,r30,0,13 // 8KB aligned
563 add r2=gw_ret_ia32-ia64_gateway_page,r2