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