x86 PAT: fix performance drop for glx, use UC minus for ioremap(), ioremap_nocache...
[linux-2.6] / 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         ldgp    $gp, 0($26)
434
435         /* check return.. */
436         blt     $0, $strace_error       /* the call failed */
437         stq     $31, 72($sp)            /* a3=0 => no error */
438 $strace_success:
439         stq     $0, 0($sp)              /* save return value */
440
441         bsr     $1, do_switch_stack
442         jsr     $26, syscall_trace
443         bsr     $1, undo_switch_stack
444         br      $31, ret_from_sys_call
445
446         .align  3
447 $strace_error:
448         ldq     $19, 0($sp)     /* old syscall nr (zero if success) */
449         beq     $19, $strace_success
450         ldq     $20, 72($sp)    /* .. and this a3 */
451
452         subq    $31, $0, $0     /* with error in v0 */
453         addq    $31, 1, $1      /* set a3 for errno return */
454         stq     $0, 0($sp)
455         stq     $1, 72($sp)     /* a3 for return */
456
457         bsr     $1, do_switch_stack
458         mov     $19, $9         /* save old syscall number */
459         mov     $20, $10        /* save old a3 */
460         jsr     $26, syscall_trace
461         mov     $9, $19
462         mov     $10, $20
463         bsr     $1, undo_switch_stack
464
465         mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
466         br      ret_from_sys_call
467 .end strace
468 \f
469 /*
470  * Save and restore the switch stack -- aka the balance of the user context.
471  */
472
473         .align  4
474         .ent    do_switch_stack
475 do_switch_stack:
476         lda     $sp, -SWITCH_STACK_SIZE($sp)
477         stq     $9, 0($sp)
478         stq     $10, 8($sp)
479         stq     $11, 16($sp)
480         stq     $12, 24($sp)
481         stq     $13, 32($sp)
482         stq     $14, 40($sp)
483         stq     $15, 48($sp)
484         stq     $26, 56($sp)
485         stt     $f0, 64($sp)
486         stt     $f1, 72($sp)
487         stt     $f2, 80($sp)
488         stt     $f3, 88($sp)
489         stt     $f4, 96($sp)
490         stt     $f5, 104($sp)
491         stt     $f6, 112($sp)
492         stt     $f7, 120($sp)
493         stt     $f8, 128($sp)
494         stt     $f9, 136($sp)
495         stt     $f10, 144($sp)
496         stt     $f11, 152($sp)
497         stt     $f12, 160($sp)
498         stt     $f13, 168($sp)
499         stt     $f14, 176($sp)
500         stt     $f15, 184($sp)
501         stt     $f16, 192($sp)
502         stt     $f17, 200($sp)
503         stt     $f18, 208($sp)
504         stt     $f19, 216($sp)
505         stt     $f20, 224($sp)
506         stt     $f21, 232($sp)
507         stt     $f22, 240($sp)
508         stt     $f23, 248($sp)
509         stt     $f24, 256($sp)
510         stt     $f25, 264($sp)
511         stt     $f26, 272($sp)
512         stt     $f27, 280($sp)
513         mf_fpcr $f0             # get fpcr
514         stt     $f28, 288($sp)
515         stt     $f29, 296($sp)
516         stt     $f30, 304($sp)
517         stt     $f0, 312($sp)   # save fpcr in slot of $f31
518         ldt     $f0, 64($sp)    # dont let "do_switch_stack" change fp state.
519         ret     $31, ($1), 1
520 .end do_switch_stack
521
522         .align  4
523         .ent    undo_switch_stack
524 undo_switch_stack:
525         ldq     $9, 0($sp)
526         ldq     $10, 8($sp)
527         ldq     $11, 16($sp)
528         ldq     $12, 24($sp)
529         ldq     $13, 32($sp)
530         ldq     $14, 40($sp)
531         ldq     $15, 48($sp)
532         ldq     $26, 56($sp)
533         ldt     $f30, 312($sp)  # get saved fpcr
534         ldt     $f0, 64($sp)
535         ldt     $f1, 72($sp)
536         ldt     $f2, 80($sp)
537         ldt     $f3, 88($sp)
538         mt_fpcr $f30            # install saved fpcr
539         ldt     $f4, 96($sp)
540         ldt     $f5, 104($sp)
541         ldt     $f6, 112($sp)
542         ldt     $f7, 120($sp)
543         ldt     $f8, 128($sp)
544         ldt     $f9, 136($sp)
545         ldt     $f10, 144($sp)
546         ldt     $f11, 152($sp)
547         ldt     $f12, 160($sp)
548         ldt     $f13, 168($sp)
549         ldt     $f14, 176($sp)
550         ldt     $f15, 184($sp)
551         ldt     $f16, 192($sp)
552         ldt     $f17, 200($sp)
553         ldt     $f18, 208($sp)
554         ldt     $f19, 216($sp)
555         ldt     $f20, 224($sp)
556         ldt     $f21, 232($sp)
557         ldt     $f22, 240($sp)
558         ldt     $f23, 248($sp)
559         ldt     $f24, 256($sp)
560         ldt     $f25, 264($sp)
561         ldt     $f26, 272($sp)
562         ldt     $f27, 280($sp)
563         ldt     $f28, 288($sp)
564         ldt     $f29, 296($sp)
565         ldt     $f30, 304($sp)
566         lda     $sp, SWITCH_STACK_SIZE($sp)
567         ret     $31, ($1), 1
568 .end undo_switch_stack
569 \f
570 /*
571  * The meat of the context switch code.
572  */
573
574         .align  4
575         .globl  alpha_switch_to
576         .ent    alpha_switch_to
577 alpha_switch_to:
578         .prologue 0
579         bsr     $1, do_switch_stack
580         call_pal PAL_swpctx
581         lda     $8, 0x3fff
582         bsr     $1, undo_switch_stack
583         bic     $sp, $8, $8
584         mov     $17, $0
585         ret
586 .end alpha_switch_to
587
588 /*
589  * New processes begin life here.
590  */
591
592         .globl  ret_from_fork
593         .align  4
594         .ent    ret_from_fork
595 ret_from_fork:
596         lda     $26, ret_from_sys_call
597         mov     $17, $16
598         jmp     $31, schedule_tail
599 .end ret_from_fork
600
601 /*
602  * kernel_thread(fn, arg, clone_flags)
603  */
604         .align 4
605         .globl  kernel_thread
606         .ent    kernel_thread
607 kernel_thread:
608         /* We can be called from a module.  */
609         ldgp    $gp, 0($27)
610         .prologue 1
611         subq    $sp, SP_OFF+6*8, $sp
612         br      $1, 2f          /* load start address */
613
614         /* We've now "returned" from a fake system call.  */
615         unop
616         blt     $0, 1f          /* error?  */
617         ldi     $1, 0x3fff
618         beq     $20, 1f         /* parent or child?  */
619
620         bic     $sp, $1, $8     /* in child.  */
621         jsr     $26, ($27)
622         ldgp    $gp, 0($26)
623         mov     $0, $16
624         mov     $31, $26
625         jmp     $31, sys_exit
626
627 1:      ret                     /* in parent.  */
628
629         .align 4
630 2:      /* Fake a system call stack frame, as we can't do system calls
631            from kernel space.  Note that we store FN and ARG as they
632            need to be set up in the child for the call.  Also store $8
633            and $26 for use in the parent.  */
634         stq     $31, SP_OFF($sp)        /* ps */
635         stq     $1, SP_OFF+8($sp)       /* pc */
636         stq     $gp, SP_OFF+16($sp)     /* gp */
637         stq     $16, 136($sp)           /* $27; FN for child */
638         stq     $17, SP_OFF+24($sp)     /* $16; ARG for child */
639         stq     $8, 64($sp)             /* $8 */
640         stq     $26, 128($sp)           /* $26 */
641         /* Avoid the HAE being gratuitously wrong, to avoid restoring it.  */
642         ldq     $2, alpha_mv+HAE_CACHE
643         stq     $2, 152($sp)            /* HAE */
644
645         /* Shuffle FLAGS to the front; add CLONE_VM.  */
646         ldi     $1, CLONE_VM|CLONE_UNTRACED
647         or      $18, $1, $16
648         bsr     $26, sys_clone
649
650         /* We don't actually care for a3 success widgetry in the kernel.
651            Not for positive errno values.  */
652         stq     $0, 0($sp)              /* $0 */
653         br      restore_all
654 .end kernel_thread
655
656 /*
657  * kernel_execve(path, argv, envp)
658  */
659         .align  4
660         .globl  kernel_execve
661         .ent    kernel_execve
662 kernel_execve:
663         /* We can be called from a module.  */
664         ldgp    $gp, 0($27)
665         lda     $sp, -(32+SIZEOF_PT_REGS+8)($sp)
666         .frame  $sp, 32+SIZEOF_PT_REGS+8, $26, 0
667         stq     $26, 0($sp)
668         stq     $16, 8($sp)
669         stq     $17, 16($sp)
670         stq     $18, 24($sp)
671         .prologue 1
672
673         lda     $16, 32($sp)
674         lda     $17, 0
675         lda     $18, SIZEOF_PT_REGS
676         bsr     $26, memset             !samegp
677
678         /* Avoid the HAE being gratuitously wrong, which would cause us
679            to do the whole turn off interrupts thing and restore it.  */
680         ldq     $2, alpha_mv+HAE_CACHE
681         stq     $2, 152+32($sp)
682
683         ldq     $16, 8($sp)
684         ldq     $17, 16($sp)
685         ldq     $18, 24($sp)
686         lda     $19, 32($sp)
687         bsr     $26, do_execve          !samegp
688
689         ldq     $26, 0($sp)
690         bne     $0, 1f                  /* error! */
691
692         /* Move the temporary pt_regs struct from its current location
693            to the top of the kernel stack frame.  See copy_thread for
694            details for a normal process.  */
695         lda     $16, 0x4000 - SIZEOF_PT_REGS($8)
696         lda     $17, 32($sp)
697         lda     $18, SIZEOF_PT_REGS
698         bsr     $26, memmove            !samegp
699
700         /* Take that over as our new stack frame and visit userland!  */
701         lda     $sp, 0x4000 - SIZEOF_PT_REGS($8)
702         br      $31, ret_from_sys_call
703
704 1:      lda     $sp, 32+SIZEOF_PT_REGS+8($sp)
705         ret
706 .end kernel_execve
707
708 \f
709 /*
710  * Special system calls.  Most of these are special in that they either
711  * have to play switch_stack games or in some way use the pt_regs struct.
712  */
713         .align  4
714         .globl  sys_fork
715         .ent    sys_fork
716 sys_fork:
717         .prologue 0
718         mov     $sp, $21
719         bsr     $1, do_switch_stack
720         bis     $31, SIGCHLD, $16
721         mov     $31, $17
722         mov     $31, $18
723         mov     $31, $19
724         mov     $31, $20
725         jsr     $26, alpha_clone
726         bsr     $1, undo_switch_stack
727         ret
728 .end sys_fork
729
730         .align  4
731         .globl  sys_clone
732         .ent    sys_clone
733 sys_clone:
734         .prologue 0
735         mov     $sp, $21
736         bsr     $1, do_switch_stack
737         /* $16, $17, $18, $19, $20 come from the user.  */
738         jsr     $26, alpha_clone
739         bsr     $1, undo_switch_stack
740         ret
741 .end sys_clone
742
743         .align  4
744         .globl  sys_vfork
745         .ent    sys_vfork
746 sys_vfork:
747         .prologue 0
748         mov     $sp, $16
749         bsr     $1, do_switch_stack
750         jsr     $26, alpha_vfork
751         bsr     $1, undo_switch_stack
752         ret
753 .end sys_vfork
754
755         .align  4
756         .globl  sys_sigreturn
757         .ent    sys_sigreturn
758 sys_sigreturn:
759         .prologue 0
760         mov     $sp, $17
761         lda     $18, -SWITCH_STACK_SIZE($sp)
762         lda     $sp, -SWITCH_STACK_SIZE($sp)
763         jsr     $26, do_sigreturn
764         br      $1, undo_switch_stack
765         br      ret_from_sys_call
766 .end sys_sigreturn
767
768         .align  4
769         .globl  sys_rt_sigreturn
770         .ent    sys_rt_sigreturn
771 sys_rt_sigreturn:
772         .prologue 0
773         mov     $sp, $17
774         lda     $18, -SWITCH_STACK_SIZE($sp)
775         lda     $sp, -SWITCH_STACK_SIZE($sp)
776         jsr     $26, do_rt_sigreturn
777         br      $1, undo_switch_stack
778         br      ret_from_sys_call
779 .end sys_rt_sigreturn
780
781         .align  4
782         .globl  sys_sigsuspend
783         .ent    sys_sigsuspend
784 sys_sigsuspend:
785         .prologue 0
786         mov     $sp, $17
787         br      $1, do_switch_stack
788         mov     $sp, $18
789         subq    $sp, 16, $sp
790         stq     $26, 0($sp)
791         jsr     $26, do_sigsuspend
792         ldq     $26, 0($sp)
793         lda     $sp, SWITCH_STACK_SIZE+16($sp)
794         ret
795 .end sys_sigsuspend
796
797         .align  4
798         .globl  sys_rt_sigsuspend
799         .ent    sys_rt_sigsuspend
800 sys_rt_sigsuspend:
801         .prologue 0
802         mov     $sp, $18
803         br      $1, do_switch_stack
804         mov     $sp, $19
805         subq    $sp, 16, $sp
806         stq     $26, 0($sp)
807         jsr     $26, do_rt_sigsuspend
808         ldq     $26, 0($sp)
809         lda     $sp, SWITCH_STACK_SIZE+16($sp)
810         ret
811 .end sys_rt_sigsuspend
812
813         .align  4
814         .globl  sys_sethae
815         .ent    sys_sethae
816 sys_sethae:
817         .prologue 0
818         stq     $16, 152($sp)
819         ret
820 .end sys_sethae
821
822         .align  4
823         .globl  osf_getpriority
824         .ent    osf_getpriority
825 osf_getpriority:
826         lda     $sp, -16($sp)
827         stq     $26, 0($sp)
828         .prologue 0
829
830         jsr     $26, sys_getpriority
831
832         ldq     $26, 0($sp)
833         blt     $0, 1f
834
835         /* Return value is the unbiased priority, i.e. 20 - prio.
836            This does result in negative return values, so signal
837            no error by writing into the R0 slot.  */
838         lda     $1, 20
839         stq     $31, 16($sp)
840         subl    $1, $0, $0
841         unop
842
843 1:      lda     $sp, 16($sp)
844         ret
845 .end osf_getpriority
846
847         .align  4
848         .globl  sys_getxuid
849         .ent    sys_getxuid
850 sys_getxuid:
851         .prologue 0
852         ldq     $2, TI_TASK($8)
853         ldl     $0, TASK_UID($2)
854         ldl     $1, TASK_EUID($2)
855         stq     $1, 80($sp)
856         ret
857 .end sys_getxuid
858
859         .align  4
860         .globl  sys_getxgid
861         .ent    sys_getxgid
862 sys_getxgid:
863         .prologue 0
864         ldq     $2, TI_TASK($8)
865         ldl     $0, TASK_GID($2)
866         ldl     $1, TASK_EGID($2)
867         stq     $1, 80($sp)
868         ret
869 .end sys_getxgid
870
871         .align  4
872         .globl  sys_getxpid
873         .ent    sys_getxpid
874 sys_getxpid:
875         .prologue 0
876         ldq     $2, TI_TASK($8)
877
878         /* See linux/kernel/timer.c sys_getppid for discussion
879            about this loop.  */
880         ldq     $3, TASK_GROUP_LEADER($2)
881         ldq     $4, TASK_REAL_PARENT($3)
882         ldl     $0, TASK_TGID($2)
883 1:      ldl     $1, TASK_TGID($4)
884 #ifdef CONFIG_SMP
885         mov     $4, $5
886         mb
887         ldq     $3, TASK_GROUP_LEADER($2)
888         ldq     $4, TASK_REAL_PARENT($3)
889         cmpeq   $4, $5, $5
890         beq     $5, 1b
891 #endif
892         stq     $1, 80($sp)
893         ret
894 .end sys_getxpid
895
896         .align  4
897         .globl  sys_pipe
898         .ent    sys_pipe
899 sys_pipe:
900         lda     $sp, -16($sp)
901         stq     $26, 0($sp)
902         .prologue 0
903
904         lda     $16, 8($sp)
905         jsr     $26, do_pipe
906
907         ldq     $26, 0($sp)
908         bne     $0, 1f
909
910         /* The return values are in $0 and $20.  */
911         ldl     $1, 12($sp)
912         ldl     $0, 8($sp)
913
914         stq     $1, 80+16($sp)
915 1:      lda     $sp, 16($sp)
916         ret
917 .end sys_pipe
918
919         .align  4
920         .globl  sys_execve
921         .ent    sys_execve
922 sys_execve:
923         .prologue 0
924         mov     $sp, $19
925         jmp     $31, do_sys_execve
926 .end sys_execve
927
928         .align  4
929         .globl  osf_sigprocmask
930         .ent    osf_sigprocmask
931 osf_sigprocmask:
932         .prologue 0
933         mov     $sp, $18
934         jmp     $31, do_osf_sigprocmask
935 .end osf_sigprocmask
936
937         .align  4
938         .globl  alpha_ni_syscall
939         .ent    alpha_ni_syscall
940 alpha_ni_syscall:
941         .prologue 0
942         /* Special because it also implements overflow handling via
943            syscall number 0.  And if you recall, zero is a special
944            trigger for "not an error".  Store large non-zero there.  */
945         lda     $0, -ENOSYS
946         unop
947         stq     $0, 0($sp)
948         ret
949 .end alpha_ni_syscall