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