xref: /openbmc/linux/arch/parisc/kernel/syscall.S (revision 00df111e)
11da177e4SLinus Torvalds/*
21da177e4SLinus Torvalds * Linux/PA-RISC Project (http://www.parisc-linux.org/)
31da177e4SLinus Torvalds *
41da177e4SLinus Torvalds * System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai>
51da177e4SLinus Torvalds * Licensed under the GNU GPL.
61da177e4SLinus Torvalds * thanks to Philipp Rumpf, Mike Shaver and various others
71da177e4SLinus Torvalds * sorry about the wall, puffin..
81da177e4SLinus Torvalds */
91da177e4SLinus Torvalds
100013a854SSam Ravnborg#include <asm/asm-offsets.h>
111da177e4SLinus Torvalds#include <asm/unistd.h>
121da177e4SLinus Torvalds#include <asm/errno.h>
131c593571SSam Ravnborg#include <asm/page.h>
141da177e4SLinus Torvalds#include <asm/psw.h>
151da177e4SLinus Torvalds#include <asm/thread_info.h>
161da177e4SLinus Torvalds#include <asm/assembly.h>
171da177e4SLinus Torvalds#include <asm/processor.h>
181da177e4SLinus Torvalds
198e9e9844SHelge Deller#include <linux/linkage.h>
208e9e9844SHelge Deller
211da177e4SLinus Torvalds	/* We fill the empty parts of the gateway page with
221da177e4SLinus Torvalds 	 * something that will kill the kernel or a
231da177e4SLinus Torvalds 	 * userspace application.
241da177e4SLinus Torvalds	 */
251da177e4SLinus Torvalds#define KILL_INSN	break	0,0
261da177e4SLinus Torvalds
270b3d643fSHelge Deller	.level          LEVEL
288e9e9844SHelge Deller
29dfcf753bSKyle McMartin	.text
301da177e4SLinus Torvalds
311da177e4SLinus Torvalds	.import syscall_exit,code
321da177e4SLinus Torvalds	.import syscall_exit_rfi,code
331da177e4SLinus Torvalds
341da177e4SLinus Torvalds	/* Linux gateway page is aliased to virtual page 0 in the kernel
351da177e4SLinus Torvalds	 * address space. Since it is a gateway page it cannot be
361da177e4SLinus Torvalds	 * dereferenced, so null pointers will still fault. We start
371da177e4SLinus Torvalds	 * the actual entry point at 0x100. We put break instructions
381da177e4SLinus Torvalds	 * at the beginning of the page to trap null indirect function
391da177e4SLinus Torvalds	 * pointers.
401da177e4SLinus Torvalds	 */
411da177e4SLinus Torvalds
421c593571SSam Ravnborg	.align PAGE_SIZE
438e9e9844SHelge DellerENTRY(linux_gateway_page)
441da177e4SLinus Torvalds
451da177e4SLinus Torvalds        /* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */
461da177e4SLinus Torvalds	.rept 44
471da177e4SLinus Torvalds	KILL_INSN
481da177e4SLinus Torvalds	.endr
491da177e4SLinus Torvalds
50f4c0346cSJohn David Anglin	/* ADDRESS 0xb0 to 0xb8, lws uses two insns for entry */
511da177e4SLinus Torvalds	/* Light-weight-syscall entry must always be located at 0xb0 */
521da177e4SLinus Torvalds	/* WARNING: Keep this number updated with table size changes */
531da177e4SLinus Torvalds#define __NR_lws_entries (2)
541da177e4SLinus Torvalds
551da177e4SLinus Torvaldslws_entry:
56f4c0346cSJohn David Anglin	gate	lws_start, %r0		/* increase privilege */
57f4c0346cSJohn David Anglin	depi	3, 31, 2, %r31		/* Ensure we return into user mode. */
581da177e4SLinus Torvalds
59f4c0346cSJohn David Anglin	/* Fill from 0xb8 to 0xe0 */
60f4c0346cSJohn David Anglin	.rept 10
611da177e4SLinus Torvalds	KILL_INSN
621da177e4SLinus Torvalds	.endr
631da177e4SLinus Torvalds
641da177e4SLinus Torvalds	/* This function MUST be located at 0xe0 for glibc's threading
651da177e4SLinus Torvalds	mechanism to work. DO NOT MOVE THIS CODE EVER! */
661da177e4SLinus Torvaldsset_thread_pointer:
671da177e4SLinus Torvalds	gate	.+8, %r0		/* increase privilege */
681da177e4SLinus Torvalds	depi	3, 31, 2, %r31		/* Ensure we return into user mode. */
691da177e4SLinus Torvalds	be	0(%sr7,%r31)		/* return to user space */
701da177e4SLinus Torvalds	mtctl	%r26, %cr27		/* move arg0 to the control register */
711da177e4SLinus Torvalds
721da177e4SLinus Torvalds	/* Increase the chance of trapping if random jumps occur to this
731da177e4SLinus Torvalds	address, fill from 0xf0 to 0x100 */
741da177e4SLinus Torvalds	.rept 4
751da177e4SLinus Torvalds	KILL_INSN
761da177e4SLinus Torvalds	.endr
771da177e4SLinus Torvalds
781da177e4SLinus Torvalds/* This address must remain fixed at 0x100 for glibc's syscalls to work */
791da177e4SLinus Torvalds	.align 256
801da177e4SLinus Torvaldslinux_gateway_entry:
811da177e4SLinus Torvalds	gate	.+8, %r0			/* become privileged */
821da177e4SLinus Torvalds	mtsp	%r0,%sr4			/* get kernel space into sr4 */
831da177e4SLinus Torvalds	mtsp	%r0,%sr5			/* get kernel space into sr5 */
841da177e4SLinus Torvalds	mtsp	%r0,%sr6			/* get kernel space into sr6 */
851da177e4SLinus Torvalds	mfsp    %sr7,%r1                        /* save user sr7 */
861da177e4SLinus Torvalds	mtsp    %r1,%sr3                        /* and store it in sr3 */
871da177e4SLinus Torvalds
88413059f2SGrant Grundler#ifdef CONFIG_64BIT
891da177e4SLinus Torvalds	/* for now we can *always* set the W bit on entry to the syscall
901da177e4SLinus Torvalds	 * since we don't support wide userland processes.  We could
911da177e4SLinus Torvalds	 * also save the current SM other than in r0 and restore it on
921da177e4SLinus Torvalds	 * exit from the syscall, and also use that value to know
931da177e4SLinus Torvalds	 * whether to do narrow or wide syscalls. -PB
941da177e4SLinus Torvalds	 */
951da177e4SLinus Torvalds	ssm	PSW_SM_W, %r1
961da177e4SLinus Torvalds	extrd,u	%r1,PSW_W_BIT,1,%r1
971da177e4SLinus Torvalds	/* sp must be aligned on 4, so deposit the W bit setting into
981da177e4SLinus Torvalds	 * the bottom of sp temporarily */
991da177e4SLinus Torvalds	or,ev	%r1,%r30,%r30
1001da177e4SLinus Torvalds	b,n	1f
1011da177e4SLinus Torvalds	/* The top halves of argument registers must be cleared on syscall
1021da177e4SLinus Torvalds	 * entry from narrow executable.
1031da177e4SLinus Torvalds	 */
1041da177e4SLinus Torvalds	depdi	0, 31, 32, %r26
1051da177e4SLinus Torvalds	depdi	0, 31, 32, %r25
1061da177e4SLinus Torvalds	depdi	0, 31, 32, %r24
1071da177e4SLinus Torvalds	depdi	0, 31, 32, %r23
1081da177e4SLinus Torvalds	depdi	0, 31, 32, %r22
1091da177e4SLinus Torvalds	depdi	0, 31, 32, %r21
1101da177e4SLinus Torvalds1:
1111da177e4SLinus Torvalds#endif
1121da177e4SLinus Torvalds	mfctl   %cr30,%r1
1131da177e4SLinus Torvalds	xor     %r1,%r30,%r30                   /* ye olde xor trick */
1141da177e4SLinus Torvalds	xor     %r1,%r30,%r1
1151da177e4SLinus Torvalds	xor     %r1,%r30,%r30
1161da177e4SLinus Torvalds
1171da177e4SLinus Torvalds	ldo     THREAD_SZ_ALGN+FRAME_SIZE(%r30),%r30  /* set up kernel stack */
1181da177e4SLinus Torvalds
1191da177e4SLinus Torvalds	/* N.B.: It is critical that we don't set sr7 to 0 until r30
1201da177e4SLinus Torvalds	 *       contains a valid kernel stack pointer. It is also
1211da177e4SLinus Torvalds	 *       critical that we don't start using the kernel stack
1221da177e4SLinus Torvalds	 *       until after sr7 has been set to 0.
1231da177e4SLinus Torvalds	 */
1241da177e4SLinus Torvalds
1251da177e4SLinus Torvalds	mtsp	%r0,%sr7			/* get kernel space into sr7 */
1261da177e4SLinus Torvalds	STREGM	%r1,FRAME_SIZE(%r30)		/* save r1 (usp) here for now */
1271da177e4SLinus Torvalds	mfctl	%cr30,%r1			/* get task ptr in %r1 */
1281da177e4SLinus Torvalds	LDREG	TI_TASK(%r1),%r1
1291da177e4SLinus Torvalds
1301da177e4SLinus Torvalds	/* Save some registers for sigcontext and potential task
1311da177e4SLinus Torvalds	   switch (see entry.S for the details of which ones are
1321da177e4SLinus Torvalds	   saved/restored).  TASK_PT_PSW is zeroed so we can see whether
1331da177e4SLinus Torvalds	   a process is on a syscall or not.  For an interrupt the real
1341da177e4SLinus Torvalds	   PSW value is stored.  This is needed for gdb and sys_ptrace. */
1351da177e4SLinus Torvalds	STREG	%r0,  TASK_PT_PSW(%r1)
1361da177e4SLinus Torvalds	STREG	%r2,  TASK_PT_GR2(%r1)		/* preserve rp */
1371da177e4SLinus Torvalds	STREG	%r19, TASK_PT_GR19(%r1)
1381da177e4SLinus Torvalds
1391da177e4SLinus Torvalds	LDREGM	-FRAME_SIZE(%r30), %r2		/* get users sp back */
140413059f2SGrant Grundler#ifdef CONFIG_64BIT
1411da177e4SLinus Torvalds	extrd,u	%r2,63,1,%r19			/* W hidden in bottom bit */
1421da177e4SLinus Torvalds#if 0
1431da177e4SLinus Torvalds	xor	%r19,%r2,%r2			/* clear bottom bit */
1441da177e4SLinus Torvalds	depd,z	%r19,1,1,%r19
1451da177e4SLinus Torvalds	std	%r19,TASK_PT_PSW(%r1)
1461da177e4SLinus Torvalds#endif
1471da177e4SLinus Torvalds#endif
1481da177e4SLinus Torvalds	STREG	%r2,  TASK_PT_GR30(%r1)		/* ... and save it */
1491da177e4SLinus Torvalds
150aa0eecb0SCarlos O'Donell	STREG	%r20, TASK_PT_GR20(%r1)		/* Syscall number */
1511da177e4SLinus Torvalds	STREG	%r21, TASK_PT_GR21(%r1)
1521da177e4SLinus Torvalds	STREG	%r22, TASK_PT_GR22(%r1)
1531da177e4SLinus Torvalds	STREG	%r23, TASK_PT_GR23(%r1)		/* 4th argument */
1541da177e4SLinus Torvalds	STREG	%r24, TASK_PT_GR24(%r1)		/* 3rd argument */
1551da177e4SLinus Torvalds	STREG	%r25, TASK_PT_GR25(%r1)		/* 2nd argument */
1561da177e4SLinus Torvalds	STREG	%r26, TASK_PT_GR26(%r1)	 	/* 1st argument */
1571da177e4SLinus Torvalds	STREG	%r27, TASK_PT_GR27(%r1)		/* user dp */
1581da177e4SLinus Torvalds	STREG   %r28, TASK_PT_GR28(%r1)         /* return value 0 */
15900df111eSAl Viro	STREG   %r0, TASK_PT_ORIG_R28(%r1)      /* don't prohibit restarts */
1601da177e4SLinus Torvalds	STREG	%r29, TASK_PT_GR29(%r1)		/* return value 1 */
1611da177e4SLinus Torvalds	STREG	%r31, TASK_PT_GR31(%r1)		/* preserve syscall return ptr */
1621da177e4SLinus Torvalds
1631da177e4SLinus Torvalds	ldo	TASK_PT_FR0(%r1), %r27		/* save fpregs from the kernel */
1641da177e4SLinus Torvalds	save_fp	%r27				/* or potential task switch  */
1651da177e4SLinus Torvalds
1661da177e4SLinus Torvalds	mfctl	%cr11, %r27			/* i.e. SAR */
1671da177e4SLinus Torvalds	STREG	%r27, TASK_PT_SAR(%r1)
1681da177e4SLinus Torvalds
1691da177e4SLinus Torvalds	loadgp
1701da177e4SLinus Torvalds
171413059f2SGrant Grundler#ifdef CONFIG_64BIT
1721da177e4SLinus Torvalds	ldo	-16(%r30),%r29			/* Reference param save area */
1731da177e4SLinus Torvalds	copy	%r19,%r2			/* W bit back to r2 */
1741da177e4SLinus Torvalds#else
1751da177e4SLinus Torvalds	/* no need to save these on stack in wide mode because the first 8
1761da177e4SLinus Torvalds	 * args are passed in registers */
1771da177e4SLinus Torvalds	stw     %r22, -52(%r30)                 /* 5th argument */
1781da177e4SLinus Torvalds	stw     %r21, -56(%r30)                 /* 6th argument */
1791da177e4SLinus Torvalds#endif
1801da177e4SLinus Torvalds
1811da177e4SLinus Torvalds	/* Are we being ptraced? */
1821da177e4SLinus Torvalds	mfctl	%cr30, %r1
1831da177e4SLinus Torvalds	LDREG	TI_TASK(%r1),%r1
184376e210bSKyle McMartin	ldw	TASK_PTRACE(%r1), %r1
1851da177e4SLinus Torvalds	bb,<,n	%r1,31,.Ltracesys
1861da177e4SLinus Torvalds
1871da177e4SLinus Torvalds	/* Note!  We cannot use the syscall table that is mapped
1881da177e4SLinus Torvalds	nearby since the gateway page is mapped execute-only. */
1891da177e4SLinus Torvalds
190413059f2SGrant Grundler#ifdef CONFIG_64BIT
1911da177e4SLinus Torvalds	ldil	L%sys_call_table, %r1
1921da177e4SLinus Torvalds	or,=	%r2,%r2,%r2
1931da177e4SLinus Torvalds	addil	L%(sys_call_table64-sys_call_table), %r1
1941da177e4SLinus Torvalds	ldo	R%sys_call_table(%r1), %r19
1951da177e4SLinus Torvalds	or,=	%r2,%r2,%r2
1961da177e4SLinus Torvalds	ldo	R%sys_call_table64(%r1), %r19
1971da177e4SLinus Torvalds#else
1981da177e4SLinus Torvalds	ldil	L%sys_call_table, %r1
1991da177e4SLinus Torvalds	ldo     R%sys_call_table(%r1), %r19
2001da177e4SLinus Torvalds#endif
2013bb457afSKyle McMartin	comiclr,>>	__NR_Linux_syscalls, %r20, %r0
2021da177e4SLinus Torvalds	b,n	.Lsyscall_nosys
2031da177e4SLinus Torvalds
2041da177e4SLinus Torvalds	LDREGX  %r20(%r19), %r19
2051da177e4SLinus Torvalds
2061da177e4SLinus Torvalds	/* If this is a sys_rt_sigreturn call, and the signal was received
2071da177e4SLinus Torvalds	 * when not in_syscall, then we want to return via syscall_exit_rfi,
2081da177e4SLinus Torvalds	 * not syscall_exit.  Signal no. in r20, in_syscall in r25 (see
2091da177e4SLinus Torvalds	 * trampoline code in signal.c).
2101da177e4SLinus Torvalds	 */
2111da177e4SLinus Torvalds	ldi	__NR_rt_sigreturn,%r2
2121da177e4SLinus Torvalds	comb,=	%r2,%r20,.Lrt_sigreturn
2131da177e4SLinus Torvalds.Lin_syscall:
2141da177e4SLinus Torvalds	ldil	L%syscall_exit,%r2
2151da177e4SLinus Torvalds	be      0(%sr7,%r19)
2161da177e4SLinus Torvalds	ldo	R%syscall_exit(%r2),%r2
2171da177e4SLinus Torvalds.Lrt_sigreturn:
2181da177e4SLinus Torvalds	comib,<> 0,%r25,.Lin_syscall
2191da177e4SLinus Torvalds	ldil	L%syscall_exit_rfi,%r2
2201da177e4SLinus Torvalds	be      0(%sr7,%r19)
2211da177e4SLinus Torvalds	ldo	R%syscall_exit_rfi(%r2),%r2
2221da177e4SLinus Torvalds
2231da177e4SLinus Torvalds	/* Note!  Because we are not running where we were linked, any
2241da177e4SLinus Torvalds	calls to functions external to this file must be indirect.  To
2251da177e4SLinus Torvalds	be safe, we apply the opposite rule to functions within this
2261da177e4SLinus Torvalds	file, with local labels given to them to ensure correctness. */
2271da177e4SLinus Torvalds
2281da177e4SLinus Torvalds.Lsyscall_nosys:
2291da177e4SLinus Torvaldssyscall_nosys:
2301da177e4SLinus Torvalds	ldil	L%syscall_exit,%r1
2311da177e4SLinus Torvalds	be	R%syscall_exit(%sr7,%r1)
2321da177e4SLinus Torvalds	ldo	-ENOSYS(%r0),%r28		   /* set errno */
2331da177e4SLinus Torvalds
2341da177e4SLinus Torvalds
2351da177e4SLinus Torvalds/* Warning! This trace code is a virtual duplicate of the code above so be
2361da177e4SLinus Torvalds * sure to maintain both! */
2371da177e4SLinus Torvalds.Ltracesys:
2381da177e4SLinus Torvaldstracesys:
2391da177e4SLinus Torvalds	/* Need to save more registers so the debugger can see where we
2401da177e4SLinus Torvalds	 * are.  This saves only the lower 8 bits of PSW, so that the C
2411da177e4SLinus Torvalds	 * bit is still clear on syscalls, and the D bit is set if this
2421da177e4SLinus Torvalds	 * full register save path has been executed.  We check the D
2431da177e4SLinus Torvalds	 * bit on syscall_return_rfi to determine which registers to
2441da177e4SLinus Torvalds	 * restore.  An interrupt results in a full PSW saved with the
2451da177e4SLinus Torvalds	 * C bit set, a non-straced syscall entry results in C and D clear
2461da177e4SLinus Torvalds	 * in the saved PSW.
2471da177e4SLinus Torvalds	 */
2481da177e4SLinus Torvalds	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
2491da177e4SLinus Torvalds	LDREG	TI_TASK(%r1), %r1
2501da177e4SLinus Torvalds	ssm	0,%r2
2511da177e4SLinus Torvalds	STREG	%r2,TASK_PT_PSW(%r1)		/* Lower 8 bits only!! */
2521da177e4SLinus Torvalds	mfsp	%sr0,%r2
2531da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR0(%r1)
2541da177e4SLinus Torvalds	mfsp	%sr1,%r2
2551da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR1(%r1)
2561da177e4SLinus Torvalds	mfsp	%sr2,%r2
2571da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR2(%r1)
2581da177e4SLinus Torvalds	mfsp	%sr3,%r2
2591da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR3(%r1)
2601da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR4(%r1)
2611da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR5(%r1)
2621da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR6(%r1)
2631da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR7(%r1)
2641da177e4SLinus Torvalds	STREG	%r2,TASK_PT_IASQ0(%r1)
2651da177e4SLinus Torvalds	STREG	%r2,TASK_PT_IASQ1(%r1)
2661da177e4SLinus Torvalds	LDREG	TASK_PT_GR31(%r1),%r2
2671da177e4SLinus Torvalds	STREG	%r2,TASK_PT_IAOQ0(%r1)
2681da177e4SLinus Torvalds	ldo	4(%r2),%r2
2691da177e4SLinus Torvalds	STREG	%r2,TASK_PT_IAOQ1(%r1)
2701da177e4SLinus Torvalds	ldo	TASK_REGS(%r1),%r2
2711da177e4SLinus Torvalds	/* reg_save %r2 */
2721da177e4SLinus Torvalds	STREG	%r3,PT_GR3(%r2)
2731da177e4SLinus Torvalds	STREG	%r4,PT_GR4(%r2)
2741da177e4SLinus Torvalds	STREG	%r5,PT_GR5(%r2)
2751da177e4SLinus Torvalds	STREG	%r6,PT_GR6(%r2)
2761da177e4SLinus Torvalds	STREG	%r7,PT_GR7(%r2)
2771da177e4SLinus Torvalds	STREG	%r8,PT_GR8(%r2)
2781da177e4SLinus Torvalds	STREG	%r9,PT_GR9(%r2)
2791da177e4SLinus Torvalds	STREG	%r10,PT_GR10(%r2)
2801da177e4SLinus Torvalds	STREG	%r11,PT_GR11(%r2)
2811da177e4SLinus Torvalds	STREG	%r12,PT_GR12(%r2)
2821da177e4SLinus Torvalds	STREG	%r13,PT_GR13(%r2)
2831da177e4SLinus Torvalds	STREG	%r14,PT_GR14(%r2)
2841da177e4SLinus Torvalds	STREG	%r15,PT_GR15(%r2)
2851da177e4SLinus Torvalds	STREG	%r16,PT_GR16(%r2)
2861da177e4SLinus Torvalds	STREG	%r17,PT_GR17(%r2)
2871da177e4SLinus Torvalds	STREG	%r18,PT_GR18(%r2)
2881da177e4SLinus Torvalds	/* Finished saving things for the debugger */
2891da177e4SLinus Torvalds
2902798af1aSKyle McMartin	copy	%r2,%r26
2912798af1aSKyle McMartin	ldil	L%do_syscall_trace_enter,%r1
2921da177e4SLinus Torvalds	ldil	L%tracesys_next,%r2
2932798af1aSKyle McMartin	be	R%do_syscall_trace_enter(%sr7,%r1)
2941da177e4SLinus Torvalds	ldo	R%tracesys_next(%r2),%r2
2951da177e4SLinus Torvalds
2961da177e4SLinus Torvaldstracesys_next:
2972798af1aSKyle McMartin	/* do_syscall_trace_enter either returned the syscallno, or -1L,
2982798af1aSKyle McMartin	 *  so we skip restoring the PT_GR20 below, since we pulled it from
2992798af1aSKyle McMartin	 *  task->thread.regs.gr[20] above.
3002798af1aSKyle McMartin	 */
3012798af1aSKyle McMartin	copy	%ret0,%r20
3021da177e4SLinus Torvalds	ldil	L%sys_call_table,%r1
3031da177e4SLinus Torvalds	ldo     R%sys_call_table(%r1), %r19
3041da177e4SLinus Torvalds
3051da177e4SLinus Torvalds	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
3061da177e4SLinus Torvalds	LDREG	TI_TASK(%r1), %r1
3071da177e4SLinus Torvalds	LDREG   TASK_PT_GR26(%r1), %r26		/* Restore the users args */
3081da177e4SLinus Torvalds	LDREG   TASK_PT_GR25(%r1), %r25
3091da177e4SLinus Torvalds	LDREG   TASK_PT_GR24(%r1), %r24
3101da177e4SLinus Torvalds	LDREG   TASK_PT_GR23(%r1), %r23
311413059f2SGrant Grundler#ifdef CONFIG_64BIT
3121da177e4SLinus Torvalds	LDREG   TASK_PT_GR22(%r1), %r22
3131da177e4SLinus Torvalds	LDREG   TASK_PT_GR21(%r1), %r21
3141da177e4SLinus Torvalds	ldo	-16(%r30),%r29			/* Reference param save area */
3151da177e4SLinus Torvalds#endif
3161da177e4SLinus Torvalds
3171da177e4SLinus Torvalds	comiclr,>>=	__NR_Linux_syscalls, %r20, %r0
3181da177e4SLinus Torvalds	b,n	.Lsyscall_nosys
3191da177e4SLinus Torvalds
3201da177e4SLinus Torvalds	LDREGX  %r20(%r19), %r19
3211da177e4SLinus Torvalds
3221da177e4SLinus Torvalds	/* If this is a sys_rt_sigreturn call, and the signal was received
3231da177e4SLinus Torvalds	 * when not in_syscall, then we want to return via syscall_exit_rfi,
3241da177e4SLinus Torvalds	 * not syscall_exit.  Signal no. in r20, in_syscall in r25 (see
3251da177e4SLinus Torvalds	 * trampoline code in signal.c).
3261da177e4SLinus Torvalds	 */
3271da177e4SLinus Torvalds	ldi	__NR_rt_sigreturn,%r2
3281da177e4SLinus Torvalds	comb,=	%r2,%r20,.Ltrace_rt_sigreturn
3291da177e4SLinus Torvalds.Ltrace_in_syscall:
3301da177e4SLinus Torvalds	ldil	L%tracesys_exit,%r2
3311da177e4SLinus Torvalds	be      0(%sr7,%r19)
3321da177e4SLinus Torvalds	ldo	R%tracesys_exit(%r2),%r2
3331da177e4SLinus Torvalds
3341da177e4SLinus Torvalds	/* Do *not* call this function on the gateway page, because it
3351da177e4SLinus Torvalds	makes a direct call to syscall_trace. */
3361da177e4SLinus Torvalds
3371da177e4SLinus Torvaldstracesys_exit:
3381da177e4SLinus Torvalds	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
3391da177e4SLinus Torvalds	LDREG	TI_TASK(%r1), %r1
340413059f2SGrant Grundler#ifdef CONFIG_64BIT
3411da177e4SLinus Torvalds	ldo	-16(%r30),%r29			/* Reference param save area */
3421da177e4SLinus Torvalds#endif
3432798af1aSKyle McMartin	ldo	TASK_REGS(%r1),%r26
3442798af1aSKyle McMartin	bl	do_syscall_trace_exit,%r2
3451da177e4SLinus Torvalds	STREG   %r28,TASK_PT_GR28(%r1)          /* save return value now */
3461da177e4SLinus Torvalds	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
3471da177e4SLinus Torvalds	LDREG	TI_TASK(%r1), %r1
3481da177e4SLinus Torvalds	LDREG   TASK_PT_GR28(%r1), %r28		/* Restore return val. */
3491da177e4SLinus Torvalds
3501da177e4SLinus Torvalds	ldil	L%syscall_exit,%r1
3511da177e4SLinus Torvalds	be,n	R%syscall_exit(%sr7,%r1)
3521da177e4SLinus Torvalds
3531da177e4SLinus Torvalds.Ltrace_rt_sigreturn:
3541da177e4SLinus Torvalds	comib,<> 0,%r25,.Ltrace_in_syscall
3551da177e4SLinus Torvalds	ldil	L%tracesys_sigexit,%r2
3561da177e4SLinus Torvalds	be      0(%sr7,%r19)
3571da177e4SLinus Torvalds	ldo	R%tracesys_sigexit(%r2),%r2
3581da177e4SLinus Torvalds
3591da177e4SLinus Torvaldstracesys_sigexit:
3601da177e4SLinus Torvalds	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
3615837d42fSKyle McMartin	LDREG	TI_TASK(%r1), %r1
362413059f2SGrant Grundler#ifdef CONFIG_64BIT
3631da177e4SLinus Torvalds	ldo	-16(%r30),%r29			/* Reference param save area */
3641da177e4SLinus Torvalds#endif
3652798af1aSKyle McMartin	bl	do_syscall_trace_exit,%r2
3662798af1aSKyle McMartin	ldo	TASK_REGS(%r1),%r26
3671da177e4SLinus Torvalds
3681da177e4SLinus Torvalds	ldil	L%syscall_exit_rfi,%r1
3691da177e4SLinus Torvalds	be,n	R%syscall_exit_rfi(%sr7,%r1)
3701da177e4SLinus Torvalds
3711da177e4SLinus Torvalds
3721da177e4SLinus Torvalds	/*********************************************************
373c84c3a69SHelge Deller		32/64-bit Light-Weight-Syscall ABI
3741da177e4SLinus Torvalds
375c84c3a69SHelge Deller		* - Indicates a hint for userspace inline asm
376c84c3a69SHelge Deller		implementations.
3771da177e4SLinus Torvalds
378c84c3a69SHelge Deller		Syscall number (caller-saves)
379c84c3a69SHelge Deller	        - %r20
380c84c3a69SHelge Deller	        * In asm clobber.
3811da177e4SLinus Torvalds
382c84c3a69SHelge Deller		Argument registers (caller-saves)
383c84c3a69SHelge Deller	        - %r26, %r25, %r24, %r23, %r22
384c84c3a69SHelge Deller	        * In asm input.
385c84c3a69SHelge Deller
386c84c3a69SHelge Deller		Return registers (caller-saves)
387c84c3a69SHelge Deller	        - %r28 (return), %r21 (errno)
388c84c3a69SHelge Deller	        * In asm output.
389c84c3a69SHelge Deller
390c84c3a69SHelge Deller		Caller-saves registers
391c84c3a69SHelge Deller	        - %r1, %r27, %r29
392c84c3a69SHelge Deller	        - %r2 (return pointer)
393c84c3a69SHelge Deller	        - %r31 (ble link register)
394c84c3a69SHelge Deller	        * In asm clobber.
395c84c3a69SHelge Deller
396c84c3a69SHelge Deller		Callee-saves registers
397c84c3a69SHelge Deller	        - %r3-%r18
398c84c3a69SHelge Deller	        - %r30 (stack pointer)
399c84c3a69SHelge Deller	        * Not in asm clobber.
400c84c3a69SHelge Deller
401c84c3a69SHelge Deller		If userspace is 32-bit:
402c84c3a69SHelge Deller		Callee-saves registers
403c84c3a69SHelge Deller	        - %r19 (32-bit PIC register)
404c84c3a69SHelge Deller
405c84c3a69SHelge Deller		Differences from 32-bit calling convention:
406c84c3a69SHelge Deller		- Syscall number in %r20
407c84c3a69SHelge Deller		- Additional argument register %r22 (arg4)
408c84c3a69SHelge Deller		- Callee-saves %r19.
409c84c3a69SHelge Deller
410c84c3a69SHelge Deller		If userspace is 64-bit:
411c84c3a69SHelge Deller		Callee-saves registers
412c84c3a69SHelge Deller		- %r27 (64-bit PIC register)
413c84c3a69SHelge Deller
414c84c3a69SHelge Deller		Differences from 64-bit calling convention:
415c84c3a69SHelge Deller		- Syscall number in %r20
416c84c3a69SHelge Deller		- Additional argument register %r22 (arg4)
417c84c3a69SHelge Deller		- Callee-saves %r27.
4181da177e4SLinus Torvalds
4191da177e4SLinus Torvalds		Error codes returned by entry path:
4201da177e4SLinus Torvalds
4211da177e4SLinus Torvalds		ENOSYS - r20 was an invalid LWS number.
4221da177e4SLinus Torvalds
4231da177e4SLinus Torvalds	*********************************************************/
4241da177e4SLinus Torvaldslws_start:
4251da177e4SLinus Torvalds
426413059f2SGrant Grundler#ifdef CONFIG_64BIT
4271da177e4SLinus Torvalds	/* FIXME: If we are a 64-bit kernel just
4281da177e4SLinus Torvalds	 *        turn this on unconditionally.
4291da177e4SLinus Torvalds	 */
4301da177e4SLinus Torvalds	ssm	PSW_SM_W, %r1
4311da177e4SLinus Torvalds	extrd,u	%r1,PSW_W_BIT,1,%r1
4321da177e4SLinus Torvalds	/* sp must be aligned on 4, so deposit the W bit setting into
4331da177e4SLinus Torvalds	 * the bottom of sp temporarily */
4341da177e4SLinus Torvalds	or,ev	%r1,%r30,%r30
4351da177e4SLinus Torvalds
4361da177e4SLinus Torvalds	/* Clip LWS number to a 32-bit value always */
4371da177e4SLinus Torvalds	depdi	0, 31, 32, %r20
4381da177e4SLinus Torvalds#endif
4391da177e4SLinus Torvalds
4401da177e4SLinus Torvalds        /* Is the lws entry number valid? */
441f4c0346cSJohn David Anglin	comiclr,>>	__NR_lws_entries, %r20, %r0
4421da177e4SLinus Torvalds	b,n	lws_exit_nosys
4431da177e4SLinus Torvalds
4441da177e4SLinus Torvalds	/* WARNING: Trashing sr2 and sr3 */
4451da177e4SLinus Torvalds	mfsp	%sr7,%r1			/* get userspace into sr3 */
4461da177e4SLinus Torvalds	mtsp	%r1,%sr3
4471da177e4SLinus Torvalds	mtsp	%r0,%sr2			/* get kernel space into sr2 */
4481da177e4SLinus Torvalds
4491da177e4SLinus Torvalds	/* Load table start */
4501da177e4SLinus Torvalds	ldil	L%lws_table, %r1
4511da177e4SLinus Torvalds	ldo	R%lws_table(%r1), %r28	/* Scratch use of r28 */
4521da177e4SLinus Torvalds	LDREGX	%r20(%sr2,r28), %r21	/* Scratch use of r21 */
4531da177e4SLinus Torvalds
4541da177e4SLinus Torvalds	/* Jump to lws, lws table pointers already relocated */
4551da177e4SLinus Torvalds	be,n	0(%sr2,%r21)
4561da177e4SLinus Torvalds
4571da177e4SLinus Torvaldslws_exit_nosys:
4581da177e4SLinus Torvalds	ldo	-ENOSYS(%r0),%r21		   /* set errno */
4591da177e4SLinus Torvalds	/* Fall through: Return to userspace */
4601da177e4SLinus Torvalds
4611da177e4SLinus Torvaldslws_exit:
462413059f2SGrant Grundler#ifdef CONFIG_64BIT
4631da177e4SLinus Torvalds	/* decide whether to reset the wide mode bit
4641da177e4SLinus Torvalds	 *
4651da177e4SLinus Torvalds	 * For a syscall, the W bit is stored in the lowest bit
4661da177e4SLinus Torvalds	 * of sp.  Extract it and reset W if it is zero */
4671da177e4SLinus Torvalds	extrd,u,*<>	%r30,63,1,%r1
4681da177e4SLinus Torvalds	rsm	PSW_SM_W, %r0
4691da177e4SLinus Torvalds	/* now reset the lowest bit of sp if it was set */
4701da177e4SLinus Torvalds	xor	%r30,%r1,%r30
4711da177e4SLinus Torvalds#endif
472f4c0346cSJohn David Anglin	be,n	0(%sr7, %r31)
4731da177e4SLinus Torvalds
4741da177e4SLinus Torvalds
4751da177e4SLinus Torvalds
4761da177e4SLinus Torvalds	/***************************************************
4771da177e4SLinus Torvalds		Implementing CAS as an atomic operation:
4781da177e4SLinus Torvalds
4791da177e4SLinus Torvalds		%r26 - Address to examine
4801da177e4SLinus Torvalds		%r25 - Old value to check (old)
4811da177e4SLinus Torvalds		%r24 - New value to set (new)
4821da177e4SLinus Torvalds		%r28 - Return prev through this register.
4831da177e4SLinus Torvalds		%r21 - Kernel error code
4841da177e4SLinus Torvalds
4851da177e4SLinus Torvalds		If debugging is DISabled:
4861da177e4SLinus Torvalds
4871da177e4SLinus Torvalds		%r21 has the following meanings:
4881da177e4SLinus Torvalds
4891da177e4SLinus Torvalds		EAGAIN - CAS is busy, ldcw failed, try again.
4901da177e4SLinus Torvalds		EFAULT - Read or write failed.
4911da177e4SLinus Torvalds
4921da177e4SLinus Torvalds		If debugging is enabled:
4931da177e4SLinus Torvalds
4941da177e4SLinus Torvalds		EDEADLOCK - CAS called recursively.
4951da177e4SLinus Torvalds		EAGAIN && r28 == 1 - CAS is busy. Lock contended.
4961da177e4SLinus Torvalds		EAGAIN && r28 == 2 - CAS is busy. ldcw failed.
4971da177e4SLinus Torvalds		EFAULT - Read or write failed.
4981da177e4SLinus Torvalds
4991da177e4SLinus Torvalds		Scratch: r20, r28, r1
5001da177e4SLinus Torvalds
5011da177e4SLinus Torvalds	****************************************************/
5021da177e4SLinus Torvalds
5031da177e4SLinus Torvalds	/* Do not enable LWS debugging */
5041da177e4SLinus Torvalds#define ENABLE_LWS_DEBUG 0
5051da177e4SLinus Torvalds
5061da177e4SLinus Torvalds	/* ELF64 Process entry path */
5071da177e4SLinus Torvaldslws_compare_and_swap64:
508413059f2SGrant Grundler#ifdef CONFIG_64BIT
5091da177e4SLinus Torvalds	b,n	lws_compare_and_swap
5101da177e4SLinus Torvalds#else
5111da177e4SLinus Torvalds	/* If we are not a 64-bit kernel, then we don't
512c84c3a69SHelge Deller	 * have 64-bit input registers, and calling
513c84c3a69SHelge Deller	 * the 64-bit LWS CAS returns ENOSYS.
5141da177e4SLinus Torvalds	 */
5151da177e4SLinus Torvalds	b,n	lws_exit_nosys
5161da177e4SLinus Torvalds#endif
5171da177e4SLinus Torvalds
5181da177e4SLinus Torvalds	/* ELF32 Process entry path */
5191da177e4SLinus Torvaldslws_compare_and_swap32:
520413059f2SGrant Grundler#ifdef CONFIG_64BIT
5211da177e4SLinus Torvalds	/* Clip all the input registers */
5221da177e4SLinus Torvalds	depdi	0, 31, 32, %r26
5231da177e4SLinus Torvalds	depdi	0, 31, 32, %r25
5241da177e4SLinus Torvalds	depdi	0, 31, 32, %r24
5251da177e4SLinus Torvalds#endif
5261da177e4SLinus Torvalds
5271da177e4SLinus Torvaldslws_compare_and_swap:
5281da177e4SLinus Torvalds	/* Load start of lock table */
5291da177e4SLinus Torvalds	ldil	L%lws_lock_start, %r20
5301da177e4SLinus Torvalds	ldo	R%lws_lock_start(%r20), %r28
5311da177e4SLinus Torvalds
5321da177e4SLinus Torvalds	/* Extract four bits from r26 and hash lock (Bits 4-7) */
5331da177e4SLinus Torvalds	extru  %r26, 27, 4, %r20
5341da177e4SLinus Torvalds
5351da177e4SLinus Torvalds	/* Find lock to use, the hash is either one of 0 to
5361da177e4SLinus Torvalds	   15, multiplied by 16 (keep it 16-byte aligned)
5371da177e4SLinus Torvalds	   and add to the lock table offset. */
5381da177e4SLinus Torvalds	shlw	%r20, 4, %r20
5391da177e4SLinus Torvalds	add	%r20, %r28, %r20
5401da177e4SLinus Torvalds
541b5e8b733SAurelien Jarno# if ENABLE_LWS_DEBUG
5421da177e4SLinus Torvalds	/*
5431da177e4SLinus Torvalds		DEBUG, check for deadlock!
5441da177e4SLinus Torvalds		If the thread register values are the same
5451da177e4SLinus Torvalds		then we were the one that locked it last and
5461da177e4SLinus Torvalds		this is a recurisve call that will deadlock.
5471da177e4SLinus Torvalds		We *must* giveup this call and fail.
5481da177e4SLinus Torvalds	*/
5491da177e4SLinus Torvalds	ldw	4(%sr2,%r20), %r28			/* Load thread register */
550aa0eecb0SCarlos O'Donell	/* WARNING: If cr27 cycles to the same value we have problems */
5511da177e4SLinus Torvalds	mfctl	%cr27, %r21				/* Get current thread register */
5521da177e4SLinus Torvalds	cmpb,<>,n	%r21, %r28, cas_lock		/* Called recursive? */
5531da177e4SLinus Torvalds	b	lws_exit				/* Return error! */
5541da177e4SLinus Torvalds	ldo	-EDEADLOCK(%r0), %r21
5551da177e4SLinus Torvaldscas_lock:
5561da177e4SLinus Torvalds	cmpb,=,n	%r0, %r28, cas_nocontend	/* Is nobody using it? */
5571da177e4SLinus Torvalds	ldo	1(%r0), %r28				/* 1st case */
5581da177e4SLinus Torvalds	b	lws_exit				/* Contended... */
5591da177e4SLinus Torvalds	ldo	-EAGAIN(%r0), %r21			/* Spin in userspace */
5601da177e4SLinus Torvaldscas_nocontend:
5611da177e4SLinus Torvalds# endif
5621da177e4SLinus Torvalds/* ENABLE_LWS_DEBUG */
5631da177e4SLinus Torvalds
56464f49532SKyle McMartin	LDCW	0(%sr2,%r20), %r28			/* Try to acquire the lock */
5651da177e4SLinus Torvalds	cmpb,<>,n	%r0, %r28, cas_action		/* Did we get it? */
5661da177e4SLinus Torvaldscas_wouldblock:
5671da177e4SLinus Torvalds	ldo	2(%r0), %r28				/* 2nd case */
5681da177e4SLinus Torvalds	b	lws_exit				/* Contended... */
5691da177e4SLinus Torvalds	ldo	-EAGAIN(%r0), %r21			/* Spin in userspace */
5701da177e4SLinus Torvalds
5711da177e4SLinus Torvalds	/*
5721da177e4SLinus Torvalds		prev = *addr;
5731da177e4SLinus Torvalds		if ( prev == old )
5741da177e4SLinus Torvalds		  *addr = new;
5751da177e4SLinus Torvalds		return prev;
5761da177e4SLinus Torvalds	*/
5771da177e4SLinus Torvalds
5781da177e4SLinus Torvalds	/* NOTES:
5791da177e4SLinus Torvalds		This all works becuse intr_do_signal
5801da177e4SLinus Torvalds		and schedule both check the return iasq
5811da177e4SLinus Torvalds		and see that we are on the kernel page
5821da177e4SLinus Torvalds		so this process is never scheduled off
5831da177e4SLinus Torvalds		or is ever sent any signal of any sort,
5841da177e4SLinus Torvalds		thus it is wholly atomic from usrspaces
5851da177e4SLinus Torvalds		perspective
5861da177e4SLinus Torvalds	*/
5871da177e4SLinus Torvaldscas_action:
588b5e8b733SAurelien Jarno#if defined CONFIG_SMP && ENABLE_LWS_DEBUG
5891da177e4SLinus Torvalds	/* DEBUG */
5901da177e4SLinus Torvalds	mfctl	%cr27, %r1
5911da177e4SLinus Torvalds	stw	%r1, 4(%sr2,%r20)
5921da177e4SLinus Torvalds#endif
5931da177e4SLinus Torvalds	/* The load and store could fail */
5941da177e4SLinus Torvalds1:	ldw	0(%sr3,%r26), %r28
5951da177e4SLinus Torvalds	sub,<>	%r28, %r25, %r0
5961da177e4SLinus Torvalds2:	stw	%r24, 0(%sr3,%r26)
5971da177e4SLinus Torvalds	/* Free lock */
5981da177e4SLinus Torvalds	stw	%r20, 0(%sr2,%r20)
599b5e8b733SAurelien Jarno#if ENABLE_LWS_DEBUG
6001da177e4SLinus Torvalds	/* Clear thread register indicator */
6011da177e4SLinus Torvalds	stw	%r0, 4(%sr2,%r20)
6021da177e4SLinus Torvalds#endif
6031da177e4SLinus Torvalds	/* Return to userspace, set no error */
6041da177e4SLinus Torvalds	b	lws_exit
6051da177e4SLinus Torvalds	copy	%r0, %r21
6061da177e4SLinus Torvalds
6071da177e4SLinus Torvalds3:
60825985edcSLucas De Marchi	/* Error occurred on load or store */
6091da177e4SLinus Torvalds	/* Free lock */
6101da177e4SLinus Torvalds	stw	%r20, 0(%sr2,%r20)
611b5e8b733SAurelien Jarno#if ENABLE_LWS_DEBUG
6121da177e4SLinus Torvalds	stw	%r0, 4(%sr2,%r20)
6131da177e4SLinus Torvalds#endif
6141da177e4SLinus Torvalds	b	lws_exit
6151da177e4SLinus Torvalds	ldo	-EFAULT(%r0),%r21	/* set errno */
6161da177e4SLinus Torvalds	nop
6171da177e4SLinus Torvalds	nop
6181da177e4SLinus Torvalds	nop
6191da177e4SLinus Torvalds	nop
6201da177e4SLinus Torvalds
6211da177e4SLinus Torvalds	/* Two exception table entries, one for the load,
6221da177e4SLinus Torvalds	   the other for the store. Either return -EFAULT.
6231da177e4SLinus Torvalds	   Each of the entries must be relocated. */
6241da177e4SLinus Torvalds	.section __ex_table,"aw"
6250b3d643fSHelge Deller	ASM_ULONG_INSN (1b - linux_gateway_page), (3b - linux_gateway_page)
6260b3d643fSHelge Deller	ASM_ULONG_INSN (2b - linux_gateway_page), (3b - linux_gateway_page)
6271da177e4SLinus Torvalds	.previous
6281da177e4SLinus Torvalds
6291da177e4SLinus Torvalds
6301da177e4SLinus Torvalds	/* Make sure nothing else is placed on this page */
6311c593571SSam Ravnborg	.align PAGE_SIZE
6328e9e9844SHelge DellerEND(linux_gateway_page)
6338e9e9844SHelge DellerENTRY(end_linux_gateway_page)
6341da177e4SLinus Torvalds
6351da177e4SLinus Torvalds	/* Relocate symbols assuming linux_gateway_page is mapped
6361da177e4SLinus Torvalds	   to virtual address 0x0 */
6378e9e9844SHelge Deller
6380b3d643fSHelge Deller#define LWS_ENTRY(_name_) ASM_ULONG_INSN (lws_##_name_ - linux_gateway_page)
6391da177e4SLinus Torvalds
6401bcdd854SHelge Deller	.section .rodata,"a"
6411bcdd854SHelge Deller
6421c593571SSam Ravnborg	.align PAGE_SIZE
6431da177e4SLinus Torvalds	/* Light-weight-syscall table */
6441da177e4SLinus Torvalds	/* Start of lws table. */
6458e9e9844SHelge DellerENTRY(lws_table)
6461da177e4SLinus Torvalds	LWS_ENTRY(compare_and_swap32)	/* 0 - ELF32 Atomic compare and swap */
6471da177e4SLinus Torvalds	LWS_ENTRY(compare_and_swap64)	/* 1 - ELF64 Atomic compare and swap */
6488e9e9844SHelge DellerEND(lws_table)
6491da177e4SLinus Torvalds	/* End of lws table */
6501da177e4SLinus Torvalds
6511c593571SSam Ravnborg	.align PAGE_SIZE
6528e9e9844SHelge DellerENTRY(sys_call_table)
6531da177e4SLinus Torvalds#include "syscall_table.S"
6548e9e9844SHelge DellerEND(sys_call_table)
6551da177e4SLinus Torvalds
656413059f2SGrant Grundler#ifdef CONFIG_64BIT
6571c593571SSam Ravnborg	.align PAGE_SIZE
6588e9e9844SHelge DellerENTRY(sys_call_table64)
6591da177e4SLinus Torvalds#define SYSCALL_TABLE_64BIT
6601da177e4SLinus Torvalds#include "syscall_table.S"
6618e9e9844SHelge DellerEND(sys_call_table64)
6621da177e4SLinus Torvalds#endif
6631da177e4SLinus Torvalds
6641da177e4SLinus Torvalds	/*
6651da177e4SLinus Torvalds		All light-weight-syscall atomic operations
6661da177e4SLinus Torvalds		will use this set of locks
667c84c3a69SHelge Deller
668c84c3a69SHelge Deller		NOTE: The lws_lock_start symbol must be
669c84c3a69SHelge Deller		at least 16-byte aligned for safe use
670c84c3a69SHelge Deller		with ldcw.
6711da177e4SLinus Torvalds	*/
672dfcf753bSKyle McMartin	.section .data
673873d50e2SKyle McMartin	.align	PAGE_SIZE
6748e9e9844SHelge DellerENTRY(lws_lock_start)
6751da177e4SLinus Torvalds	/* lws locks */
6761da177e4SLinus Torvalds	.rept 16
6771da177e4SLinus Torvalds	/* Keep locks aligned at 16-bytes */
6781da177e4SLinus Torvalds	.word 1
6791da177e4SLinus Torvalds	.word 0
6801da177e4SLinus Torvalds	.word 0
6811da177e4SLinus Torvalds	.word 0
6821da177e4SLinus Torvalds	.endr
6838e9e9844SHelge DellerEND(lws_lock_start)
6841da177e4SLinus Torvalds	.previous
6851da177e4SLinus Torvalds
6861da177e4SLinus Torvalds.end
6871da177e4SLinus Torvalds
6881da177e4SLinus Torvalds
689