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, FreeBSD
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#include "cgo/abi_amd64.h"
13
14TEXT runtime·sys_umtx_sleep(SB),NOSPLIT,$0
15	MOVQ addr+0(FP), DI		// arg 1 - ptr
16	MOVL val+8(FP), SI		// arg 2 - value
17	MOVL timeout+12(FP), DX		// arg 3 - timeout
18	MOVL $469, AX		// umtx_sleep
19	SYSCALL
20	JCC	2(PC)
21	NEGQ	AX
22	MOVL	AX, ret+16(FP)
23	RET
24
25TEXT runtime·sys_umtx_wakeup(SB),NOSPLIT,$0
26	MOVQ addr+0(FP), DI		// arg 1 - ptr
27	MOVL val+8(FP), SI		// arg 2 - count
28	MOVL $470, AX		// umtx_wakeup
29	SYSCALL
30	JCC	2(PC)
31	NEGQ	AX
32	MOVL	AX, ret+16(FP)
33	RET
34
35TEXT runtime·lwp_create(SB),NOSPLIT,$0
36	MOVQ param+0(FP), DI		// arg 1 - params
37	MOVL $495, AX		// lwp_create
38	SYSCALL
39	MOVL	AX, ret+8(FP)
40	RET
41
42TEXT runtime·lwp_start(SB),NOSPLIT,$0
43	MOVQ	DI, R13 // m
44
45	// set up FS to point at m->tls
46	LEAQ	m_tls(R13), DI
47	CALL	runtime·settls(SB)	// smashes DI
48
49	// set up m, g
50	get_tls(CX)
51	MOVQ	m_g0(R13), DI
52	MOVQ	R13, g_m(DI)
53	MOVQ	DI, g(CX)
54
55	CALL	runtime·stackcheck(SB)
56	CALL	runtime·mstart(SB)
57
58	MOVQ 0, AX			// crash (not reached)
59
60// Exit the entire program (like C exit)
61TEXT runtime·exit(SB),NOSPLIT,$-8
62	MOVL	code+0(FP), DI		// arg 1 exit status
63	MOVL	$1, AX
64	SYSCALL
65	MOVL	$0xf1, 0xf1  // crash
66	RET
67
68// func exitThread(wait *atomic.Uint32)
69TEXT runtime·exitThread(SB),NOSPLIT,$0-8
70	MOVQ	wait+0(FP), AX
71	// We're done using the stack.
72	MOVL	$0, (AX)
73	MOVL	$0x10000, DI	// arg 1 how - EXTEXIT_LWP
74	MOVL	$0, SI		// arg 2 status
75	MOVL	$0, DX		// arg 3 addr
76	MOVL	$494, AX	// extexit
77	SYSCALL
78	MOVL	$0xf1, 0xf1  // crash
79	JMP	0(PC)
80
81TEXT runtime·open(SB),NOSPLIT,$-8
82	MOVQ	name+0(FP), DI		// arg 1 pathname
83	MOVL	mode+8(FP), SI		// arg 2 flags
84	MOVL	perm+12(FP), DX		// arg 3 mode
85	MOVL	$5, AX
86	SYSCALL
87	JCC	2(PC)
88	MOVL	$-1, AX
89	MOVL	AX, ret+16(FP)
90	RET
91
92TEXT runtime·closefd(SB),NOSPLIT,$-8
93	MOVL	fd+0(FP), DI		// arg 1 fd
94	MOVL	$6, AX
95	SYSCALL
96	JCC	2(PC)
97	MOVL	$-1, AX
98	MOVL	AX, ret+8(FP)
99	RET
100
101TEXT runtime·read(SB),NOSPLIT,$-8
102	MOVL	fd+0(FP), DI		// arg 1 fd
103	MOVQ	p+8(FP), SI		// arg 2 buf
104	MOVL	n+16(FP), DX		// arg 3 count
105	MOVL	$3, AX
106	SYSCALL
107	JCC	2(PC)
108	NEGL	AX			// caller expects negative errno
109	MOVL	AX, ret+24(FP)
110	RET
111
112// func pipe2(flags int32) (r, w int32, errno int32)
113TEXT runtime·pipe2(SB),NOSPLIT,$0-20
114	MOVL	$0, DI
115	// dragonfly expects flags as the 2nd argument
116	MOVL	flags+0(FP), SI
117	MOVL	$538, AX
118	SYSCALL
119	JCC	pipe2ok
120	MOVL	$-1,r+8(FP)
121	MOVL	$-1,w+12(FP)
122	MOVL	AX, errno+16(FP)
123	RET
124pipe2ok:
125	MOVL	AX, r+8(FP)
126	MOVL	DX, w+12(FP)
127	MOVL	$0, errno+16(FP)
128	RET
129
130TEXT runtime·write1(SB),NOSPLIT,$-8
131	MOVQ	fd+0(FP), DI		// arg 1 fd
132	MOVQ	p+8(FP), SI		// arg 2 buf
133	MOVL	n+16(FP), DX		// arg 3 count
134	MOVL	$4, AX
135	SYSCALL
136	JCC	2(PC)
137	NEGL	AX			// caller expects negative errno
138	MOVL	AX, ret+24(FP)
139	RET
140
141TEXT runtime·lwp_gettid(SB),NOSPLIT,$0-4
142	MOVL	$496, AX	// lwp_gettid
143	SYSCALL
144	MOVL	AX, ret+0(FP)
145	RET
146
147TEXT runtime·lwp_kill(SB),NOSPLIT,$0-16
148	MOVL	pid+0(FP), DI	// arg 1 - pid
149	MOVL	tid+4(FP), SI	// arg 2 - tid
150	MOVQ	sig+8(FP), DX	// arg 3 - signum
151	MOVL	$497, AX	// lwp_kill
152	SYSCALL
153	RET
154
155TEXT runtime·raiseproc(SB),NOSPLIT,$0
156	MOVL	$20, AX		// getpid
157	SYSCALL
158	MOVQ	AX, DI		// arg 1 - pid
159	MOVL	sig+0(FP), SI	// arg 2 - signum
160	MOVL	$37, AX		// kill
161	SYSCALL
162	RET
163
164TEXT runtime·setitimer(SB), NOSPLIT, $-8
165	MOVL	mode+0(FP), DI
166	MOVQ	new+8(FP), SI
167	MOVQ	old+16(FP), DX
168	MOVL	$83, AX
169	SYSCALL
170	RET
171
172// func walltime() (sec int64, nsec int32)
173TEXT runtime·walltime(SB), NOSPLIT, $32
174	MOVL	$232, AX // clock_gettime
175	MOVQ	$0, DI  	// CLOCK_REALTIME
176	LEAQ	8(SP), SI
177	SYSCALL
178	MOVQ	8(SP), AX	// sec
179	MOVQ	16(SP), DX	// nsec
180
181	// sec is in AX, nsec in DX
182	MOVQ	AX, sec+0(FP)
183	MOVL	DX, nsec+8(FP)
184	RET
185
186TEXT runtime·nanotime1(SB), NOSPLIT, $32
187	MOVL	$232, AX
188	MOVQ	$4, DI  	// CLOCK_MONOTONIC
189	LEAQ	8(SP), SI
190	SYSCALL
191	MOVQ	8(SP), AX	// sec
192	MOVQ	16(SP), DX	// nsec
193
194	// sec is in AX, nsec in DX
195	// return nsec in AX
196	IMULQ	$1000000000, AX
197	ADDQ	DX, AX
198	MOVQ	AX, ret+0(FP)
199	RET
200
201TEXT runtime·sigaction(SB),NOSPLIT,$-8
202	MOVL	sig+0(FP), DI		// arg 1 sig
203	MOVQ	new+8(FP), SI		// arg 2 act
204	MOVQ	old+16(FP), DX		// arg 3 oact
205	MOVL	$342, AX
206	SYSCALL
207	JCC	2(PC)
208	MOVL	$0xf1, 0xf1  // crash
209	RET
210
211TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
212	MOVQ	fn+0(FP),    AX
213	MOVL	sig+8(FP),   DI
214	MOVQ	info+16(FP), SI
215	MOVQ	ctx+24(FP),  DX
216	MOVQ	SP, BX		// callee-saved
217	ANDQ	$~15, SP	// alignment for x86_64 ABI
218	CALL	AX
219	MOVQ	BX, SP
220	RET
221
222// Called using C ABI.
223TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
224	// Transition from C ABI to Go ABI.
225	PUSH_REGS_HOST_TO_ABI0()
226
227	// Set up ABIInternal environment: g in R14, cleared X15.
228	get_tls(R12)
229	MOVQ	g(R12), R14
230	PXOR	X15, X15
231
232	// Reserve space for spill slots.
233	NOP	SP		// disable vet stack checking
234	ADJSP   $24
235
236	// Call into the Go signal handler
237	MOVQ	DI, AX	// sig
238	MOVQ	SI, BX	// info
239	MOVQ	DX, CX	// ctx
240	CALL	·sigtrampgo<ABIInternal>(SB)
241
242	ADJSP	$-24
243
244	POP_REGS_HOST_TO_ABI0()
245	RET
246
247TEXT runtime·mmap(SB),NOSPLIT,$0
248	MOVQ	addr+0(FP), DI		// arg 1 - addr
249	MOVQ	n+8(FP), SI		// arg 2 - len
250	MOVL	prot+16(FP), DX		// arg 3 - prot
251	MOVL	flags+20(FP), R10		// arg 4 - flags
252	MOVL	fd+24(FP), R8		// arg 5 - fd
253	MOVL	off+28(FP), R9
254	SUBQ	$16, SP
255	MOVQ	R9, 8(SP)		// arg 7 - offset (passed on stack)
256	MOVQ	$0, R9			// arg 6 - pad
257	MOVL	$197, AX
258	SYSCALL
259	JCC	ok
260	ADDQ	$16, SP
261	MOVQ	$0, p+32(FP)
262	MOVQ	AX, err+40(FP)
263	RET
264ok:
265	ADDQ	$16, SP
266	MOVQ	AX, p+32(FP)
267	MOVQ	$0, err+40(FP)
268	RET
269
270TEXT runtime·munmap(SB),NOSPLIT,$0
271	MOVQ	addr+0(FP), DI		// arg 1 addr
272	MOVQ	n+8(FP), SI		// arg 2 len
273	MOVL	$73, AX
274	SYSCALL
275	JCC	2(PC)
276	MOVL	$0xf1, 0xf1  // crash
277	RET
278
279TEXT runtime·madvise(SB),NOSPLIT,$0
280	MOVQ	addr+0(FP), DI
281	MOVQ	n+8(FP), SI
282	MOVL	flags+16(FP), DX
283	MOVQ	$75, AX	// madvise
284	SYSCALL
285	JCC	2(PC)
286	MOVL	$-1, AX
287	MOVL	AX, ret+24(FP)
288	RET
289
290TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
291	MOVQ	new+0(FP), DI
292	MOVQ	old+8(FP), SI
293	MOVQ	$53, AX
294	SYSCALL
295	JCC	2(PC)
296	MOVL	$0xf1, 0xf1  // crash
297	RET
298
299TEXT runtime·usleep(SB),NOSPLIT,$16
300	MOVL	$0, DX
301	MOVL	usec+0(FP), AX
302	MOVL	$1000000, CX
303	DIVL	CX
304	MOVQ	AX, 0(SP)		// tv_sec
305	MOVL	$1000, AX
306	MULL	DX
307	MOVQ	AX, 8(SP)		// tv_nsec
308
309	MOVQ	SP, DI			// arg 1 - rqtp
310	MOVQ	$0, SI			// arg 2 - rmtp
311	MOVL	$240, AX		// sys_nanosleep
312	SYSCALL
313	RET
314
315// set tls base to DI
316TEXT runtime·settls(SB),NOSPLIT,$16
317	ADDQ	$8, DI	// adjust for ELF: wants to use -8(FS) for g
318	MOVQ	DI, 0(SP)
319	MOVQ	$16, 8(SP)
320	MOVQ	$0, DI			// arg 1 - which
321	MOVQ	SP, SI			// arg 2 - tls_info
322	MOVQ	$16, DX			// arg 3 - infosize
323	MOVQ	$472, AX		// set_tls_area
324	SYSCALL
325	JCC	2(PC)
326	MOVL	$0xf1, 0xf1  // crash
327	RET
328
329TEXT runtime·sysctl(SB),NOSPLIT,$0
330	MOVQ	mib+0(FP), DI		// arg 1 - name
331	MOVL	miblen+8(FP), SI		// arg 2 - namelen
332	MOVQ	out+16(FP), DX		// arg 3 - oldp
333	MOVQ	size+24(FP), R10		// arg 4 - oldlenp
334	MOVQ	dst+32(FP), R8		// arg 5 - newp
335	MOVQ	ndst+40(FP), R9		// arg 6 - newlen
336	MOVQ	$202, AX		// sys___sysctl
337	SYSCALL
338	JCC 4(PC)
339	NEGQ	AX
340	MOVL	AX, ret+48(FP)
341	RET
342	MOVL	$0, AX
343	MOVL	AX, ret+48(FP)
344	RET
345
346TEXT runtime·osyield(SB),NOSPLIT,$-4
347	MOVL	$331, AX		// sys_sched_yield
348	SYSCALL
349	RET
350
351TEXT runtime·sigprocmask(SB),NOSPLIT,$0
352	MOVL	how+0(FP), DI		// arg 1 - how
353	MOVQ	new+8(FP), SI		// arg 2 - set
354	MOVQ	old+16(FP), DX		// arg 3 - oset
355	MOVL	$340, AX		// sys_sigprocmask
356	SYSCALL
357	JAE	2(PC)
358	MOVL	$0xf1, 0xf1  // crash
359	RET
360
361// int32 runtime·kqueue(void);
362TEXT runtime·kqueue(SB),NOSPLIT,$0
363	MOVQ	$0, DI
364	MOVQ	$0, SI
365	MOVQ	$0, DX
366	MOVL	$362, AX
367	SYSCALL
368	JCC	2(PC)
369	NEGQ	AX
370	MOVL	AX, ret+0(FP)
371	RET
372
373// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
374TEXT runtime·kevent(SB),NOSPLIT,$0
375	MOVL	kq+0(FP), DI
376	MOVQ	ch+8(FP), SI
377	MOVL	nch+16(FP), DX
378	MOVQ	ev+24(FP), R10
379	MOVL	nev+32(FP), R8
380	MOVQ	ts+40(FP), R9
381	MOVL	$363, AX
382	SYSCALL
383	JCC	2(PC)
384	NEGQ	AX
385	MOVL	AX, ret+48(FP)
386	RET
387
388// func fcntl(fd, cmd, arg int32) (ret int32, errno int32)
389TEXT runtime·fcntl(SB),NOSPLIT,$0
390	MOVL	fd+0(FP), DI	// fd
391	MOVL	cmd+4(FP), SI	// cmd
392	MOVL	arg+8(FP), DX	// arg
393	MOVL	$92, AX		// fcntl
394	SYSCALL
395	JCC	noerr
396	MOVL	$-1, ret+16(FP)
397	MOVL	AX, errno+20(FP)
398	RET
399noerr:
400	MOVL	AX, ret+16(FP)
401	MOVL	$0, errno+20(FP)
402	RET
403
404// func issetugid() int32
405TEXT runtime·issetugid(SB),NOSPLIT,$0
406	MOVQ	$0, DI
407	MOVQ	$0, SI
408	MOVQ	$0, DX
409	MOVL	$253, AX
410	SYSCALL
411	MOVL	AX, ret+0(FP)
412	RET
413