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