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 runtimesigtramp(SB),NOSPLIT,$44 219 get_tls(CX) 220 221 // check that g exists 222 MOVL g(CX), DI 223 CMPL DI, $0 224 JNE 6(PC) 225 MOVL signo+0(FP), BX 226 MOVL BX, 0(SP) 227 MOVL $runtimebadsignal(SB), AX 228 CALL AX 229 RET 230 231 // save g 232 MOVL DI, 20(SP) 233 234 // g = m->gsignal 235 MOVL g_m(DI), BX 236 MOVL m_gsignal(BX), BX 237 MOVL BX, g(CX) 238 239 // copy arguments for call to sighandler 240 MOVL signo+0(FP), BX 241 MOVL BX, 0(SP) 242 MOVL info+4(FP), BX 243 MOVL BX, 4(SP) 244 MOVL context+8(FP), BX 245 MOVL BX, 8(SP) 246 MOVL DI, 12(SP) 247 248 CALL runtimesighandler(SB) 249 250 // restore g 251 get_tls(CX) 252 MOVL 20(SP), BX 253 MOVL BX, g(CX) 254 RET 255 256 // int32 lwp_create(void *context, uintptr flags, void *lwpid); 257 TEXT runtimelwp_create(SB),NOSPLIT,$16 258 MOVL $0, 0(SP) 259 MOVL ctxt+0(FP), AX 260 MOVL AX, 4(SP) // arg 1 - context 261 MOVL flags+4(FP), AX 262 MOVL AX, 8(SP) // arg 2 - flags 263 MOVL lwpid+8(FP), AX 264 MOVL AX, 12(SP) // arg 3 - lwpid 265 MOVL $309, AX // sys__lwp_create 266 INT $0x80 267 JCC 2(PC) 268 NEGL AX 269 MOVL AX, ret+12(FP) 270 RET 271 272 TEXT runtimelwp_tramp(SB),NOSPLIT,$0 273 274 // Set FS to point at m->tls 275 LEAL m_tls(BX), BP 276 PUSHAL // save registers 277 PUSHL BP 278 CALL runtimesettls(SB) 279 POPL AX 280 POPAL 281 282 // Now segment is established. Initialize m, g. 283 get_tls(AX) 284 MOVL DX, g(AX) 285 MOVL BX, g_m(DX) 286 287 CALL runtimestackcheck(SB) // smashes AX, CX 288 MOVL 0(DX), DX // paranoia; check they are not nil 289 MOVL 0(BX), BX 290 291 // more paranoia; check that stack splitting code works 292 PUSHAL 293 CALL runtimeemptyfunc(SB) 294 POPAL 295 296 // Call fn 297 CALL SI 298 299 CALL runtimeexit1(SB) 300 MOVL $0x1234, 0x1005 301 RET 302 303 TEXT runtimesigaltstack(SB),NOSPLIT,$-8 304 MOVL $281, AX // sys___sigaltstack14 305 MOVL new+4(SP), BX 306 MOVL old+8(SP), CX 307 INT $0x80 308 CMPL AX, $0xfffff001 309 JLS 2(PC) 310 INT $3 311 RET 312 313 TEXT runtimesetldt(SB),NOSPLIT,$8 314 // Under NetBSD we set the GS base instead of messing with the LDT. 315 MOVL 16(SP), AX // tls0 316 MOVL AX, 0(SP) 317 CALL runtimesettls(SB) 318 RET 319 320 TEXT runtimesettls(SB),NOSPLIT,$16 321 // adjust for ELF: wants to use -4(GS) for g 322 MOVL base+0(FP), CX 323 ADDL $4, CX 324 MOVL $0, 0(SP) // syscall gap 325 MOVL CX, 4(SP) // arg 1 - ptr 326 MOVL $317, AX // sys__lwp_setprivate 327 INT $0x80 328 JCC 2(PC) 329 MOVL $0xf1, 0xf1 // crash 330 RET 331 332 TEXT runtimeosyield(SB),NOSPLIT,$-4 333 MOVL $350, AX // sys_sched_yield 334 INT $0x80 335 RET 336 337 TEXT runtimelwp_park(SB),NOSPLIT,$-4 338 MOVL $434, AX // sys__lwp_park 339 INT $0x80 340 MOVL AX, ret+16(FP) 341 RET 342 343 TEXT runtimelwp_unpark(SB),NOSPLIT,$-4 344 MOVL $321, AX // sys__lwp_unpark 345 INT $0x80 346 MOVL AX, ret+8(FP) 347 RET 348 349 TEXT runtimelwp_self(SB),NOSPLIT,$-4 350 MOVL $311, AX // sys__lwp_self 351 INT $0x80 352 MOVL AX, ret+0(FP) 353 RET 354 355 TEXT runtimesysctl(SB),NOSPLIT,$28 356 LEAL mib+0(FP), SI 357 LEAL 4(SP), DI 358 CLD 359 MOVSL // arg 1 - name 360 MOVSL // arg 2 - namelen 361 MOVSL // arg 3 - oldp 362 MOVSL // arg 4 - oldlenp 363 MOVSL // arg 5 - newp 364 MOVSL // arg 6 - newlen 365 MOVL $202, AX // sys___sysctl 366 INT $0x80 367 JCC 3(PC) 368 NEGL AX 369 RET 370 MOVL $0, AX 371 RET 372 373 GLOBL runtimetlsoffset(SB),NOPTR,$4 374 375 // int32 runtimekqueue(void) 376 TEXT runtimekqueue(SB),NOSPLIT,$0 377 MOVL $344, AX 378 INT $0x80 379 JAE 2(PC) 380 NEGL AX 381 MOVL AX, ret+0(FP) 382 RET 383 384 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout) 385 TEXT runtimekevent(SB),NOSPLIT,$0 386 MOVL $435, AX 387 INT $0x80 388 JAE 2(PC) 389 NEGL AX 390 MOVL AX, ret+24(FP) 391 RET 392 393 // int32 runtimecloseonexec(int32 fd) 394 TEXT runtimecloseonexec(SB),NOSPLIT,$32 395 MOVL $92, AX // fcntl 396 // 0(SP) is where the caller PC would be; kernel skips it 397 MOVL fd+0(FP), BX 398 MOVL BX, 4(SP) // fd 399 MOVL $2, 8(SP) // F_SETFD 400 MOVL $1, 12(SP) // FD_CLOEXEC 401 INT $0x80 402 JAE 2(PC) 403 NEGL AX 404 RET 405