1// 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// System calls and other sys.stuff for ARM, OpenBSD
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#define CLOCK_REALTIME	$0
14#define	CLOCK_MONOTONIC	$3
15
16// Exit the entire program (like C exit)
17TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
18	MOVW	code+0(FP), R0	// arg 1 - status
19	MOVW	$1, R12			// sys_exit
20	SWI	$0
21	MOVW.CS	$0, R8			// crash on syscall failure
22	MOVW.CS	R8, (R8)
23	RET
24
25// func exitThread(wait *uint32)
26TEXT runtime·exitThread(SB),NOSPLIT,$0-4
27	MOVW	wait+0(FP), R0		// arg 1 - notdead
28	MOVW	$302, R12		// sys___threxit
29	SWI	$0
30	MOVW.CS	$1, R8			// crash on syscall failure
31	MOVW.CS	R8, (R8)
32	JMP	0(PC)
33
34TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0
35	MOVW	name+0(FP), R0		// arg 1 - path
36	MOVW	mode+4(FP), R1		// arg 2 - mode
37	MOVW	perm+8(FP), R2		// arg 3 - perm
38	MOVW	$5, R12			// sys_open
39	SWI	$0
40	MOVW.CS	$-1, R0
41	MOVW	R0, ret+12(FP)
42	RET
43
44TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0
45	MOVW	fd+0(FP), R0		// arg 1 - fd
46	MOVW	$6, R12			// sys_close
47	SWI	$0
48	MOVW.CS	$-1, R0
49	MOVW	R0, ret+4(FP)
50	RET
51
52TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0
53	MOVW	fd+0(FP), R0		// arg 1 - fd
54	MOVW	p+4(FP), R1		// arg 2 - buf
55	MOVW	n+8(FP), R2		// arg 3 - nbyte
56	MOVW	$3, R12			// sys_read
57	SWI	$0
58	RSB.CS	$0, R0		// caller expects negative errno
59	MOVW	R0, ret+12(FP)
60	RET
61
62// func pipe() (r, w int32, errno int32)
63TEXT runtime·pipe(SB),NOSPLIT,$0-12
64	MOVW	$r+0(FP), R0
65	MOVW	$263, R12
66	SWI	$0
67	MOVW	R0, errno+8(FP)
68	RET
69
70// func pipe2(flags int32) (r, w int32, errno int32)
71TEXT runtime·pipe2(SB),NOSPLIT,$0-16
72	MOVW	$r+4(FP), R0
73	MOVW	flags+0(FP), R1
74	MOVW	$101, R12
75	SWI	$0
76	MOVW	R0, errno+12(FP)
77	RET
78
79TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0
80	MOVW	fd+0(FP), R0		// arg 1 - fd
81	MOVW	p+4(FP), R1		// arg 2 - buf
82	MOVW	n+8(FP), R2		// arg 3 - nbyte
83	MOVW	$4, R12			// sys_write
84	SWI	$0
85	RSB.CS	$0, R0		// caller expects negative errno
86	MOVW	R0, ret+12(FP)
87	RET
88
89TEXT runtime·usleep(SB),NOSPLIT,$16
90	MOVW	usec+0(FP), R0
91	CALL	runtime·usplitR0(SB)
92	MOVW	R0, 4(R13)		// tv_sec - l32
93	MOVW	$0, R0
94	MOVW	R0, 8(R13)		// tv_sec - h32
95	MOVW	$1000, R2
96	MUL	R1, R2
97	MOVW	R2, 12(R13)		// tv_nsec
98
99	MOVW	$4(R13), R0		// arg 1 - rqtp
100	MOVW	$0, R1			// arg 2 - rmtp
101	MOVW	$91, R12		// sys_nanosleep
102	SWI	$0
103	RET
104
105TEXT runtime·getthrid(SB),NOSPLIT,$0-4
106	MOVW	$299, R12		// sys_getthrid
107	SWI	$0
108	MOVW	R0, ret+0(FP)
109	RET
110
111TEXT runtime·thrkill(SB),NOSPLIT,$0-8
112	MOVW	tid+0(FP), R0		// arg 1 - tid
113	MOVW	sig+4(FP), R1		// arg 2 - signum
114	MOVW	$0, R2			// arg 3 - tcb
115	MOVW	$119, R12		// sys_thrkill
116	SWI	$0
117	RET
118
119TEXT runtime·raiseproc(SB),NOSPLIT,$12
120	MOVW	$20, R12
121	SWI	$0			// sys_getpid
122					// arg 1 - pid, already in R0
123	MOVW	sig+0(FP), R1		// arg 2 - signum
124	MOVW	$122, R12		// sys_kill
125	SWI	$0
126	RET
127
128TEXT runtime·mmap(SB),NOSPLIT,$16
129	MOVW	addr+0(FP), R0		// arg 1 - addr
130	MOVW	n+4(FP), R1		// arg 2 - len
131	MOVW	prot+8(FP), R2		// arg 3 - prot
132	MOVW	flags+12(FP), R3	// arg 4 - flags
133	MOVW	fd+16(FP), R4		// arg 5 - fd (on stack)
134	MOVW	R4, 4(R13)
135	MOVW	$0, R5			// arg 6 - pad (on stack)
136	MOVW	R5, 8(R13)
137	MOVW	off+20(FP), R6		// arg 7 - offset (on stack)
138	MOVW	R6, 12(R13)		// lower 32 bits (from Go runtime)
139	MOVW	$0, R7
140	MOVW	R7, 16(R13)		// high 32 bits
141	ADD	$4, R13
142	MOVW	$197, R12		// sys_mmap
143	SWI	$0
144	SUB	$4, R13
145	MOVW	$0, R1
146	MOVW.CS	R0, R1			// if error, move to R1
147	MOVW.CS $0, R0
148	MOVW	R0, p+24(FP)
149	MOVW	R1, err+28(FP)
150	RET
151
152TEXT runtime·munmap(SB),NOSPLIT,$0
153	MOVW	addr+0(FP), R0		// arg 1 - addr
154	MOVW	n+4(FP), R1		// arg 2 - len
155	MOVW	$73, R12		// sys_munmap
156	SWI	$0
157	MOVW.CS	$0, R8			// crash on syscall failure
158	MOVW.CS	R8, (R8)
159	RET
160
161TEXT runtime·madvise(SB),NOSPLIT,$0
162	MOVW	addr+0(FP), R0		// arg 1 - addr
163	MOVW	n+4(FP), R1		// arg 2 - len
164	MOVW	flags+8(FP), R2		// arg 2 - flags
165	MOVW	$75, R12		// sys_madvise
166	SWI	$0
167	MOVW.CS	$-1, R0
168	MOVW	R0, ret+12(FP)
169	RET
170
171TEXT runtime·setitimer(SB),NOSPLIT,$0
172	MOVW	mode+0(FP), R0		// arg 1 - mode
173	MOVW	new+4(FP), R1		// arg 2 - new value
174	MOVW	old+8(FP), R2		// arg 3 - old value
175	MOVW	$69, R12		// sys_setitimer
176	SWI	$0
177	RET
178
179// func walltime1() (sec int64, nsec int32)
180TEXT runtime·walltime1(SB), NOSPLIT, $32
181	MOVW	CLOCK_REALTIME, R0	// arg 1 - clock_id
182	MOVW	$8(R13), R1		// arg 2 - tp
183	MOVW	$87, R12		// sys_clock_gettime
184	SWI	$0
185
186	MOVW	8(R13), R0		// sec - l32
187	MOVW	12(R13), R1		// sec - h32
188	MOVW	16(R13), R2		// nsec
189
190	MOVW	R0, sec_lo+0(FP)
191	MOVW	R1, sec_hi+4(FP)
192	MOVW	R2, nsec+8(FP)
193
194	RET
195
196// int64 nanotime1(void) so really
197// void nanotime1(int64 *nsec)
198TEXT runtime·nanotime1(SB),NOSPLIT,$32
199	MOVW	CLOCK_MONOTONIC, R0	// arg 1 - clock_id
200	MOVW	$8(R13), R1		// arg 2 - tp
201	MOVW	$87, R12		// sys_clock_gettime
202	SWI	$0
203
204	MOVW	8(R13), R0		// sec - l32
205	MOVW	12(R13), R4		// sec - h32
206	MOVW	16(R13), R2		// nsec
207
208	MOVW	$1000000000, R3
209	MULLU	R0, R3, (R1, R0)
210	MUL	R3, R4
211	ADD.S	R2, R0
212	ADC	R4, R1
213
214	MOVW	R0, ret_lo+0(FP)
215	MOVW	R1, ret_hi+4(FP)
216	RET
217
218TEXT runtime·sigaction(SB),NOSPLIT,$0
219	MOVW	sig+0(FP), R0		// arg 1 - signum
220	MOVW	new+4(FP), R1		// arg 2 - new sigaction
221	MOVW	old+8(FP), R2		// arg 3 - old sigaction
222	MOVW	$46, R12		// sys_sigaction
223	SWI	$0
224	MOVW.CS	$3, R8			// crash on syscall failure
225	MOVW.CS	R8, (R8)
226	RET
227
228TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0
229	MOVW	how+0(FP), R0		// arg 1 - mode
230	MOVW	new+4(FP), R1		// arg 2 - new
231	MOVW	$48, R12		// sys_sigprocmask
232	SWI	$0
233	MOVW.CS	$3, R8			// crash on syscall failure
234	MOVW.CS	R8, (R8)
235	MOVW	R0, ret+8(FP)
236	RET
237
238TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
239	MOVW	sig+4(FP), R0
240	MOVW	info+8(FP), R1
241	MOVW	ctx+12(FP), R2
242	MOVW	fn+0(FP), R11
243	MOVW	R13, R4
244	SUB	$24, R13
245	BIC	$0x7, R13 // alignment for ELF ABI
246	BL	(R11)
247	MOVW	R4, R13
248	RET
249
250TEXT runtime·sigtramp(SB),NOSPLIT,$0
251	// Reserve space for callee-save registers and arguments.
252	MOVM.DB.W [R4-R11], (R13)
253	SUB	$16, R13
254
255	// If called from an external code context, g will not be set.
256	// Save R0, since runtime·load_g will clobber it.
257	MOVW	R0, 4(R13)		// signum
258	MOVB	runtime·iscgo(SB), R0
259	CMP	$0, R0
260	BL.NE	runtime·load_g(SB)
261
262	MOVW	R1, 8(R13)
263	MOVW	R2, 12(R13)
264	BL	runtime·sigtrampgo(SB)
265
266	// Restore callee-save registers.
267	ADD	$16, R13
268	MOVM.IA.W (R13), [R4-R11]
269
270	RET
271
272// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
273TEXT runtime·tfork(SB),NOSPLIT,$0
274
275	// Copy mp, gp and fn off parent stack for use by child.
276	MOVW	mm+8(FP), R4
277	MOVW	gg+12(FP), R5
278	MOVW	fn+16(FP), R6
279
280	MOVW	param+0(FP), R0		// arg 1 - param
281	MOVW	psize+4(FP), R1		// arg 2 - psize
282	MOVW	$8, R12			// sys___tfork
283	SWI	$0
284
285	// Return if syscall failed.
286	B.CC	4(PC)
287	RSB	$0, R0
288	MOVW	R0, ret+20(FP)
289	RET
290
291	// In parent, return.
292	CMP	$0, R0
293	BEQ	3(PC)
294	MOVW	R0, ret+20(FP)
295	RET
296
297	// Initialise m, g.
298	MOVW	R5, g
299	MOVW	R4, g_m(g)
300
301	// Paranoia; check that stack splitting code works.
302	BL	runtime·emptyfunc(SB)
303
304	// Call fn.
305	BL	(R6)
306
307	// fn should never return.
308	MOVW	$2, R8			// crash if reached
309	MOVW	R8, (R8)
310	RET
311
312TEXT runtime·sigaltstack(SB),NOSPLIT,$0
313	MOVW	new+0(FP), R0		// arg 1 - new sigaltstack
314	MOVW	old+4(FP), R1		// arg 2 - old sigaltstack
315	MOVW	$288, R12		// sys_sigaltstack
316	SWI	$0
317	MOVW.CS	$0, R8			// crash on syscall failure
318	MOVW.CS	R8, (R8)
319	RET
320
321TEXT runtime·osyield(SB),NOSPLIT,$0
322	MOVW	$298, R12		// sys_sched_yield
323	SWI	$0
324	RET
325
326TEXT runtime·thrsleep(SB),NOSPLIT,$4
327	MOVW	ident+0(FP), R0		// arg 1 - ident
328	MOVW	clock_id+4(FP), R1	// arg 2 - clock_id
329	MOVW	tsp+8(FP), R2		// arg 3 - tsp
330	MOVW	lock+12(FP), R3		// arg 4 - lock
331	MOVW	abort+16(FP), R4	// arg 5 - abort (on stack)
332	MOVW	R4, 4(R13)
333	ADD	$4, R13
334	MOVW	$94, R12		// sys___thrsleep
335	SWI	$0
336	SUB	$4, R13
337	MOVW	R0, ret+20(FP)
338	RET
339
340TEXT runtime·thrwakeup(SB),NOSPLIT,$0
341	MOVW	ident+0(FP), R0		// arg 1 - ident
342	MOVW	n+4(FP), R1		// arg 2 - n
343	MOVW	$301, R12		// sys___thrwakeup
344	SWI	$0
345	MOVW	R0, ret+8(FP)
346	RET
347
348TEXT runtime·sysctl(SB),NOSPLIT,$8
349	MOVW	mib+0(FP), R0		// arg 1 - mib
350	MOVW	miblen+4(FP), R1	// arg 2 - miblen
351	MOVW	out+8(FP), R2		// arg 3 - out
352	MOVW	size+12(FP), R3		// arg 4 - size
353	MOVW	dst+16(FP), R4		// arg 5 - dest (on stack)
354	MOVW	R4, 4(R13)
355	MOVW	ndst+20(FP), R5		// arg 6 - newlen (on stack)
356	MOVW	R5, 8(R13)
357	ADD	$4, R13
358	MOVW	$202, R12		// sys___sysctl
359	SWI	$0
360	SUB	$4, R13
361	MOVW.CC	$0, R0
362	RSB.CS	$0, R0
363	MOVW	R0, ret+24(FP)
364	RET
365
366// int32 runtime·kqueue(void);
367TEXT runtime·kqueue(SB),NOSPLIT,$0
368	MOVW	$269, R12		// sys_kqueue
369	SWI	$0
370	RSB.CS	$0, R0
371	MOVW	R0, ret+0(FP)
372	RET
373
374// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
375TEXT runtime·kevent(SB),NOSPLIT,$8
376	MOVW	kq+0(FP), R0		// arg 1 - kq
377	MOVW	ch+4(FP), R1		// arg 2 - changelist
378	MOVW	nch+8(FP), R2		// arg 3 - nchanges
379	MOVW	ev+12(FP), R3		// arg 4 - eventlist
380	MOVW	nev+16(FP), R4		// arg 5 - nevents (on stack)
381	MOVW	R4, 4(R13)
382	MOVW	ts+20(FP), R5		// arg 6 - timeout (on stack)
383	MOVW	R5, 8(R13)
384	ADD	$4, R13
385	MOVW	$72, R12		// sys_kevent
386	SWI	$0
387	RSB.CS	$0, R0
388	SUB	$4, R13
389	MOVW	R0, ret+24(FP)
390	RET
391
392// func closeonexec(fd int32)
393TEXT runtime·closeonexec(SB),NOSPLIT,$0
394	MOVW	fd+0(FP), R0		// arg 1 - fd
395	MOVW	$2, R1			// arg 2 - cmd (F_SETFD)
396	MOVW	$1, R2			// arg 3 - arg (FD_CLOEXEC)
397	MOVW	$92, R12		// sys_fcntl
398	SWI	$0
399	RET
400
401// func runtime·setNonblock(fd int32)
402TEXT runtime·setNonblock(SB),NOSPLIT,$0-4
403	MOVW	fd+0(FP), R0	// fd
404	MOVW	$3, R1	// F_GETFL
405	MOVW	$0, R2
406	MOVW	$92, R12
407	SWI	$0
408	ORR	$0x4, R0, R2	// O_NONBLOCK
409	MOVW	fd+0(FP), R0	// fd
410	MOVW	$4, R1	// F_SETFL
411	MOVW	$92, R12
412	SWI	$0
413	RET
414
415TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
416	B	runtime·armPublicationBarrier(SB)
417
418TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
419	MOVM.WP	[R1, R2, R3, R12], (R13)
420	MOVW	$330, R12		// sys___get_tcb
421	SWI	$0
422	MOVM.IAW (R13), [R1, R2, R3, R12]
423	RET
424