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) 17 TEXT runtimeexit(SB),NOSPLIT,$-4 18 MOVW status+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 TEXT runtimeexit1(SB),NOSPLIT,$-4 26 MOVW $0, R0 // arg 1 - notdead 27 MOVW $302, R12 // sys___threxit 28 SWI $0 29 MOVW.CS $1, R8 // crash on syscall failure 30 MOVW.CS R8, (R8) 31 RET 32 33 TEXT runtimeopen(SB),NOSPLIT,$-4 34 MOVW path+0(FP), R0 // arg 1 - path 35 MOVW flags+4(FP), R1 // arg 2 - flags 36 MOVW mode+8(FP), R2 // arg 3 - mode 37 MOVW $5, R12 // sys_open 38 SWI $0 39 MOVW.CS $-1, R0 40 MOVW R0, ret+12(FP) 41 RET 42 43 TEXT runtimeclosefd(SB),NOSPLIT,$-4 44 MOVW path+0(FP), R0 // arg 1 - path 45 MOVW $6, R12 // sys_close 46 SWI $0 47 MOVW.CS $-1, R0 48 MOVW R0, ret+4(FP) 49 RET 50 51 TEXT runtimeread(SB),NOSPLIT,$-4 52 MOVW fd+0(FP), R0 // arg 1 - fd 53 MOVW buf+4(FP), R1 // arg 2 - buf 54 MOVW nbyte+8(FP), R2 // arg 3 - nbyte 55 MOVW $3, R12 // sys_read 56 SWI $0 57 MOVW.CS $-1, R0 58 MOVW R0, ret+12(FP) 59 RET 60 61 TEXT runtimewrite(SB),NOSPLIT,$-4 62 MOVW fd+0(FP), R0 // arg 1 - fd 63 MOVW buf+4(FP), R1 // arg 2 - buf 64 MOVW nbyte+8(FP), R2 // arg 3 - nbyte 65 MOVW $4, R12 // sys_write 66 SWI $0 67 MOVW.CS $-1, R0 68 MOVW R0, ret+12(FP) 69 RET 70 71 TEXT runtimeusleep(SB),NOSPLIT,$16 72 MOVW usec+0(FP), R0 73 CALL runtimeusplitR0(SB) 74 MOVW R0, 4(R13) // tv_sec - l32 75 MOVW $0, R0 76 MOVW R0, 8(R13) // tv_sec - h32 77 MOVW $1000, R2 78 MUL R1, R2 79 MOVW R2, 12(R13) // tv_nsec 80 81 MOVW $4(R13), R0 // arg 1 - rqtp 82 MOVW $0, R1 // arg 2 - rmtp 83 MOVW $91, R12 // sys_nanosleep 84 SWI $0 85 RET 86 87 TEXT runtimeraise(SB),NOSPLIT,$12 88 MOVW $0x12B, R12 89 SWI $0 // sys_getthrid 90 // arg 1 - pid, already in R0 91 MOVW sig+0(FP), R1 // arg 2 - signum 92 MOVW $37, R12 // sys_kill 93 SWI $0 94 RET 95 96 TEXT runtimeraiseproc(SB),NOSPLIT,$12 97 MOVW $20, R12 98 SWI $0 // sys_getpid 99 // arg 1 - pid, already in R0 100 MOVW sig+0(FP), R1 // arg 2 - signum 101 MOVW $37, R12 // sys_kill 102 SWI $0 103 RET 104 105 TEXT runtimemmap(SB),NOSPLIT,$16 106 MOVW addr+0(FP), R0 // arg 1 - addr 107 MOVW len+4(FP), R1 // arg 2 - len 108 MOVW prot+8(FP), R2 // arg 3 - prot 109 MOVW flags+12(FP), R3 // arg 4 - flags 110 MOVW fd+16(FP), R4 // arg 5 - fd (on stack) 111 MOVW R4, 4(R13) 112 MOVW $0, R5 // arg 6 - pad (on stack) 113 MOVW R5, 8(R13) 114 MOVW offset+20(FP), R6 // arg 7 - offset (on stack) 115 MOVW R6, 12(R13) // lower 32 bits (from Go runtime) 116 MOVW $0, R7 117 MOVW R7, 16(R13) // high 32 bits 118 ADD $4, R13 119 MOVW $197, R12 // sys_mmap 120 SWI $0 121 SUB $4, R13 122 MOVW R0, ret+24(FP) 123 RET 124 125 TEXT runtimemunmap(SB),NOSPLIT,$0 126 MOVW addr+0(FP), R0 // arg 1 - addr 127 MOVW len+4(FP), R1 // arg 2 - len 128 MOVW $73, R12 // sys_munmap 129 SWI $0 130 MOVW.CS $0, R8 // crash on syscall failure 131 MOVW.CS R8, (R8) 132 RET 133 134 TEXT runtimemadvise(SB),NOSPLIT,$0 135 MOVW addr+0(FP), R0 // arg 1 - addr 136 MOVW len+4(FP), R1 // arg 2 - len 137 MOVW behav+8(FP), R2 // arg 2 - behav 138 MOVW $75, R12 // sys_madvise 139 SWI $0 140 MOVW.CS $0, R8 // crash on syscall failure 141 MOVW.CS R8, (R8) 142 RET 143 144 TEXT runtimesetitimer(SB),NOSPLIT,$0 145 MOVW which+0(FP), R0 // arg 1 - which 146 MOVW value+4(FP), R1 // arg 2 - value 147 MOVW ovalue+8(FP), R2 // arg 3 - ovalue 148 MOVW $69, R12 // sys_setitimer 149 SWI $0 150 RET 151 152 // func now() (sec int64, nsec int32) 153 TEXT timenow(SB), NOSPLIT, $32 154 MOVW CLOCK_REALTIME, R0 // arg 1 - clock_id 155 MOVW $8(R13), R1 // arg 2 - tp 156 MOVW $87, R12 // sys_clock_gettime 157 SWI $0 158 159 MOVW 8(R13), R0 // sec - l32 160 MOVW 12(R13), R1 // sec - h32 161 MOVW 16(R13), R2 // nsec 162 163 MOVW R0, sec_lo+0(FP) 164 MOVW R1, sec_hi+4(FP) 165 MOVW R2, nsec+8(FP) 166 167 RET 168 169 // int64 nanotime(void) so really 170 // void nanotime(int64 *nsec) 171 TEXT runtimenanotime(SB),NOSPLIT,$32 172 MOVW CLOCK_MONOTONIC, R0 // arg 1 - clock_id 173 MOVW $8(R13), R1 // arg 2 - tp 174 MOVW $87, R12 // sys_clock_gettime 175 SWI $0 176 177 MOVW 8(R13), R0 // sec - l32 178 MOVW 12(R13), R4 // sec - h32 179 MOVW 16(R13), R2 // nsec 180 181 MOVW $1000000000, R3 182 MULLU R0, R3, (R1, R0) 183 MUL R3, R4 184 ADD.S R2, R0 185 ADC R4, R1 186 187 MOVW R0, ret_lo+0(FP) 188 MOVW R1, ret_hi+4(FP) 189 RET 190 191 TEXT runtimesigaction(SB),NOSPLIT,$0 192 MOVW signum+0(FP), R0 // arg 1 - signum 193 MOVW nsa+4(FP), R1 // arg 2 - nsa 194 MOVW osa+8(FP), R2 // arg 3 - osa 195 MOVW $46, R12 // sys_sigaction 196 SWI $0 197 MOVW.CS $3, R8 // crash on syscall failure 198 MOVW.CS R8, (R8) 199 RET 200 201 TEXT runtimesigprocmask(SB),NOSPLIT,$0 202 MOVW how+0(FP), R0 // arg 1 - how 203 MOVW mask+4(FP), R1 // arg 2 - mask 204 MOVW $48, R12 // sys_sigprocmask 205 SWI $0 206 MOVW.CS $3, R8 // crash on syscall failure 207 MOVW.CS R8, (R8) 208 MOVW R0, ret+8(FP) 209 RET 210 211 TEXT runtimesigtramp(SB),NOSPLIT,$24 212 // If called from an external code context, g will not be set. 213 // Save R0, since runtimeload_g will clobber it. 214 MOVW R0, 4(R13) // signum 215 MOVB runtimeiscgo(SB), R0 216 CMP $0, R0 217 BL.NE runtimeload_g(SB) 218 219 CMP $0, g 220 BNE 4(PC) 221 // Signal number saved in 4(R13). 222 MOVW runtimebadsignal(SB), R11 223 BL (R11) 224 RET 225 226 // Save g. 227 MOVW g, R3 228 MOVW g, 20(R13) 229 230 // g = m->signal 231 MOVW g_m(g), R8 232 MOVW m_gsignal(R8), g 233 234 // R0 already saved. 235 MOVW R1, 8(R13) // info 236 MOVW R2, 12(R13) // context 237 MOVW R3, 16(R13) // gp (original g) 238 239 BL runtimesighandler(SB) 240 241 // Restore g. 242 MOVW 20(R13), g 243 RET 244 245 // int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void)); 246 TEXT runtimetfork(SB),NOSPLIT,$0 247 248 // Copy mp, gp and fn off parent stack for use by child. 249 MOVW mm+8(FP), R4 250 MOVW gg+12(FP), R5 251 MOVW fn+16(FP), R6 252 253 MOVW param+0(FP), R0 // arg 1 - param 254 MOVW psize+4(FP), R1 // arg 2 - psize 255 MOVW $8, R12 // sys___tfork 256 SWI $0 257 258 // Return if syscall failed. 259 B.CC 4(PC) 260 RSB $0, R0 261 MOVW R0, ret+20(FP) 262 RET 263 264 // In parent, return. 265 CMP $0, R0 266 BEQ 3(PC) 267 MOVW R0, ret+20(FP) 268 RET 269 270 // Initialise m, g. 271 MOVW R5, g 272 MOVW R4, g_m(g) 273 274 // Paranoia; check that stack splitting code works. 275 BL runtimeemptyfunc(SB) 276 277 // Call fn. 278 BL (R6) 279 280 BL runtimeexit1(SB) 281 MOVW $2, R8 // crash if reached 282 MOVW R8, (R8) 283 RET 284 285 TEXT runtimesigaltstack(SB),NOSPLIT,$0 286 MOVW nss+0(FP), R0 // arg 1 - nss 287 MOVW oss+4(FP), R1 // arg 2 - oss 288 MOVW $288, R12 // sys_sigaltstack 289 SWI $0 290 MOVW.CS $0, R8 // crash on syscall failure 291 MOVW.CS R8, (R8) 292 RET 293 294 TEXT runtimeosyield(SB),NOSPLIT,$0 295 MOVW $298, R12 // sys_sched_yield 296 SWI $0 297 RET 298 299 TEXT runtimethrsleep(SB),NOSPLIT,$4 300 MOVW ident+0(FP), R0 // arg 1 - ident 301 MOVW clock_id+4(FP), R1 // arg 2 - clock_id 302 MOVW tp+8(FP), R2 // arg 3 - tp 303 MOVW lock+12(FP), R3 // arg 4 - lock 304 MOVW abort+16(FP), R4 // arg 5 - abort (on stack) 305 MOVW R4, 4(R13) 306 ADD $4, R13 307 MOVW $94, R12 // sys___thrsleep 308 SWI $0 309 SUB $4, R13 310 MOVW R0, ret+20(FP) 311 RET 312 313 TEXT runtimethrwakeup(SB),NOSPLIT,$0 314 MOVW ident+0(FP), R0 // arg 1 - ident 315 MOVW n+4(FP), R1 // arg 2 - n 316 MOVW $301, R12 // sys___thrwakeup 317 SWI $0 318 MOVW R0, ret+8(FP) 319 RET 320 321 TEXT runtimesysctl(SB),NOSPLIT,$8 322 MOVW name+0(FP), R0 // arg 1 - name 323 MOVW namelen+4(FP), R1 // arg 2 - namelen 324 MOVW oldp+8(FP), R2 // arg 3 - oldp 325 MOVW oldlenp+12(FP), R3 // arg 4 - oldlenp 326 MOVW newp+16(FP), R4 // arg 5 - newp (on stack) 327 MOVW R4, 4(R13) 328 MOVW newlen+20(FP), R5 // arg 6 - newlen (on stack) 329 MOVW R5, 8(R13) 330 ADD $4, R13 331 MOVW $202, R12 // sys___sysctl 332 SWI $0 333 SUB $4, R13 334 MOVW.CC $0, R0 335 RSB.CS $0, R0 336 MOVW R0, ret+24(FP) 337 RET 338 339 // int32 runtimekqueue(void); 340 TEXT runtimekqueue(SB),NOSPLIT,$0 341 MOVW $269, R12 // sys_kqueue 342 SWI $0 343 RSB.CS $0, R0 344 MOVW R0, ret+0(FP) 345 RET 346 347 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout); 348 TEXT runtimekevent(SB),NOSPLIT,$8 349 MOVW fd+0(FP), R0 // arg 1 - fd 350 MOVW changelist+4(FP), R1 // arg 2 - changelist 351 MOVW nchanges+8(FP), R2 // arg 3 - nchanges 352 MOVW eventlist+12(FP), R3 // arg 4 - eventlist 353 MOVW nevents+16(FP), R4 // arg 5 - nevents (on stack) 354 MOVW R4, 4(R13) 355 MOVW timeout+20(FP), R5 // arg 6 - timeout (on stack) 356 MOVW R5, 8(R13) 357 ADD $4, R13 358 MOVW $72, R12 // sys_kevent 359 SWI $0 360 RSB.CS $0, R0 361 SUB $4, R13 362 MOVW R0, ret+24(FP) 363 RET 364 365 // int32 runtimecloseonexec(int32 fd); 366 TEXT runtimecloseonexec(SB),NOSPLIT,$0 367 MOVW fd+0(FP), R0 // arg 1 - fd 368 MOVW $2, R1 // arg 2 - cmd (F_SETFD) 369 MOVW $1, R2 // arg 3 - arg (FD_CLOEXEC) 370 MOVW $92, R12 // sys_fcntl 371 SWI $0 372 RSB.CS $0, R0 373 MOVW R0, ret+4(FP) 374 RET 375 376 TEXT runtimecasp1(SB),NOSPLIT,$0 377 //B runtimearmcas(SB) 378 B runtimecas(SB) 379 380 TEXT runtimecas(SB),NOSPLIT,$0 381 B runtimearmcas(SB) 382 383 TEXT publicationBarrier(SB),NOSPLIT,$-4-0 384 B runtimearmPublicationBarrier(SB) 385 386 // TODO(jsing): Implement. 387 TEXT runtimeread_tls_fallback(SB),NOSPLIT,$-4 388 MOVW $5, R0 389 MOVW R0, (R0) 390 RET 391