1// Copyright 2014 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 arm64, Linux 7// 8 9#include "go_asm.h" 10#include "go_tls.h" 11#include "textflag.h" 12 13#define AT_FDCWD -100 14 15#define SYS_exit 93 16#define SYS_read 63 17#define SYS_write 64 18#define SYS_openat 56 19#define SYS_close 57 20#define SYS_fcntl 25 21#define SYS_gettimeofday 169 22#define SYS_pselect6 72 23#define SYS_mmap 222 24#define SYS_munmap 215 25#define SYS_setitimer 103 26#define SYS_clone 220 27#define SYS_sched_yield 124 28#define SYS_rt_sigreturn 139 29#define SYS_rt_sigaction 134 30#define SYS_rt_sigprocmask 135 31#define SYS_sigaltstack 132 32#define SYS_getrlimit 163 33#define SYS_madvise 233 34#define SYS_mincore 232 35#define SYS_getpid 172 36#define SYS_gettid 178 37#define SYS_kill 129 38#define SYS_tkill 130 39#define SYS_futex 98 40#define SYS_sched_getaffinity 123 41#define SYS_exit_group 94 42#define SYS_epoll_create1 20 43#define SYS_epoll_ctl 21 44#define SYS_epoll_pwait 22 45#define SYS_clock_gettime 113 46#define SYS_faccessat 48 47#define SYS_socket 198 48#define SYS_connect 203 49#define SYS_brk 214 50 51TEXT runtime·exit(SB),NOSPLIT,$-8-4 52 MOVW code+0(FP), R0 53 MOVD $SYS_exit_group, R8 54 SVC 55 RET 56 57// func exitThread(wait *uint32) 58TEXT runtime·exitThread(SB),NOSPLIT,$-8-8 59 MOVD wait+0(FP), R0 60 // We're done using the stack. 61 MOVW $0, R1 62 STLRW R1, (R0) 63 MOVW $0, R0 // exit code 64 MOVD $SYS_exit, R8 65 SVC 66 JMP 0(PC) 67 68TEXT runtime·open(SB),NOSPLIT,$-8-20 69 MOVD $AT_FDCWD, R0 70 MOVD name+0(FP), R1 71 MOVW mode+8(FP), R2 72 MOVW perm+12(FP), R3 73 MOVD $SYS_openat, R8 74 SVC 75 CMN $4095, R0 76 BCC done 77 MOVW $-1, R0 78done: 79 MOVW R0, ret+16(FP) 80 RET 81 82TEXT runtime·closefd(SB),NOSPLIT,$-8-12 83 MOVW fd+0(FP), R0 84 MOVD $SYS_close, R8 85 SVC 86 CMN $4095, R0 87 BCC done 88 MOVW $-1, R0 89done: 90 MOVW R0, ret+8(FP) 91 RET 92 93TEXT runtime·write(SB),NOSPLIT,$-8-28 94 MOVD fd+0(FP), R0 95 MOVD p+8(FP), R1 96 MOVW n+16(FP), R2 97 MOVD $SYS_write, R8 98 SVC 99 CMN $4095, R0 100 BCC done 101 MOVW $-1, R0 102done: 103 MOVW R0, ret+24(FP) 104 RET 105 106TEXT runtime·read(SB),NOSPLIT,$-8-28 107 MOVW fd+0(FP), R0 108 MOVD p+8(FP), R1 109 MOVW n+16(FP), R2 110 MOVD $SYS_read, R8 111 SVC 112 CMN $4095, R0 113 BCC done 114 MOVW $-1, R0 115done: 116 MOVW R0, ret+24(FP) 117 RET 118 119TEXT runtime·getrlimit(SB),NOSPLIT,$-8-20 120 MOVW kind+0(FP), R0 121 MOVD limit+8(FP), R1 122 MOVD $SYS_getrlimit, R8 123 SVC 124 MOVW R0, ret+16(FP) 125 RET 126 127TEXT runtime·usleep(SB),NOSPLIT,$24-4 128 MOVWU usec+0(FP), R3 129 MOVD R3, R5 130 MOVW $1000000, R4 131 UDIV R4, R3 132 MOVD R3, 8(RSP) 133 MUL R3, R4 134 SUB R4, R5 135 MOVW $1000, R4 136 MUL R4, R5 137 MOVD R5, 16(RSP) 138 139 // pselect6(0, 0, 0, 0, &ts, 0) 140 MOVD $0, R0 141 MOVD R0, R1 142 MOVD R0, R2 143 MOVD R0, R3 144 ADD $8, RSP, R4 145 MOVD R0, R5 146 MOVD $SYS_pselect6, R8 147 SVC 148 RET 149 150TEXT runtime·gettid(SB),NOSPLIT,$0-4 151 MOVD $SYS_gettid, R8 152 SVC 153 MOVW R0, ret+0(FP) 154 RET 155 156TEXT runtime·raise(SB),NOSPLIT,$-8 157 MOVD $SYS_gettid, R8 158 SVC 159 MOVW R0, R0 // arg 1 tid 160 MOVW sig+0(FP), R1 // arg 2 161 MOVD $SYS_tkill, R8 162 SVC 163 RET 164 165TEXT runtime·raiseproc(SB),NOSPLIT,$-8 166 MOVD $SYS_getpid, R8 167 SVC 168 MOVW R0, R0 // arg 1 pid 169 MOVW sig+0(FP), R1 // arg 2 170 MOVD $SYS_kill, R8 171 SVC 172 RET 173 174TEXT runtime·setitimer(SB),NOSPLIT,$-8-24 175 MOVW mode+0(FP), R0 176 MOVD new+8(FP), R1 177 MOVD old+16(FP), R2 178 MOVD $SYS_setitimer, R8 179 SVC 180 RET 181 182TEXT runtime·mincore(SB),NOSPLIT,$-8-28 183 MOVD addr+0(FP), R0 184 MOVD n+8(FP), R1 185 MOVD dst+16(FP), R2 186 MOVD $SYS_mincore, R8 187 SVC 188 MOVW R0, ret+24(FP) 189 RET 190 191// func walltime() (sec int64, nsec int32) 192TEXT runtime·walltime(SB),NOSPLIT,$24-12 193 MOVW $0, R0 // CLOCK_REALTIME 194 MOVD RSP, R1 195 MOVD $SYS_clock_gettime, R8 196 SVC 197 MOVD 0(RSP), R3 // sec 198 MOVD 8(RSP), R5 // nsec 199 MOVD R3, sec+0(FP) 200 MOVW R5, nsec+8(FP) 201 RET 202 203TEXT runtime·nanotime(SB),NOSPLIT,$24-8 204 MOVW $1, R0 // CLOCK_MONOTONIC 205 MOVD RSP, R1 206 MOVD $SYS_clock_gettime, R8 207 SVC 208 MOVD 0(RSP), R3 // sec 209 MOVD 8(RSP), R5 // nsec 210 // sec is in R3, nsec in R5 211 // return nsec in R3 212 MOVD $1000000000, R4 213 MUL R4, R3 214 ADD R5, R3 215 MOVD R3, ret+0(FP) 216 RET 217 218TEXT runtime·rtsigprocmask(SB),NOSPLIT,$-8-28 219 MOVW how+0(FP), R0 220 MOVD new+8(FP), R1 221 MOVD old+16(FP), R2 222 MOVW size+24(FP), R3 223 MOVD $SYS_rt_sigprocmask, R8 224 SVC 225 CMN $4095, R0 226 BCC done 227 MOVD $0, R0 228 MOVD R0, (R0) // crash 229done: 230 RET 231 232TEXT runtime·rt_sigaction(SB),NOSPLIT,$-8-36 233 MOVD sig+0(FP), R0 234 MOVD new+8(FP), R1 235 MOVD old+16(FP), R2 236 MOVD size+24(FP), R3 237 MOVD $SYS_rt_sigaction, R8 238 SVC 239 MOVW R0, ret+32(FP) 240 RET 241 242TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 243 MOVW sig+8(FP), R0 244 MOVD info+16(FP), R1 245 MOVD ctx+24(FP), R2 246 MOVD fn+0(FP), R11 247 BL (R11) 248 RET 249 250TEXT runtime·sigtramp(SB),NOSPLIT,$24 251 // this might be called in external code context, 252 // where g is not set. 253 // first save R0, because runtime·load_g will clobber it 254 MOVW R0, 8(RSP) 255 MOVBU runtime·iscgo(SB), R0 256 CMP $0, R0 257 BEQ 2(PC) 258 BL runtime·load_g(SB) 259 260 MOVD R1, 16(RSP) 261 MOVD R2, 24(RSP) 262 MOVD $runtime·sigtrampgo(SB), R0 263 BL (R0) 264 RET 265 266TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 267 MOVD $runtime·sigtramp(SB), R3 268 B (R3) 269 270TEXT runtime·mmap(SB),NOSPLIT,$-8 271 MOVD addr+0(FP), R0 272 MOVD n+8(FP), R1 273 MOVW prot+16(FP), R2 274 MOVW flags+20(FP), R3 275 MOVW fd+24(FP), R4 276 MOVW off+28(FP), R5 277 278 MOVD $SYS_mmap, R8 279 SVC 280 CMN $4095, R0 281 BCC ok 282 NEG R0,R0 283 MOVD $0, p+32(FP) 284 MOVD R0, err+40(FP) 285 RET 286ok: 287 MOVD R0, p+32(FP) 288 MOVD $0, err+40(FP) 289 RET 290 291TEXT runtime·munmap(SB),NOSPLIT,$-8 292 MOVD addr+0(FP), R0 293 MOVD n+8(FP), R1 294 MOVD $SYS_munmap, R8 295 SVC 296 CMN $4095, R0 297 BCC cool 298 MOVD R0, 0xf0(R0) 299cool: 300 RET 301 302TEXT runtime·madvise(SB),NOSPLIT,$-8 303 MOVD addr+0(FP), R0 304 MOVD n+8(FP), R1 305 MOVW flags+16(FP), R2 306 MOVD $SYS_madvise, R8 307 SVC 308 // ignore failure - maybe pages are locked 309 RET 310 311// int64 futex(int32 *uaddr, int32 op, int32 val, 312// struct timespec *timeout, int32 *uaddr2, int32 val2); 313TEXT runtime·futex(SB),NOSPLIT,$-8 314 MOVD addr+0(FP), R0 315 MOVW op+8(FP), R1 316 MOVW val+12(FP), R2 317 MOVD ts+16(FP), R3 318 MOVD addr2+24(FP), R4 319 MOVW val3+32(FP), R5 320 MOVD $SYS_futex, R8 321 SVC 322 MOVW R0, ret+40(FP) 323 RET 324 325// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 326TEXT runtime·clone(SB),NOSPLIT,$-8 327 MOVW flags+0(FP), R0 328 MOVD stk+8(FP), R1 329 330 // Copy mp, gp, fn off parent stack for use by child. 331 MOVD mp+16(FP), R10 332 MOVD gp+24(FP), R11 333 MOVD fn+32(FP), R12 334 335 MOVD R10, -8(R1) 336 MOVD R11, -16(R1) 337 MOVD R12, -24(R1) 338 MOVD $1234, R10 339 MOVD R10, -32(R1) 340 341 MOVD $SYS_clone, R8 342 SVC 343 344 // In parent, return. 345 CMP ZR, R0 346 BEQ child 347 MOVW R0, ret+40(FP) 348 RET 349child: 350 351 // In child, on new stack. 352 MOVD -32(RSP), R10 353 MOVD $1234, R0 354 CMP R0, R10 355 BEQ good 356 MOVD $0, R0 357 MOVD R0, (R0) // crash 358 359good: 360 // Initialize m->procid to Linux tid 361 MOVD $SYS_gettid, R8 362 SVC 363 364 MOVD -24(RSP), R12 // fn 365 MOVD -16(RSP), R11 // g 366 MOVD -8(RSP), R10 // m 367 368 CMP $0, R10 369 BEQ nog 370 CMP $0, R11 371 BEQ nog 372 373 MOVD R0, m_procid(R10) 374 375 // TODO: setup TLS. 376 377 // In child, set up new stack 378 MOVD R10, g_m(R11) 379 MOVD R11, g 380 //CALL runtime·stackcheck(SB) 381 382nog: 383 // Call fn 384 MOVD R12, R0 385 BL (R0) 386 387 // It shouldn't return. If it does, exit that thread. 388 MOVW $111, R0 389again: 390 MOVD $SYS_exit, R8 391 SVC 392 B again // keep exiting 393 394TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 395 MOVD new+0(FP), R0 396 MOVD old+8(FP), R1 397 MOVD $SYS_sigaltstack, R8 398 SVC 399 CMN $4095, R0 400 BCC ok 401 MOVD $0, R0 402 MOVD R0, (R0) // crash 403ok: 404 RET 405 406TEXT runtime·osyield(SB),NOSPLIT,$-8 407 MOVD $SYS_sched_yield, R8 408 SVC 409 RET 410 411TEXT runtime·sched_getaffinity(SB),NOSPLIT,$-8 412 MOVD pid+0(FP), R0 413 MOVD len+8(FP), R1 414 MOVD buf+16(FP), R2 415 MOVD $SYS_sched_getaffinity, R8 416 SVC 417 MOVW R0, ret+24(FP) 418 RET 419 420// int32 runtime·epollcreate(int32 size); 421TEXT runtime·epollcreate(SB),NOSPLIT,$-8 422 MOVW $0, R0 423 MOVD $SYS_epoll_create1, R8 424 SVC 425 MOVW R0, ret+8(FP) 426 RET 427 428// int32 runtime·epollcreate1(int32 flags); 429TEXT runtime·epollcreate1(SB),NOSPLIT,$-8 430 MOVW flags+0(FP), R0 431 MOVD $SYS_epoll_create1, R8 432 SVC 433 MOVW R0, ret+8(FP) 434 RET 435 436// func epollctl(epfd, op, fd int32, ev *epollEvent) int 437TEXT runtime·epollctl(SB),NOSPLIT,$-8 438 MOVW epfd+0(FP), R0 439 MOVW op+4(FP), R1 440 MOVW fd+8(FP), R2 441 MOVD ev+16(FP), R3 442 MOVD $SYS_epoll_ctl, R8 443 SVC 444 MOVW R0, ret+24(FP) 445 RET 446 447// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 448TEXT runtime·epollwait(SB),NOSPLIT,$-8 449 MOVW epfd+0(FP), R0 450 MOVD ev+8(FP), R1 451 MOVW nev+16(FP), R2 452 MOVW timeout+20(FP), R3 453 MOVD $0, R4 454 MOVD $SYS_epoll_pwait, R8 455 SVC 456 MOVW R0, ret+24(FP) 457 RET 458 459// void runtime·closeonexec(int32 fd); 460TEXT runtime·closeonexec(SB),NOSPLIT,$-8 461 MOVW fd+0(FP), R0 // fd 462 MOVD $2, R1 // F_SETFD 463 MOVD $1, R2 // FD_CLOEXEC 464 MOVD $SYS_fcntl, R8 465 SVC 466 RET 467 468// int access(const char *name, int mode) 469TEXT runtime·access(SB),NOSPLIT,$0-20 470 MOVD $AT_FDCWD, R0 471 MOVD name+0(FP), R1 472 MOVW mode+8(FP), R2 473 MOVD $SYS_faccessat, R8 474 SVC 475 MOVW R0, ret+16(FP) 476 RET 477 478// int connect(int fd, const struct sockaddr *addr, socklen_t len) 479TEXT runtime·connect(SB),NOSPLIT,$0-28 480 MOVW fd+0(FP), R0 481 MOVD addr+8(FP), R1 482 MOVW len+16(FP), R2 483 MOVD $SYS_connect, R8 484 SVC 485 MOVW R0, ret+24(FP) 486 RET 487 488// int socket(int domain, int typ, int prot) 489TEXT runtime·socket(SB),NOSPLIT,$0-20 490 MOVW domain+0(FP), R0 491 MOVW typ+4(FP), R1 492 MOVW prot+8(FP), R2 493 MOVD $SYS_socket, R8 494 SVC 495 MOVW R0, ret+16(FP) 496 RET 497 498// func sbrk0() uintptr 499TEXT runtime·sbrk0(SB),NOSPLIT,$0-8 500 // Implemented as brk(NULL). 501 MOVD $0, R0 502 MOVD $SYS_brk, R8 503 SVC 504 MOVD R0, ret+0(FP) 505 RET 506