]> git.saurik.com Git - apple/libc.git/blob - arm/sys/SYS.h
1fdf5708710dd50cc50940ee2818331b7d768eaf
[apple/libc.git] / arm / sys / SYS.h
1 /*
2 * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Header files.
26 */
27 #import <sys/syscall.h>
28 #define SWI_SYSCALL 0x80 // from <mach/vm_param.h>
29
30 /*
31 * ARM system call interface:
32 *
33 * swi 0x80
34 * args: r0-r6
35 * return code: r0
36 * on error, carry bit is set in the psr, otherwise carry bit is cleared.
37 */
38
39 /*
40 * Macros.
41 */
42
43 /*
44 * until we update the architecture project, these live here
45 */
46
47 #if defined(__DYNAMIC__)
48 #define MI_GET_ADDRESS(reg,var) \
49 ldr reg, 4f ;\
50 3: ldr reg, [pc, reg] ;\
51 b 5f ;\
52 4: .long 6f - (3b + 8) ;\
53 5: ;\
54 .non_lazy_symbol_pointer ;\
55 6: ;\
56 .indirect_symbol var ;\
57 .long 0 ;\
58 .text ;\
59 .align 2
60 #else
61 #define MI_GET_ADDRESS(reg,var) \
62 ldr reg, 3f ;\
63 b 4f ;\
64 3: .long var ;\
65 4:
66 #endif
67
68 #if defined(__DYNAMIC__)
69 #define MI_BRANCH_EXTERNAL(var) \
70 .globl var ;\
71 MI_GET_ADDRESS(ip, var) ;\
72 bx ip
73 #else
74 #define MI_BRANCH_EXTERNAL(var) ;\
75 .globl var ;\
76 b var
77 #endif
78
79 #if defined(__DYNAMIC__)
80 #define MI_CALL_EXTERNAL(var) \
81 .globl var ;\
82 MI_GET_ADDRESS(ip,var) ;\
83 mov lr, pc ;\
84 bx ip
85 #else
86 #define MI_CALL_EXTERNAL(var) \
87 .globl var ;\
88 bl var
89 #endif
90
91 #define MI_ENTRY_POINT(name) \
92 .align 2 ;\
93 .globl name ;\
94 .text ;\
95 name:
96
97 /* load the syscall number into r12 and trap */
98 #define DO_SYSCALL(num) \
99 .if (((num) & 0xff) == (num)) ;\
100 mov r12, #(num) ;\
101 .elseif (((num) & 0x3fc) == (num)) ;\
102 mov r12, #(num) ;\
103 .else ;\
104 mov r12, #((num) & 0xffffff00) /* top half of the syscall number */ ;\
105 orr r12, r12, #((num) & 0xff) /* bottom half */ ;\
106 .endif ;\
107 swi #SWI_SYSCALL
108
109 /* simple syscalls (0 to 4 args) */
110 #define SYSCALL_0to4(name) \
111 MI_ENTRY_POINT(_##name) ;\
112 DO_SYSCALL(SYS_##name) ;\
113 bxcc lr /* return if carry is clear (no error) */ ; \
114 1: MI_BRANCH_EXTERNAL(cerror)
115
116 /* syscalls with 5 args is different, because of the single arg register load */
117 #define SYSCALL_5(name) \
118 MI_ENTRY_POINT(_##name) ;\
119 mov ip, sp /* save a pointer to the args */ ; \
120 stmfd sp!, { r4-r5 } /* save r4-r5 */ ;\
121 ldr r4, [ip] /* load 5th arg */ ; \
122 DO_SYSCALL(SYS_##name) ;\
123 ldmfd sp!, { r4-r5 } /* restore r4-r5 */ ; \
124 bxcc lr /* return if carry is clear (no error) */ ; \
125 1: MI_BRANCH_EXTERNAL(cerror)
126
127 /* syscalls with 6 to 8 args */
128 #define SYSCALL_6to8(name, save_regs, arg_regs) \
129 MI_ENTRY_POINT(_##name) ;\
130 mov ip, sp /* save a pointer to the args */ ; \
131 stmfd sp!, { save_regs } /* callee saved regs */ ;\
132 ldmia ip, { arg_regs } /* load arg regs */ ; \
133 DO_SYSCALL(SYS_##name) ;\
134 ldmfd sp!, { save_regs } /* restore callee saved regs */ ; \
135 bxcc lr /* return if carry is clear (no error) */ ; \
136 1: MI_BRANCH_EXTERNAL(cerror)
137
138 #define COMMA ,
139
140 #define SYSCALL_0(name) SYSCALL_0to4(name)
141 #define SYSCALL_1(name) SYSCALL_0to4(name)
142 #define SYSCALL_2(name) SYSCALL_0to4(name)
143 #define SYSCALL_3(name) SYSCALL_0to4(name)
144 #define SYSCALL_4(name) SYSCALL_0to4(name)
145 /* SYSCALL_5 declared above */
146 #define SYSCALL_6(name) SYSCALL_6to8(name, r4-r5, r4-r5)
147 #define SYSCALL_7(name) SYSCALL_6to8(name, r4-r6 COMMA r8, r4-r6)
148 /* there are no 8-argument syscalls currently defined */
149
150 /* select the appropriate syscall code, based on the number of arguments */
151 #define SYSCALL(name, nargs) SYSCALL_##nargs(name)
152
153 #define SYSCALL_NONAME_0to4(name) \
154 DO_SYSCALL(SYS_##name) ;\
155 bcc 1f /* branch if carry bit is clear (no error) */ ; \
156 MI_BRANCH_EXTERNAL(cerror) /* call cerror */ ; \
157 1:
158
159 #define SYSCALL_NONAME_5(name) \
160 mov ip, sp /* save a pointer to the args */ ; \
161 stmfd sp!, { r4-r5 } /* save r4-r5 */ ;\
162 ldr r4, [ip] /* load 5th arg */ ; \
163 DO_SYSCALL(SYS_##name) ;\
164 ldmfd sp!, { r4-r5 } /* restore r4-r7 */ ; \
165 bcc 1f /* branch if carry bit is clear (no error) */ ; \
166 MI_BRANCH_EXTERNAL(cerror) /* call cerror */ ; \
167 1:
168
169 #define SYSCALL_NONAME_6to8(name, save_regs, arg_regs) \
170 mov ip, sp /* save a pointer to the args */ ; \
171 stmfd sp!, { save_regs } /* callee save regs */ ;\
172 ldmia ip, { arg_regs } /* load arguments */ ; \
173 DO_SYSCALL(SYS_##name) ;\
174 ldmfd sp!, { save_regs } /* restore callee saved regs */ ; \
175 bcc 1f /* branch if carry bit is clear (no error) */ ; \
176 MI_BRANCH_EXTERNAL(cerror) /* call cerror */ ; \
177 1:
178
179 #define SYSCALL_NONAME_0(name) SYSCALL_NONAME_0to4(name)
180 #define SYSCALL_NONAME_1(name) SYSCALL_NONAME_0to4(name)
181 #define SYSCALL_NONAME_2(name) SYSCALL_NONAME_0to4(name)
182 #define SYSCALL_NONAME_3(name) SYSCALL_NONAME_0to4(name)
183 #define SYSCALL_NONAME_4(name) SYSCALL_NONAME_0to4(name)
184 /* SYSCALL_NONAME_5 declared above */
185 #define SYSCALL_NONAME_6(name) SYSCALL_NONAME_6to8(name, r4-r5, r4-r5)
186 #define SYSCALL_NONAME_7(name) SYSCALL_NONAME_6to8(name, r4-r6 COMMA r8, r4-r6)
187 /* there are no 8-argument syscalls currently defined */
188
189 /* select the appropriate syscall code, based on the number of arguments */
190 #define SYSCALL_NONAME(name, nargs) SYSCALL_NONAME_##nargs(name)
191
192 #define PSEUDO(pseudo, name, nargs) \
193 .globl _##pseudo ;\
194 .text ;\
195 .align 2 ;\
196 _##pseudo: ;\
197 SYSCALL_NONAME(name, nargs)
198
199 #undef END
200 #import <mach/arm/syscall_sw.h>
201
202 #if !defined(SYS___pthread_canceled)
203 #define SYS___pthread_markcancel 332
204 #define SYS___pthread_canceled 333
205 #define SYS___semwait_signal 334
206 #endif