blob: ca443b699fdcf3b2cf6b3866fadad8a008ff5c57 [file] [log] [blame]
Brent Austinba3052e2015-04-21 16:08:23 -07001// Copyright 2009 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//
6// System calls and other sys.stuff for arm, Linux
7//
8
Dan Willemsen09eb3b12015-09-16 14:34:17 -07009#include "go_asm.h"
10#include "go_tls.h"
Brent Austinba3052e2015-04-21 16:08:23 -070011#include "textflag.h"
12
Dan Willemsenc7413322018-08-27 23:21:26 -070013#define CLOCK_REALTIME 0
14#define CLOCK_MONOTONIC 1
15
Brent Austinba3052e2015-04-21 16:08:23 -070016// for EABI, as we don't support OABI
17#define SYS_BASE 0x0
18
19#define SYS_exit (SYS_BASE + 1)
20#define SYS_read (SYS_BASE + 3)
21#define SYS_write (SYS_BASE + 4)
22#define SYS_open (SYS_BASE + 5)
23#define SYS_close (SYS_BASE + 6)
Dan Willemsen09eb3b12015-09-16 14:34:17 -070024#define SYS_getpid (SYS_BASE + 20)
25#define SYS_kill (SYS_BASE + 37)
Patrice Arruda748609c2020-06-25 12:12:21 -070026#define SYS_pipe (SYS_BASE + 42)
Brent Austinba3052e2015-04-21 16:08:23 -070027#define SYS_clone (SYS_BASE + 120)
28#define SYS_rt_sigreturn (SYS_BASE + 173)
29#define SYS_rt_sigaction (SYS_BASE + 174)
30#define SYS_rt_sigprocmask (SYS_BASE + 175)
31#define SYS_sigaltstack (SYS_BASE + 186)
32#define SYS_mmap2 (SYS_BASE + 192)
33#define SYS_futex (SYS_BASE + 240)
34#define SYS_exit_group (SYS_BASE + 248)
35#define SYS_munmap (SYS_BASE + 91)
36#define SYS_madvise (SYS_BASE + 220)
37#define SYS_setitimer (SYS_BASE + 104)
38#define SYS_mincore (SYS_BASE + 219)
39#define SYS_gettid (SYS_BASE + 224)
Colin Crossd9c6b802019-03-19 21:10:31 -070040#define SYS_tgkill (SYS_BASE + 268)
Brent Austinba3052e2015-04-21 16:08:23 -070041#define SYS_sched_yield (SYS_BASE + 158)
Dan Willemsenc7413322018-08-27 23:21:26 -070042#define SYS_nanosleep (SYS_BASE + 162)
Brent Austinba3052e2015-04-21 16:08:23 -070043#define SYS_sched_getaffinity (SYS_BASE + 242)
44#define SYS_clock_gettime (SYS_BASE + 263)
45#define SYS_epoll_create (SYS_BASE + 250)
46#define SYS_epoll_ctl (SYS_BASE + 251)
47#define SYS_epoll_wait (SYS_BASE + 252)
Dan Willemsenbc60c3c2021-12-15 01:09:00 -080048#define SYS_timer_create (SYS_BASE + 257)
49#define SYS_timer_settime (SYS_BASE + 258)
50#define SYS_timer_delete (SYS_BASE + 261)
Brent Austinba3052e2015-04-21 16:08:23 -070051#define SYS_epoll_create1 (SYS_BASE + 357)
Patrice Arruda748609c2020-06-25 12:12:21 -070052#define SYS_pipe2 (SYS_BASE + 359)
Brent Austinba3052e2015-04-21 16:08:23 -070053#define SYS_fcntl (SYS_BASE + 55)
Dan Willemsen09eb3b12015-09-16 14:34:17 -070054#define SYS_access (SYS_BASE + 33)
55#define SYS_connect (SYS_BASE + 283)
56#define SYS_socket (SYS_BASE + 281)
Dan Willemsend2797482017-07-26 13:13:13 -070057#define SYS_brk (SYS_BASE + 45)
Brent Austinba3052e2015-04-21 16:08:23 -070058
59#define ARM_BASE (SYS_BASE + 0x0f0000)
60
61TEXT runtime·open(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -070062 MOVW name+0(FP), R0
63 MOVW mode+4(FP), R1
64 MOVW perm+8(FP), R2
Brent Austinba3052e2015-04-21 16:08:23 -070065 MOVW $SYS_open, R7
66 SWI $0
Dan Willemsen09eb3b12015-09-16 14:34:17 -070067 MOVW $0xfffff001, R1
68 CMP R1, R0
69 MOVW.HI $-1, R0
Brent Austinba3052e2015-04-21 16:08:23 -070070 MOVW R0, ret+12(FP)
71 RET
72
Dan Willemsen09eb3b12015-09-16 14:34:17 -070073TEXT runtime·closefd(SB),NOSPLIT,$0
74 MOVW fd+0(FP), R0
Brent Austinba3052e2015-04-21 16:08:23 -070075 MOVW $SYS_close, R7
76 SWI $0
Dan Willemsen09eb3b12015-09-16 14:34:17 -070077 MOVW $0xfffff001, R1
78 CMP R1, R0
79 MOVW.HI $-1, R0
Brent Austinba3052e2015-04-21 16:08:23 -070080 MOVW R0, ret+4(FP)
81 RET
82
Patrice Arruda748609c2020-06-25 12:12:21 -070083TEXT runtime·write1(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -070084 MOVW fd+0(FP), R0
85 MOVW p+4(FP), R1
86 MOVW n+8(FP), R2
Brent Austinba3052e2015-04-21 16:08:23 -070087 MOVW $SYS_write, R7
88 SWI $0
89 MOVW R0, ret+12(FP)
90 RET
91
92TEXT runtime·read(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -070093 MOVW fd+0(FP), R0
94 MOVW p+4(FP), R1
95 MOVW n+8(FP), R2
Brent Austinba3052e2015-04-21 16:08:23 -070096 MOVW $SYS_read, R7
97 SWI $0
98 MOVW R0, ret+12(FP)
99 RET
100
Patrice Arruda748609c2020-06-25 12:12:21 -0700101// func pipe() (r, w int32, errno int32)
102TEXT runtime·pipe(SB),NOSPLIT,$0-12
103 MOVW $r+0(FP), R0
104 MOVW $SYS_pipe, R7
105 SWI $0
106 MOVW R0, errno+8(FP)
107 RET
108
109// func pipe2(flags int32) (r, w int32, errno int32)
110TEXT runtime·pipe2(SB),NOSPLIT,$0-16
111 MOVW $r+4(FP), R0
112 MOVW flags+0(FP), R1
113 MOVW $SYS_pipe2, R7
114 SWI $0
115 MOVW R0, errno+12(FP)
116 RET
117
Dan Willemsenc7413322018-08-27 23:21:26 -0700118TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700119 MOVW code+0(FP), R0
Brent Austinba3052e2015-04-21 16:08:23 -0700120 MOVW $SYS_exit_group, R7
121 SWI $0
122 MOVW $1234, R0
123 MOVW $1002, R1
124 MOVW R0, (R1) // fail hard
125
Dan Willemsenc7413322018-08-27 23:21:26 -0700126TEXT exit1<>(SB),NOSPLIT|NOFRAME,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700127 MOVW code+0(FP), R0
Brent Austinba3052e2015-04-21 16:08:23 -0700128 MOVW $SYS_exit, R7
129 SWI $0
130 MOVW $1234, R0
131 MOVW $1003, R1
132 MOVW R0, (R1) // fail hard
133
Dan Willemsena3223282018-02-27 19:41:43 -0800134// func exitThread(wait *uint32)
Dan Willemsenc7413322018-08-27 23:21:26 -0700135TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-4
Dan Willemsena3223282018-02-27 19:41:43 -0800136 MOVW wait+0(FP), R0
137 // We're done using the stack.
138 // Alas, there's no reliable way to make this write atomic
139 // without potentially using the stack. So it goes.
140 MOVW $0, R1
141 MOVW R1, (R0)
142 MOVW $0, R0 // exit code
143 MOVW $SYS_exit, R7
144 SWI $0
145 MOVW $1234, R0
146 MOVW $1004, R1
147 MOVW R0, (R1) // fail hard
148 JMP 0(PC)
149
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700150TEXT runtime·gettid(SB),NOSPLIT,$0-4
151 MOVW $SYS_gettid, R7
152 SWI $0
153 MOVW R0, ret+0(FP)
154 RET
155
Dan Willemsenc7413322018-08-27 23:21:26 -0700156TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
Colin Crossd9c6b802019-03-19 21:10:31 -0700157 MOVW $SYS_getpid, R7
158 SWI $0
159 MOVW R0, R4
Brent Austinba3052e2015-04-21 16:08:23 -0700160 MOVW $SYS_gettid, R7
161 SWI $0
Colin Crossd9c6b802019-03-19 21:10:31 -0700162 MOVW R0, R1 // arg 2 tid
163 MOVW R4, R0 // arg 1 pid
164 MOVW sig+0(FP), R2 // arg 3
165 MOVW $SYS_tgkill, R7
Brent Austinba3052e2015-04-21 16:08:23 -0700166 SWI $0
167 RET
168
Dan Willemsenc7413322018-08-27 23:21:26 -0700169TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700170 MOVW $SYS_getpid, R7
171 SWI $0
172 // arg 1 tid already in R0 from getpid
173 MOVW sig+0(FP), R1 // arg 2 - signal
174 MOVW $SYS_kill, R7
175 SWI $0
176 RET
177
Patrice Arruda748609c2020-06-25 12:12:21 -0700178TEXT ·getpid(SB),NOSPLIT,$0-4
179 MOVW $SYS_getpid, R7
180 SWI $0
181 MOVW R0, ret+0(FP)
182 RET
183
184TEXT ·tgkill(SB),NOSPLIT,$0-12
185 MOVW tgid+0(FP), R0
186 MOVW tid+4(FP), R1
187 MOVW sig+8(FP), R2
188 MOVW $SYS_tgkill, R7
189 SWI $0
190 RET
191
Brent Austinba3052e2015-04-21 16:08:23 -0700192TEXT runtime·mmap(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700193 MOVW addr+0(FP), R0
194 MOVW n+4(FP), R1
195 MOVW prot+8(FP), R2
196 MOVW flags+12(FP), R3
197 MOVW fd+16(FP), R4
198 MOVW off+20(FP), R5
Brent Austinba3052e2015-04-21 16:08:23 -0700199 MOVW $SYS_mmap2, R7
200 SWI $0
201 MOVW $0xfffff001, R6
202 CMP R6, R0
Dan Willemsena3223282018-02-27 19:41:43 -0800203 MOVW $0, R1
Brent Austinba3052e2015-04-21 16:08:23 -0700204 RSB.HI $0, R0
Dan Willemsena3223282018-02-27 19:41:43 -0800205 MOVW.HI R0, R1 // if error, put in R1
206 MOVW.HI $0, R0
207 MOVW R0, p+24(FP)
208 MOVW R1, err+28(FP)
Brent Austinba3052e2015-04-21 16:08:23 -0700209 RET
210
211TEXT runtime·munmap(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700212 MOVW addr+0(FP), R0
213 MOVW n+4(FP), R1
Brent Austinba3052e2015-04-21 16:08:23 -0700214 MOVW $SYS_munmap, R7
215 SWI $0
216 MOVW $0xfffff001, R6
217 CMP R6, R0
218 MOVW.HI $0, R8 // crash on syscall failure
219 MOVW.HI R8, (R8)
220 RET
221
222TEXT runtime·madvise(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700223 MOVW addr+0(FP), R0
224 MOVW n+4(FP), R1
225 MOVW flags+8(FP), R2
Brent Austinba3052e2015-04-21 16:08:23 -0700226 MOVW $SYS_madvise, R7
227 SWI $0
Colin Crossd9c6b802019-03-19 21:10:31 -0700228 MOVW R0, ret+12(FP)
Brent Austinba3052e2015-04-21 16:08:23 -0700229 RET
230
231TEXT runtime·setitimer(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700232 MOVW mode+0(FP), R0
233 MOVW new+4(FP), R1
234 MOVW old+8(FP), R2
Brent Austinba3052e2015-04-21 16:08:23 -0700235 MOVW $SYS_setitimer, R7
236 SWI $0
237 RET
238
Dan Willemsenbc60c3c2021-12-15 01:09:00 -0800239TEXT runtime·timer_create(SB),NOSPLIT,$0-16
240 MOVW clockid+0(FP), R0
241 MOVW sevp+4(FP), R1
242 MOVW timerid+8(FP), R2
243 MOVW $SYS_timer_create, R7
244 SWI $0
245 MOVW R0, ret+12(FP)
246 RET
247
248TEXT runtime·timer_settime(SB),NOSPLIT,$0-20
249 MOVW timerid+0(FP), R0
250 MOVW flags+4(FP), R1
251 MOVW new+8(FP), R2
252 MOVW old+12(FP), R3
253 MOVW $SYS_timer_settime, R7
254 SWI $0
255 MOVW R0, ret+16(FP)
256 RET
257
258TEXT runtime·timer_delete(SB),NOSPLIT,$0-8
259 MOVW timerid+0(FP), R0
260 MOVW $SYS_timer_delete, R7
261 SWI $0
262 MOVW R0, ret+4(FP)
263 RET
264
Brent Austinba3052e2015-04-21 16:08:23 -0700265TEXT runtime·mincore(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700266 MOVW addr+0(FP), R0
267 MOVW n+4(FP), R1
268 MOVW dst+8(FP), R2
Brent Austinba3052e2015-04-21 16:08:23 -0700269 MOVW $SYS_mincore, R7
270 SWI $0
271 MOVW R0, ret+12(FP)
272 RET
273
Dan Willemsencc753b72021-08-31 13:25:42 -0700274TEXT runtime·walltime(SB),NOSPLIT,$8-12
Dan Willemsenc7413322018-08-27 23:21:26 -0700275 // We don't know how much stack space the VDSO code will need,
276 // so switch to g0.
277
278 // Save old SP. Use R13 instead of SP to avoid linker rewriting the offsets.
279 MOVW R13, R4 // R4 is unchanged by C code.
280
281 MOVW g_m(g), R5 // R5 is unchanged by C code.
282
283 // Set vdsoPC and vdsoSP for SIGPROF traceback.
Patrice Arruda7e580222020-08-12 13:34:23 -0700284 // Save the old values on stack and restore them on exit,
285 // so this function is reentrant.
286 MOVW m_vdsoPC(R5), R1
287 MOVW m_vdsoSP(R5), R2
288 MOVW R1, 4(R13)
289 MOVW R2, 8(R13)
290
Dan Willemsenbc60c3c2021-12-15 01:09:00 -0800291 MOVW $ret-4(FP), R2 // caller's SP
Dan Willemsenc7413322018-08-27 23:21:26 -0700292 MOVW LR, m_vdsoPC(R5)
Dan Willemsenbc60c3c2021-12-15 01:09:00 -0800293 MOVW R2, m_vdsoSP(R5)
Dan Willemsenc7413322018-08-27 23:21:26 -0700294
295 MOVW m_curg(R5), R0
296
297 CMP g, R0 // Only switch if on curg.
298 B.NE noswitch
299
300 MOVW m_g0(R5), R0
301 MOVW (g_sched+gobuf_sp)(R0), R13 // Set SP to g0 stack
302
303noswitch:
304 SUB $24, R13 // Space for results
305 BIC $0x7, R13 // Align for C code
306
307 MOVW $CLOCK_REALTIME, R0
308 MOVW $8(R13), R1 // timespec
Patrice Arruda748609c2020-06-25 12:12:21 -0700309 MOVW runtime·vdsoClockgettimeSym(SB), R2
310 CMP $0, R2
Dan Willemsenc7413322018-08-27 23:21:26 -0700311 B.EQ fallback
312
Patrice Arruda748609c2020-06-25 12:12:21 -0700313 // Store g on gsignal's stack, so if we receive a signal
314 // during VDSO code we can find the g.
315 // If we don't have a signal stack, we won't receive signal,
316 // so don't bother saving g.
317 // When using cgo, we already saved g on TLS, also don't save
318 // g here.
319 // Also don't save g if we are already on the signal stack.
320 // We won't get a nested signal.
321 MOVB runtime·iscgo(SB), R6
322 CMP $0, R6
323 BNE nosaveg
324 MOVW m_gsignal(R5), R6 // g.m.gsignal
325 CMP $0, R6
326 BEQ nosaveg
327 CMP g, R6
328 BEQ nosaveg
329 MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
330 MOVW g, (R6)
331
332 BL (R2)
333
334 MOVW $0, R1
335 MOVW R1, (R6) // clear g slot, R6 is unchanged by C code
336
337 JMP finish
338
339nosaveg:
340 BL (R2)
Dan Willemsenc7413322018-08-27 23:21:26 -0700341 JMP finish
342
343fallback:
Brent Austinba3052e2015-04-21 16:08:23 -0700344 MOVW $SYS_clock_gettime, R7
345 SWI $0
Dan Willemsenc7413322018-08-27 23:21:26 -0700346
347finish:
Brent Austinba3052e2015-04-21 16:08:23 -0700348 MOVW 8(R13), R0 // sec
349 MOVW 12(R13), R2 // nsec
Dan Willemsenc7413322018-08-27 23:21:26 -0700350
351 MOVW R4, R13 // Restore real SP
Patrice Arruda7e580222020-08-12 13:34:23 -0700352 // Restore vdsoPC, vdsoSP
353 // We don't worry about being signaled between the two stores.
354 // If we are not in a signal handler, we'll restore vdsoSP to 0,
355 // and no one will care about vdsoPC. If we are in a signal handler,
356 // we cannot receive another signal.
357 MOVW 8(R13), R1
Dan Willemsenc7413322018-08-27 23:21:26 -0700358 MOVW R1, m_vdsoSP(R5)
Patrice Arruda7e580222020-08-12 13:34:23 -0700359 MOVW 4(R13), R1
360 MOVW R1, m_vdsoPC(R5)
Dan Willemsenc7413322018-08-27 23:21:26 -0700361
362 MOVW R0, sec_lo+0(FP)
Dan Willemsenbc60c3c2021-12-15 01:09:00 -0800363 MOVW $0, R1
Dan Willemsend2797482017-07-26 13:13:13 -0700364 MOVW R1, sec_hi+4(FP)
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700365 MOVW R2, nsec+8(FP)
Dan Willemsenc7413322018-08-27 23:21:26 -0700366 RET
Brent Austinba3052e2015-04-21 16:08:23 -0700367
Patrice Arruda748609c2020-06-25 12:12:21 -0700368// int64 nanotime1(void)
Patrice Arruda7e580222020-08-12 13:34:23 -0700369TEXT runtime·nanotime1(SB),NOSPLIT,$8-8
Dan Willemsenc7413322018-08-27 23:21:26 -0700370 // Switch to g0 stack. See comment above in runtime·walltime.
371
372 // Save old SP. Use R13 instead of SP to avoid linker rewriting the offsets.
373 MOVW R13, R4 // R4 is unchanged by C code.
374
375 MOVW g_m(g), R5 // R5 is unchanged by C code.
376
377 // Set vdsoPC and vdsoSP for SIGPROF traceback.
Patrice Arruda7e580222020-08-12 13:34:23 -0700378 // Save the old values on stack and restore them on exit,
379 // so this function is reentrant.
380 MOVW m_vdsoPC(R5), R1
381 MOVW m_vdsoSP(R5), R2
382 MOVW R1, 4(R13)
383 MOVW R2, 8(R13)
384
Dan Willemsenbc60c3c2021-12-15 01:09:00 -0800385 MOVW $ret-4(FP), R2 // caller's SP
Dan Willemsenc7413322018-08-27 23:21:26 -0700386 MOVW LR, m_vdsoPC(R5)
Dan Willemsenbc60c3c2021-12-15 01:09:00 -0800387 MOVW R2, m_vdsoSP(R5)
Dan Willemsenc7413322018-08-27 23:21:26 -0700388
389 MOVW m_curg(R5), R0
390
391 CMP g, R0 // Only switch if on curg.
392 B.NE noswitch
393
394 MOVW m_g0(R5), R0
395 MOVW (g_sched+gobuf_sp)(R0), R13 // Set SP to g0 stack
396
397noswitch:
398 SUB $24, R13 // Space for results
399 BIC $0x7, R13 // Align for C code
400
401 MOVW $CLOCK_MONOTONIC, R0
402 MOVW $8(R13), R1 // timespec
Patrice Arruda748609c2020-06-25 12:12:21 -0700403 MOVW runtime·vdsoClockgettimeSym(SB), R2
404 CMP $0, R2
Dan Willemsenc7413322018-08-27 23:21:26 -0700405 B.EQ fallback
406
Patrice Arruda748609c2020-06-25 12:12:21 -0700407 // Store g on gsignal's stack, so if we receive a signal
408 // during VDSO code we can find the g.
409 // If we don't have a signal stack, we won't receive signal,
410 // so don't bother saving g.
411 // When using cgo, we already saved g on TLS, also don't save
412 // g here.
413 // Also don't save g if we are already on the signal stack.
414 // We won't get a nested signal.
415 MOVB runtime·iscgo(SB), R6
416 CMP $0, R6
417 BNE nosaveg
418 MOVW m_gsignal(R5), R6 // g.m.gsignal
419 CMP $0, R6
420 BEQ nosaveg
421 CMP g, R6
422 BEQ nosaveg
423 MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
424 MOVW g, (R6)
425
426 BL (R2)
427
428 MOVW $0, R1
429 MOVW R1, (R6) // clear g slot, R6 is unchanged by C code
430
431 JMP finish
432
433nosaveg:
434 BL (R2)
Dan Willemsenc7413322018-08-27 23:21:26 -0700435 JMP finish
436
437fallback:
Brent Austinba3052e2015-04-21 16:08:23 -0700438 MOVW $SYS_clock_gettime, R7
439 SWI $0
Dan Willemsenc7413322018-08-27 23:21:26 -0700440
441finish:
442 MOVW 8(R13), R0 // sec
443 MOVW 12(R13), R2 // nsec
444
445 MOVW R4, R13 // Restore real SP
Patrice Arruda7e580222020-08-12 13:34:23 -0700446 // Restore vdsoPC, vdsoSP
447 // We don't worry about being signaled between the two stores.
448 // If we are not in a signal handler, we'll restore vdsoSP to 0,
449 // and no one will care about vdsoPC. If we are in a signal handler,
450 // we cannot receive another signal.
451 MOVW 8(R13), R4
Dan Willemsenc7413322018-08-27 23:21:26 -0700452 MOVW R4, m_vdsoSP(R5)
Patrice Arruda7e580222020-08-12 13:34:23 -0700453 MOVW 4(R13), R4
454 MOVW R4, m_vdsoPC(R5)
Dan Willemsenc7413322018-08-27 23:21:26 -0700455
Brent Austinba3052e2015-04-21 16:08:23 -0700456 MOVW $1000000000, R3
457 MULLU R0, R3, (R1, R0)
Brent Austinba3052e2015-04-21 16:08:23 -0700458 ADD.S R2, R0
Dan Willemsenbc60c3c2021-12-15 01:09:00 -0800459 ADC $0, R1 // Add carry bit to upper half.
Brent Austinba3052e2015-04-21 16:08:23 -0700460
461 MOVW R0, ret_lo+0(FP)
462 MOVW R1, ret_hi+4(FP)
463 RET
464
465// int32 futex(int32 *uaddr, int32 op, int32 val,
466// struct timespec *timeout, int32 *uaddr2, int32 val2);
467TEXT runtime·futex(SB),NOSPLIT,$0
Dan Willemsenebae3022017-01-13 23:01:08 -0800468 MOVW addr+0(FP), R0
469 MOVW op+4(FP), R1
470 MOVW val+8(FP), R2
471 MOVW ts+12(FP), R3
472 MOVW addr2+16(FP), R4
473 MOVW val3+20(FP), R5
Brent Austinba3052e2015-04-21 16:08:23 -0700474 MOVW $SYS_futex, R7
475 SWI $0
476 MOVW R0, ret+24(FP)
477 RET
478
Brent Austinba3052e2015-04-21 16:08:23 -0700479// int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
480TEXT runtime·clone(SB),NOSPLIT,$0
481 MOVW flags+0(FP), R0
482 MOVW stk+4(FP), R1
483 MOVW $0, R2 // parent tid ptr
484 MOVW $0, R3 // tls_val
485 MOVW $0, R4 // child tid ptr
486 MOVW $0, R5
487
488 // Copy mp, gp, fn off parent stack for use by child.
Brent Austinba3052e2015-04-21 16:08:23 -0700489 MOVW $-16(R1), R1
Dan Willemsenebae3022017-01-13 23:01:08 -0800490 MOVW mp+8(FP), R6
Brent Austinba3052e2015-04-21 16:08:23 -0700491 MOVW R6, 0(R1)
Dan Willemsenebae3022017-01-13 23:01:08 -0800492 MOVW gp+12(FP), R6
Brent Austinba3052e2015-04-21 16:08:23 -0700493 MOVW R6, 4(R1)
494 MOVW fn+16(FP), R6
495 MOVW R6, 8(R1)
496 MOVW $1234, R6
497 MOVW R6, 12(R1)
498
499 MOVW $SYS_clone, R7
500 SWI $0
501
502 // In parent, return.
503 CMP $0, R0
504 BEQ 3(PC)
505 MOVW R0, ret+20(FP)
506 RET
507
508 // Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup'
Colin Cross430342c2019-09-07 08:36:04 -0700509 NOP R13 // tell vet SP/R13 changed - stop checking offsets
Brent Austinba3052e2015-04-21 16:08:23 -0700510 MOVW 12(R13), R0
511 MOVW $1234, R1
512 CMP R0, R1
513 BEQ 2(PC)
514 BL runtime·abort(SB)
515
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700516 MOVW 0(R13), R8 // m
517 MOVW 4(R13), R0 // g
518
519 CMP $0, R8
520 BEQ nog
521 CMP $0, R0
522 BEQ nog
523
524 MOVW R0, g
Brent Austinba3052e2015-04-21 16:08:23 -0700525 MOVW R8, g_m(g)
526
527 // paranoia; check they are not nil
528 MOVW 0(R8), R0
529 MOVW 0(g), R0
530
531 BL runtime·emptyfunc(SB) // fault if stack check is wrong
532
533 // Initialize m->procid to Linux tid
534 MOVW $SYS_gettid, R7
535 SWI $0
536 MOVW g_m(g), R8
537 MOVW R0, m_procid(R8)
538
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700539nog:
Brent Austinba3052e2015-04-21 16:08:23 -0700540 // Call fn
541 MOVW 8(R13), R0
542 MOVW $16(R13), R13
543 BL (R0)
544
Dan Willemsen38f2dba2016-07-08 14:54:35 -0700545 // It shouldn't return. If it does, exit that thread.
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700546 SUB $16, R13 // restore the stack pointer to avoid memory corruption
Brent Austinba3052e2015-04-21 16:08:23 -0700547 MOVW $0, R0
548 MOVW R0, 4(R13)
Dan Willemsena3223282018-02-27 19:41:43 -0800549 BL exit1<>(SB)
Brent Austinba3052e2015-04-21 16:08:23 -0700550
Brent Austinba3052e2015-04-21 16:08:23 -0700551 MOVW $1234, R0
552 MOVW $1005, R1
553 MOVW R0, (R1)
554
555TEXT runtime·sigaltstack(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700556 MOVW new+0(FP), R0
557 MOVW old+4(FP), R1
Brent Austinba3052e2015-04-21 16:08:23 -0700558 MOVW $SYS_sigaltstack, R7
559 SWI $0
560 MOVW $0xfffff001, R6
561 CMP R6, R0
562 MOVW.HI $0, R8 // crash on syscall failure
563 MOVW.HI R8, (R8)
564 RET
565
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700566TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
567 MOVW sig+4(FP), R0
568 MOVW info+8(FP), R1
569 MOVW ctx+12(FP), R2
570 MOVW fn+0(FP), R11
Dan Willemsen38f2dba2016-07-08 14:54:35 -0700571 MOVW R13, R4
572 SUB $24, R13
573 BIC $0x7, R13 // alignment for ELF ABI
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700574 BL (R11)
Dan Willemsen38f2dba2016-07-08 14:54:35 -0700575 MOVW R4, R13
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700576 RET
577
Patrice Arruda748609c2020-06-25 12:12:21 -0700578TEXT runtime·sigtramp(SB),NOSPLIT,$0
579 // Reserve space for callee-save registers and arguments.
580 MOVM.DB.W [R4-R11], (R13)
581 SUB $16, R13
582
Brent Austinba3052e2015-04-21 16:08:23 -0700583 // this might be called in external code context,
584 // where g is not set.
585 // first save R0, because runtime·load_g will clobber it
586 MOVW R0, 4(R13)
587 MOVB runtime·iscgo(SB), R0
588 CMP $0, R0
589 BL.NE runtime·load_g(SB)
590
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700591 MOVW R1, 8(R13)
592 MOVW R2, 12(R13)
593 MOVW $runtime·sigtrampgo(SB), R11
Brent Austinba3052e2015-04-21 16:08:23 -0700594 BL (R11)
Patrice Arruda748609c2020-06-25 12:12:21 -0700595
596 // Restore callee-save registers.
597 ADD $16, R13
598 MOVM.IA.W (R13), [R4-R11]
599
Brent Austinba3052e2015-04-21 16:08:23 -0700600 RET
601
Dan Willemsen38f2dba2016-07-08 14:54:35 -0700602TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
603 MOVW $runtime·sigtramp(SB), R11
604 B (R11)
605
Brent Austinba3052e2015-04-21 16:08:23 -0700606TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
Dan Willemsenebae3022017-01-13 23:01:08 -0800607 MOVW how+0(FP), R0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700608 MOVW new+4(FP), R1
609 MOVW old+8(FP), R2
610 MOVW size+12(FP), R3
Brent Austinba3052e2015-04-21 16:08:23 -0700611 MOVW $SYS_rt_sigprocmask, R7
612 SWI $0
613 RET
614
615TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700616 MOVW sig+0(FP), R0
617 MOVW new+4(FP), R1
618 MOVW old+8(FP), R2
619 MOVW size+12(FP), R3
Brent Austinba3052e2015-04-21 16:08:23 -0700620 MOVW $SYS_rt_sigaction, R7
621 SWI $0
622 MOVW R0, ret+16(FP)
623 RET
624
625TEXT runtime·usleep(SB),NOSPLIT,$12
626 MOVW usec+0(FP), R0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700627 CALL runtime·usplitR0(SB)
628 MOVW R0, 4(R13)
Dan Willemsend2797482017-07-26 13:13:13 -0700629 MOVW $1000, R0 // usec to nsec
630 MUL R0, R1
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700631 MOVW R1, 8(R13)
Dan Willemsenc7413322018-08-27 23:21:26 -0700632 MOVW $4(R13), R0
Brent Austinba3052e2015-04-21 16:08:23 -0700633 MOVW $0, R1
Dan Willemsenc7413322018-08-27 23:21:26 -0700634 MOVW $SYS_nanosleep, R7
Brent Austinba3052e2015-04-21 16:08:23 -0700635 SWI $0
636 RET
637
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700638// As for cas, memory barriers are complicated on ARM, but the kernel
639// provides a user helper. ARMv5 does not support SMP and has no
640// memory barrier instruction at all. ARMv6 added SMP support and has
641// a memory barrier, but it requires writing to a coprocessor
642// register. ARMv7 introduced the DMB instruction, but it's expensive
643// even on single-core devices. The kernel helper takes care of all of
644// this for us.
645
Dan Willemsenc7413322018-08-27 23:21:26 -0700646TEXT kernelPublicationBarrier<>(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700647 // void __kuser_memory_barrier(void);
Dan Willemsenc7413322018-08-27 23:21:26 -0700648 MOVW $0xffff0fa0, R11
649 CALL (R11)
650 RET
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700651
652TEXT ·publicationBarrier(SB),NOSPLIT,$0
Dan Willemsenc7413322018-08-27 23:21:26 -0700653 MOVB ·goarm(SB), R11
654 CMP $7, R11
655 BLT 2(PC)
656 JMP ·armPublicationBarrier(SB)
657 JMP kernelPublicationBarrier<>(SB) // extra layer so this function is leaf and no SP adjustment on GOARM=7
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700658
Brent Austinba3052e2015-04-21 16:08:23 -0700659TEXT runtime·osyield(SB),NOSPLIT,$0
660 MOVW $SYS_sched_yield, R7
661 SWI $0
662 RET
663
664TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700665 MOVW pid+0(FP), R0
666 MOVW len+4(FP), R1
667 MOVW buf+8(FP), R2
Brent Austinba3052e2015-04-21 16:08:23 -0700668 MOVW $SYS_sched_getaffinity, R7
669 SWI $0
670 MOVW R0, ret+12(FP)
671 RET
672
673// int32 runtime·epollcreate(int32 size)
674TEXT runtime·epollcreate(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700675 MOVW size+0(FP), R0
Brent Austinba3052e2015-04-21 16:08:23 -0700676 MOVW $SYS_epoll_create, R7
677 SWI $0
678 MOVW R0, ret+4(FP)
679 RET
680
681// int32 runtime·epollcreate1(int32 flags)
682TEXT runtime·epollcreate1(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700683 MOVW flags+0(FP), R0
Brent Austinba3052e2015-04-21 16:08:23 -0700684 MOVW $SYS_epoll_create1, R7
685 SWI $0
686 MOVW R0, ret+4(FP)
687 RET
688
689// func epollctl(epfd, op, fd int32, ev *epollEvent) int
690TEXT runtime·epollctl(SB),NOSPLIT,$0
691 MOVW epfd+0(FP), R0
692 MOVW op+4(FP), R1
693 MOVW fd+8(FP), R2
694 MOVW ev+12(FP), R3
695 MOVW $SYS_epoll_ctl, R7
696 SWI $0
697 MOVW R0, ret+16(FP)
698 RET
699
700// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout)
701TEXT runtime·epollwait(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700702 MOVW epfd+0(FP), R0
703 MOVW ev+4(FP), R1
704 MOVW nev+8(FP), R2
705 MOVW timeout+12(FP), R3
Brent Austinba3052e2015-04-21 16:08:23 -0700706 MOVW $SYS_epoll_wait, R7
707 SWI $0
708 MOVW R0, ret+16(FP)
709 RET
710
711// void runtime·closeonexec(int32 fd)
712TEXT runtime·closeonexec(SB),NOSPLIT,$0
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700713 MOVW fd+0(FP), R0 // fd
Brent Austinba3052e2015-04-21 16:08:23 -0700714 MOVW $2, R1 // F_SETFD
715 MOVW $1, R2 // FD_CLOEXEC
716 MOVW $SYS_fcntl, R7
717 SWI $0
718 RET
719
Patrice Arruda748609c2020-06-25 12:12:21 -0700720// func runtime·setNonblock(fd int32)
721TEXT runtime·setNonblock(SB),NOSPLIT,$0-4
722 MOVW fd+0(FP), R0 // fd
723 MOVW $3, R1 // F_GETFL
724 MOVW $0, R2
725 MOVW $SYS_fcntl, R7
726 SWI $0
727 ORR $0x800, R0, R2 // O_NONBLOCK
728 MOVW fd+0(FP), R0 // fd
729 MOVW $4, R1 // F_SETFL
730 MOVW $SYS_fcntl, R7
731 SWI $0
732 RET
733
Brent Austinba3052e2015-04-21 16:08:23 -0700734// b __kuser_get_tls @ 0xffff0fe0
Dan Willemsenc7413322018-08-27 23:21:26 -0700735TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
Brent Austinba3052e2015-04-21 16:08:23 -0700736 MOVW $0xffff0fe0, R0
737 B (R0)
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700738
739TEXT runtime·access(SB),NOSPLIT,$0
740 MOVW name+0(FP), R0
741 MOVW mode+4(FP), R1
742 MOVW $SYS_access, R7
743 SWI $0
744 MOVW R0, ret+8(FP)
745 RET
746
747TEXT runtime·connect(SB),NOSPLIT,$0
748 MOVW fd+0(FP), R0
749 MOVW addr+4(FP), R1
Dan Willemsenebae3022017-01-13 23:01:08 -0800750 MOVW len+8(FP), R2
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700751 MOVW $SYS_connect, R7
752 SWI $0
753 MOVW R0, ret+12(FP)
754 RET
755
756TEXT runtime·socket(SB),NOSPLIT,$0
757 MOVW domain+0(FP), R0
Dan Willemsenebae3022017-01-13 23:01:08 -0800758 MOVW typ+4(FP), R1
759 MOVW prot+8(FP), R2
Dan Willemsen09eb3b12015-09-16 14:34:17 -0700760 MOVW $SYS_socket, R7
761 SWI $0
762 MOVW R0, ret+12(FP)
763 RET
Dan Willemsend2797482017-07-26 13:13:13 -0700764
765// func sbrk0() uintptr
766TEXT runtime·sbrk0(SB),NOSPLIT,$0-4
767 // Implemented as brk(NULL).
768 MOVW $0, R0
769 MOVW $SYS_brk, R7
770 SWI $0
771 MOVW R0, ret+0(FP)
772 RET
Colin Cross430342c2019-09-07 08:36:04 -0700773
774TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
775 RET