Text file src/runtime/sys_freebsd_arm.s
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 //
5 // System calls and other sys.stuff for ARM, FreeBSD
6 // /usr/src/sys/kern/syscalls.master for syscall numbers.
7 //
8
9 #include "go_asm.h"
10 #include "go_tls.h"
11 #include "textflag.h"
12
13 // for EABI, as we don't support OABI
14 #define SYS_BASE 0x0
15
16 #define SYS_exit (SYS_BASE + 1)
17 #define SYS_read (SYS_BASE + 3)
18 #define SYS_write (SYS_BASE + 4)
19 #define SYS_open (SYS_BASE + 5)
20 #define SYS_close (SYS_BASE + 6)
21 #define SYS_getpid (SYS_BASE + 20)
22 #define SYS_kill (SYS_BASE + 37)
23 #define SYS_sigaltstack (SYS_BASE + 53)
24 #define SYS_munmap (SYS_BASE + 73)
25 #define SYS_madvise (SYS_BASE + 75)
26 #define SYS_setitimer (SYS_BASE + 83)
27 #define SYS_fcntl (SYS_BASE + 92)
28 #define SYS___sysctl (SYS_BASE + 202)
29 #define SYS_nanosleep (SYS_BASE + 240)
30 #define SYS_clock_gettime (SYS_BASE + 232)
31 #define SYS_sched_yield (SYS_BASE + 331)
32 #define SYS_sigprocmask (SYS_BASE + 340)
33 #define SYS_kqueue (SYS_BASE + 362)
34 #define SYS_kevent (SYS_BASE + 363)
35 #define SYS_sigaction (SYS_BASE + 416)
36 #define SYS_thr_exit (SYS_BASE + 431)
37 #define SYS_thr_self (SYS_BASE + 432)
38 #define SYS_thr_kill (SYS_BASE + 433)
39 #define SYS__umtx_op (SYS_BASE + 454)
40 #define SYS_thr_new (SYS_BASE + 455)
41 #define SYS_mmap (SYS_BASE + 477)
42 #define SYS_cpuset_getaffinity (SYS_BASE + 487)
43
44 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
45 MOVW addr+0(FP), R0
46 MOVW mode+4(FP), R1
47 MOVW val+8(FP), R2
48 MOVW uaddr1+12(FP), R3
49 ADD $20, R13 // arg 5 is passed on stack
50 MOVW $SYS__umtx_op, R7
51 SWI $0
52 SUB $20, R13
53 // BCS error
54 MOVW R0, ret+20(FP)
55 RET
56
57 TEXT runtime·thr_new(SB),NOSPLIT,$0
58 MOVW param+0(FP), R0
59 MOVW size+4(FP), R1
60 MOVW $SYS_thr_new, R7
61 SWI $0
62 MOVW R0, ret+8(FP)
63 RET
64
65 TEXT runtime·thr_start(SB),NOSPLIT,$0
66 // set up g
67 MOVW m_g0(R0), g
68 MOVW R0, g_m(g)
69 BL runtime·emptyfunc(SB) // fault if stack check is wrong
70 BL runtime·mstart(SB)
71
72 MOVW $2, R8 // crash (not reached)
73 MOVW R8, (R8)
74 RET
75
76 // Exit the entire program (like C exit)
77 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
78 MOVW code+0(FP), R0 // arg 1 exit status
79 MOVW $SYS_exit, R7
80 SWI $0
81 MOVW.CS $0, R8 // crash on syscall failure
82 MOVW.CS R8, (R8)
83 RET
84
85 // func exitThread(wait *uint32)
86 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
87 MOVW wait+0(FP), R0
88 // We're done using the stack.
89 MOVW $0, R2
90 storeloop:
91 LDREX (R0), R4 // loads R4
92 STREX R2, (R0), R1 // stores R2
93 CMP $0, R1
94 BNE storeloop
95 MOVW $0, R0 // arg 1 long *state
96 MOVW $SYS_thr_exit, R7
97 SWI $0
98 MOVW.CS $0, R8 // crash on syscall failure
99 MOVW.CS R8, (R8)
100 JMP 0(PC)
101
102 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0
103 MOVW name+0(FP), R0 // arg 1 name
104 MOVW mode+4(FP), R1 // arg 2 mode
105 MOVW perm+8(FP), R2 // arg 3 perm
106 MOVW $SYS_open, R7
107 SWI $0
108 MOVW.CS $-1, R0
109 MOVW R0, ret+12(FP)
110 RET
111
112 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0
113 MOVW fd+0(FP), R0 // arg 1 fd
114 MOVW p+4(FP), R1 // arg 2 buf
115 MOVW n+8(FP), R2 // arg 3 count
116 MOVW $SYS_read, R7
117 SWI $0
118 MOVW.CS $-1, R0
119 MOVW R0, ret+12(FP)
120 RET
121
122 TEXT runtime·write(SB),NOSPLIT|NOFRAME,$0
123 MOVW fd+0(FP), R0 // arg 1 fd
124 MOVW p+4(FP), R1 // arg 2 buf
125 MOVW n+8(FP), R2 // arg 3 count
126 MOVW $SYS_write, R7
127 SWI $0
128 MOVW.CS $-1, R0
129 MOVW R0, ret+12(FP)
130 RET
131
132 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0
133 MOVW fd+0(FP), R0 // arg 1 fd
134 MOVW $SYS_close, R7
135 SWI $0
136 MOVW.CS $-1, R0
137 MOVW R0, ret+4(FP)
138 RET
139
140 TEXT runtime·raise(SB),NOSPLIT,$8
141 // thr_self(&4(R13))
142 MOVW $4(R13), R0 // arg 1 &4(R13)
143 MOVW $SYS_thr_self, R7
144 SWI $0
145 // thr_kill(self, SIGPIPE)
146 MOVW 4(R13), R0 // arg 1 id
147 MOVW sig+0(FP), R1 // arg 2 - signal
148 MOVW $SYS_thr_kill, R7
149 SWI $0
150 RET
151
152 TEXT runtime·raiseproc(SB),NOSPLIT,$0
153 // getpid
154 MOVW $SYS_getpid, R7
155 SWI $0
156 // kill(self, sig)
157 // arg 1 - pid, now in R0
158 MOVW sig+0(FP), R1 // arg 2 - signal
159 MOVW $SYS_kill, R7
160 SWI $0
161 RET
162
163 TEXT runtime·setitimer(SB), NOSPLIT|NOFRAME, $0
164 MOVW mode+0(FP), R0
165 MOVW new+4(FP), R1
166 MOVW old+8(FP), R2
167 MOVW $SYS_setitimer, R7
168 SWI $0
169 RET
170
171 // func fallback_walltime() (sec int64, nsec int32)
172 TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12
173 MOVW $0, R0 // CLOCK_REALTIME
174 MOVW $8(R13), R1
175 MOVW $SYS_clock_gettime, R7
176 SWI $0
177
178 MOVW 8(R13), R0 // sec.low
179 MOVW 12(R13), R1 // sec.high
180 MOVW 16(R13), R2 // nsec
181
182 MOVW R0, sec_lo+0(FP)
183 MOVW R1, sec_hi+4(FP)
184 MOVW R2, nsec+8(FP)
185 RET
186
187 // func fallback_nanotime() int64
188 TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32
189 MOVW $4, R0 // CLOCK_MONOTONIC
190 MOVW $8(R13), R1
191 MOVW $SYS_clock_gettime, R7
192 SWI $0
193
194 MOVW 8(R13), R0 // sec.low
195 MOVW 12(R13), R4 // sec.high
196 MOVW 16(R13), R2 // nsec
197
198 MOVW $1000000000, R3
199 MULLU R0, R3, (R1, R0)
200 MUL R3, R4
201 ADD.S R2, R0
202 ADC R4, R1
203
204 MOVW R0, ret_lo+0(FP)
205 MOVW R1, ret_hi+4(FP)
206 RET
207
208 TEXT runtime·asmSigaction(SB),NOSPLIT|NOFRAME,$0
209 MOVW sig+0(FP), R0 // arg 1 sig
210 MOVW new+4(FP), R1 // arg 2 act
211 MOVW old+8(FP), R2 // arg 3 oact
212 MOVW $SYS_sigaction, R7
213 SWI $0
214 MOVW.CS $-1, R0
215 MOVW R0, ret+12(FP)
216 RET
217
218 TEXT runtime·sigtramp(SB),NOSPLIT,$12
219 // this might be called in external code context,
220 // where g is not set.
221 // first save R0, because runtime·load_g will clobber it
222 MOVW R0, 4(R13) // signum
223 MOVB runtime·iscgo(SB), R0
224 CMP $0, R0
225 BL.NE runtime·load_g(SB)
226
227 MOVW R1, 8(R13)
228 MOVW R2, 12(R13)
229 BL runtime·sigtrampgo(SB)
230 RET
231
232 TEXT runtime·mmap(SB),NOSPLIT,$16
233 MOVW addr+0(FP), R0 // arg 1 addr
234 MOVW n+4(FP), R1 // arg 2 len
235 MOVW prot+8(FP), R2 // arg 3 prot
236 MOVW flags+12(FP), R3 // arg 4 flags
237 // arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack
238 // note the C runtime only passes the 32-bit offset_lo to us
239 MOVW fd+16(FP), R4 // arg 5
240 MOVW R4, 4(R13)
241 MOVW off+20(FP), R5 // arg 6 lower 32-bit
242 // the word at 8(R13) is skipped due to 64-bit argument alignment.
243 MOVW R5, 12(R13)
244 MOVW $0, R6 // higher 32-bit for arg 6
245 MOVW R6, 16(R13)
246 ADD $4, R13
247 MOVW $SYS_mmap, R7
248 SWI $0
249 SUB $4, R13
250 MOVW $0, R1
251 MOVW.CS R0, R1 // if failed, put in R1
252 MOVW.CS $0, R0
253 MOVW R0, p+24(FP)
254 MOVW R1, err+28(FP)
255 RET
256
257 TEXT runtime·munmap(SB),NOSPLIT,$0
258 MOVW addr+0(FP), R0 // arg 1 addr
259 MOVW n+4(FP), R1 // arg 2 len
260 MOVW $SYS_munmap, R7
261 SWI $0
262 MOVW.CS $0, R8 // crash on syscall failure
263 MOVW.CS R8, (R8)
264 RET
265
266 TEXT runtime·madvise(SB),NOSPLIT,$0
267 MOVW addr+0(FP), R0 // arg 1 addr
268 MOVW n+4(FP), R1 // arg 2 len
269 MOVW flags+8(FP), R2 // arg 3 flags
270 MOVW $SYS_madvise, R7
271 SWI $0
272 MOVW.CS $-1, R0
273 MOVW R0, ret+12(FP)
274 RET
275
276 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
277 MOVW new+0(FP), R0
278 MOVW old+4(FP), R1
279 MOVW $SYS_sigaltstack, R7
280 SWI $0
281 MOVW.CS $0, R8 // crash on syscall failure
282 MOVW.CS R8, (R8)
283 RET
284
285 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
286 MOVW sig+4(FP), R0
287 MOVW info+8(FP), R1
288 MOVW ctx+12(FP), R2
289 MOVW fn+0(FP), R11
290 MOVW R13, R4
291 SUB $24, R13
292 BIC $0x7, R13 // alignment for ELF ABI
293 BL (R11)
294 MOVW R4, R13
295 RET
296
297 TEXT runtime·usleep(SB),NOSPLIT,$16
298 MOVW usec+0(FP), R0
299 CALL runtime·usplitR0(SB)
300 // 0(R13) is the saved LR, don't use it
301 MOVW R0, 4(R13) // tv_sec.low
302 MOVW $0, R0
303 MOVW R0, 8(R13) // tv_sec.high
304 MOVW $1000, R2
305 MUL R1, R2
306 MOVW R2, 12(R13) // tv_nsec
307
308 MOVW $4(R13), R0 // arg 1 - rqtp
309 MOVW $0, R1 // arg 2 - rmtp
310 MOVW $SYS_nanosleep, R7
311 SWI $0
312 RET
313
314 TEXT runtime·sysctl(SB),NOSPLIT,$0
315 MOVW mib+0(FP), R0 // arg 1 - name
316 MOVW miblen+4(FP), R1 // arg 2 - namelen
317 MOVW out+8(FP), R2 // arg 3 - old
318 MOVW size+12(FP), R3 // arg 4 - oldlenp
319 // arg 5 (newp) and arg 6 (newlen) are passed on stack
320 ADD $20, R13
321 MOVW $SYS___sysctl, R7
322 SWI $0
323 SUB.CS $0, R0, R0
324 SUB $20, R13
325 MOVW R0, ret+24(FP)
326 RET
327
328 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
329 MOVW $SYS_sched_yield, R7
330 SWI $0
331 RET
332
333 TEXT runtime·sigprocmask(SB),NOSPLIT,$0
334 MOVW how+0(FP), R0 // arg 1 - how
335 MOVW new+4(FP), R1 // arg 2 - set
336 MOVW old+8(FP), R2 // arg 3 - oset
337 MOVW $SYS_sigprocmask, R7
338 SWI $0
339 MOVW.CS $0, R8 // crash on syscall failure
340 MOVW.CS R8, (R8)
341 RET
342
343 // int32 runtime·kqueue(void)
344 TEXT runtime·kqueue(SB),NOSPLIT,$0
345 MOVW $SYS_kqueue, R7
346 SWI $0
347 RSB.CS $0, R0
348 MOVW R0, ret+0(FP)
349 RET
350
351 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
352 TEXT runtime·kevent(SB),NOSPLIT,$0
353 MOVW kq+0(FP), R0 // kq
354 MOVW ch+4(FP), R1 // changelist
355 MOVW nch+8(FP), R2 // nchanges
356 MOVW ev+12(FP), R3 // eventlist
357 ADD $20, R13 // pass arg 5 and 6 on stack
358 MOVW $SYS_kevent, R7
359 SWI $0
360 RSB.CS $0, R0
361 SUB $20, R13
362 MOVW R0, ret+24(FP)
363 RET
364
365 // void runtime·closeonexec(int32 fd)
366 TEXT runtime·closeonexec(SB),NOSPLIT,$0
367 MOVW fd+0(FP), R0 // fd
368 MOVW $2, R1 // F_SETFD
369 MOVW $1, R2 // FD_CLOEXEC
370 MOVW $SYS_fcntl, R7
371 SWI $0
372 RET
373
374 // TODO: this is only valid for ARMv7+
375 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
376 B runtime·armPublicationBarrier(SB)
377
378 // TODO(minux): this only supports ARMv6K+.
379 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
380 WORD $0xee1d0f70 // mrc p15, 0, r0, c13, c0, 3
381 RET
382
383 // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
384 TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-28
385 MOVW level+0(FP), R0
386 MOVW which+4(FP), R1
387 MOVW id_lo+8(FP), R2
388 MOVW id_hi+12(FP), R3
389 ADD $20, R13 // Pass size and mask on stack.
390 MOVW $SYS_cpuset_getaffinity, R7
391 SWI $0
392 RSB.CS $0, R0
393 SUB $20, R13
394 MOVW R0, ret+24(FP)
395 RET
396
397 // func getCntxct(physical bool) uint32
398 TEXT runtime·getCntxct(SB),NOSPLIT|NOFRAME,$0-8
399 MOVB runtime·goarm(SB), R11
400 CMP $7, R11
401 BLT 2(PC)
402 DMB
403
404 MOVB physical+0(FP), R0
405 CMP $1, R0
406 B.NE 3(PC)
407
408 // get CNTPCT (Physical Count Register) into R0(low) R1(high)
409 // mrrc 15, 0, r0, r1, cr14
410 WORD $0xec510f0e
411 B 2(PC)
412
413 // get CNTVCT (Virtual Count Register) into R0(low) R1(high)
414 // mrrc 15, 1, r0, r1, cr14
415 WORD $0xec510f1e
416
417 MOVW R0, ret+4(FP)
418 RET
View as plain text