Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[sfrench/cifs-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, $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  * 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         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_GROUP_LEADER($2)
882         ldq     $4, TASK_REAL_PARENT($3)
883         ldl     $0, TASK_TGID($2)
884 1:      ldl     $1, TASK_TGID($4)
885 #ifdef CONFIG_SMP
886         mov     $4, $5
887         mb
888         ldq     $3, TASK_GROUP_LEADER($2)
889         ldq     $4, TASK_REAL_PARENT($3)
890         cmpeq   $4, $5, $5
891         beq     $5, 1b
892 #endif
893         stq     $1, 80($sp)
894         ret
895 .end sys_getxpid
896
897         .align  4
898         .globl  sys_pipe
899         .ent    sys_pipe
900 sys_pipe:
901         lda     $sp, -16($sp)
902         stq     $26, 0($sp)
903         .prologue 0
904
905         lda     $16, 8($sp)
906         jsr     $26, do_pipe
907
908         ldq     $26, 0($sp)
909         bne     $0, 1f
910
911         /* The return values are in $0 and $20.  */
912         ldl     $1, 12($sp)
913         ldl     $0, 8($sp)
914
915         stq     $1, 80+16($sp)
916 1:      lda     $sp, 16($sp)
917         ret
918 .end sys_pipe
919
920         .align  4
921         .globl  sys_ptrace
922         .ent    sys_ptrace
923 sys_ptrace:
924         .prologue 0
925         mov     $sp, $20
926         jmp     $31, do_sys_ptrace
927 .end sys_ptrace
928
929         .align  4
930         .globl  sys_execve
931         .ent    sys_execve
932 sys_execve:
933         .prologue 0
934         mov     $sp, $19
935         jmp     $31, do_sys_execve
936 .end sys_execve
937
938         .align  4
939         .globl  osf_sigprocmask
940         .ent    osf_sigprocmask
941 osf_sigprocmask:
942         .prologue 0
943         mov     $sp, $18
944         jmp     $31, do_osf_sigprocmask
945 .end osf_sigprocmask
946
947         .align  4
948         .globl  alpha_ni_syscall
949         .ent    alpha_ni_syscall
950 alpha_ni_syscall:
951         .prologue 0
952         /* Special because it also implements overflow handling via
953            syscall number 0.  And if you recall, zero is a special
954            trigger for "not an error".  Store large non-zero there.  */
955         lda     $0, -ENOSYS
956         unop
957         stq     $0, 0($sp)
958         ret
959 .end alpha_ni_syscall