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, NetBSD 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 // Exit the entire program (like C exit) 14 TEXT runtimeexit(SB),NOSPLIT,$-4 15 MOVL $1, AX 16 INT $0x80 17 MOVL $0xf1, 0xf1 // crash 18 RET 19 20 TEXT runtimeexit1(SB),NOSPLIT,$-4 21 MOVL $310, AX // sys__lwp_exit 22 INT $0x80 23 JAE 2(PC) 24 MOVL $0xf1, 0xf1 // crash 25 RET 26 27 TEXT runtimeopen(SB),NOSPLIT,$-4 28 MOVL $5, AX 29 INT $0x80 30 JAE 2(PC) 31 MOVL $-1, AX 32 MOVL AX, ret+12(FP) 33 RET 34 35 TEXT runtimeclosefd(SB),NOSPLIT,$-4 36 MOVL $6, AX 37 INT $0x80 38 JAE 2(PC) 39 MOVL $-1, AX 40 MOVL AX, ret+4(FP) 41 RET 42 43 TEXT runtimeread(SB),NOSPLIT,$-4 44 MOVL $3, AX 45 INT $0x80 46 JAE 2(PC) 47 MOVL $-1, AX 48 MOVL AX, ret+12(FP) 49 RET 50 51 TEXT runtimewrite(SB),NOSPLIT,$-4 52 MOVL $4, AX // sys_write 53 INT $0x80 54 JAE 2(PC) 55 MOVL $-1, AX 56 MOVL AX, ret+12(FP) 57 RET 58 59 TEXT runtimeusleep(SB),NOSPLIT,$24 60 MOVL $0, DX 61 MOVL usec+0(FP), AX 62 MOVL $1000000, CX 63 DIVL CX 64 MOVL AX, 12(SP) // tv_sec - l32 65 MOVL $0, 16(SP) // tv_sec - h32 66 MOVL $1000, AX 67 MULL DX 68 MOVL AX, 20(SP) // tv_nsec 69 70 MOVL $0, 0(SP) 71 LEAL 12(SP), AX 72 MOVL AX, 4(SP) // arg 1 - rqtp 73 MOVL $0, 8(SP) // arg 2 - rmtp 74 MOVL $430, AX // sys_nanosleep 75 INT $0x80 76 RET 77 78 TEXT runtimeraise(SB),NOSPLIT,$12 79 MOVL $311, AX // sys__lwp_self 80 INT $0x80 81 MOVL $0, 0(SP) 82 MOVL AX, 4(SP) // arg 1 - target 83 MOVL sig+0(FP), AX 84 MOVL AX, 8(SP) // arg 2 - signo 85 MOVL $318, AX // sys__lwp_kill 86 INT $0x80 87 RET 88 89 TEXT runtimeraiseproc(SB),NOSPLIT,$12 90 MOVL $20, AX // sys_getpid 91 INT $0x80 92 MOVL $0, 0(SP) 93 MOVL AX, 4(SP) // arg 1 - pid 94 MOVL sig+0(FP), AX 95 MOVL AX, 8(SP) // arg 2 - signo 96 MOVL $37, AX // sys_kill 97 INT $0x80 98 RET 99 100 TEXT runtimemmap(SB),NOSPLIT,$36 101 LEAL addr+0(FP), SI 102 LEAL 4(SP), DI 103 CLD 104 MOVSL // arg 1 - addr 105 MOVSL // arg 2 - len 106 MOVSL // arg 3 - prot 107 MOVSL // arg 4 - flags 108 MOVSL // arg 5 - fd 109 MOVL $0, AX 110 STOSL // arg 6 - pad 111 MOVSL // arg 7 - offset 112 MOVL $0, AX // top 32 bits of file offset 113 STOSL 114 MOVL $197, AX // sys_mmap 115 INT $0x80 116 MOVL AX, ret+24(FP) 117 RET 118 119 TEXT runtimemunmap(SB),NOSPLIT,$-4 120 MOVL $73, AX // sys_munmap 121 INT $0x80 122 JAE 2(PC) 123 MOVL $0xf1, 0xf1 // crash 124 RET 125 126 TEXT runtimemadvise(SB),NOSPLIT,$-4 127 MOVL $75, AX // sys_madvise 128 INT $0x80 129 // ignore failure - maybe pages are locked 130 RET 131 132 TEXT runtimesetitimer(SB),NOSPLIT,$-4 133 MOVL $425, AX // sys_setitimer 134 INT $0x80 135 RET 136 137 // func now() (sec int64, nsec int32) 138 TEXT timenow(SB), NOSPLIT, $32 139 LEAL 12(SP), BX 140 MOVL $0, 4(SP) // arg 1 - clock_id 141 MOVL BX, 8(SP) // arg 2 - tp 142 MOVL $427, AX // sys_clock_gettime 143 INT $0x80 144 145 MOVL 12(SP), AX // sec - l32 146 MOVL AX, sec+0(FP) 147 MOVL 16(SP), AX // sec - h32 148 MOVL AX, sec+4(FP) 149 150 MOVL 20(SP), BX // nsec 151 MOVL BX, nsec+8(FP) 152 RET 153 154 // int64 nanotime(void) so really 155 // void nanotime(int64 *nsec) 156 TEXT runtimenanotime(SB),NOSPLIT,$32 157 LEAL 12(SP), BX 158 MOVL $0, 4(SP) // arg 1 - clock_id 159 MOVL BX, 8(SP) // arg 2 - tp 160 MOVL $427, AX // sys_clock_gettime 161 INT $0x80 162 163 MOVL 16(SP), CX // sec - h32 164 IMULL $1000000000, CX 165 166 MOVL 12(SP), AX // sec - l32 167 MOVL $1000000000, BX 168 MULL BX // result in dx:ax 169 170 MOVL 20(SP), BX // nsec 171 ADDL BX, AX 172 ADCL CX, DX // add high bits with carry 173 174 MOVL AX, ret_lo+0(FP) 175 MOVL DX, ret_hi+4(FP) 176 RET 177 178 TEXT runtimegetcontext(SB),NOSPLIT,$-4 179 MOVL $307, AX // sys_getcontext 180 INT $0x80 181 JAE 2(PC) 182 MOVL $0xf1, 0xf1 // crash 183 RET 184 185 TEXT runtimesigprocmask(SB),NOSPLIT,$-4 186 MOVL $293, AX // sys_sigprocmask 187 INT $0x80 188 JAE 2(PC) 189 MOVL $0xf1, 0xf1 // crash 190 RET 191 192 TEXT runtimesigreturn_tramp(SB),NOSPLIT,$0 193 LEAL 140(SP), AX // Load address of ucontext 194 MOVL AX, 4(SP) 195 MOVL $308, AX // sys_setcontext 196 INT $0x80 197 MOVL $-1, 4(SP) // Something failed... 198 MOVL $1, AX // sys_exit 199 INT $0x80 200 201 TEXT runtimesigaction(SB),NOSPLIT,$24 202 LEAL sig+0(FP), SI 203 LEAL 4(SP), DI 204 CLD 205 MOVSL // arg 1 - sig 206 MOVSL // arg 2 - act 207 MOVSL // arg 3 - oact 208 LEAL runtimesigreturn_tramp(SB), AX 209 STOSL // arg 4 - tramp 210 MOVL $2, AX 211 STOSL // arg 5 - vers 212 MOVL $340, AX // sys___sigaction_sigtramp 213 INT $0x80 214 JAE 2(PC) 215 MOVL $0xf1, 0xf1 // crash 216 RET 217 218 TEXT runtimesigfwd(SB),NOSPLIT,$12-16 219 MOVL fn+0(FP), AX 220 MOVL sig+4(FP), BX 221 MOVL info+8(FP), CX 222 MOVL ctx+12(FP), DX 223 MOVL SP, SI 224 SUBL $32, SP 225 ANDL $-15, SP // align stack: handler might be a C function 226 MOVL BX, 0(SP) 227 MOVL CX, 4(SP) 228 MOVL DX, 8(SP) 229 MOVL SI, 12(SP) // save SI: handler might be a Go function 230 CALL AX 231 MOVL 12(SP), AX 232 MOVL AX, SP 233 RET 234 235 TEXT runtimesigtramp(SB),NOSPLIT,$28 236 // Save callee-saved C registers, since the caller may be a C signal handler. 237 MOVL BX, bx-4(SP) 238 MOVL BP, bp-8(SP) 239 MOVL SI, si-12(SP) 240 MOVL DI, di-16(SP) 241 // We don't save mxcsr or the x87 control word because sigtrampgo doesn't 242 // modify them. 243 244 MOVL signo+0(FP), BX 245 MOVL BX, 0(SP) 246 MOVL info+4(FP), BX 247 MOVL BX, 4(SP) 248 MOVL context+8(FP), BX 249 MOVL BX, 8(SP) 250 CALL runtimesigtrampgo(SB) 251 252 MOVL di-16(SP), DI 253 MOVL si-12(SP), SI 254 MOVL bp-8(SP), BP 255 MOVL bx-4(SP), BX 256 RET 257 258 // int32 lwp_create(void *context, uintptr flags, void *lwpid); 259 TEXT runtimelwp_create(SB),NOSPLIT,$16 260 MOVL $0, 0(SP) 261 MOVL ctxt+0(FP), AX 262 MOVL AX, 4(SP) // arg 1 - context 263 MOVL flags+4(FP), AX 264 MOVL AX, 8(SP) // arg 2 - flags 265 MOVL lwpid+8(FP), AX 266 MOVL AX, 12(SP) // arg 3 - lwpid 267 MOVL $309, AX // sys__lwp_create 268 INT $0x80 269 JCC 2(PC) 270 NEGL AX 271 MOVL AX, ret+12(FP) 272 RET 273 274 TEXT runtimelwp_tramp(SB),NOSPLIT,$0 275 276 // Set FS to point at m->tls 277 LEAL m_tls(BX), BP 278 PUSHAL // save registers 279 PUSHL BP 280 CALL runtimesettls(SB) 281 POPL AX 282 POPAL 283 284 // Now segment is established. Initialize m, g. 285 get_tls(AX) 286 MOVL DX, g(AX) 287 MOVL BX, g_m(DX) 288 289 CALL runtimestackcheck(SB) // smashes AX, CX 290 MOVL 0(DX), DX // paranoia; check they are not nil 291 MOVL 0(BX), BX 292 293 // more paranoia; check that stack splitting code works 294 PUSHAL 295 CALL runtimeemptyfunc(SB) 296 POPAL 297 298 // Call fn 299 CALL SI 300 301 CALL runtimeexit1(SB) 302 MOVL $0x1234, 0x1005 303 RET 304 305 TEXT runtimesigaltstack(SB),NOSPLIT,$-8 306 MOVL $281, AX // sys___sigaltstack14 307 MOVL new+0(FP), BX 308 MOVL old+4(FP), CX 309 INT $0x80 310 CMPL AX, $0xfffff001 311 JLS 2(PC) 312 INT $3 313 RET 314 315 TEXT runtimesetldt(SB),NOSPLIT,$8 316 // Under NetBSD we set the GS base instead of messing with the LDT. 317 MOVL 16(SP), AX // tls0 318 MOVL AX, 0(SP) 319 CALL runtimesettls(SB) 320 RET 321 322 TEXT runtimesettls(SB),NOSPLIT,$16 323 // adjust for ELF: wants to use -4(GS) for g 324 MOVL base+0(FP), CX 325 ADDL $4, CX 326 MOVL $0, 0(SP) // syscall gap 327 MOVL CX, 4(SP) // arg 1 - ptr 328 MOVL $317, AX // sys__lwp_setprivate 329 INT $0x80 330 JCC 2(PC) 331 MOVL $0xf1, 0xf1 // crash 332 RET 333 334 TEXT runtimeosyield(SB),NOSPLIT,$-4 335 MOVL $350, AX // sys_sched_yield 336 INT $0x80 337 RET 338 339 TEXT runtimelwp_park(SB),NOSPLIT,$-4 340 MOVL $434, AX // sys__lwp_park 341 INT $0x80 342 MOVL AX, ret+16(FP) 343 RET 344 345 TEXT runtimelwp_unpark(SB),NOSPLIT,$-4 346 MOVL $321, AX // sys__lwp_unpark 347 INT $0x80 348 MOVL AX, ret+8(FP) 349 RET 350 351 TEXT runtimelwp_self(SB),NOSPLIT,$-4 352 MOVL $311, AX // sys__lwp_self 353 INT $0x80 354 MOVL AX, ret+0(FP) 355 RET 356 357 TEXT runtimesysctl(SB),NOSPLIT,$28 358 LEAL mib+0(FP), SI 359 LEAL 4(SP), DI 360 CLD 361 MOVSL // arg 1 - name 362 MOVSL // arg 2 - namelen 363 MOVSL // arg 3 - oldp 364 MOVSL // arg 4 - oldlenp 365 MOVSL // arg 5 - newp 366 MOVSL // arg 6 - newlen 367 MOVL $202, AX // sys___sysctl 368 INT $0x80 369 JCC 3(PC) 370 NEGL AX 371 RET 372 MOVL $0, AX 373 RET 374 375 GLOBL runtimetlsoffset(SB),NOPTR,$4 376 377 // int32 runtimekqueue(void) 378 TEXT runtimekqueue(SB),NOSPLIT,$0 379 MOVL $344, AX 380 INT $0x80 381 JAE 2(PC) 382 NEGL AX 383 MOVL AX, ret+0(FP) 384 RET 385 386 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout) 387 TEXT runtimekevent(SB),NOSPLIT,$0 388 MOVL $435, AX 389 INT $0x80 390 JAE 2(PC) 391 NEGL AX 392 MOVL AX, ret+24(FP) 393 RET 394 395 // int32 runtimecloseonexec(int32 fd) 396 TEXT runtimecloseonexec(SB),NOSPLIT,$32 397 MOVL $92, AX // fcntl 398 // 0(SP) is where the caller PC would be; kernel skips it 399 MOVL fd+0(FP), BX 400 MOVL BX, 4(SP) // fd 401 MOVL $2, 8(SP) // F_SETFD 402 MOVL $1, 12(SP) // FD_CLOEXEC 403 INT $0x80 404 JAE 2(PC) 405 NEGL AX 406 RET 407