sys.s 6.92 KB
Newer Older
Russ Cox's avatar
Russ Cox committed
1 2 3 4 5 6 7 8
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// System calls and other sys.stuff for 386, Darwin
// See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228
// or /usr/include/sys/syscall.h (on a Mac) for system call numbers.

9 10
#include "386/asm.h"

11
TEXT runtime·notok(SB),7,$0
Russ Cox's avatar
Russ Cox committed
12 13 14 15
	MOVL	$0xf1, 0xf1
	RET

// Exit the entire program (like C exit)
16
TEXT runtime·exit(SB),7,$0
Russ Cox's avatar
Russ Cox committed
17 18
	MOVL	$1, AX
	INT	$0x80
19
	CALL	runtime·notok(SB)
Russ Cox's avatar
Russ Cox committed
20 21 22 23
	RET

// Exit this OS thread (like pthread_exit, which eventually
// calls __bsdthread_terminate).
24
TEXT runtime·exit1(SB),7,$0
Russ Cox's avatar
Russ Cox committed
25 26 27
	MOVL	$361, AX
	INT	$0x80
	JAE 2(PC)
28
	CALL	runtime·notok(SB)
Russ Cox's avatar
Russ Cox committed
29 30
	RET

31
TEXT runtime·write(SB),7,$0
Russ Cox's avatar
Russ Cox committed
32 33 34 35
	MOVL	$4, AX
	INT	$0x80
	RET

36
TEXT runtime·mmap(SB),7,$0
Russ Cox's avatar
Russ Cox committed
37 38 39 40
	MOVL	$197, AX
	INT	$0x80
	RET

41
TEXT runtime·munmap(SB),7,$0
42 43 44
	MOVL	$73, AX
	INT	$0x80
	JAE	2(PC)
45
	CALL	runtime·notok(SB)
46 47
	RET

48
// void gettime(int64 *sec, int32 *usec)
49
TEXT runtime·gettime(SB), 7, $32
50 51 52 53 54 55 56 57 58 59 60 61 62 63
	LEAL	12(SP), AX	// must be non-nil, unused
	MOVL	AX, 4(SP)
	MOVL	$0, 8(SP)	// time zone pointer
	MOVL	$116, AX
	INT	$0x80

	MOVL	sec+0(FP), DI
	MOVL	AX, (DI)
	MOVL	$0, 4(DI)	// zero extend 32 -> 64

	MOVL	usec+4(FP), DI
	MOVL	DX, (DI)
	RET

64
TEXT runtime·sigaction(SB),7,$0
Russ Cox's avatar
Russ Cox committed
65 66 67
	MOVL	$46, AX
	INT	$0x80
	JAE	2(PC)
68
	CALL	runtime·notok(SB)
Russ Cox's avatar
Russ Cox committed
69 70 71 72 73 74 75 76 77 78
	RET

// Sigtramp's job is to call the actual signal handler.
// It is called with the following arguments on the stack:
//	0(FP)	"return address" - ignored
//	4(FP)	actual handler
//	8(FP)	siginfo style - ignored
//	12(FP)	signal number
//	16(FP)	siginfo
//	20(FP)	context
79
TEXT runtime·sigtramp(SB),7,$40
Hector Chu's avatar
Hector Chu committed
80
	get_tls(CX)
81 82 83 84 85 86

	// save g
	MOVL	g(CX), BP
	MOVL	BP, 20(SP)
	
	// g = m->gsignal
Hector Chu's avatar
Hector Chu committed
87
	MOVL	m(CX), BP
88
	MOVL	m_gsignal(BP), BP
Hector Chu's avatar
Hector Chu committed
89
	MOVL	BP, g(CX)
Russ Cox's avatar
Russ Cox committed
90

91 92 93 94 95
	MOVL	handler+0(FP), DI
	// 4(FP) is sigstyle
	MOVL	signo+8(FP), AX
	MOVL	siginfo+12(FP), BX
	MOVL	context+16(FP), CX
Russ Cox's avatar
Russ Cox committed
96 97 98 99 100 101

	MOVL	AX, 0(SP)
	MOVL	BX, 4(SP)
	MOVL	CX, 8(SP)
	CALL	DI

102
	// restore g
Hector Chu's avatar
Hector Chu committed
103
	get_tls(CX)
104
	MOVL	20(SP), BP
Hector Chu's avatar
Hector Chu committed
105
	MOVL	BP, g(CX)
106 107 108

	MOVL	context+16(FP), CX
	MOVL	style+4(FP), BX
Russ Cox's avatar
Russ Cox committed
109 110 111 112 113 114

	MOVL	$0, 0(SP)	// "caller PC" - ignored
	MOVL	CX, 4(SP)
	MOVL	BX, 8(SP)
	MOVL	$184, AX	// sigreturn(ucontext, infostyle)
	INT	$0x80
115
	CALL	runtime·notok(SB)
Russ Cox's avatar
Russ Cox committed
116 117
	RET

118
TEXT runtime·sigaltstack(SB),7,$0
Russ Cox's avatar
Russ Cox committed
119 120 121
	MOVL	$53, AX
	INT	$0x80
	JAE	2(PC)
122
	CALL	runtime·notok(SB)
Russ Cox's avatar
Russ Cox committed
123 124
	RET

Russ Cox's avatar
Russ Cox committed
125 126
// void bsdthread_create(void *stk, M *m, G *g, void (*fn)(void))
// System call args are: func arg stack pthread flags.
127
TEXT runtime·bsdthread_create(SB),7,$32
Russ Cox's avatar
Russ Cox committed
128
	MOVL	$360, AX
Russ Cox's avatar
Russ Cox committed
129 130 131
	// 0(SP) is where the caller PC would be; kernel skips it
	MOVL	func+12(FP), BX
	MOVL	BX, 4(SP)	// func
132
	MOVL	mm+4(FP), BX
Russ Cox's avatar
Russ Cox committed
133 134 135
	MOVL	BX, 8(SP)	// arg
	MOVL	stk+0(FP), BX
	MOVL	BX, 12(SP)	// stack
136
	MOVL	gg+8(FP), BX
Russ Cox's avatar
Russ Cox committed
137 138
	MOVL	BX, 16(SP)	// pthread
	MOVL	$0x1000000, 20(SP)	// flags = PTHREAD_START_CUSTOM
Russ Cox's avatar
Russ Cox committed
139
	INT	$0x80
140
	JAE	3(PC)
141
	NEGL	AX
142 143
	RET
	MOVL	$0, AX
Russ Cox's avatar
Russ Cox committed
144 145
	RET

Russ Cox's avatar
Russ Cox committed
146 147 148 149 150 151 152 153 154 155
// The thread that bsdthread_create creates starts executing here,
// because we registered this function using bsdthread_register
// at startup.
//	AX = "pthread" (= g)
//	BX = mach thread port
//	CX = "func" (= fn)
//	DX = "arg" (= m)
//	DI = stack top
//	SI = flags (= 0x1000000)
//	SP = stack - C_32_STK_ALIGN
156
TEXT runtime·bsdthread_start(SB),7,$0
Russ Cox's avatar
Russ Cox committed
157 158 159
	// set up ldt 7+id to point at m->tls.
	// m->tls is at m+40.  newosproc left
	// the m->id in tls[0].
160
	LEAL	m_tls(DX), BP
Russ Cox's avatar
Russ Cox committed
161 162 163 164 165 166 167
	MOVL	0(BP), DI
	ADDL	$7, DI	// m0 is LDT#7. count up.
	// setldt(tls#, &tls, sizeof tls)
	PUSHAL	// save registers
	PUSHL	$32	// sizeof tls
	PUSHL	BP	// &tls
	PUSHL	DI	// tls #
168
	CALL	runtime·setldt(SB)
Russ Cox's avatar
Russ Cox committed
169 170 171 172 173 174
	POPL	AX
	POPL	AX
	POPL	AX
	POPAL

	// Now segment is established.  Initialize m, g.
Hector Chu's avatar
Hector Chu committed
175 176 177
	get_tls(BP)
	MOVL	AX, g(BP)
	MOVL	DX, m(BP)
178
	MOVL	BX, m_procid(DX)	// m->procid = thread port (for debuggers)
179
	CALL	runtime·stackcheck(SB)		// smashes AX
Russ Cox's avatar
Russ Cox committed
180
	CALL	CX	// fn()
181
	CALL	runtime·exit1(SB)
Russ Cox's avatar
Russ Cox committed
182 183
	RET

Russ Cox's avatar
Russ Cox committed
184 185 186
// void bsdthread_register(void)
// registers callbacks for threadstart (see bsdthread_create above
// and wqthread and pthsize (not used).  returns 0 on success.
187
TEXT runtime·bsdthread_register(SB),7,$40
Russ Cox's avatar
Russ Cox committed
188
	MOVL	$366, AX
Russ Cox's avatar
Russ Cox committed
189
	// 0(SP) is where kernel expects caller PC; ignored
190
	MOVL	$runtime·bsdthread_start(SB), 4(SP)	// threadstart
Russ Cox's avatar
Russ Cox committed
191 192
	MOVL	$0, 8(SP)	// wqthread, not used by us
	MOVL	$0, 12(SP)	// pthsize, not used by us
193 194 195
	MOVL	$0, 16(SP)	// dummy_value [sic]
	MOVL	$0, 20(SP)	// targetconc_ptr
	MOVL	$0, 24(SP)	// dispatchqueue_offset
Russ Cox's avatar
Russ Cox committed
196 197
	INT	$0x80
	JAE	2(PC)
198
	CALL	runtime·notok(SB)
Russ Cox's avatar
Russ Cox committed
199 200 201 202 203 204 205 206 207 208 209 210 211
	RET

// Invoke Mach system call.
// Assumes system call number in AX,
// caller PC on stack, caller's caller PC next,
// and then the system call arguments.
//
// Can be used for BSD too, but we don't,
// because if you use this interface the BSD
// system call numbers need an extra field
// in the high 16 bits that seems to be the
// argument count in bytes but is not always.
// INT $0x80 works fine for those.
212
TEXT runtime·sysenter(SB),7,$0
Russ Cox's avatar
Russ Cox committed
213 214 215 216 217
	POPL	DX
	MOVL	SP, CX
	BYTE $0x0F; BYTE $0x34;  // SYSENTER
	// returns to DX with SP set to CX

218
TEXT runtime·mach_msg_trap(SB),7,$0
Russ Cox's avatar
Russ Cox committed
219
	MOVL	$-31, AX
220
	CALL	runtime·sysenter(SB)
Russ Cox's avatar
Russ Cox committed
221 222
	RET

223
TEXT runtime·mach_reply_port(SB),7,$0
Russ Cox's avatar
Russ Cox committed
224
	MOVL	$-26, AX
225
	CALL	runtime·sysenter(SB)
Russ Cox's avatar
Russ Cox committed
226 227
	RET

228
TEXT runtime·mach_task_self(SB),7,$0
Russ Cox's avatar
Russ Cox committed
229
	MOVL	$-28, AX
230
	CALL	runtime·sysenter(SB)
Russ Cox's avatar
Russ Cox committed
231 232 233 234 235 236
	RET

// Mach provides trap versions of the semaphore ops,
// instead of requiring the use of RPC.

// uint32 mach_semaphore_wait(uint32)
237
TEXT runtime·mach_semaphore_wait(SB),7,$0
Russ Cox's avatar
Russ Cox committed
238
	MOVL	$-36, AX
239
	CALL	runtime·sysenter(SB)
Russ Cox's avatar
Russ Cox committed
240 241 242
	RET

// uint32 mach_semaphore_timedwait(uint32, uint32, uint32)
243
TEXT runtime·mach_semaphore_timedwait(SB),7,$0
Russ Cox's avatar
Russ Cox committed
244
	MOVL	$-38, AX
245
	CALL	runtime·sysenter(SB)
Russ Cox's avatar
Russ Cox committed
246 247 248
	RET

// uint32 mach_semaphore_signal(uint32)
249
TEXT runtime·mach_semaphore_signal(SB),7,$0
Russ Cox's avatar
Russ Cox committed
250
	MOVL	$-33, AX
251
	CALL	runtime·sysenter(SB)
Russ Cox's avatar
Russ Cox committed
252 253 254
	RET

// uint32 mach_semaphore_signal_all(uint32)
255
TEXT runtime·mach_semaphore_signal_all(SB),7,$0
Russ Cox's avatar
Russ Cox committed
256
	MOVL	$-34, AX
257
	CALL	runtime·sysenter(SB)
Russ Cox's avatar
Russ Cox committed
258 259 260
	RET

// setldt(int entry, int address, int limit)
261
// entry and limit are ignored.
262
TEXT runtime·setldt(SB),7,$32
Russ Cox's avatar
Russ Cox committed
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
	MOVL	address+4(FP), BX	// aka base

	/*
	 * When linking against the system libraries,
	 * we use its pthread_create and let it set up %gs
	 * for us.  When we do that, the private storage
	 * we get is not at 0(GS) but at 0x468(GS).
	 * To insulate the rest of the tool chain from this ugliness,
	 * 8l rewrites 0(GS) into 0x468(GS) for us.
	 * To accommodate that rewrite, we translate the
	 * address and limit here so that 0x468(GS) maps to 0(address).
	 *
	 * See ../../../../libcgo/darwin_386.c for the derivation
	 * of the constant.
	 */
	SUBL	$0x468, BX
Russ Cox's avatar
Russ Cox committed
279

280 281 282 283 284 285 286 287 288 289 290 291
	/*
	 * Must set up as USER_CTHREAD segment because
	 * Darwin forces that value into %gs for signal handlers,
	 * and if we don't set one up, we'll get a recursive
	 * fault trying to get into the signal handler.
	 * Since we have to set one up anyway, it might as
	 * well be the value we want.  So don't bother with
	 * i386_set_ldt.
	 */
	MOVL	BX, 4(SP)
	MOVL	$3, AX	// thread_fast_set_cthread_self - machdep call #3
	INT	$0x82	// sic: 0x82, not 0x80, for machdep call
Russ Cox's avatar
Russ Cox committed
292

293 294
	XORL	AX, AX
	MOVW	GS, AX
Russ Cox's avatar
Russ Cox committed
295
	RET