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