xref: /linux-6.15/arch/alpha/kernel/entry.S (revision 3b35a171)
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
18231b0bedSRichard Henderson.macro	CFI_START_OSF_FRAME	func
19231b0bedSRichard Henderson	.align	4
20231b0bedSRichard Henderson	.globl	\func
21231b0bedSRichard Henderson	.type	\func,@function
22231b0bedSRichard Henderson\func:
23231b0bedSRichard Henderson	.cfi_startproc simple
24231b0bedSRichard Henderson	.cfi_return_column 64
25231b0bedSRichard Henderson	.cfi_def_cfa	$sp, 48
26231b0bedSRichard Henderson	.cfi_rel_offset	64, 8
27231b0bedSRichard Henderson	.cfi_rel_offset	$gp, 16
28231b0bedSRichard Henderson	.cfi_rel_offset	$16, 24
29231b0bedSRichard Henderson	.cfi_rel_offset	$17, 32
30231b0bedSRichard Henderson	.cfi_rel_offset	$18, 40
31231b0bedSRichard Henderson.endm
32231b0bedSRichard Henderson
33231b0bedSRichard Henderson.macro	CFI_END_OSF_FRAME	func
34231b0bedSRichard Henderson	.cfi_endproc
35231b0bedSRichard Henderson	.size	\func, . - \func
36231b0bedSRichard Henderson.endm
37231b0bedSRichard Henderson
381da177e4SLinus Torvalds/*
391da177e4SLinus Torvalds * This defines the normal kernel pt-regs layout.
401da177e4SLinus Torvalds *
411da177e4SLinus Torvalds * regs 9-15 preserved by C code
421da177e4SLinus Torvalds * regs 16-18 saved by PAL-code
431da177e4SLinus Torvalds * regs 29-30 saved and set up by PAL-code
441da177e4SLinus Torvalds * JRP - Save regs 16-18 in a special area of the stack, so that
451da177e4SLinus Torvalds * the palcode-provided values are available to the signal handler.
461da177e4SLinus Torvalds */
471da177e4SLinus Torvalds
48231b0bedSRichard Henderson.macro	SAVE_ALL
49231b0bedSRichard Henderson	subq	$sp, SP_OFF, $sp
50231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	SP_OFF
51231b0bedSRichard Henderson	stq	$0, 0($sp)
52231b0bedSRichard Henderson	stq	$1, 8($sp)
53231b0bedSRichard Henderson	stq	$2, 16($sp)
54231b0bedSRichard Henderson	stq	$3, 24($sp)
55231b0bedSRichard Henderson	stq	$4, 32($sp)
56231b0bedSRichard Henderson	stq	$28, 144($sp)
57231b0bedSRichard Henderson	.cfi_rel_offset	$0, 0
58231b0bedSRichard Henderson	.cfi_rel_offset $1, 8
59231b0bedSRichard Henderson	.cfi_rel_offset	$2, 16
60231b0bedSRichard Henderson	.cfi_rel_offset	$3, 24
61231b0bedSRichard Henderson	.cfi_rel_offset	$4, 32
62231b0bedSRichard Henderson	.cfi_rel_offset	$28, 144
63231b0bedSRichard Henderson	lda	$2, alpha_mv
64231b0bedSRichard Henderson	stq	$5, 40($sp)
65231b0bedSRichard Henderson	stq	$6, 48($sp)
66231b0bedSRichard Henderson	stq	$7, 56($sp)
67231b0bedSRichard Henderson	stq	$8, 64($sp)
68231b0bedSRichard Henderson	stq	$19, 72($sp)
69231b0bedSRichard Henderson	stq	$20, 80($sp)
70231b0bedSRichard Henderson	stq	$21, 88($sp)
71231b0bedSRichard Henderson	ldq	$2, HAE_CACHE($2)
72231b0bedSRichard Henderson	stq	$22, 96($sp)
73231b0bedSRichard Henderson	stq	$23, 104($sp)
74231b0bedSRichard Henderson	stq	$24, 112($sp)
75231b0bedSRichard Henderson	stq	$25, 120($sp)
76231b0bedSRichard Henderson	stq	$26, 128($sp)
77231b0bedSRichard Henderson	stq	$27, 136($sp)
78231b0bedSRichard Henderson	stq	$2, 152($sp)
79231b0bedSRichard Henderson	stq	$16, 160($sp)
80231b0bedSRichard Henderson	stq	$17, 168($sp)
811da177e4SLinus Torvalds	stq	$18, 176($sp)
82231b0bedSRichard Henderson	.cfi_rel_offset	$5, 40
83231b0bedSRichard Henderson	.cfi_rel_offset	$6, 48
84231b0bedSRichard Henderson	.cfi_rel_offset	$7, 56
85231b0bedSRichard Henderson	.cfi_rel_offset	$8, 64
86231b0bedSRichard Henderson	.cfi_rel_offset $19, 72
87231b0bedSRichard Henderson	.cfi_rel_offset	$20, 80
88231b0bedSRichard Henderson	.cfi_rel_offset	$21, 88
89231b0bedSRichard Henderson	.cfi_rel_offset $22, 96
90231b0bedSRichard Henderson	.cfi_rel_offset	$23, 104
91231b0bedSRichard Henderson	.cfi_rel_offset	$24, 112
92231b0bedSRichard Henderson	.cfi_rel_offset	$25, 120
93231b0bedSRichard Henderson	.cfi_rel_offset	$26, 128
94231b0bedSRichard Henderson	.cfi_rel_offset	$27, 136
95231b0bedSRichard Henderson.endm
961da177e4SLinus Torvalds
97231b0bedSRichard Henderson.macro	RESTORE_ALL
98231b0bedSRichard Henderson	lda	$19, alpha_mv
99231b0bedSRichard Henderson	ldq	$0, 0($sp)
100231b0bedSRichard Henderson	ldq	$1, 8($sp)
101231b0bedSRichard Henderson	ldq	$2, 16($sp)
102231b0bedSRichard Henderson	ldq	$3, 24($sp)
103231b0bedSRichard Henderson	ldq	$21, 152($sp)
104231b0bedSRichard Henderson	ldq	$20, HAE_CACHE($19)
105231b0bedSRichard Henderson	ldq	$4, 32($sp)
106231b0bedSRichard Henderson	ldq	$5, 40($sp)
107231b0bedSRichard Henderson	ldq	$6, 48($sp)
108231b0bedSRichard Henderson	ldq	$7, 56($sp)
109231b0bedSRichard Henderson	subq	$20, $21, $20
110231b0bedSRichard Henderson	ldq	$8, 64($sp)
111231b0bedSRichard Henderson	beq	$20, 99f
112231b0bedSRichard Henderson	ldq	$20, HAE_REG($19)
113231b0bedSRichard Henderson	stq	$21, HAE_CACHE($19)
114231b0bedSRichard Henderson	stq	$21, 0($20)
115231b0bedSRichard Henderson99:	ldq	$19, 72($sp)
116231b0bedSRichard Henderson	ldq	$20, 80($sp)
117231b0bedSRichard Henderson	ldq	$21, 88($sp)
118231b0bedSRichard Henderson	ldq	$22, 96($sp)
119231b0bedSRichard Henderson	ldq	$23, 104($sp)
120231b0bedSRichard Henderson	ldq	$24, 112($sp)
121231b0bedSRichard Henderson	ldq	$25, 120($sp)
122231b0bedSRichard Henderson	ldq	$26, 128($sp)
123231b0bedSRichard Henderson	ldq	$27, 136($sp)
124231b0bedSRichard Henderson	ldq	$28, 144($sp)
1251da177e4SLinus Torvalds	addq	$sp, SP_OFF, $sp
126231b0bedSRichard Henderson	.cfi_restore	$0
127231b0bedSRichard Henderson	.cfi_restore	$1
128231b0bedSRichard Henderson	.cfi_restore	$2
129231b0bedSRichard Henderson	.cfi_restore	$3
130231b0bedSRichard Henderson	.cfi_restore	$4
131231b0bedSRichard Henderson	.cfi_restore	$5
132231b0bedSRichard Henderson	.cfi_restore	$6
133231b0bedSRichard Henderson	.cfi_restore	$7
134231b0bedSRichard Henderson	.cfi_restore	$8
135231b0bedSRichard Henderson	.cfi_restore	$19
136231b0bedSRichard Henderson	.cfi_restore	$20
137231b0bedSRichard Henderson	.cfi_restore	$21
138231b0bedSRichard Henderson	.cfi_restore	$22
139231b0bedSRichard Henderson	.cfi_restore	$23
140231b0bedSRichard Henderson	.cfi_restore	$24
141231b0bedSRichard Henderson	.cfi_restore	$25
142231b0bedSRichard Henderson	.cfi_restore	$26
143231b0bedSRichard Henderson	.cfi_restore	$27
144231b0bedSRichard Henderson	.cfi_restore	$28
145231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-SP_OFF
146231b0bedSRichard Henderson.endm
147231b0bedSRichard Henderson
148231b0bedSRichard Henderson.macro	DO_SWITCH_STACK
149231b0bedSRichard Henderson	bsr	$1, do_switch_stack
150231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	SWITCH_STACK_SIZE
151231b0bedSRichard Henderson	.cfi_rel_offset	$9, 0
152231b0bedSRichard Henderson	.cfi_rel_offset	$10, 8
153231b0bedSRichard Henderson	.cfi_rel_offset	$11, 16
154231b0bedSRichard Henderson	.cfi_rel_offset	$12, 24
155231b0bedSRichard Henderson	.cfi_rel_offset	$13, 32
156231b0bedSRichard Henderson	.cfi_rel_offset	$14, 40
157231b0bedSRichard Henderson	.cfi_rel_offset	$15, 48
158231b0bedSRichard Henderson.endm
159231b0bedSRichard Henderson
160231b0bedSRichard Henderson.macro	UNDO_SWITCH_STACK
161231b0bedSRichard Henderson	bsr	$1, undo_switch_stack
162231b0bedSRichard Henderson	.cfi_restore	$9
163231b0bedSRichard Henderson	.cfi_restore	$10
164231b0bedSRichard Henderson	.cfi_restore	$11
165231b0bedSRichard Henderson	.cfi_restore	$12
166231b0bedSRichard Henderson	.cfi_restore	$13
167231b0bedSRichard Henderson	.cfi_restore	$14
168231b0bedSRichard Henderson	.cfi_restore	$15
169231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-SWITCH_STACK_SIZE
170231b0bedSRichard Henderson.endm
1711da177e4SLinus Torvalds
1721da177e4SLinus Torvalds/*
1731da177e4SLinus Torvalds * Non-syscall kernel entry points.
1741da177e4SLinus Torvalds */
1751da177e4SLinus Torvalds
176231b0bedSRichard HendersonCFI_START_OSF_FRAME entInt
1771da177e4SLinus Torvalds	SAVE_ALL
1781da177e4SLinus Torvalds	lda	$8, 0x3fff
1791da177e4SLinus Torvalds	lda	$26, ret_from_sys_call
1801da177e4SLinus Torvalds	bic	$sp, $8, $8
1811da177e4SLinus Torvalds	mov	$sp, $19
1821da177e4SLinus Torvalds	jsr	$31, do_entInt
183231b0bedSRichard HendersonCFI_END_OSF_FRAME entInt
1841da177e4SLinus Torvalds
185231b0bedSRichard HendersonCFI_START_OSF_FRAME entArith
1861da177e4SLinus Torvalds	SAVE_ALL
1871da177e4SLinus Torvalds	lda	$8, 0x3fff
1881da177e4SLinus Torvalds	lda	$26, ret_from_sys_call
1891da177e4SLinus Torvalds	bic	$sp, $8, $8
1901da177e4SLinus Torvalds	mov	$sp, $18
1911da177e4SLinus Torvalds	jsr	$31, do_entArith
192231b0bedSRichard HendersonCFI_END_OSF_FRAME entArith
1931da177e4SLinus Torvalds
194231b0bedSRichard HendersonCFI_START_OSF_FRAME entMM
1951da177e4SLinus Torvalds	SAVE_ALL
1961da177e4SLinus Torvalds/* save $9 - $15 so the inline exception code can manipulate them.  */
197*3b35a171SIvan Kokshaysky	subq	$sp, 64, $sp
198*3b35a171SIvan Kokshaysky	.cfi_adjust_cfa_offset	64
1991da177e4SLinus Torvalds	stq	$9, 0($sp)
2001da177e4SLinus Torvalds	stq	$10, 8($sp)
2011da177e4SLinus Torvalds	stq	$11, 16($sp)
2021da177e4SLinus Torvalds	stq	$12, 24($sp)
2031da177e4SLinus Torvalds	stq	$13, 32($sp)
2041da177e4SLinus Torvalds	stq	$14, 40($sp)
2051da177e4SLinus Torvalds	stq	$15, 48($sp)
206231b0bedSRichard Henderson	.cfi_rel_offset	$9, 0
207231b0bedSRichard Henderson	.cfi_rel_offset	$10, 8
208231b0bedSRichard Henderson	.cfi_rel_offset	$11, 16
209231b0bedSRichard Henderson	.cfi_rel_offset	$12, 24
210231b0bedSRichard Henderson	.cfi_rel_offset	$13, 32
211231b0bedSRichard Henderson	.cfi_rel_offset	$14, 40
212231b0bedSRichard Henderson	.cfi_rel_offset	$15, 48
213*3b35a171SIvan Kokshaysky	addq	$sp, 64, $19
2141da177e4SLinus Torvalds/* handle the fault */
2151da177e4SLinus Torvalds	lda	$8, 0x3fff
2161da177e4SLinus Torvalds	bic	$sp, $8, $8
2171da177e4SLinus Torvalds	jsr	$26, do_page_fault
2181da177e4SLinus Torvalds/* reload the registers after the exception code played.  */
2191da177e4SLinus Torvalds	ldq	$9, 0($sp)
2201da177e4SLinus Torvalds	ldq	$10, 8($sp)
2211da177e4SLinus Torvalds	ldq	$11, 16($sp)
2221da177e4SLinus Torvalds	ldq	$12, 24($sp)
2231da177e4SLinus Torvalds	ldq	$13, 32($sp)
2241da177e4SLinus Torvalds	ldq	$14, 40($sp)
2251da177e4SLinus Torvalds	ldq	$15, 48($sp)
226*3b35a171SIvan Kokshaysky	addq	$sp, 64, $sp
227231b0bedSRichard Henderson	.cfi_restore	$9
228231b0bedSRichard Henderson	.cfi_restore	$10
229231b0bedSRichard Henderson	.cfi_restore	$11
230231b0bedSRichard Henderson	.cfi_restore	$12
231231b0bedSRichard Henderson	.cfi_restore	$13
232231b0bedSRichard Henderson	.cfi_restore	$14
233231b0bedSRichard Henderson	.cfi_restore	$15
234*3b35a171SIvan Kokshaysky	.cfi_adjust_cfa_offset	-64
2351da177e4SLinus Torvalds/* finish up the syscall as normal.  */
2361da177e4SLinus Torvalds	br	ret_from_sys_call
237231b0bedSRichard HendersonCFI_END_OSF_FRAME entMM
2381da177e4SLinus Torvalds
239231b0bedSRichard HendersonCFI_START_OSF_FRAME entIF
2401da177e4SLinus Torvalds	SAVE_ALL
2411da177e4SLinus Torvalds	lda	$8, 0x3fff
2421da177e4SLinus Torvalds	lda	$26, ret_from_sys_call
2431da177e4SLinus Torvalds	bic	$sp, $8, $8
2441da177e4SLinus Torvalds	mov	$sp, $17
2451da177e4SLinus Torvalds	jsr	$31, do_entIF
246231b0bedSRichard HendersonCFI_END_OSF_FRAME entIF
2471da177e4SLinus Torvalds
248231b0bedSRichard HendersonCFI_START_OSF_FRAME entUna
2491da177e4SLinus Torvalds	lda	$sp, -256($sp)
250231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	256
2511da177e4SLinus Torvalds	stq	$0, 0($sp)
252231b0bedSRichard Henderson	.cfi_rel_offset	$0, 0
253231b0bedSRichard Henderson	.cfi_remember_state
2541da177e4SLinus Torvalds	ldq	$0, 256($sp)	/* get PS */
2551da177e4SLinus Torvalds	stq	$1, 8($sp)
2561da177e4SLinus Torvalds	stq	$2, 16($sp)
2571da177e4SLinus Torvalds	stq	$3, 24($sp)
2581da177e4SLinus Torvalds	and	$0, 8, $0		/* user mode? */
2591da177e4SLinus Torvalds	stq	$4, 32($sp)
2601da177e4SLinus Torvalds	bne	$0, entUnaUser	/* yup -> do user-level unaligned fault */
2611da177e4SLinus Torvalds	stq	$5, 40($sp)
2621da177e4SLinus Torvalds	stq	$6, 48($sp)
2631da177e4SLinus Torvalds	stq	$7, 56($sp)
2641da177e4SLinus Torvalds	stq	$8, 64($sp)
2651da177e4SLinus Torvalds	stq	$9, 72($sp)
2661da177e4SLinus Torvalds	stq	$10, 80($sp)
2671da177e4SLinus Torvalds	stq	$11, 88($sp)
2681da177e4SLinus Torvalds	stq	$12, 96($sp)
2691da177e4SLinus Torvalds	stq	$13, 104($sp)
2701da177e4SLinus Torvalds	stq	$14, 112($sp)
2711da177e4SLinus Torvalds	stq	$15, 120($sp)
2721da177e4SLinus Torvalds	/* 16-18 PAL-saved */
2731da177e4SLinus Torvalds	stq	$19, 152($sp)
2741da177e4SLinus Torvalds	stq	$20, 160($sp)
2751da177e4SLinus Torvalds	stq	$21, 168($sp)
2761da177e4SLinus Torvalds	stq	$22, 176($sp)
2771da177e4SLinus Torvalds	stq	$23, 184($sp)
2781da177e4SLinus Torvalds	stq	$24, 192($sp)
2791da177e4SLinus Torvalds	stq	$25, 200($sp)
2801da177e4SLinus Torvalds	stq	$26, 208($sp)
2811da177e4SLinus Torvalds	stq	$27, 216($sp)
2821da177e4SLinus Torvalds	stq	$28, 224($sp)
283d70ddac1SRichard Henderson	mov	$sp, $19
2841da177e4SLinus Torvalds	stq	$gp, 232($sp)
285231b0bedSRichard Henderson	.cfi_rel_offset	$1, 1*8
286231b0bedSRichard Henderson	.cfi_rel_offset	$2, 2*8
287231b0bedSRichard Henderson	.cfi_rel_offset	$3, 3*8
288231b0bedSRichard Henderson	.cfi_rel_offset	$4, 4*8
289231b0bedSRichard Henderson	.cfi_rel_offset	$5, 5*8
290231b0bedSRichard Henderson	.cfi_rel_offset	$6, 6*8
291231b0bedSRichard Henderson	.cfi_rel_offset	$7, 7*8
292231b0bedSRichard Henderson	.cfi_rel_offset	$8, 8*8
293231b0bedSRichard Henderson	.cfi_rel_offset	$9, 9*8
294231b0bedSRichard Henderson	.cfi_rel_offset	$10, 10*8
295231b0bedSRichard Henderson	.cfi_rel_offset	$11, 11*8
296231b0bedSRichard Henderson	.cfi_rel_offset	$12, 12*8
297231b0bedSRichard Henderson	.cfi_rel_offset	$13, 13*8
298231b0bedSRichard Henderson	.cfi_rel_offset	$14, 14*8
299231b0bedSRichard Henderson	.cfi_rel_offset	$15, 15*8
300231b0bedSRichard Henderson	.cfi_rel_offset	$19, 19*8
301231b0bedSRichard Henderson	.cfi_rel_offset	$20, 20*8
302231b0bedSRichard Henderson	.cfi_rel_offset	$21, 21*8
303231b0bedSRichard Henderson	.cfi_rel_offset	$22, 22*8
304231b0bedSRichard Henderson	.cfi_rel_offset	$23, 23*8
305231b0bedSRichard Henderson	.cfi_rel_offset	$24, 24*8
306231b0bedSRichard Henderson	.cfi_rel_offset	$25, 25*8
307231b0bedSRichard Henderson	.cfi_rel_offset	$26, 26*8
308231b0bedSRichard Henderson	.cfi_rel_offset	$27, 27*8
309231b0bedSRichard Henderson	.cfi_rel_offset	$28, 28*8
310231b0bedSRichard Henderson	.cfi_rel_offset	$29, 29*8
3111da177e4SLinus Torvalds	lda	$8, 0x3fff
3121da177e4SLinus Torvalds	stq	$31, 248($sp)
3131da177e4SLinus Torvalds	bic	$sp, $8, $8
3141da177e4SLinus Torvalds	jsr	$26, do_entUna
3151da177e4SLinus Torvalds	ldq	$0, 0($sp)
3161da177e4SLinus Torvalds	ldq	$1, 8($sp)
3171da177e4SLinus Torvalds	ldq	$2, 16($sp)
3181da177e4SLinus Torvalds	ldq	$3, 24($sp)
3191da177e4SLinus Torvalds	ldq	$4, 32($sp)
3201da177e4SLinus Torvalds	ldq	$5, 40($sp)
3211da177e4SLinus Torvalds	ldq	$6, 48($sp)
3221da177e4SLinus Torvalds	ldq	$7, 56($sp)
3231da177e4SLinus Torvalds	ldq	$8, 64($sp)
3241da177e4SLinus Torvalds	ldq	$9, 72($sp)
3251da177e4SLinus Torvalds	ldq	$10, 80($sp)
3261da177e4SLinus Torvalds	ldq	$11, 88($sp)
3271da177e4SLinus Torvalds	ldq	$12, 96($sp)
3281da177e4SLinus Torvalds	ldq	$13, 104($sp)
3291da177e4SLinus Torvalds	ldq	$14, 112($sp)
3301da177e4SLinus Torvalds	ldq	$15, 120($sp)
3311da177e4SLinus Torvalds	/* 16-18 PAL-saved */
3321da177e4SLinus Torvalds	ldq	$19, 152($sp)
3331da177e4SLinus Torvalds	ldq	$20, 160($sp)
3341da177e4SLinus Torvalds	ldq	$21, 168($sp)
3351da177e4SLinus Torvalds	ldq	$22, 176($sp)
3361da177e4SLinus Torvalds	ldq	$23, 184($sp)
3371da177e4SLinus Torvalds	ldq	$24, 192($sp)
3381da177e4SLinus Torvalds	ldq	$25, 200($sp)
3391da177e4SLinus Torvalds	ldq	$26, 208($sp)
3401da177e4SLinus Torvalds	ldq	$27, 216($sp)
3411da177e4SLinus Torvalds	ldq	$28, 224($sp)
3421da177e4SLinus Torvalds	ldq	$gp, 232($sp)
3431da177e4SLinus Torvalds	lda	$sp, 256($sp)
344231b0bedSRichard Henderson	.cfi_restore	$1
345231b0bedSRichard Henderson	.cfi_restore	$2
346231b0bedSRichard Henderson	.cfi_restore	$3
347231b0bedSRichard Henderson	.cfi_restore	$4
348231b0bedSRichard Henderson	.cfi_restore	$5
349231b0bedSRichard Henderson	.cfi_restore	$6
350231b0bedSRichard Henderson	.cfi_restore	$7
351231b0bedSRichard Henderson	.cfi_restore	$8
352231b0bedSRichard Henderson	.cfi_restore	$9
353231b0bedSRichard Henderson	.cfi_restore	$10
354231b0bedSRichard Henderson	.cfi_restore	$11
355231b0bedSRichard Henderson	.cfi_restore	$12
356231b0bedSRichard Henderson	.cfi_restore	$13
357231b0bedSRichard Henderson	.cfi_restore	$14
358231b0bedSRichard Henderson	.cfi_restore	$15
359231b0bedSRichard Henderson	.cfi_restore	$19
360231b0bedSRichard Henderson	.cfi_restore	$20
361231b0bedSRichard Henderson	.cfi_restore	$21
362231b0bedSRichard Henderson	.cfi_restore	$22
363231b0bedSRichard Henderson	.cfi_restore	$23
364231b0bedSRichard Henderson	.cfi_restore	$24
365231b0bedSRichard Henderson	.cfi_restore	$25
366231b0bedSRichard Henderson	.cfi_restore	$26
367231b0bedSRichard Henderson	.cfi_restore	$27
368231b0bedSRichard Henderson	.cfi_restore	$28
369231b0bedSRichard Henderson	.cfi_restore	$29
370231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-256
3711da177e4SLinus Torvalds	call_pal PAL_rti
3721da177e4SLinus Torvalds
3731da177e4SLinus Torvalds	.align	4
3741da177e4SLinus TorvaldsentUnaUser:
375231b0bedSRichard Henderson	.cfi_restore_state
3761da177e4SLinus Torvalds	ldq	$0, 0($sp)	/* restore original $0 */
3771da177e4SLinus Torvalds	lda	$sp, 256($sp)	/* pop entUna's stack frame */
378231b0bedSRichard Henderson	.cfi_restore	$0
379231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	-256
3801da177e4SLinus Torvalds	SAVE_ALL		/* setup normal kernel stack */
381*3b35a171SIvan Kokshaysky	lda	$sp, -64($sp)
382*3b35a171SIvan Kokshaysky	.cfi_adjust_cfa_offset	64
3831da177e4SLinus Torvalds	stq	$9, 0($sp)
3841da177e4SLinus Torvalds	stq	$10, 8($sp)
3851da177e4SLinus Torvalds	stq	$11, 16($sp)
3861da177e4SLinus Torvalds	stq	$12, 24($sp)
3871da177e4SLinus Torvalds	stq	$13, 32($sp)
3881da177e4SLinus Torvalds	stq	$14, 40($sp)
3891da177e4SLinus Torvalds	stq	$15, 48($sp)
390231b0bedSRichard Henderson	.cfi_rel_offset	$9, 0
391231b0bedSRichard Henderson	.cfi_rel_offset	$10, 8
392231b0bedSRichard Henderson	.cfi_rel_offset	$11, 16
393231b0bedSRichard Henderson	.cfi_rel_offset	$12, 24
394231b0bedSRichard Henderson	.cfi_rel_offset	$13, 32
395231b0bedSRichard Henderson	.cfi_rel_offset	$14, 40
396231b0bedSRichard Henderson	.cfi_rel_offset	$15, 48
3971da177e4SLinus Torvalds	lda	$8, 0x3fff
398*3b35a171SIvan Kokshaysky	addq	$sp, 64, $19
3991da177e4SLinus Torvalds	bic	$sp, $8, $8
4001da177e4SLinus Torvalds	jsr	$26, do_entUnaUser
4011da177e4SLinus Torvalds	ldq	$9, 0($sp)
4021da177e4SLinus Torvalds	ldq	$10, 8($sp)
4031da177e4SLinus Torvalds	ldq	$11, 16($sp)
4041da177e4SLinus Torvalds	ldq	$12, 24($sp)
4051da177e4SLinus Torvalds	ldq	$13, 32($sp)
4061da177e4SLinus Torvalds	ldq	$14, 40($sp)
4071da177e4SLinus Torvalds	ldq	$15, 48($sp)
408*3b35a171SIvan Kokshaysky	lda	$sp, 64($sp)
409231b0bedSRichard Henderson	.cfi_restore	$9
410231b0bedSRichard Henderson	.cfi_restore	$10
411231b0bedSRichard Henderson	.cfi_restore	$11
412231b0bedSRichard Henderson	.cfi_restore	$12
413231b0bedSRichard Henderson	.cfi_restore	$13
414231b0bedSRichard Henderson	.cfi_restore	$14
415231b0bedSRichard Henderson	.cfi_restore	$15
416*3b35a171SIvan Kokshaysky	.cfi_adjust_cfa_offset	-64
4171da177e4SLinus Torvalds	br	ret_from_sys_call
418231b0bedSRichard HendersonCFI_END_OSF_FRAME entUna
4191da177e4SLinus Torvalds
420231b0bedSRichard HendersonCFI_START_OSF_FRAME entDbg
4211da177e4SLinus Torvalds	SAVE_ALL
4221da177e4SLinus Torvalds	lda	$8, 0x3fff
4231da177e4SLinus Torvalds	lda	$26, ret_from_sys_call
4241da177e4SLinus Torvalds	bic	$sp, $8, $8
4251da177e4SLinus Torvalds	mov	$sp, $16
4261da177e4SLinus Torvalds	jsr	$31, do_entDbg
427231b0bedSRichard HendersonCFI_END_OSF_FRAME entDbg
4281da177e4SLinus Torvalds
4291da177e4SLinus Torvalds/*
4301da177e4SLinus Torvalds * The system call entry point is special.  Most importantly, it looks
4311da177e4SLinus Torvalds * like a function call to userspace as far as clobbered registers.  We
4321da177e4SLinus Torvalds * do preserve the argument registers (for syscall restarts) and $26
4331da177e4SLinus Torvalds * (for leaf syscall functions).
4341da177e4SLinus Torvalds *
4351da177e4SLinus Torvalds * So much for theory.  We don't take advantage of this yet.
4361da177e4SLinus Torvalds *
4371da177e4SLinus Torvalds * Note that a0-a2 are not saved by PALcode as with the other entry points.
4381da177e4SLinus Torvalds */
4391da177e4SLinus Torvalds
4401da177e4SLinus Torvalds	.align	4
4411da177e4SLinus Torvalds	.globl	entSys
442231b0bedSRichard Henderson	.type	entSys, @function
443231b0bedSRichard Henderson	.cfi_startproc simple
444231b0bedSRichard Henderson	.cfi_return_column 64
445231b0bedSRichard Henderson	.cfi_def_cfa	$sp, 48
446231b0bedSRichard Henderson	.cfi_rel_offset	64, 8
447231b0bedSRichard Henderson	.cfi_rel_offset	$gp, 16
4481da177e4SLinus TorvaldsentSys:
4491da177e4SLinus Torvalds	SAVE_ALL
4501da177e4SLinus Torvalds	lda	$8, 0x3fff
4511da177e4SLinus Torvalds	bic	$sp, $8, $8
452d6e59579SYang Yang	lda	$4, NR_syscalls($31)
4531da177e4SLinus Torvalds	stq	$16, SP_OFF+24($sp)
4541da177e4SLinus Torvalds	lda	$5, sys_call_table
4551da177e4SLinus Torvalds	lda	$27, sys_ni_syscall
4561da177e4SLinus Torvalds	cmpult	$0, $4, $4
4571da177e4SLinus Torvalds	ldl	$3, TI_FLAGS($8)
4581da177e4SLinus Torvalds	stq	$17, SP_OFF+32($sp)
4591da177e4SLinus Torvalds	s8addq	$0, $5, $5
4601da177e4SLinus Torvalds	stq	$18, SP_OFF+40($sp)
461231b0bedSRichard Henderson	.cfi_rel_offset	$16, SP_OFF+24
462231b0bedSRichard Henderson	.cfi_rel_offset	$17, SP_OFF+32
463231b0bedSRichard Henderson	.cfi_rel_offset	$18, SP_OFF+40
464a9302e84S蔡正龙#ifdef CONFIG_AUDITSYSCALL
465a9302e84S蔡正龙	lda     $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
466a9302e84S蔡正龙	and     $3, $6, $3
467a9302e84S蔡正龙	bne     $3, strace
468f7b2431aSAl Viro#else
469f7b2431aSAl Viro	blbs    $3, strace		/* check for SYSCALL_TRACE in disguise */
470f7b2431aSAl Viro#endif
4711da177e4SLinus Torvalds	beq	$4, 1f
4721da177e4SLinus Torvalds	ldq	$27, 0($5)
473060581c1SAl Viro1:	jsr	$26, ($27), sys_ni_syscall
4741da177e4SLinus Torvalds	ldgp	$gp, 0($26)
4751da177e4SLinus Torvalds	blt	$0, $syscall_error	/* the call failed */
476e778eaecSAl Viro$ret_success:
4771da177e4SLinus Torvalds	stq	$0, 0($sp)
4781da177e4SLinus Torvalds	stq	$31, 72($sp)		/* a3=0 => no error */
4791da177e4SLinus Torvalds
4801da177e4SLinus Torvalds	.align	4
481231b0bedSRichard Henderson	.globl	ret_from_sys_call
4821da177e4SLinus Torvaldsret_from_sys_call:
483cb450766SAl Viro	cmovne	$26, 0, $18		/* $18 = 0 => non-restartable */
4841da177e4SLinus Torvalds	ldq	$0, SP_OFF($sp)
4851da177e4SLinus Torvalds	and	$0, 8, $0
48677edffb6SAl Viro	beq	$0, ret_to_kernel
487494486a1SAl Viroret_to_user:
4881da177e4SLinus Torvalds	/* Make sure need_resched and sigpending don't change between
4891da177e4SLinus Torvalds		sampling and the rti.  */
4901da177e4SLinus Torvalds	lda	$16, 7
4911da177e4SLinus Torvalds	call_pal PAL_swpipl
492cb450766SAl Viro	ldl	$17, TI_FLAGS($8)
493cb450766SAl Viro	and	$17, _TIF_WORK_MASK, $2
494494486a1SAl Viro	bne	$2, work_pending
4951da177e4SLinus Torvaldsrestore_all:
49605096666SAl Viro	ldl	$2, TI_STATUS($8)
49705096666SAl Viro	and	$2, TS_SAVED_FP | TS_RESTORE_FP, $3
49805096666SAl Viro	bne	$3, restore_fpu
49905096666SAl Virorestore_other:
500231b0bedSRichard Henderson	.cfi_remember_state
5011da177e4SLinus Torvalds	RESTORE_ALL
5021da177e4SLinus Torvalds	call_pal PAL_rti
5031da177e4SLinus Torvalds
50477edffb6SAl Viroret_to_kernel:
505231b0bedSRichard Henderson	.cfi_restore_state
50677edffb6SAl Viro	lda	$16, 7
50777edffb6SAl Viro	call_pal PAL_swpipl
50805096666SAl Viro	br restore_other
50977edffb6SAl Viro
5101da177e4SLinus Torvalds	.align 3
5111da177e4SLinus Torvalds$syscall_error:
5121da177e4SLinus Torvalds	/*
5131da177e4SLinus Torvalds	 * Some system calls (e.g., ptrace) can return arbitrary
5141da177e4SLinus Torvalds	 * values which might normally be mistaken as error numbers.
5151da177e4SLinus Torvalds	 * Those functions must zero $0 (v0) directly in the stack
5161da177e4SLinus Torvalds	 * frame to indicate that a negative return value wasn't an
5171da177e4SLinus Torvalds	 * error number..
5181da177e4SLinus Torvalds	 */
519cb450766SAl Viro	ldq	$18, 0($sp)	/* old syscall nr (zero if success) */
520cb450766SAl Viro	beq	$18, $ret_success
5211da177e4SLinus Torvalds
522cb450766SAl Viro	ldq	$19, 72($sp)	/* .. and this a3 */
5231da177e4SLinus Torvalds	subq	$31, $0, $0	/* with error in v0 */
5241da177e4SLinus Torvalds	addq	$31, 1, $1	/* set a3 for errno return */
5251da177e4SLinus Torvalds	stq	$0, 0($sp)
5261da177e4SLinus Torvalds	mov	$31, $26	/* tell "ret_from_sys_call" we can restart */
5271da177e4SLinus Torvalds	stq	$1, 72($sp)	/* a3 for return */
5281da177e4SLinus Torvalds	br	ret_from_sys_call
5291da177e4SLinus Torvalds
5301da177e4SLinus Torvalds/*
5311da177e4SLinus Torvalds * Do all cleanup when returning from all interrupts and system calls.
5321da177e4SLinus Torvalds *
5331da177e4SLinus Torvalds * Arguments:
5341da177e4SLinus Torvalds *       $8: current.
535cb450766SAl Viro *      $17: TI_FLAGS.
536cb450766SAl Viro *      $18: The old syscall number, or zero if this is not a return
5371da177e4SLinus Torvalds *           from a syscall that errored and is possibly restartable.
538cb450766SAl Viro *      $19: The old a3 value
5391da177e4SLinus Torvalds */
5401da177e4SLinus Torvalds
5411da177e4SLinus Torvalds	.align	4
542231b0bedSRichard Henderson	.type	work_pending, @function
5431da177e4SLinus Torvaldswork_pending:
5445a9a8897SJens Axboe	and	$17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL, $2
5457721d3c2SAl Viro	bne	$2, $work_notifysig
5461da177e4SLinus Torvalds
5471da177e4SLinus Torvalds$work_resched:
5487721d3c2SAl Viro	/*
5497721d3c2SAl Viro	 * We can get here only if we returned from syscall without SIGPENDING
5507721d3c2SAl Viro	 * or got through work_notifysig already.  Either case means no syscall
551cb450766SAl Viro	 * restarts for us, so let $18 and $19 burn.
5527721d3c2SAl Viro	 */
5531da177e4SLinus Torvalds	jsr	$26, schedule
554cb450766SAl Viro	mov	0, $18
5557721d3c2SAl Viro	br	ret_to_user
5561da177e4SLinus Torvalds
5571da177e4SLinus Torvalds$work_notifysig:
558b927b3e2SRichard Henderson	mov	$sp, $16
559231b0bedSRichard Henderson	DO_SWITCH_STACK
5606972d6f2SAl Viro	jsr	$26, do_work_pending
561231b0bedSRichard Henderson	UNDO_SWITCH_STACK
5626972d6f2SAl Viro	br	restore_all
5631da177e4SLinus Torvalds
5641da177e4SLinus Torvalds/*
5651da177e4SLinus Torvalds * PTRACE syscall handler
5661da177e4SLinus Torvalds */
5671da177e4SLinus Torvalds
5681da177e4SLinus Torvalds	.align	4
569231b0bedSRichard Henderson	.type	strace, @function
5701da177e4SLinus Torvaldsstrace:
5711da177e4SLinus Torvalds	/* set up signal stack, call syscall_trace */
57205096666SAl Viro	// NB: if anyone adds preemption, this block will need to be protected
57305096666SAl Viro	ldl	$1, TI_STATUS($8)
57405096666SAl Viro	and	$1, TS_SAVED_FP, $3
57505096666SAl Viro	or	$1, TS_SAVED_FP, $2
57605096666SAl Viro	bne	$3, 1f
57705096666SAl Viro	stl	$2, TI_STATUS($8)
57805096666SAl Viro	bsr	$26, __save_fpu
57905096666SAl Viro1:
580231b0bedSRichard Henderson	DO_SWITCH_STACK
58112f79be9SAl Viro	jsr	$26, syscall_trace_enter /* returns the syscall number */
582231b0bedSRichard Henderson	UNDO_SWITCH_STACK
5831da177e4SLinus Torvalds
58412f79be9SAl Viro	/* get the arguments back.. */
5851da177e4SLinus Torvalds	ldq	$16, SP_OFF+24($sp)
5861da177e4SLinus Torvalds	ldq	$17, SP_OFF+32($sp)
5871da177e4SLinus Torvalds	ldq	$18, SP_OFF+40($sp)
5881da177e4SLinus Torvalds	ldq	$19, 72($sp)
5891da177e4SLinus Torvalds	ldq	$20, 80($sp)
5901da177e4SLinus Torvalds	ldq	$21, 88($sp)
5911da177e4SLinus Torvalds
5921da177e4SLinus Torvalds	/* get the system call pointer.. */
593d6e59579SYang Yang	lda	$1, NR_syscalls($31)
5941da177e4SLinus Torvalds	lda	$2, sys_call_table
595060581c1SAl Viro	lda	$27, sys_ni_syscall
5961da177e4SLinus Torvalds	cmpult	$0, $1, $1
5971da177e4SLinus Torvalds	s8addq	$0, $2, $2
5981da177e4SLinus Torvalds	beq	$1, 1f
5991da177e4SLinus Torvalds	ldq	$27, 0($2)
6001da177e4SLinus Torvalds1:	jsr	$26, ($27), sys_gettimeofday
60153293638SAl Viroret_from_straced:
6021da177e4SLinus Torvalds	ldgp	$gp, 0($26)
6031da177e4SLinus Torvalds
6041da177e4SLinus Torvalds	/* check return.. */
6051da177e4SLinus Torvalds	blt	$0, $strace_error	/* the call failed */
6061da177e4SLinus Torvalds$strace_success:
60719a09e42SAl Viro	stq	$31, 72($sp)		/* a3=0 => no error */
6081da177e4SLinus Torvalds	stq	$0, 0($sp)		/* save return value */
6091da177e4SLinus Torvalds
610231b0bedSRichard Henderson	DO_SWITCH_STACK
61112f79be9SAl Viro	jsr	$26, syscall_trace_leave
612231b0bedSRichard Henderson	UNDO_SWITCH_STACK
6131da177e4SLinus Torvalds	br	$31, ret_from_sys_call
6141da177e4SLinus Torvalds
6151da177e4SLinus Torvalds	.align	3
6161da177e4SLinus Torvalds$strace_error:
617cb450766SAl Viro	ldq	$18, 0($sp)	/* old syscall nr (zero if success) */
618cb450766SAl Viro	beq	$18, $strace_success
619cb450766SAl Viro	ldq	$19, 72($sp)	/* .. and this a3 */
6201da177e4SLinus Torvalds
6211da177e4SLinus Torvalds	subq	$31, $0, $0	/* with error in v0 */
6221da177e4SLinus Torvalds	addq	$31, 1, $1	/* set a3 for errno return */
6231da177e4SLinus Torvalds	stq	$0, 0($sp)
6241da177e4SLinus Torvalds	stq	$1, 72($sp)	/* a3 for return */
6251da177e4SLinus Torvalds
626231b0bedSRichard Henderson	DO_SWITCH_STACK
627cb450766SAl Viro	mov	$18, $9		/* save old syscall number */
628cb450766SAl Viro	mov	$19, $10	/* save old a3 */
62912f79be9SAl Viro	jsr	$26, syscall_trace_leave
630cb450766SAl Viro	mov	$9, $18
631cb450766SAl Viro	mov	$10, $19
632231b0bedSRichard Henderson	UNDO_SWITCH_STACK
6331da177e4SLinus Torvalds
6341da177e4SLinus Torvalds	mov	$31, $26	/* tell "ret_from_sys_call" we can restart */
6351da177e4SLinus Torvalds	br	ret_from_sys_call
636231b0bedSRichard HendersonCFI_END_OSF_FRAME entSys
6371da177e4SLinus Torvalds
6381da177e4SLinus Torvalds/*
6391da177e4SLinus Torvalds * Save and restore the switch stack -- aka the balance of the user context.
6401da177e4SLinus Torvalds */
6411da177e4SLinus Torvalds
6421da177e4SLinus Torvalds	.align	4
643231b0bedSRichard Henderson	.type	do_switch_stack, @function
644231b0bedSRichard Henderson	.cfi_startproc simple
645231b0bedSRichard Henderson	.cfi_return_column 64
646231b0bedSRichard Henderson	.cfi_def_cfa $sp, 0
647231b0bedSRichard Henderson	.cfi_register 64, $1
6481da177e4SLinus Torvaldsdo_switch_stack:
6491da177e4SLinus Torvalds	lda	$sp, -SWITCH_STACK_SIZE($sp)
650231b0bedSRichard Henderson	.cfi_adjust_cfa_offset	SWITCH_STACK_SIZE
6511da177e4SLinus Torvalds	stq	$9, 0($sp)
6521da177e4SLinus Torvalds	stq	$10, 8($sp)
6531da177e4SLinus Torvalds	stq	$11, 16($sp)
6541da177e4SLinus Torvalds	stq	$12, 24($sp)
6551da177e4SLinus Torvalds	stq	$13, 32($sp)
6561da177e4SLinus Torvalds	stq	$14, 40($sp)
6571da177e4SLinus Torvalds	stq	$15, 48($sp)
6581da177e4SLinus Torvalds	stq	$26, 56($sp)
6591da177e4SLinus Torvalds	ret	$31, ($1), 1
660231b0bedSRichard Henderson	.cfi_endproc
661231b0bedSRichard Henderson	.size	do_switch_stack, .-do_switch_stack
6621da177e4SLinus Torvalds
6631da177e4SLinus Torvalds	.align	4
664231b0bedSRichard Henderson	.type	undo_switch_stack, @function
665231b0bedSRichard Henderson	.cfi_startproc simple
666231b0bedSRichard Henderson	.cfi_def_cfa $sp, 0
667231b0bedSRichard Henderson	.cfi_register 64, $1
6681da177e4SLinus Torvaldsundo_switch_stack:
6691da177e4SLinus Torvalds	ldq	$9, 0($sp)
6701da177e4SLinus Torvalds	ldq	$10, 8($sp)
6711da177e4SLinus Torvalds	ldq	$11, 16($sp)
6721da177e4SLinus Torvalds	ldq	$12, 24($sp)
6731da177e4SLinus Torvalds	ldq	$13, 32($sp)
6741da177e4SLinus Torvalds	ldq	$14, 40($sp)
6751da177e4SLinus Torvalds	ldq	$15, 48($sp)
6761da177e4SLinus Torvalds	ldq	$26, 56($sp)
6771da177e4SLinus Torvalds	lda	$sp, SWITCH_STACK_SIZE($sp)
6781da177e4SLinus Torvalds	ret	$31, ($1), 1
679231b0bedSRichard Henderson	.cfi_endproc
680231b0bedSRichard Henderson	.size	undo_switch_stack, .-undo_switch_stack
68105096666SAl Viro
68205096666SAl Viro#define FR(n) n * 8 + TI_FP($8)
68305096666SAl Viro	.align	4
68405096666SAl Viro	.globl	__save_fpu
68505096666SAl Viro	.type	__save_fpu, @function
68605096666SAl Viro__save_fpu:
68705096666SAl Viro#define V(n) stt	$f##n, FR(n)
68805096666SAl Viro	V( 0); V( 1); V( 2); V( 3)
68905096666SAl Viro	V( 4); V( 5); V( 6); V( 7)
69005096666SAl Viro	V( 8); V( 9); V(10); V(11)
69105096666SAl Viro	V(12); V(13); V(14); V(15)
69205096666SAl Viro	V(16); V(17); V(18); V(19)
69305096666SAl Viro	V(20); V(21); V(22); V(23)
69405096666SAl Viro	V(24); V(25); V(26); V(27)
69505096666SAl Viro	mf_fpcr	$f0		# get fpcr
69605096666SAl Viro	V(28); V(29); V(30)
69705096666SAl Viro	stt	$f0, FR(31)	# save fpcr in slot of $f31
69805096666SAl Viro	ldt	$f0, FR(0)	# don't let "__save_fpu" change fp state.
69905096666SAl Viro	ret
70005096666SAl Viro#undef V
70105096666SAl Viro	.size	__save_fpu, .-__save_fpu
70205096666SAl Viro
70305096666SAl Viro	.align	4
70405096666SAl Virorestore_fpu:
70505096666SAl Viro	and	$3, TS_RESTORE_FP, $3
70605096666SAl Viro	bic	$2, TS_SAVED_FP | TS_RESTORE_FP, $2
70705096666SAl Viro	beq	$3, 1f
70805096666SAl Viro#define V(n) ldt	$f##n, FR(n)
70905096666SAl Viro	ldt	$f30, FR(31)	# get saved fpcr
71005096666SAl Viro	V( 0); V( 1); V( 2); V( 3)
71105096666SAl Viro	mt_fpcr	$f30		# install saved fpcr
71205096666SAl Viro	V( 4); V( 5); V( 6); V( 7)
71305096666SAl Viro	V( 8); V( 9); V(10); V(11)
71405096666SAl Viro	V(12); V(13); V(14); V(15)
71505096666SAl Viro	V(16); V(17); V(18); V(19)
71605096666SAl Viro	V(20); V(21); V(22); V(23)
71705096666SAl Viro	V(24); V(25); V(26); V(27)
71805096666SAl Viro	V(28); V(29); V(30)
71905096666SAl Viro1:	stl $2, TI_STATUS($8)
72005096666SAl Viro	br restore_other
72105096666SAl Viro#undef V
72205096666SAl Viro
7231da177e4SLinus Torvalds
7241da177e4SLinus Torvalds/*
7251da177e4SLinus Torvalds * The meat of the context switch code.
7261da177e4SLinus Torvalds */
7271da177e4SLinus Torvalds	.align	4
7281da177e4SLinus Torvalds	.globl	alpha_switch_to
729231b0bedSRichard Henderson	.type	alpha_switch_to, @function
730231b0bedSRichard Henderson	.cfi_startproc
7311da177e4SLinus Torvaldsalpha_switch_to:
732231b0bedSRichard Henderson	DO_SWITCH_STACK
73305096666SAl Viro	ldl	$1, TI_STATUS($8)
73405096666SAl Viro	and	$1, TS_RESTORE_FP, $3
73505096666SAl Viro	bne	$3, 1f
73605096666SAl Viro	or	$1, TS_RESTORE_FP | TS_SAVED_FP, $2
73705096666SAl Viro	and	$1, TS_SAVED_FP, $3
73805096666SAl Viro	stl	$2, TI_STATUS($8)
73905096666SAl Viro	bne	$3, 1f
74005096666SAl Viro	bsr	$26, __save_fpu
74105096666SAl Viro1:
7421da177e4SLinus Torvalds	call_pal PAL_swpctx
7431da177e4SLinus Torvalds	lda	$8, 0x3fff
744231b0bedSRichard Henderson	UNDO_SWITCH_STACK
7451da177e4SLinus Torvalds	bic	$sp, $8, $8
7461da177e4SLinus Torvalds	mov	$17, $0
7471da177e4SLinus Torvalds	ret
748231b0bedSRichard Henderson	.cfi_endproc
749231b0bedSRichard Henderson	.size	alpha_switch_to, .-alpha_switch_to
7501da177e4SLinus Torvalds
7511da177e4SLinus Torvalds/*
7521da177e4SLinus Torvalds * New processes begin life here.
7531da177e4SLinus Torvalds */
7541da177e4SLinus Torvalds
7551da177e4SLinus Torvalds	.globl	ret_from_fork
7561da177e4SLinus Torvalds	.align	4
7571da177e4SLinus Torvalds	.ent	ret_from_fork
7581da177e4SLinus Torvaldsret_from_fork:
759fa6a3bf7SAl Viro	lda	$26, ret_to_user
7601da177e4SLinus Torvalds	mov	$17, $16
7611da177e4SLinus Torvalds	jmp	$31, schedule_tail
7621da177e4SLinus Torvalds.end ret_from_fork
7631da177e4SLinus Torvalds
7641da177e4SLinus Torvalds/*
765cba1ec7eSAl Viro * ... and new kernel threads - here
7661da177e4SLinus Torvalds */
7671da177e4SLinus Torvalds	.align 4
768cba1ec7eSAl Viro	.globl	ret_from_kernel_thread
769cba1ec7eSAl Viro	.ent	ret_from_kernel_thread
770cba1ec7eSAl Viroret_from_kernel_thread:
771cba1ec7eSAl Viro	mov	$17, $16
772cba1ec7eSAl Viro	jsr	$26, schedule_tail
773cba1ec7eSAl Viro	mov	$9, $27
774cba1ec7eSAl Viro	mov	$10, $16
775cba1ec7eSAl Viro	jsr	$26, ($9)
77644f4b56bSAl Viro	br	$31, ret_to_user
7775522be6aSAl Viro.end ret_from_kernel_thread
77844f4b56bSAl Viro
7791da177e4SLinus Torvalds
7801da177e4SLinus Torvalds/*
7811da177e4SLinus Torvalds * Special system calls.  Most of these are special in that they either
7828a68060cSAl Viro * have to play switch_stack games.
7831da177e4SLinus Torvalds */
784dfe09ae0SAl Viro
785dfe09ae0SAl Viro.macro	fork_like name
7861da177e4SLinus Torvalds	.align	4
787dfe09ae0SAl Viro	.globl	alpha_\name
788dfe09ae0SAl Viro	.ent	alpha_\name
789dfe09ae0SAl Viroalpha_\name:
7901da177e4SLinus Torvalds	.prologue 0
7911da177e4SLinus Torvalds	bsr	$1, do_switch_stack
79205096666SAl Viro	// NB: if anyone adds preemption, this block will need to be protected
79305096666SAl Viro	ldl	$1, TI_STATUS($8)
79405096666SAl Viro	and	$1, TS_SAVED_FP, $3
79505096666SAl Viro	or	$1, TS_SAVED_FP, $2
79605096666SAl Viro	bne	$3, 1f
79705096666SAl Viro	stl	$2, TI_STATUS($8)
79805096666SAl Viro	bsr	$26, __save_fpu
79905096666SAl Viro1:
800dfe09ae0SAl Viro	jsr	$26, sys_\name
801e0e431aaSAl Viro	ldq	$26, 56($sp)
802e0e431aaSAl Viro	lda	$sp, SWITCH_STACK_SIZE($sp)
8031da177e4SLinus Torvalds	ret
804dfe09ae0SAl Viro.end	alpha_\name
805dfe09ae0SAl Viro.endm
8061da177e4SLinus Torvalds
807dfe09ae0SAl Virofork_like fork
808dfe09ae0SAl Virofork_like vfork
809dfe09ae0SAl Virofork_like clone
810b973afe9SAl Virofork_like clone3
8111da177e4SLinus Torvalds
8128a68060cSAl Viro.macro	sigreturn_like name
8131da177e4SLinus Torvalds	.align	4
8148a68060cSAl Viro	.globl	sys_\name
8158a68060cSAl Viro	.ent	sys_\name
8168a68060cSAl Virosys_\name:
8171da177e4SLinus Torvalds	.prologue 0
81853293638SAl Viro	lda	$9, ret_from_straced
81953293638SAl Viro	cmpult	$26, $9, $9
8201da177e4SLinus Torvalds	lda	$sp, -SWITCH_STACK_SIZE($sp)
8218a68060cSAl Viro	jsr	$26, do_\name
82253293638SAl Viro	bne	$9, 1f
82312f79be9SAl Viro	jsr	$26, syscall_trace_leave
82453293638SAl Viro1:	br	$1, undo_switch_stack
8251da177e4SLinus Torvalds	br	ret_from_sys_call
8268a68060cSAl Viro.end sys_\name
8278a68060cSAl Viro.endm
8281da177e4SLinus Torvalds
8298a68060cSAl Virosigreturn_like sigreturn
8308a68060cSAl Virosigreturn_like rt_sigreturn
8311da177e4SLinus Torvalds
8321da177e4SLinus Torvalds	.align	4
833060581c1SAl Viro	.globl	alpha_syscall_zero
834060581c1SAl Viro	.ent	alpha_syscall_zero
835060581c1SAl Viroalpha_syscall_zero:
8361da177e4SLinus Torvalds	.prologue 0
837060581c1SAl Viro	/* Special because it needs to do something opposite to
838060581c1SAl Viro	   force_successful_syscall_return().  We use the saved
839060581c1SAl Viro	   syscall number for that, zero meaning "not an error".
840060581c1SAl Viro	   That works nicely, but for real syscall 0 we need to
841060581c1SAl Viro	   make sure that this logics doesn't get confused.
842060581c1SAl Viro	   Store a non-zero there - -ENOSYS we need in register
843060581c1SAl Viro	   for our return value will do just fine.
844060581c1SAl Viro	  */
8451da177e4SLinus Torvalds	lda	$0, -ENOSYS
8461da177e4SLinus Torvalds	unop
8471da177e4SLinus Torvalds	stq	$0, 0($sp)
8481da177e4SLinus Torvalds	ret
849060581c1SAl Viro.end alpha_syscall_zero
850