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