github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/runtime/sys_freebsd_arm.s (about) 1 // Copyright 2012 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 ARM, FreeBSD 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 // for EABI, as we don't support OABI 14 #define SYS_BASE 0x0 15 16 #define SYS_exit (SYS_BASE + 1) 17 #define SYS_read (SYS_BASE + 3) 18 #define SYS_write (SYS_BASE + 4) 19 #define SYS_open (SYS_BASE + 5) 20 #define SYS_close (SYS_BASE + 6) 21 #define SYS_getpid (SYS_BASE + 20) 22 #define SYS_kill (SYS_BASE + 37) 23 #define SYS_pipe (SYS_BASE + 42) 24 #define SYS_sigaltstack (SYS_BASE + 53) 25 #define SYS_munmap (SYS_BASE + 73) 26 #define SYS_madvise (SYS_BASE + 75) 27 #define SYS_setitimer (SYS_BASE + 83) 28 #define SYS_fcntl (SYS_BASE + 92) 29 #define SYS___sysctl (SYS_BASE + 202) 30 #define SYS_nanosleep (SYS_BASE + 240) 31 #define SYS_clock_gettime (SYS_BASE + 232) 32 #define SYS_sched_yield (SYS_BASE + 331) 33 #define SYS_sigprocmask (SYS_BASE + 340) 34 #define SYS_kqueue (SYS_BASE + 362) 35 #define SYS_kevent (SYS_BASE + 363) 36 #define SYS_sigaction (SYS_BASE + 416) 37 #define SYS_thr_exit (SYS_BASE + 431) 38 #define SYS_thr_self (SYS_BASE + 432) 39 #define SYS_thr_kill (SYS_BASE + 433) 40 #define SYS__umtx_op (SYS_BASE + 454) 41 #define SYS_thr_new (SYS_BASE + 455) 42 #define SYS_mmap (SYS_BASE + 477) 43 #define SYS_cpuset_getaffinity (SYS_BASE + 487) 44 #define SYS_pipe2 (SYS_BASE + 542) 45 46 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0 47 MOVW addr+0(FP), R0 48 MOVW mode+4(FP), R1 49 MOVW val+8(FP), R2 50 MOVW uaddr1+12(FP), R3 51 ADD $20, R13 // arg 5 is passed on stack 52 MOVW $SYS__umtx_op, R7 53 SWI $0 54 SUB $20, R13 55 // BCS error 56 MOVW R0, ret+20(FP) 57 RET 58 59 TEXT runtime·thr_new(SB),NOSPLIT,$0 60 MOVW param+0(FP), R0 61 MOVW size+4(FP), R1 62 MOVW $SYS_thr_new, R7 63 SWI $0 64 MOVW R0, ret+8(FP) 65 RET 66 67 TEXT runtime·thr_start(SB),NOSPLIT,$0 68 // set up g 69 MOVW m_g0(R0), g 70 MOVW R0, g_m(g) 71 BL runtime·emptyfunc(SB) // fault if stack check is wrong 72 BL runtime·mstart(SB) 73 74 MOVW $2, R8 // crash (not reached) 75 MOVW R8, (R8) 76 RET 77 78 // Exit the entire program (like C exit) 79 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0 80 MOVW code+0(FP), R0 // arg 1 exit status 81 MOVW $SYS_exit, R7 82 SWI $0 83 MOVW.CS $0, R8 // crash on syscall failure 84 MOVW.CS R8, (R8) 85 RET 86 87 // func exitThread(wait *uint32) 88 TEXT runtime·exitThread(SB),NOSPLIT,$0-4 89 MOVW wait+0(FP), R0 90 // We're done using the stack. 91 MOVW $0, R2 92 storeloop: 93 LDREX (R0), R4 // loads R4 94 STREX R2, (R0), R1 // stores R2 95 CMP $0, R1 96 BNE storeloop 97 MOVW $0, R0 // arg 1 long *state 98 MOVW $SYS_thr_exit, R7 99 SWI $0 100 MOVW.CS $0, R8 // crash on syscall failure 101 MOVW.CS R8, (R8) 102 JMP 0(PC) 103 104 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0 105 MOVW name+0(FP), R0 // arg 1 name 106 MOVW mode+4(FP), R1 // arg 2 mode 107 MOVW perm+8(FP), R2 // arg 3 perm 108 MOVW $SYS_open, R7 109 SWI $0 110 MOVW.CS $-1, R0 111 MOVW R0, ret+12(FP) 112 RET 113 114 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0 115 MOVW fd+0(FP), R0 // arg 1 fd 116 MOVW p+4(FP), R1 // arg 2 buf 117 MOVW n+8(FP), R2 // arg 3 count 118 MOVW $SYS_read, R7 119 SWI $0 120 RSB.CS $0, R0 // caller expects negative errno 121 MOVW R0, ret+12(FP) 122 RET 123 124 // func pipe() (r, w int32, errno int32) 125 TEXT runtime·pipe(SB),NOSPLIT,$0-12 126 MOVW $SYS_pipe, R7 127 SWI $0 128 BCC ok 129 MOVW $0, R1 130 MOVW R1, r+0(FP) 131 MOVW R1, w+4(FP) 132 MOVW R0, errno+8(FP) 133 RET 134 ok: 135 MOVW R0, r+0(FP) 136 MOVW R1, w+4(FP) 137 MOVW $0, R1 138 MOVW R1, errno+8(FP) 139 RET 140 141 // func pipe2(flags int32) (r, w int32, errno int32) 142 TEXT runtime·pipe2(SB),NOSPLIT,$0-16 143 MOVW $r+4(FP), R0 144 MOVW flags+0(FP), R1 145 MOVW $SYS_pipe2, R7 146 SWI $0 147 MOVW R0, errno+12(FP) 148 RET 149 150 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0 151 MOVW fd+0(FP), R0 // arg 1 fd 152 MOVW p+4(FP), R1 // arg 2 buf 153 MOVW n+8(FP), R2 // arg 3 count 154 MOVW $SYS_write, R7 155 SWI $0 156 RSB.CS $0, R0 // caller expects negative errno 157 MOVW R0, ret+12(FP) 158 RET 159 160 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0 161 MOVW fd+0(FP), R0 // arg 1 fd 162 MOVW $SYS_close, R7 163 SWI $0 164 MOVW.CS $-1, R0 165 MOVW R0, ret+4(FP) 166 RET 167 168 TEXT runtime·thr_self(SB),NOSPLIT,$0-4 169 // thr_self(&0(FP)) 170 MOVW $ret+0(FP), R0 // arg 1 171 MOVW $SYS_thr_self, R7 172 SWI $0 173 RET 174 175 TEXT runtime·thr_kill(SB),NOSPLIT,$0-8 176 // thr_kill(tid, sig) 177 MOVW tid+0(FP), R0 // arg 1 id 178 MOVW sig+4(FP), R1 // arg 2 signal 179 MOVW $SYS_thr_kill, R7 180 SWI $0 181 RET 182 183 TEXT runtime·raiseproc(SB),NOSPLIT,$0 184 // getpid 185 MOVW $SYS_getpid, R7 186 SWI $0 187 // kill(self, sig) 188 // arg 1 - pid, now in R0 189 MOVW sig+0(FP), R1 // arg 2 - signal 190 MOVW $SYS_kill, R7 191 SWI $0 192 RET 193 194 TEXT runtime·setitimer(SB), NOSPLIT|NOFRAME, $0 195 MOVW mode+0(FP), R0 196 MOVW new+4(FP), R1 197 MOVW old+8(FP), R2 198 MOVW $SYS_setitimer, R7 199 SWI $0 200 RET 201 202 // func fallback_walltime() (sec int64, nsec int32) 203 TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12 204 MOVW $0, R0 // CLOCK_REALTIME 205 MOVW $8(R13), R1 206 MOVW $SYS_clock_gettime, R7 207 SWI $0 208 209 MOVW 8(R13), R0 // sec.low 210 MOVW 12(R13), R1 // sec.high 211 MOVW 16(R13), R2 // nsec 212 213 MOVW R0, sec_lo+0(FP) 214 MOVW R1, sec_hi+4(FP) 215 MOVW R2, nsec+8(FP) 216 RET 217 218 // func fallback_nanotime() int64 219 TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32 220 MOVW $4, R0 // CLOCK_MONOTONIC 221 MOVW $8(R13), R1 222 MOVW $SYS_clock_gettime, R7 223 SWI $0 224 225 MOVW 8(R13), R0 // sec.low 226 MOVW 12(R13), R4 // sec.high 227 MOVW 16(R13), R2 // nsec 228 229 MOVW $1000000000, R3 230 MULLU R0, R3, (R1, R0) 231 MUL R3, R4 232 ADD.S R2, R0 233 ADC R4, R1 234 235 MOVW R0, ret_lo+0(FP) 236 MOVW R1, ret_hi+4(FP) 237 RET 238 239 TEXT runtime·asmSigaction(SB),NOSPLIT|NOFRAME,$0 240 MOVW sig+0(FP), R0 // arg 1 sig 241 MOVW new+4(FP), R1 // arg 2 act 242 MOVW old+8(FP), R2 // arg 3 oact 243 MOVW $SYS_sigaction, R7 244 SWI $0 245 MOVW.CS $-1, R0 246 MOVW R0, ret+12(FP) 247 RET 248 249 TEXT runtime·sigtramp(SB),NOSPLIT,$0 250 // Reserve space for callee-save registers and arguments. 251 MOVM.DB.W [R4-R11], (R13) 252 SUB $16, R13 253 254 // this might be called in external code context, 255 // where g is not set. 256 // first save R0, because runtime·load_g will clobber it 257 MOVW R0, 4(R13) // signum 258 MOVB runtime·iscgo(SB), R0 259 CMP $0, R0 260 BL.NE runtime·load_g(SB) 261 262 MOVW R1, 8(R13) 263 MOVW R2, 12(R13) 264 BL runtime·sigtrampgo(SB) 265 266 // Restore callee-save registers. 267 ADD $16, R13 268 MOVM.IA.W (R13), [R4-R11] 269 270 RET 271 272 TEXT runtime·mmap(SB),NOSPLIT,$16 273 MOVW addr+0(FP), R0 // arg 1 addr 274 MOVW n+4(FP), R1 // arg 2 len 275 MOVW prot+8(FP), R2 // arg 3 prot 276 MOVW flags+12(FP), R3 // arg 4 flags 277 // arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack 278 // note the C runtime only passes the 32-bit offset_lo to us 279 MOVW fd+16(FP), R4 // arg 5 280 MOVW R4, 4(R13) 281 MOVW off+20(FP), R5 // arg 6 lower 32-bit 282 // the word at 8(R13) is skipped due to 64-bit argument alignment. 283 MOVW R5, 12(R13) 284 MOVW $0, R6 // higher 32-bit for arg 6 285 MOVW R6, 16(R13) 286 ADD $4, R13 287 MOVW $SYS_mmap, R7 288 SWI $0 289 SUB $4, R13 290 MOVW $0, R1 291 MOVW.CS R0, R1 // if failed, put in R1 292 MOVW.CS $0, R0 293 MOVW R0, p+24(FP) 294 MOVW R1, err+28(FP) 295 RET 296 297 TEXT runtime·munmap(SB),NOSPLIT,$0 298 MOVW addr+0(FP), R0 // arg 1 addr 299 MOVW n+4(FP), R1 // arg 2 len 300 MOVW $SYS_munmap, R7 301 SWI $0 302 MOVW.CS $0, R8 // crash on syscall failure 303 MOVW.CS R8, (R8) 304 RET 305 306 TEXT runtime·madvise(SB),NOSPLIT,$0 307 MOVW addr+0(FP), R0 // arg 1 addr 308 MOVW n+4(FP), R1 // arg 2 len 309 MOVW flags+8(FP), R2 // arg 3 flags 310 MOVW $SYS_madvise, R7 311 SWI $0 312 MOVW.CS $-1, R0 313 MOVW R0, ret+12(FP) 314 RET 315 316 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0 317 MOVW new+0(FP), R0 318 MOVW old+4(FP), R1 319 MOVW $SYS_sigaltstack, R7 320 SWI $0 321 MOVW.CS $0, R8 // crash on syscall failure 322 MOVW.CS R8, (R8) 323 RET 324 325 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 326 MOVW sig+4(FP), R0 327 MOVW info+8(FP), R1 328 MOVW ctx+12(FP), R2 329 MOVW fn+0(FP), R11 330 MOVW R13, R4 331 SUB $24, R13 332 BIC $0x7, R13 // alignment for ELF ABI 333 BL (R11) 334 MOVW R4, R13 335 RET 336 337 TEXT runtime·usleep(SB),NOSPLIT,$16 338 MOVW usec+0(FP), R0 339 CALL runtime·usplitR0(SB) 340 // 0(R13) is the saved LR, don't use it 341 MOVW R0, 4(R13) // tv_sec.low 342 MOVW $0, R0 343 MOVW R0, 8(R13) // tv_sec.high 344 MOVW $1000, R2 345 MUL R1, R2 346 MOVW R2, 12(R13) // tv_nsec 347 348 MOVW $4(R13), R0 // arg 1 - rqtp 349 MOVW $0, R1 // arg 2 - rmtp 350 MOVW $SYS_nanosleep, R7 351 SWI $0 352 RET 353 354 TEXT runtime·sysctl(SB),NOSPLIT,$0 355 MOVW mib+0(FP), R0 // arg 1 - name 356 MOVW miblen+4(FP), R1 // arg 2 - namelen 357 MOVW out+8(FP), R2 // arg 3 - old 358 MOVW size+12(FP), R3 // arg 4 - oldlenp 359 // arg 5 (newp) and arg 6 (newlen) are passed on stack 360 ADD $20, R13 361 MOVW $SYS___sysctl, R7 362 SWI $0 363 SUB.CS $0, R0, R0 364 SUB $20, R13 365 MOVW R0, ret+24(FP) 366 RET 367 368 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0 369 MOVW $SYS_sched_yield, R7 370 SWI $0 371 RET 372 373 TEXT runtime·sigprocmask(SB),NOSPLIT,$0 374 MOVW how+0(FP), R0 // arg 1 - how 375 MOVW new+4(FP), R1 // arg 2 - set 376 MOVW old+8(FP), R2 // arg 3 - oset 377 MOVW $SYS_sigprocmask, R7 378 SWI $0 379 MOVW.CS $0, R8 // crash on syscall failure 380 MOVW.CS R8, (R8) 381 RET 382 383 // int32 runtime·kqueue(void) 384 TEXT runtime·kqueue(SB),NOSPLIT,$0 385 MOVW $SYS_kqueue, R7 386 SWI $0 387 RSB.CS $0, R0 388 MOVW R0, ret+0(FP) 389 RET 390 391 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout) 392 TEXT runtime·kevent(SB),NOSPLIT,$0 393 MOVW kq+0(FP), R0 // kq 394 MOVW ch+4(FP), R1 // changelist 395 MOVW nch+8(FP), R2 // nchanges 396 MOVW ev+12(FP), R3 // eventlist 397 ADD $20, R13 // pass arg 5 and 6 on stack 398 MOVW $SYS_kevent, R7 399 SWI $0 400 RSB.CS $0, R0 401 SUB $20, R13 402 MOVW R0, ret+24(FP) 403 RET 404 405 // void runtime·closeonexec(int32 fd) 406 TEXT runtime·closeonexec(SB),NOSPLIT,$0 407 MOVW fd+0(FP), R0 // fd 408 MOVW $2, R1 // F_SETFD 409 MOVW $1, R2 // FD_CLOEXEC 410 MOVW $SYS_fcntl, R7 411 SWI $0 412 RET 413 414 // func runtime·setNonblock(fd int32) 415 TEXT runtime·setNonblock(SB),NOSPLIT,$0-4 416 MOVW fd+0(FP), R0 // fd 417 MOVW $3, R1 // F_GETFL 418 MOVW $0, R2 419 MOVW $SYS_fcntl, R7 420 SWI $0 421 ORR $0x4, R0, R2 // O_NONBLOCK 422 MOVW fd+0(FP), R0 // fd 423 MOVW $4, R1 // F_SETFL 424 MOVW $SYS_fcntl, R7 425 SWI $0 426 RET 427 428 // TODO: this is only valid for ARMv7+ 429 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0 430 B runtime·armPublicationBarrier(SB) 431 432 // TODO(minux): this only supports ARMv6K+. 433 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0 434 WORD $0xee1d0f70 // mrc p15, 0, r0, c13, c0, 3 435 RET 436 437 // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32 438 TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-28 439 MOVW level+0(FP), R0 440 MOVW which+4(FP), R1 441 MOVW id_lo+8(FP), R2 442 MOVW id_hi+12(FP), R3 443 ADD $20, R13 // Pass size and mask on stack. 444 MOVW $SYS_cpuset_getaffinity, R7 445 SWI $0 446 RSB.CS $0, R0 447 SUB $20, R13 448 MOVW R0, ret+24(FP) 449 RET 450 451 // func getCntxct(physical bool) uint32 452 TEXT runtime·getCntxct(SB),NOSPLIT|NOFRAME,$0-8 453 MOVB runtime·goarm(SB), R11 454 CMP $7, R11 455 BLT 2(PC) 456 DMB 457 458 MOVB physical+0(FP), R0 459 CMP $1, R0 460 B.NE 3(PC) 461 462 // get CNTPCT (Physical Count Register) into R0(low) R1(high) 463 // mrrc 15, 0, r0, r1, cr14 464 WORD $0xec510f0e 465 B 2(PC) 466 467 // get CNTVCT (Virtual Count Register) into R0(low) R1(high) 468 // mrrc 15, 1, r0, r1, cr14 469 WORD $0xec510f1e 470 471 MOVW R0, ret+4(FP) 472 RET