github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/runtime/sys_linux_arm.s (about) 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 // 6 // System calls and other sys.stuff for arm, Linux 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 1 15 16 // for EABI, as we don't support OABI 17 #define SYS_BASE 0x0 18 19 #define SYS_exit (SYS_BASE + 1) 20 #define SYS_read (SYS_BASE + 3) 21 #define SYS_write (SYS_BASE + 4) 22 #define SYS_open (SYS_BASE + 5) 23 #define SYS_close (SYS_BASE + 6) 24 #define SYS_getpid (SYS_BASE + 20) 25 #define SYS_kill (SYS_BASE + 37) 26 #define SYS_clone (SYS_BASE + 120) 27 #define SYS_rt_sigreturn (SYS_BASE + 173) 28 #define SYS_rt_sigaction (SYS_BASE + 174) 29 #define SYS_rt_sigprocmask (SYS_BASE + 175) 30 #define SYS_sigaltstack (SYS_BASE + 186) 31 #define SYS_mmap2 (SYS_BASE + 192) 32 #define SYS_futex (SYS_BASE + 240) 33 #define SYS_exit_group (SYS_BASE + 248) 34 #define SYS_munmap (SYS_BASE + 91) 35 #define SYS_madvise (SYS_BASE + 220) 36 #define SYS_setitimer (SYS_BASE + 104) 37 #define SYS_mincore (SYS_BASE + 219) 38 #define SYS_gettid (SYS_BASE + 224) 39 #define SYS_tgkill (SYS_BASE + 268) 40 #define SYS_sched_yield (SYS_BASE + 158) 41 #define SYS_nanosleep (SYS_BASE + 162) 42 #define SYS_sched_getaffinity (SYS_BASE + 242) 43 #define SYS_clock_gettime (SYS_BASE + 263) 44 #define SYS_epoll_create (SYS_BASE + 250) 45 #define SYS_epoll_ctl (SYS_BASE + 251) 46 #define SYS_epoll_wait (SYS_BASE + 252) 47 #define SYS_epoll_create1 (SYS_BASE + 357) 48 #define SYS_fcntl (SYS_BASE + 55) 49 #define SYS_access (SYS_BASE + 33) 50 #define SYS_connect (SYS_BASE + 283) 51 #define SYS_socket (SYS_BASE + 281) 52 #define SYS_brk (SYS_BASE + 45) 53 54 #define ARM_BASE (SYS_BASE + 0x0f0000) 55 56 TEXT runtime·open(SB),NOSPLIT,$0 57 MOVW name+0(FP), R0 58 MOVW mode+4(FP), R1 59 MOVW perm+8(FP), R2 60 MOVW $SYS_open, R7 61 SWI $0 62 MOVW $0xfffff001, R1 63 CMP R1, R0 64 MOVW.HI $-1, R0 65 MOVW R0, ret+12(FP) 66 RET 67 68 TEXT runtime·closefd(SB),NOSPLIT,$0 69 MOVW fd+0(FP), R0 70 MOVW $SYS_close, R7 71 SWI $0 72 MOVW $0xfffff001, R1 73 CMP R1, R0 74 MOVW.HI $-1, R0 75 MOVW R0, ret+4(FP) 76 RET 77 78 TEXT runtime·write(SB),NOSPLIT,$0 79 MOVW fd+0(FP), R0 80 MOVW p+4(FP), R1 81 MOVW n+8(FP), R2 82 MOVW $SYS_write, R7 83 SWI $0 84 MOVW $0xfffff001, R1 85 CMP R1, R0 86 MOVW.HI $-1, R0 87 MOVW R0, ret+12(FP) 88 RET 89 90 TEXT runtime·read(SB),NOSPLIT,$0 91 MOVW fd+0(FP), R0 92 MOVW p+4(FP), R1 93 MOVW n+8(FP), R2 94 MOVW $SYS_read, R7 95 SWI $0 96 MOVW $0xfffff001, R1 97 CMP R1, R0 98 MOVW.HI $-1, R0 99 MOVW R0, ret+12(FP) 100 RET 101 102 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0 103 MOVW code+0(FP), R0 104 MOVW $SYS_exit_group, R7 105 SWI $0 106 MOVW $1234, R0 107 MOVW $1002, R1 108 MOVW R0, (R1) // fail hard 109 110 TEXT exit1<>(SB),NOSPLIT|NOFRAME,$0 111 MOVW code+0(FP), R0 112 MOVW $SYS_exit, R7 113 SWI $0 114 MOVW $1234, R0 115 MOVW $1003, R1 116 MOVW R0, (R1) // fail hard 117 118 // func exitThread(wait *uint32) 119 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-4 120 MOVW wait+0(FP), R0 121 // We're done using the stack. 122 // Alas, there's no reliable way to make this write atomic 123 // without potentially using the stack. So it goes. 124 MOVW $0, R1 125 MOVW R1, (R0) 126 MOVW $0, R0 // exit code 127 MOVW $SYS_exit, R7 128 SWI $0 129 MOVW $1234, R0 130 MOVW $1004, R1 131 MOVW R0, (R1) // fail hard 132 JMP 0(PC) 133 134 TEXT runtime·gettid(SB),NOSPLIT,$0-4 135 MOVW $SYS_gettid, R7 136 SWI $0 137 MOVW R0, ret+0(FP) 138 RET 139 140 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0 141 MOVW $SYS_getpid, R7 142 SWI $0 143 MOVW R0, R4 144 MOVW $SYS_gettid, R7 145 SWI $0 146 MOVW R0, R1 // arg 2 tid 147 MOVW R4, R0 // arg 1 pid 148 MOVW sig+0(FP), R2 // arg 3 149 MOVW $SYS_tgkill, R7 150 SWI $0 151 RET 152 153 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0 154 MOVW $SYS_getpid, R7 155 SWI $0 156 // arg 1 tid already in R0 from getpid 157 MOVW sig+0(FP), R1 // arg 2 - signal 158 MOVW $SYS_kill, R7 159 SWI $0 160 RET 161 162 TEXT runtime·mmap(SB),NOSPLIT,$0 163 MOVW addr+0(FP), R0 164 MOVW n+4(FP), R1 165 MOVW prot+8(FP), R2 166 MOVW flags+12(FP), R3 167 MOVW fd+16(FP), R4 168 MOVW off+20(FP), R5 169 MOVW $SYS_mmap2, R7 170 SWI $0 171 MOVW $0xfffff001, R6 172 CMP R6, R0 173 MOVW $0, R1 174 RSB.HI $0, R0 175 MOVW.HI R0, R1 // if error, put in R1 176 MOVW.HI $0, R0 177 MOVW R0, p+24(FP) 178 MOVW R1, err+28(FP) 179 RET 180 181 TEXT runtime·munmap(SB),NOSPLIT,$0 182 MOVW addr+0(FP), R0 183 MOVW n+4(FP), R1 184 MOVW $SYS_munmap, R7 185 SWI $0 186 MOVW $0xfffff001, R6 187 CMP R6, R0 188 MOVW.HI $0, R8 // crash on syscall failure 189 MOVW.HI R8, (R8) 190 RET 191 192 TEXT runtime·madvise(SB),NOSPLIT,$0 193 MOVW addr+0(FP), R0 194 MOVW n+4(FP), R1 195 MOVW flags+8(FP), R2 196 MOVW $SYS_madvise, R7 197 SWI $0 198 MOVW R0, ret+12(FP) 199 RET 200 201 TEXT runtime·setitimer(SB),NOSPLIT,$0 202 MOVW mode+0(FP), R0 203 MOVW new+4(FP), R1 204 MOVW old+8(FP), R2 205 MOVW $SYS_setitimer, R7 206 SWI $0 207 RET 208 209 TEXT runtime·mincore(SB),NOSPLIT,$0 210 MOVW addr+0(FP), R0 211 MOVW n+4(FP), R1 212 MOVW dst+8(FP), R2 213 MOVW $SYS_mincore, R7 214 SWI $0 215 MOVW R0, ret+12(FP) 216 RET 217 218 TEXT runtime·walltime(SB),NOSPLIT,$0-12 219 // We don't know how much stack space the VDSO code will need, 220 // so switch to g0. 221 222 // Save old SP. Use R13 instead of SP to avoid linker rewriting the offsets. 223 MOVW R13, R4 // R4 is unchanged by C code. 224 225 MOVW g_m(g), R5 // R5 is unchanged by C code. 226 227 // Set vdsoPC and vdsoSP for SIGPROF traceback. 228 MOVW LR, m_vdsoPC(R5) 229 MOVW R13, m_vdsoSP(R5) 230 231 MOVW m_curg(R5), R0 232 233 CMP g, R0 // Only switch if on curg. 234 B.NE noswitch 235 236 MOVW m_g0(R5), R0 237 MOVW (g_sched+gobuf_sp)(R0), R13 // Set SP to g0 stack 238 239 noswitch: 240 SUB $24, R13 // Space for results 241 BIC $0x7, R13 // Align for C code 242 243 MOVW $CLOCK_REALTIME, R0 244 MOVW $8(R13), R1 // timespec 245 MOVW runtime·vdsoClockgettimeSym(SB), R11 246 CMP $0, R11 247 B.EQ fallback 248 249 BL (R11) 250 JMP finish 251 252 fallback: 253 MOVW $SYS_clock_gettime, R7 254 SWI $0 255 256 finish: 257 MOVW 8(R13), R0 // sec 258 MOVW 12(R13), R2 // nsec 259 260 MOVW R4, R13 // Restore real SP 261 MOVW $0, R1 262 MOVW R1, m_vdsoSP(R5) 263 264 MOVW R0, sec_lo+0(FP) 265 MOVW R1, sec_hi+4(FP) 266 MOVW R2, nsec+8(FP) 267 RET 268 269 // int64 nanotime(void) 270 TEXT runtime·nanotime(SB),NOSPLIT,$0-8 271 // Switch to g0 stack. See comment above in runtime·walltime. 272 273 // Save old SP. Use R13 instead of SP to avoid linker rewriting the offsets. 274 MOVW R13, R4 // R4 is unchanged by C code. 275 276 MOVW g_m(g), R5 // R5 is unchanged by C code. 277 278 // Set vdsoPC and vdsoSP for SIGPROF traceback. 279 MOVW LR, m_vdsoPC(R5) 280 MOVW R13, m_vdsoSP(R5) 281 282 MOVW m_curg(R5), R0 283 284 CMP g, R0 // Only switch if on curg. 285 B.NE noswitch 286 287 MOVW m_g0(R5), R0 288 MOVW (g_sched+gobuf_sp)(R0), R13 // Set SP to g0 stack 289 290 noswitch: 291 SUB $24, R13 // Space for results 292 BIC $0x7, R13 // Align for C code 293 294 MOVW $CLOCK_MONOTONIC, R0 295 MOVW $8(R13), R1 // timespec 296 MOVW runtime·vdsoClockgettimeSym(SB), R11 297 CMP $0, R11 298 B.EQ fallback 299 300 BL (R11) 301 JMP finish 302 303 fallback: 304 MOVW $SYS_clock_gettime, R7 305 SWI $0 306 307 finish: 308 MOVW 8(R13), R0 // sec 309 MOVW 12(R13), R2 // nsec 310 311 MOVW R4, R13 // Restore real SP 312 MOVW $0, R4 313 MOVW R4, m_vdsoSP(R5) 314 315 MOVW $1000000000, R3 316 MULLU R0, R3, (R1, R0) 317 ADD.S R2, R0 318 ADC R4, R1 319 320 MOVW R0, ret_lo+0(FP) 321 MOVW R1, ret_hi+4(FP) 322 RET 323 324 // int32 futex(int32 *uaddr, int32 op, int32 val, 325 // struct timespec *timeout, int32 *uaddr2, int32 val2); 326 TEXT runtime·futex(SB),NOSPLIT,$0 327 MOVW addr+0(FP), R0 328 MOVW op+4(FP), R1 329 MOVW val+8(FP), R2 330 MOVW ts+12(FP), R3 331 MOVW addr2+16(FP), R4 332 MOVW val3+20(FP), R5 333 MOVW $SYS_futex, R7 334 SWI $0 335 MOVW R0, ret+24(FP) 336 RET 337 338 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void)); 339 TEXT runtime·clone(SB),NOSPLIT,$0 340 MOVW flags+0(FP), R0 341 MOVW stk+4(FP), R1 342 MOVW $0, R2 // parent tid ptr 343 MOVW $0, R3 // tls_val 344 MOVW $0, R4 // child tid ptr 345 MOVW $0, R5 346 347 // Copy mp, gp, fn off parent stack for use by child. 348 // TODO(kaib): figure out which registers are clobbered by clone and avoid stack copying 349 MOVW $-16(R1), R1 350 MOVW mp+8(FP), R6 351 MOVW R6, 0(R1) 352 MOVW gp+12(FP), R6 353 MOVW R6, 4(R1) 354 MOVW fn+16(FP), R6 355 MOVW R6, 8(R1) 356 MOVW $1234, R6 357 MOVW R6, 12(R1) 358 359 MOVW $SYS_clone, R7 360 SWI $0 361 362 // In parent, return. 363 CMP $0, R0 364 BEQ 3(PC) 365 MOVW R0, ret+20(FP) 366 RET 367 368 // Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup' 369 MOVW 12(R13), R0 370 MOVW $1234, R1 371 CMP R0, R1 372 BEQ 2(PC) 373 BL runtime·abort(SB) 374 375 MOVW 0(R13), R8 // m 376 MOVW 4(R13), R0 // g 377 378 CMP $0, R8 379 BEQ nog 380 CMP $0, R0 381 BEQ nog 382 383 MOVW R0, g 384 MOVW R8, g_m(g) 385 386 // paranoia; check they are not nil 387 MOVW 0(R8), R0 388 MOVW 0(g), R0 389 390 BL runtime·emptyfunc(SB) // fault if stack check is wrong 391 392 // Initialize m->procid to Linux tid 393 MOVW $SYS_gettid, R7 394 SWI $0 395 MOVW g_m(g), R8 396 MOVW R0, m_procid(R8) 397 398 nog: 399 // Call fn 400 MOVW 8(R13), R0 401 MOVW $16(R13), R13 402 BL (R0) 403 404 // It shouldn't return. If it does, exit that thread. 405 SUB $16, R13 // restore the stack pointer to avoid memory corruption 406 MOVW $0, R0 407 MOVW R0, 4(R13) 408 BL exit1<>(SB) 409 410 MOVW $1234, R0 411 MOVW $1005, R1 412 MOVW R0, (R1) 413 414 TEXT runtime·sigaltstack(SB),NOSPLIT,$0 415 MOVW new+0(FP), R0 416 MOVW old+4(FP), R1 417 MOVW $SYS_sigaltstack, R7 418 SWI $0 419 MOVW $0xfffff001, R6 420 CMP R6, R0 421 MOVW.HI $0, R8 // crash on syscall failure 422 MOVW.HI R8, (R8) 423 RET 424 425 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 426 MOVW sig+4(FP), R0 427 MOVW info+8(FP), R1 428 MOVW ctx+12(FP), R2 429 MOVW fn+0(FP), R11 430 MOVW R13, R4 431 SUB $24, R13 432 BIC $0x7, R13 // alignment for ELF ABI 433 BL (R11) 434 MOVW R4, R13 435 RET 436 437 TEXT runtime·sigtramp(SB),NOSPLIT,$12 438 // this might be called in external code context, 439 // where g is not set. 440 // first save R0, because runtime·load_g will clobber it 441 MOVW R0, 4(R13) 442 MOVB runtime·iscgo(SB), R0 443 CMP $0, R0 444 BL.NE runtime·load_g(SB) 445 446 MOVW R1, 8(R13) 447 MOVW R2, 12(R13) 448 MOVW $runtime·sigtrampgo(SB), R11 449 BL (R11) 450 RET 451 452 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 453 MOVW $runtime·sigtramp(SB), R11 454 B (R11) 455 456 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0 457 MOVW how+0(FP), R0 458 MOVW new+4(FP), R1 459 MOVW old+8(FP), R2 460 MOVW size+12(FP), R3 461 MOVW $SYS_rt_sigprocmask, R7 462 SWI $0 463 RET 464 465 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0 466 MOVW sig+0(FP), R0 467 MOVW new+4(FP), R1 468 MOVW old+8(FP), R2 469 MOVW size+12(FP), R3 470 MOVW $SYS_rt_sigaction, R7 471 SWI $0 472 MOVW R0, ret+16(FP) 473 RET 474 475 TEXT runtime·usleep(SB),NOSPLIT,$12 476 MOVW usec+0(FP), R0 477 CALL runtime·usplitR0(SB) 478 MOVW R0, 4(R13) 479 MOVW $1000, R0 // usec to nsec 480 MUL R0, R1 481 MOVW R1, 8(R13) 482 MOVW $4(R13), R0 483 MOVW $0, R1 484 MOVW $SYS_nanosleep, R7 485 SWI $0 486 RET 487 488 // As for cas, memory barriers are complicated on ARM, but the kernel 489 // provides a user helper. ARMv5 does not support SMP and has no 490 // memory barrier instruction at all. ARMv6 added SMP support and has 491 // a memory barrier, but it requires writing to a coprocessor 492 // register. ARMv7 introduced the DMB instruction, but it's expensive 493 // even on single-core devices. The kernel helper takes care of all of 494 // this for us. 495 496 TEXT kernelPublicationBarrier<>(SB),NOSPLIT,$0 497 // void __kuser_memory_barrier(void); 498 MOVW $0xffff0fa0, R11 499 CALL (R11) 500 RET 501 502 TEXT ·publicationBarrier(SB),NOSPLIT,$0 503 MOVB ·goarm(SB), R11 504 CMP $7, R11 505 BLT 2(PC) 506 JMP ·armPublicationBarrier(SB) 507 JMP kernelPublicationBarrier<>(SB) // extra layer so this function is leaf and no SP adjustment on GOARM=7 508 509 TEXT runtime·osyield(SB),NOSPLIT,$0 510 MOVW $SYS_sched_yield, R7 511 SWI $0 512 RET 513 514 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 515 MOVW pid+0(FP), R0 516 MOVW len+4(FP), R1 517 MOVW buf+8(FP), R2 518 MOVW $SYS_sched_getaffinity, R7 519 SWI $0 520 MOVW R0, ret+12(FP) 521 RET 522 523 // int32 runtime·epollcreate(int32 size) 524 TEXT runtime·epollcreate(SB),NOSPLIT,$0 525 MOVW size+0(FP), R0 526 MOVW $SYS_epoll_create, R7 527 SWI $0 528 MOVW R0, ret+4(FP) 529 RET 530 531 // int32 runtime·epollcreate1(int32 flags) 532 TEXT runtime·epollcreate1(SB),NOSPLIT,$0 533 MOVW flags+0(FP), R0 534 MOVW $SYS_epoll_create1, R7 535 SWI $0 536 MOVW R0, ret+4(FP) 537 RET 538 539 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 540 TEXT runtime·epollctl(SB),NOSPLIT,$0 541 MOVW epfd+0(FP), R0 542 MOVW op+4(FP), R1 543 MOVW fd+8(FP), R2 544 MOVW ev+12(FP), R3 545 MOVW $SYS_epoll_ctl, R7 546 SWI $0 547 MOVW R0, ret+16(FP) 548 RET 549 550 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout) 551 TEXT runtime·epollwait(SB),NOSPLIT,$0 552 MOVW epfd+0(FP), R0 553 MOVW ev+4(FP), R1 554 MOVW nev+8(FP), R2 555 MOVW timeout+12(FP), R3 556 MOVW $SYS_epoll_wait, R7 557 SWI $0 558 MOVW R0, ret+16(FP) 559 RET 560 561 // void runtime·closeonexec(int32 fd) 562 TEXT runtime·closeonexec(SB),NOSPLIT,$0 563 MOVW fd+0(FP), R0 // fd 564 MOVW $2, R1 // F_SETFD 565 MOVW $1, R2 // FD_CLOEXEC 566 MOVW $SYS_fcntl, R7 567 SWI $0 568 RET 569 570 // b __kuser_get_tls @ 0xffff0fe0 571 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0 572 MOVW $0xffff0fe0, R0 573 B (R0) 574 575 TEXT runtime·access(SB),NOSPLIT,$0 576 MOVW name+0(FP), R0 577 MOVW mode+4(FP), R1 578 MOVW $SYS_access, R7 579 SWI $0 580 MOVW R0, ret+8(FP) 581 RET 582 583 TEXT runtime·connect(SB),NOSPLIT,$0 584 MOVW fd+0(FP), R0 585 MOVW addr+4(FP), R1 586 MOVW len+8(FP), R2 587 MOVW $SYS_connect, R7 588 SWI $0 589 MOVW R0, ret+12(FP) 590 RET 591 592 TEXT runtime·socket(SB),NOSPLIT,$0 593 MOVW domain+0(FP), R0 594 MOVW typ+4(FP), R1 595 MOVW prot+8(FP), R2 596 MOVW $SYS_socket, R7 597 SWI $0 598 MOVW R0, ret+12(FP) 599 RET 600 601 // func sbrk0() uintptr 602 TEXT runtime·sbrk0(SB),NOSPLIT,$0-4 603 // Implemented as brk(NULL). 604 MOVW $0, R0 605 MOVW $SYS_brk, R7 606 SWI $0 607 MOVW R0, ret+0(FP) 608 RET