Home | History | Annotate | Download | only in runtime
      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, 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 
     13 TEXT runtimesys_umtx_op(SB),NOSPLIT,$-4
     14 	MOVL	$454, AX
     15 	INT	$0x80
     16 	MOVL	AX, ret+20(FP)
     17 	RET
     18 
     19 TEXT runtimethr_new(SB),NOSPLIT,$-4
     20 	MOVL	$455, AX
     21 	INT	$0x80
     22 	RET
     23 
     24 TEXT runtimethr_start(SB),NOSPLIT,$0
     25 	MOVL	mm+0(FP), AX
     26 	MOVL	m_g0(AX), BX
     27 	LEAL	m_tls(AX), BP
     28 	MOVL	m_id(AX), DI
     29 	ADDL	$7, DI
     30 	PUSHAL
     31 	PUSHL	$32
     32 	PUSHL	BP
     33 	PUSHL	DI
     34 	CALL	runtimesetldt(SB)
     35 	POPL	AX
     36 	POPL	AX
     37 	POPL	AX
     38 	POPAL
     39 	get_tls(CX)
     40 	MOVL	BX, g(CX)
     41 
     42 	MOVL	AX, g_m(BX)
     43 	CALL	runtimestackcheck(SB)		// smashes AX
     44 	CALL	runtimemstart(SB)
     45 
     46 	MOVL	0, AX			// crash (not reached)
     47 
     48 // Exit the entire program (like C exit)
     49 TEXT runtimeexit(SB),NOSPLIT,$-4
     50 	MOVL	$1, AX
     51 	INT	$0x80
     52 	MOVL	$0xf1, 0xf1  // crash
     53 	RET
     54 
     55 GLOBL exitStack<>(SB),RODATA,$8
     56 DATA exitStack<>+0x00(SB)/4, $0
     57 DATA exitStack<>+0x04(SB)/4, $0
     58 
     59 // func exitThread(wait *uint32)
     60 TEXT runtimeexitThread(SB),NOSPLIT,$0-4
     61 	MOVL	wait+0(FP), AX
     62 	// We're done using the stack.
     63 	MOVL	$0, (AX)
     64 	// thr_exit takes a single pointer argument, which it expects
     65 	// on the stack. We want to pass 0, so switch over to a fake
     66 	// stack of 0s. It won't write to the stack.
     67 	MOVL	$exitStack<>(SB), SP
     68 	MOVL	$431, AX	// thr_exit
     69 	INT	$0x80
     70 	MOVL	$0xf1, 0xf1  // crash
     71 	JMP	0(PC)
     72 
     73 TEXT runtimeopen(SB),NOSPLIT,$-4
     74 	MOVL	$5, AX
     75 	INT	$0x80
     76 	JAE	2(PC)
     77 	MOVL	$-1, AX
     78 	MOVL	AX, ret+12(FP)
     79 	RET
     80 
     81 TEXT runtimeclosefd(SB),NOSPLIT,$-4
     82 	MOVL	$6, AX
     83 	INT	$0x80
     84 	JAE	2(PC)
     85 	MOVL	$-1, AX
     86 	MOVL	AX, ret+4(FP)
     87 	RET
     88 
     89 TEXT runtimeread(SB),NOSPLIT,$-4
     90 	MOVL	$3, AX
     91 	INT	$0x80
     92 	JAE	2(PC)
     93 	MOVL	$-1, AX
     94 	MOVL	AX, ret+12(FP)
     95 	RET
     96 
     97 TEXT runtimewrite(SB),NOSPLIT,$-4
     98 	MOVL	$4, AX
     99 	INT	$0x80
    100 	JAE	2(PC)
    101 	MOVL	$-1, AX
    102 	MOVL	AX, ret+12(FP)
    103 	RET
    104 
    105 TEXT runtimegetrlimit(SB),NOSPLIT,$-4
    106 	MOVL	$194, AX
    107 	INT	$0x80
    108 	MOVL	AX, ret+8(FP)
    109 	RET
    110 
    111 TEXT runtimeraise(SB),NOSPLIT,$16
    112 	// thr_self(&8(SP))
    113 	LEAL	8(SP), AX
    114 	MOVL	AX, 4(SP)
    115 	MOVL	$432, AX
    116 	INT	$0x80
    117 	// thr_kill(self, SIGPIPE)
    118 	MOVL	8(SP), AX
    119 	MOVL	AX, 4(SP)
    120 	MOVL	sig+0(FP), AX
    121 	MOVL	AX, 8(SP)
    122 	MOVL	$433, AX
    123 	INT	$0x80
    124 	RET
    125 
    126 TEXT runtimeraiseproc(SB),NOSPLIT,$16
    127 	// getpid
    128 	MOVL	$20, AX
    129 	INT	$0x80
    130 	// kill(self, sig)
    131 	MOVL	AX, 4(SP)
    132 	MOVL	sig+0(FP), AX
    133 	MOVL	AX, 8(SP)
    134 	MOVL	$37, AX
    135 	INT	$0x80
    136 	RET
    137 
    138 TEXT runtimemmap(SB),NOSPLIT,$32
    139 	LEAL addr+0(FP), SI
    140 	LEAL	4(SP), DI
    141 	CLD
    142 	MOVSL
    143 	MOVSL
    144 	MOVSL
    145 	MOVSL
    146 	MOVSL
    147 	MOVSL
    148 	MOVL	$0, AX	// top 32 bits of file offset
    149 	STOSL
    150 	MOVL	$477, AX
    151 	INT	$0x80
    152 	JAE	ok
    153 	MOVL	$0, p+24(FP)
    154 	MOVL	AX, err+28(FP)
    155 	RET
    156 ok:
    157 	MOVL	AX, p+24(FP)
    158 	MOVL	$0, err+28(FP)
    159 	RET
    160 
    161 TEXT runtimemunmap(SB),NOSPLIT,$-4
    162 	MOVL	$73, AX
    163 	INT	$0x80
    164 	JAE	2(PC)
    165 	MOVL	$0xf1, 0xf1  // crash
    166 	RET
    167 
    168 TEXT runtimemadvise(SB),NOSPLIT,$-4
    169 	MOVL	$75, AX	// madvise
    170 	INT	$0x80
    171 	// ignore failure - maybe pages are locked
    172 	RET
    173 
    174 TEXT runtimesetitimer(SB), NOSPLIT, $-4
    175 	MOVL	$83, AX
    176 	INT	$0x80
    177 	RET
    178 
    179 // func walltime() (sec int64, nsec int32)
    180 TEXT runtimewalltime(SB), NOSPLIT, $32
    181 	MOVL	$232, AX // clock_gettime
    182 	LEAL	12(SP), BX
    183 	MOVL	$0, 4(SP)	// CLOCK_REALTIME
    184 	MOVL	BX, 8(SP)
    185 	INT	$0x80
    186 	MOVL	12(SP), AX	// sec
    187 	MOVL	16(SP), BX	// nsec
    188 
    189 	// sec is in AX, nsec in BX
    190 	MOVL	AX, sec_lo+0(FP)
    191 	MOVL	$0, sec_hi+4(FP)
    192 	MOVL	BX, nsec+8(FP)
    193 	RET
    194 
    195 // int64 nanotime(void) so really
    196 // void nanotime(int64 *nsec)
    197 TEXT runtimenanotime(SB), NOSPLIT, $32
    198 	MOVL	$232, AX
    199 	LEAL	12(SP), BX
    200 	// We can use CLOCK_MONOTONIC_FAST here when we drop
    201 	// support for FreeBSD 8-STABLE.
    202 	MOVL	$4, 4(SP)	// CLOCK_MONOTONIC
    203 	MOVL	BX, 8(SP)
    204 	INT	$0x80
    205 	MOVL	12(SP), AX	// sec
    206 	MOVL	16(SP), BX	// nsec
    207 
    208 	// sec is in AX, nsec in BX
    209 	// convert to DX:AX nsec
    210 	MOVL	$1000000000, CX
    211 	MULL	CX
    212 	ADDL	BX, AX
    213 	ADCL	$0, DX
    214 
    215 	MOVL	AX, ret_lo+0(FP)
    216 	MOVL	DX, ret_hi+4(FP)
    217 	RET
    218 
    219 
    220 TEXT runtimesigaction(SB),NOSPLIT,$-4
    221 	MOVL	$416, AX
    222 	INT	$0x80
    223 	JAE	2(PC)
    224 	MOVL	$0xf1, 0xf1  // crash
    225 	RET
    226 
    227 TEXT runtimesigfwd(SB),NOSPLIT,$12-16
    228 	MOVL	fn+0(FP), AX
    229 	MOVL	sig+4(FP), BX
    230 	MOVL	info+8(FP), CX
    231 	MOVL	ctx+12(FP), DX
    232 	MOVL	SP, SI
    233 	SUBL	$32, SP
    234 	ANDL	$~15, SP	// align stack: handler might be a C function
    235 	MOVL	BX, 0(SP)
    236 	MOVL	CX, 4(SP)
    237 	MOVL	DX, 8(SP)
    238 	MOVL	SI, 12(SP)	// save SI: handler might be a Go function
    239 	CALL	AX
    240 	MOVL	12(SP), AX
    241 	MOVL	AX, SP
    242 	RET
    243 
    244 TEXT runtimesigtramp(SB),NOSPLIT,$12
    245 	MOVL	signo+0(FP), BX
    246 	MOVL	BX, 0(SP)
    247 	MOVL	info+4(FP), BX
    248 	MOVL	BX, 4(SP)
    249 	MOVL	context+8(FP), BX
    250 	MOVL	BX, 8(SP)
    251 	CALL	runtimesigtrampgo(SB)
    252 
    253 	// call sigreturn
    254 	MOVL	context+8(FP), AX
    255 	MOVL	$0, 0(SP)	// syscall gap
    256 	MOVL	AX, 4(SP)
    257 	MOVL	$417, AX	// sigreturn(ucontext)
    258 	INT	$0x80
    259 	MOVL	$0xf1, 0xf1  // crash
    260 	RET
    261 
    262 TEXT runtimesigaltstack(SB),NOSPLIT,$0
    263 	MOVL	$53, AX
    264 	INT	$0x80
    265 	JAE	2(PC)
    266 	MOVL	$0xf1, 0xf1  // crash
    267 	RET
    268 
    269 TEXT runtimeusleep(SB),NOSPLIT,$20
    270 	MOVL	$0, DX
    271 	MOVL	usec+0(FP), AX
    272 	MOVL	$1000000, CX
    273 	DIVL	CX
    274 	MOVL	AX, 12(SP)		// tv_sec
    275 	MOVL	$1000, AX
    276 	MULL	DX
    277 	MOVL	AX, 16(SP)		// tv_nsec
    278 
    279 	MOVL	$0, 0(SP)
    280 	LEAL	12(SP), AX
    281 	MOVL	AX, 4(SP)		// arg 1 - rqtp
    282 	MOVL	$0, 8(SP)		// arg 2 - rmtp
    283 	MOVL	$240, AX		// sys_nanosleep
    284 	INT	$0x80
    285 	RET
    286 
    287 /*
    288 descriptor entry format for system call
    289 is the native machine format, ugly as it is:
    290 
    291 	2-byte limit
    292 	3-byte base
    293 	1-byte: 0x80=present, 0x60=dpl<<5, 0x1F=type
    294 	1-byte: 0x80=limit is *4k, 0x40=32-bit operand size,
    295 		0x0F=4 more bits of limit
    296 	1 byte: 8 more bits of base
    297 
    298 int i386_get_ldt(int, union ldt_entry *, int);
    299 int i386_set_ldt(int, const union ldt_entry *, int);
    300 
    301 */
    302 
    303 // setldt(int entry, int address, int limit)
    304 TEXT runtimesetldt(SB),NOSPLIT,$32
    305 	MOVL	address+4(FP), BX	// aka base
    306 	// see comment in sys_linux_386.s; freebsd is similar
    307 	ADDL	$0x4, BX
    308 
    309 	// set up data_desc
    310 	LEAL	16(SP), AX	// struct data_desc
    311 	MOVL	$0, 0(AX)
    312 	MOVL	$0, 4(AX)
    313 
    314 	MOVW	BX, 2(AX)
    315 	SHRL	$16, BX
    316 	MOVB	BX, 4(AX)
    317 	SHRL	$8, BX
    318 	MOVB	BX, 7(AX)
    319 
    320 	MOVW	$0xffff, 0(AX)
    321 	MOVB	$0xCF, 6(AX)	// 32-bit operand, 4k limit unit, 4 more bits of limit
    322 
    323 	MOVB	$0xF2, 5(AX)	// r/w data descriptor, dpl=3, present
    324 
    325 	// call i386_set_ldt(entry, desc, 1)
    326 	MOVL	$0xffffffff, 0(SP)	// auto-allocate entry and return in AX
    327 	MOVL	AX, 4(SP)
    328 	MOVL	$1, 8(SP)
    329 	CALL	runtimei386_set_ldt(SB)
    330 
    331 	// compute segment selector - (entry*8+7)
    332 	SHLL	$3, AX
    333 	ADDL	$7, AX
    334 	MOVW	AX, GS
    335 	RET
    336 
    337 TEXT runtimei386_set_ldt(SB),NOSPLIT,$16
    338 	LEAL	args+0(FP), AX	// 0(FP) == 4(SP) before SP got moved
    339 	MOVL	$0, 0(SP)	// syscall gap
    340 	MOVL	$1, 4(SP)
    341 	MOVL	AX, 8(SP)
    342 	MOVL	$165, AX
    343 	INT	$0x80
    344 	JAE	2(PC)
    345 	INT	$3
    346 	RET
    347 
    348 TEXT runtimesysctl(SB),NOSPLIT,$28
    349 	LEAL	mib+0(FP), SI
    350 	LEAL	4(SP), DI
    351 	CLD
    352 	MOVSL				// arg 1 - name
    353 	MOVSL				// arg 2 - namelen
    354 	MOVSL				// arg 3 - oldp
    355 	MOVSL				// arg 4 - oldlenp
    356 	MOVSL				// arg 5 - newp
    357 	MOVSL				// arg 6 - newlen
    358 	MOVL	$202, AX		// sys___sysctl
    359 	INT	$0x80
    360 	JAE	4(PC)
    361 	NEGL	AX
    362 	MOVL	AX, ret+24(FP)
    363 	RET
    364 	MOVL	$0, AX
    365 	MOVL	AX, ret+24(FP)
    366 	RET
    367 
    368 TEXT runtimeosyield(SB),NOSPLIT,$-4
    369 	MOVL	$331, AX		// sys_sched_yield
    370 	INT	$0x80
    371 	RET
    372 
    373 TEXT runtimesigprocmask(SB),NOSPLIT,$16
    374 	MOVL	$0, 0(SP)		// syscall gap
    375 	MOVL	how+0(FP), AX		// arg 1 - how
    376 	MOVL	AX, 4(SP)
    377 	MOVL	new+4(FP), AX
    378 	MOVL	AX, 8(SP)		// arg 2 - set
    379 	MOVL	old+8(FP), AX
    380 	MOVL	AX, 12(SP)		// arg 3 - oset
    381 	MOVL	$340, AX		// sys_sigprocmask
    382 	INT	$0x80
    383 	JAE	2(PC)
    384 	MOVL	$0xf1, 0xf1  // crash
    385 	RET
    386 
    387 // int32 runtimekqueue(void);
    388 TEXT runtimekqueue(SB),NOSPLIT,$0
    389 	MOVL	$362, AX
    390 	INT	$0x80
    391 	JAE	2(PC)
    392 	NEGL	AX
    393 	MOVL	AX, ret+0(FP)
    394 	RET
    395 
    396 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
    397 TEXT runtimekevent(SB),NOSPLIT,$0
    398 	MOVL	$363, AX
    399 	INT	$0x80
    400 	JAE	2(PC)
    401 	NEGL	AX
    402 	MOVL	AX, ret+24(FP)
    403 	RET
    404 
    405 // int32 runtimecloseonexec(int32 fd);
    406 TEXT runtimecloseonexec(SB),NOSPLIT,$32
    407 	MOVL	$92, AX		// fcntl
    408 	// 0(SP) is where the caller PC would be; kernel skips it
    409 	MOVL	fd+0(FP), BX
    410 	MOVL	BX, 4(SP)	// fd
    411 	MOVL	$2, 8(SP)	// F_SETFD
    412 	MOVL	$1, 12(SP)	// FD_CLOEXEC
    413 	INT	$0x80
    414 	JAE	2(PC)
    415 	NEGL	AX
    416 	RET
    417 
    418 // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
    419 TEXT runtimecpuset_getaffinity(SB), NOSPLIT, $0-28
    420 	MOVL	$487, AX
    421 	INT	$0x80
    422 	JAE	2(PC)
    423 	NEGL	AX
    424 	MOVL	AX, ret+24(FP)
    425 	RET
    426 
    427 GLOBL runtimetlsoffset(SB),NOPTR,$4
    428