]>
Commit | Line | Data |
---|---|---|
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_ */ |