alpha: switch to saner kernel_execve() semantics
[pandora-kernel.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 99:;                                    \
77         ldq     $19, 72($sp);           \
78         ldq     $20, 80($sp);           \
79         ldq     $21, 88($sp);           \
80         ldq     $22, 96($sp);           \
81         ldq     $23, 104($sp);          \
82         ldq     $24, 112($sp);          \
83         ldq     $25, 120($sp);          \
84         ldq     $26, 128($sp);          \
85         ldq     $27, 136($sp);          \
86         ldq     $28, 144($sp);          \
87         addq    $sp, SP_OFF, $sp
88
89 /*
90  * Non-syscall kernel entry points.
91  */
92
93         .align  4
94         .globl  entInt
95         .ent    entInt
96 entInt:
97         SAVE_ALL
98         lda     $8, 0x3fff
99         lda     $26, ret_from_sys_call
100         bic     $sp, $8, $8
101         mov     $sp, $19
102         jsr     $31, do_entInt
103 .end entInt
104
105         .align  4
106         .globl  entArith
107         .ent    entArith
108 entArith:
109         SAVE_ALL
110         lda     $8, 0x3fff
111         lda     $26, ret_from_sys_call
112         bic     $sp, $8, $8
113         mov     $sp, $18
114         jsr     $31, do_entArith
115 .end entArith
116
117         .align  4
118         .globl  entMM
119         .ent    entMM
120 entMM:
121         SAVE_ALL
122 /* save $9 - $15 so the inline exception code can manipulate them.  */
123         subq    $sp, 56, $sp
124         stq     $9, 0($sp)
125         stq     $10, 8($sp)
126         stq     $11, 16($sp)
127         stq     $12, 24($sp)
128         stq     $13, 32($sp)
129         stq     $14, 40($sp)
130         stq     $15, 48($sp)
131         addq    $sp, 56, $19
132 /* handle the fault */
133         lda     $8, 0x3fff
134         bic     $sp, $8, $8
135         jsr     $26, do_page_fault
136 /* reload the registers after the exception code played.  */
137         ldq     $9, 0($sp)
138         ldq     $10, 8($sp)
139         ldq     $11, 16($sp)
140         ldq     $12, 24($sp)
141         ldq     $13, 32($sp)
142         ldq     $14, 40($sp)
143         ldq     $15, 48($sp)
144         addq    $sp, 56, $sp
145 /* finish up the syscall as normal.  */
146         br      ret_from_sys_call
147 .end entMM
148
149         .align  4
150         .globl  entIF
151         .ent    entIF
152 entIF:
153         SAVE_ALL
154         lda     $8, 0x3fff
155         lda     $26, ret_from_sys_call
156         bic     $sp, $8, $8
157         mov     $sp, $17
158         jsr     $31, do_entIF
159 .end entIF
160
161         .align  4
162         .globl  entUna
163         .ent    entUna
164 entUna:
165         lda     $sp, -256($sp)
166         stq     $0, 0($sp)
167         ldq     $0, 256($sp)    /* get PS */
168         stq     $1, 8($sp)
169         stq     $2, 16($sp)
170         stq     $3, 24($sp)
171         and     $0, 8, $0               /* user mode? */
172         stq     $4, 32($sp)
173         bne     $0, entUnaUser  /* yup -> do user-level unaligned fault */
174         stq     $5, 40($sp)
175         stq     $6, 48($sp)
176         stq     $7, 56($sp)
177         stq     $8, 64($sp)
178         stq     $9, 72($sp)
179         stq     $10, 80($sp)
180         stq     $11, 88($sp)
181         stq     $12, 96($sp)
182         stq     $13, 104($sp)
183         stq     $14, 112($sp)
184         stq     $15, 120($sp)
185         /* 16-18 PAL-saved */
186         stq     $19, 152($sp)
187         stq     $20, 160($sp)
188         stq     $21, 168($sp)
189         stq     $22, 176($sp)
190         stq     $23, 184($sp)
191         stq     $24, 192($sp)
192         stq     $25, 200($sp)
193         stq     $26, 208($sp)
194         stq     $27, 216($sp)
195         stq     $28, 224($sp)
196         mov     $sp, $19
197         stq     $gp, 232($sp)
198         lda     $8, 0x3fff
199         stq     $31, 248($sp)
200         bic     $sp, $8, $8
201         jsr     $26, do_entUna
202         ldq     $0, 0($sp)
203         ldq     $1, 8($sp)
204         ldq     $2, 16($sp)
205         ldq     $3, 24($sp)
206         ldq     $4, 32($sp)
207         ldq     $5, 40($sp)
208         ldq     $6, 48($sp)
209         ldq     $7, 56($sp)
210         ldq     $8, 64($sp)
211         ldq     $9, 72($sp)
212         ldq     $10, 80($sp)
213         ldq     $11, 88($sp)
214         ldq     $12, 96($sp)
215         ldq     $13, 104($sp)
216         ldq     $14, 112($sp)
217         ldq     $15, 120($sp)
218         /* 16-18 PAL-saved */
219         ldq     $19, 152($sp)
220         ldq     $20, 160($sp)
221         ldq     $21, 168($sp)
222         ldq     $22, 176($sp)
223         ldq     $23, 184($sp)
224         ldq     $24, 192($sp)
225         ldq     $25, 200($sp)
226         ldq     $26, 208($sp)
227         ldq     $27, 216($sp)
228         ldq     $28, 224($sp)
229         ldq     $gp, 232($sp)
230         lda     $sp, 256($sp)
231         call_pal PAL_rti
232 .end entUna
233
234         .align  4
235         .ent    entUnaUser
236 entUnaUser:
237         ldq     $0, 0($sp)      /* restore original $0 */
238         lda     $sp, 256($sp)   /* pop entUna's stack frame */
239         SAVE_ALL                /* setup normal kernel stack */
240         lda     $sp, -56($sp)
241         stq     $9, 0($sp)
242         stq     $10, 8($sp)
243         stq     $11, 16($sp)
244         stq     $12, 24($sp)
245         stq     $13, 32($sp)
246         stq     $14, 40($sp)
247         stq     $15, 48($sp)
248         lda     $8, 0x3fff
249         addq    $sp, 56, $19
250         bic     $sp, $8, $8
251         jsr     $26, do_entUnaUser
252         ldq     $9, 0($sp)
253         ldq     $10, 8($sp)
254         ldq     $11, 16($sp)
255         ldq     $12, 24($sp)
256         ldq     $13, 32($sp)
257         ldq     $14, 40($sp)
258         ldq     $15, 48($sp)
259         lda     $sp, 56($sp)
260         br      ret_from_sys_call
261 .end entUnaUser
262
263         .align  4
264         .globl  entDbg
265         .ent    entDbg
266 entDbg:
267         SAVE_ALL
268         lda     $8, 0x3fff
269         lda     $26, ret_from_sys_call
270         bic     $sp, $8, $8
271         mov     $sp, $16
272         jsr     $31, do_entDbg
273 .end entDbg
274 \f
275 /*
276  * The system call entry point is special.  Most importantly, it looks
277  * like a function call to userspace as far as clobbered registers.  We
278  * do preserve the argument registers (for syscall restarts) and $26
279  * (for leaf syscall functions).
280  *
281  * So much for theory.  We don't take advantage of this yet.
282  *
283  * Note that a0-a2 are not saved by PALcode as with the other entry points.
284  */
285
286         .align  4
287         .globl  entSys
288         .globl  ret_from_sys_call
289         .ent    entSys
290 entSys:
291         SAVE_ALL
292         lda     $8, 0x3fff
293         bic     $sp, $8, $8
294         lda     $4, NR_SYSCALLS($31)
295         stq     $16, SP_OFF+24($sp)
296         lda     $5, sys_call_table
297         lda     $27, sys_ni_syscall
298         cmpult  $0, $4, $4
299         ldl     $3, TI_FLAGS($8)
300         stq     $17, SP_OFF+32($sp)
301         s8addq  $0, $5, $5
302         stq     $18, SP_OFF+40($sp)
303         blbs    $3, strace
304         beq     $4, 1f
305         ldq     $27, 0($5)
306 1:      jsr     $26, ($27), alpha_ni_syscall
307         ldgp    $gp, 0($26)
308         blt     $0, $syscall_error      /* the call failed */
309         stq     $0, 0($sp)
310         stq     $31, 72($sp)            /* a3=0 => no error */
311
312         .align  4
313 ret_from_sys_call:
314         cmovne  $26, 0, $18             /* $18 = 0 => non-restartable */
315         ldq     $0, SP_OFF($sp)
316         and     $0, 8, $0
317         beq     $0, ret_to_kernel
318 ret_to_user:
319         /* Make sure need_resched and sigpending don't change between
320                 sampling and the rti.  */
321         lda     $16, 7
322         call_pal PAL_swpipl
323         ldl     $17, TI_FLAGS($8)
324         and     $17, _TIF_WORK_MASK, $2
325         bne     $2, work_pending
326 restore_all:
327         RESTORE_ALL
328         call_pal PAL_rti
329
330 ret_to_kernel:
331         lda     $16, 7
332         call_pal PAL_swpipl
333         br restore_all
334
335         .align 3
336 $syscall_error:
337         /*
338          * Some system calls (e.g., ptrace) can return arbitrary
339          * values which might normally be mistaken as error numbers.
340          * Those functions must zero $0 (v0) directly in the stack
341          * frame to indicate that a negative return value wasn't an
342          * error number..
343          */
344         ldq     $18, 0($sp)     /* old syscall nr (zero if success) */
345         beq     $18, $ret_success
346
347         ldq     $19, 72($sp)    /* .. and this a3 */
348         subq    $31, $0, $0     /* with error in v0 */
349         addq    $31, 1, $1      /* set a3 for errno return */
350         stq     $0, 0($sp)
351         mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
352         stq     $1, 72($sp)     /* a3 for return */
353         br      ret_from_sys_call
354
355 $ret_success:
356         stq     $0, 0($sp)
357         stq     $31, 72($sp)    /* a3=0 => no error */
358         br      ret_from_sys_call
359 .end entSys
360
361 /*
362  * Do all cleanup when returning from all interrupts and system calls.
363  *
364  * Arguments:
365  *       $8: current.
366  *      $17: TI_FLAGS.
367  *      $18: The old syscall number, or zero if this is not a return
368  *           from a syscall that errored and is possibly restartable.
369  *      $19: The old a3 value
370  */
371
372         .align  4
373         .ent    work_pending
374 work_pending:
375         and     $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2
376         bne     $2, $work_notifysig
377
378 $work_resched:
379         /*
380          * We can get here only if we returned from syscall without SIGPENDING
381          * or got through work_notifysig already.  Either case means no syscall
382          * restarts for us, so let $18 and $19 burn.
383          */
384         jsr     $26, schedule
385         mov     0, $18
386         br      ret_to_user
387
388 $work_notifysig:
389         mov     $sp, $16
390         bsr     $1, do_switch_stack
391         jsr     $26, do_work_pending
392         bsr     $1, undo_switch_stack
393         br      restore_all
394 .end work_pending
395
396 /*
397  * PTRACE syscall handler
398  */
399
400         .align  4
401         .ent    strace
402 strace:
403         /* set up signal stack, call syscall_trace */
404         bsr     $1, do_switch_stack
405         jsr     $26, syscall_trace_enter /* returns the syscall number */
406         bsr     $1, undo_switch_stack
407
408         /* get the arguments back.. */
409         ldq     $16, SP_OFF+24($sp)
410         ldq     $17, SP_OFF+32($sp)
411         ldq     $18, SP_OFF+40($sp)
412         ldq     $19, 72($sp)
413         ldq     $20, 80($sp)
414         ldq     $21, 88($sp)
415
416         /* get the system call pointer.. */
417         lda     $1, NR_SYSCALLS($31)
418         lda     $2, sys_call_table
419         lda     $27, alpha_ni_syscall
420         cmpult  $0, $1, $1
421         s8addq  $0, $2, $2
422         beq     $1, 1f
423         ldq     $27, 0($2)
424 1:      jsr     $26, ($27), sys_gettimeofday
425 ret_from_straced:
426         ldgp    $gp, 0($26)
427
428         /* check return.. */
429         blt     $0, $strace_error       /* the call failed */
430         stq     $31, 72($sp)            /* a3=0 => no error */
431 $strace_success:
432         stq     $0, 0($sp)              /* save return value */
433
434         bsr     $1, do_switch_stack
435         jsr     $26, syscall_trace_leave
436         bsr     $1, undo_switch_stack
437         br      $31, ret_from_sys_call
438
439         .align  3
440 $strace_error:
441         ldq     $18, 0($sp)     /* old syscall nr (zero if success) */
442         beq     $18, $strace_success
443         ldq     $19, 72($sp)    /* .. and this a3 */
444
445         subq    $31, $0, $0     /* with error in v0 */
446         addq    $31, 1, $1      /* set a3 for errno return */
447         stq     $0, 0($sp)
448         stq     $1, 72($sp)     /* a3 for return */
449
450         bsr     $1, do_switch_stack
451         mov     $18, $9         /* save old syscall number */
452         mov     $19, $10        /* save old a3 */
453         jsr     $26, syscall_trace_leave
454         mov     $9, $18
455         mov     $10, $19
456         bsr     $1, undo_switch_stack
457
458         mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
459         br      ret_from_sys_call
460 .end strace
461 \f
462 /*
463  * Save and restore the switch stack -- aka the balance of the user context.
464  */
465
466         .align  4
467         .ent    do_switch_stack
468 do_switch_stack:
469         lda     $sp, -SWITCH_STACK_SIZE($sp)
470         stq     $9, 0($sp)
471         stq     $10, 8($sp)
472         stq     $11, 16($sp)
473         stq     $12, 24($sp)
474         stq     $13, 32($sp)
475         stq     $14, 40($sp)
476         stq     $15, 48($sp)
477         stq     $26, 56($sp)
478         stt     $f0, 64($sp)
479         stt     $f1, 72($sp)
480         stt     $f2, 80($sp)
481         stt     $f3, 88($sp)
482         stt     $f4, 96($sp)
483         stt     $f5, 104($sp)
484         stt     $f6, 112($sp)
485         stt     $f7, 120($sp)
486         stt     $f8, 128($sp)
487         stt     $f9, 136($sp)
488         stt     $f10, 144($sp)
489         stt     $f11, 152($sp)
490         stt     $f12, 160($sp)
491         stt     $f13, 168($sp)
492         stt     $f14, 176($sp)
493         stt     $f15, 184($sp)
494         stt     $f16, 192($sp)
495         stt     $f17, 200($sp)
496         stt     $f18, 208($sp)
497         stt     $f19, 216($sp)
498         stt     $f20, 224($sp)
499         stt     $f21, 232($sp)
500         stt     $f22, 240($sp)
501         stt     $f23, 248($sp)
502         stt     $f24, 256($sp)
503         stt     $f25, 264($sp)
504         stt     $f26, 272($sp)
505         stt     $f27, 280($sp)
506         mf_fpcr $f0             # get fpcr
507         stt     $f28, 288($sp)
508         stt     $f29, 296($sp)
509         stt     $f30, 304($sp)
510         stt     $f0, 312($sp)   # save fpcr in slot of $f31
511         ldt     $f0, 64($sp)    # dont let "do_switch_stack" change fp state.
512         ret     $31, ($1), 1
513 .end do_switch_stack
514
515         .align  4
516         .ent    undo_switch_stack
517 undo_switch_stack:
518         ldq     $9, 0($sp)
519         ldq     $10, 8($sp)
520         ldq     $11, 16($sp)
521         ldq     $12, 24($sp)
522         ldq     $13, 32($sp)
523         ldq     $14, 40($sp)
524         ldq     $15, 48($sp)
525         ldq     $26, 56($sp)
526         ldt     $f30, 312($sp)  # get saved fpcr
527         ldt     $f0, 64($sp)
528         ldt     $f1, 72($sp)
529         ldt     $f2, 80($sp)
530         ldt     $f3, 88($sp)
531         mt_fpcr $f30            # install saved fpcr
532         ldt     $f4, 96($sp)
533         ldt     $f5, 104($sp)
534         ldt     $f6, 112($sp)
535         ldt     $f7, 120($sp)
536         ldt     $f8, 128($sp)
537         ldt     $f9, 136($sp)
538         ldt     $f10, 144($sp)
539         ldt     $f11, 152($sp)
540         ldt     $f12, 160($sp)
541         ldt     $f13, 168($sp)
542         ldt     $f14, 176($sp)
543         ldt     $f15, 184($sp)
544         ldt     $f16, 192($sp)
545         ldt     $f17, 200($sp)
546         ldt     $f18, 208($sp)
547         ldt     $f19, 216($sp)
548         ldt     $f20, 224($sp)
549         ldt     $f21, 232($sp)
550         ldt     $f22, 240($sp)
551         ldt     $f23, 248($sp)
552         ldt     $f24, 256($sp)
553         ldt     $f25, 264($sp)
554         ldt     $f26, 272($sp)
555         ldt     $f27, 280($sp)
556         ldt     $f28, 288($sp)
557         ldt     $f29, 296($sp)
558         ldt     $f30, 304($sp)
559         lda     $sp, SWITCH_STACK_SIZE($sp)
560         ret     $31, ($1), 1
561 .end undo_switch_stack
562 \f
563 /*
564  * The meat of the context switch code.
565  */
566
567         .align  4
568         .globl  alpha_switch_to
569         .ent    alpha_switch_to
570 alpha_switch_to:
571         .prologue 0
572         bsr     $1, do_switch_stack
573         call_pal PAL_swpctx
574         lda     $8, 0x3fff
575         bsr     $1, undo_switch_stack
576         bic     $sp, $8, $8
577         mov     $17, $0
578         ret
579 .end alpha_switch_to
580
581 /*
582  * New processes begin life here.
583  */
584
585         .globl  ret_from_fork
586         .align  4
587         .ent    ret_from_fork
588 ret_from_fork:
589         lda     $26, ret_from_sys_call
590         mov     $17, $16
591         jmp     $31, schedule_tail
592 .end ret_from_fork
593
594 /*
595  * ... and new kernel threads - here
596  */
597         .align 4
598         .globl  ret_from_kernel_thread
599         .ent    ret_from_kernel_thread
600 ret_from_kernel_thread:
601         mov     $17, $16
602         jsr     $26, schedule_tail
603         mov     $9, $27
604         mov     $10, $16
605         jsr     $26, ($9)
606         mov     $31, $19                /* to disable syscall restarts */
607         br      $31, ret_to_user
608 .end ret_from_kernel_thread
609
610 \f
611 /*
612  * Special system calls.  Most of these are special in that they either
613  * have to play switch_stack games or in some way use the pt_regs struct.
614  */
615         .align  4
616         .globl  sys_fork
617         .ent    sys_fork
618 sys_fork:
619         .prologue 0
620         mov     $sp, $21
621         bsr     $1, do_switch_stack
622         bis     $31, SIGCHLD, $16
623         mov     $31, $17
624         mov     $31, $18
625         mov     $31, $19
626         mov     $31, $20
627         jsr     $26, alpha_clone
628         bsr     $1, undo_switch_stack
629         ret
630 .end sys_fork
631
632         .align  4
633         .globl  sys_clone
634         .ent    sys_clone
635 sys_clone:
636         .prologue 0
637         mov     $sp, $21
638         bsr     $1, do_switch_stack
639         /* $16, $17, $18, $19, $20 come from the user.  */
640         jsr     $26, alpha_clone
641         bsr     $1, undo_switch_stack
642         ret
643 .end sys_clone
644
645         .align  4
646         .globl  sys_vfork
647         .ent    sys_vfork
648 sys_vfork:
649         .prologue 0
650         mov     $sp, $16
651         bsr     $1, do_switch_stack
652         jsr     $26, alpha_vfork
653         bsr     $1, undo_switch_stack
654         ret
655 .end sys_vfork
656
657         .align  4
658         .globl  sys_sigreturn
659         .ent    sys_sigreturn
660 sys_sigreturn:
661         .prologue 0
662         lda     $9, ret_from_straced
663         cmpult  $26, $9, $9
664         mov     $sp, $17
665         lda     $18, -SWITCH_STACK_SIZE($sp)
666         lda     $sp, -SWITCH_STACK_SIZE($sp)
667         jsr     $26, do_sigreturn
668         bne     $9, 1f
669         jsr     $26, syscall_trace_leave
670 1:      br      $1, undo_switch_stack
671         br      ret_from_sys_call
672 .end sys_sigreturn
673
674         .align  4
675         .globl  sys_rt_sigreturn
676         .ent    sys_rt_sigreturn
677 sys_rt_sigreturn:
678         .prologue 0
679         lda     $9, ret_from_straced
680         cmpult  $26, $9, $9
681         mov     $sp, $17
682         lda     $18, -SWITCH_STACK_SIZE($sp)
683         lda     $sp, -SWITCH_STACK_SIZE($sp)
684         jsr     $26, do_rt_sigreturn
685         bne     $9, 1f
686         jsr     $26, syscall_trace_leave
687 1:      br      $1, undo_switch_stack
688         br      ret_from_sys_call
689 .end sys_rt_sigreturn
690
691         .align  4
692         .globl  alpha_ni_syscall
693         .ent    alpha_ni_syscall
694 alpha_ni_syscall:
695         .prologue 0
696         /* Special because it also implements overflow handling via
697            syscall number 0.  And if you recall, zero is a special
698            trigger for "not an error".  Store large non-zero there.  */
699         lda     $0, -ENOSYS
700         unop
701         stq     $0, 0($sp)
702         ret
703 .end alpha_ni_syscall