]> bbs.cooldavid.org Git - net-next-2.6.git/blob - arch/alpha/kernel/entry.S
a3e9cd85cfee38d1cf08d7e80d79a84c678675c2
[net-next-2.6.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         ldq     $0, 0($sp);             \
77         ldq     $1, 8($sp);             \
78 99:;                                    \
79         ldq     $19, 72($sp);           \
80         ldq     $20, 80($sp);           \
81         ldq     $21, 88($sp);           \
82         ldq     $22, 96($sp);           \
83         ldq     $23, 104($sp);          \
84         ldq     $24, 112($sp);          \
85         ldq     $25, 120($sp);          \
86         ldq     $26, 128($sp);          \
87         ldq     $27, 136($sp);          \
88         ldq     $28, 144($sp);          \
89         addq    $sp, SP_OFF, $sp
90
91 /*
92  * Non-syscall kernel entry points.
93  */
94
95         .align  4
96         .globl  entInt
97         .ent    entInt
98 entInt:
99         SAVE_ALL
100         lda     $8, 0x3fff
101         lda     $26, ret_from_sys_call
102         bic     $sp, $8, $8
103         mov     $sp, $19
104         jsr     $31, do_entInt
105 .end entInt
106
107         .align  4
108         .globl  entArith
109         .ent    entArith
110 entArith:
111         SAVE_ALL
112         lda     $8, 0x3fff
113         lda     $26, ret_from_sys_call
114         bic     $sp, $8, $8
115         mov     $sp, $18
116         jsr     $31, do_entArith
117 .end entArith
118
119         .align  4
120         .globl  entMM
121         .ent    entMM
122 entMM:
123         SAVE_ALL
124 /* save $9 - $15 so the inline exception code can manipulate them.  */
125         subq    $sp, 56, $sp
126         stq     $9, 0($sp)
127         stq     $10, 8($sp)
128         stq     $11, 16($sp)
129         stq     $12, 24($sp)
130         stq     $13, 32($sp)
131         stq     $14, 40($sp)
132         stq     $15, 48($sp)
133         addq    $sp, 56, $19
134 /* handle the fault */
135         lda     $8, 0x3fff
136         bic     $sp, $8, $8
137         jsr     $26, do_page_fault
138 /* reload the registers after the exception code played.  */
139         ldq     $9, 0($sp)
140         ldq     $10, 8($sp)
141         ldq     $11, 16($sp)
142         ldq     $12, 24($sp)
143         ldq     $13, 32($sp)
144         ldq     $14, 40($sp)
145         ldq     $15, 48($sp)
146         addq    $sp, 56, $sp
147 /* finish up the syscall as normal.  */
148         br      ret_from_sys_call
149 .end entMM
150
151         .align  4
152         .globl  entIF
153         .ent    entIF
154 entIF:
155         SAVE_ALL
156         lda     $8, 0x3fff
157         lda     $26, ret_from_sys_call
158         bic     $sp, $8, $8
159         mov     $sp, $17
160         jsr     $31, do_entIF
161 .end entIF
162
163         .align  4
164         .globl  entUna
165         .ent    entUna
166 entUna:
167         lda     $sp, -256($sp)
168         stq     $0, 0($sp)
169         ldq     $0, 256($sp)    /* get PS */
170         stq     $1, 8($sp)
171         stq     $2, 16($sp)
172         stq     $3, 24($sp)
173         and     $0, 8, $0               /* user mode? */
174         stq     $4, 32($sp)
175         bne     $0, entUnaUser  /* yup -> do user-level unaligned fault */
176         stq     $5, 40($sp)
177         stq     $6, 48($sp)
178         stq     $7, 56($sp)
179         stq     $8, 64($sp)
180         stq     $9, 72($sp)
181         stq     $10, 80($sp)
182         stq     $11, 88($sp)
183         stq     $12, 96($sp)
184         stq     $13, 104($sp)
185         stq     $14, 112($sp)
186         stq     $15, 120($sp)
187         /* 16-18 PAL-saved */
188         stq     $19, 152($sp)
189         stq     $20, 160($sp)
190         stq     $21, 168($sp)
191         stq     $22, 176($sp)
192         stq     $23, 184($sp)
193         stq     $24, 192($sp)
194         stq     $25, 200($sp)
195         stq     $26, 208($sp)
196         stq     $27, 216($sp)
197         stq     $28, 224($sp)
198         mov     $sp, $19
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, $16
395         br      $1, do_switch_stack
396         mov     $sp, $17
397         mov     $5, $18
398         jsr     $26, do_notify_resume
399         bsr     $1, undo_switch_stack
400         br      restore_all
401 .end work_pending
402
403 /*
404  * PTRACE syscall handler
405  */
406
407         .align  4
408         .ent    strace
409 strace:
410         /* set up signal stack, call syscall_trace */
411         bsr     $1, do_switch_stack
412         jsr     $26, syscall_trace
413         bsr     $1, undo_switch_stack
414
415         /* get the system call number and the arguments back.. */
416         ldq     $0, 0($sp)
417         ldq     $16, SP_OFF+24($sp)
418         ldq     $17, SP_OFF+32($sp)
419         ldq     $18, SP_OFF+40($sp)
420         ldq     $19, 72($sp)
421         ldq     $20, 80($sp)
422         ldq     $21, 88($sp)
423
424         /* get the system call pointer.. */
425         lda     $1, NR_SYSCALLS($31)
426         lda     $2, sys_call_table
427         lda     $27, alpha_ni_syscall
428         cmpult  $0, $1, $1
429         s8addq  $0, $2, $2
430         beq     $1, 1f
431         ldq     $27, 0($2)
432 1:      jsr     $26, ($27), sys_gettimeofday
433 ret_from_straced:
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  * kernel_execve(path, argv, envp)
659  */
660         .align  4
661         .globl  kernel_execve
662         .ent    kernel_execve
663 kernel_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 kernel_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         lda     $9, ret_from_straced
762         cmpult  $26, $9, $9
763         mov     $sp, $17
764         lda     $18, -SWITCH_STACK_SIZE($sp)
765         lda     $sp, -SWITCH_STACK_SIZE($sp)
766         jsr     $26, do_sigreturn
767         bne     $9, 1f
768         jsr     $26, syscall_trace
769 1:      br      $1, undo_switch_stack
770         br      ret_from_sys_call
771 .end sys_sigreturn
772
773         .align  4
774         .globl  sys_rt_sigreturn
775         .ent    sys_rt_sigreturn
776 sys_rt_sigreturn:
777         .prologue 0
778         lda     $9, ret_from_straced
779         cmpult  $26, $9, $9
780         mov     $sp, $17
781         lda     $18, -SWITCH_STACK_SIZE($sp)
782         lda     $sp, -SWITCH_STACK_SIZE($sp)
783         jsr     $26, do_rt_sigreturn
784         bne     $9, 1f
785         jsr     $26, syscall_trace
786 1:      br      $1, undo_switch_stack
787         br      ret_from_sys_call
788 .end sys_rt_sigreturn
789
790         .align  4
791         .globl  sys_sethae
792         .ent    sys_sethae
793 sys_sethae:
794         .prologue 0
795         stq     $16, 152($sp)
796         ret
797 .end sys_sethae
798
799         .align  4
800         .globl  osf_getpriority
801         .ent    osf_getpriority
802 osf_getpriority:
803         lda     $sp, -16($sp)
804         stq     $26, 0($sp)
805         .prologue 0
806
807         jsr     $26, sys_getpriority
808
809         ldq     $26, 0($sp)
810         blt     $0, 1f
811
812         /* Return value is the unbiased priority, i.e. 20 - prio.
813            This does result in negative return values, so signal
814            no error by writing into the R0 slot.  */
815         lda     $1, 20
816         stq     $31, 16($sp)
817         subl    $1, $0, $0
818         unop
819
820 1:      lda     $sp, 16($sp)
821         ret
822 .end osf_getpriority
823
824         .align  4
825         .globl  sys_getxuid
826         .ent    sys_getxuid
827 sys_getxuid:
828         .prologue 0
829         ldq     $2, TI_TASK($8)
830         ldq     $3, TASK_CRED($2)
831         ldl     $0, CRED_UID($3)
832         ldl     $1, CRED_EUID($3)
833         stq     $1, 80($sp)
834         ret
835 .end sys_getxuid
836
837         .align  4
838         .globl  sys_getxgid
839         .ent    sys_getxgid
840 sys_getxgid:
841         .prologue 0
842         ldq     $2, TI_TASK($8)
843         ldq     $3, TASK_CRED($2)
844         ldl     $0, CRED_GID($3)
845         ldl     $1, CRED_EGID($3)
846         stq     $1, 80($sp)
847         ret
848 .end sys_getxgid
849
850         .align  4
851         .globl  sys_getxpid
852         .ent    sys_getxpid
853 sys_getxpid:
854         .prologue 0
855         ldq     $2, TI_TASK($8)
856
857         /* See linux/kernel/timer.c sys_getppid for discussion
858            about this loop.  */
859         ldq     $3, TASK_GROUP_LEADER($2)
860         ldq     $4, TASK_REAL_PARENT($3)
861         ldl     $0, TASK_TGID($2)
862 1:      ldl     $1, TASK_TGID($4)
863 #ifdef CONFIG_SMP
864         mov     $4, $5
865         mb
866         ldq     $3, TASK_GROUP_LEADER($2)
867         ldq     $4, TASK_REAL_PARENT($3)
868         cmpeq   $4, $5, $5
869         beq     $5, 1b
870 #endif
871         stq     $1, 80($sp)
872         ret
873 .end sys_getxpid
874
875         .align  4
876         .globl  sys_alpha_pipe
877         .ent    sys_alpha_pipe
878 sys_alpha_pipe:
879         lda     $sp, -16($sp)
880         stq     $26, 0($sp)
881         .prologue 0
882
883         mov     $31, $17
884         lda     $16, 8($sp)
885         jsr     $26, do_pipe_flags
886
887         ldq     $26, 0($sp)
888         bne     $0, 1f
889
890         /* The return values are in $0 and $20.  */
891         ldl     $1, 12($sp)
892         ldl     $0, 8($sp)
893
894         stq     $1, 80+16($sp)
895 1:      lda     $sp, 16($sp)
896         ret
897 .end sys_alpha_pipe
898
899         .align  4
900         .globl  sys_execve
901         .ent    sys_execve
902 sys_execve:
903         .prologue 0
904         mov     $sp, $19
905         jmp     $31, do_sys_execve
906 .end sys_execve
907
908         .align  4
909         .globl  osf_sigprocmask
910         .ent    osf_sigprocmask
911 osf_sigprocmask:
912         .prologue 0
913         mov     $sp, $18
914         jmp     $31, sys_osf_sigprocmask
915 .end osf_sigprocmask
916
917         .align  4
918         .globl  alpha_ni_syscall
919         .ent    alpha_ni_syscall
920 alpha_ni_syscall:
921         .prologue 0
922         /* Special because it also implements overflow handling via
923            syscall number 0.  And if you recall, zero is a special
924            trigger for "not an error".  Store large non-zero there.  */
925         lda     $0, -ENOSYS
926         unop
927         stq     $0, 0($sp)
928         ret
929 .end alpha_ni_syscall