xref: /xnu-8020.140.41/osfmk/mach/arm/syscall_sw.h (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
1 /*
2  * Copyright (c) 2007 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * FILE_ID: syscall_sw.h
30  */
31 
32 #ifndef	_MACH_ARM_SYSCALL_SW_H_
33 #define _MACH_ARM_SYSCALL_SW_H_
34 
35 #if defined(__arm__)
36 
37 #include <mach/machine/vm_param.h>
38 #include <architecture/arm/asm_help.h>
39 
40 /* 0 to 4 args are already loaded in r0-r3 */
41 #define _kernel_trap_0to4(trap_name, trap_number) \
42 	mov		r12, # ## trap_number			/* load syscall number */ ; \
43 	swi		#SWI_SYSCALL					; \
44 	bx		lr								/* return */ ;
45 
46 #define _kernel_trap_5(trap_name, trap_number) \
47 	mov		ip, sp							/* save pointer to args */ ; \
48 	stmfd	sp!, { r4-r5 }					/* save r4-r5, keep stack 64-bit aligned */; \
49 	ldr		r4, [ ip ]						/* load arg 5 */ ; \
50 	mov		r12, # ## trap_number			/* load syscall number */ ; \
51 	swi		#SWI_SYSCALL					; \
52 	ldmfd	sp!, { r4-r5 }					/* restore r4-r5 */ ;\
53 	bx		lr								/* return */ ;
54 
55 #define _kernel_trap_6to9(trap_name, trap_number, save_regs, arg_regs) \
56 	mov		ip, sp							/* save pointer to args */ ; \
57 	stmfd	sp!, { save_regs }				/* callee saved regs */; \
58 	ldmia	ip, { arg_regs }				/* load arg registers (above r0-r3) */ ;\
59 	mov		r12, # ## trap_number			/* load syscall number */ ; \
60 	swi		#SWI_SYSCALL					; \
61 	ldmfd	sp!, { save_regs }	 			/* restore callee saved regs */ ;\
62 	bx		lr								/* return */ ;
63 
64 #define COMMA ,
65 
66 /* For the armv7k ABI, the alignment requirements may add padding. So we
67  * let the kernel figure it out and push extra on the stack to avoid un-needed
68  * copy-ins. We are relying on arguments that aren't in registers starting
69  * 32 bytes from sp.  */
70 #if __BIGGEST_ALIGNMENT__ > 4
71 
72 #define _kernel_trap_0(trap_name, trap_number) _kernel_trap_0to4(trap_name, trap_number)
73 #define _kernel_trap_1(trap_name, trap_number) _kernel_trap_0to4(trap_name, trap_number)
74 #define _kernel_trap_2(trap_name, trap_number) _kernel_trap_0to4(trap_name, trap_number)
75 #define _kernel_trap_3(trap_name, trap_number) _kernel_trap_0to4(trap_name, trap_number)
76 #define _kernel_trap_4(trap_name, trap_number) _kernel_trap_6to9(trap_name, trap_number, r4-r5, r4-r5)
77 #undef _kernel_trap_5
78 #define _kernel_trap_5(trap_name, trap_number) _kernel_trap_6to9(trap_name, trap_number, r4-r5, r4-r5)
79 #define _kernel_trap_6(trap_name, trap_number) _kernel_trap_6to9(trap_name, trap_number, r4-r6 COMMA r8, r4-r6 COMMA r8)
80 #define _kernel_trap_7(trap_name, trap_number) _kernel_trap_6to9(trap_name, trap_number, r4-r6 COMMA r8, r4-r6 COMMA r8)
81 #define _kernel_trap_8(trap_name, trap_number) _kernel_trap_6to9(trap_name, trap_number, r4-r6 COMMA r8, r4-r6 COMMA r8)
82 #define _kernel_trap_9(trap_name, trap_number) _kernel_trap_6to9(trap_name, trap_number, r4-r6 COMMA r8, r4-r6 COMMA r8)
83 #else // !(__BIGGEST_ALIGNMENT__ > 4)
84 
85 #define _kernel_trap_0(trap_name, trap_number) _kernel_trap_0to4(trap_name, trap_number)
86 #define _kernel_trap_1(trap_name, trap_number) _kernel_trap_0to4(trap_name, trap_number)
87 #define _kernel_trap_2(trap_name, trap_number) _kernel_trap_0to4(trap_name, trap_number)
88 #define _kernel_trap_3(trap_name, trap_number) _kernel_trap_0to4(trap_name, trap_number)
89 #define _kernel_trap_4(trap_name, trap_number) _kernel_trap_0to4(trap_name, trap_number)
90 /* _kernel_trap_5 defined above */
91 #define _kernel_trap_6(trap_name, trap_number) _kernel_trap_6to9(trap_name, trap_number, r4-r5, r4-r5)
92 /* need to save r8 not just for alignment but because mach_msg_trap overwrites the eighth argument */
93 #define _kernel_trap_7(trap_name, trap_number) _kernel_trap_6to9(trap_name, trap_number, r4-r6 COMMA r8, r4-r6)
94 #define _kernel_trap_8(trap_name, trap_number) _kernel_trap_6to9(trap_name, trap_number, r4-r6 COMMA r8, r4-r6 COMMA r8)
95 /* there is only one nine-argument trap (mach_msg_overwrite_trap) and it doesn't use the ninth argument */
96 #define _kernel_trap_9(trap_name, trap_number) _kernel_trap_8(trap_name, trap_number)
97 
98 #endif // __BIGGEST_ALIGNMENT__ > 4
99 
100 
101 /* select the appropriate trap macro based off the number of args */
102 #define kernel_trap(trap_name, trap_number, num_args) \
103 	LEAF(_##trap_name, 0)	\
104 	_kernel_trap_##num_args(trap_name, trap_number)
105 
106 #elif defined(__arm64__)
107 
108 #include <mach/machine/vm_param.h>
109 
110 #define kernel_trap(trap_name, trap_number, num_args) \
111 .globl _##trap_name                                           %% \
112 .text                                                         %% \
113 .align  2                                                     %% \
114 _##trap_name:                                                 %% \
115     mov x16, #(trap_number)                                   %% \
116     svc #SWI_SYSCALL                                          %% \
117     ret
118 
119 #else
120 #error Unsupported architecture
121 #endif
122 
123 #endif	/* _MACH_ARM_SYSCALL_SW_H_ */
124