xref: /openbmc/linux/arch/arm/kernel/entry-common.S (revision 6176d394)
11da177e4SLinus Torvalds/*
21da177e4SLinus Torvalds *  linux/arch/arm/kernel/entry-common.S
31da177e4SLinus Torvalds *
41da177e4SLinus Torvalds *  Copyright (C) 2000 Russell King
51da177e4SLinus Torvalds *
61da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify
71da177e4SLinus Torvalds * it under the terms of the GNU General Public License version 2 as
81da177e4SLinus Torvalds * published by the Free Software Foundation.
91da177e4SLinus Torvalds */
101da177e4SLinus Torvalds
111da177e4SLinus Torvalds#include <asm/unistd.h>
12395a59d0SAbhishek Sagar#include <asm/ftrace.h>
13a09e64fbSRussell King#include <mach/entry-macro.S>
14c4c5716eSCatalin Marinas#include <asm/unwind.h>
151da177e4SLinus Torvalds
161da177e4SLinus Torvalds#include "entry-header.S"
171da177e4SLinus Torvalds
181da177e4SLinus Torvalds
191da177e4SLinus Torvalds	.align	5
201da177e4SLinus Torvalds/*
211da177e4SLinus Torvalds * This is the fast syscall return path.  We do as little as
221da177e4SLinus Torvalds * possible here, and this includes saving r0 back into the SVC
231da177e4SLinus Torvalds * stack.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvaldsret_fast_syscall:
26c4c5716eSCatalin Marinas UNWIND(.fnstart	)
27c4c5716eSCatalin Marinas UNWIND(.cantunwind	)
281ec42c0cSRussell King	disable_irq				@ disable interrupts
291da177e4SLinus Torvalds	ldr	r1, [tsk, #TI_FLAGS]
301da177e4SLinus Torvalds	tst	r1, #_TIF_WORK_MASK
311da177e4SLinus Torvalds	bne	fast_work_pending
32f4dc9a4cSRussell King
33f80dff9dSDan Williams	/* perform architecture specific actions before user return */
34f80dff9dSDan Williams	arch_ret_to_user r1, lr
35f80dff9dSDan Williams
36b86040a5SCatalin Marinas	restore_user_regs fast = 1, offset = S_OFF
37c4c5716eSCatalin Marinas UNWIND(.fnend		)
381da177e4SLinus Torvalds
391da177e4SLinus Torvalds/*
401da177e4SLinus Torvalds * Ok, we need to do extra processing, enter the slow path.
411da177e4SLinus Torvalds */
421da177e4SLinus Torvaldsfast_work_pending:
431da177e4SLinus Torvalds	str	r0, [sp, #S_R0+S_OFF]!		@ returned r0
441da177e4SLinus Torvaldswork_pending:
451da177e4SLinus Torvalds	tst	r1, #_TIF_NEED_RESCHED
461da177e4SLinus Torvalds	bne	work_resched
47d0420c83SDavid Howells	tst	r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
481da177e4SLinus Torvalds	beq	no_work_pending
491da177e4SLinus Torvalds	mov	r0, sp				@ 'regs'
501da177e4SLinus Torvalds	mov	r2, why				@ 'syscall'
511da177e4SLinus Torvalds	bl	do_notify_resume
52a6c61e9dSDaniel Jacobowitz	b	ret_slow_syscall		@ Check work again
531da177e4SLinus Torvalds
541da177e4SLinus Torvaldswork_resched:
551da177e4SLinus Torvalds	bl	schedule
561da177e4SLinus Torvalds/*
571da177e4SLinus Torvalds * "slow" syscall return path.  "why" tells us if this was a real syscall.
581da177e4SLinus Torvalds */
591da177e4SLinus TorvaldsENTRY(ret_to_user)
601da177e4SLinus Torvaldsret_slow_syscall:
611ec42c0cSRussell King	disable_irq				@ disable interrupts
621da177e4SLinus Torvalds	ldr	r1, [tsk, #TI_FLAGS]
631da177e4SLinus Torvalds	tst	r1, #_TIF_WORK_MASK
641da177e4SLinus Torvalds	bne	work_pending
651da177e4SLinus Torvaldsno_work_pending:
66f80dff9dSDan Williams	/* perform architecture specific actions before user return */
67f80dff9dSDan Williams	arch_ret_to_user r1, lr
68f80dff9dSDan Williams
69b86040a5SCatalin Marinas	restore_user_regs fast = 0, offset = 0
7093ed3970SCatalin MarinasENDPROC(ret_to_user)
711da177e4SLinus Torvalds
721da177e4SLinus Torvalds/*
731da177e4SLinus Torvalds * This is how we return from a fork.
741da177e4SLinus Torvalds */
751da177e4SLinus TorvaldsENTRY(ret_from_fork)
761da177e4SLinus Torvalds	bl	schedule_tail
771da177e4SLinus Torvalds	get_thread_info tsk
781da177e4SLinus Torvalds	ldr	r1, [tsk, #TI_FLAGS]		@ check for syscall tracing
791da177e4SLinus Torvalds	mov	why, #1
801da177e4SLinus Torvalds	tst	r1, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
811da177e4SLinus Torvalds	beq	ret_slow_syscall
821da177e4SLinus Torvalds	mov	r1, sp
831da177e4SLinus Torvalds	mov	r0, #1				@ trace exit [IP = 1]
841da177e4SLinus Torvalds	bl	syscall_trace
851da177e4SLinus Torvalds	b	ret_slow_syscall
8693ed3970SCatalin MarinasENDPROC(ret_from_fork)
871da177e4SLinus Torvalds
88fa1b4f91SAl Viro	.equ NR_syscalls,0
89fa1b4f91SAl Viro#define CALL(x) .equ NR_syscalls,NR_syscalls+1
901da177e4SLinus Torvalds#include "calls.S"
91fa1b4f91SAl Viro#undef CALL
92fa1b4f91SAl Viro#define CALL(x) .long x
931da177e4SLinus Torvalds
94606576ceSSteven Rostedt#ifdef CONFIG_FUNCTION_TRACER
95014c257cSAbhishek Sagar#ifdef CONFIG_DYNAMIC_FTRACE
96014c257cSAbhishek SagarENTRY(mcount)
97014c257cSAbhishek Sagar	stmdb sp!, {r0-r3, lr}
98014c257cSAbhishek Sagar	mov r0, lr
99395a59d0SAbhishek Sagar	sub r0, r0, #MCOUNT_INSN_SIZE
100014c257cSAbhishek Sagar
101014c257cSAbhishek Sagar	.globl mcount_call
102014c257cSAbhishek Sagarmcount_call:
103014c257cSAbhishek Sagar	bl ftrace_stub
104d4cc510cSUwe Kleine-König	ldr lr, [fp, #-4]			@ restore lr
105014c257cSAbhishek Sagar	ldmia sp!, {r0-r3, pc}
106014c257cSAbhishek Sagar
107014c257cSAbhishek SagarENTRY(ftrace_caller)
108014c257cSAbhishek Sagar	stmdb sp!, {r0-r3, lr}
109014c257cSAbhishek Sagar	ldr r1, [fp, #-4]
110014c257cSAbhishek Sagar	mov r0, lr
111395a59d0SAbhishek Sagar	sub r0, r0, #MCOUNT_INSN_SIZE
112014c257cSAbhishek Sagar
113014c257cSAbhishek Sagar	.globl ftrace_call
114014c257cSAbhishek Sagarftrace_call:
115014c257cSAbhishek Sagar	bl ftrace_stub
116d4cc510cSUwe Kleine-König	ldr lr, [fp, #-4]			@ restore lr
117014c257cSAbhishek Sagar	ldmia sp!, {r0-r3, pc}
118014c257cSAbhishek Sagar
119014c257cSAbhishek Sagar#else
120014c257cSAbhishek Sagar
121181f817eSUwe Kleine-KönigENTRY(__gnu_mcount_nc)
122181f817eSUwe Kleine-König	stmdb sp!, {r0-r3, lr}
123181f817eSUwe Kleine-König	ldr r0, =ftrace_trace_function
124181f817eSUwe Kleine-König	ldr r2, [r0]
125181f817eSUwe Kleine-König	adr r0, ftrace_stub
126181f817eSUwe Kleine-König	cmp r0, r2
127181f817eSUwe Kleine-König	bne gnu_trace
128181f817eSUwe Kleine-König	ldmia sp!, {r0-r3, ip, lr}
1296176d394SDmitry Artamonow	mov pc, ip
130181f817eSUwe Kleine-König
131181f817eSUwe Kleine-Königgnu_trace:
132181f817eSUwe Kleine-König	ldr r1, [sp, #20]			@ lr of instrumented routine
133181f817eSUwe Kleine-König	mov r0, lr
134181f817eSUwe Kleine-König	sub r0, r0, #MCOUNT_INSN_SIZE
135181f817eSUwe Kleine-König	mov lr, pc
136181f817eSUwe Kleine-König	mov pc, r2
137181f817eSUwe Kleine-König	ldmia sp!, {r0-r3, ip, lr}
1386176d394SDmitry Artamonow	mov pc, ip
139181f817eSUwe Kleine-König
140014c257cSAbhishek SagarENTRY(mcount)
141014c257cSAbhishek Sagar	stmdb sp!, {r0-r3, lr}
142014c257cSAbhishek Sagar	ldr r0, =ftrace_trace_function
143014c257cSAbhishek Sagar	ldr r2, [r0]
144014c257cSAbhishek Sagar	adr r0, ftrace_stub
145014c257cSAbhishek Sagar	cmp r0, r2
146014c257cSAbhishek Sagar	bne trace
147d4cc510cSUwe Kleine-König	ldr lr, [fp, #-4]			@ restore lr
148014c257cSAbhishek Sagar	ldmia sp!, {r0-r3, pc}
149014c257cSAbhishek Sagar
150014c257cSAbhishek Sagartrace:
151b3c960b2SUwe Kleine-König	ldr r1, [fp, #-4]			@ lr of instrumented routine
152014c257cSAbhishek Sagar	mov r0, lr
153395a59d0SAbhishek Sagar	sub r0, r0, #MCOUNT_INSN_SIZE
154014c257cSAbhishek Sagar	mov lr, pc
155014c257cSAbhishek Sagar	mov pc, r2
1563ef7143dSUwe Kleine-König	ldr lr, [fp, #-4]			@ restore lr
157014c257cSAbhishek Sagar	ldmia sp!, {r0-r3, pc}
158014c257cSAbhishek Sagar
159014c257cSAbhishek Sagar#endif /* CONFIG_DYNAMIC_FTRACE */
160014c257cSAbhishek Sagar
161014c257cSAbhishek Sagar	.globl ftrace_stub
162014c257cSAbhishek Sagarftrace_stub:
163014c257cSAbhishek Sagar	mov pc, lr
164014c257cSAbhishek Sagar
165606576ceSSteven Rostedt#endif /* CONFIG_FUNCTION_TRACER */
166014c257cSAbhishek Sagar
1671da177e4SLinus Torvalds/*=============================================================================
1681da177e4SLinus Torvalds * SWI handler
1691da177e4SLinus Torvalds *-----------------------------------------------------------------------------
1701da177e4SLinus Torvalds */
1711da177e4SLinus Torvalds
1721da177e4SLinus Torvalds	/* If we're optimising for StrongARM the resulting code won't
1731da177e4SLinus Torvalds	   run on an ARM7 and we can save a couple of instructions.
1741da177e4SLinus Torvalds								--pb */
1751da177e4SLinus Torvalds#ifdef CONFIG_CPU_ARM710
1763f2829a3SNicolas Pitre#define A710(code...) code
1773f2829a3SNicolas Pitre.Larm710bug:
1781da177e4SLinus Torvalds	ldmia	sp, {r0 - lr}^			@ Get calling r0 - lr
1791da177e4SLinus Torvalds	mov	r0, r0
1801da177e4SLinus Torvalds	add	sp, sp, #S_FRAME_SIZE
18160ac133aSNicolas Pitre	subs	pc, lr, #4
1821da177e4SLinus Torvalds#else
1833f2829a3SNicolas Pitre#define A710(code...)
1841da177e4SLinus Torvalds#endif
1851da177e4SLinus Torvalds
1861da177e4SLinus Torvalds	.align	5
1871da177e4SLinus TorvaldsENTRY(vector_swi)
188f4dc9a4cSRussell King	sub	sp, sp, #S_FRAME_SIZE
189f4dc9a4cSRussell King	stmia	sp, {r0 - r12}			@ Calling r0 - r12
190b86040a5SCatalin Marinas ARM(	add	r8, sp, #S_PC		)
191b86040a5SCatalin Marinas ARM(	stmdb	r8, {sp, lr}^		)	@ Calling sp, lr
192b86040a5SCatalin Marinas THUMB(	mov	r8, sp			)
193b86040a5SCatalin Marinas THUMB(	store_user_sp_lr r8, r10, S_SP	)	@ calling sp, lr
194f4dc9a4cSRussell King	mrs	r8, spsr			@ called from non-FIQ mode, so ok.
195f4dc9a4cSRussell King	str	lr, [sp, #S_PC]			@ Save calling PC
196f4dc9a4cSRussell King	str	r8, [sp, #S_PSR]		@ Save CPSR
197f4dc9a4cSRussell King	str	r0, [sp, #S_OLD_R0]		@ Save OLD_R0
1981da177e4SLinus Torvalds	zero_fp
199e0f9f4a6SRussell King
200e0f9f4a6SRussell King	/*
201e0f9f4a6SRussell King	 * Get the system call number.
202e0f9f4a6SRussell King	 */
2033f2829a3SNicolas Pitre
204dd35afc2SNicolas Pitre#if defined(CONFIG_OABI_COMPAT)
2053f2829a3SNicolas Pitre
206dd35afc2SNicolas Pitre	/*
207dd35afc2SNicolas Pitre	 * If we have CONFIG_OABI_COMPAT then we need to look at the swi
208dd35afc2SNicolas Pitre	 * value to determine if it is an EABI or an old ABI call.
209dd35afc2SNicolas Pitre	 */
210dd35afc2SNicolas Pitre#ifdef CONFIG_ARM_THUMB
211dd35afc2SNicolas Pitre	tst	r8, #PSR_T_BIT
212dd35afc2SNicolas Pitre	movne	r10, #0				@ no thumb OABI emulation
213dd35afc2SNicolas Pitre	ldreq	r10, [lr, #-4]			@ get SWI instruction
214dd35afc2SNicolas Pitre#else
215dd35afc2SNicolas Pitre	ldr	r10, [lr, #-4]			@ get SWI instruction
216dd35afc2SNicolas Pitre  A710(	and	ip, r10, #0x0f000000		@ check for SWI		)
217dd35afc2SNicolas Pitre  A710(	teq	ip, #0x0f000000						)
218dd35afc2SNicolas Pitre  A710(	bne	.Larm710bug						)
219dd35afc2SNicolas Pitre#endif
22026584853SCatalin Marinas#ifdef CONFIG_CPU_ENDIAN_BE8
22126584853SCatalin Marinas	rev	r10, r10			@ little endian instruction
22226584853SCatalin Marinas#endif
223dd35afc2SNicolas Pitre
224dd35afc2SNicolas Pitre#elif defined(CONFIG_AEABI)
225dd35afc2SNicolas Pitre
226dd35afc2SNicolas Pitre	/*
227dd35afc2SNicolas Pitre	 * Pure EABI user space always put syscall number into scno (r7).
228dd35afc2SNicolas Pitre	 */
2293f2829a3SNicolas Pitre  A710(	ldr	ip, [lr, #-4]			@ get SWI instruction	)
2303f2829a3SNicolas Pitre  A710(	and	ip, ip, #0x0f000000		@ check for SWI		)
2313f2829a3SNicolas Pitre  A710(	teq	ip, #0x0f000000						)
2323f2829a3SNicolas Pitre  A710(	bne	.Larm710bug						)
233dd35afc2SNicolas Pitre
2343f2829a3SNicolas Pitre#elif defined(CONFIG_ARM_THUMB)
235dd35afc2SNicolas Pitre
236dd35afc2SNicolas Pitre	/* Legacy ABI only, possibly thumb mode. */
237e0f9f4a6SRussell King	tst	r8, #PSR_T_BIT			@ this is SPSR from save_user_regs
238e0f9f4a6SRussell King	addne	scno, r7, #__NR_SYSCALL_BASE	@ put OS number in
239e0f9f4a6SRussell King	ldreq	scno, [lr, #-4]
240dd35afc2SNicolas Pitre
241e0f9f4a6SRussell King#else
242dd35afc2SNicolas Pitre
243dd35afc2SNicolas Pitre	/* Legacy ABI only. */
244e0f9f4a6SRussell King	ldr	scno, [lr, #-4]			@ get SWI instruction
2453f2829a3SNicolas Pitre  A710(	and	ip, scno, #0x0f000000		@ check for SWI		)
2463f2829a3SNicolas Pitre  A710(	teq	ip, #0x0f000000						)
2473f2829a3SNicolas Pitre  A710(	bne	.Larm710bug						)
248dd35afc2SNicolas Pitre
249e0f9f4a6SRussell King#endif
2501da177e4SLinus Torvalds
2511da177e4SLinus Torvalds#ifdef CONFIG_ALIGNMENT_TRAP
2521da177e4SLinus Torvalds	ldr	ip, __cr_alignment
2531da177e4SLinus Torvalds	ldr	ip, [ip]
2541da177e4SLinus Torvalds	mcr	p15, 0, ip, c1, c0		@ update control register
2551da177e4SLinus Torvalds#endif
2561ec42c0cSRussell King	enable_irq
2571da177e4SLinus Torvalds
2581da177e4SLinus Torvalds	get_thread_info tsk
259dd35afc2SNicolas Pitre	adr	tbl, sys_call_table		@ load syscall table pointer
2601da177e4SLinus Torvalds	ldr	ip, [tsk, #TI_FLAGS]		@ check for syscall tracing
261dd35afc2SNicolas Pitre
262dd35afc2SNicolas Pitre#if defined(CONFIG_OABI_COMPAT)
263dd35afc2SNicolas Pitre	/*
264dd35afc2SNicolas Pitre	 * If the swi argument is zero, this is an EABI call and we do nothing.
265dd35afc2SNicolas Pitre	 *
266dd35afc2SNicolas Pitre	 * If this is an old ABI call, get the syscall number into scno and
267dd35afc2SNicolas Pitre	 * get the old ABI syscall table address.
268dd35afc2SNicolas Pitre	 */
269dd35afc2SNicolas Pitre	bics	r10, r10, #0xff000000
270dd35afc2SNicolas Pitre	eorne	scno, r10, #__NR_OABI_SYSCALL_BASE
271dd35afc2SNicolas Pitre	ldrne	tbl, =sys_oabi_call_table
272dd35afc2SNicolas Pitre#elif !defined(CONFIG_AEABI)
2731da177e4SLinus Torvalds	bic	scno, scno, #0xff000000		@ mask off SWI op-code
274e0f9f4a6SRussell King	eor	scno, scno, #__NR_SYSCALL_BASE	@ check OS number
2753f2829a3SNicolas Pitre#endif
276dd35afc2SNicolas Pitre
2773f2829a3SNicolas Pitre	stmdb	sp!, {r4, r5}			@ push fifth and sixth args
2781da177e4SLinus Torvalds	tst	ip, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
2791da177e4SLinus Torvalds	bne	__sys_trace
2801da177e4SLinus Torvalds
2811da177e4SLinus Torvalds	cmp	scno, #NR_syscalls		@ check upper syscall limit
282b86040a5SCatalin Marinas	adr	lr, BSYM(ret_fast_syscall)	@ return address
2831da177e4SLinus Torvalds	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
2841da177e4SLinus Torvalds
2851da177e4SLinus Torvalds	add	r1, sp, #S_OFF
2861da177e4SLinus Torvalds2:	mov	why, #0				@ no longer a real syscall
287e0f9f4a6SRussell King	cmp	scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
288e0f9f4a6SRussell King	eor	r0, scno, #__NR_SYSCALL_BASE	@ put OS number back
2891da177e4SLinus Torvalds	bcs	arm_syscall
2901da177e4SLinus Torvalds	b	sys_ni_syscall			@ not private func
29193ed3970SCatalin MarinasENDPROC(vector_swi)
2921da177e4SLinus Torvalds
2931da177e4SLinus Torvalds	/*
2941da177e4SLinus Torvalds	 * This is the really slow path.  We're going to be doing
2951da177e4SLinus Torvalds	 * context switches, and waiting for our parent to respond.
2961da177e4SLinus Torvalds	 */
2971da177e4SLinus Torvalds__sys_trace:
2983f471126SNicolas Pitre	mov	r2, scno
2991da177e4SLinus Torvalds	add	r1, sp, #S_OFF
3001da177e4SLinus Torvalds	mov	r0, #0				@ trace entry [IP = 0]
3011da177e4SLinus Torvalds	bl	syscall_trace
3021da177e4SLinus Torvalds
303b86040a5SCatalin Marinas	adr	lr, BSYM(__sys_trace_return)	@ return address
3043f471126SNicolas Pitre	mov	scno, r0			@ syscall number (possibly new)
3051da177e4SLinus Torvalds	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
3061da177e4SLinus Torvalds	cmp	scno, #NR_syscalls		@ check upper syscall limit
3071da177e4SLinus Torvalds	ldmccia	r1, {r0 - r3}			@ have to reload r0 - r3
3081da177e4SLinus Torvalds	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
3091da177e4SLinus Torvalds	b	2b
3101da177e4SLinus Torvalds
3111da177e4SLinus Torvalds__sys_trace_return:
3121da177e4SLinus Torvalds	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
3133f471126SNicolas Pitre	mov	r2, scno
3141da177e4SLinus Torvalds	mov	r1, sp
3151da177e4SLinus Torvalds	mov	r0, #1				@ trace exit [IP = 1]
3161da177e4SLinus Torvalds	bl	syscall_trace
3171da177e4SLinus Torvalds	b	ret_slow_syscall
3181da177e4SLinus Torvalds
3191da177e4SLinus Torvalds	.align	5
3201da177e4SLinus Torvalds#ifdef CONFIG_ALIGNMENT_TRAP
3211da177e4SLinus Torvalds	.type	__cr_alignment, #object
3221da177e4SLinus Torvalds__cr_alignment:
3231da177e4SLinus Torvalds	.word	cr_alignment
3241da177e4SLinus Torvalds#endif
325dd35afc2SNicolas Pitre	.ltorg
326dd35afc2SNicolas Pitre
327dd35afc2SNicolas Pitre/*
328dd35afc2SNicolas Pitre * This is the syscall table declaration for native ABI syscalls.
329dd35afc2SNicolas Pitre * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
330dd35afc2SNicolas Pitre */
331dd35afc2SNicolas Pitre#define ABI(native, compat) native
332dd35afc2SNicolas Pitre#ifdef CONFIG_AEABI
333dd35afc2SNicolas Pitre#define OBSOLETE(syscall) sys_ni_syscall
334dd35afc2SNicolas Pitre#else
335dd35afc2SNicolas Pitre#define OBSOLETE(syscall) syscall
336dd35afc2SNicolas Pitre#endif
3371da177e4SLinus Torvalds
3381da177e4SLinus Torvalds	.type	sys_call_table, #object
3391da177e4SLinus TorvaldsENTRY(sys_call_table)
3401da177e4SLinus Torvalds#include "calls.S"
341dd35afc2SNicolas Pitre#undef ABI
342dd35afc2SNicolas Pitre#undef OBSOLETE
3431da177e4SLinus Torvalds
3441da177e4SLinus Torvalds/*============================================================================
3451da177e4SLinus Torvalds * Special system call wrappers
3461da177e4SLinus Torvalds */
3471da177e4SLinus Torvalds@ r0 = syscall number
348567bd980SRussell King@ r8 = syscall table
3491da177e4SLinus Torvaldssys_syscall:
3505247593cSPaul Brook		bic	scno, r0, #__NR_OABI_SYSCALL_BASE
3511da177e4SLinus Torvalds		cmp	scno, #__NR_syscall - __NR_SYSCALL_BASE
3521da177e4SLinus Torvalds		cmpne	scno, #NR_syscalls	@ check range
3531da177e4SLinus Torvalds		stmloia	sp, {r5, r6}		@ shuffle args
3541da177e4SLinus Torvalds		movlo	r0, r1
3551da177e4SLinus Torvalds		movlo	r1, r2
3561da177e4SLinus Torvalds		movlo	r2, r3
3571da177e4SLinus Torvalds		movlo	r3, r4
3581da177e4SLinus Torvalds		ldrlo	pc, [tbl, scno, lsl #2]
3591da177e4SLinus Torvalds		b	sys_ni_syscall
36093ed3970SCatalin MarinasENDPROC(sys_syscall)
3611da177e4SLinus Torvalds
3621da177e4SLinus Torvaldssys_fork_wrapper:
3631da177e4SLinus Torvalds		add	r0, sp, #S_OFF
3641da177e4SLinus Torvalds		b	sys_fork
36593ed3970SCatalin MarinasENDPROC(sys_fork_wrapper)
3661da177e4SLinus Torvalds
3671da177e4SLinus Torvaldssys_vfork_wrapper:
3681da177e4SLinus Torvalds		add	r0, sp, #S_OFF
3691da177e4SLinus Torvalds		b	sys_vfork
37093ed3970SCatalin MarinasENDPROC(sys_vfork_wrapper)
3711da177e4SLinus Torvalds
3721da177e4SLinus Torvaldssys_execve_wrapper:
3731da177e4SLinus Torvalds		add	r3, sp, #S_OFF
3741da177e4SLinus Torvalds		b	sys_execve
37593ed3970SCatalin MarinasENDPROC(sys_execve_wrapper)
3761da177e4SLinus Torvalds
3771da177e4SLinus Torvaldssys_clone_wrapper:
3781da177e4SLinus Torvalds		add	ip, sp, #S_OFF
3791da177e4SLinus Torvalds		str	ip, [sp, #4]
3801da177e4SLinus Torvalds		b	sys_clone
38193ed3970SCatalin MarinasENDPROC(sys_clone_wrapper)
3821da177e4SLinus Torvalds
3831da177e4SLinus Torvaldssys_sigreturn_wrapper:
3841da177e4SLinus Torvalds		add	r0, sp, #S_OFF
3851da177e4SLinus Torvalds		b	sys_sigreturn
38693ed3970SCatalin MarinasENDPROC(sys_sigreturn_wrapper)
3871da177e4SLinus Torvalds
3881da177e4SLinus Torvaldssys_rt_sigreturn_wrapper:
3891da177e4SLinus Torvalds		add	r0, sp, #S_OFF
3901da177e4SLinus Torvalds		b	sys_rt_sigreturn
39193ed3970SCatalin MarinasENDPROC(sys_rt_sigreturn_wrapper)
3921da177e4SLinus Torvalds
3931da177e4SLinus Torvaldssys_sigaltstack_wrapper:
3941da177e4SLinus Torvalds		ldr	r2, [sp, #S_OFF + S_SP]
3951da177e4SLinus Torvalds		b	do_sigaltstack
39693ed3970SCatalin MarinasENDPROC(sys_sigaltstack_wrapper)
3971da177e4SLinus Torvalds
398713c4815SNicolas Pitresys_statfs64_wrapper:
399713c4815SNicolas Pitre		teq	r1, #88
400713c4815SNicolas Pitre		moveq	r1, #84
401713c4815SNicolas Pitre		b	sys_statfs64
40293ed3970SCatalin MarinasENDPROC(sys_statfs64_wrapper)
403713c4815SNicolas Pitre
404713c4815SNicolas Pitresys_fstatfs64_wrapper:
405713c4815SNicolas Pitre		teq	r1, #88
406713c4815SNicolas Pitre		moveq	r1, #84
407713c4815SNicolas Pitre		b	sys_fstatfs64
40893ed3970SCatalin MarinasENDPROC(sys_fstatfs64_wrapper)
409713c4815SNicolas Pitre
4101da177e4SLinus Torvalds/*
4111da177e4SLinus Torvalds * Note: off_4k (r5) is always units of 4K.  If we can't do the requested
4121da177e4SLinus Torvalds * offset, we return EINVAL.
4131da177e4SLinus Torvalds */
4141da177e4SLinus Torvaldssys_mmap2:
4151da177e4SLinus Torvalds#if PAGE_SHIFT > 12
4161da177e4SLinus Torvalds		tst	r5, #PGOFF_MASK
4171da177e4SLinus Torvalds		moveq	r5, r5, lsr #PAGE_SHIFT - 12
4181da177e4SLinus Torvalds		streq	r5, [sp, #4]
4191da177e4SLinus Torvalds		beq	do_mmap2
4201da177e4SLinus Torvalds		mov	r0, #-EINVAL
4217999d8d7SRussell King		mov	pc, lr
4221da177e4SLinus Torvalds#else
4231da177e4SLinus Torvalds		str	r5, [sp, #4]
4241da177e4SLinus Torvalds		b	do_mmap2
4251da177e4SLinus Torvalds#endif
42693ed3970SCatalin MarinasENDPROC(sys_mmap2)
427687ad019SNicolas Pitre
42848d7927bSPaul BrookENTRY(pabort_ifar)
42948d7927bSPaul Brook		mrc	p15, 0, r0, cr6, cr0, 2
43048d7927bSPaul BrookENTRY(pabort_noifar)
43148d7927bSPaul Brook		mov	pc, lr
43293ed3970SCatalin MarinasENDPROC(pabort_ifar)
43393ed3970SCatalin MarinasENDPROC(pabort_noifar)
43448d7927bSPaul Brook
435687ad019SNicolas Pitre#ifdef CONFIG_OABI_COMPAT
436dd35afc2SNicolas Pitre
437687ad019SNicolas Pitre/*
438687ad019SNicolas Pitre * These are syscalls with argument register differences
439687ad019SNicolas Pitre */
440687ad019SNicolas Pitre
441687ad019SNicolas Pitresys_oabi_pread64:
442687ad019SNicolas Pitre		stmia	sp, {r3, r4}
443687ad019SNicolas Pitre		b	sys_pread64
44493ed3970SCatalin MarinasENDPROC(sys_oabi_pread64)
445687ad019SNicolas Pitre
446687ad019SNicolas Pitresys_oabi_pwrite64:
447687ad019SNicolas Pitre		stmia	sp, {r3, r4}
448687ad019SNicolas Pitre		b	sys_pwrite64
44993ed3970SCatalin MarinasENDPROC(sys_oabi_pwrite64)
450687ad019SNicolas Pitre
451687ad019SNicolas Pitresys_oabi_truncate64:
452687ad019SNicolas Pitre		mov	r3, r2
453687ad019SNicolas Pitre		mov	r2, r1
454687ad019SNicolas Pitre		b	sys_truncate64
45593ed3970SCatalin MarinasENDPROC(sys_oabi_truncate64)
456687ad019SNicolas Pitre
457687ad019SNicolas Pitresys_oabi_ftruncate64:
458687ad019SNicolas Pitre		mov	r3, r2
459687ad019SNicolas Pitre		mov	r2, r1
460687ad019SNicolas Pitre		b	sys_ftruncate64
46193ed3970SCatalin MarinasENDPROC(sys_oabi_ftruncate64)
462687ad019SNicolas Pitre
463687ad019SNicolas Pitresys_oabi_readahead:
464687ad019SNicolas Pitre		str	r3, [sp]
465687ad019SNicolas Pitre		mov	r3, r2
466687ad019SNicolas Pitre		mov	r2, r1
467687ad019SNicolas Pitre		b	sys_readahead
46893ed3970SCatalin MarinasENDPROC(sys_oabi_readahead)
469687ad019SNicolas Pitre
470dd35afc2SNicolas Pitre/*
471dd35afc2SNicolas Pitre * Let's declare a second syscall table for old ABI binaries
472dd35afc2SNicolas Pitre * using the compatibility syscall entries.
473dd35afc2SNicolas Pitre */
474dd35afc2SNicolas Pitre#define ABI(native, compat) compat
475dd35afc2SNicolas Pitre#define OBSOLETE(syscall) syscall
476dd35afc2SNicolas Pitre
477dd35afc2SNicolas Pitre	.type	sys_oabi_call_table, #object
478dd35afc2SNicolas PitreENTRY(sys_oabi_call_table)
479dd35afc2SNicolas Pitre#include "calls.S"
480dd35afc2SNicolas Pitre#undef ABI
481dd35afc2SNicolas Pitre#undef OBSOLETE
482dd35afc2SNicolas Pitre
483687ad019SNicolas Pitre#endif
484687ad019SNicolas Pitre
485