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

View as plain text