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