Merge branch 'for-linus-bugs' of git://git.kernel.org/pub/scm/linux/kernel/git/sage...
[platform/adaptation/renesas_rcar/renesas_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         .cfi_sections   .debug_frame
16
17 /* Stack offsets.  */
18 #define SP_OFF                  184
19 #define SWITCH_STACK_SIZE       320
20
21 .macro  CFI_START_OSF_FRAME     func
22         .align  4
23         .globl  \func
24         .type   \func,@function
25 \func:
26         .cfi_startproc simple
27         .cfi_return_column 64
28         .cfi_def_cfa    $sp, 48
29         .cfi_rel_offset 64, 8
30         .cfi_rel_offset $gp, 16
31         .cfi_rel_offset $16, 24
32         .cfi_rel_offset $17, 32
33         .cfi_rel_offset $18, 40
34 .endm
35
36 .macro  CFI_END_OSF_FRAME       func
37         .cfi_endproc
38         .size   \func, . - \func
39 .endm
40
41 /*
42  * This defines the normal kernel pt-regs layout.
43  *
44  * regs 9-15 preserved by C code
45  * regs 16-18 saved by PAL-code
46  * regs 29-30 saved and set up by PAL-code
47  * JRP - Save regs 16-18 in a special area of the stack, so that
48  * the palcode-provided values are available to the signal handler.
49  */
50
51 .macro  SAVE_ALL
52         subq    $sp, SP_OFF, $sp
53         .cfi_adjust_cfa_offset  SP_OFF
54         stq     $0, 0($sp)
55         stq     $1, 8($sp)
56         stq     $2, 16($sp)
57         stq     $3, 24($sp)
58         stq     $4, 32($sp)
59         stq     $28, 144($sp)
60         .cfi_rel_offset $0, 0
61         .cfi_rel_offset $1, 8
62         .cfi_rel_offset $2, 16
63         .cfi_rel_offset $3, 24
64         .cfi_rel_offset $4, 32
65         .cfi_rel_offset $28, 144
66         lda     $2, alpha_mv
67         stq     $5, 40($sp)
68         stq     $6, 48($sp)
69         stq     $7, 56($sp)
70         stq     $8, 64($sp)
71         stq     $19, 72($sp)
72         stq     $20, 80($sp)
73         stq     $21, 88($sp)
74         ldq     $2, HAE_CACHE($2)
75         stq     $22, 96($sp)
76         stq     $23, 104($sp)
77         stq     $24, 112($sp)
78         stq     $25, 120($sp)
79         stq     $26, 128($sp)
80         stq     $27, 136($sp)
81         stq     $2, 152($sp)
82         stq     $16, 160($sp)
83         stq     $17, 168($sp)
84         stq     $18, 176($sp)
85         .cfi_rel_offset $5, 40
86         .cfi_rel_offset $6, 48
87         .cfi_rel_offset $7, 56
88         .cfi_rel_offset $8, 64
89         .cfi_rel_offset $19, 72
90         .cfi_rel_offset $20, 80
91         .cfi_rel_offset $21, 88
92         .cfi_rel_offset $22, 96
93         .cfi_rel_offset $23, 104
94         .cfi_rel_offset $24, 112
95         .cfi_rel_offset $25, 120
96         .cfi_rel_offset $26, 128
97         .cfi_rel_offset $27, 136
98 .endm
99
100 .macro  RESTORE_ALL
101         lda     $19, alpha_mv
102         ldq     $0, 0($sp)
103         ldq     $1, 8($sp)
104         ldq     $2, 16($sp)
105         ldq     $3, 24($sp)
106         ldq     $21, 152($sp)
107         ldq     $20, HAE_CACHE($19)
108         ldq     $4, 32($sp)
109         ldq     $5, 40($sp)
110         ldq     $6, 48($sp)
111         ldq     $7, 56($sp)
112         subq    $20, $21, $20
113         ldq     $8, 64($sp)
114         beq     $20, 99f
115         ldq     $20, HAE_REG($19)
116         stq     $21, HAE_CACHE($19)
117         stq     $21, 0($20)
118 99:     ldq     $19, 72($sp)
119         ldq     $20, 80($sp)
120         ldq     $21, 88($sp)
121         ldq     $22, 96($sp)
122         ldq     $23, 104($sp)
123         ldq     $24, 112($sp)
124         ldq     $25, 120($sp)
125         ldq     $26, 128($sp)
126         ldq     $27, 136($sp)
127         ldq     $28, 144($sp)
128         addq    $sp, SP_OFF, $sp
129         .cfi_restore    $0
130         .cfi_restore    $1
131         .cfi_restore    $2
132         .cfi_restore    $3
133         .cfi_restore    $4
134         .cfi_restore    $5
135         .cfi_restore    $6
136         .cfi_restore    $7
137         .cfi_restore    $8
138         .cfi_restore    $19
139         .cfi_restore    $20
140         .cfi_restore    $21
141         .cfi_restore    $22
142         .cfi_restore    $23
143         .cfi_restore    $24
144         .cfi_restore    $25
145         .cfi_restore    $26
146         .cfi_restore    $27
147         .cfi_restore    $28
148         .cfi_adjust_cfa_offset  -SP_OFF
149 .endm
150
151 .macro  DO_SWITCH_STACK
152         bsr     $1, do_switch_stack
153         .cfi_adjust_cfa_offset  SWITCH_STACK_SIZE
154         .cfi_rel_offset $9, 0
155         .cfi_rel_offset $10, 8
156         .cfi_rel_offset $11, 16
157         .cfi_rel_offset $12, 24
158         .cfi_rel_offset $13, 32
159         .cfi_rel_offset $14, 40
160         .cfi_rel_offset $15, 48
161         /* We don't really care about the FP registers for debugging.  */
162 .endm
163
164 .macro  UNDO_SWITCH_STACK
165         bsr     $1, undo_switch_stack
166         .cfi_restore    $9
167         .cfi_restore    $10
168         .cfi_restore    $11
169         .cfi_restore    $12
170         .cfi_restore    $13
171         .cfi_restore    $14
172         .cfi_restore    $15
173         .cfi_adjust_cfa_offset  -SWITCH_STACK_SIZE
174 .endm
175
176 /*
177  * Non-syscall kernel entry points.
178  */
179
180 CFI_START_OSF_FRAME entInt
181         SAVE_ALL
182         lda     $8, 0x3fff
183         lda     $26, ret_from_sys_call
184         bic     $sp, $8, $8
185         mov     $sp, $19
186         jsr     $31, do_entInt
187 CFI_END_OSF_FRAME entInt
188
189 CFI_START_OSF_FRAME entArith
190         SAVE_ALL
191         lda     $8, 0x3fff
192         lda     $26, ret_from_sys_call
193         bic     $sp, $8, $8
194         mov     $sp, $18
195         jsr     $31, do_entArith
196 CFI_END_OSF_FRAME entArith
197
198 CFI_START_OSF_FRAME entMM
199         SAVE_ALL
200 /* save $9 - $15 so the inline exception code can manipulate them.  */
201         subq    $sp, 56, $sp
202         .cfi_adjust_cfa_offset  56
203         stq     $9, 0($sp)
204         stq     $10, 8($sp)
205         stq     $11, 16($sp)
206         stq     $12, 24($sp)
207         stq     $13, 32($sp)
208         stq     $14, 40($sp)
209         stq     $15, 48($sp)
210         .cfi_rel_offset $9, 0
211         .cfi_rel_offset $10, 8
212         .cfi_rel_offset $11, 16
213         .cfi_rel_offset $12, 24
214         .cfi_rel_offset $13, 32
215         .cfi_rel_offset $14, 40
216         .cfi_rel_offset $15, 48
217         addq    $sp, 56, $19
218 /* handle the fault */
219         lda     $8, 0x3fff
220         bic     $sp, $8, $8
221         jsr     $26, do_page_fault
222 /* reload the registers after the exception code played.  */
223         ldq     $9, 0($sp)
224         ldq     $10, 8($sp)
225         ldq     $11, 16($sp)
226         ldq     $12, 24($sp)
227         ldq     $13, 32($sp)
228         ldq     $14, 40($sp)
229         ldq     $15, 48($sp)
230         addq    $sp, 56, $sp
231         .cfi_restore    $9
232         .cfi_restore    $10
233         .cfi_restore    $11
234         .cfi_restore    $12
235         .cfi_restore    $13
236         .cfi_restore    $14
237         .cfi_restore    $15
238         .cfi_adjust_cfa_offset  -56
239 /* finish up the syscall as normal.  */
240         br      ret_from_sys_call
241 CFI_END_OSF_FRAME entMM
242
243 CFI_START_OSF_FRAME entIF
244         SAVE_ALL
245         lda     $8, 0x3fff
246         lda     $26, ret_from_sys_call
247         bic     $sp, $8, $8
248         mov     $sp, $17
249         jsr     $31, do_entIF
250 CFI_END_OSF_FRAME entIF
251
252 CFI_START_OSF_FRAME entUna
253         lda     $sp, -256($sp)
254         .cfi_adjust_cfa_offset  256
255         stq     $0, 0($sp)
256         .cfi_rel_offset $0, 0
257         .cfi_remember_state
258         ldq     $0, 256($sp)    /* get PS */
259         stq     $1, 8($sp)
260         stq     $2, 16($sp)
261         stq     $3, 24($sp)
262         and     $0, 8, $0               /* user mode? */
263         stq     $4, 32($sp)
264         bne     $0, entUnaUser  /* yup -> do user-level unaligned fault */
265         stq     $5, 40($sp)
266         stq     $6, 48($sp)
267         stq     $7, 56($sp)
268         stq     $8, 64($sp)
269         stq     $9, 72($sp)
270         stq     $10, 80($sp)
271         stq     $11, 88($sp)
272         stq     $12, 96($sp)
273         stq     $13, 104($sp)
274         stq     $14, 112($sp)
275         stq     $15, 120($sp)
276         /* 16-18 PAL-saved */
277         stq     $19, 152($sp)
278         stq     $20, 160($sp)
279         stq     $21, 168($sp)
280         stq     $22, 176($sp)
281         stq     $23, 184($sp)
282         stq     $24, 192($sp)
283         stq     $25, 200($sp)
284         stq     $26, 208($sp)
285         stq     $27, 216($sp)
286         stq     $28, 224($sp)
287         mov     $sp, $19
288         stq     $gp, 232($sp)
289         .cfi_rel_offset $1, 1*8
290         .cfi_rel_offset $2, 2*8
291         .cfi_rel_offset $3, 3*8
292         .cfi_rel_offset $4, 4*8
293         .cfi_rel_offset $5, 5*8
294         .cfi_rel_offset $6, 6*8
295         .cfi_rel_offset $7, 7*8
296         .cfi_rel_offset $8, 8*8
297         .cfi_rel_offset $9, 9*8
298         .cfi_rel_offset $10, 10*8
299         .cfi_rel_offset $11, 11*8
300         .cfi_rel_offset $12, 12*8
301         .cfi_rel_offset $13, 13*8
302         .cfi_rel_offset $14, 14*8
303         .cfi_rel_offset $15, 15*8
304         .cfi_rel_offset $19, 19*8
305         .cfi_rel_offset $20, 20*8
306         .cfi_rel_offset $21, 21*8
307         .cfi_rel_offset $22, 22*8
308         .cfi_rel_offset $23, 23*8
309         .cfi_rel_offset $24, 24*8
310         .cfi_rel_offset $25, 25*8
311         .cfi_rel_offset $26, 26*8
312         .cfi_rel_offset $27, 27*8
313         .cfi_rel_offset $28, 28*8
314         .cfi_rel_offset $29, 29*8
315         lda     $8, 0x3fff
316         stq     $31, 248($sp)
317         bic     $sp, $8, $8
318         jsr     $26, do_entUna
319         ldq     $0, 0($sp)
320         ldq     $1, 8($sp)
321         ldq     $2, 16($sp)
322         ldq     $3, 24($sp)
323         ldq     $4, 32($sp)
324         ldq     $5, 40($sp)
325         ldq     $6, 48($sp)
326         ldq     $7, 56($sp)
327         ldq     $8, 64($sp)
328         ldq     $9, 72($sp)
329         ldq     $10, 80($sp)
330         ldq     $11, 88($sp)
331         ldq     $12, 96($sp)
332         ldq     $13, 104($sp)
333         ldq     $14, 112($sp)
334         ldq     $15, 120($sp)
335         /* 16-18 PAL-saved */
336         ldq     $19, 152($sp)
337         ldq     $20, 160($sp)
338         ldq     $21, 168($sp)
339         ldq     $22, 176($sp)
340         ldq     $23, 184($sp)
341         ldq     $24, 192($sp)
342         ldq     $25, 200($sp)
343         ldq     $26, 208($sp)
344         ldq     $27, 216($sp)
345         ldq     $28, 224($sp)
346         ldq     $gp, 232($sp)
347         lda     $sp, 256($sp)
348         .cfi_restore    $1
349         .cfi_restore    $2
350         .cfi_restore    $3
351         .cfi_restore    $4
352         .cfi_restore    $5
353         .cfi_restore    $6
354         .cfi_restore    $7
355         .cfi_restore    $8
356         .cfi_restore    $9
357         .cfi_restore    $10
358         .cfi_restore    $11
359         .cfi_restore    $12
360         .cfi_restore    $13
361         .cfi_restore    $14
362         .cfi_restore    $15
363         .cfi_restore    $19
364         .cfi_restore    $20
365         .cfi_restore    $21
366         .cfi_restore    $22
367         .cfi_restore    $23
368         .cfi_restore    $24
369         .cfi_restore    $25
370         .cfi_restore    $26
371         .cfi_restore    $27
372         .cfi_restore    $28
373         .cfi_restore    $29
374         .cfi_adjust_cfa_offset  -256
375         call_pal PAL_rti
376
377         .align  4
378 entUnaUser:
379         .cfi_restore_state
380         ldq     $0, 0($sp)      /* restore original $0 */
381         lda     $sp, 256($sp)   /* pop entUna's stack frame */
382         .cfi_restore    $0
383         .cfi_adjust_cfa_offset  -256
384         SAVE_ALL                /* setup normal kernel stack */
385         lda     $sp, -56($sp)
386         .cfi_adjust_cfa_offset  56
387         stq     $9, 0($sp)
388         stq     $10, 8($sp)
389         stq     $11, 16($sp)
390         stq     $12, 24($sp)
391         stq     $13, 32($sp)
392         stq     $14, 40($sp)
393         stq     $15, 48($sp)
394         .cfi_rel_offset $9, 0
395         .cfi_rel_offset $10, 8
396         .cfi_rel_offset $11, 16
397         .cfi_rel_offset $12, 24
398         .cfi_rel_offset $13, 32
399         .cfi_rel_offset $14, 40
400         .cfi_rel_offset $15, 48
401         lda     $8, 0x3fff
402         addq    $sp, 56, $19
403         bic     $sp, $8, $8
404         jsr     $26, do_entUnaUser
405         ldq     $9, 0($sp)
406         ldq     $10, 8($sp)
407         ldq     $11, 16($sp)
408         ldq     $12, 24($sp)
409         ldq     $13, 32($sp)
410         ldq     $14, 40($sp)
411         ldq     $15, 48($sp)
412         lda     $sp, 56($sp)
413         .cfi_restore    $9
414         .cfi_restore    $10
415         .cfi_restore    $11
416         .cfi_restore    $12
417         .cfi_restore    $13
418         .cfi_restore    $14
419         .cfi_restore    $15
420         .cfi_adjust_cfa_offset  -56
421         br      ret_from_sys_call
422 CFI_END_OSF_FRAME entUna
423
424 CFI_START_OSF_FRAME entDbg
425         SAVE_ALL
426         lda     $8, 0x3fff
427         lda     $26, ret_from_sys_call
428         bic     $sp, $8, $8
429         mov     $sp, $16
430         jsr     $31, do_entDbg
431 CFI_END_OSF_FRAME entDbg
432 \f
433 /*
434  * The system call entry point is special.  Most importantly, it looks
435  * like a function call to userspace as far as clobbered registers.  We
436  * do preserve the argument registers (for syscall restarts) and $26
437  * (for leaf syscall functions).
438  *
439  * So much for theory.  We don't take advantage of this yet.
440  *
441  * Note that a0-a2 are not saved by PALcode as with the other entry points.
442  */
443
444         .align  4
445         .globl  entSys
446         .type   entSys, @function
447         .cfi_startproc simple
448         .cfi_return_column 64
449         .cfi_def_cfa    $sp, 48
450         .cfi_rel_offset 64, 8
451         .cfi_rel_offset $gp, 16
452 entSys:
453         SAVE_ALL
454         lda     $8, 0x3fff
455         bic     $sp, $8, $8
456         lda     $4, NR_SYSCALLS($31)
457         stq     $16, SP_OFF+24($sp)
458         lda     $5, sys_call_table
459         lda     $27, sys_ni_syscall
460         cmpult  $0, $4, $4
461         ldl     $3, TI_FLAGS($8)
462         stq     $17, SP_OFF+32($sp)
463         s8addq  $0, $5, $5
464         stq     $18, SP_OFF+40($sp)
465         .cfi_rel_offset $16, SP_OFF+24
466         .cfi_rel_offset $17, SP_OFF+32
467         .cfi_rel_offset $18, SP_OFF+40
468         blbs    $3, strace
469         beq     $4, 1f
470         ldq     $27, 0($5)
471 1:      jsr     $26, ($27), alpha_ni_syscall
472         ldgp    $gp, 0($26)
473         blt     $0, $syscall_error      /* the call failed */
474         stq     $0, 0($sp)
475         stq     $31, 72($sp)            /* a3=0 => no error */
476
477         .align  4
478         .globl  ret_from_sys_call
479 ret_from_sys_call:
480         cmovne  $26, 0, $18             /* $18 = 0 => non-restartable */
481         ldq     $0, SP_OFF($sp)
482         and     $0, 8, $0
483         beq     $0, ret_to_kernel
484 ret_to_user:
485         /* Make sure need_resched and sigpending don't change between
486                 sampling and the rti.  */
487         lda     $16, 7
488         call_pal PAL_swpipl
489         ldl     $17, TI_FLAGS($8)
490         and     $17, _TIF_WORK_MASK, $2
491         bne     $2, work_pending
492 restore_all:
493         .cfi_remember_state
494         RESTORE_ALL
495         call_pal PAL_rti
496
497 ret_to_kernel:
498         .cfi_restore_state
499         lda     $16, 7
500         call_pal PAL_swpipl
501         br restore_all
502
503         .align 3
504 $syscall_error:
505         /*
506          * Some system calls (e.g., ptrace) can return arbitrary
507          * values which might normally be mistaken as error numbers.
508          * Those functions must zero $0 (v0) directly in the stack
509          * frame to indicate that a negative return value wasn't an
510          * error number..
511          */
512         ldq     $18, 0($sp)     /* old syscall nr (zero if success) */
513         beq     $18, $ret_success
514
515         ldq     $19, 72($sp)    /* .. and this a3 */
516         subq    $31, $0, $0     /* with error in v0 */
517         addq    $31, 1, $1      /* set a3 for errno return */
518         stq     $0, 0($sp)
519         mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
520         stq     $1, 72($sp)     /* a3 for return */
521         br      ret_from_sys_call
522
523 $ret_success:
524         stq     $0, 0($sp)
525         stq     $31, 72($sp)    /* a3=0 => no error */
526         br      ret_from_sys_call
527
528 /*
529  * Do all cleanup when returning from all interrupts and system calls.
530  *
531  * Arguments:
532  *       $8: current.
533  *      $17: TI_FLAGS.
534  *      $18: The old syscall number, or zero if this is not a return
535  *           from a syscall that errored and is possibly restartable.
536  *      $19: The old a3 value
537  */
538
539         .align  4
540         .type   work_pending, @function
541 work_pending:
542         and     $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2
543         bne     $2, $work_notifysig
544
545 $work_resched:
546         /*
547          * We can get here only if we returned from syscall without SIGPENDING
548          * or got through work_notifysig already.  Either case means no syscall
549          * restarts for us, so let $18 and $19 burn.
550          */
551         jsr     $26, schedule
552         mov     0, $18
553         br      ret_to_user
554
555 $work_notifysig:
556         mov     $sp, $16
557         DO_SWITCH_STACK
558         jsr     $26, do_work_pending
559         UNDO_SWITCH_STACK
560         br      restore_all
561
562 /*
563  * PTRACE syscall handler
564  */
565
566         .align  4
567         .type   strace, @function
568 strace:
569         /* set up signal stack, call syscall_trace */
570         DO_SWITCH_STACK
571         jsr     $26, syscall_trace_enter /* returns the syscall number */
572         UNDO_SWITCH_STACK
573
574         /* get the arguments back.. */
575         ldq     $16, SP_OFF+24($sp)
576         ldq     $17, SP_OFF+32($sp)
577         ldq     $18, SP_OFF+40($sp)
578         ldq     $19, 72($sp)
579         ldq     $20, 80($sp)
580         ldq     $21, 88($sp)
581
582         /* get the system call pointer.. */
583         lda     $1, NR_SYSCALLS($31)
584         lda     $2, sys_call_table
585         lda     $27, alpha_ni_syscall
586         cmpult  $0, $1, $1
587         s8addq  $0, $2, $2
588         beq     $1, 1f
589         ldq     $27, 0($2)
590 1:      jsr     $26, ($27), sys_gettimeofday
591 ret_from_straced:
592         ldgp    $gp, 0($26)
593
594         /* check return.. */
595         blt     $0, $strace_error       /* the call failed */
596         stq     $31, 72($sp)            /* a3=0 => no error */
597 $strace_success:
598         stq     $0, 0($sp)              /* save return value */
599
600         DO_SWITCH_STACK
601         jsr     $26, syscall_trace_leave
602         UNDO_SWITCH_STACK
603         br      $31, ret_from_sys_call
604
605         .align  3
606 $strace_error:
607         ldq     $18, 0($sp)     /* old syscall nr (zero if success) */
608         beq     $18, $strace_success
609         ldq     $19, 72($sp)    /* .. and this a3 */
610
611         subq    $31, $0, $0     /* with error in v0 */
612         addq    $31, 1, $1      /* set a3 for errno return */
613         stq     $0, 0($sp)
614         stq     $1, 72($sp)     /* a3 for return */
615
616         DO_SWITCH_STACK
617         mov     $18, $9         /* save old syscall number */
618         mov     $19, $10        /* save old a3 */
619         jsr     $26, syscall_trace_leave
620         mov     $9, $18
621         mov     $10, $19
622         UNDO_SWITCH_STACK
623
624         mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
625         br      ret_from_sys_call
626 CFI_END_OSF_FRAME entSys
627 \f
628 /*
629  * Save and restore the switch stack -- aka the balance of the user context.
630  */
631
632         .align  4
633         .type   do_switch_stack, @function
634         .cfi_startproc simple
635         .cfi_return_column 64
636         .cfi_def_cfa $sp, 0
637         .cfi_register 64, $1
638 do_switch_stack:
639         lda     $sp, -SWITCH_STACK_SIZE($sp)
640         .cfi_adjust_cfa_offset  SWITCH_STACK_SIZE
641         stq     $9, 0($sp)
642         stq     $10, 8($sp)
643         stq     $11, 16($sp)
644         stq     $12, 24($sp)
645         stq     $13, 32($sp)
646         stq     $14, 40($sp)
647         stq     $15, 48($sp)
648         stq     $26, 56($sp)
649         stt     $f0, 64($sp)
650         stt     $f1, 72($sp)
651         stt     $f2, 80($sp)
652         stt     $f3, 88($sp)
653         stt     $f4, 96($sp)
654         stt     $f5, 104($sp)
655         stt     $f6, 112($sp)
656         stt     $f7, 120($sp)
657         stt     $f8, 128($sp)
658         stt     $f9, 136($sp)
659         stt     $f10, 144($sp)
660         stt     $f11, 152($sp)
661         stt     $f12, 160($sp)
662         stt     $f13, 168($sp)
663         stt     $f14, 176($sp)
664         stt     $f15, 184($sp)
665         stt     $f16, 192($sp)
666         stt     $f17, 200($sp)
667         stt     $f18, 208($sp)
668         stt     $f19, 216($sp)
669         stt     $f20, 224($sp)
670         stt     $f21, 232($sp)
671         stt     $f22, 240($sp)
672         stt     $f23, 248($sp)
673         stt     $f24, 256($sp)
674         stt     $f25, 264($sp)
675         stt     $f26, 272($sp)
676         stt     $f27, 280($sp)
677         mf_fpcr $f0             # get fpcr
678         stt     $f28, 288($sp)
679         stt     $f29, 296($sp)
680         stt     $f30, 304($sp)
681         stt     $f0, 312($sp)   # save fpcr in slot of $f31
682         ldt     $f0, 64($sp)    # dont let "do_switch_stack" change fp state.
683         ret     $31, ($1), 1
684         .cfi_endproc
685         .size   do_switch_stack, .-do_switch_stack
686
687         .align  4
688         .type   undo_switch_stack, @function
689         .cfi_startproc simple
690         .cfi_def_cfa $sp, 0
691         .cfi_register 64, $1
692 undo_switch_stack:
693         ldq     $9, 0($sp)
694         ldq     $10, 8($sp)
695         ldq     $11, 16($sp)
696         ldq     $12, 24($sp)
697         ldq     $13, 32($sp)
698         ldq     $14, 40($sp)
699         ldq     $15, 48($sp)
700         ldq     $26, 56($sp)
701         ldt     $f30, 312($sp)  # get saved fpcr
702         ldt     $f0, 64($sp)
703         ldt     $f1, 72($sp)
704         ldt     $f2, 80($sp)
705         ldt     $f3, 88($sp)
706         mt_fpcr $f30            # install saved fpcr
707         ldt     $f4, 96($sp)
708         ldt     $f5, 104($sp)
709         ldt     $f6, 112($sp)
710         ldt     $f7, 120($sp)
711         ldt     $f8, 128($sp)
712         ldt     $f9, 136($sp)
713         ldt     $f10, 144($sp)
714         ldt     $f11, 152($sp)
715         ldt     $f12, 160($sp)
716         ldt     $f13, 168($sp)
717         ldt     $f14, 176($sp)
718         ldt     $f15, 184($sp)
719         ldt     $f16, 192($sp)
720         ldt     $f17, 200($sp)
721         ldt     $f18, 208($sp)
722         ldt     $f19, 216($sp)
723         ldt     $f20, 224($sp)
724         ldt     $f21, 232($sp)
725         ldt     $f22, 240($sp)
726         ldt     $f23, 248($sp)
727         ldt     $f24, 256($sp)
728         ldt     $f25, 264($sp)
729         ldt     $f26, 272($sp)
730         ldt     $f27, 280($sp)
731         ldt     $f28, 288($sp)
732         ldt     $f29, 296($sp)
733         ldt     $f30, 304($sp)
734         lda     $sp, SWITCH_STACK_SIZE($sp)
735         ret     $31, ($1), 1
736         .cfi_endproc
737         .size   undo_switch_stack, .-undo_switch_stack
738 \f
739 /*
740  * The meat of the context switch code.
741  */
742
743         .align  4
744         .globl  alpha_switch_to
745         .type   alpha_switch_to, @function
746         .cfi_startproc
747 alpha_switch_to:
748         DO_SWITCH_STACK
749         call_pal PAL_swpctx
750         lda     $8, 0x3fff
751         UNDO_SWITCH_STACK
752         bic     $sp, $8, $8
753         mov     $17, $0
754         ret
755         .cfi_endproc
756         .size   alpha_switch_to, .-alpha_switch_to
757
758 /*
759  * New processes begin life here.
760  */
761
762         .globl  ret_from_fork
763         .align  4
764         .ent    ret_from_fork
765 ret_from_fork:
766         lda     $26, ret_from_sys_call
767         mov     $17, $16
768         jmp     $31, schedule_tail
769 .end ret_from_fork
770
771 /*
772  * ... and new kernel threads - here
773  */
774         .align 4
775         .globl  ret_from_kernel_thread
776         .ent    ret_from_kernel_thread
777 ret_from_kernel_thread:
778         mov     $17, $16
779         jsr     $26, schedule_tail
780         mov     $9, $27
781         mov     $10, $16
782         jsr     $26, ($9)
783         mov     $31, $19                /* to disable syscall restarts */
784         br      $31, ret_to_user
785 .end ret_from_kernel_thread
786
787 \f
788 /*
789  * Special system calls.  Most of these are special in that they either
790  * have to play switch_stack games or in some way use the pt_regs struct.
791  */
792
793 .macro  fork_like name
794         .align  4
795         .globl  alpha_\name
796         .ent    alpha_\name
797 alpha_\name:
798         .prologue 0
799         bsr     $1, do_switch_stack
800         jsr     $26, sys_\name
801         ldq     $26, 56($sp)
802         lda     $sp, SWITCH_STACK_SIZE($sp)
803         ret
804 .end    alpha_\name
805 .endm
806
807 fork_like fork
808 fork_like vfork
809 fork_like clone
810
811         .align  4
812         .globl  sys_sigreturn
813         .ent    sys_sigreturn
814 sys_sigreturn:
815         .prologue 0
816         lda     $9, ret_from_straced
817         cmpult  $26, $9, $9
818         lda     $sp, -SWITCH_STACK_SIZE($sp)
819         jsr     $26, do_sigreturn
820         bne     $9, 1f
821         jsr     $26, syscall_trace_leave
822 1:      br      $1, undo_switch_stack
823         br      ret_from_sys_call
824 .end sys_sigreturn
825
826         .align  4
827         .globl  sys_rt_sigreturn
828         .ent    sys_rt_sigreturn
829 sys_rt_sigreturn:
830         .prologue 0
831         lda     $9, ret_from_straced
832         cmpult  $26, $9, $9
833         lda     $sp, -SWITCH_STACK_SIZE($sp)
834         jsr     $26, do_rt_sigreturn
835         bne     $9, 1f
836         jsr     $26, syscall_trace_leave
837 1:      br      $1, undo_switch_stack
838         br      ret_from_sys_call
839 .end sys_rt_sigreturn
840
841         .align  4
842         .globl  alpha_ni_syscall
843         .ent    alpha_ni_syscall
844 alpha_ni_syscall:
845         .prologue 0
846         /* Special because it also implements overflow handling via
847            syscall number 0.  And if you recall, zero is a special
848            trigger for "not an error".  Store large non-zero there.  */
849         lda     $0, -ENOSYS
850         unop
851         stq     $0, 0($sp)
852         ret
853 .end alpha_ni_syscall