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_sigaltstack (SYS_BASE + 53) 24 #define SYS_munmap (SYS_BASE + 73) 25 #define SYS_madvise (SYS_BASE + 75) 26 #define SYS_setitimer (SYS_BASE + 83) 27 #define SYS_fcntl (SYS_BASE + 92) 28 #define SYS_getrlimit (SYS_BASE + 194) 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 44 TEXT runtimesys_umtx_op(SB),NOSPLIT,$0 45 MOVW addr+0(FP), R0 46 MOVW mode+4(FP), R1 47 MOVW val+8(FP), R2 48 MOVW uaddr1+12(FP), R3 49 ADD $20, R13 // arg 5 is passed on stack 50 MOVW $SYS__umtx_op, R7 51 SWI $0 52 SUB $20, R13 53 // BCS error 54 MOVW R0, ret+20(FP) 55 RET 56 57 TEXT runtimethr_new(SB),NOSPLIT,$0 58 MOVW param+0(FP), R0 59 MOVW size+4(FP), R1 60 MOVW $SYS_thr_new, R7 61 SWI $0 62 RET 63 64 TEXT runtimethr_start(SB),NOSPLIT,$0 65 // set up g 66 MOVW m_g0(R0), g 67 MOVW R0, g_m(g) 68 BL runtimeemptyfunc(SB) // fault if stack check is wrong 69 BL runtimemstart(SB) 70 71 MOVW $2, R8 // crash (not reached) 72 MOVW R8, (R8) 73 RET 74 75 // Exit the entire program (like C exit) 76 TEXT runtimeexit(SB),NOSPLIT,$-8 77 MOVW code+0(FP), R0 // arg 1 exit status 78 MOVW $SYS_exit, R7 79 SWI $0 80 MOVW.CS $0, R8 // crash on syscall failure 81 MOVW.CS R8, (R8) 82 RET 83 84 TEXT runtimeexit1(SB),NOSPLIT,$-8 85 MOVW code+0(FP), R0 // arg 1 exit status 86 MOVW $SYS_thr_exit, R7 87 SWI $0 88 MOVW.CS $0, R8 // crash on syscall failure 89 MOVW.CS R8, (R8) 90 RET 91 92 TEXT runtimeopen(SB),NOSPLIT,$-8 93 MOVW name+0(FP), R0 // arg 1 name 94 MOVW mode+4(FP), R1 // arg 2 mode 95 MOVW perm+8(FP), R2 // arg 3 perm 96 MOVW $SYS_open, R7 97 SWI $0 98 MOVW.CS $-1, R0 99 MOVW R0, ret+12(FP) 100 RET 101 102 TEXT runtimeread(SB),NOSPLIT,$-8 103 MOVW fd+0(FP), R0 // arg 1 fd 104 MOVW p+4(FP), R1 // arg 2 buf 105 MOVW n+8(FP), R2 // arg 3 count 106 MOVW $SYS_read, R7 107 SWI $0 108 MOVW.CS $-1, R0 109 MOVW R0, ret+12(FP) 110 RET 111 112 TEXT runtimewrite(SB),NOSPLIT,$-8 113 MOVW fd+0(FP), R0 // arg 1 fd 114 MOVW p+4(FP), R1 // arg 2 buf 115 MOVW n+8(FP), R2 // arg 3 count 116 MOVW $SYS_write, R7 117 SWI $0 118 MOVW.CS $-1, R0 119 MOVW R0, ret+12(FP) 120 RET 121 122 TEXT runtimeclosefd(SB),NOSPLIT,$-8 123 MOVW fd+0(FP), R0 // arg 1 fd 124 MOVW $SYS_close, R7 125 SWI $0 126 MOVW.CS $-1, R0 127 MOVW R0, ret+4(FP) 128 RET 129 130 TEXT runtimegetrlimit(SB),NOSPLIT,$-8 131 MOVW kind+0(FP), R0 132 MOVW limit+4(FP), R1 133 MOVW $SYS_getrlimit, R7 134 SWI $0 135 MOVW R0, ret+8(FP) 136 RET 137 138 TEXT runtimeraise(SB),NOSPLIT,$8 139 // thr_self(&4(R13)) 140 MOVW $4(R13), R0 // arg 1 &4(R13) 141 MOVW $SYS_thr_self, R7 142 SWI $0 143 // thr_kill(self, SIGPIPE) 144 MOVW 4(R13), R0 // arg 1 id 145 MOVW sig+0(FP), R1 // arg 2 - signal 146 MOVW $SYS_thr_kill, R7 147 SWI $0 148 RET 149 150 TEXT runtimeraiseproc(SB),NOSPLIT,$0 151 // getpid 152 MOVW $SYS_getpid, R7 153 SWI $0 154 // kill(self, sig) 155 // arg 1 - pid, now in R0 156 MOVW sig+0(FP), R1 // arg 2 - signal 157 MOVW $SYS_kill, R7 158 SWI $0 159 RET 160 161 TEXT runtimesetitimer(SB), NOSPLIT, $-8 162 MOVW mode+0(FP), R0 163 MOVW new+4(FP), R1 164 MOVW old+8(FP), R2 165 MOVW $SYS_setitimer, R7 166 SWI $0 167 RET 168 169 // func now() (sec int64, nsec int32) 170 TEXT timenow(SB), NOSPLIT, $32 171 MOVW $0, R0 // CLOCK_REALTIME 172 MOVW $8(R13), R1 173 MOVW $SYS_clock_gettime, R7 174 SWI $0 175 176 MOVW 8(R13), R0 // sec.low 177 MOVW 12(R13), R1 // sec.high 178 MOVW 16(R13), R2 // nsec 179 180 MOVW R0, sec_lo+0(FP) 181 MOVW R1, sec_hi+4(FP) 182 MOVW R2, nsec+8(FP) 183 RET 184 185 // int64 nanotime(void) so really 186 // void nanotime(int64 *nsec) 187 TEXT runtimenanotime(SB), NOSPLIT, $32 188 // We can use CLOCK_MONOTONIC_FAST here when we drop 189 // support for FreeBSD 8-STABLE. 190 MOVW $4, R0 // CLOCK_MONOTONIC 191 MOVW $8(R13), R1 192 MOVW $SYS_clock_gettime, R7 193 SWI $0 194 195 MOVW 8(R13), R0 // sec.low 196 MOVW 12(R13), R4 // sec.high 197 MOVW 16(R13), R2 // nsec 198 199 MOVW $1000000000, R3 200 MULLU R0, R3, (R1, R0) 201 MUL R3, R4 202 ADD.S R2, R0 203 ADC R4, R1 204 205 MOVW R0, ret_lo+0(FP) 206 MOVW R1, ret_hi+4(FP) 207 RET 208 209 TEXT runtimesigaction(SB),NOSPLIT,$-8 210 MOVW sig+0(FP), R0 // arg 1 sig 211 MOVW new+4(FP), R1 // arg 2 act 212 MOVW old+8(FP), R2 // arg 3 oact 213 MOVW $SYS_sigaction, R7 214 SWI $0 215 MOVW.CS $0, R8 // crash on syscall failure 216 MOVW.CS R8, (R8) 217 RET 218 219 TEXT runtimesigtramp(SB),NOSPLIT,$12 220 // this might be called in external code context, 221 // where g is not set. 222 // first save R0, because runtimeload_g will clobber it 223 MOVW R0, 4(R13) // signum 224 MOVB runtimeiscgo(SB), R0 225 CMP $0, R0 226 BL.NE runtimeload_g(SB) 227 228 MOVW R1, 8(R13) 229 MOVW R2, 12(R13) 230 BL runtimesigtrampgo(SB) 231 RET 232 233 TEXT runtimemmap(SB),NOSPLIT,$16 234 MOVW addr+0(FP), R0 // arg 1 addr 235 MOVW n+4(FP), R1 // arg 2 len 236 MOVW prot+8(FP), R2 // arg 3 prot 237 MOVW flags+12(FP), R3 // arg 4 flags 238 // arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack 239 // note the C runtime only passes the 32-bit offset_lo to us 240 MOVW fd+16(FP), R4 // arg 5 241 MOVW R4, 4(R13) 242 MOVW off+20(FP), R5 // arg 6 lower 32-bit 243 // the word at 8(R13) is skipped due to 64-bit argument alignment. 244 MOVW R5, 12(R13) 245 MOVW $0, R6 // higher 32-bit for arg 6 246 MOVW R6, 16(R13) 247 ADD $4, R13 248 MOVW $SYS_mmap, R7 249 SWI $0 250 SUB $4, R13 251 // TODO(dfc) error checking ? 252 MOVW R0, ret+24(FP) 253 RET 254 255 TEXT runtimemunmap(SB),NOSPLIT,$0 256 MOVW addr+0(FP), R0 // arg 1 addr 257 MOVW n+4(FP), R1 // arg 2 len 258 MOVW $SYS_munmap, R7 259 SWI $0 260 MOVW.CS $0, R8 // crash on syscall failure 261 MOVW.CS R8, (R8) 262 RET 263 264 TEXT runtimemadvise(SB),NOSPLIT,$0 265 MOVW addr+0(FP), R0 // arg 1 addr 266 MOVW n+4(FP), R1 // arg 2 len 267 MOVW flags+8(FP), R2 // arg 3 flags 268 MOVW $SYS_madvise, R7 269 SWI $0 270 // ignore failure - maybe pages are locked 271 RET 272 273 TEXT runtimesigaltstack(SB),NOSPLIT,$-8 274 MOVW new+0(FP), R0 275 MOVW old+4(FP), R1 276 MOVW $SYS_sigaltstack, R7 277 SWI $0 278 MOVW.CS $0, R8 // crash on syscall failure 279 MOVW.CS R8, (R8) 280 RET 281 282 TEXT runtimesigfwd(SB),NOSPLIT,$0-16 283 MOVW sig+4(FP), R0 284 MOVW info+8(FP), R1 285 MOVW ctx+12(FP), R2 286 MOVW fn+0(FP), R11 287 MOVW R13, R4 288 SUB $24, R13 289 BIC $0x7, R13 // alignment for ELF ABI 290 BL (R11) 291 MOVW R4, R13 292 RET 293 294 TEXT runtimeusleep(SB),NOSPLIT,$16 295 MOVW usec+0(FP), R0 296 CALL runtimeusplitR0(SB) 297 // 0(R13) is the saved LR, don't use it 298 MOVW R0, 4(R13) // tv_sec.low 299 MOVW $0, R0 300 MOVW R0, 8(R13) // tv_sec.high 301 MOVW $1000, R2 302 MUL R1, R2 303 MOVW R2, 12(R13) // tv_nsec 304 305 MOVW $4(R13), R0 // arg 1 - rqtp 306 MOVW $0, R1 // arg 2 - rmtp 307 MOVW $SYS_nanosleep, R7 308 SWI $0 309 RET 310 311 TEXT runtimesysctl(SB),NOSPLIT,$0 312 MOVW mib+0(FP), R0 // arg 1 - name 313 MOVW miblen+4(FP), R1 // arg 2 - namelen 314 MOVW out+8(FP), R2 // arg 3 - old 315 MOVW size+12(FP), R3 // arg 4 - oldlenp 316 // arg 5 (newp) and arg 6 (newlen) are passed on stack 317 ADD $20, R13 318 MOVW $SYS___sysctl, R7 319 SWI $0 320 SUB.CS $0, R0, R0 321 SUB $20, R13 322 MOVW R0, ret+24(FP) 323 RET 324 325 TEXT runtimeosyield(SB),NOSPLIT,$-4 326 MOVW $SYS_sched_yield, R7 327 SWI $0 328 RET 329 330 TEXT runtimesigprocmask(SB),NOSPLIT,$0 331 MOVW how+0(FP), R0 // arg 1 - how 332 MOVW new+4(FP), R1 // arg 2 - set 333 MOVW old+8(FP), R2 // arg 3 - oset 334 MOVW $SYS_sigprocmask, R7 335 SWI $0 336 MOVW.CS $0, R8 // crash on syscall failure 337 MOVW.CS R8, (R8) 338 RET 339 340 // int32 runtimekqueue(void) 341 TEXT runtimekqueue(SB),NOSPLIT,$0 342 MOVW $SYS_kqueue, R7 343 SWI $0 344 RSB.CS $0, R0 345 MOVW R0, ret+0(FP) 346 RET 347 348 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout) 349 TEXT runtimekevent(SB),NOSPLIT,$0 350 MOVW kq+0(FP), R0 // kq 351 MOVW ch+4(FP), R1 // changelist 352 MOVW nch+8(FP), R2 // nchanges 353 MOVW ev+12(FP), R3 // eventlist 354 ADD $20, R13 // pass arg 5 and 6 on stack 355 MOVW $SYS_kevent, R7 356 SWI $0 357 RSB.CS $0, R0 358 SUB $20, R13 359 MOVW R0, ret+24(FP) 360 RET 361 362 // void runtimecloseonexec(int32 fd) 363 TEXT runtimecloseonexec(SB),NOSPLIT,$0 364 MOVW fd+0(FP), R0 // fd 365 MOVW $2, R1 // F_SETFD 366 MOVW $1, R2 // FD_CLOEXEC 367 MOVW $SYS_fcntl, R7 368 SWI $0 369 RET 370 371 // TODO: this is only valid for ARMv7+ 372 TEXT publicationBarrier(SB),NOSPLIT,$-4-0 373 B runtimearmPublicationBarrier(SB) 374 375 // TODO(minux): this only supports ARMv6K+. 376 TEXT runtimeread_tls_fallback(SB),NOSPLIT,$-4 377 WORD $0xee1d0f70 // mrc p15, 0, r0, c13, c0, 3 378 RET 379