blob: abc5d3297ab3ea57aad6538c42a02bc01ef61b10 [file] [log] [blame]
Russ Cox4702c0e2009-03-31 15:45:12 -07001// 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, Darwin
6// See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228
7// or /usr/include/sys/syscall.h (on a Mac) for system call numbers.
8
Russ Cox15ced2d2014-11-11 17:06:22 -05009#include "go_asm.h"
10#include "go_tls.h"
Russ Coxcb040d52014-09-04 23:05:18 -040011#include "textflag.h"
Russ Cox8522a472009-06-17 15:15:55 -070012
Russ Cox4702c0e2009-03-31 15:45:12 -070013// Exit the entire program (like C exit)
Keith Randall0273dc12013-08-07 12:20:05 -070014TEXT runtime·exit(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -070015 MOVL $1, AX
16 INT $0x80
Russ Cox36aa7d42012-03-08 14:03:56 -050017 MOVL $0xf1, 0xf1 // crash
Russ Cox4702c0e2009-03-31 15:45:12 -070018 RET
19
20// Exit this OS thread (like pthread_exit, which eventually
21// calls __bsdthread_terminate).
Keith Randall0273dc12013-08-07 12:20:05 -070022TEXT runtime·exit1(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -070023 MOVL $361, AX
24 INT $0x80
25 JAE 2(PC)
Russ Cox36aa7d42012-03-08 14:03:56 -050026 MOVL $0xf1, 0xf1 // crash
Russ Cox4702c0e2009-03-31 15:45:12 -070027 RET
28
Keith Randall0273dc12013-08-07 12:20:05 -070029TEXT runtime·open(SB),NOSPLIT,$0
Keith Randalla5d40242013-03-12 10:47:44 -070030 MOVL $5, AX
31 INT $0x80
Keith Randallf584c052015-03-02 20:16:48 -080032 JAE 2(PC)
33 MOVL $-1, AX
Russ Cox25f6b022014-08-27 11:32:17 -040034 MOVL AX, ret+12(FP)
Keith Randalla5d40242013-03-12 10:47:44 -070035 RET
36
David Crawshawcea272d2015-04-13 19:37:04 -040037TEXT runtime·closefd(SB),NOSPLIT,$0
Keith Randalla5d40242013-03-12 10:47:44 -070038 MOVL $6, AX
39 INT $0x80
Keith Randallf584c052015-03-02 20:16:48 -080040 JAE 2(PC)
41 MOVL $-1, AX
Russ Cox25f6b022014-08-27 11:32:17 -040042 MOVL AX, ret+4(FP)
Keith Randalla5d40242013-03-12 10:47:44 -070043 RET
44
Keith Randall0273dc12013-08-07 12:20:05 -070045TEXT runtime·read(SB),NOSPLIT,$0
Keith Randalla5d40242013-03-12 10:47:44 -070046 MOVL $3, AX
47 INT $0x80
Keith Randallf584c052015-03-02 20:16:48 -080048 JAE 2(PC)
49 MOVL $-1, AX
Russ Cox25f6b022014-08-27 11:32:17 -040050 MOVL AX, ret+12(FP)
Keith Randalla5d40242013-03-12 10:47:44 -070051 RET
52
Keith Randall0273dc12013-08-07 12:20:05 -070053TEXT runtime·write(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -070054 MOVL $4, AX
55 INT $0x80
Keith Randallf584c052015-03-02 20:16:48 -080056 JAE 2(PC)
57 MOVL $-1, AX
Russ Cox25f6b022014-08-27 11:32:17 -040058 MOVL AX, ret+12(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -070059 RET
60
Russ Cox5bfed7c2015-01-14 11:18:24 -050061TEXT runtime·raise(SB),NOSPLIT,$0
62 // Ideally we'd send the signal to the current thread,
63 // not the whole process, but that's too hard on OS X.
64 JMP runtime·raiseproc(SB)
65
66TEXT runtime·raiseproc(SB),NOSPLIT,$16
Russ Cox5146a932013-03-15 01:11:03 -040067 MOVL $20, AX // getpid
68 INT $0x80
69 MOVL AX, 4(SP) // pid
70 MOVL sig+0(FP), AX
71 MOVL AX, 8(SP) // signal
72 MOVL $1, 12(SP) // posix
73 MOVL $37, AX // kill
Russ Cox8698bb62011-04-25 16:58:00 -040074 INT $0x80
75 RET
76
Keith Randall0273dc12013-08-07 12:20:05 -070077TEXT runtime·mmap(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -070078 MOVL $197, AX
79 INT $0x80
Russ Cox25f6b022014-08-27 11:32:17 -040080 MOVL AX, ret+24(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -070081 RET
82
Keith Randall0273dc12013-08-07 12:20:05 -070083TEXT runtime·madvise(SB),NOSPLIT,$0
Dave Cheneyc354f932012-01-19 15:51:29 -050084 MOVL $75, AX
85 INT $0x80
Russ Cox295a4d82012-12-22 15:06:28 -050086 // ignore failure - maybe pages are locked
Dave Cheneyc354f932012-01-19 15:51:29 -050087 RET
88
Keith Randall0273dc12013-08-07 12:20:05 -070089TEXT runtime·munmap(SB),NOSPLIT,$0
Russ Coxd4cc5572010-09-07 09:57:22 -040090 MOVL $73, AX
91 INT $0x80
92 JAE 2(PC)
Russ Cox36aa7d42012-03-08 14:03:56 -050093 MOVL $0xf1, 0xf1 // crash
Russ Coxd4cc5572010-09-07 09:57:22 -040094 RET
95
Keith Randall0273dc12013-08-07 12:20:05 -070096TEXT runtime·setitimer(SB),NOSPLIT,$0
Russ Cox8dee8722011-03-23 11:31:42 -040097 MOVL $83, AX
98 INT $0x80
99 RET
100
Russ Coxc7be4de2012-06-05 16:23:30 -0400101// OS X comm page time offsets
102// http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/i386/cpu_capabilities.h
103#define cpu_capabilities 0x20
104#define nt_tsc_base 0x50
105#define nt_scale 0x58
106#define nt_shift 0x5c
107#define nt_ns_base 0x60
108#define nt_generation 0x68
109#define gtod_generation 0x6c
110#define gtod_ns_base 0x70
111#define gtod_sec_base 0x78
Russ Coxefe3d352011-11-30 11:59:44 -0500112
Russ Coxc7be4de2012-06-05 16:23:30 -0400113// called from assembly
114// 64-bit unix nanoseconds returned in DX:AX.
115// I'd much rather write this in C but we need
116// assembly for the 96-bit multiply and RDTSC.
Keith Randall0273dc12013-08-07 12:20:05 -0700117TEXT runtime·now(SB),NOSPLIT,$40
Russ Coxc7be4de2012-06-05 16:23:30 -0400118 MOVL $0xffff0000, BP /* comm page base */
119
120 // Test for slow CPU. If so, the math is completely
121 // different, and unimplemented here, so use the
122 // system call.
123 MOVL cpu_capabilities(BP), AX
124 TESTL $0x4000, AX
125 JNZ systime
126
127 // Loop trying to take a consistent snapshot
128 // of the time parameters.
129timeloop:
130 MOVL gtod_generation(BP), BX
131 TESTL BX, BX
132 JZ systime
133 MOVL nt_generation(BP), CX
134 TESTL CX, CX
135 JZ timeloop
136 RDTSC
137 MOVL nt_tsc_base(BP), SI
138 MOVL (nt_tsc_base+4)(BP), DI
139 MOVL SI, 0(SP)
140 MOVL DI, 4(SP)
141 MOVL nt_scale(BP), SI
142 MOVL SI, 8(SP)
143 MOVL nt_ns_base(BP), SI
144 MOVL (nt_ns_base+4)(BP), DI
145 MOVL SI, 12(SP)
146 MOVL DI, 16(SP)
147 CMPL nt_generation(BP), CX
148 JNE timeloop
149 MOVL gtod_ns_base(BP), SI
150 MOVL (gtod_ns_base+4)(BP), DI
151 MOVL SI, 20(SP)
152 MOVL DI, 24(SP)
153 MOVL gtod_sec_base(BP), SI
154 MOVL (gtod_sec_base+4)(BP), DI
155 MOVL SI, 28(SP)
156 MOVL DI, 32(SP)
157 CMPL gtod_generation(BP), BX
158 JNE timeloop
159
160 // Gathered all the data we need. Compute time.
161 // ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base - gtod_ns_base + gtod_sec_base*1e9
162 // The multiply and shift extracts the top 64 bits of the 96-bit product.
163 SUBL 0(SP), AX // DX:AX = (tsc - nt_tsc_base)
164 SBBL 4(SP), DX
165
166 // We have x = tsc - nt_tsc_base - DX:AX to be
167 // multiplied by y = nt_scale = 8(SP), keeping the top 64 bits of the 96-bit product.
168 // x*y = (x&0xffffffff)*y + (x&0xffffffff00000000)*y
169 // (x*y)>>32 = ((x&0xffffffff)*y)>>32 + (x>>32)*y
170 MOVL DX, CX // SI = (x&0xffffffff)*y >> 32
171 MOVL $0, DX
172 MULL 8(SP)
173 MOVL DX, SI
174
175 MOVL CX, AX // DX:AX = (x>>32)*y
176 MOVL $0, DX
177 MULL 8(SP)
178
179 ADDL SI, AX // DX:AX += (x&0xffffffff)*y >> 32
180 ADCL $0, DX
181
182 // DX:AX is now ((tsc - nt_tsc_base) * nt_scale) >> 32.
183 ADDL 12(SP), AX // DX:AX += nt_ns_base
184 ADCL 16(SP), DX
185 SUBL 20(SP), AX // DX:AX -= gtod_ns_base
186 SBBL 24(SP), DX
187 MOVL AX, SI // DI:SI = DX:AX
188 MOVL DX, DI
189 MOVL 28(SP), AX // DX:AX = gtod_sec_base*1e9
190 MOVL 32(SP), DX
191 MOVL $1000000000, CX
192 MULL CX
193 ADDL SI, AX // DX:AX += DI:SI
194 ADCL DI, DX
Russ Coxefe3d352011-11-30 11:59:44 -0500195 RET
196
Russ Coxc7be4de2012-06-05 16:23:30 -0400197systime:
198 // Fall back to system call (usually first call in this thread)
Russ Coxe4f06812010-02-08 14:32:22 -0800199 LEAL 12(SP), AX // must be non-nil, unused
200 MOVL AX, 4(SP)
201 MOVL $0, 8(SP) // time zone pointer
202 MOVL $116, AX
203 INT $0x80
Russ Coxc7be4de2012-06-05 16:23:30 -0400204 // sec is in AX, usec in DX
Russ Coxf4373312011-11-03 17:35:28 -0400205 // convert to DX:AX nsec
Russ Coxc7be4de2012-06-05 16:23:30 -0400206 MOVL DX, BX
Russ Coxf4373312011-11-03 17:35:28 -0400207 MOVL $1000000000, CX
208 MULL CX
209 IMULL $1000, BX
210 ADDL BX, AX
211 ADCL $0, DX
Russ Coxc7be4de2012-06-05 16:23:30 -0400212 RET
Russ Cox6e2ae0a2012-02-28 16:18:24 -0500213
Russ Coxc7be4de2012-06-05 16:23:30 -0400214// func now() (sec int64, nsec int32)
Keith Randall0273dc12013-08-07 12:20:05 -0700215TEXT time·now(SB),NOSPLIT,$0
Russ Coxc7be4de2012-06-05 16:23:30 -0400216 CALL runtime·now(SB)
217 MOVL $1000000000, CX
218 DIVL CX
219 MOVL AX, sec+0(FP)
220 MOVL $0, sec+4(FP)
221 MOVL DX, nsec+8(FP)
222 RET
223
Michael Matlooba1733572015-01-23 17:56:47 -0800224// func nanotime() int64
Keith Randall0273dc12013-08-07 12:20:05 -0700225TEXT runtime·nanotime(SB),NOSPLIT,$0
Russ Coxc7be4de2012-06-05 16:23:30 -0400226 CALL runtime·now(SB)
Russ Cox25f6b022014-08-27 11:32:17 -0400227 MOVL AX, ret_lo+0(FP)
228 MOVL DX, ret_hi+4(FP)
Russ Coxe4f06812010-02-08 14:32:22 -0800229 RET
230
Keith Randall0273dc12013-08-07 12:20:05 -0700231TEXT runtime·sigprocmask(SB),NOSPLIT,$0
Russ Cox6e2ae0a2012-02-28 16:18:24 -0500232 MOVL $329, AX // pthread_sigmask (on OS X, sigprocmask==entire process)
Russ Cox224f05b2012-02-23 14:44:06 -0500233 INT $0x80
234 JAE 2(PC)
Russ Cox36aa7d42012-03-08 14:03:56 -0500235 MOVL $0xf1, 0xf1 // crash
Russ Cox224f05b2012-02-23 14:44:06 -0500236 RET
237
Keith Randall0273dc12013-08-07 12:20:05 -0700238TEXT runtime·sigaction(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700239 MOVL $46, AX
240 INT $0x80
241 JAE 2(PC)
Russ Cox36aa7d42012-03-08 14:03:56 -0500242 MOVL $0xf1, 0xf1 // crash
Russ Cox4702c0e2009-03-31 15:45:12 -0700243 RET
244
245// Sigtramp's job is to call the actual signal handler.
246// It is called with the following arguments on the stack:
247// 0(FP) "return address" - ignored
248// 4(FP) actual handler
Alan Donovan532dee32012-09-04 14:40:49 -0400249// 8(FP) signal number
250// 12(FP) siginfo style
Russ Cox4702c0e2009-03-31 15:45:12 -0700251// 16(FP) siginfo
252// 20(FP) context
Keith Randall0273dc12013-08-07 12:20:05 -0700253TEXT runtime·sigtramp(SB),NOSPLIT,$40
Hector Chu6bfe5f52010-01-06 17:58:55 -0800254 get_tls(CX)
Russ Coxb2369112012-03-12 15:55:18 -0400255
Russ Cox89f185f2014-06-26 11:54:39 -0400256 // check that g exists
257 MOVL g(CX), DI
258 CMPL DI, $0
Shenghou Ma2f1ead72013-07-12 04:39:39 +0800259 JNE 6(PC)
Alan Donovan532dee32012-09-04 14:40:49 -0400260 MOVL sig+8(FP), BX
261 MOVL BX, 0(SP)
Shenghou Ma2f1ead72013-07-12 04:39:39 +0800262 MOVL $runtime·badsignal(SB), AX
263 CALL AX
Russ Coxb55791e2014-10-28 21:50:16 -0400264 JMP ret
Russ Cox53a529a2010-06-12 10:48:04 -0700265
266 // save g
Russ Cox690291a2011-02-23 14:47:42 -0500267 MOVL DI, 20(SP)
Russ Coxd324f212011-09-30 09:40:01 -0400268
Russ Cox53a529a2010-06-12 10:48:04 -0700269 // g = m->gsignal
Russ Cox89f185f2014-06-26 11:54:39 -0400270 MOVL g_m(DI), BP
Russ Cox8522a472009-06-17 15:15:55 -0700271 MOVL m_gsignal(BP), BP
Hector Chu6bfe5f52010-01-06 17:58:55 -0800272 MOVL BP, g(CX)
Russ Cox4702c0e2009-03-31 15:45:12 -0700273
Russ Cox690291a2011-02-23 14:47:42 -0500274 // copy arguments to sighandler
275 MOVL sig+8(FP), BX
276 MOVL BX, 0(SP)
277 MOVL info+12(FP), BX
Russ Cox4702c0e2009-03-31 15:45:12 -0700278 MOVL BX, 4(SP)
Russ Cox690291a2011-02-23 14:47:42 -0500279 MOVL context+16(FP), BX
280 MOVL BX, 8(SP)
281 MOVL DI, 12(SP)
Russ Coxd324f212011-09-30 09:40:01 -0400282
Russ Cox690291a2011-02-23 14:47:42 -0500283 MOVL handler+0(FP), BX
284 CALL BX
Russ Cox4702c0e2009-03-31 15:45:12 -0700285
Russ Cox53a529a2010-06-12 10:48:04 -0700286 // restore g
Hector Chu6bfe5f52010-01-06 17:58:55 -0800287 get_tls(CX)
Russ Cox690291a2011-02-23 14:47:42 -0500288 MOVL 20(SP), DI
289 MOVL DI, g(CX)
Russ Cox597b2a92009-11-16 17:51:47 -0800290
Russ Coxb55791e2014-10-28 21:50:16 -0400291ret:
Russ Cox690291a2011-02-23 14:47:42 -0500292 // call sigreturn
Russ Cox597b2a92009-11-16 17:51:47 -0800293 MOVL context+16(FP), CX
294 MOVL style+4(FP), BX
Russ Cox4702c0e2009-03-31 15:45:12 -0700295 MOVL $0, 0(SP) // "caller PC" - ignored
296 MOVL CX, 4(SP)
297 MOVL BX, 8(SP)
298 MOVL $184, AX // sigreturn(ucontext, infostyle)
299 INT $0x80
Russ Cox36aa7d42012-03-08 14:03:56 -0500300 MOVL $0xf1, 0xf1 // crash
Russ Cox4702c0e2009-03-31 15:45:12 -0700301 RET
302
Keith Randall0273dc12013-08-07 12:20:05 -0700303TEXT runtime·sigaltstack(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700304 MOVL $53, AX
305 INT $0x80
306 JAE 2(PC)
Russ Cox36aa7d42012-03-08 14:03:56 -0500307 MOVL $0xf1, 0xf1 // crash
Russ Cox4702c0e2009-03-31 15:45:12 -0700308 RET
309
Keith Randall0273dc12013-08-07 12:20:05 -0700310TEXT runtime·usleep(SB),NOSPLIT,$32
Russ Coxd324f212011-09-30 09:40:01 -0400311 MOVL $0, DX
312 MOVL usec+0(FP), AX
313 MOVL $1000000, CX
314 DIVL CX
315 MOVL AX, 24(SP) // sec
316 MOVL DX, 28(SP) // usec
317
318 // select(0, 0, 0, 0, &tv)
319 MOVL $0, 0(SP) // "return PC" - ignored
320 MOVL $0, 4(SP)
321 MOVL $0, 8(SP)
322 MOVL $0, 12(SP)
323 MOVL $0, 16(SP)
324 LEAL 24(SP), AX
325 MOVL AX, 20(SP)
326 MOVL $93, AX
327 INT $0x80
328 RET
329
David Crawshawc844bf42015-04-08 19:44:14 -0400330// func bsdthread_create(stk, arg unsafe.Pointer, fn uintptr) int32
Russ Cox3a0df4c2009-06-04 11:16:03 -0700331// System call args are: func arg stack pthread flags.
Keith Randall0273dc12013-08-07 12:20:05 -0700332TEXT runtime·bsdthread_create(SB),NOSPLIT,$32
Russ Cox4702c0e2009-03-31 15:45:12 -0700333 MOVL $360, AX
Russ Cox3a0df4c2009-06-04 11:16:03 -0700334 // 0(SP) is where the caller PC would be; kernel skips it
David Crawshawc844bf42015-04-08 19:44:14 -0400335 MOVL fn+8(FP), BX
Russ Cox3a0df4c2009-06-04 11:16:03 -0700336 MOVL BX, 4(SP) // func
David Crawshawc844bf42015-04-08 19:44:14 -0400337 MOVL arg+4(FP), BX
Russ Cox3a0df4c2009-06-04 11:16:03 -0700338 MOVL BX, 8(SP) // arg
339 MOVL stk+0(FP), BX
340 MOVL BX, 12(SP) // stack
David Crawshawc844bf42015-04-08 19:44:14 -0400341 MOVL $0, 16(SP) // pthread
Russ Cox3a0df4c2009-06-04 11:16:03 -0700342 MOVL $0x1000000, 20(SP) // flags = PTHREAD_START_CUSTOM
Russ Cox4702c0e2009-03-31 15:45:12 -0700343 INT $0x80
Russ Cox25f6b022014-08-27 11:32:17 -0400344 JAE 4(PC)
Russ Cox4608feb2011-01-28 15:03:26 -0500345 NEGL AX
David Crawshawc844bf42015-04-08 19:44:14 -0400346 MOVL AX, ret+12(FP)
Russ Cox718da332010-04-28 19:36:42 -0700347 RET
348 MOVL $0, AX
David Crawshawc844bf42015-04-08 19:44:14 -0400349 MOVL AX, ret+12(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -0700350 RET
351
Russ Cox3a0df4c2009-06-04 11:16:03 -0700352// The thread that bsdthread_create creates starts executing here,
353// because we registered this function using bsdthread_register
354// at startup.
David Crawshawc844bf42015-04-08 19:44:14 -0400355// AX = "pthread" (= 0x0)
Russ Cox3a0df4c2009-06-04 11:16:03 -0700356// BX = mach thread port
357// CX = "func" (= fn)
358// DX = "arg" (= m)
359// DI = stack top
360// SI = flags (= 0x1000000)
361// SP = stack - C_32_STK_ALIGN
Keith Randall0273dc12013-08-07 12:20:05 -0700362TEXT runtime·bsdthread_start(SB),NOSPLIT,$0
Russ Cox3a0df4c2009-06-04 11:16:03 -0700363 // set up ldt 7+id to point at m->tls.
364 // m->tls is at m+40. newosproc left
365 // the m->id in tls[0].
Russ Cox8522a472009-06-17 15:15:55 -0700366 LEAL m_tls(DX), BP
Russ Cox3a0df4c2009-06-04 11:16:03 -0700367 MOVL 0(BP), DI
368 ADDL $7, DI // m0 is LDT#7. count up.
369 // setldt(tls#, &tls, sizeof tls)
370 PUSHAL // save registers
371 PUSHL $32 // sizeof tls
372 PUSHL BP // &tls
373 PUSHL DI // tls #
Russ Cox68b42552010-11-04 14:00:19 -0400374 CALL runtime·setldt(SB)
Russ Cox3a0df4c2009-06-04 11:16:03 -0700375 POPL AX
376 POPL AX
377 POPL AX
378 POPAL
Russ Cox3a0df4c2009-06-04 11:16:03 -0700379
380 // Now segment is established. Initialize m, g.
Hector Chu6bfe5f52010-01-06 17:58:55 -0800381 get_tls(BP)
David Crawshawc844bf42015-04-08 19:44:14 -0400382 MOVL m_g0(DX), AX
Hector Chu6bfe5f52010-01-06 17:58:55 -0800383 MOVL AX, g(BP)
Russ Cox89f185f2014-06-26 11:54:39 -0400384 MOVL DX, g_m(AX)
Russ Cox8522a472009-06-17 15:15:55 -0700385 MOVL BX, m_procid(DX) // m->procid = thread port (for debuggers)
Russ Cox68b42552010-11-04 14:00:19 -0400386 CALL runtime·stackcheck(SB) // smashes AX
Russ Cox3a0df4c2009-06-04 11:16:03 -0700387 CALL CX // fn()
Russ Cox68b42552010-11-04 14:00:19 -0400388 CALL runtime·exit1(SB)
Russ Cox6b070212009-04-02 16:48:06 -0700389 RET
390
Michael Matlooba1733572015-01-23 17:56:47 -0800391// func bsdthread_register() int32
Russ Cox3a0df4c2009-06-04 11:16:03 -0700392// registers callbacks for threadstart (see bsdthread_create above
393// and wqthread and pthsize (not used). returns 0 on success.
Keith Randall0273dc12013-08-07 12:20:05 -0700394TEXT runtime·bsdthread_register(SB),NOSPLIT,$40
Russ Cox4702c0e2009-03-31 15:45:12 -0700395 MOVL $366, AX
Russ Cox3a0df4c2009-06-04 11:16:03 -0700396 // 0(SP) is where kernel expects caller PC; ignored
Russ Cox68b42552010-11-04 14:00:19 -0400397 MOVL $runtime·bsdthread_start(SB), 4(SP) // threadstart
Russ Cox3a0df4c2009-06-04 11:16:03 -0700398 MOVL $0, 8(SP) // wqthread, not used by us
399 MOVL $0, 12(SP) // pthsize, not used by us
Russ Cox2f0cae42010-04-08 13:24:37 -0700400 MOVL $0, 16(SP) // dummy_value [sic]
401 MOVL $0, 20(SP) // targetconc_ptr
402 MOVL $0, 24(SP) // dispatchqueue_offset
Russ Cox4702c0e2009-03-31 15:45:12 -0700403 INT $0x80
Russ Cox25f6b022014-08-27 11:32:17 -0400404 JAE 4(PC)
Shenghou Ma44fd1d12012-04-30 15:55:07 -0400405 NEGL AX
Russ Cox25f6b022014-08-27 11:32:17 -0400406 MOVL AX, ret+0(FP)
Shenghou Ma44fd1d12012-04-30 15:55:07 -0400407 RET
408 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400409 MOVL AX, ret+0(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -0700410 RET
411
412// Invoke Mach system call.
413// Assumes system call number in AX,
414// caller PC on stack, caller's caller PC next,
415// and then the system call arguments.
416//
417// Can be used for BSD too, but we don't,
418// because if you use this interface the BSD
419// system call numbers need an extra field
420// in the high 16 bits that seems to be the
421// argument count in bytes but is not always.
422// INT $0x80 works fine for those.
Keith Randall0273dc12013-08-07 12:20:05 -0700423TEXT runtime·sysenter(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700424 POPL DX
425 MOVL SP, CX
426 BYTE $0x0F; BYTE $0x34; // SYSENTER
427 // returns to DX with SP set to CX
428
Keith Randall0273dc12013-08-07 12:20:05 -0700429TEXT runtime·mach_msg_trap(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700430 MOVL $-31, AX
Russ Cox68b42552010-11-04 14:00:19 -0400431 CALL runtime·sysenter(SB)
Russ Cox25f6b022014-08-27 11:32:17 -0400432 MOVL AX, ret+28(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -0700433 RET
434
Keith Randall0273dc12013-08-07 12:20:05 -0700435TEXT runtime·mach_reply_port(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700436 MOVL $-26, AX
Russ Cox68b42552010-11-04 14:00:19 -0400437 CALL runtime·sysenter(SB)
Russ Cox25f6b022014-08-27 11:32:17 -0400438 MOVL AX, ret+0(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -0700439 RET
440
Keith Randall0273dc12013-08-07 12:20:05 -0700441TEXT runtime·mach_task_self(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700442 MOVL $-28, AX
Russ Cox68b42552010-11-04 14:00:19 -0400443 CALL runtime·sysenter(SB)
Russ Cox25f6b022014-08-27 11:32:17 -0400444 MOVL AX, ret+0(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -0700445 RET
446
447// Mach provides trap versions of the semaphore ops,
448// instead of requiring the use of RPC.
449
Michael Matlooba1733572015-01-23 17:56:47 -0800450// func mach_semaphore_wait(sema uint32) int32
Keith Randall0273dc12013-08-07 12:20:05 -0700451TEXT runtime·mach_semaphore_wait(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700452 MOVL $-36, AX
Russ Cox68b42552010-11-04 14:00:19 -0400453 CALL runtime·sysenter(SB)
Russ Cox25f6b022014-08-27 11:32:17 -0400454 MOVL AX, ret+4(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -0700455 RET
456
Michael Matlooba1733572015-01-23 17:56:47 -0800457// func mach_semaphore_timedwait(sema, sec, nsec uint32) int32
Keith Randall0273dc12013-08-07 12:20:05 -0700458TEXT runtime·mach_semaphore_timedwait(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700459 MOVL $-38, AX
Russ Cox68b42552010-11-04 14:00:19 -0400460 CALL runtime·sysenter(SB)
Russ Cox25f6b022014-08-27 11:32:17 -0400461 MOVL AX, ret+12(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -0700462 RET
463
Michael Matlooba1733572015-01-23 17:56:47 -0800464// func mach_semaphore_signal(sema uint32) int32
Keith Randall0273dc12013-08-07 12:20:05 -0700465TEXT runtime·mach_semaphore_signal(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700466 MOVL $-33, AX
Russ Cox68b42552010-11-04 14:00:19 -0400467 CALL runtime·sysenter(SB)
Russ Cox25f6b022014-08-27 11:32:17 -0400468 MOVL AX, ret+4(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -0700469 RET
470
Michael Matlooba1733572015-01-23 17:56:47 -0800471// func mach_semaphore_signal_all(sema uint32) int32
Keith Randall0273dc12013-08-07 12:20:05 -0700472TEXT runtime·mach_semaphore_signal_all(SB),NOSPLIT,$0
Russ Cox4702c0e2009-03-31 15:45:12 -0700473 MOVL $-34, AX
Russ Cox68b42552010-11-04 14:00:19 -0400474 CALL runtime·sysenter(SB)
Russ Cox25f6b022014-08-27 11:32:17 -0400475 MOVL AX, ret+4(FP)
Russ Cox4702c0e2009-03-31 15:45:12 -0700476 RET
477
Michael Matlooba1733572015-01-23 17:56:47 -0800478// func setldt(entry int, address int, limit int)
Russ Cox2f0cae42010-04-08 13:24:37 -0700479// entry and limit are ignored.
Keith Randall0273dc12013-08-07 12:20:05 -0700480TEXT runtime·setldt(SB),NOSPLIT,$32
Russ Cox133a1582009-10-03 10:37:12 -0700481 MOVL address+4(FP), BX // aka base
Russ Cox133a1582009-10-03 10:37:12 -0700482
483 /*
484 * When linking against the system libraries,
485 * we use its pthread_create and let it set up %gs
486 * for us. When we do that, the private storage
487 * we get is not at 0(GS) but at 0x468(GS).
Russ Cox90093f02014-04-15 13:45:39 -0400488 * 8l rewrites 0(TLS) into 0x468(GS) for us.
Russ Cox133a1582009-10-03 10:37:12 -0700489 * To accommodate that rewrite, we translate the
490 * address and limit here so that 0x468(GS) maps to 0(address).
491 *
Shenghou Mafec7aa92012-01-19 17:13:33 -0500492 * See cgo/gcc_darwin_386.c:/468 for the derivation
Russ Cox133a1582009-10-03 10:37:12 -0700493 * of the constant.
494 */
495 SUBL $0x468, BX
Russ Cox133a1582009-10-03 10:37:12 -0700496
Russ Cox2f0cae42010-04-08 13:24:37 -0700497 /*
498 * Must set up as USER_CTHREAD segment because
499 * Darwin forces that value into %gs for signal handlers,
500 * and if we don't set one up, we'll get a recursive
501 * fault trying to get into the signal handler.
502 * Since we have to set one up anyway, it might as
503 * well be the value we want. So don't bother with
504 * i386_set_ldt.
505 */
506 MOVL BX, 4(SP)
507 MOVL $3, AX // thread_fast_set_cthread_self - machdep call #3
508 INT $0x82 // sic: 0x82, not 0x80, for machdep call
Russ Cox4702c0e2009-03-31 15:45:12 -0700509
Russ Cox2f0cae42010-04-08 13:24:37 -0700510 XORL AX, AX
511 MOVW GS, AX
Russ Cox4702c0e2009-03-31 15:45:12 -0700512 RET
Russ Coxd324f212011-09-30 09:40:01 -0400513
Keith Randall0273dc12013-08-07 12:20:05 -0700514TEXT runtime·sysctl(SB),NOSPLIT,$0
Russ Coxd324f212011-09-30 09:40:01 -0400515 MOVL $202, AX
516 INT $0x80
Russ Cox25f6b022014-08-27 11:32:17 -0400517 JAE 4(PC)
Russ Coxd324f212011-09-30 09:40:01 -0400518 NEGL AX
Russ Cox25f6b022014-08-27 11:32:17 -0400519 MOVL AX, ret+24(FP)
Russ Coxd324f212011-09-30 09:40:01 -0400520 RET
521 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400522 MOVL AX, ret+24(FP)
Russ Coxd324f212011-09-30 09:40:01 -0400523 RET
Dmitriy Vyukov0bee99a2013-03-14 10:38:37 +0400524
Michael Matlooba1733572015-01-23 17:56:47 -0800525// func kqueue() int32
Keith Randall0273dc12013-08-07 12:20:05 -0700526TEXT runtime·kqueue(SB),NOSPLIT,$0
Dmitriy Vyukov0bee99a2013-03-14 10:38:37 +0400527 MOVL $362, AX
528 INT $0x80
529 JAE 2(PC)
530 NEGL AX
Russ Cox25f6b022014-08-27 11:32:17 -0400531 MOVL AX, ret+0(FP)
Dmitriy Vyukov0bee99a2013-03-14 10:38:37 +0400532 RET
533
Michael Matlooba1733572015-01-23 17:56:47 -0800534// func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
Keith Randall0273dc12013-08-07 12:20:05 -0700535TEXT runtime·kevent(SB),NOSPLIT,$0
Dmitriy Vyukov0bee99a2013-03-14 10:38:37 +0400536 MOVL $363, AX
537 INT $0x80
538 JAE 2(PC)
539 NEGL AX
Russ Cox25f6b022014-08-27 11:32:17 -0400540 MOVL AX, ret+24(FP)
Dmitriy Vyukov0bee99a2013-03-14 10:38:37 +0400541 RET
542
Michael Matlooba1733572015-01-23 17:56:47 -0800543// func closeonexec(fd int32)
Keith Randall0273dc12013-08-07 12:20:05 -0700544TEXT runtime·closeonexec(SB),NOSPLIT,$32
Dmitriy Vyukov0bee99a2013-03-14 10:38:37 +0400545 MOVL $92, AX // fcntl
546 // 0(SP) is where the caller PC would be; kernel skips it
547 MOVL fd+0(FP), BX
548 MOVL BX, 4(SP) // fd
549 MOVL $2, 8(SP) // F_SETFD
550 MOVL $1, 12(SP) // FD_CLOEXEC
551 INT $0x80
552 JAE 2(PC)
553 NEGL AX
554 RET