]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/ia64/ia64/syscall.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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         nop             0
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             r21=ar.unat
243         add             r30=-SIZEOF_TRAPFRAME,r14
244         mov             r20=sp
245         ;;
246 }
247 {       .mii
248         mov             r17=r13
249         dep             r30=0,r30,0,10
250         ;;
251         add             sp=-16,r30
252         ;;
253 }
254 {       .mmi
255         mov             ar.bspstore=r15
256         ;;
257         mov             ar.rnat=r19
258         add             r31=8,r30
259         ;;
260 }
261 {       .mmi
262         mov             r13=ar.k4
263         mov             r22=ar.fpsr
264         sub             r29=r14,r30
265 }
266 {       .mmi
267         mov             r23=ar.bsp
268         mov             ar.rsc=3
269         add             r28=FRAME_SYSCALL,r0
270         ;;
271 }
272 {       .mmi
273         st8             [r30]=r29,16            // tf_length
274         st8             [r31]=r28,16            // tf_flags
275         mov             r24=rp
276         ;;
277 }
278 {       .mmi
279         st8             [r30]=r20,16            // sp
280         st8             [r31]=r21,16            // unat
281         mov             r25=pr
282         ;;
283 }
284 {       .mmi
285         st8             [r30]=r10,16            // rp (syscall caller)
286         st8             [r31]=r25,16            // pr
287         mov             r26=ar.pfs
288         ;;
289 }
290 {       .mmi
291         st8             [r30]=r9,16             // pfs (syscall caller)
292         st8             [r31]=r18,16            // bspstore
293         sub             r27=r23,r15
294         ;;
295 }
296 {       .mmi
297         st8             [r30]=r19,16            // rnat
298         st8             [r31]=r0,16             // __spare
299         nop             0
300         ;;
301 }
302 {       .mmi
303         st8             [r30]=r17,16            // tp
304         st8             [r31]=r16,16            // rsc
305         dep             r11=-1,r11,32,2         // Set psr.cpl=3
306         ;;
307 }
308 {       .mmi
309         st8             [r30]=r22,16            // fpsr
310         st8             [r31]=r11,16            // psr
311         nop             0
312         ;;
313 }
314 {       .mmi
315         st8             [r30]=r1,16             // gp
316         st8             [r31]=r27,16            // ndirty
317         nop             0
318         ;;
319 }
320 {       .mmi
321         st8             [r30]=r26,16            // pfs (syscall stub)
322         st8             [r31]=r24,16            // rp (syscall stub)
323         nop             0
324         ;;
325 }
326 {       .mmi
327         st8             [r30]=r0,80             // ifa
328         st8             [r31]=r0,80             // isr
329         nop             0
330         ;;
331 }
332 {       .mmi
333         alloc           r14=ar.pfs,0,0,8,0
334         st8             [r30]=r8,16             // syscall number (=r15)
335         nop             0
336         ;;
337 }
338 {       .mmi
339         .mem.offset     0,0
340         st8.spill       [r31]=r32,16            // arg0 (=r16)
341         .mem.offset     8,0
342         st8.spill       [r30]=r33,16            // arg1 (=r17)
343         nop             0
344         ;;
345 }
346 {       .mmi
347         .mem.offset     16,0
348         st8.spill       [r31]=r34,16            // arg2 (=r18)
349         .mem.offset     24,0
350         st8.spill       [r30]=r35,16            // arg3 (=r19)
351         nop             0
352         ;;
353 }
354 {       .mmi
355         .mem.offset     32,0
356         st8.spill       [r31]=r36,16            // arg4 (=r20)
357         .mem.offset     40,0
358         st8.spill       [r30]=r37,16            // arg5 (=r21)
359         nop             0
360         ;;
361 }
362 {       .mmi
363         .mem.offset     48,0
364         st8.spill       [r31]=r38               // arg6 (=r22)
365         .mem.offset     56,0
366         st8.spill       [r30]=r39               // arg7 (=r23)
367         nop             0
368         ;;
369 }
370 {       .mlx
371         ssm             psr.dfh|psr.ac
372         movl            gp=__gp
373         ;;
374 }
375 1:
376 {       .mib
377         srlz.d
378         add             out0=16,sp
379         br.call.sptk    rp=syscall
380         ;;
381 }
382         .global         epc_syscall_return
383 epc_syscall_return:
384 {       .mib
385         add             out0=16,sp
386         nop             0
387         br.call.sptk    rp=do_ast
388         ;;
389 }
390 {       .mib
391         cmp4.eq         p15,p0=ERESTART,r8
392         add             r14=24,sp
393 (p15)   br.spnt         1b                      // restart syscall
394         ;;
395 }
396 {       .mmi
397         ld8             r14=[r14]               // tf_flags
398         nop             0
399         nop             0
400         ;;
401 }
402 {       .mib
403         nop             0
404         tbit.z          p15,p0=r14,0
405 (p15)   br.spnt         exception_restore
406         ;;
407 }
408 {       .mmi
409         alloc           r31=ar.pfs,0,0,0,0
410         add             r14=32,sp
411         add             r15=16,sp
412         ;;
413 }
414 {       .mmi
415         ld8             r31=[r15],24            // tf_length
416         ld8             r16=[r14],16            // sp
417         add             sp=16,sp
418         ;;
419 }
420 {       .mmi
421         ld8             r17=[r15],16            // unat (before)
422         ld8             r18=[r14],16            // rp (syscall caller)
423         add             r31=r31,sp
424         ;;
425 }
426 {       .mmi
427         ld8             r19=[r15],16            // pr
428         ld8             r20=[r14],16            // pfs (syscall caller)
429         nop             0
430         ;;
431 }
432 {       .mmi
433         ld8             r21=[r15],24            // bspstore
434         ld8             r22=[r14],24            // rnat
435         mov             pr=r19,0x1fffe
436         ;;
437 }
438 {       .mmi
439         ld8             r23=[r15],16            // tp
440         ld8             r24=[r14],16            // rsc
441         nop             0
442         ;;
443 }
444 {       .mmi
445         ld8             r25=[r15],16            // fpsr
446         ld8             r26=[r14],16            // psr
447         nop             0
448         ;;
449 }
450 {       .mmi
451         ld8             gp=[r15],16             // gp
452         ld8             r27=[r14],16            // ndirty
453         tbit.z          p14,p15=r26,34          // p14=ia64, p15=ia32
454         ;;
455 }
456 {       .mmi
457         ld8             r28=[r15],56            // pfs (syscall stub)
458         ld8             r29=[r14],56            // rp (syscall stub)
459         shl             r27=r27,16
460         ;;
461 }
462 {       .mmi
463         ld8             r8=[r15],16             // r8
464         mov             ar.rsc=r27
465         mov             b6=r29
466         ;;
467 }
468 {       .mmb
469         ld8             r9=[r14],40             // r9
470         ld8             r10=[r15],40            // r10
471 (p15)   br.spnt         epc_syscall_setup_ia32
472         ;;
473 }
474 {       .mmi
475         loadrs
476         mov             ar.k7=r31
477         mov             sp=r16
478         ;;
479 }
480 {       .mmi
481         mov             r30=ar.bspstore
482         mov             r14=ar.k5
483         mov             ar.pfs=r28
484         ;;
485 }
486 {       .mmi
487         mov             ar.bspstore=r21
488         add             r14=gw_ret-ia64_gateway_page,r14
489         dep             r30=0,r30,0,13          // 8KB aligned.
490         ;;
491 }
492 {       .mii
493         mov             ar.k6=r30
494         mov             r13=r23
495         nop             0
496 }
497 {       .mmi
498         mov             psr.l=r26
499         mov             ar.unat=r17
500         nop             0
501         ;;
502 }
503 {       .mib
504         srlz.d
505         mov             b7=r14
506         br.ret.sptk     b7
507         ;;
508 }
509 epc_syscall_setup_ia32:
510 {       .mmi
511         loadrs
512         mov             ar.k7=r31
513         mov             sp=r16
514         ;;
515 }
516 {       .mmi
517         mov             r30=ar.bspstore
518         ;;
519         mov             ar.unat=r17
520         dep             r30=0,r30,0,13          // 8KB aligned
521         ;;
522 }
523 {       .mmi
524         mov             ar.k6=r30
525         mov             ar.bspstore=r21
526         mov             r11=r0
527         ;;
528 }
529 {       .mmi
530         ld8             r16=[r14],64
531         ld8             r17=[r15],80
532         mov             r13=r0
533         ;;
534 }
535  
536         ld8             r24=[r14],32
537         ld8             r27=[r15],16
538         ;;
539         ld8             r28=[r14],16
540         ld8             r29=[r15],16
541         ;;
542         ld8             r30=[r14],40
543         ld8             r31=[r15],40
544         ;;
545
546 {       .mmi
547         ld8             r2=[r14]
548         ld8             r3=[r15]
549         mov             r14=r0
550         ;;
551 }
552 {       .mmi
553         mov             ar.csd=r2
554         mov             ar.ssd=r3
555         mov             r15=r0
556         ;;
557 }
558
559         mov             r2=ar.k5
560         mov             psr.l=r26
561         ;;
562         srlz.d
563         add             r2=gw_ret_ia32-ia64_gateway_page,r2
564         ;;
565         mov             ar.rsc=0
566         mov             b7=r2
567         br.ret.sptk     b7
568         ;;
569 END(epc_syscall)