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 AMD64, 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#define FD_CLOEXEC		1
16#define F_SETFD			2
17
18#define SYS_exit			1
19#define SYS_read			3
20#define SYS_write			4
21#define SYS_open			5
22#define SYS_close			6
23#define SYS_getpid			20
24#define SYS_kill			37
25#define SYS_munmap			73
26#define SYS_madvise			75
27#define SYS_fcntl			92
28#define SYS_mmap			197
29#define SYS___sysctl			202
30#define SYS___sigaltstack14		281
31#define SYS___sigprocmask14		293
32#define SYS_getcontext			307
33#define SYS_setcontext			308
34#define SYS__lwp_create			309
35#define SYS__lwp_exit			310
36#define SYS__lwp_self			311
37#define SYS__lwp_setprivate		317
38#define SYS__lwp_kill			318
39#define SYS__lwp_unpark			321
40#define SYS___sigaction_sigtramp	340
41#define SYS_kqueue			344
42#define SYS_sched_yield			350
43#define SYS___setitimer50		425
44#define SYS___clock_gettime50		427
45#define SYS___nanosleep50		430
46#define SYS___kevent50			435
47#define SYS____lwp_park60		478
48
49// int32 lwp_create(void *context, uintptr flags, void *lwpid)
50TEXT runtime·lwp_create(SB),NOSPLIT,$0
51	MOVQ	ctxt+0(FP), DI
52	MOVQ	flags+8(FP), SI
53	MOVQ	lwpid+16(FP), DX
54	MOVL	$SYS__lwp_create, AX
55	SYSCALL
56	JCC	2(PC)
57	NEGQ	AX
58	MOVL	AX, ret+24(FP)
59	RET
60
61TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
62
63	// Set FS to point at m->tls.
64	LEAQ	m_tls(R8), DI
65	CALL	runtime·settls(SB)
66
67	// Set up new stack.
68	get_tls(CX)
69	MOVQ	R8, g_m(R9)
70	MOVQ	R9, g(CX)
71	CALL	runtime·stackcheck(SB)
72
73	// Call fn
74	CALL	R12
75
76	// It shouldn't return. If it does, exit.
77	MOVL	$SYS__lwp_exit, AX
78	SYSCALL
79	JMP	-3(PC)			// keep exiting
80
81TEXT runtime·osyield(SB),NOSPLIT,$0
82	MOVL	$SYS_sched_yield, AX
83	SYSCALL
84	RET
85
86TEXT runtime·lwp_park(SB),NOSPLIT,$0
87	MOVL	clockid+0(FP), DI		// arg 1 - clockid
88	MOVL	flags+4(FP), SI			// arg 2 - flags
89	MOVQ	ts+8(FP), DX			// arg 3 - ts
90	MOVL	unpark+16(FP), R10		// arg 4 - unpark
91	MOVQ	hint+24(FP), R8			// arg 5 - hint
92	MOVQ	unparkhint+32(FP), R9		// arg 6 - unparkhint
93	MOVL	$SYS____lwp_park60, AX
94	SYSCALL
95	MOVL	AX, ret+40(FP)
96	RET
97
98TEXT runtime·lwp_unpark(SB),NOSPLIT,$0
99	MOVL	lwp+0(FP), DI		// arg 1 - lwp
100	MOVQ	hint+8(FP), SI		// arg 2 - hint
101	MOVL	$SYS__lwp_unpark, AX
102	SYSCALL
103	MOVL	AX, ret+16(FP)
104	RET
105
106TEXT runtime·lwp_self(SB),NOSPLIT,$0
107	MOVL	$SYS__lwp_self, AX
108	SYSCALL
109	MOVL	AX, ret+0(FP)
110	RET
111
112// Exit the entire program (like C exit)
113TEXT runtime·exit(SB),NOSPLIT,$-8
114	MOVL	code+0(FP), DI		// arg 1 - exit status
115	MOVL	$SYS_exit, AX
116	SYSCALL
117	MOVL	$0xf1, 0xf1		// crash
118	RET
119
120// func exitThread(wait *uint32)
121TEXT runtime·exitThread(SB),NOSPLIT,$0-8
122	MOVQ	wait+0(FP), AX
123	// We're done using the stack.
124	MOVL	$0, (AX)
125	MOVL	$SYS__lwp_exit, AX
126	SYSCALL
127	MOVL	$0xf1, 0xf1		// crash
128	JMP	0(PC)
129
130TEXT runtime·open(SB),NOSPLIT,$-8
131	MOVQ	name+0(FP), DI		// arg 1 pathname
132	MOVL	mode+8(FP), SI		// arg 2 flags
133	MOVL	perm+12(FP), DX		// arg 3 mode
134	MOVL	$SYS_open, AX
135	SYSCALL
136	JCC	2(PC)
137	MOVL	$-1, AX
138	MOVL	AX, ret+16(FP)
139	RET
140
141TEXT runtime·closefd(SB),NOSPLIT,$-8
142	MOVL	fd+0(FP), DI		// arg 1 fd
143	MOVL	$SYS_close, AX
144	SYSCALL
145	JCC	2(PC)
146	MOVL	$-1, AX
147	MOVL	AX, ret+8(FP)
148	RET
149
150TEXT runtime·read(SB),NOSPLIT,$-8
151	MOVL	fd+0(FP), DI		// arg 1 fd
152	MOVQ	p+8(FP), SI		// arg 2 buf
153	MOVL	n+16(FP), DX		// arg 3 count
154	MOVL	$SYS_read, AX
155	SYSCALL
156	JCC	2(PC)
157	NEGQ	AX			// caller expects negative errno
158	MOVL	AX, ret+24(FP)
159	RET
160
161// func pipe() (r, w int32, errno int32)
162TEXT runtime·pipe(SB),NOSPLIT,$0-12
163	MOVL	$42, AX
164	SYSCALL
165	JCC	pipeok
166	MOVL	$-1, r+0(FP)
167	MOVL	$-1, w+4(FP)
168	MOVL	AX, errno+8(FP)
169	RET
170pipeok:
171	MOVL	AX, r+0(FP)
172	MOVL	DX, w+4(FP)
173	MOVL	$0, errno+8(FP)
174	RET
175
176// func pipe2(flags int32) (r, w int32, errno int32)
177TEXT runtime·pipe2(SB),NOSPLIT,$0-20
178	LEAQ	r+8(FP), DI
179	MOVL	flags+0(FP), SI
180	MOVL	$453, AX
181	SYSCALL
182	MOVL	AX, errno+16(FP)
183	RET
184
185TEXT runtime·write1(SB),NOSPLIT,$-8
186	MOVQ	fd+0(FP), DI		// arg 1 - fd
187	MOVQ	p+8(FP), SI		// arg 2 - buf
188	MOVL	n+16(FP), DX		// arg 3 - nbyte
189	MOVL	$SYS_write, AX
190	SYSCALL
191	JCC	2(PC)
192	NEGQ	AX			// caller expects negative errno
193	MOVL	AX, ret+24(FP)
194	RET
195
196TEXT runtime·usleep(SB),NOSPLIT,$16
197	MOVL	$0, DX
198	MOVL	usec+0(FP), AX
199	MOVL	$1000000, CX
200	DIVL	CX
201	MOVQ	AX, 0(SP)		// tv_sec
202	MOVL	$1000, AX
203	MULL	DX
204	MOVQ	AX, 8(SP)		// tv_nsec
205
206	MOVQ	SP, DI			// arg 1 - rqtp
207	MOVQ	$0, SI			// arg 2 - rmtp
208	MOVL	$SYS___nanosleep50, AX
209	SYSCALL
210	RET
211
212TEXT runtime·lwp_kill(SB),NOSPLIT,$0-16
213	MOVL	tid+0(FP), DI		// arg 1 - target
214	MOVQ	sig+8(FP), SI		// arg 2 - signo
215	MOVL	$SYS__lwp_kill, AX
216	SYSCALL
217	RET
218
219TEXT runtime·raiseproc(SB),NOSPLIT,$16
220	MOVL	$SYS_getpid, AX
221	SYSCALL
222	MOVQ	AX, DI			// arg 1 - pid
223	MOVL	sig+0(FP), SI		// arg 2 - signo
224	MOVL	$SYS_kill, AX
225	SYSCALL
226	RET
227
228TEXT runtime·setitimer(SB),NOSPLIT,$-8
229	MOVL	mode+0(FP), DI		// arg 1 - which
230	MOVQ	new+8(FP), SI		// arg 2 - itv
231	MOVQ	old+16(FP), DX		// arg 3 - oitv
232	MOVL	$SYS___setitimer50, AX
233	SYSCALL
234	RET
235
236// func walltime1() (sec int64, nsec int32)
237TEXT runtime·walltime1(SB), NOSPLIT, $32
238	MOVQ	$CLOCK_REALTIME, DI	// arg 1 - clock_id
239	LEAQ	8(SP), SI		// arg 2 - tp
240	MOVL	$SYS___clock_gettime50, AX
241	SYSCALL
242	MOVQ	8(SP), AX		// sec
243	MOVQ	16(SP), DX		// nsec
244
245	// sec is in AX, nsec in DX
246	MOVQ	AX, sec+0(FP)
247	MOVL	DX, nsec+8(FP)
248	RET
249
250TEXT runtime·nanotime1(SB),NOSPLIT,$32
251	MOVQ	$CLOCK_MONOTONIC, DI	// arg 1 - clock_id
252	LEAQ	8(SP), SI		// arg 2 - tp
253	MOVL	$SYS___clock_gettime50, AX
254	SYSCALL
255	MOVQ	8(SP), AX		// sec
256	MOVQ	16(SP), DX		// nsec
257
258	// sec is in AX, nsec in DX
259	// return nsec in AX
260	IMULQ	$1000000000, AX
261	ADDQ	DX, AX
262	MOVQ	AX, ret+0(FP)
263	RET
264
265TEXT runtime·getcontext(SB),NOSPLIT,$-8
266	MOVQ	ctxt+0(FP), DI		// arg 1 - context
267	MOVL	$SYS_getcontext, AX
268	SYSCALL
269	JCC	2(PC)
270	MOVL	$0xf1, 0xf1		// crash
271	RET
272
273TEXT runtime·sigprocmask(SB),NOSPLIT,$0
274	MOVL	how+0(FP), DI		// arg 1 - how
275	MOVQ	new+8(FP), SI		// arg 2 - set
276	MOVQ	old+16(FP), DX		// arg 3 - oset
277	MOVL	$SYS___sigprocmask14, AX
278	SYSCALL
279	JCC	2(PC)
280	MOVL	$0xf1, 0xf1		// crash
281	RET
282
283TEXT sigreturn_tramp<>(SB),NOSPLIT,$-8
284	MOVQ	R15, DI			// Load address of ucontext
285	MOVQ	$SYS_setcontext, AX
286	SYSCALL
287	MOVQ	$-1, DI			// Something failed...
288	MOVL	$SYS_exit, AX
289	SYSCALL
290
291TEXT runtime·sigaction(SB),NOSPLIT,$-8
292	MOVL	sig+0(FP), DI		// arg 1 - signum
293	MOVQ	new+8(FP), SI		// arg 2 - nsa
294	MOVQ	old+16(FP), DX		// arg 3 - osa
295					// arg 4 - tramp
296	LEAQ	sigreturn_tramp<>(SB), R10
297	MOVQ	$2, R8			// arg 5 - vers
298	MOVL	$SYS___sigaction_sigtramp, AX
299	SYSCALL
300	JCC	2(PC)
301	MOVL	$0xf1, 0xf1		// crash
302	RET
303
304TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
305	MOVQ	fn+0(FP),    AX
306	MOVL	sig+8(FP),   DI
307	MOVQ	info+16(FP), SI
308	MOVQ	ctx+24(FP),  DX
309	PUSHQ	BP
310	MOVQ	SP, BP
311	ANDQ	$~15, SP     // alignment for x86_64 ABI
312	CALL	AX
313	MOVQ	BP, SP
314	POPQ	BP
315	RET
316
317TEXT runtime·sigtramp(SB),NOSPLIT,$72
318	// Save callee-saved C registers, since the caller may be a C signal handler.
319	MOVQ	BX,  bx-8(SP)
320	MOVQ	BP,  bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
321	MOVQ	R12, r12-24(SP)
322	MOVQ	R13, r13-32(SP)
323	MOVQ	R14, r14-40(SP)
324	MOVQ	R15, r15-48(SP)
325	// We don't save mxcsr or the x87 control word because sigtrampgo doesn't
326	// modify them.
327
328	MOVQ	DX, ctx-56(SP)
329	MOVQ	SI, info-64(SP)
330	MOVQ	DI, signum-72(SP)
331	CALL	runtime·sigtrampgo(SB)
332
333	MOVQ	r15-48(SP), R15
334	MOVQ	r14-40(SP), R14
335	MOVQ	r13-32(SP), R13
336	MOVQ	r12-24(SP), R12
337	MOVQ	bp-16(SP),  BP
338	MOVQ	bx-8(SP),   BX
339	RET
340
341TEXT runtime·mmap(SB),NOSPLIT,$0
342	MOVQ	addr+0(FP), DI		// arg 1 - addr
343	MOVQ	n+8(FP), SI		// arg 2 - len
344	MOVL	prot+16(FP), DX		// arg 3 - prot
345	MOVL	flags+20(FP), R10		// arg 4 - flags
346	MOVL	fd+24(FP), R8		// arg 5 - fd
347	MOVL	off+28(FP), R9
348	SUBQ	$16, SP
349	MOVQ	R9, 8(SP)		// arg 7 - offset (passed on stack)
350	MOVQ	$0, R9			// arg 6 - pad
351	MOVL	$SYS_mmap, AX
352	SYSCALL
353	JCC	ok
354	ADDQ	$16, SP
355	MOVQ	$0, p+32(FP)
356	MOVQ	AX, err+40(FP)
357	RET
358ok:
359	ADDQ	$16, SP
360	MOVQ	AX, p+32(FP)
361	MOVQ	$0, err+40(FP)
362	RET
363
364TEXT runtime·munmap(SB),NOSPLIT,$0
365	MOVQ	addr+0(FP), DI		// arg 1 - addr
366	MOVQ	n+8(FP), SI		// arg 2 - len
367	MOVL	$SYS_munmap, AX
368	SYSCALL
369	JCC	2(PC)
370	MOVL	$0xf1, 0xf1		// crash
371	RET
372
373
374TEXT runtime·madvise(SB),NOSPLIT,$0
375	MOVQ	addr+0(FP), DI		// arg 1 - addr
376	MOVQ	n+8(FP), SI		// arg 2 - len
377	MOVL	flags+16(FP), DX	// arg 3 - behav
378	MOVQ	$SYS_madvise, AX
379	SYSCALL
380	JCC	2(PC)
381	MOVL	$-1, AX
382	MOVL	AX, ret+24(FP)
383	RET
384
385TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
386	MOVQ	new+0(FP), DI		// arg 1 - nss
387	MOVQ	old+8(FP), SI		// arg 2 - oss
388	MOVQ	$SYS___sigaltstack14, AX
389	SYSCALL
390	JCC	2(PC)
391	MOVL	$0xf1, 0xf1		// crash
392	RET
393
394// set tls base to DI
395TEXT runtime·settls(SB),NOSPLIT,$8
396	// adjust for ELF: wants to use -8(FS) for g
397	ADDQ	$8, DI			// arg 1 - ptr
398	MOVQ	$SYS__lwp_setprivate, AX
399	SYSCALL
400	JCC	2(PC)
401	MOVL	$0xf1, 0xf1		// crash
402	RET
403
404TEXT runtime·sysctl(SB),NOSPLIT,$0
405	MOVQ	mib+0(FP), DI		// arg 1 - name
406	MOVL	miblen+8(FP), SI		// arg 2 - namelen
407	MOVQ	out+16(FP), DX		// arg 3 - oldp
408	MOVQ	size+24(FP), R10		// arg 4 - oldlenp
409	MOVQ	dst+32(FP), R8		// arg 5 - newp
410	MOVQ	ndst+40(FP), R9		// arg 6 - newlen
411	MOVQ	$SYS___sysctl, AX
412	SYSCALL
413	JCC 4(PC)
414	NEGQ	AX
415	MOVL	AX, ret+48(FP)
416	RET
417	MOVL	$0, AX
418	MOVL	AX, ret+48(FP)
419	RET
420
421// int32 runtime·kqueue(void)
422TEXT runtime·kqueue(SB),NOSPLIT,$0
423	MOVQ	$0, DI
424	MOVL	$SYS_kqueue, AX
425	SYSCALL
426	JCC	2(PC)
427	NEGQ	AX
428	MOVL	AX, ret+0(FP)
429	RET
430
431// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
432TEXT runtime·kevent(SB),NOSPLIT,$0
433	MOVL	kq+0(FP), DI
434	MOVQ	ch+8(FP), SI
435	MOVL	nch+16(FP), DX
436	MOVQ	ev+24(FP), R10
437	MOVL	nev+32(FP), R8
438	MOVQ	ts+40(FP), R9
439	MOVL	$SYS___kevent50, AX
440	SYSCALL
441	JCC	2(PC)
442	NEGQ	AX
443	MOVL	AX, ret+48(FP)
444	RET
445
446// void runtime·closeonexec(int32 fd)
447TEXT runtime·closeonexec(SB),NOSPLIT,$0
448	MOVL	fd+0(FP), DI	// fd
449	MOVQ	$F_SETFD, SI
450	MOVQ	$FD_CLOEXEC, DX
451	MOVL	$SYS_fcntl, AX
452	SYSCALL
453	RET
454
455// func runtime·setNonblock(int32 fd)
456TEXT runtime·setNonblock(SB),NOSPLIT,$0-4
457	MOVL    fd+0(FP), DI  // fd
458	MOVQ    $3, SI  // F_GETFL
459	MOVQ    $0, DX
460	MOVL	$92, AX // fcntl
461	SYSCALL
462	MOVL	fd+0(FP), DI // fd
463	MOVQ	$4, SI // F_SETFL
464	MOVQ	$4, DX // O_NONBLOCK
465	ORL	AX, DX
466	MOVL	$92, AX // fcntl
467	SYSCALL
468	RET
469