22b0c4d414a7cec4413d78be35482e91f6c4a2f2
[linux-3.10.git] / arch / alpha / kernel / entry.S
1 /*
2  * arch/alpha/kernel/entry.S
3  *
4  * Kernel entry-points.
5  */
6
7 #include <asm/asm-offsets.h>
8 #include <asm/thread_info.h>
9 #include <asm/pal.h>
10 #include <asm/errno.h>
11 #include <asm/unistd.h>
12
13         .text
14         .set noat
15
16 /* Stack offsets.  */
17 #define SP_OFF                  184
18 #define SWITCH_STACK_SIZE       320
19
20 /*
21  * This defines the normal kernel pt-regs layout.
22  *
23  * regs 9-15 preserved by C code
24  * regs 16-18 saved by PAL-code
25  * regs 29-30 saved and set up by PAL-code
26  * JRP - Save regs 16-18 in a special area of the stack, so that
27  * the palcode-provided values are available to the signal handler.
28  */
29
30 #define SAVE_ALL                        \
31         subq    $sp, SP_OFF, $sp;       \
32         stq     $0, 0($sp);             \
33         stq     $1, 8($sp);             \
34         stq     $2, 16($sp);            \
35         stq     $3, 24($sp);            \
36         stq     $4, 32($sp);            \
37         stq     $28, 144($sp);          \
38         lda     $2, alpha_mv;           \
39         stq     $5, 40($sp);            \
40         stq     $6, 48($sp);            \
41         stq     $7, 56($sp);            \
42         stq     $8, 64($sp);            \
43         stq     $19, 72($sp);           \
44         stq     $20, 80($sp);           \
45         stq     $21, 88($sp);           \
46         ldq     $2, HAE_CACHE($2);      \
47         stq     $22, 96($sp);           \
48         stq     $23, 104($sp);          \
49         stq     $24, 112($sp);          \
50         stq     $25, 120($sp);          \
51         stq     $26, 128($sp);          \
52         stq     $27, 136($sp);          \
53         stq     $2, 152($sp);           \
54         stq     $16, 160($sp);          \
55         stq     $17, 168($sp);          \
56         stq     $18, 176($sp)
57
58 #define RESTORE_ALL                     \
59         lda     $19, alpha_mv;          \
60         ldq     $0, 0($sp);             \
61         ldq     $1, 8($sp);             \
62         ldq     $2, 16($sp);            \
63         ldq     $3, 24($sp);            \
64         ldq     $21, 152($sp);          \
65         ldq     $20, HAE_CACHE($19);    \
66         ldq     $4, 32($sp);            \
67         ldq     $5, 40($sp);            \
68         ldq     $6, 48($sp);            \
69         ldq     $7, 56($sp);            \
70         subq    $20, $21, $20;          \
71         ldq     $8, 64($sp);            \
72         beq     $20, 99f;               \
73         ldq     $20, HAE_REG($19);      \
74         stq     $21, HAE_CACHE($19);    \
75         stq     $21, 0($20);            \
76 99:;                                    \
77         ldq     $19, 72($sp);           \
78         ldq     $20, 80($sp);           \
79         ldq     $21, 88($sp);           \
80         ldq     $22, 96($sp);           \
81         ldq     $23, 104($sp);          \
82         ldq     $24, 112($sp);          \
83         ldq     $25, 120($sp);          \
84         ldq     $26, 128($sp);          \
85         ldq     $27, 136($sp);          \
86         ldq     $28, 144($sp);          \
87         addq    $sp, SP_OFF, $sp
88
89 /*
90  * Non-syscall kernel entry points.
91  */
92
93         .align  4
94         .globl  entInt
95         .ent    entInt
96 entInt:
97         SAVE_ALL
98         lda     $8, 0x3fff
99         lda     $26, ret_from_sys_call
100         bic     $sp, $8, $8
101         mov     $sp, $19
102         jsr     $31, do_entInt
103 .end entInt
104
105         .align  4
106         .globl  entArith
107         .ent    entArith
108 entArith:
109         SAVE_ALL
110         lda     $8, 0x3fff
111         lda     $26, ret_from_sys_call
112         bic     $sp, $8, $8
113         mov     $sp, $18
114         jsr     $31, do_entArith
115 .end entArith
116
117         .align  4
118         .globl  entMM
119         .ent    entMM
120 entMM:
121         SAVE_ALL
122 /* save $9 - $15 so the inline exception code can manipulate them.  */
123         subq    $sp, 56, $sp
124         stq     $9, 0($sp)
125         stq     $10, 8($sp)
126         stq     $11, 16($sp)
127         stq     $12, 24($sp)
128         stq     $13, 32($sp)
129         stq     $14, 40($sp)
130         stq     $15, 48($sp)
131         addq    $sp, 56, $19
132 /* handle the fault */
133         lda     $8, 0x3fff
134         bic     $sp, $8, $8
135         jsr     $26, do_page_fault
136 /* reload the registers after the exception code played.  */
137         ldq     $9, 0($sp)
138         ldq     $10, 8($sp)
139         ldq     $11, 16($sp)
140         ldq     $12, 24($sp)
141         ldq     $13, 32($sp)
142         ldq     $14, 40($sp)
143         ldq     $15, 48($sp)
144         addq    $sp, 56, $sp
145 /* finish up the syscall as normal.  */
146         br      ret_from_sys_call
147 .end entMM
148
149         .align  4
150         .globl  entIF
151         .ent    entIF
152 entIF:
153         SAVE_ALL
154         lda     $8, 0x3fff
155         lda     $26, ret_from_sys_call
156         bic     $sp, $8, $8
157         mov     $sp, $17
158         jsr     $31, do_entIF
159 .end entIF
160
161         .align  4
162         .globl  entUna
163         .ent    entUna
164 entUna:
165         lda     $sp, -256($sp)
166         stq     $0, 0($sp)
167         ldq     $0, 256($sp)    /* get PS */
168         stq     $1, 8($sp)
169         stq     $2, 16($sp)
170         stq     $3, 24($sp)
171         and     $0, 8, $0               /* user mode? */
172         stq     $4, 32($sp)
173         bne     $0, entUnaUser  /* yup -> do user-level unaligned fault */
174         stq     $5, 40($sp)
175         stq     $6, 48($sp)
176         stq     $7, 56($sp)
177         stq     $8, 64($sp)
178         stq     $9, 72($sp)
179         stq     $10, 80($sp)
180         stq     $11, 88($sp)
181         stq     $12, 96($sp)
182         stq     $13, 104($sp)
183         stq     $14, 112($sp)
184         stq     $15, 120($sp)
185         /* 16-18 PAL-saved */
186         stq     $19, 152($sp)
187         stq     $20, 160($sp)
188         stq     $21, 168($sp)
189         stq     $22, 176($sp)
190         stq     $23, 184($sp)
191         stq     $24, 192($sp)
192         stq     $25, 200($sp)
193         stq     $26, 208($sp)
194         stq     $27, 216($sp)
195         stq     $28, 224($sp)
196         mov     $sp, $19
197         stq     $gp, 232($sp)
198         lda     $8, 0x3fff
199         stq     $31, 248($sp)
200         bic     $sp, $8, $8
201         jsr     $26, do_entUna
202         ldq     $0, 0($sp)
203         ldq     $1, 8($sp)
204         ldq     $2, 16($sp)
205         ldq     $3, 24($sp)
206         ldq     $4, 32($sp)
207         ldq     $5, 40($sp)
208         ldq     $6, 48($sp)
209         ldq     $7, 56($sp)
210         ldq     $8, 64($sp)
211         ldq     $9, 72($sp)
212         ldq     $10, 80($sp)
213         ldq     $11, 88($sp)
214         ldq     $12, 96($sp)
215         ldq     $13, 104($sp)
216         ldq     $14, 112($sp)
217         ldq     $15, 120($sp)
218         /* 16-18 PAL-saved */
219         ldq     $19, 152($sp)
220         ldq     $20, 160($sp)
221         ldq     $21, 168($sp)
222         ldq     $22, 176($sp)
223         ldq     $23, 184($sp)
224         ldq     $24, 192($sp)
225         ldq     $25, 200($sp)
226         ldq     $26, 208($sp)
227         ldq     $27, 216($sp)
228         ldq     $28, 224($sp)
229         ldq     $gp, 232($sp)
230         lda     $sp, 256($sp)
231         call_pal PAL_rti
232 .end entUna
233
234         .align  4
235         .ent    entUnaUser
236 entUnaUser:
237         ldq     $0, 0($sp)      /* restore original $0 */
238         lda     $sp, 256($sp)   /* pop entUna's stack frame */
239         SAVE_ALL                /* setup normal kernel stack */
240         lda     $sp, -56($sp)
241         stq     $9, 0($sp)
242         stq     $10, 8($sp)
243         stq     $11, 16($sp)
244         stq     $12, 24($sp)
245         stq     $13, 32($sp)
246         stq     $14, 40($sp)
247         stq     $15, 48($sp)
248         lda     $8, 0x3fff
249         addq    $sp, 56, $19
250         bic     $sp, $8, $8
251         jsr     $26, do_entUnaUser
252         ldq     $9, 0($sp)
253         ldq     $10, 8($sp)
254         ldq     $11, 16($sp)
255         ldq     $12, 24($sp)
256         ldq     $13, 32($sp)
257         ldq     $14, 40($sp)
258         ldq     $15, 48($sp)
259         lda     $sp, 56($sp)
260         br      ret_from_sys_call
261 .end entUnaUser
262
263         .align  4
264         .globl  entDbg
265         .ent    entDbg
266 entDbg:
267         SAVE_ALL
268         lda     $8, 0x3fff
269         lda     $26, ret_from_sys_call
270         bic     $sp, $8, $8
271         mov     $sp, $16
272         jsr     $31, do_entDbg
273 .end entDbg
274 \f
275 /*
276  * The system call entry point is special.  Most importantly, it looks
277  * like a function call to userspace as far as clobbered registers.  We
278  * do preserve the argument registers (for syscall restarts) and $26
279  * (for leaf syscall functions).
280  *
281  * So much for theory.  We don't take advantage of this yet.
282  *
283  * Note that a0-a2 are not saved by PALcode as with the other entry points.
284  */
285
286         .align  4
287         .globl  entSys
288         .globl  ret_from_sys_call
289         .ent    entSys
290 entSys:
291         SAVE_ALL
292         lda     $8, 0x3fff
293         bic     $sp, $8, $8
294         lda     $4, NR_SYSCALLS($31)
295         stq     $16, SP_OFF+24($sp)
296         lda     $5, sys_call_table
297         lda     $27, sys_ni_syscall
298         cmpult  $0, $4, $4
299         ldl     $3, TI_FLAGS($8)
300         stq     $17, SP_OFF+32($sp)
301         s8addq  $0, $5, $5
302         stq     $18, SP_OFF+40($sp)
303         blbs    $3, strace
304         beq     $4, 1f
305         ldq     $27, 0($5)
306 1:      jsr     $26, ($27), alpha_ni_syscall
307         ldgp    $gp, 0($26)
308         blt     $0, $syscall_error      /* the call failed */
309         stq     $0, 0($sp)
310         stq     $31, 72($sp)            /* a3=0 => no error */
311
312         .align  4
313 ret_from_sys_call:
314         cmovne  $26, 0, $19             /* $19 = 0 => non-restartable */
315         ldq     $0, SP_OFF($sp)
316         and     $0, 8, $0
317         beq     $0, ret_to_kernel
318 ret_to_user:
319         /* Make sure need_resched and sigpending don't change between
320                 sampling and the rti.  */
321         lda     $16, 7
322         call_pal PAL_swpipl
323         ldl     $5, TI_FLAGS($8)
324         and     $5, _TIF_WORK_MASK, $2
325         bne     $2, work_pending
326 restore_all:
327         RESTORE_ALL
328         call_pal PAL_rti
329
330 ret_to_kernel:
331         lda     $16, 7
332         call_pal PAL_swpipl
333         br restore_all
334
335         .align 3
336 $syscall_error:
337         /*
338          * Some system calls (e.g., ptrace) can return arbitrary
339          * values which might normally be mistaken as error numbers.
340          * Those functions must zero $0 (v0) directly in the stack
341          * frame to indicate that a negative return value wasn't an
342          * error number..
343          */
344         ldq     $19, 0($sp)     /* old syscall nr (zero if success) */
345         beq     $19, $ret_success
346
347         ldq     $20, 72($sp)    /* .. and this a3 */
348         subq    $31, $0, $0     /* with error in v0 */
349         addq    $31, 1, $1      /* set a3 for errno return */
350         stq     $0, 0($sp)
351         mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
352         stq     $1, 72($sp)     /* a3 for return */
353         br      ret_from_sys_call
354
355 $ret_success:
356         stq     $0, 0($sp)
357         stq     $31, 72($sp)    /* a3=0 => no error */
358         br      ret_from_sys_call
359 .end entSys
360
361 /*
362  * Do all cleanup when returning from all interrupts and system calls.
363  *
364  * Arguments:
365  *       $5: TI_FLAGS.
366  *       $8: current.
367  *      $19: The old syscall number, or zero if this is not a return
368  *           from a syscall that errored and is possibly restartable.
369  *      $20: The old a3 value
370  */
371
372         .align  4
373         .ent    work_pending
374 work_pending:
375         and     $5, _TIF_NEED_RESCHED, $2
376         beq     $2, $work_notifysig
377
378 $work_resched:
379         subq    $sp, 16, $sp
380         stq     $19, 0($sp)              /* save syscall nr */
381         stq     $20, 8($sp)              /* and error indication (a3) */
382         jsr     $26, schedule
383         ldq     $19, 0($sp)
384         ldq     $20, 8($sp)
385         addq    $sp, 16, $sp
386         /* Make sure need_resched and sigpending don't change between
387                 sampling and the rti.  */
388         lda     $16, 7
389         call_pal PAL_swpipl
390         ldl     $5, TI_FLAGS($8)
391         and     $5, _TIF_WORK_MASK, $2
392         beq     $2, restore_all
393         and     $5, _TIF_NEED_RESCHED, $2
394         bne     $2, $work_resched
395
396 $work_notifysig:
397         mov     $sp, $16
398         bsr     $1, do_switch_stack
399         mov     $sp, $17
400         mov     $5, $18
401         mov     $19, $9         /* save old syscall number */
402         mov     $20, $10        /* save old a3 */
403         and     $5, _TIF_SIGPENDING, $2
404         cmovne  $2, 0, $9       /* we don't want double syscall restarts */
405         jsr     $26, do_notify_resume
406         mov     $9, $19
407         mov     $10, $20
408         bsr     $1, undo_switch_stack
409         br      ret_to_user
410 .end work_pending
411
412 /*
413  * PTRACE syscall handler
414  */
415
416         .align  4
417         .ent    strace
418 strace:
419         /* set up signal stack, call syscall_trace */
420         bsr     $1, do_switch_stack
421         jsr     $26, syscall_trace
422         bsr     $1, undo_switch_stack
423
424         /* get the system call number and the arguments back.. */
425         ldq     $0, 0($sp)
426         ldq     $16, SP_OFF+24($sp)
427         ldq     $17, SP_OFF+32($sp)
428         ldq     $18, SP_OFF+40($sp)
429         ldq     $19, 72($sp)
430         ldq     $20, 80($sp)
431         ldq     $21, 88($sp)
432
433         /* get the system call pointer.. */
434         lda     $1, NR_SYSCALLS($31)
435         lda     $2, sys_call_table
436         lda     $27, alpha_ni_syscall
437         cmpult  $0, $1, $1
438         s8addq  $0, $2, $2
439         beq     $1, 1f
440         ldq     $27, 0($2)
441 1:      jsr     $26, ($27), sys_gettimeofday
442 ret_from_straced:
443         ldgp    $gp, 0($26)
444
445         /* check return.. */
446         blt     $0, $strace_error       /* the call failed */
447         stq     $31, 72($sp)            /* a3=0 => no error */
448 $strace_success:
449         stq     $0, 0($sp)              /* save return value */
450
451         bsr     $1, do_switch_stack
452         jsr     $26, syscall_trace
453         bsr     $1, undo_switch_stack
454         br      $31, ret_from_sys_call
455
456         .align  3
457 $strace_error:
458         ldq     $19, 0($sp)     /* old syscall nr (zero if success) */
459         beq     $19, $strace_success
460         ldq     $20, 72($sp)    /* .. and this a3 */
461
462         subq    $31, $0, $0     /* with error in v0 */
463         addq    $31, 1, $1      /* set a3 for errno return */
464         stq     $0, 0($sp)
465         stq     $1, 72($sp)     /* a3 for return */
466
467         bsr     $1, do_switch_stack
468         mov     $19, $9         /* save old syscall number */
469         mov     $20, $10        /* save old a3 */
470         jsr     $26, syscall_trace
471         mov     $9, $19
472         mov     $10, $20
473         bsr     $1, undo_switch_stack
474
475         mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
476         br      ret_from_sys_call
477 .end strace
478 \f
479 /*
480  * Save and restore the switch stack -- aka the balance of the user context.
481  */
482
483         .align  4
484         .ent    do_switch_stack
485 do_switch_stack:
486         lda     $sp, -SWITCH_STACK_SIZE($sp)
487         stq     $9, 0($sp)
488         stq     $10, 8($sp)
489         stq     $11, 16($sp)
490         stq     $12, 24($sp)
491         stq     $13, 32($sp)
492         stq     $14, 40($sp)
493         stq     $15, 48($sp)
494         stq     $26, 56($sp)
495         stt     $f0, 64($sp)
496         stt     $f1, 72($sp)
497         stt     $f2, 80($sp)
498         stt     $f3, 88($sp)
499         stt     $f4, 96($sp)
500         stt     $f5, 104($sp)
501         stt     $f6, 112($sp)
502         stt     $f7, 120($sp)
503         stt     $f8, 128($sp)
504         stt     $f9, 136($sp)
505         stt     $f10, 144($sp)
506         stt     $f11, 152($sp)
507         stt     $f12, 160($sp)
508         stt     $f13, 168($sp)
509         stt     $f14, 176($sp)
510         stt     $f15, 184($sp)
511         stt     $f16, 192($sp)
512         stt     $f17, 200($sp)
513         stt     $f18, 208($sp)
514         stt     $f19, 216($sp)
515         stt     $f20, 224($sp)
516         stt     $f21, 232($sp)
517         stt     $f22, 240($sp)
518         stt     $f23, 248($sp)
519         stt     $f24, 256($sp)
520         stt     $f25, 264($sp)
521         stt     $f26, 272($sp)
522         stt     $f27, 280($sp)
523         mf_fpcr $f0             # get fpcr
524         stt     $f28, 288($sp)
525         stt     $f29, 296($sp)
526         stt     $f30, 304($sp)
527         stt     $f0, 312($sp)   # save fpcr in slot of $f31
528         ldt     $f0, 64($sp)    # dont let "do_switch_stack" change fp state.
529         ret     $31, ($1), 1
530 .end do_switch_stack
531
532         .align  4
533         .ent    undo_switch_stack
534 undo_switch_stack:
535         ldq     $9, 0($sp)
536         ldq     $10, 8($sp)
537         ldq     $11, 16($sp)
538         ldq     $12, 24($sp)
539         ldq     $13, 32($sp)
540         ldq     $14, 40($sp)
541         ldq     $15, 48($sp)
542         ldq     $26, 56($sp)
543         ldt     $f30, 312($sp)  # get saved fpcr
544         ldt     $f0, 64($sp)
545         ldt     $f1, 72($sp)
546         ldt     $f2, 80($sp)
547         ldt     $f3, 88($sp)
548         mt_fpcr $f30            # install saved fpcr
549         ldt     $f4, 96($sp)
550         ldt     $f5, 104($sp)
551         ldt     $f6, 112($sp)
552         ldt     $f7, 120($sp)
553         ldt     $f8, 128($sp)
554         ldt     $f9, 136($sp)
555         ldt     $f10, 144($sp)
556         ldt     $f11, 152($sp)
557         ldt     $f12, 160($sp)
558         ldt     $f13, 168($sp)
559         ldt     $f14, 176($sp)
560         ldt     $f15, 184($sp)
561         ldt     $f16, 192($sp)
562         ldt     $f17, 200($sp)
563         ldt     $f18, 208($sp)
564         ldt     $f19, 216($sp)
565         ldt     $f20, 224($sp)
566         ldt     $f21, 232($sp)
567         ldt     $f22, 240($sp)
568         ldt     $f23, 248($sp)
569         ldt     $f24, 256($sp)
570         ldt     $f25, 264($sp)
571         ldt     $f26, 272($sp)
572         ldt     $f27, 280($sp)
573         ldt     $f28, 288($sp)
574         ldt     $f29, 296($sp)
575         ldt     $f30, 304($sp)
576         lda     $sp, SWITCH_STACK_SIZE($sp)
577         ret     $31, ($1), 1
578 .end undo_switch_stack
579 \f
580 /*
581  * The meat of the context switch code.
582  */
583
584         .align  4
585         .globl  alpha_switch_to
586         .ent    alpha_switch_to
587 alpha_switch_to:
588         .prologue 0
589         bsr     $1, do_switch_stack
590         call_pal PAL_swpctx
591         lda     $8, 0x3fff
592         bsr     $1, undo_switch_stack
593         bic     $sp, $8, $8
594         mov     $17, $0
595         ret
596 .end alpha_switch_to
597
598 /*
599  * New processes begin life here.
600  */
601
602         .globl  ret_from_fork
603         .align  4
604         .ent    ret_from_fork
605 ret_from_fork:
606         lda     $26, ret_from_sys_call
607         mov     $17, $16
608         jmp     $31, schedule_tail
609 .end ret_from_fork
610
611 /*
612  * kernel_thread(fn, arg, clone_flags)
613  */
614         .align 4
615         .globl  kernel_thread
616         .ent    kernel_thread
617 kernel_thread:
618         /* We can be called from a module.  */
619         ldgp    $gp, 0($27)
620         .prologue 1
621         subq    $sp, SP_OFF+6*8, $sp
622         br      $1, 2f          /* load start address */
623
624         /* We've now "returned" from a fake system call.  */
625         unop
626         blt     $0, 1f          /* error?  */
627         ldi     $1, 0x3fff
628         beq     $20, 1f         /* parent or child?  */
629
630         bic     $sp, $1, $8     /* in child.  */
631         jsr     $26, ($27)
632         ldgp    $gp, 0($26)
633         mov     $0, $16
634         mov     $31, $26
635         jmp     $31, sys_exit
636
637 1:      ret                     /* in parent.  */
638
639         .align 4
640 2:      /* Fake a system call stack frame, as we can't do system calls
641            from kernel space.  Note that we store FN and ARG as they
642            need to be set up in the child for the call.  Also store $8
643            and $26 for use in the parent.  */
644         stq     $31, SP_OFF($sp)        /* ps */
645         stq     $1, SP_OFF+8($sp)       /* pc */
646         stq     $gp, SP_OFF+16($sp)     /* gp */
647         stq     $16, 136($sp)           /* $27; FN for child */
648         stq     $17, SP_OFF+24($sp)     /* $16; ARG for child */
649         stq     $8, 64($sp)             /* $8 */
650         stq     $26, 128($sp)           /* $26 */
651         /* Avoid the HAE being gratuitously wrong, to avoid restoring it.  */
652         ldq     $2, alpha_mv+HAE_CACHE
653         stq     $2, 152($sp)            /* HAE */
654
655         /* Shuffle FLAGS to the front; add CLONE_VM.  */
656         ldi     $1, CLONE_VM|CLONE_UNTRACED
657         or      $18, $1, $16
658         bsr     $26, sys_clone
659
660         /* We don't actually care for a3 success widgetry in the kernel.
661            Not for positive errno values.  */
662         stq     $0, 0($sp)              /* $0 */
663         br      ret_to_kernel
664 .end kernel_thread
665
666 /*
667  * kernel_execve(path, argv, envp)
668  */
669         .align  4
670         .globl  kernel_execve
671         .ent    kernel_execve
672 kernel_execve:
673         /* We can be called from a module.  */
674         ldgp    $gp, 0($27)
675         lda     $sp, -(32+SIZEOF_PT_REGS+8)($sp)
676         .frame  $sp, 32+SIZEOF_PT_REGS+8, $26, 0
677         stq     $26, 0($sp)
678         stq     $16, 8($sp)
679         stq     $17, 16($sp)
680         stq     $18, 24($sp)
681         .prologue 1
682
683         lda     $16, 32($sp)
684         lda     $17, 0
685         lda     $18, SIZEOF_PT_REGS
686         bsr     $26, memset             !samegp
687
688         /* Avoid the HAE being gratuitously wrong, which would cause us
689            to do the whole turn off interrupts thing and restore it.  */
690         ldq     $2, alpha_mv+HAE_CACHE
691         stq     $2, 152+32($sp)
692
693         ldq     $16, 8($sp)
694         ldq     $17, 16($sp)
695         ldq     $18, 24($sp)
696         lda     $19, 32($sp)
697         bsr     $26, do_execve          !samegp
698
699         ldq     $26, 0($sp)
700         bne     $0, 1f                  /* error! */
701
702         /* Move the temporary pt_regs struct from its current location
703            to the top of the kernel stack frame.  See copy_thread for
704            details for a normal process.  */
705         lda     $16, 0x4000 - SIZEOF_PT_REGS($8)
706         lda     $17, 32($sp)
707         lda     $18, SIZEOF_PT_REGS
708         bsr     $26, memmove            !samegp
709
710         /* Take that over as our new stack frame and visit userland!  */
711         lda     $sp, 0x4000 - SIZEOF_PT_REGS($8)
712         br      $31, ret_from_sys_call
713
714 1:      lda     $sp, 32+SIZEOF_PT_REGS+8($sp)
715         ret
716 .end kernel_execve
717
718 \f
719 /*
720  * Special system calls.  Most of these are special in that they either
721  * have to play switch_stack games or in some way use the pt_regs struct.
722  */
723         .align  4
724         .globl  sys_fork
725         .ent    sys_fork
726 sys_fork:
727         .prologue 0
728         mov     $sp, $21
729         bsr     $1, do_switch_stack
730         bis     $31, SIGCHLD, $16
731         mov     $31, $17
732         mov     $31, $18
733         mov     $31, $19
734         mov     $31, $20
735         jsr     $26, alpha_clone
736         bsr     $1, undo_switch_stack
737         ret
738 .end sys_fork
739
740         .align  4
741         .globl  sys_clone
742         .ent    sys_clone
743 sys_clone:
744         .prologue 0
745         mov     $sp, $21
746         bsr     $1, do_switch_stack
747         /* $16, $17, $18, $19, $20 come from the user.  */
748         jsr     $26, alpha_clone
749         bsr     $1, undo_switch_stack
750         ret
751 .end sys_clone
752
753         .align  4
754         .globl  sys_vfork
755         .ent    sys_vfork
756 sys_vfork:
757         .prologue 0
758         mov     $sp, $16
759         bsr     $1, do_switch_stack
760         jsr     $26, alpha_vfork
761         bsr     $1, undo_switch_stack
762         ret
763 .end sys_vfork
764
765         .align  4
766         .globl  sys_sigreturn
767         .ent    sys_sigreturn
768 sys_sigreturn:
769         .prologue 0
770         lda     $9, ret_from_straced
771         cmpult  $26, $9, $9
772         mov     $sp, $17
773         lda     $18, -SWITCH_STACK_SIZE($sp)
774         lda     $sp, -SWITCH_STACK_SIZE($sp)
775         jsr     $26, do_sigreturn
776         bne     $9, 1f
777         jsr     $26, syscall_trace
778 1:      br      $1, undo_switch_stack
779         br      ret_from_sys_call
780 .end sys_sigreturn
781
782         .align  4
783         .globl  sys_rt_sigreturn
784         .ent    sys_rt_sigreturn
785 sys_rt_sigreturn:
786         .prologue 0
787         lda     $9, ret_from_straced
788         cmpult  $26, $9, $9
789         mov     $sp, $17
790         lda     $18, -SWITCH_STACK_SIZE($sp)
791         lda     $sp, -SWITCH_STACK_SIZE($sp)
792         jsr     $26, do_rt_sigreturn
793         bne     $9, 1f
794         jsr     $26, syscall_trace
795 1:      br      $1, undo_switch_stack
796         br      ret_from_sys_call
797 .end sys_rt_sigreturn
798
799         .align  4
800         .globl  sys_execve
801         .ent    sys_execve
802 sys_execve:
803         .prologue 0
804         mov     $sp, $19
805         jmp     $31, do_sys_execve
806 .end sys_execve
807
808         .align  4
809         .globl  alpha_ni_syscall
810         .ent    alpha_ni_syscall
811 alpha_ni_syscall:
812         .prologue 0
813         /* Special because it also implements overflow handling via
814            syscall number 0.  And if you recall, zero is a special
815            trigger for "not an error".  Store large non-zero there.  */
816         lda     $0, -ENOSYS
817         unop
818         stq     $0, 0($sp)
819         ret
820 .end alpha_ni_syscall