1// Copyright 2019 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 arm64, OpenBSD 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#define CLOCK_REALTIME $0 14#define CLOCK_MONOTONIC $3 15 16// Exit the entire program (like C exit) 17TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0 18 MOVW code+0(FP), R0 // arg 1 - status 19 MOVD $1, R8 // sys_exit 20 SVC 21 BCC 3(PC) 22 MOVD $0, R0 // crash on syscall failure 23 MOVD R0, (R0) 24 RET 25 26// func exitThread(wait *uint32) 27TEXT runtime·exitThread(SB),NOSPLIT,$0 28 MOVD wait+0(FP), R0 // arg 1 - notdead 29 MOVD $302, R8 // sys___threxit 30 SVC 31 MOVD $0, R0 // crash on syscall failure 32 MOVD R0, (R0) 33 JMP 0(PC) 34 35TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0 36 MOVD name+0(FP), R0 // arg 1 - path 37 MOVW mode+8(FP), R1 // arg 2 - mode 38 MOVW perm+12(FP), R2 // arg 3 - perm 39 MOVD $5, R8 // sys_open 40 SVC 41 BCC 2(PC) 42 MOVW $-1, R0 43 MOVW R0, ret+16(FP) 44 RET 45 46TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0 47 MOVW fd+0(FP), R0 // arg 1 - fd 48 MOVD $6, R8 // sys_close 49 SVC 50 BCC 2(PC) 51 MOVW $-1, R0 52 MOVW R0, ret+8(FP) 53 RET 54 55TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0 56 MOVW fd+0(FP), R0 // arg 1 - fd 57 MOVD p+8(FP), R1 // arg 2 - buf 58 MOVW n+16(FP), R2 // arg 3 - nbyte 59 MOVD $3, R8 // sys_read 60 SVC 61 BCC 2(PC) 62 NEG R0, R0 63 MOVW R0, ret+24(FP) 64 RET 65 66// func pipe() (r, w int32, errno int32) 67TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12 68 MOVD $r+0(FP), R0 69 MOVW $0, R1 70 MOVD $101, R8 // sys_pipe2 71 SVC 72 BCC 2(PC) 73 NEG R0, R0 74 MOVW R0, errno+8(FP) 75 RET 76 77// func pipe2(flags int32) (r, w int32, errno int32) 78TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20 79 MOVD $r+8(FP), R0 80 MOVW flags+0(FP), R1 81 MOVD $101, R8 // sys_pipe2 82 SVC 83 BCC 2(PC) 84 NEG R0, R0 85 MOVW R0, errno+16(FP) 86 RET 87 88TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0 89 MOVD fd+0(FP), R0 // arg 1 - fd 90 MOVD p+8(FP), R1 // arg 2 - buf 91 MOVW n+16(FP), R2 // arg 3 - nbyte 92 MOVD $4, R8 // sys_write 93 SVC 94 BCC 2(PC) 95 NEG R0, R0 96 MOVW R0, ret+24(FP) 97 RET 98 99TEXT runtime·usleep(SB),NOSPLIT,$24-4 100 MOVWU usec+0(FP), R3 101 MOVD R3, R5 102 MOVW $1000000, R4 103 UDIV R4, R3 104 MOVD R3, 8(RSP) // tv_sec 105 MUL R3, R4 106 SUB R4, R5 107 MOVW $1000, R4 108 MUL R4, R5 109 MOVD R5, 16(RSP) // tv_nsec 110 111 ADD $8, RSP, R0 // arg 1 - rqtp 112 MOVD $0, R1 // arg 2 - rmtp 113 MOVD $91, R8 // sys_nanosleep 114 SVC 115 RET 116 117TEXT runtime·getthrid(SB),NOSPLIT,$0-4 118 MOVD $299, R8 // sys_getthrid 119 SVC 120 MOVW R0, ret+0(FP) 121 RET 122 123TEXT runtime·thrkill(SB),NOSPLIT,$0-16 124 MOVW tid+0(FP), R0 // arg 1 - tid 125 MOVD sig+8(FP), R1 // arg 2 - signum 126 MOVW $0, R2 // arg 3 - tcb 127 MOVD $119, R8 // sys_thrkill 128 SVC 129 RET 130 131TEXT runtime·raiseproc(SB),NOSPLIT,$0 132 MOVD $20, R8 // sys_getpid 133 SVC 134 // arg 1 - pid, already in R0 135 MOVW sig+0(FP), R1 // arg 2 - signum 136 MOVD $122, R8 // sys_kill 137 SVC 138 RET 139 140TEXT runtime·mmap(SB),NOSPLIT,$0 141 MOVD addr+0(FP), R0 // arg 1 - addr 142 MOVD n+8(FP), R1 // arg 2 - len 143 MOVW prot+16(FP), R2 // arg 3 - prot 144 MOVW flags+20(FP), R3 // arg 4 - flags 145 MOVW fd+24(FP), R4 // arg 5 - fd 146 MOVW $0, R5 // arg 6 - pad 147 MOVW off+28(FP), R6 // arg 7 - offset 148 MOVD $197, R8 // sys_mmap 149 SVC 150 MOVD $0, R1 151 BCC 3(PC) 152 MOVD R0, R1 // if error, move to R1 153 MOVD $0, R0 154 MOVD R0, p+32(FP) 155 MOVD R1, err+40(FP) 156 RET 157 158TEXT runtime·munmap(SB),NOSPLIT,$0 159 MOVD addr+0(FP), R0 // arg 1 - addr 160 MOVD n+8(FP), R1 // arg 2 - len 161 MOVD $73, R8 // sys_munmap 162 SVC 163 BCC 3(PC) 164 MOVD $0, R0 // crash on syscall failure 165 MOVD R0, (R0) 166 RET 167 168TEXT runtime·madvise(SB),NOSPLIT,$0 169 MOVD addr+0(FP), R0 // arg 1 - addr 170 MOVD n+8(FP), R1 // arg 2 - len 171 MOVW flags+16(FP), R2 // arg 2 - flags 172 MOVD $75, R8 // sys_madvise 173 SVC 174 BCC 2(PC) 175 MOVW $-1, R0 176 MOVW R0, ret+24(FP) 177 RET 178 179TEXT runtime·setitimer(SB),NOSPLIT,$0 180 MOVW mode+0(FP), R0 // arg 1 - mode 181 MOVD new+8(FP), R1 // arg 2 - new value 182 MOVD old+16(FP), R2 // arg 3 - old value 183 MOVD $69, R8 // sys_setitimer 184 SVC 185 RET 186 187// func walltime1() (sec int64, nsec int32) 188TEXT runtime·walltime1(SB), NOSPLIT, $32 189 MOVW CLOCK_REALTIME, R0 // arg 1 - clock_id 190 MOVD $8(RSP), R1 // arg 2 - tp 191 MOVD $87, R8 // sys_clock_gettime 192 SVC 193 194 MOVD 8(RSP), R0 // sec 195 MOVD 16(RSP), R1 // nsec 196 MOVD R0, sec+0(FP) 197 MOVW R1, nsec+8(FP) 198 199 RET 200 201// int64 nanotime1(void) so really 202// void nanotime1(int64 *nsec) 203TEXT runtime·nanotime1(SB),NOSPLIT,$32 204 MOVW CLOCK_MONOTONIC, R0 // arg 1 - clock_id 205 MOVD $8(RSP), R1 // arg 2 - tp 206 MOVD $87, R8 // sys_clock_gettime 207 SVC 208 209 MOVW 8(RSP), R3 // sec 210 MOVW 16(RSP), R5 // nsec 211 212 MOVD $1000000000, R4 213 MUL R4, R3 214 ADD R5, R3 215 MOVD R3, ret+0(FP) 216 RET 217 218TEXT runtime·sigaction(SB),NOSPLIT,$0 219 MOVW sig+0(FP), R0 // arg 1 - signum 220 MOVD new+8(FP), R1 // arg 2 - new sigaction 221 MOVD old+16(FP), R2 // arg 3 - old sigaction 222 MOVD $46, R8 // sys_sigaction 223 SVC 224 BCC 3(PC) 225 MOVD $3, R0 // crash on syscall failure 226 MOVD R0, (R0) 227 RET 228 229TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0 230 MOVW how+0(FP), R0 // arg 1 - mode 231 MOVW new+4(FP), R1 // arg 2 - new 232 MOVD $48, R8 // sys_sigprocmask 233 SVC 234 BCC 3(PC) 235 MOVD $3, R8 // crash on syscall failure 236 MOVD R8, (R8) 237 MOVW R0, ret+8(FP) 238 RET 239 240TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 241 MOVW sig+8(FP), R0 242 MOVD info+16(FP), R1 243 MOVD ctx+24(FP), R2 244 MOVD fn+0(FP), R11 245 BL (R11) // Alignment for ELF ABI? 246 RET 247 248TEXT runtime·sigtramp(SB),NOSPLIT,$192 249 // Save callee-save registers in the case of signal forwarding. 250 // Please refer to https://golang.org/issue/31827 . 251 MOVD R19, 8*4(RSP) 252 MOVD R20, 8*5(RSP) 253 MOVD R21, 8*6(RSP) 254 MOVD R22, 8*7(RSP) 255 MOVD R23, 8*8(RSP) 256 MOVD R24, 8*9(RSP) 257 MOVD R25, 8*10(RSP) 258 MOVD R26, 8*11(RSP) 259 MOVD R27, 8*12(RSP) 260 MOVD g, 8*13(RSP) 261 MOVD R29, 8*14(RSP) 262 FMOVD F8, 8*15(RSP) 263 FMOVD F9, 8*16(RSP) 264 FMOVD F10, 8*17(RSP) 265 FMOVD F11, 8*18(RSP) 266 FMOVD F12, 8*19(RSP) 267 FMOVD F13, 8*20(RSP) 268 FMOVD F14, 8*21(RSP) 269 FMOVD F15, 8*22(RSP) 270 271 // If called from an external code context, g will not be set. 272 // Save R0, since runtime·load_g will clobber it. 273 MOVW R0, 8(RSP) // signum 274 MOVB runtime·iscgo(SB), R0 275 CMP $0, R0 276 BEQ 2(PC) 277 BL runtime·load_g(SB) 278 279 MOVD R1, 16(RSP) 280 MOVD R2, 24(RSP) 281 BL runtime·sigtrampgo(SB) 282 283 // Restore callee-save registers. 284 MOVD 8*4(RSP), R19 285 MOVD 8*5(RSP), R20 286 MOVD 8*6(RSP), R21 287 MOVD 8*7(RSP), R22 288 MOVD 8*8(RSP), R23 289 MOVD 8*9(RSP), R24 290 MOVD 8*10(RSP), R25 291 MOVD 8*11(RSP), R26 292 MOVD 8*12(RSP), R27 293 MOVD 8*13(RSP), g 294 MOVD 8*14(RSP), R29 295 FMOVD 8*15(RSP), F8 296 FMOVD 8*16(RSP), F9 297 FMOVD 8*17(RSP), F10 298 FMOVD 8*18(RSP), F11 299 FMOVD 8*19(RSP), F12 300 FMOVD 8*20(RSP), F13 301 FMOVD 8*21(RSP), F14 302 FMOVD 8*22(RSP), F15 303 304 RET 305 306// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void)); 307TEXT runtime·tfork(SB),NOSPLIT,$0 308 309 // Copy mp, gp and fn off parent stack for use by child. 310 MOVD mm+16(FP), R4 311 MOVD gg+24(FP), R5 312 MOVD fn+32(FP), R6 313 314 MOVD param+0(FP), R0 // arg 1 - param 315 MOVD psize+8(FP), R1 // arg 2 - psize 316 MOVD $8, R8 // sys___tfork 317 SVC 318 319 // Return if syscall failed. 320 BCC 4(PC) 321 NEG R0, R0 322 MOVW R0, ret+40(FP) 323 RET 324 325 // In parent, return. 326 CMP $0, R0 327 BEQ 3(PC) 328 MOVW R0, ret+40(FP) 329 RET 330 331 // Initialise m, g. 332 MOVD R5, g 333 MOVD R4, g_m(g) 334 335 // Call fn. 336 BL (R6) 337 338 // fn should never return. 339 MOVD $2, R8 // crash if reached 340 MOVD R8, (R8) 341 RET 342 343TEXT runtime·sigaltstack(SB),NOSPLIT,$0 344 MOVD new+0(FP), R0 // arg 1 - new sigaltstack 345 MOVD old+8(FP), R1 // arg 2 - old sigaltstack 346 MOVD $288, R8 // sys_sigaltstack 347 SVC 348 BCC 3(PC) 349 MOVD $0, R8 // crash on syscall failure 350 MOVD R8, (R8) 351 RET 352 353TEXT runtime·osyield(SB),NOSPLIT,$0 354 MOVD $298, R8 // sys_sched_yield 355 SVC 356 RET 357 358TEXT runtime·thrsleep(SB),NOSPLIT,$0 359 MOVD ident+0(FP), R0 // arg 1 - ident 360 MOVW clock_id+8(FP), R1 // arg 2 - clock_id 361 MOVD tsp+16(FP), R2 // arg 3 - tsp 362 MOVD lock+24(FP), R3 // arg 4 - lock 363 MOVD abort+32(FP), R4 // arg 5 - abort 364 MOVD $94, R8 // sys___thrsleep 365 SVC 366 MOVW R0, ret+40(FP) 367 RET 368 369TEXT runtime·thrwakeup(SB),NOSPLIT,$0 370 MOVD ident+0(FP), R0 // arg 1 - ident 371 MOVW n+8(FP), R1 // arg 2 - n 372 MOVD $301, R8 // sys___thrwakeup 373 SVC 374 MOVW R0, ret+16(FP) 375 RET 376 377TEXT runtime·sysctl(SB),NOSPLIT,$0 378 MOVD mib+0(FP), R0 // arg 1 - mib 379 MOVW miblen+8(FP), R1 // arg 2 - miblen 380 MOVD out+16(FP), R2 // arg 3 - out 381 MOVD size+24(FP), R3 // arg 4 - size 382 MOVD dst+32(FP), R4 // arg 5 - dest 383 MOVD ndst+40(FP), R5 // arg 6 - newlen 384 MOVD $202, R8 // sys___sysctl 385 SVC 386 BCC 2(PC) 387 NEG R0, R0 388 MOVW R0, ret+48(FP) 389 RET 390 391// int32 runtime·kqueue(void); 392TEXT runtime·kqueue(SB),NOSPLIT,$0 393 MOVD $269, R8 // sys_kqueue 394 SVC 395 BCC 2(PC) 396 NEG R0, R0 397 MOVW R0, ret+0(FP) 398 RET 399 400// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout); 401TEXT runtime·kevent(SB),NOSPLIT,$0 402 MOVW kq+0(FP), R0 // arg 1 - kq 403 MOVD ch+8(FP), R1 // arg 2 - changelist 404 MOVW nch+16(FP), R2 // arg 3 - nchanges 405 MOVD ev+24(FP), R3 // arg 4 - eventlist 406 MOVW nev+32(FP), R4 // arg 5 - nevents 407 MOVD ts+40(FP), R5 // arg 6 - timeout 408 MOVD $72, R8 // sys_kevent 409 SVC 410 BCC 2(PC) 411 NEG R0, R0 412 MOVW R0, ret+48(FP) 413 RET 414 415// func closeonexec(fd int32) 416TEXT runtime·closeonexec(SB),NOSPLIT,$0 417 MOVW fd+0(FP), R0 // arg 1 - fd 418 MOVD $2, R1 // arg 2 - cmd (F_SETFD) 419 MOVD $1, R2 // arg 3 - arg (FD_CLOEXEC) 420 MOVD $92, R8 // sys_fcntl 421 SVC 422 RET 423 424// func runtime·setNonblock(int32 fd) 425TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4 426 MOVW fd+0(FP), R0 // arg 1 - fd 427 MOVD $3, R1 // arg 2 - cmd (F_GETFL) 428 MOVD $0, R2 // arg 3 429 MOVD $92, R8 // sys_fcntl 430 SVC 431 MOVD $4, R2 // O_NONBLOCK 432 ORR R0, R2 // arg 3 - flags 433 MOVW fd+0(FP), R0 // arg 1 - fd 434 MOVD $4, R1 // arg 2 - cmd (F_SETFL) 435 MOVD $92, R8 // sys_fcntl 436 SVC 437 RET 438