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 386, NetBSD
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#define SYS_exit			1
17#define SYS_read			3
18#define SYS_write			4
19#define SYS_open			5
20#define SYS_close			6
21#define SYS_getpid			20
22#define SYS_kill			37
23#define SYS_munmap			73
24#define SYS_madvise			75
25#define SYS_fcntl			92
26#define SYS_mmap			197
27#define SYS___sysctl			202
28#define SYS___sigaltstack14		281
29#define SYS___sigprocmask14		293
30#define SYS_issetugid			305
31#define SYS_getcontext			307
32#define SYS_setcontext			308
33#define SYS__lwp_create			309
34#define SYS__lwp_exit			310
35#define SYS__lwp_self			311
36#define SYS__lwp_setprivate		317
37#define SYS__lwp_kill			318
38#define SYS__lwp_unpark			321
39#define SYS___sigaction_sigtramp	340
40#define SYS_kqueue			344
41#define SYS_sched_yield			350
42#define SYS___setitimer50		425
43#define SYS___clock_gettime50		427
44#define SYS___nanosleep50		430
45#define SYS___kevent50			435
46#define SYS____lwp_park60		478
47
48// Exit the entire program (like C exit)
49TEXT runtime·exit(SB),NOSPLIT,$-4
50	MOVL	$SYS_exit, AX
51	INT	$0x80
52	MOVL	$0xf1, 0xf1		// crash
53	RET
54
55// func exitThread(wait *atomic.Uint32)
56TEXT runtime·exitThread(SB),NOSPLIT,$0-4
57	MOVL	wait+0(FP), AX
58	// We're done using the stack.
59	MOVL	$0, (AX)
60	MOVL	$SYS__lwp_exit, AX
61	INT	$0x80
62	MOVL	$0xf1, 0xf1		// crash
63	JMP	0(PC)
64
65TEXT runtime·open(SB),NOSPLIT,$-4
66	MOVL	$SYS_open, AX
67	INT	$0x80
68	JAE	2(PC)
69	MOVL	$-1, AX
70	MOVL	AX, ret+12(FP)
71	RET
72
73TEXT runtime·closefd(SB),NOSPLIT,$-4
74	MOVL	$SYS_close, AX
75	INT	$0x80
76	JAE	2(PC)
77	MOVL	$-1, AX
78	MOVL	AX, ret+4(FP)
79	RET
80
81TEXT runtime·read(SB),NOSPLIT,$-4
82	MOVL	$SYS_read, AX
83	INT	$0x80
84	JAE	2(PC)
85	NEGL	AX			// caller expects negative errno
86	MOVL	AX, ret+12(FP)
87	RET
88
89// func pipe2(flags int32) (r, w int32, errno int32)
90TEXT runtime·pipe2(SB),NOSPLIT,$12-16
91	MOVL	$453, AX
92	LEAL	r+4(FP), BX
93	MOVL	BX, 4(SP)
94	MOVL	flags+0(FP), BX
95	MOVL	BX, 8(SP)
96	INT	$0x80
97	MOVL	AX, errno+12(FP)
98	RET
99
100TEXT runtime·write1(SB),NOSPLIT,$-4
101	MOVL	$SYS_write, AX
102	INT	$0x80
103	JAE	2(PC)
104	NEGL	AX			// caller expects negative errno
105	MOVL	AX, ret+12(FP)
106	RET
107
108TEXT runtime·usleep(SB),NOSPLIT,$24
109	MOVL	$0, DX
110	MOVL	usec+0(FP), AX
111	MOVL	$1000000, CX
112	DIVL	CX
113	MOVL	AX, 12(SP)		// tv_sec - l32
114	MOVL	$0, 16(SP)		// tv_sec - h32
115	MOVL	$1000, AX
116	MULL	DX
117	MOVL	AX, 20(SP)		// tv_nsec
118
119	MOVL	$0, 0(SP)
120	LEAL	12(SP), AX
121	MOVL	AX, 4(SP)		// arg 1 - rqtp
122	MOVL	$0, 8(SP)		// arg 2 - rmtp
123	MOVL	$SYS___nanosleep50, AX
124	INT	$0x80
125	RET
126
127TEXT runtime·lwp_kill(SB),NOSPLIT,$12-8
128	MOVL	$0, 0(SP)
129	MOVL	tid+0(FP), AX
130	MOVL	AX, 4(SP)		// arg 1 - target
131	MOVL	sig+4(FP), AX
132	MOVL	AX, 8(SP)		// arg 2 - signo
133	MOVL	$SYS__lwp_kill, AX
134	INT	$0x80
135	RET
136
137TEXT runtime·raiseproc(SB),NOSPLIT,$12
138	MOVL	$SYS_getpid, AX
139	INT	$0x80
140	MOVL	$0, 0(SP)
141	MOVL	AX, 4(SP)		// arg 1 - pid
142	MOVL	sig+0(FP), AX
143	MOVL	AX, 8(SP)		// arg 2 - signo
144	MOVL	$SYS_kill, AX
145	INT	$0x80
146	RET
147
148TEXT runtime·mmap(SB),NOSPLIT,$36
149	LEAL	addr+0(FP), SI
150	LEAL	4(SP), DI
151	CLD
152	MOVSL				// arg 1 - addr
153	MOVSL				// arg 2 - len
154	MOVSL				// arg 3 - prot
155	MOVSL				// arg 4 - flags
156	MOVSL				// arg 5 - fd
157	MOVL	$0, AX
158	STOSL				// arg 6 - pad
159	MOVSL				// arg 7 - offset
160	MOVL	$0, AX			// top 32 bits of file offset
161	STOSL
162	MOVL	$SYS_mmap, AX
163	INT	$0x80
164	JAE	ok
165	MOVL	$0, p+24(FP)
166	MOVL	AX, err+28(FP)
167	RET
168ok:
169	MOVL	AX, p+24(FP)
170	MOVL	$0, err+28(FP)
171	RET
172
173TEXT runtime·munmap(SB),NOSPLIT,$-4
174	MOVL	$SYS_munmap, AX
175	INT	$0x80
176	JAE	2(PC)
177	MOVL	$0xf1, 0xf1		// crash
178	RET
179
180TEXT runtime·madvise(SB),NOSPLIT,$-4
181	MOVL	$SYS_madvise, AX
182	INT	$0x80
183	JAE	2(PC)
184	MOVL	$-1, AX
185	MOVL	AX, ret+12(FP)
186	RET
187
188TEXT runtime·setitimer(SB),NOSPLIT,$-4
189	MOVL	$SYS___setitimer50, AX
190	INT	$0x80
191	RET
192
193// func walltime() (sec int64, nsec int32)
194TEXT runtime·walltime(SB), NOSPLIT, $32
195	LEAL	12(SP), BX
196	MOVL	$CLOCK_REALTIME, 4(SP)	// arg 1 - clock_id
197	MOVL	BX, 8(SP)		// arg 2 - tp
198	MOVL	$SYS___clock_gettime50, AX
199	INT	$0x80
200
201	MOVL	12(SP), AX		// sec - l32
202	MOVL	AX, sec_lo+0(FP)
203	MOVL	16(SP), AX		// sec - h32
204	MOVL	AX, sec_hi+4(FP)
205
206	MOVL	20(SP), BX		// nsec
207	MOVL	BX, nsec+8(FP)
208	RET
209
210// int64 nanotime1(void) so really
211// void nanotime1(int64 *nsec)
212TEXT runtime·nanotime1(SB),NOSPLIT,$32
213	LEAL	12(SP), BX
214	MOVL	$CLOCK_MONOTONIC, 4(SP)	// arg 1 - clock_id
215	MOVL	BX, 8(SP)		// arg 2 - tp
216	MOVL	$SYS___clock_gettime50, AX
217	INT	$0x80
218
219	MOVL	16(SP), CX		// sec - h32
220	IMULL	$1000000000, CX
221
222	MOVL	12(SP), AX		// sec - l32
223	MOVL	$1000000000, BX
224	MULL	BX			// result in dx:ax
225
226	MOVL	20(SP), BX		// nsec
227	ADDL	BX, AX
228	ADCL	CX, DX			// add high bits with carry
229
230	MOVL	AX, ret_lo+0(FP)
231	MOVL	DX, ret_hi+4(FP)
232	RET
233
234TEXT runtime·getcontext(SB),NOSPLIT,$-4
235	MOVL	$SYS_getcontext, AX
236	INT	$0x80
237	JAE	2(PC)
238	MOVL	$0xf1, 0xf1		// crash
239	RET
240
241TEXT runtime·sigprocmask(SB),NOSPLIT,$-4
242	MOVL	$SYS___sigprocmask14, AX
243	INT	$0x80
244	JAE	2(PC)
245	MOVL	$0xf1, 0xf1		// crash
246	RET
247
248TEXT sigreturn_tramp<>(SB),NOSPLIT,$0
249	LEAL	140(SP), AX		// Load address of ucontext
250	MOVL	AX, 4(SP)
251	MOVL	$SYS_setcontext, AX
252	INT	$0x80
253	MOVL	$-1, 4(SP)		// Something failed...
254	MOVL	$SYS_exit, AX
255	INT	$0x80
256
257TEXT runtime·sigaction(SB),NOSPLIT,$24
258	LEAL	sig+0(FP), SI
259	LEAL	4(SP), DI
260	CLD
261	MOVSL				// arg 1 - sig
262	MOVSL				// arg 2 - act
263	MOVSL				// arg 3 - oact
264	LEAL	sigreturn_tramp<>(SB), AX
265	STOSL				// arg 4 - tramp
266	MOVL	$2, AX
267	STOSL				// arg 5 - vers
268	MOVL	$SYS___sigaction_sigtramp, AX
269	INT	$0x80
270	JAE	2(PC)
271	MOVL	$0xf1, 0xf1		// crash
272	RET
273
274TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
275	MOVL	fn+0(FP), AX
276	MOVL	sig+4(FP), BX
277	MOVL	info+8(FP), CX
278	MOVL	ctx+12(FP), DX
279	MOVL	SP, SI
280	SUBL	$32, SP
281	ANDL	$-15, SP	// align stack: handler might be a C function
282	MOVL	BX, 0(SP)
283	MOVL	CX, 4(SP)
284	MOVL	DX, 8(SP)
285	MOVL	SI, 12(SP)	// save SI: handler might be a Go function
286	CALL	AX
287	MOVL	12(SP), AX
288	MOVL	AX, SP
289	RET
290
291// Called by OS using C ABI.
292TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$28
293	NOP	SP	// tell vet SP changed - stop checking offsets
294	// Save callee-saved C registers, since the caller may be a C signal handler.
295	MOVL	BX, bx-4(SP)
296	MOVL	BP, bp-8(SP)
297	MOVL	SI, si-12(SP)
298	MOVL	DI, di-16(SP)
299	// We don't save mxcsr or the x87 control word because sigtrampgo doesn't
300	// modify them.
301
302	MOVL	32(SP), BX // signo
303	MOVL	BX, 0(SP)
304	MOVL	36(SP), BX // info
305	MOVL	BX, 4(SP)
306	MOVL	40(SP), BX // context
307	MOVL	BX, 8(SP)
308	CALL	runtime·sigtrampgo(SB)
309
310	MOVL	di-16(SP), DI
311	MOVL	si-12(SP), SI
312	MOVL	bp-8(SP),  BP
313	MOVL	bx-4(SP),  BX
314	RET
315
316// int32 lwp_create(void *context, uintptr flags, void *lwpid);
317TEXT runtime·lwp_create(SB),NOSPLIT,$16
318	MOVL	$0, 0(SP)
319	MOVL	ctxt+0(FP), AX
320	MOVL	AX, 4(SP)		// arg 1 - context
321	MOVL	flags+4(FP), AX
322	MOVL	AX, 8(SP)		// arg 2 - flags
323	MOVL	lwpid+8(FP), AX
324	MOVL	AX, 12(SP)		// arg 3 - lwpid
325	MOVL	$SYS__lwp_create, AX
326	INT	$0x80
327	JCC	2(PC)
328	NEGL	AX
329	MOVL	AX, ret+12(FP)
330	RET
331
332TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
333
334	// Set FS to point at m->tls
335	LEAL	m_tls(BX), BP
336	PUSHAL				// save registers
337	PUSHL	BP
338	CALL	lwp_setprivate<>(SB)
339	POPL	AX
340	POPAL
341
342	// Now segment is established. Initialize m, g.
343	get_tls(AX)
344	MOVL	DX, g(AX)
345	MOVL	BX, g_m(DX)
346
347	CALL	runtime·stackcheck(SB)	// smashes AX, CX
348	MOVL	0(DX), DX		// paranoia; check they are not nil
349	MOVL	0(BX), BX
350
351	// more paranoia; check that stack splitting code works
352	PUSHAL
353	CALL	runtime·emptyfunc(SB)
354	POPAL
355
356	// Call fn
357	CALL	SI
358
359	// fn should never return
360	MOVL	$0x1234, 0x1005
361	RET
362
363TEXT ·netbsdMstart(SB),NOSPLIT|TOPFRAME,$0
364	CALL	·netbsdMstart0(SB)
365	RET // not reached
366
367TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
368	MOVL	$SYS___sigaltstack14, AX
369	MOVL	new+0(FP), BX
370	MOVL	old+4(FP), CX
371	INT	$0x80
372	CMPL	AX, $0xfffff001
373	JLS	2(PC)
374	INT	$3
375	RET
376
377TEXT runtime·setldt(SB),NOSPLIT,$8
378	// Under NetBSD we set the GS base instead of messing with the LDT.
379	MOVL	base+4(FP), AX
380	MOVL	AX, 0(SP)
381	CALL	lwp_setprivate<>(SB)
382	RET
383
384TEXT lwp_setprivate<>(SB),NOSPLIT,$16
385	// adjust for ELF: wants to use -4(GS) for g
386	MOVL	base+0(FP), CX
387	ADDL	$4, CX
388	MOVL	$0, 0(SP)		// syscall gap
389	MOVL	CX, 4(SP)		// arg 1 - ptr
390	MOVL	$SYS__lwp_setprivate, AX
391	INT	$0x80
392	JCC	2(PC)
393	MOVL	$0xf1, 0xf1		// crash
394	RET
395
396TEXT runtime·osyield(SB),NOSPLIT,$-4
397	MOVL	$SYS_sched_yield, AX
398	INT	$0x80
399	RET
400
401TEXT runtime·lwp_park(SB),NOSPLIT,$-4
402	MOVL	$SYS____lwp_park60, AX
403	INT	$0x80
404	MOVL	AX, ret+24(FP)
405	RET
406
407TEXT runtime·lwp_unpark(SB),NOSPLIT,$-4
408	MOVL	$SYS__lwp_unpark, AX
409	INT	$0x80
410	MOVL	AX, ret+8(FP)
411	RET
412
413TEXT runtime·lwp_self(SB),NOSPLIT,$-4
414	MOVL	$SYS__lwp_self, AX
415	INT	$0x80
416	MOVL	AX, ret+0(FP)
417	RET
418
419TEXT runtime·sysctl(SB),NOSPLIT,$28
420	LEAL	mib+0(FP), SI
421	LEAL	4(SP), DI
422	CLD
423	MOVSL				// arg 1 - name
424	MOVSL				// arg 2 - namelen
425	MOVSL				// arg 3 - oldp
426	MOVSL				// arg 4 - oldlenp
427	MOVSL				// arg 5 - newp
428	MOVSL				// arg 6 - newlen
429	MOVL	$SYS___sysctl, AX
430	INT	$0x80
431	JAE	4(PC)
432	NEGL	AX
433	MOVL	AX, ret+24(FP)
434	RET
435	MOVL	$0, AX
436	MOVL	AX, ret+24(FP)
437	RET
438
439GLOBL runtime·tlsoffset(SB),NOPTR,$4
440
441// int32 runtime·kqueue(void)
442TEXT runtime·kqueue(SB),NOSPLIT,$0
443	MOVL	$SYS_kqueue, AX
444	INT	$0x80
445	JAE	2(PC)
446	NEGL	AX
447	MOVL	AX, ret+0(FP)
448	RET
449
450// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
451TEXT runtime·kevent(SB),NOSPLIT,$0
452	MOVL	$SYS___kevent50, AX
453	INT	$0x80
454	JAE	2(PC)
455	NEGL	AX
456	MOVL	AX, ret+24(FP)
457	RET
458
459// func fcntl(fd, cmd, arg int32) (int32, int32)
460TEXT runtime·fcntl(SB),NOSPLIT,$-4
461	MOVL	$SYS_fcntl, AX
462	INT	$0x80
463	JAE	noerr
464	MOVL	$-1, ret+12(FP)
465	MOVL	AX, errno+16(FP)
466	RET
467noerr:
468	MOVL	AX, ret+12(FP)
469	MOVL	$0, errno+16(FP)
470	RET
471
472// func issetugid() int32
473TEXT runtime·issetugid(SB),NOSPLIT,$0
474	MOVL	$SYS_issetugid, AX
475	INT	$0x80
476	MOVL	AX, ret+0(FP)
477	RET
478