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