]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/ia64/ia64/syscall.S
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / ia64 / ia64 / syscall.S
1 /*-
2  * Copyright (c) 2002, 2003 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
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.
14  *
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.
25  *
26  * $FreeBSD$
27  */
28
29 #include <sys/syscall.h>
30 #include <machine/asm.h>
31 #include <assym.s>
32
33 /*
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
39  * getting too weird.
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.
44  *
45  * A process defines:
46  *      r8              -       syscall number
47  *      r9              -       copy of ar.pfs
48  *      r10             -       copy of rp
49  *      in0-in7         -       syscall arguments
50  *
51  * A syscall returns:
52  *      r8+r9           -       syscall return value(s)
53  *      r10             -       syscall error flag
54  *      ar.pfs          -       restored from r9
55  *      rp              -       restored from r10
56  *      gp              -       preserved
57  *
58  * The EPC syscall code defines:
59  *      r11             -       copy of psr.l
60  *      r14             -       Kernel memory stack
61  *      r15             -       Kernel register stack
62  *
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.
68  */
69
70         .section        .text.gateway, "ax"
71         .align          PAGE_SIZE
72         .global         ia64_gateway_page
73 ia64_gateway_page:
74 {       .mmb
75         mov             r14=ar.k7               // Memory stack
76         mov             r15=ar.k6               // Register stack
77         epc
78         ;;
79 }
80 {       .mlx
81         mov             r11=psr
82         movl            r31=epc_syscall
83         ;;
84 }
85 {       .mib
86         rum             psr.be
87         mov             b7=r31
88         br              b7
89         ;;
90 }
91 gw_ret:
92 {       .mmi
93         mov             ar.rnat=r22
94         ;;
95         mov             ar.rsc=r24
96         mov             ar.pfs=r20
97 }
98 {       .mib
99         mov             ar.fpsr=r25
100         mov             b0=r18
101         br.sptk         b6
102         ;;
103 }
104 gw_ret_ia32:
105 {       .mmi
106         flushrs
107         nop             0
108         nop             0
109         ;;
110 }
111 {       .mib
112         nop             0
113         nop             0
114         br.ia.sptk      b6
115         ;;
116 }
117
118
119 ENTRY_NOPROFILE(break_sigtramp, 0)
120 {       .mib
121         mov             ar.rsc=0
122         cmp.ne          p15,p0=0,gp
123         cover
124         ;;
125 }
126 {       .mmi
127         flushrs
128 (p15)   invala
129         add             r16=16+UC_MCONTEXT+MC_SPECIAL,sp
130         ;;
131 }
132 {       .mmi
133         mov             r17=ar.bsp
134         mov             r18=ar.rnat
135         add             r14=40,r16
136         ;;
137 }
138 {       .mmi
139         st8             [r14]=r17,64            // bspstore
140 (p15)   mov             ar.bspstore=gp
141         add             r15=48,r16
142         ;;
143 }
144 {       .mmi
145         st8             [r15]=r18               // rnat
146         st8             [r14]=r0                // ndirty
147         nop             0
148         ;;
149 }
150 {       .mmi
151         alloc           r14=ar.pfs, 0, 0, 3, 0
152         mov             ar.rsc=15
153         mov             out0=r8
154         ;;
155 }
156 {       .mmi
157         ld8             r16=[r10],8             // function address
158         ;;
159         ld8             gp=[r10]                // function's gp value
160         mov             b7=r16
161         ;;
162 }
163 {       .mib
164         mov             out1=r9
165         add             out2=16,sp
166         br.call.sptk    rp=b7
167         ;;
168 }
169 {       .mmi
170         mov             r15=SYS_sigreturn
171         add             out0=16,sp
172         break           0x100000
173         ;;
174 }
175 {       .mmi
176         mov             r15=SYS_exit
177         mov             out0=ret0
178         break           0x100000
179         ;;
180 }
181 END(break_sigtramp)
182
183 ENTRY_NOPROFILE(epc_sigtramp, 0)
184 {       .mmi
185         ld8             r16=[r10],8             // function address
186         mov             ar.rsc=0
187         cmp.ne          p15,p0=0,gp
188         ;;
189 }
190 {       .mmi
191 (p15)   invala
192 (p15)   mov             ar.bspstore=gp
193         mov             b7=r16
194         ;;
195 }
196 {       .mmi
197         alloc           r14=ar.pfs, 0, 0, 3, 0
198         mov             ar.rsc=15
199         nop             0
200         ;;
201 }
202 {       .mii
203         ld8             gp=[r10]                // function's gp value
204         mov             out0=r8
205         mov             out1=r9
206 }
207 {       .mib
208         add             out2=16,sp
209         nop             0
210         br.call.sptk    rp=b7
211         ;;
212 }
213         add             out0=16,sp
214         CALLSYS_NOERROR(sigreturn)
215         mov             out0=ret0
216         CALLSYS_NOERROR(exit)
217 END(epc_sigtramp)
218
219         .align          PAGE_SIZE
220
221         .text
222
223 ENTRY_NOPROFILE(epc_syscall, 8)
224         .prologue
225         .unwabi         @svr4, 'E'
226         .save           rp, r0
227         .body
228 {       .mmi
229         mov             r16=ar.rsc
230         mov             ar.rsc=0
231         mov             r17=r13
232         ;;
233 }
234 {       .mmi
235         mov             r18=ar.bspstore
236         ;;
237         mov             r19=ar.rnat
238         dep             r15=r18,r15,0,9
239         ;;
240 }
241 {       .mmi
242         mov             ar.bspstore=r15
243         add             r30=-SIZEOF_TRAPFRAME,r14
244         mov             r20=sp
245         ;;
246 }
247 {       .mii
248         mov             r13=ar.k4
249         dep             r30=0,r30,0,10
250         ;;
251         add             sp=-16,r30
252         ;;
253 }
254 {       .mmi
255         mov             ar.rnat=r19
256         mov             r21=ar.unat
257         add             r31=8,r30
258         ;;
259 }
260 {       .mii
261         mov             r22=ar.fpsr
262         sub             r29=r14,r30
263         nop             0
264 }
265 {       .mmi
266         mov             r23=ar.bsp
267         mov             ar.rsc=3
268         add             r28=FRAME_SYSCALL,r0
269         ;;
270 }
271 {       .mmi
272         st8             [r30]=r29,16            // tf_length
273         st8             [r31]=r28,16            // tf_flags
274         mov             r24=rp
275         ;;
276 }
277 {       .mmi
278         st8             [r30]=r20,16            // sp
279         st8             [r31]=r21,16            // unat
280         mov             r25=pr
281         ;;
282 }
283 {       .mmi
284         st8             [r30]=r10,16            // rp (syscall caller)
285         st8             [r31]=r25,16            // pr
286         mov             r26=ar.pfs
287         ;;
288 }
289 {       .mmi
290         st8             [r30]=r9,16             // pfs (syscall caller)
291         st8             [r31]=r18,16            // bspstore
292         sub             r27=r23,r15
293         ;;
294 }
295 {       .mmi
296         st8             [r30]=r19,16            // rnat
297         st8             [r31]=r0,16             // __spare
298         nop             0
299         ;;
300 }
301 {       .mmi
302         st8             [r30]=r17,16            // tp
303         st8             [r31]=r16,16            // rsc
304         dep             r11=-1,r11,32,2         // Set psr.cpl=3
305         ;;
306 }
307 {       .mmi
308         st8             [r30]=r22,16            // fpsr
309         st8             [r31]=r11,16            // psr
310         nop             0
311         ;;
312 }
313 {       .mmi
314         st8             [r30]=r1,16             // gp
315         st8             [r31]=r27,16            // ndirty
316         nop             0
317         ;;
318 }
319 {       .mmi
320         st8             [r30]=r26,16            // pfs (syscall stub)
321         st8             [r31]=r24,16            // rp (syscall stub)
322         nop             0
323         ;;
324 }
325 {       .mmi
326         st8             [r30]=r0,80             // ifa
327         st8             [r31]=r0,80             // isr
328         nop             0
329         ;;
330 }
331 {       .mmi
332         alloc           r14=ar.pfs,0,0,8,0
333         st8             [r30]=r8,16             // syscall number (=r15)
334         nop             0
335         ;;
336 }
337 {       .mmi
338         .mem.offset     0,0
339         st8.spill       [r31]=r32,16            // arg0 (=r16)
340         .mem.offset     8,0
341         st8.spill       [r30]=r33,16            // arg1 (=r17)
342         nop             0
343         ;;
344 }
345 {       .mmi
346         .mem.offset     16,0
347         st8.spill       [r31]=r34,16            // arg2 (=r18)
348         .mem.offset     24,0
349         st8.spill       [r30]=r35,16            // arg3 (=r19)
350         nop             0
351         ;;
352 }
353 {       .mmi
354         .mem.offset     32,0
355         st8.spill       [r31]=r36,16            // arg4 (=r20)
356         .mem.offset     40,0
357         st8.spill       [r30]=r37,16            // arg5 (=r21)
358         nop             0
359         ;;
360 }
361 {       .mmi
362         .mem.offset     48,0
363         st8.spill       [r31]=r38               // arg6 (=r22)
364         .mem.offset     56,0
365         st8.spill       [r30]=r39               // arg7 (=r23)
366         nop             0
367         ;;
368 }
369 {       .mlx
370         ssm             psr.dfh|psr.ac
371         movl            gp=__gp
372         ;;
373 }
374 1:
375 {       .mib
376         srlz.d
377         add             out0=16,sp
378         br.call.sptk    rp=syscall
379         ;;
380 }
381         .global         epc_syscall_return
382 epc_syscall_return:
383 {       .mib
384         add             out0=16,sp
385         nop             0
386         br.call.sptk    rp=do_ast
387         ;;
388 }
389 {       .mib
390         cmp4.eq         p15,p0=ERESTART,r8
391         add             r14=24,sp
392 (p15)   br.spnt         1b                      // restart syscall
393         ;;
394 }
395 {       .mmi
396         ld8             r14=[r14]               // tf_flags
397         nop             0
398         nop             0
399         ;;
400 }
401 {       .mib
402         nop             0
403         tbit.z          p15,p0=r14,0
404 (p15)   br.spnt         exception_restore
405         ;;
406 }
407 {       .mmi
408         alloc           r31=ar.pfs,0,0,0,0
409         add             r14=32,sp
410         add             r15=16,sp
411         ;;
412 }
413 {       .mmi
414         ld8             r31=[r15],24            // tf_length
415         ld8             r16=[r14],16            // sp
416         add             sp=16,sp
417         ;;
418 }
419 {       .mmi
420         ld8             r17=[r15],16            // unat (before)
421         ld8             r18=[r14],16            // rp (syscall caller)
422         add             r31=r31,sp
423         ;;
424 }
425 {       .mmi
426         ld8             r19=[r15],16            // pr
427         ld8             r20=[r14],16            // pfs (syscall caller)
428         nop             0
429         ;;
430 }
431 {       .mmi
432         ld8             r21=[r15],24            // bspstore
433         ld8             r22=[r14],24            // rnat
434         mov             pr=r19,0x1fffe
435         ;;
436 }
437 {       .mmi
438         ld8             r23=[r15],16            // tp
439         ld8             r24=[r14],16            // rsc
440         nop             0
441         ;;
442 }
443 {       .mmi
444         ld8             r25=[r15],16            // fpsr
445         ld8             r26=[r14],16            // psr
446         nop             0
447         ;;
448 }
449 {       .mmi
450         ld8             gp=[r15],16             // gp
451         ld8             r27=[r14],16            // ndirty
452         tbit.z          p14,p15=r26,34          // p14=ia64, p15=ia32
453         ;;
454 }
455 {       .mmi
456         ld8             r28=[r15],56            // pfs (syscall stub)
457         ld8             r29=[r14],56            // rp (syscall stub)
458         shl             r27=r27,16
459         ;;
460 }
461 {       .mmi
462         ld8             r8=[r15],16             // r8
463         mov             ar.rsc=r27
464         mov             b6=r29
465         ;;
466 }
467 {       .mmb
468         ld8             r9=[r14],40             // r9
469         ld8             r10=[r15],40            // r10
470 (p15)   br.spnt         epc_syscall_setup_ia32
471         ;;
472 }
473 {       .mmi
474         loadrs
475         mov             ar.k7=r31
476         mov             sp=r16
477         ;;
478 }
479 {       .mmi
480         mov             r30=ar.bspstore
481         mov             r14=ar.k5
482         mov             ar.pfs=r28
483         ;;
484 }
485 {       .mmi
486         mov             ar.bspstore=r21
487         add             r14=gw_ret-ia64_gateway_page,r14
488         dep             r30=0,r30,0,13          // 8KB aligned.
489         ;;
490 }
491 {       .mii
492         mov             ar.k6=r30
493         mov             r13=r23
494         nop             0
495 }
496 {       .mmi
497         mov             psr.l=r26
498         mov             ar.unat=r17
499         nop             0
500         ;;
501 }
502 {       .mib
503         srlz.d
504         mov             b7=r14
505         br.ret.sptk     b7
506         ;;
507 }
508 epc_syscall_setup_ia32:
509 {       .mmi
510         loadrs
511         mov             ar.k7=r31
512         mov             sp=r16
513         ;;
514 }
515 {       .mmi
516         mov             r30=ar.bspstore
517         ;;
518         mov             ar.unat=r17
519         dep             r30=0,r30,0,13          // 8KB aligned
520         ;;
521 }
522 {       .mmi
523         mov             ar.k6=r30
524         mov             ar.bspstore=r21
525         mov             r11=r0
526         ;;
527 }
528 {       .mmi
529         ld8             r16=[r14],64
530         ld8             r17=[r15],80
531         mov             r13=r0
532         ;;
533 }
534  
535         ld8             r24=[r14],32
536         ld8             r27=[r15],16
537         ;;
538         ld8             r28=[r14],16
539         ld8             r29=[r15],16
540         ;;
541         ld8             r30=[r14],40
542         ld8             r31=[r15],40
543         ;;
544
545 {       .mmi
546         ld8             r2=[r14]
547         ld8             r3=[r15]
548         mov             r14=r0
549         ;;
550 }
551 {       .mmi
552         mov             ar.csd=r2
553         mov             ar.ssd=r3
554         mov             r15=r0
555         ;;
556 }
557
558         mov             r2=ar.k5
559         mov             psr.l=r26
560         ;;
561         srlz.d
562         add             r2=gw_ret_ia32-ia64_gateway_page,r2
563         ;;
564         mov             ar.rsc=0
565         mov             b7=r2
566         br.ret.sptk     b7
567         ;;
568 END(epc_syscall)