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