Text file src/runtime/sys_freebsd_386.s

     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  #define CLOCK_REALTIME		0
    14  #define CLOCK_MONOTONIC		4
    15  #define FD_CLOEXEC		1
    16  #define F_SETFD			2
    17  
    18  #define SYS_exit		1
    19  #define SYS_read		3
    20  #define SYS_write		4
    21  #define SYS_open		5
    22  #define SYS_close		6
    23  #define SYS_getpid		20
    24  #define SYS_kill		37
    25  #define SYS_sigaltstack		53
    26  #define SYS_munmap		73
    27  #define SYS_madvise		75
    28  #define SYS_setitimer		83
    29  #define SYS_fcntl		92
    30  #define SYS_sysarch		165
    31  #define SYS___sysctl		202
    32  #define SYS_clock_gettime	232
    33  #define SYS_nanosleep		240
    34  #define SYS_sched_yield		331
    35  #define SYS_sigprocmask		340
    36  #define SYS_kqueue		362
    37  #define SYS_sigaction		416
    38  #define SYS_sigreturn		417
    39  #define SYS_thr_exit		431
    40  #define SYS_thr_self		432
    41  #define SYS_thr_kill		433
    42  #define SYS__umtx_op		454
    43  #define SYS_thr_new		455
    44  #define SYS_mmap		477
    45  #define SYS_cpuset_getaffinity	487
    46  #define SYS_pipe2 		542
    47  #define SYS_kevent		560
    48  
    49  TEXT runtime·sys_umtx_op(SB),NOSPLIT,$-4
    50  	MOVL	$SYS__umtx_op, AX
    51  	INT	$0x80
    52  	JAE	2(PC)
    53  	NEGL	AX
    54  	MOVL	AX, ret+20(FP)
    55  	RET
    56  
    57  TEXT runtime·thr_new(SB),NOSPLIT,$-4
    58  	MOVL	$SYS_thr_new, AX
    59  	INT	$0x80
    60  	JAE	2(PC)
    61  	NEGL	AX
    62  	MOVL	AX, ret+8(FP)
    63  	RET
    64  
    65  // Called by OS using C ABI.
    66  TEXT runtime·thr_start(SB),NOSPLIT,$0
    67  	NOP	SP	// tell vet SP changed - stop checking offsets
    68  	MOVL	4(SP), AX // m
    69  	MOVL	m_g0(AX), BX
    70  	LEAL	m_tls(AX), BP
    71  	MOVL	m_id(AX), DI
    72  	ADDL	$7, DI
    73  	PUSHAL
    74  	PUSHL	$32
    75  	PUSHL	BP
    76  	PUSHL	DI
    77  	CALL	runtime·setldt(SB)
    78  	POPL	AX
    79  	POPL	AX
    80  	POPL	AX
    81  	POPAL
    82  	get_tls(CX)
    83  	MOVL	BX, g(CX)
    84  
    85  	MOVL	AX, g_m(BX)
    86  	CALL	runtime·stackcheck(SB)		// smashes AX
    87  	CALL	runtime·mstart(SB)
    88  
    89  	MOVL	0, AX			// crash (not reached)
    90  
    91  // Exit the entire program (like C exit)
    92  TEXT runtime·exit(SB),NOSPLIT,$-4
    93  	MOVL	$SYS_exit, AX
    94  	INT	$0x80
    95  	MOVL	$0xf1, 0xf1  // crash
    96  	RET
    97  
    98  GLOBL exitStack<>(SB),RODATA,$8
    99  DATA exitStack<>+0x00(SB)/4, $0
   100  DATA exitStack<>+0x04(SB)/4, $0
   101  
   102  // func exitThread(wait *atomic.Uint32)
   103  TEXT runtime·exitThread(SB),NOSPLIT,$0-4
   104  	MOVL	wait+0(FP), AX
   105  	// We're done using the stack.
   106  	MOVL	$0, (AX)
   107  	// thr_exit takes a single pointer argument, which it expects
   108  	// on the stack. We want to pass 0, so switch over to a fake
   109  	// stack of 0s. It won't write to the stack.
   110  	MOVL	$exitStack<>(SB), SP
   111  	MOVL	$SYS_thr_exit, AX
   112  	INT	$0x80
   113  	MOVL	$0xf1, 0xf1  // crash
   114  	JMP	0(PC)
   115  
   116  TEXT runtime·open(SB),NOSPLIT,$-4
   117  	MOVL	$SYS_open, AX
   118  	INT	$0x80
   119  	JAE	2(PC)
   120  	MOVL	$-1, AX
   121  	MOVL	AX, ret+12(FP)
   122  	RET
   123  
   124  TEXT runtime·closefd(SB),NOSPLIT,$-4
   125  	MOVL	$SYS_close, AX
   126  	INT	$0x80
   127  	JAE	2(PC)
   128  	MOVL	$-1, AX
   129  	MOVL	AX, ret+4(FP)
   130  	RET
   131  
   132  TEXT runtime·read(SB),NOSPLIT,$-4
   133  	MOVL	$SYS_read, AX
   134  	INT	$0x80
   135  	JAE	2(PC)
   136  	NEGL	AX			// caller expects negative errno
   137  	MOVL	AX, ret+12(FP)
   138  	RET
   139  
   140  // func pipe2(flags int32) (r, w int32, errno int32)
   141  TEXT runtime·pipe2(SB),NOSPLIT,$12-16
   142  	MOVL	$SYS_pipe2, AX
   143  	LEAL	r+4(FP), BX
   144  	MOVL	BX, 4(SP)
   145  	MOVL	flags+0(FP), BX
   146  	MOVL	BX, 8(SP)
   147  	INT	$0x80
   148  	JAE	2(PC)
   149  	NEGL	AX
   150  	MOVL	AX, errno+12(FP)
   151  	RET
   152  
   153  TEXT runtime·write1(SB),NOSPLIT,$-4
   154  	MOVL	$SYS_write, AX
   155  	INT	$0x80
   156  	JAE	2(PC)
   157  	NEGL	AX			// caller expects negative errno
   158  	MOVL	AX, ret+12(FP)
   159  	RET
   160  
   161  TEXT runtime·thr_self(SB),NOSPLIT,$8-4
   162  	// thr_self(&0(FP))
   163  	LEAL	ret+0(FP), AX
   164  	MOVL	AX, 4(SP)
   165  	MOVL	$SYS_thr_self, AX
   166  	INT	$0x80
   167  	RET
   168  
   169  TEXT runtime·thr_kill(SB),NOSPLIT,$-4
   170  	// thr_kill(tid, sig)
   171  	MOVL	$SYS_thr_kill, AX
   172  	INT	$0x80
   173  	RET
   174  
   175  TEXT runtime·raiseproc(SB),NOSPLIT,$16
   176  	// getpid
   177  	MOVL	$SYS_getpid, AX
   178  	INT	$0x80
   179  	// kill(self, sig)
   180  	MOVL	AX, 4(SP)
   181  	MOVL	sig+0(FP), AX
   182  	MOVL	AX, 8(SP)
   183  	MOVL	$SYS_kill, AX
   184  	INT	$0x80
   185  	RET
   186  
   187  TEXT runtime·mmap(SB),NOSPLIT,$32
   188  	LEAL addr+0(FP), SI
   189  	LEAL	4(SP), DI
   190  	CLD
   191  	MOVSL
   192  	MOVSL
   193  	MOVSL
   194  	MOVSL
   195  	MOVSL
   196  	MOVSL
   197  	MOVL	$0, AX	// top 32 bits of file offset
   198  	STOSL
   199  	MOVL	$SYS_mmap, AX
   200  	INT	$0x80
   201  	JAE	ok
   202  	MOVL	$0, p+24(FP)
   203  	MOVL	AX, err+28(FP)
   204  	RET
   205  ok:
   206  	MOVL	AX, p+24(FP)
   207  	MOVL	$0, err+28(FP)
   208  	RET
   209  
   210  TEXT runtime·munmap(SB),NOSPLIT,$-4
   211  	MOVL	$SYS_munmap, AX
   212  	INT	$0x80
   213  	JAE	2(PC)
   214  	MOVL	$0xf1, 0xf1  // crash
   215  	RET
   216  
   217  TEXT runtime·madvise(SB),NOSPLIT,$-4
   218  	MOVL	$SYS_madvise, AX
   219  	INT	$0x80
   220  	JAE	2(PC)
   221  	MOVL	$-1, AX
   222  	MOVL	AX, ret+12(FP)
   223  	RET
   224  
   225  TEXT runtime·setitimer(SB), NOSPLIT, $-4
   226  	MOVL	$SYS_setitimer, AX
   227  	INT	$0x80
   228  	RET
   229  
   230  // func fallback_walltime() (sec int64, nsec int32)
   231  TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12
   232  	MOVL	$SYS_clock_gettime, AX
   233  	LEAL	12(SP), BX
   234  	MOVL	$CLOCK_REALTIME, 4(SP)
   235  	MOVL	BX, 8(SP)
   236  	INT	$0x80
   237  	MOVL	12(SP), AX	// sec
   238  	MOVL	16(SP), BX	// nsec
   239  
   240  	// sec is in AX, nsec in BX
   241  	MOVL	AX, sec_lo+0(FP)
   242  	MOVL	$0, sec_hi+4(FP)
   243  	MOVL	BX, nsec+8(FP)
   244  	RET
   245  
   246  // func fallback_nanotime() int64
   247  TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32-8
   248  	MOVL	$SYS_clock_gettime, AX
   249  	LEAL	12(SP), BX
   250  	MOVL	$CLOCK_MONOTONIC, 4(SP)
   251  	MOVL	BX, 8(SP)
   252  	INT	$0x80
   253  	MOVL	12(SP), AX	// sec
   254  	MOVL	16(SP), BX	// nsec
   255  
   256  	// sec is in AX, nsec in BX
   257  	// convert to DX:AX nsec
   258  	MOVL	$1000000000, CX
   259  	MULL	CX
   260  	ADDL	BX, AX
   261  	ADCL	$0, DX
   262  
   263  	MOVL	AX, ret_lo+0(FP)
   264  	MOVL	DX, ret_hi+4(FP)
   265  	RET
   266  
   267  
   268  TEXT runtime·asmSigaction(SB),NOSPLIT,$-4
   269  	MOVL	$SYS_sigaction, AX
   270  	INT	$0x80
   271  	MOVL	AX, ret+12(FP)
   272  	RET
   273  
   274  TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
   275  	MOVL	fn+0(FP), AX
   276  	MOVL	sig+4(FP), BX
   277  	MOVL	info+8(FP), CX
   278  	MOVL	ctx+12(FP), DX
   279  	MOVL	SP, SI
   280  	SUBL	$32, SP
   281  	ANDL	$~15, SP	// align stack: handler might be a C function
   282  	MOVL	BX, 0(SP)
   283  	MOVL	CX, 4(SP)
   284  	MOVL	DX, 8(SP)
   285  	MOVL	SI, 12(SP)	// save SI: handler might be a Go function
   286  	CALL	AX
   287  	MOVL	12(SP), AX
   288  	MOVL	AX, SP
   289  	RET
   290  
   291  // Called by OS using C ABI.
   292  TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$12
   293  	NOP	SP	// tell vet SP changed - stop checking offsets
   294  	MOVL	16(SP), BX	// signo
   295  	MOVL	BX, 0(SP)
   296  	MOVL	20(SP), BX // info
   297  	MOVL	BX, 4(SP)
   298  	MOVL	24(SP), BX // context
   299  	MOVL	BX, 8(SP)
   300  	CALL	runtime·sigtrampgo(SB)
   301  
   302  	// call sigreturn
   303  	MOVL	24(SP), AX	// context
   304  	MOVL	$0, 0(SP)	// syscall gap
   305  	MOVL	AX, 4(SP)
   306  	MOVL	$SYS_sigreturn, AX
   307  	INT	$0x80
   308  	MOVL	$0xf1, 0xf1  // crash
   309  	RET
   310  
   311  TEXT runtime·sigaltstack(SB),NOSPLIT,$0
   312  	MOVL	$SYS_sigaltstack, AX
   313  	INT	$0x80
   314  	JAE	2(PC)
   315  	MOVL	$0xf1, 0xf1  // crash
   316  	RET
   317  
   318  TEXT runtime·usleep(SB),NOSPLIT,$20
   319  	MOVL	$0, DX
   320  	MOVL	usec+0(FP), AX
   321  	MOVL	$1000000, CX
   322  	DIVL	CX
   323  	MOVL	AX, 12(SP)		// tv_sec
   324  	MOVL	$1000, AX
   325  	MULL	DX
   326  	MOVL	AX, 16(SP)		// tv_nsec
   327  
   328  	MOVL	$0, 0(SP)
   329  	LEAL	12(SP), AX
   330  	MOVL	AX, 4(SP)		// arg 1 - rqtp
   331  	MOVL	$0, 8(SP)		// arg 2 - rmtp
   332  	MOVL	$SYS_nanosleep, AX
   333  	INT	$0x80
   334  	RET
   335  
   336  /*
   337  descriptor entry format for system call
   338  is the native machine format, ugly as it is:
   339  
   340  	2-byte limit
   341  	3-byte base
   342  	1-byte: 0x80=present, 0x60=dpl<<5, 0x1F=type
   343  	1-byte: 0x80=limit is *4k, 0x40=32-bit operand size,
   344  		0x0F=4 more bits of limit
   345  	1 byte: 8 more bits of base
   346  
   347  int i386_get_ldt(int, union ldt_entry *, int);
   348  int i386_set_ldt(int, const union ldt_entry *, int);
   349  
   350  */
   351  
   352  // setldt(int entry, int address, int limit)
   353  TEXT runtime·setldt(SB),NOSPLIT,$32
   354  	MOVL	base+4(FP), BX
   355  	// see comment in sys_linux_386.s; freebsd is similar
   356  	ADDL	$0x4, BX
   357  
   358  	// set up data_desc
   359  	LEAL	16(SP), AX	// struct data_desc
   360  	MOVL	$0, 0(AX)
   361  	MOVL	$0, 4(AX)
   362  
   363  	MOVW	BX, 2(AX)
   364  	SHRL	$16, BX
   365  	MOVB	BX, 4(AX)
   366  	SHRL	$8, BX
   367  	MOVB	BX, 7(AX)
   368  
   369  	MOVW	$0xffff, 0(AX)
   370  	MOVB	$0xCF, 6(AX)	// 32-bit operand, 4k limit unit, 4 more bits of limit
   371  
   372  	MOVB	$0xF2, 5(AX)	// r/w data descriptor, dpl=3, present
   373  
   374  	// call i386_set_ldt(entry, desc, 1)
   375  	MOVL	$0xffffffff, 0(SP)	// auto-allocate entry and return in AX
   376  	MOVL	AX, 4(SP)
   377  	MOVL	$1, 8(SP)
   378  	CALL	i386_set_ldt<>(SB)
   379  
   380  	// compute segment selector - (entry*8+7)
   381  	SHLL	$3, AX
   382  	ADDL	$7, AX
   383  	MOVW	AX, GS
   384  	RET
   385  
   386  TEXT i386_set_ldt<>(SB),NOSPLIT,$16
   387  	LEAL	args+0(FP), AX	// 0(FP) == 4(SP) before SP got moved
   388  	MOVL	$0, 0(SP)	// syscall gap
   389  	MOVL	$1, 4(SP)
   390  	MOVL	AX, 8(SP)
   391  	MOVL	$SYS_sysarch, AX
   392  	INT	$0x80
   393  	JAE	2(PC)
   394  	INT	$3
   395  	RET
   396  
   397  TEXT runtime·sysctl(SB),NOSPLIT,$28
   398  	LEAL	mib+0(FP), SI
   399  	LEAL	4(SP), DI
   400  	CLD
   401  	MOVSL				// arg 1 - name
   402  	MOVSL				// arg 2 - namelen
   403  	MOVSL				// arg 3 - oldp
   404  	MOVSL				// arg 4 - oldlenp
   405  	MOVSL				// arg 5 - newp
   406  	MOVSL				// arg 6 - newlen
   407  	MOVL	$SYS___sysctl, AX
   408  	INT	$0x80
   409  	JAE	4(PC)
   410  	NEGL	AX
   411  	MOVL	AX, ret+24(FP)
   412  	RET
   413  	MOVL	$0, AX
   414  	MOVL	AX, ret+24(FP)
   415  	RET
   416  
   417  TEXT runtime·osyield(SB),NOSPLIT,$-4
   418  	MOVL	$SYS_sched_yield, AX
   419  	INT	$0x80
   420  	RET
   421  
   422  TEXT runtime·sigprocmask(SB),NOSPLIT,$16
   423  	MOVL	$0, 0(SP)		// syscall gap
   424  	MOVL	how+0(FP), AX		// arg 1 - how
   425  	MOVL	AX, 4(SP)
   426  	MOVL	new+4(FP), AX
   427  	MOVL	AX, 8(SP)		// arg 2 - set
   428  	MOVL	old+8(FP), AX
   429  	MOVL	AX, 12(SP)		// arg 3 - oset
   430  	MOVL	$SYS_sigprocmask, AX
   431  	INT	$0x80
   432  	JAE	2(PC)
   433  	MOVL	$0xf1, 0xf1  // crash
   434  	RET
   435  
   436  // int32 runtime·kqueue(void);
   437  TEXT runtime·kqueue(SB),NOSPLIT,$0
   438  	MOVL	$SYS_kqueue, AX
   439  	INT	$0x80
   440  	JAE	2(PC)
   441  	NEGL	AX
   442  	MOVL	AX, ret+0(FP)
   443  	RET
   444  
   445  // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
   446  TEXT runtime·kevent(SB),NOSPLIT,$0
   447  	MOVL	$SYS_kevent, AX
   448  	INT	$0x80
   449  	JAE	2(PC)
   450  	NEGL	AX
   451  	MOVL	AX, ret+24(FP)
   452  	RET
   453  
   454  // int32 runtime·closeonexec(int32 fd);
   455  TEXT runtime·closeonexec(SB),NOSPLIT,$32
   456  	MOVL	$SYS_fcntl, AX
   457  	// 0(SP) is where the caller PC would be; kernel skips it
   458  	MOVL	fd+0(FP), BX
   459  	MOVL	BX, 4(SP)	// fd
   460  	MOVL	$F_SETFD, 8(SP)
   461  	MOVL	$FD_CLOEXEC, 12(SP)
   462  	INT	$0x80
   463  	JAE	2(PC)
   464  	NEGL	AX
   465  	RET
   466  
   467  // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
   468  TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-28
   469  	MOVL	$SYS_cpuset_getaffinity, AX
   470  	INT	$0x80
   471  	JAE	2(PC)
   472  	NEGL	AX
   473  	MOVL	AX, ret+24(FP)
   474  	RET
   475  
   476  GLOBL runtime·tlsoffset(SB),NOPTR,$4
   477  

View as plain text