xref: /openbmc/linux/arch/alpha/kernel/entry.S (revision 05096666)
1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds/*
31da177e4SLinus Torvalds * arch/alpha/kernel/entry.S
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds * Kernel entry-points.
61da177e4SLinus Torvalds */
71da177e4SLinus Torvalds
8e2d5df93SSam Ravnborg#include <asm/asm-offsets.h>
91da177e4SLinus Torvalds#include <asm/thread_info.h>
101da177e4SLinus Torvalds#include <asm/pal.h>
111da177e4SLinus Torvalds#include <asm/errno.h>
121da177e4SLinus Torvalds#include <asm/unistd.h>
131da177e4SLinus Torvalds
141da177e4SLinus Torvalds	.text
151da177e4SLinus Torvalds	.set noat
16231b0bedSRichard Henderson	.cfi_sections	.debug_frame
171da177e4SLinus Torvalds
181da177e4SLinus Torvalds/* Stack offsets.  */
191da177e4SLinus Torvalds#define SP_OFF			184
20*05096666SAl Viro#define SWITCH_STACK_SIZE	64
211da177e4SLinus Torvalds
22231b0bedSRichard Henderson.macro	CFI_START_OSF_FRAME	func
23231b0bedSRichard Henderson	.align	4
24231b0bedSRichard Henderson	.globl	\func
25231b0bedSRichard Henderson	.type	\func,@function
26231b0bedSRichard Henderson\func:
27231b0bedSRichard Henderson	.cfi_startproc simple
28231b0bedSRichard Henderson	.cfi_return_column 64
29231b0bedSRichard Henderson	.cfi_def_cfa	$sp, 48
30231b0bedSRichard Henderson	.cfi_rel_offset	64, 8
31231b0bedSRichard Henderson	.cfi_rel_offset	$gp, 16
32231b0bedSRichard Henderson	.cfi_rel_offset	$16, 24
33231b0bedSRichard Henderson	.cfi_rel_offset	$17, 32
34231b0bedSRichard Henderson	.cfi_rel_offset	$18, 40
35231b0bedSRichard Henderson.endm
36231b0bedSRichard Henderson
37231b0bedSRichard Henderson.macro	CFI_END_OSF_FRAME	func
38231b0bedSRichard Henderson	.cfi_endproc
39231b0bedSRichard Henderson	.size	\func, . - \func
40231b0bedSRichard Henderson.endm
41231b0bedSRichard Henderson
421da177e4SLinus Torvalds/*
431da177e4SLinus Torvalds * This defines the normal kernel pt-regs layout.
441da177e4SLinus Torvalds *
451da177e4SLinus Torvalds * regs 9-15 preserved by C code
461da177e4SLinus Torvalds * regs 16-18 saved by PAL-code
471da177e4SLinus Torvalds * regs 29-30 saved and set up by PAL-code
481da177e4SLinus Torvalds * JRP - Save regs 16-18 in a special area of the stack, so that
491da177e4SLinus Torvalds * the palcode-provided values are available to the signal handler.
501da177e4SLinus Torvalds */
511da177e4SLinus Torvalds
52231b0bedSRichard Henderson.macro	SAVE_ALL
53231b0bedSRichard Henderson	subq	$sp, SP_OFF, $sp
54231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	SP_OFF
55231b0bedSRichard Henderson	stq	$0, 0($sp)
56231b0bedSRichard Henderson	stq	$1, 8($sp)
57231b0bedSRichard Henderson	stq	$2, 16($sp)
58231b0bedSRichard Henderson	stq	$3, 24($sp)
59231b0bedSRichard Henderson	stq	$4, 32($sp)
60231b0bedSRichard Henderson	stq	$28, 144($sp)
61231b0bedSRichard Henderson	.cfi_rel_offset	$0, 0
62231b0bedSRichard Henderson	.cfi_rel_offset $1, 8
63231b0bedSRichard Henderson	.cfi_rel_offset	$2, 16
64231b0bedSRichard Henderson	.cfi_rel_offset	$3, 24
65231b0bedSRichard Henderson	.cfi_rel_offset	$4, 32
66231b0bedSRichard Henderson	.cfi_rel_offset	$28, 144
67231b0bedSRichard Henderson	lda	$2, alpha_mv
68231b0bedSRichard Henderson	stq	$5, 40($sp)
69231b0bedSRichard Henderson	stq	$6, 48($sp)
70231b0bedSRichard Henderson	stq	$7, 56($sp)
71231b0bedSRichard Henderson	stq	$8, 64($sp)
72231b0bedSRichard Henderson	stq	$19, 72($sp)
73231b0bedSRichard Henderson	stq	$20, 80($sp)
74231b0bedSRichard Henderson	stq	$21, 88($sp)
75231b0bedSRichard Henderson	ldq	$2, HAE_CACHE($2)
76231b0bedSRichard Henderson	stq	$22, 96($sp)
77231b0bedSRichard Henderson	stq	$23, 104($sp)
78231b0bedSRichard Henderson	stq	$24, 112($sp)
79231b0bedSRichard Henderson	stq	$25, 120($sp)
80231b0bedSRichard Henderson	stq	$26, 128($sp)
81231b0bedSRichard Henderson	stq	$27, 136($sp)
82231b0bedSRichard Henderson	stq	$2, 152($sp)
83231b0bedSRichard Henderson	stq	$16, 160($sp)
84231b0bedSRichard Henderson	stq	$17, 168($sp)
851da177e4SLinus Torvalds	stq	$18, 176($sp)
86231b0bedSRichard Henderson	.cfi_rel_offset	$5, 40
87231b0bedSRichard Henderson	.cfi_rel_offset	$6, 48
88231b0bedSRichard Henderson	.cfi_rel_offset	$7, 56
89231b0bedSRichard Henderson	.cfi_rel_offset	$8, 64
90231b0bedSRichard Henderson	.cfi_rel_offset $19, 72
91231b0bedSRichard Henderson	.cfi_rel_offset	$20, 80
92231b0bedSRichard Henderson	.cfi_rel_offset	$21, 88
93231b0bedSRichard Henderson	.cfi_rel_offset $22, 96
94231b0bedSRichard Henderson	.cfi_rel_offset	$23, 104
95231b0bedSRichard Henderson	.cfi_rel_offset	$24, 112
96231b0bedSRichard Henderson	.cfi_rel_offset	$25, 120
97231b0bedSRichard Henderson	.cfi_rel_offset	$26, 128
98231b0bedSRichard Henderson	.cfi_rel_offset	$27, 136
99231b0bedSRichard Henderson.endm
1001da177e4SLinus Torvalds
101231b0bedSRichard Henderson.macro	RESTORE_ALL
102231b0bedSRichard Henderson	lda	$19, alpha_mv
103231b0bedSRichard Henderson	ldq	$0, 0($sp)
104231b0bedSRichard Henderson	ldq	$1, 8($sp)
105231b0bedSRichard Henderson	ldq	$2, 16($sp)
106231b0bedSRichard Henderson	ldq	$3, 24($sp)
107231b0bedSRichard Henderson	ldq	$21, 152($sp)
108231b0bedSRichard Henderson	ldq	$20, HAE_CACHE($19)
109231b0bedSRichard Henderson	ldq	$4, 32($sp)
110231b0bedSRichard Henderson	ldq	$5, 40($sp)
111231b0bedSRichard Henderson	ldq	$6, 48($sp)
112231b0bedSRichard Henderson	ldq	$7, 56($sp)
113231b0bedSRichard Henderson	subq	$20, $21, $20
114231b0bedSRichard Henderson	ldq	$8, 64($sp)
115231b0bedSRichard Henderson	beq	$20, 99f
116231b0bedSRichard Henderson	ldq	$20, HAE_REG($19)
117231b0bedSRichard Henderson	stq	$21, HAE_CACHE($19)
118231b0bedSRichard Henderson	stq	$21, 0($20)
119231b0bedSRichard Henderson99:	ldq	$19, 72($sp)
120231b0bedSRichard Henderson	ldq	$20, 80($sp)
121231b0bedSRichard Henderson	ldq	$21, 88($sp)
122231b0bedSRichard Henderson	ldq	$22, 96($sp)
123231b0bedSRichard Henderson	ldq	$23, 104($sp)
124231b0bedSRichard Henderson	ldq	$24, 112($sp)
125231b0bedSRichard Henderson	ldq	$25, 120($sp)
126231b0bedSRichard Henderson	ldq	$26, 128($sp)
127231b0bedSRichard Henderson	ldq	$27, 136($sp)
128231b0bedSRichard Henderson	ldq	$28, 144($sp)
1291da177e4SLinus Torvalds	addq	$sp, SP_OFF, $sp
130231b0bedSRichard Henderson	.cfi_restore	$0
131231b0bedSRichard Henderson	.cfi_restore	$1
132231b0bedSRichard Henderson	.cfi_restore	$2
133231b0bedSRichard Henderson	.cfi_restore	$3
134231b0bedSRichard Henderson	.cfi_restore	$4
135231b0bedSRichard Henderson	.cfi_restore	$5
136231b0bedSRichard Henderson	.cfi_restore	$6
137231b0bedSRichard Henderson	.cfi_restore	$7
138231b0bedSRichard Henderson	.cfi_restore	$8
139231b0bedSRichard Henderson	.cfi_restore	$19
140231b0bedSRichard Henderson	.cfi_restore	$20
141231b0bedSRichard Henderson	.cfi_restore	$21
142231b0bedSRichard Henderson	.cfi_restore	$22
143231b0bedSRichard Henderson	.cfi_restore	$23
144231b0bedSRichard Henderson	.cfi_restore	$24
145231b0bedSRichard Henderson	.cfi_restore	$25
146231b0bedSRichard Henderson	.cfi_restore	$26
147231b0bedSRichard Henderson	.cfi_restore	$27
148231b0bedSRichard Henderson	.cfi_restore	$28
149231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-SP_OFF
150231b0bedSRichard Henderson.endm
151231b0bedSRichard Henderson
152231b0bedSRichard Henderson.macro	DO_SWITCH_STACK
153231b0bedSRichard Henderson	bsr	$1, do_switch_stack
154231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	SWITCH_STACK_SIZE
155231b0bedSRichard Henderson	.cfi_rel_offset	$9, 0
156231b0bedSRichard Henderson	.cfi_rel_offset	$10, 8
157231b0bedSRichard Henderson	.cfi_rel_offset	$11, 16
158231b0bedSRichard Henderson	.cfi_rel_offset	$12, 24
159231b0bedSRichard Henderson	.cfi_rel_offset	$13, 32
160231b0bedSRichard Henderson	.cfi_rel_offset	$14, 40
161231b0bedSRichard Henderson	.cfi_rel_offset	$15, 48
162231b0bedSRichard Henderson.endm
163231b0bedSRichard Henderson
164231b0bedSRichard Henderson.macro	UNDO_SWITCH_STACK
165231b0bedSRichard Henderson	bsr	$1, undo_switch_stack
166231b0bedSRichard Henderson	.cfi_restore	$9
167231b0bedSRichard Henderson	.cfi_restore	$10
168231b0bedSRichard Henderson	.cfi_restore	$11
169231b0bedSRichard Henderson	.cfi_restore	$12
170231b0bedSRichard Henderson	.cfi_restore	$13
171231b0bedSRichard Henderson	.cfi_restore	$14
172231b0bedSRichard Henderson	.cfi_restore	$15
173231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-SWITCH_STACK_SIZE
174231b0bedSRichard Henderson.endm
1751da177e4SLinus Torvalds
1761da177e4SLinus Torvalds/*
1771da177e4SLinus Torvalds * Non-syscall kernel entry points.
1781da177e4SLinus Torvalds */
1791da177e4SLinus Torvalds
180231b0bedSRichard HendersonCFI_START_OSF_FRAME entInt
1811da177e4SLinus Torvalds	SAVE_ALL
1821da177e4SLinus Torvalds	lda	$8, 0x3fff
1831da177e4SLinus Torvalds	lda	$26, ret_from_sys_call
1841da177e4SLinus Torvalds	bic	$sp, $8, $8
1851da177e4SLinus Torvalds	mov	$sp, $19
1861da177e4SLinus Torvalds	jsr	$31, do_entInt
187231b0bedSRichard HendersonCFI_END_OSF_FRAME entInt
1881da177e4SLinus Torvalds
189231b0bedSRichard HendersonCFI_START_OSF_FRAME entArith
1901da177e4SLinus Torvalds	SAVE_ALL
1911da177e4SLinus Torvalds	lda	$8, 0x3fff
1921da177e4SLinus Torvalds	lda	$26, ret_from_sys_call
1931da177e4SLinus Torvalds	bic	$sp, $8, $8
1941da177e4SLinus Torvalds	mov	$sp, $18
1951da177e4SLinus Torvalds	jsr	$31, do_entArith
196231b0bedSRichard HendersonCFI_END_OSF_FRAME entArith
1971da177e4SLinus Torvalds
198231b0bedSRichard HendersonCFI_START_OSF_FRAME entMM
1991da177e4SLinus Torvalds	SAVE_ALL
2001da177e4SLinus Torvalds/* save $9 - $15 so the inline exception code can manipulate them.  */
2011da177e4SLinus Torvalds	subq	$sp, 56, $sp
202231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	56
2031da177e4SLinus Torvalds	stq	$9, 0($sp)
2041da177e4SLinus Torvalds	stq	$10, 8($sp)
2051da177e4SLinus Torvalds	stq	$11, 16($sp)
2061da177e4SLinus Torvalds	stq	$12, 24($sp)
2071da177e4SLinus Torvalds	stq	$13, 32($sp)
2081da177e4SLinus Torvalds	stq	$14, 40($sp)
2091da177e4SLinus Torvalds	stq	$15, 48($sp)
210231b0bedSRichard Henderson	.cfi_rel_offset	$9, 0
211231b0bedSRichard Henderson	.cfi_rel_offset	$10, 8
212231b0bedSRichard Henderson	.cfi_rel_offset	$11, 16
213231b0bedSRichard Henderson	.cfi_rel_offset	$12, 24
214231b0bedSRichard Henderson	.cfi_rel_offset	$13, 32
215231b0bedSRichard Henderson	.cfi_rel_offset	$14, 40
216231b0bedSRichard Henderson	.cfi_rel_offset	$15, 48
2171da177e4SLinus Torvalds	addq	$sp, 56, $19
2181da177e4SLinus Torvalds/* handle the fault */
2191da177e4SLinus Torvalds	lda	$8, 0x3fff
2201da177e4SLinus Torvalds	bic	$sp, $8, $8
2211da177e4SLinus Torvalds	jsr	$26, do_page_fault
2221da177e4SLinus Torvalds/* reload the registers after the exception code played.  */
2231da177e4SLinus Torvalds	ldq	$9, 0($sp)
2241da177e4SLinus Torvalds	ldq	$10, 8($sp)
2251da177e4SLinus Torvalds	ldq	$11, 16($sp)
2261da177e4SLinus Torvalds	ldq	$12, 24($sp)
2271da177e4SLinus Torvalds	ldq	$13, 32($sp)
2281da177e4SLinus Torvalds	ldq	$14, 40($sp)
2291da177e4SLinus Torvalds	ldq	$15, 48($sp)
2301da177e4SLinus Torvalds	addq	$sp, 56, $sp
231231b0bedSRichard Henderson	.cfi_restore	$9
232231b0bedSRichard Henderson	.cfi_restore	$10
233231b0bedSRichard Henderson	.cfi_restore	$11
234231b0bedSRichard Henderson	.cfi_restore	$12
235231b0bedSRichard Henderson	.cfi_restore	$13
236231b0bedSRichard Henderson	.cfi_restore	$14
237231b0bedSRichard Henderson	.cfi_restore	$15
238231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-56
2391da177e4SLinus Torvalds/* finish up the syscall as normal.  */
2401da177e4SLinus Torvalds	br	ret_from_sys_call
241231b0bedSRichard HendersonCFI_END_OSF_FRAME entMM
2421da177e4SLinus Torvalds
243231b0bedSRichard HendersonCFI_START_OSF_FRAME entIF
2441da177e4SLinus Torvalds	SAVE_ALL
2451da177e4SLinus Torvalds	lda	$8, 0x3fff
2461da177e4SLinus Torvalds	lda	$26, ret_from_sys_call
2471da177e4SLinus Torvalds	bic	$sp, $8, $8
2481da177e4SLinus Torvalds	mov	$sp, $17
2491da177e4SLinus Torvalds	jsr	$31, do_entIF
250231b0bedSRichard HendersonCFI_END_OSF_FRAME entIF
2511da177e4SLinus Torvalds
252231b0bedSRichard HendersonCFI_START_OSF_FRAME entUna
2531da177e4SLinus Torvalds	lda	$sp, -256($sp)
254231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	256
2551da177e4SLinus Torvalds	stq	$0, 0($sp)
256231b0bedSRichard Henderson	.cfi_rel_offset	$0, 0
257231b0bedSRichard Henderson	.cfi_remember_state
2581da177e4SLinus Torvalds	ldq	$0, 256($sp)	/* get PS */
2591da177e4SLinus Torvalds	stq	$1, 8($sp)
2601da177e4SLinus Torvalds	stq	$2, 16($sp)
2611da177e4SLinus Torvalds	stq	$3, 24($sp)
2621da177e4SLinus Torvalds	and	$0, 8, $0		/* user mode? */
2631da177e4SLinus Torvalds	stq	$4, 32($sp)
2641da177e4SLinus Torvalds	bne	$0, entUnaUser	/* yup -> do user-level unaligned fault */
2651da177e4SLinus Torvalds	stq	$5, 40($sp)
2661da177e4SLinus Torvalds	stq	$6, 48($sp)
2671da177e4SLinus Torvalds	stq	$7, 56($sp)
2681da177e4SLinus Torvalds	stq	$8, 64($sp)
2691da177e4SLinus Torvalds	stq	$9, 72($sp)
2701da177e4SLinus Torvalds	stq	$10, 80($sp)
2711da177e4SLinus Torvalds	stq	$11, 88($sp)
2721da177e4SLinus Torvalds	stq	$12, 96($sp)
2731da177e4SLinus Torvalds	stq	$13, 104($sp)
2741da177e4SLinus Torvalds	stq	$14, 112($sp)
2751da177e4SLinus Torvalds	stq	$15, 120($sp)
2761da177e4SLinus Torvalds	/* 16-18 PAL-saved */
2771da177e4SLinus Torvalds	stq	$19, 152($sp)
2781da177e4SLinus Torvalds	stq	$20, 160($sp)
2791da177e4SLinus Torvalds	stq	$21, 168($sp)
2801da177e4SLinus Torvalds	stq	$22, 176($sp)
2811da177e4SLinus Torvalds	stq	$23, 184($sp)
2821da177e4SLinus Torvalds	stq	$24, 192($sp)
2831da177e4SLinus Torvalds	stq	$25, 200($sp)
2841da177e4SLinus Torvalds	stq	$26, 208($sp)
2851da177e4SLinus Torvalds	stq	$27, 216($sp)
2861da177e4SLinus Torvalds	stq	$28, 224($sp)
287d70ddac1SRichard Henderson	mov	$sp, $19
2881da177e4SLinus Torvalds	stq	$gp, 232($sp)
289231b0bedSRichard Henderson	.cfi_rel_offset	$1, 1*8
290231b0bedSRichard Henderson	.cfi_rel_offset	$2, 2*8
291231b0bedSRichard Henderson	.cfi_rel_offset	$3, 3*8
292231b0bedSRichard Henderson	.cfi_rel_offset	$4, 4*8
293231b0bedSRichard Henderson	.cfi_rel_offset	$5, 5*8
294231b0bedSRichard Henderson	.cfi_rel_offset	$6, 6*8
295231b0bedSRichard Henderson	.cfi_rel_offset	$7, 7*8
296231b0bedSRichard Henderson	.cfi_rel_offset	$8, 8*8
297231b0bedSRichard Henderson	.cfi_rel_offset	$9, 9*8
298231b0bedSRichard Henderson	.cfi_rel_offset	$10, 10*8
299231b0bedSRichard Henderson	.cfi_rel_offset	$11, 11*8
300231b0bedSRichard Henderson	.cfi_rel_offset	$12, 12*8
301231b0bedSRichard Henderson	.cfi_rel_offset	$13, 13*8
302231b0bedSRichard Henderson	.cfi_rel_offset	$14, 14*8
303231b0bedSRichard Henderson	.cfi_rel_offset	$15, 15*8
304231b0bedSRichard Henderson	.cfi_rel_offset	$19, 19*8
305231b0bedSRichard Henderson	.cfi_rel_offset	$20, 20*8
306231b0bedSRichard Henderson	.cfi_rel_offset	$21, 21*8
307231b0bedSRichard Henderson	.cfi_rel_offset	$22, 22*8
308231b0bedSRichard Henderson	.cfi_rel_offset	$23, 23*8
309231b0bedSRichard Henderson	.cfi_rel_offset	$24, 24*8
310231b0bedSRichard Henderson	.cfi_rel_offset	$25, 25*8
311231b0bedSRichard Henderson	.cfi_rel_offset	$26, 26*8
312231b0bedSRichard Henderson	.cfi_rel_offset	$27, 27*8
313231b0bedSRichard Henderson	.cfi_rel_offset	$28, 28*8
314231b0bedSRichard Henderson	.cfi_rel_offset	$29, 29*8
3151da177e4SLinus Torvalds	lda	$8, 0x3fff
3161da177e4SLinus Torvalds	stq	$31, 248($sp)
3171da177e4SLinus Torvalds	bic	$sp, $8, $8
3181da177e4SLinus Torvalds	jsr	$26, do_entUna
3191da177e4SLinus Torvalds	ldq	$0, 0($sp)
3201da177e4SLinus Torvalds	ldq	$1, 8($sp)
3211da177e4SLinus Torvalds	ldq	$2, 16($sp)
3221da177e4SLinus Torvalds	ldq	$3, 24($sp)
3231da177e4SLinus Torvalds	ldq	$4, 32($sp)
3241da177e4SLinus Torvalds	ldq	$5, 40($sp)
3251da177e4SLinus Torvalds	ldq	$6, 48($sp)
3261da177e4SLinus Torvalds	ldq	$7, 56($sp)
3271da177e4SLinus Torvalds	ldq	$8, 64($sp)
3281da177e4SLinus Torvalds	ldq	$9, 72($sp)
3291da177e4SLinus Torvalds	ldq	$10, 80($sp)
3301da177e4SLinus Torvalds	ldq	$11, 88($sp)
3311da177e4SLinus Torvalds	ldq	$12, 96($sp)
3321da177e4SLinus Torvalds	ldq	$13, 104($sp)
3331da177e4SLinus Torvalds	ldq	$14, 112($sp)
3341da177e4SLinus Torvalds	ldq	$15, 120($sp)
3351da177e4SLinus Torvalds	/* 16-18 PAL-saved */
3361da177e4SLinus Torvalds	ldq	$19, 152($sp)
3371da177e4SLinus Torvalds	ldq	$20, 160($sp)
3381da177e4SLinus Torvalds	ldq	$21, 168($sp)
3391da177e4SLinus Torvalds	ldq	$22, 176($sp)
3401da177e4SLinus Torvalds	ldq	$23, 184($sp)
3411da177e4SLinus Torvalds	ldq	$24, 192($sp)
3421da177e4SLinus Torvalds	ldq	$25, 200($sp)
3431da177e4SLinus Torvalds	ldq	$26, 208($sp)
3441da177e4SLinus Torvalds	ldq	$27, 216($sp)
3451da177e4SLinus Torvalds	ldq	$28, 224($sp)
3461da177e4SLinus Torvalds	ldq	$gp, 232($sp)
3471da177e4SLinus Torvalds	lda	$sp, 256($sp)
348231b0bedSRichard Henderson	.cfi_restore	$1
349231b0bedSRichard Henderson	.cfi_restore	$2
350231b0bedSRichard Henderson	.cfi_restore	$3
351231b0bedSRichard Henderson	.cfi_restore	$4
352231b0bedSRichard Henderson	.cfi_restore	$5
353231b0bedSRichard Henderson	.cfi_restore	$6
354231b0bedSRichard Henderson	.cfi_restore	$7
355231b0bedSRichard Henderson	.cfi_restore	$8
356231b0bedSRichard Henderson	.cfi_restore	$9
357231b0bedSRichard Henderson	.cfi_restore	$10
358231b0bedSRichard Henderson	.cfi_restore	$11
359231b0bedSRichard Henderson	.cfi_restore	$12
360231b0bedSRichard Henderson	.cfi_restore	$13
361231b0bedSRichard Henderson	.cfi_restore	$14
362231b0bedSRichard Henderson	.cfi_restore	$15
363231b0bedSRichard Henderson	.cfi_restore	$19
364231b0bedSRichard Henderson	.cfi_restore	$20
365231b0bedSRichard Henderson	.cfi_restore	$21
366231b0bedSRichard Henderson	.cfi_restore	$22
367231b0bedSRichard Henderson	.cfi_restore	$23
368231b0bedSRichard Henderson	.cfi_restore	$24
369231b0bedSRichard Henderson	.cfi_restore	$25
370231b0bedSRichard Henderson	.cfi_restore	$26
371231b0bedSRichard Henderson	.cfi_restore	$27
372231b0bedSRichard Henderson	.cfi_restore	$28
373231b0bedSRichard Henderson	.cfi_restore	$29
374231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-256
3751da177e4SLinus Torvalds	call_pal PAL_rti
3761da177e4SLinus Torvalds
3771da177e4SLinus Torvalds	.align	4
3781da177e4SLinus TorvaldsentUnaUser:
379231b0bedSRichard Henderson	.cfi_restore_state
3801da177e4SLinus Torvalds	ldq	$0, 0($sp)	/* restore original $0 */
3811da177e4SLinus Torvalds	lda	$sp, 256($sp)	/* pop entUna's stack frame */
382231b0bedSRichard Henderson	.cfi_restore	$0
383231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-256
3841da177e4SLinus Torvalds	SAVE_ALL		/* setup normal kernel stack */
3851da177e4SLinus Torvalds	lda	$sp, -56($sp)
386231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	56
3871da177e4SLinus Torvalds	stq	$9, 0($sp)
3881da177e4SLinus Torvalds	stq	$10, 8($sp)
3891da177e4SLinus Torvalds	stq	$11, 16($sp)
3901da177e4SLinus Torvalds	stq	$12, 24($sp)
3911da177e4SLinus Torvalds	stq	$13, 32($sp)
3921da177e4SLinus Torvalds	stq	$14, 40($sp)
3931da177e4SLinus Torvalds	stq	$15, 48($sp)
394231b0bedSRichard Henderson	.cfi_rel_offset	$9, 0
395231b0bedSRichard Henderson	.cfi_rel_offset	$10, 8
396231b0bedSRichard Henderson	.cfi_rel_offset	$11, 16
397231b0bedSRichard Henderson	.cfi_rel_offset	$12, 24
398231b0bedSRichard Henderson	.cfi_rel_offset	$13, 32
399231b0bedSRichard Henderson	.cfi_rel_offset	$14, 40
400231b0bedSRichard Henderson	.cfi_rel_offset	$15, 48
4011da177e4SLinus Torvalds	lda	$8, 0x3fff
4021da177e4SLinus Torvalds	addq	$sp, 56, $19
4031da177e4SLinus Torvalds	bic	$sp, $8, $8
4041da177e4SLinus Torvalds	jsr	$26, do_entUnaUser
4051da177e4SLinus Torvalds	ldq	$9, 0($sp)
4061da177e4SLinus Torvalds	ldq	$10, 8($sp)
4071da177e4SLinus Torvalds	ldq	$11, 16($sp)
4081da177e4SLinus Torvalds	ldq	$12, 24($sp)
4091da177e4SLinus Torvalds	ldq	$13, 32($sp)
4101da177e4SLinus Torvalds	ldq	$14, 40($sp)
4111da177e4SLinus Torvalds	ldq	$15, 48($sp)
4121da177e4SLinus Torvalds	lda	$sp, 56($sp)
413231b0bedSRichard Henderson	.cfi_restore	$9
414231b0bedSRichard Henderson	.cfi_restore	$10
415231b0bedSRichard Henderson	.cfi_restore	$11
416231b0bedSRichard Henderson	.cfi_restore	$12
417231b0bedSRichard Henderson	.cfi_restore	$13
418231b0bedSRichard Henderson	.cfi_restore	$14
419231b0bedSRichard Henderson	.cfi_restore	$15
420231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-56
4211da177e4SLinus Torvalds	br	ret_from_sys_call
422231b0bedSRichard HendersonCFI_END_OSF_FRAME entUna
4231da177e4SLinus Torvalds
424231b0bedSRichard HendersonCFI_START_OSF_FRAME entDbg
4251da177e4SLinus Torvalds	SAVE_ALL
4261da177e4SLinus Torvalds	lda	$8, 0x3fff
4271da177e4SLinus Torvalds	lda	$26, ret_from_sys_call
4281da177e4SLinus Torvalds	bic	$sp, $8, $8
4291da177e4SLinus Torvalds	mov	$sp, $16
4301da177e4SLinus Torvalds	jsr	$31, do_entDbg
431231b0bedSRichard HendersonCFI_END_OSF_FRAME entDbg
4321da177e4SLinus Torvalds
4331da177e4SLinus Torvalds/*
4341da177e4SLinus Torvalds * The system call entry point is special.  Most importantly, it looks
4351da177e4SLinus Torvalds * like a function call to userspace as far as clobbered registers.  We
4361da177e4SLinus Torvalds * do preserve the argument registers (for syscall restarts) and $26
4371da177e4SLinus Torvalds * (for leaf syscall functions).
4381da177e4SLinus Torvalds *
4391da177e4SLinus Torvalds * So much for theory.  We don't take advantage of this yet.
4401da177e4SLinus Torvalds *
4411da177e4SLinus Torvalds * Note that a0-a2 are not saved by PALcode as with the other entry points.
4421da177e4SLinus Torvalds */
4431da177e4SLinus Torvalds
4441da177e4SLinus Torvalds	.align	4
4451da177e4SLinus Torvalds	.globl	entSys
446231b0bedSRichard Henderson	.type	entSys, @function
447231b0bedSRichard Henderson	.cfi_startproc simple
448231b0bedSRichard Henderson	.cfi_return_column 64
449231b0bedSRichard Henderson	.cfi_def_cfa	$sp, 48
450231b0bedSRichard Henderson	.cfi_rel_offset	64, 8
451231b0bedSRichard Henderson	.cfi_rel_offset	$gp, 16
4521da177e4SLinus TorvaldsentSys:
4531da177e4SLinus Torvalds	SAVE_ALL
4541da177e4SLinus Torvalds	lda	$8, 0x3fff
4551da177e4SLinus Torvalds	bic	$sp, $8, $8
456d6e59579SYang Yang	lda	$4, NR_syscalls($31)
4571da177e4SLinus Torvalds	stq	$16, SP_OFF+24($sp)
4581da177e4SLinus Torvalds	lda	$5, sys_call_table
4591da177e4SLinus Torvalds	lda	$27, sys_ni_syscall
4601da177e4SLinus Torvalds	cmpult	$0, $4, $4
4611da177e4SLinus Torvalds	ldl	$3, TI_FLAGS($8)
4621da177e4SLinus Torvalds	stq	$17, SP_OFF+32($sp)
4631da177e4SLinus Torvalds	s8addq	$0, $5, $5
4641da177e4SLinus Torvalds	stq	$18, SP_OFF+40($sp)
465231b0bedSRichard Henderson	.cfi_rel_offset	$16, SP_OFF+24
466231b0bedSRichard Henderson	.cfi_rel_offset	$17, SP_OFF+32
467231b0bedSRichard Henderson	.cfi_rel_offset	$18, SP_OFF+40
468a9302e84S蔡正龙#ifdef CONFIG_AUDITSYSCALL
469a9302e84S蔡正龙	lda     $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
470a9302e84S蔡正龙	and     $3, $6, $3
471a9302e84S蔡正龙	bne     $3, strace
472f7b2431aSAl Viro#else
473f7b2431aSAl Viro	blbs    $3, strace		/* check for SYSCALL_TRACE in disguise */
474f7b2431aSAl Viro#endif
4751da177e4SLinus Torvalds	beq	$4, 1f
4761da177e4SLinus Torvalds	ldq	$27, 0($5)
477060581c1SAl Viro1:	jsr	$26, ($27), sys_ni_syscall
4781da177e4SLinus Torvalds	ldgp	$gp, 0($26)
4791da177e4SLinus Torvalds	blt	$0, $syscall_error	/* the call failed */
480e778eaecSAl Viro$ret_success:
4811da177e4SLinus Torvalds	stq	$0, 0($sp)
4821da177e4SLinus Torvalds	stq	$31, 72($sp)		/* a3=0 => no error */
4831da177e4SLinus Torvalds
4841da177e4SLinus Torvalds	.align	4
485231b0bedSRichard Henderson	.globl	ret_from_sys_call
4861da177e4SLinus Torvaldsret_from_sys_call:
487cb450766SAl Viro	cmovne	$26, 0, $18		/* $18 = 0 => non-restartable */
4881da177e4SLinus Torvalds	ldq	$0, SP_OFF($sp)
4891da177e4SLinus Torvalds	and	$0, 8, $0
49077edffb6SAl Viro	beq	$0, ret_to_kernel
491494486a1SAl Viroret_to_user:
4921da177e4SLinus Torvalds	/* Make sure need_resched and sigpending don't change between
4931da177e4SLinus Torvalds		sampling and the rti.  */
4941da177e4SLinus Torvalds	lda	$16, 7
4951da177e4SLinus Torvalds	call_pal PAL_swpipl
496cb450766SAl Viro	ldl	$17, TI_FLAGS($8)
497cb450766SAl Viro	and	$17, _TIF_WORK_MASK, $2
498494486a1SAl Viro	bne	$2, work_pending
4991da177e4SLinus Torvaldsrestore_all:
500*05096666SAl Viro	ldl	$2, TI_STATUS($8)
501*05096666SAl Viro	and	$2, TS_SAVED_FP | TS_RESTORE_FP, $3
502*05096666SAl Viro	bne	$3, restore_fpu
503*05096666SAl Virorestore_other:
504231b0bedSRichard Henderson	.cfi_remember_state
5051da177e4SLinus Torvalds	RESTORE_ALL
5061da177e4SLinus Torvalds	call_pal PAL_rti
5071da177e4SLinus Torvalds
50877edffb6SAl Viroret_to_kernel:
509231b0bedSRichard Henderson	.cfi_restore_state
51077edffb6SAl Viro	lda	$16, 7
51177edffb6SAl Viro	call_pal PAL_swpipl
512*05096666SAl Viro	br restore_other
51377edffb6SAl Viro
5141da177e4SLinus Torvalds	.align 3
5151da177e4SLinus Torvalds$syscall_error:
5161da177e4SLinus Torvalds	/*
5171da177e4SLinus Torvalds	 * Some system calls (e.g., ptrace) can return arbitrary
5181da177e4SLinus Torvalds	 * values which might normally be mistaken as error numbers.
5191da177e4SLinus Torvalds	 * Those functions must zero $0 (v0) directly in the stack
5201da177e4SLinus Torvalds	 * frame to indicate that a negative return value wasn't an
5211da177e4SLinus Torvalds	 * error number..
5221da177e4SLinus Torvalds	 */
523cb450766SAl Viro	ldq	$18, 0($sp)	/* old syscall nr (zero if success) */
524cb450766SAl Viro	beq	$18, $ret_success
5251da177e4SLinus Torvalds
526cb450766SAl Viro	ldq	$19, 72($sp)	/* .. and this a3 */
5271da177e4SLinus Torvalds	subq	$31, $0, $0	/* with error in v0 */
5281da177e4SLinus Torvalds	addq	$31, 1, $1	/* set a3 for errno return */
5291da177e4SLinus Torvalds	stq	$0, 0($sp)
5301da177e4SLinus Torvalds	mov	$31, $26	/* tell "ret_from_sys_call" we can restart */
5311da177e4SLinus Torvalds	stq	$1, 72($sp)	/* a3 for return */
5321da177e4SLinus Torvalds	br	ret_from_sys_call
5331da177e4SLinus Torvalds
5341da177e4SLinus Torvalds/*
5351da177e4SLinus Torvalds * Do all cleanup when returning from all interrupts and system calls.
5361da177e4SLinus Torvalds *
5371da177e4SLinus Torvalds * Arguments:
5381da177e4SLinus Torvalds *       $8: current.
539cb450766SAl Viro *      $17: TI_FLAGS.
540cb450766SAl Viro *      $18: The old syscall number, or zero if this is not a return
5411da177e4SLinus Torvalds *           from a syscall that errored and is possibly restartable.
542cb450766SAl Viro *      $19: The old a3 value
5431da177e4SLinus Torvalds */
5441da177e4SLinus Torvalds
5451da177e4SLinus Torvalds	.align	4
546231b0bedSRichard Henderson	.type	work_pending, @function
5471da177e4SLinus Torvaldswork_pending:
5485a9a8897SJens Axboe	and	$17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL, $2
5497721d3c2SAl Viro	bne	$2, $work_notifysig
5501da177e4SLinus Torvalds
5511da177e4SLinus Torvalds$work_resched:
5527721d3c2SAl Viro	/*
5537721d3c2SAl Viro	 * We can get here only if we returned from syscall without SIGPENDING
5547721d3c2SAl Viro	 * or got through work_notifysig already.  Either case means no syscall
555cb450766SAl Viro	 * restarts for us, so let $18 and $19 burn.
5567721d3c2SAl Viro	 */
5571da177e4SLinus Torvalds	jsr	$26, schedule
558cb450766SAl Viro	mov	0, $18
5597721d3c2SAl Viro	br	ret_to_user
5601da177e4SLinus Torvalds
5611da177e4SLinus Torvalds$work_notifysig:
562b927b3e2SRichard Henderson	mov	$sp, $16
563231b0bedSRichard Henderson	DO_SWITCH_STACK
5646972d6f2SAl Viro	jsr	$26, do_work_pending
565231b0bedSRichard Henderson	UNDO_SWITCH_STACK
5666972d6f2SAl Viro	br	restore_all
5671da177e4SLinus Torvalds
5681da177e4SLinus Torvalds/*
5691da177e4SLinus Torvalds * PTRACE syscall handler
5701da177e4SLinus Torvalds */
5711da177e4SLinus Torvalds
5721da177e4SLinus Torvalds	.align	4
573231b0bedSRichard Henderson	.type	strace, @function
5741da177e4SLinus Torvaldsstrace:
5751da177e4SLinus Torvalds	/* set up signal stack, call syscall_trace */
576*05096666SAl Viro	// NB: if anyone adds preemption, this block will need to be protected
577*05096666SAl Viro	ldl	$1, TI_STATUS($8)
578*05096666SAl Viro	and	$1, TS_SAVED_FP, $3
579*05096666SAl Viro	or	$1, TS_SAVED_FP, $2
580*05096666SAl Viro	bne	$3, 1f
581*05096666SAl Viro	stl	$2, TI_STATUS($8)
582*05096666SAl Viro	bsr	$26, __save_fpu
583*05096666SAl Viro1:
584231b0bedSRichard Henderson	DO_SWITCH_STACK
58512f79be9SAl Viro	jsr	$26, syscall_trace_enter /* returns the syscall number */
586231b0bedSRichard Henderson	UNDO_SWITCH_STACK
5871da177e4SLinus Torvalds
58812f79be9SAl Viro	/* get the arguments back.. */
5891da177e4SLinus Torvalds	ldq	$16, SP_OFF+24($sp)
5901da177e4SLinus Torvalds	ldq	$17, SP_OFF+32($sp)
5911da177e4SLinus Torvalds	ldq	$18, SP_OFF+40($sp)
5921da177e4SLinus Torvalds	ldq	$19, 72($sp)
5931da177e4SLinus Torvalds	ldq	$20, 80($sp)
5941da177e4SLinus Torvalds	ldq	$21, 88($sp)
5951da177e4SLinus Torvalds
5961da177e4SLinus Torvalds	/* get the system call pointer.. */
597d6e59579SYang Yang	lda	$1, NR_syscalls($31)
5981da177e4SLinus Torvalds	lda	$2, sys_call_table
599060581c1SAl Viro	lda	$27, sys_ni_syscall
6001da177e4SLinus Torvalds	cmpult	$0, $1, $1
6011da177e4SLinus Torvalds	s8addq	$0, $2, $2
6021da177e4SLinus Torvalds	beq	$1, 1f
6031da177e4SLinus Torvalds	ldq	$27, 0($2)
6041da177e4SLinus Torvalds1:	jsr	$26, ($27), sys_gettimeofday
60553293638SAl Viroret_from_straced:
6061da177e4SLinus Torvalds	ldgp	$gp, 0($26)
6071da177e4SLinus Torvalds
6081da177e4SLinus Torvalds	/* check return.. */
6091da177e4SLinus Torvalds	blt	$0, $strace_error	/* the call failed */
6101da177e4SLinus Torvalds$strace_success:
61119a09e42SAl Viro	stq	$31, 72($sp)		/* a3=0 => no error */
6121da177e4SLinus Torvalds	stq	$0, 0($sp)		/* save return value */
6131da177e4SLinus Torvalds
614231b0bedSRichard Henderson	DO_SWITCH_STACK
61512f79be9SAl Viro	jsr	$26, syscall_trace_leave
616231b0bedSRichard Henderson	UNDO_SWITCH_STACK
6171da177e4SLinus Torvalds	br	$31, ret_from_sys_call
6181da177e4SLinus Torvalds
6191da177e4SLinus Torvalds	.align	3
6201da177e4SLinus Torvalds$strace_error:
621cb450766SAl Viro	ldq	$18, 0($sp)	/* old syscall nr (zero if success) */
622cb450766SAl Viro	beq	$18, $strace_success
623cb450766SAl Viro	ldq	$19, 72($sp)	/* .. and this a3 */
6241da177e4SLinus Torvalds
6251da177e4SLinus Torvalds	subq	$31, $0, $0	/* with error in v0 */
6261da177e4SLinus Torvalds	addq	$31, 1, $1	/* set a3 for errno return */
6271da177e4SLinus Torvalds	stq	$0, 0($sp)
6281da177e4SLinus Torvalds	stq	$1, 72($sp)	/* a3 for return */
6291da177e4SLinus Torvalds
630231b0bedSRichard Henderson	DO_SWITCH_STACK
631cb450766SAl Viro	mov	$18, $9		/* save old syscall number */
632cb450766SAl Viro	mov	$19, $10	/* save old a3 */
63312f79be9SAl Viro	jsr	$26, syscall_trace_leave
634cb450766SAl Viro	mov	$9, $18
635cb450766SAl Viro	mov	$10, $19
636231b0bedSRichard Henderson	UNDO_SWITCH_STACK
6371da177e4SLinus Torvalds
6381da177e4SLinus Torvalds	mov	$31, $26	/* tell "ret_from_sys_call" we can restart */
6391da177e4SLinus Torvalds	br	ret_from_sys_call
640231b0bedSRichard HendersonCFI_END_OSF_FRAME entSys
6411da177e4SLinus Torvalds
6421da177e4SLinus Torvalds/*
6431da177e4SLinus Torvalds * Save and restore the switch stack -- aka the balance of the user context.
6441da177e4SLinus Torvalds */
6451da177e4SLinus Torvalds
6461da177e4SLinus Torvalds	.align	4
647231b0bedSRichard Henderson	.type	do_switch_stack, @function
648231b0bedSRichard Henderson	.cfi_startproc simple
649231b0bedSRichard Henderson	.cfi_return_column 64
650231b0bedSRichard Henderson	.cfi_def_cfa $sp, 0
651231b0bedSRichard Henderson	.cfi_register 64, $1
6521da177e4SLinus Torvaldsdo_switch_stack:
6531da177e4SLinus Torvalds	lda	$sp, -SWITCH_STACK_SIZE($sp)
654231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	SWITCH_STACK_SIZE
6551da177e4SLinus Torvalds	stq	$9, 0($sp)
6561da177e4SLinus Torvalds	stq	$10, 8($sp)
6571da177e4SLinus Torvalds	stq	$11, 16($sp)
6581da177e4SLinus Torvalds	stq	$12, 24($sp)
6591da177e4SLinus Torvalds	stq	$13, 32($sp)
6601da177e4SLinus Torvalds	stq	$14, 40($sp)
6611da177e4SLinus Torvalds	stq	$15, 48($sp)
6621da177e4SLinus Torvalds	stq	$26, 56($sp)
6631da177e4SLinus Torvalds	ret	$31, ($1), 1
664231b0bedSRichard Henderson	.cfi_endproc
665231b0bedSRichard Henderson	.size	do_switch_stack, .-do_switch_stack
6661da177e4SLinus Torvalds
6671da177e4SLinus Torvalds	.align	4
668231b0bedSRichard Henderson	.type	undo_switch_stack, @function
669231b0bedSRichard Henderson	.cfi_startproc simple
670231b0bedSRichard Henderson	.cfi_def_cfa $sp, 0
671231b0bedSRichard Henderson	.cfi_register 64, $1
6721da177e4SLinus Torvaldsundo_switch_stack:
6731da177e4SLinus Torvalds	ldq	$9, 0($sp)
6741da177e4SLinus Torvalds	ldq	$10, 8($sp)
6751da177e4SLinus Torvalds	ldq	$11, 16($sp)
6761da177e4SLinus Torvalds	ldq	$12, 24($sp)
6771da177e4SLinus Torvalds	ldq	$13, 32($sp)
6781da177e4SLinus Torvalds	ldq	$14, 40($sp)
6791da177e4SLinus Torvalds	ldq	$15, 48($sp)
6801da177e4SLinus Torvalds	ldq	$26, 56($sp)
6811da177e4SLinus Torvalds	lda	$sp, SWITCH_STACK_SIZE($sp)
6821da177e4SLinus Torvalds	ret	$31, ($1), 1
683231b0bedSRichard Henderson	.cfi_endproc
684231b0bedSRichard Henderson	.size	undo_switch_stack, .-undo_switch_stack
685*05096666SAl Viro
686*05096666SAl Viro#define FR(n) n * 8 + TI_FP($8)
687*05096666SAl Viro	.align	4
688*05096666SAl Viro	.globl	__save_fpu
689*05096666SAl Viro	.type	__save_fpu, @function
690*05096666SAl Viro__save_fpu:
691*05096666SAl Viro#define V(n) stt	$f##n, FR(n)
692*05096666SAl Viro	V( 0); V( 1); V( 2); V( 3)
693*05096666SAl Viro	V( 4); V( 5); V( 6); V( 7)
694*05096666SAl Viro	V( 8); V( 9); V(10); V(11)
695*05096666SAl Viro	V(12); V(13); V(14); V(15)
696*05096666SAl Viro	V(16); V(17); V(18); V(19)
697*05096666SAl Viro	V(20); V(21); V(22); V(23)
698*05096666SAl Viro	V(24); V(25); V(26); V(27)
699*05096666SAl Viro	mf_fpcr	$f0		# get fpcr
700*05096666SAl Viro	V(28); V(29); V(30)
701*05096666SAl Viro	stt	$f0, FR(31)	# save fpcr in slot of $f31
702*05096666SAl Viro	ldt	$f0, FR(0)	# don't let "__save_fpu" change fp state.
703*05096666SAl Viro	ret
704*05096666SAl Viro#undef V
705*05096666SAl Viro	.size	__save_fpu, .-__save_fpu
706*05096666SAl Viro
707*05096666SAl Viro	.align	4
708*05096666SAl Virorestore_fpu:
709*05096666SAl Viro	and	$3, TS_RESTORE_FP, $3
710*05096666SAl Viro	bic	$2, TS_SAVED_FP | TS_RESTORE_FP, $2
711*05096666SAl Viro	beq	$3, 1f
712*05096666SAl Viro#define V(n) ldt	$f##n, FR(n)
713*05096666SAl Viro	ldt	$f30, FR(31)	# get saved fpcr
714*05096666SAl Viro	V( 0); V( 1); V( 2); V( 3)
715*05096666SAl Viro	mt_fpcr	$f30		# install saved fpcr
716*05096666SAl Viro	V( 4); V( 5); V( 6); V( 7)
717*05096666SAl Viro	V( 8); V( 9); V(10); V(11)
718*05096666SAl Viro	V(12); V(13); V(14); V(15)
719*05096666SAl Viro	V(16); V(17); V(18); V(19)
720*05096666SAl Viro	V(20); V(21); V(22); V(23)
721*05096666SAl Viro	V(24); V(25); V(26); V(27)
722*05096666SAl Viro	V(28); V(29); V(30)
723*05096666SAl Viro1:	stl $2, TI_STATUS($8)
724*05096666SAl Viro	br restore_other
725*05096666SAl Viro#undef V
726*05096666SAl Viro
7271da177e4SLinus Torvalds
7281da177e4SLinus Torvalds/*
7291da177e4SLinus Torvalds * The meat of the context switch code.
7301da177e4SLinus Torvalds */
7311da177e4SLinus Torvalds	.align	4
7321da177e4SLinus Torvalds	.globl	alpha_switch_to
733231b0bedSRichard Henderson	.type	alpha_switch_to, @function
734231b0bedSRichard Henderson	.cfi_startproc
7351da177e4SLinus Torvaldsalpha_switch_to:
736231b0bedSRichard Henderson	DO_SWITCH_STACK
737*05096666SAl Viro	ldl	$1, TI_STATUS($8)
738*05096666SAl Viro	and	$1, TS_RESTORE_FP, $3
739*05096666SAl Viro	bne	$3, 1f
740*05096666SAl Viro	or	$1, TS_RESTORE_FP | TS_SAVED_FP, $2
741*05096666SAl Viro	and	$1, TS_SAVED_FP, $3
742*05096666SAl Viro	stl	$2, TI_STATUS($8)
743*05096666SAl Viro	bne	$3, 1f
744*05096666SAl Viro	bsr	$26, __save_fpu
745*05096666SAl Viro1:
7461da177e4SLinus Torvalds	call_pal PAL_swpctx
7471da177e4SLinus Torvalds	lda	$8, 0x3fff
748231b0bedSRichard Henderson	UNDO_SWITCH_STACK
7491da177e4SLinus Torvalds	bic	$sp, $8, $8
7501da177e4SLinus Torvalds	mov	$17, $0
7511da177e4SLinus Torvalds	ret
752231b0bedSRichard Henderson	.cfi_endproc
753231b0bedSRichard Henderson	.size	alpha_switch_to, .-alpha_switch_to
7541da177e4SLinus Torvalds
7551da177e4SLinus Torvalds/*
7561da177e4SLinus Torvalds * New processes begin life here.
7571da177e4SLinus Torvalds */
7581da177e4SLinus Torvalds
7591da177e4SLinus Torvalds	.globl	ret_from_fork
7601da177e4SLinus Torvalds	.align	4
7611da177e4SLinus Torvalds	.ent	ret_from_fork
7621da177e4SLinus Torvaldsret_from_fork:
763fa6a3bf7SAl Viro	lda	$26, ret_to_user
7641da177e4SLinus Torvalds	mov	$17, $16
7651da177e4SLinus Torvalds	jmp	$31, schedule_tail
7661da177e4SLinus Torvalds.end ret_from_fork
7671da177e4SLinus Torvalds
7681da177e4SLinus Torvalds/*
769cba1ec7eSAl Viro * ... and new kernel threads - here
7701da177e4SLinus Torvalds */
7711da177e4SLinus Torvalds	.align 4
772cba1ec7eSAl Viro	.globl	ret_from_kernel_thread
773cba1ec7eSAl Viro	.ent	ret_from_kernel_thread
774cba1ec7eSAl Viroret_from_kernel_thread:
775cba1ec7eSAl Viro	mov	$17, $16
776cba1ec7eSAl Viro	jsr	$26, schedule_tail
777cba1ec7eSAl Viro	mov	$9, $27
778cba1ec7eSAl Viro	mov	$10, $16
779cba1ec7eSAl Viro	jsr	$26, ($9)
78044f4b56bSAl Viro	br	$31, ret_to_user
7815522be6aSAl Viro.end ret_from_kernel_thread
78244f4b56bSAl Viro
7831da177e4SLinus Torvalds
7841da177e4SLinus Torvalds/*
7851da177e4SLinus Torvalds * Special system calls.  Most of these are special in that they either
7868a68060cSAl Viro * have to play switch_stack games.
7871da177e4SLinus Torvalds */
788dfe09ae0SAl Viro
789dfe09ae0SAl Viro.macro	fork_like name
7901da177e4SLinus Torvalds	.align	4
791dfe09ae0SAl Viro	.globl	alpha_\name
792dfe09ae0SAl Viro	.ent	alpha_\name
793dfe09ae0SAl Viroalpha_\name:
7941da177e4SLinus Torvalds	.prologue 0
7951da177e4SLinus Torvalds	bsr	$1, do_switch_stack
796*05096666SAl Viro	// NB: if anyone adds preemption, this block will need to be protected
797*05096666SAl Viro	ldl	$1, TI_STATUS($8)
798*05096666SAl Viro	and	$1, TS_SAVED_FP, $3
799*05096666SAl Viro	or	$1, TS_SAVED_FP, $2
800*05096666SAl Viro	bne	$3, 1f
801*05096666SAl Viro	stl	$2, TI_STATUS($8)
802*05096666SAl Viro	bsr	$26, __save_fpu
803*05096666SAl Viro1:
804dfe09ae0SAl Viro	jsr	$26, sys_\name
805e0e431aaSAl Viro	ldq	$26, 56($sp)
806e0e431aaSAl Viro	lda	$sp, SWITCH_STACK_SIZE($sp)
8071da177e4SLinus Torvalds	ret
808dfe09ae0SAl Viro.end	alpha_\name
809dfe09ae0SAl Viro.endm
8101da177e4SLinus Torvalds
811dfe09ae0SAl Virofork_like fork
812dfe09ae0SAl Virofork_like vfork
813dfe09ae0SAl Virofork_like clone
8141da177e4SLinus Torvalds
8158a68060cSAl Viro.macro	sigreturn_like name
8161da177e4SLinus Torvalds	.align	4
8178a68060cSAl Viro	.globl	sys_\name
8188a68060cSAl Viro	.ent	sys_\name
8198a68060cSAl Virosys_\name:
8201da177e4SLinus Torvalds	.prologue 0
82153293638SAl Viro	lda	$9, ret_from_straced
82253293638SAl Viro	cmpult	$26, $9, $9
8231da177e4SLinus Torvalds	lda	$sp, -SWITCH_STACK_SIZE($sp)
8248a68060cSAl Viro	jsr	$26, do_\name
82553293638SAl Viro	bne	$9, 1f
82612f79be9SAl Viro	jsr	$26, syscall_trace_leave
82753293638SAl Viro1:	br	$1, undo_switch_stack
8281da177e4SLinus Torvalds	br	ret_from_sys_call
8298a68060cSAl Viro.end sys_\name
8308a68060cSAl Viro.endm
8311da177e4SLinus Torvalds
8328a68060cSAl Virosigreturn_like sigreturn
8338a68060cSAl Virosigreturn_like rt_sigreturn
8341da177e4SLinus Torvalds
8351da177e4SLinus Torvalds	.align	4
836060581c1SAl Viro	.globl	alpha_syscall_zero
837060581c1SAl Viro	.ent	alpha_syscall_zero
838060581c1SAl Viroalpha_syscall_zero:
8391da177e4SLinus Torvalds	.prologue 0
840060581c1SAl Viro	/* Special because it needs to do something opposite to
841060581c1SAl Viro	   force_successful_syscall_return().  We use the saved
842060581c1SAl Viro	   syscall number for that, zero meaning "not an error".
843060581c1SAl Viro	   That works nicely, but for real syscall 0 we need to
844060581c1SAl Viro	   make sure that this logics doesn't get confused.
845060581c1SAl Viro	   Store a non-zero there - -ENOSYS we need in register
846060581c1SAl Viro	   for our return value will do just fine.
847060581c1SAl Viro	  */
8481da177e4SLinus Torvalds	lda	$0, -ENOSYS
8491da177e4SLinus Torvalds	unop
8501da177e4SLinus Torvalds	stq	$0, 0($sp)
8511da177e4SLinus Torvalds	ret
852060581c1SAl Viro.end alpha_syscall_zero
853