1// Copyright 2020 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 mips64, OpenBSD
7// /usr/src/sys/kern/syscalls.master for syscall numbers.
8//
9
10#include "go_asm.h"
11#include "go_tls.h"
12#include "textflag.h"
13
14#define CLOCK_REALTIME	$0
15#define	CLOCK_MONOTONIC	$3
16
17// Exit the entire program (like C exit)
18TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
19	MOVW	code+0(FP), R4		// arg 1 - status
20	MOVV	$1, R2			// sys_exit
21	SYSCALL
22	BEQ	R7, 3(PC)
23	MOVV	$0, R2			// crash on syscall failure
24	MOVV	R2, (R2)
25	RET
26
27// func exitThread(wait *atomic.Uint32)
28TEXT runtime·exitThread(SB),NOSPLIT,$0
29	MOVV	wait+0(FP), R4		// arg 1 - notdead
30	MOVV	$302, R2		// sys___threxit
31	SYSCALL
32	MOVV	$0, R2			// crash on syscall failure
33	MOVV	R2, (R2)
34	JMP	0(PC)
35
36TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0
37	MOVV	name+0(FP), R4		// arg 1 - path
38	MOVW	mode+8(FP), R5		// arg 2 - mode
39	MOVW	perm+12(FP), R6		// arg 3 - perm
40	MOVV	$5, R2			// sys_open
41	SYSCALL
42	BEQ	R7, 2(PC)
43	MOVW	$-1, R2
44	MOVW	R2, ret+16(FP)
45	RET
46
47TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0
48	MOVW	fd+0(FP), R4		// arg 1 - fd
49	MOVV	$6, R2			// sys_close
50	SYSCALL
51	BEQ	R7, 2(PC)
52	MOVW	$-1, R2
53	MOVW	R2, ret+8(FP)
54	RET
55
56TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0
57	MOVW	fd+0(FP), R4		// arg 1 - fd
58	MOVV	p+8(FP), R5		// arg 2 - buf
59	MOVW	n+16(FP), R6		// arg 3 - nbyte
60	MOVV	$3, R2			// sys_read
61	SYSCALL
62	BEQ	R7, 2(PC)
63	SUBVU	R2, R0, R2	// caller expects negative errno
64	MOVW	R2, ret+24(FP)
65	RET
66
67// func pipe2(flags int32) (r, w int32, errno int32)
68TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
69	MOVV	$r+8(FP), R4
70	MOVW	flags+0(FP), R5
71	MOVV	$101, R2		// sys_pipe2
72	SYSCALL
73	BEQ	R7, 2(PC)
74	SUBVU	R2, R0, R2	// caller expects negative errno
75	MOVW	R2, errno+16(FP)
76	RET
77
78TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0
79	MOVV	fd+0(FP), R4		// arg 1 - fd
80	MOVV	p+8(FP), R5		// arg 2 - buf
81	MOVW	n+16(FP), R6		// arg 3 - nbyte
82	MOVV	$4, R2			// sys_write
83	SYSCALL
84	BEQ	R7, 2(PC)
85	SUBVU	R2, R0, R2	// caller expects negative errno
86	MOVW	R2, ret+24(FP)
87	RET
88
89TEXT runtime·usleep(SB),NOSPLIT,$24-4
90	MOVWU	usec+0(FP), R3
91	MOVV	R3, R5
92	MOVW	$1000000, R4
93	DIVVU	R4, R3
94	MOVV	LO, R3
95	MOVV	R3, 8(R29)		// tv_sec
96	MOVW	$1000, R4
97	MULVU	R3, R4
98	MOVV	LO, R4
99	SUBVU	R4, R5
100	MOVV	R5, 16(R29)		// tv_nsec
101
102	ADDV	$8, R29, R4		// arg 1 - rqtp
103	MOVV	$0, R5			// arg 2 - rmtp
104	MOVV	$91, R2			// sys_nanosleep
105	SYSCALL
106	RET
107
108TEXT runtime·getthrid(SB),NOSPLIT,$0-4
109	MOVV	$299, R2		// sys_getthrid
110	SYSCALL
111	MOVW	R2, ret+0(FP)
112	RET
113
114TEXT runtime·thrkill(SB),NOSPLIT,$0-16
115	MOVW	tid+0(FP), R4		// arg 1 - tid
116	MOVV	sig+8(FP), R5		// arg 2 - signum
117	MOVW	$0, R6			// arg 3 - tcb
118	MOVV	$119, R2		// sys_thrkill
119	SYSCALL
120	RET
121
122TEXT runtime·raiseproc(SB),NOSPLIT,$0
123	MOVV	$20, R4			// sys_getpid
124	SYSCALL
125	MOVV	R2, R4			// arg 1 - pid
126	MOVW	sig+0(FP), R5		// arg 2 - signum
127	MOVV	$122, R2		// sys_kill
128	SYSCALL
129	RET
130
131TEXT runtime·mmap(SB),NOSPLIT,$0
132	MOVV	addr+0(FP), R4		// arg 1 - addr
133	MOVV	n+8(FP), R5		// arg 2 - len
134	MOVW	prot+16(FP), R6		// arg 3 - prot
135	MOVW	flags+20(FP), R7	// arg 4 - flags
136	MOVW	fd+24(FP), R8		// arg 5 - fd
137	MOVW	$0, R9			// arg 6 - pad
138	MOVW	off+28(FP), R10		// arg 7 - offset
139	MOVV	$197, R2		// sys_mmap
140	SYSCALL
141	MOVV	$0, R4
142	BEQ	R7, 3(PC)
143	MOVV	R2, R4			// if error, move to R4
144	MOVV	$0, R2
145	MOVV	R2, p+32(FP)
146	MOVV	R4, err+40(FP)
147	RET
148
149TEXT runtime·munmap(SB),NOSPLIT,$0
150	MOVV	addr+0(FP), R4		// arg 1 - addr
151	MOVV	n+8(FP), R5		// arg 2 - len
152	MOVV	$73, R2			// sys_munmap
153	SYSCALL
154	BEQ	R7, 3(PC)
155	MOVV	$0, R2			// crash on syscall failure
156	MOVV	R2, (R2)
157	RET
158
159TEXT runtime·madvise(SB),NOSPLIT,$0
160	MOVV	addr+0(FP), R4		// arg 1 - addr
161	MOVV	n+8(FP), R5		// arg 2 - len
162	MOVW	flags+16(FP), R6	// arg 2 - flags
163	MOVV	$75, R2			// sys_madvise
164	SYSCALL
165	BEQ	R7, 2(PC)
166	MOVW	$-1, R2
167	MOVW	R2, ret+24(FP)
168	RET
169
170TEXT runtime·setitimer(SB),NOSPLIT,$0
171	MOVW	mode+0(FP), R4		// arg 1 - mode
172	MOVV	new+8(FP), R5		// arg 2 - new value
173	MOVV	old+16(FP), R6		// arg 3 - old value
174	MOVV	$69, R2			// sys_setitimer
175	SYSCALL
176	RET
177
178// func walltime() (sec int64, nsec int32)
179TEXT runtime·walltime(SB), NOSPLIT, $32
180	MOVW	CLOCK_REALTIME, R4	// arg 1 - clock_id
181	MOVV	$8(R29), R5		// arg 2 - tp
182	MOVV	$87, R2			// sys_clock_gettime
183	SYSCALL
184
185	MOVV	8(R29), R4		// sec
186	MOVV	16(R29), R5		// nsec
187	MOVV	R4, sec+0(FP)
188	MOVW	R5, nsec+8(FP)
189
190	RET
191
192// int64 nanotime1(void) so really
193// void nanotime1(int64 *nsec)
194TEXT runtime·nanotime1(SB),NOSPLIT,$32
195	MOVW	CLOCK_MONOTONIC, R4	// arg 1 - clock_id
196	MOVV	$8(R29), R5		// arg 2 - tp
197	MOVV	$87, R2			// sys_clock_gettime
198	SYSCALL
199
200	MOVV	8(R29), R3		// sec
201	MOVV	16(R29), R5		// nsec
202
203	MOVV	$1000000000, R4
204	MULVU	R4, R3
205	MOVV	LO, R3
206	ADDVU	R5, R3
207	MOVV	R3, ret+0(FP)
208	RET
209
210TEXT runtime·sigaction(SB),NOSPLIT,$0
211	MOVW	sig+0(FP), R4		// arg 1 - signum
212	MOVV	new+8(FP), R5		// arg 2 - new sigaction
213	MOVV	old+16(FP), R6		// arg 3 - old sigaction
214	MOVV	$46, R2			// sys_sigaction
215	SYSCALL
216	BEQ	R7, 3(PC)
217	MOVV	$3, R2			// crash on syscall failure
218	MOVV	R2, (R2)
219	RET
220
221TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0
222	MOVW	how+0(FP), R4		// arg 1 - mode
223	MOVW	new+4(FP), R5		// arg 2 - new
224	MOVV	$48, R2			// sys_sigprocmask
225	SYSCALL
226	BEQ	R7, 3(PC)
227	MOVV	$3, R2			// crash on syscall failure
228	MOVV	R2, (R2)
229	MOVW	R2, ret+8(FP)
230	RET
231
232TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
233	MOVW	sig+8(FP), R4
234	MOVV	info+16(FP), R5
235	MOVV	ctx+24(FP), R6
236	MOVV	fn+0(FP), R25		// Must use R25, needed for PIC code.
237	CALL	(R25)
238	RET
239
240TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$192
241	// initialize REGSB = PC&0xffffffff00000000
242	BGEZAL	R0, 1(PC)
243	SRLV	$32, R31, RSB
244	SLLV	$32, RSB
245
246	// this might be called in external code context,
247	// where g is not set.
248	MOVB	runtime·iscgo(SB), R1
249	BEQ	R1, 2(PC)
250	JAL	runtime·load_g(SB)
251
252	MOVW	R4, 8(R29)
253	MOVV	R5, 16(R29)
254	MOVV	R6, 24(R29)
255	MOVV	$runtime·sigtrampgo(SB), R1
256	JAL	(R1)
257	RET
258
259// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
260TEXT runtime·tfork(SB),NOSPLIT,$0
261
262	// Copy mp, gp and fn off parent stack for use by child.
263	MOVV	mm+16(FP), R16
264	MOVV	gg+24(FP), R17
265	MOVV	fn+32(FP), R18
266
267	MOVV	param+0(FP), R4		// arg 1 - param
268	MOVV	psize+8(FP), R5		// arg 2 - psize
269	MOVV	$8, R2			// sys___tfork
270	SYSCALL
271
272	// Return if syscall failed.
273	BEQ	R7, 4(PC)
274	SUBVU	R2, R0, R2		// caller expects negative errno
275	MOVW	R2, ret+40(FP)
276	RET
277
278	// In parent, return.
279	BEQ	R2, 3(PC)
280	MOVW	$0, ret+40(FP)
281	RET
282
283	// Initialise m, g.
284	MOVV	R17, g
285	MOVV	R16, g_m(g)
286
287	// Call fn.
288	CALL	(R18)
289
290	// fn should never return.
291	MOVV	$2, R8			// crash if reached
292	MOVV	R8, (R8)
293	RET
294
295TEXT runtime·sigaltstack(SB),NOSPLIT,$0
296	MOVV	new+0(FP), R4		// arg 1 - new sigaltstack
297	MOVV	old+8(FP), R5		// arg 2 - old sigaltstack
298	MOVV	$288, R2		// sys_sigaltstack
299	SYSCALL
300	BEQ	R7, 3(PC)
301	MOVV	$0, R8			// crash on syscall failure
302	MOVV	R8, (R8)
303	RET
304
305TEXT runtime·osyield(SB),NOSPLIT,$0
306	MOVV	$298, R2		// sys_sched_yield
307	SYSCALL
308	RET
309
310TEXT runtime·thrsleep(SB),NOSPLIT,$0
311	MOVV	ident+0(FP), R4		// arg 1 - ident
312	MOVW	clock_id+8(FP), R5	// arg 2 - clock_id
313	MOVV	tsp+16(FP), R6		// arg 3 - tsp
314	MOVV	lock+24(FP), R7		// arg 4 - lock
315	MOVV	abort+32(FP), R8	// arg 5 - abort
316	MOVV	$94, R2			// sys___thrsleep
317	SYSCALL
318	MOVW	R2, ret+40(FP)
319	RET
320
321TEXT runtime·thrwakeup(SB),NOSPLIT,$0
322	MOVV	ident+0(FP), R4		// arg 1 - ident
323	MOVW	n+8(FP), R5		// arg 2 - n
324	MOVV	$301, R2		// sys___thrwakeup
325	SYSCALL
326	MOVW	R2, ret+16(FP)
327	RET
328
329TEXT runtime·sysctl(SB),NOSPLIT,$0
330	MOVV	mib+0(FP), R4		// arg 1 - mib
331	MOVW	miblen+8(FP), R5	// arg 2 - miblen
332	MOVV	out+16(FP), R6		// arg 3 - out
333	MOVV	size+24(FP), R7		// arg 4 - size
334	MOVV	dst+32(FP), R8		// arg 5 - dest
335	MOVV	ndst+40(FP), R9		// arg 6 - newlen
336	MOVV	$202, R2		// sys___sysctl
337	SYSCALL
338	BEQ	R7, 2(PC)
339	SUBVU	R2, R0, R2	// caller expects negative errno
340	MOVW	R2, ret+48(FP)
341	RET
342
343// int32 runtime·kqueue(void);
344TEXT runtime·kqueue(SB),NOSPLIT,$0
345	MOVV	$269, R2		// sys_kqueue
346	SYSCALL
347	BEQ	R7, 2(PC)
348	SUBVU	R2, R0, R2	// caller expects negative errno
349	MOVW	R2, ret+0(FP)
350	RET
351
352// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
353TEXT runtime·kevent(SB),NOSPLIT,$0
354	MOVW	kq+0(FP), R4		// arg 1 - kq
355	MOVV	ch+8(FP), R5		// arg 2 - changelist
356	MOVW	nch+16(FP), R6		// arg 3 - nchanges
357	MOVV	ev+24(FP), R7		// arg 4 - eventlist
358	MOVW	nev+32(FP), R8		// arg 5 - nevents
359	MOVV	ts+40(FP), R9		// arg 6 - timeout
360	MOVV	$72, R2			// sys_kevent
361	SYSCALL
362	BEQ	R7, 2(PC)
363	SUBVU	R2, R0, R2	// caller expects negative errno
364	MOVW	R2, ret+48(FP)
365	RET
366
367// func fcntl(fd, cmd, arg int32) (int32, int32)
368TEXT runtime·fcntl(SB),NOSPLIT,$0
369	MOVW	fd+0(FP), R4	// fd
370	MOVW	cmd+4(FP), R5	// cmd
371	MOVW	arg+8(FP), R6	// arg
372	MOVV	$92, R2		// sys_fcntl
373	SYSCALL
374	MOVV	$0, R4
375	BEQ	R7, noerr
376	MOVV	R2, R4
377	MOVW	$-1, R2
378noerr:
379	MOVW	R2, ret+16(FP)
380	MOVW	R4, errno+20(FP)
381	RET
382
383// func issetugid() int32
384TEXT runtime·issetugid(SB),NOSPLIT,$0
385	MOVV	$253, R2	// sys_issetugid
386	SYSCALL
387	MOVW	R2, ret+0(FP)
388	RET
389