github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/runtime/sys_linux_arm.s (about) 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 // 6 // System calls and other sys.stuff for arm, Linux 7 // 8 9 #include "zasm_GOOS_GOARCH.h" 10 #include "../../cmd/ld/textflag.h" 11 12 // for EABI, as we don't support OABI 13 #define SYS_BASE 0x0 14 15 #define SYS_exit (SYS_BASE + 1) 16 #define SYS_read (SYS_BASE + 3) 17 #define SYS_write (SYS_BASE + 4) 18 #define SYS_open (SYS_BASE + 5) 19 #define SYS_close (SYS_BASE + 6) 20 #define SYS_gettimeofday (SYS_BASE + 78) 21 #define SYS_clone (SYS_BASE + 120) 22 #define SYS_rt_sigreturn (SYS_BASE + 173) 23 #define SYS_rt_sigaction (SYS_BASE + 174) 24 #define SYS_rt_sigprocmask (SYS_BASE + 175) 25 #define SYS_sigaltstack (SYS_BASE + 186) 26 #define SYS_mmap2 (SYS_BASE + 192) 27 #define SYS_futex (SYS_BASE + 240) 28 #define SYS_exit_group (SYS_BASE + 248) 29 #define SYS_munmap (SYS_BASE + 91) 30 #define SYS_madvise (SYS_BASE + 220) 31 #define SYS_setitimer (SYS_BASE + 104) 32 #define SYS_mincore (SYS_BASE + 219) 33 #define SYS_gettid (SYS_BASE + 224) 34 #define SYS_tkill (SYS_BASE + 238) 35 #define SYS_sched_yield (SYS_BASE + 158) 36 #define SYS_select (SYS_BASE + 142) // newselect 37 #define SYS_ugetrlimit (SYS_BASE + 191) 38 #define SYS_sched_getaffinity (SYS_BASE + 242) 39 #define SYS_clock_gettime (SYS_BASE + 263) 40 #define SYS_epoll_create (SYS_BASE + 250) 41 #define SYS_epoll_ctl (SYS_BASE + 251) 42 #define SYS_epoll_wait (SYS_BASE + 252) 43 #define SYS_epoll_create1 (SYS_BASE + 357) 44 #define SYS_fcntl (SYS_BASE + 55) 45 46 #define ARM_BASE (SYS_BASE + 0x0f0000) 47 48 TEXT runtime·open(SB),NOSPLIT,$0 49 MOVW 0(FP), R0 50 MOVW 4(FP), R1 51 MOVW 8(FP), R2 52 MOVW $SYS_open, R7 53 SWI $0 54 RET 55 56 TEXT runtime·close(SB),NOSPLIT,$0 57 MOVW 0(FP), R0 58 MOVW $SYS_close, R7 59 SWI $0 60 RET 61 62 TEXT runtime·write(SB),NOSPLIT,$0 63 MOVW 0(FP), R0 64 MOVW 4(FP), R1 65 MOVW 8(FP), R2 66 MOVW $SYS_write, R7 67 SWI $0 68 RET 69 70 TEXT runtime·read(SB),NOSPLIT,$0 71 MOVW 0(FP), R0 72 MOVW 4(FP), R1 73 MOVW 8(FP), R2 74 MOVW $SYS_read, R7 75 SWI $0 76 RET 77 78 TEXT runtime·getrlimit(SB),NOSPLIT,$0 79 MOVW 0(FP), R0 80 MOVW 4(FP), R1 81 MOVW $SYS_ugetrlimit, R7 82 SWI $0 83 RET 84 85 TEXT runtime·exit(SB),NOSPLIT,$-4 86 MOVW 0(FP), R0 87 MOVW $SYS_exit_group, R7 88 SWI $0 89 MOVW $1234, R0 90 MOVW $1002, R1 91 MOVW R0, (R1) // fail hard 92 93 TEXT runtime·exit1(SB),NOSPLIT,$-4 94 MOVW 0(FP), R0 95 MOVW $SYS_exit, R7 96 SWI $0 97 MOVW $1234, R0 98 MOVW $1003, R1 99 MOVW R0, (R1) // fail hard 100 101 TEXT runtime·raise(SB),NOSPLIT,$-4 102 MOVW $SYS_gettid, R7 103 SWI $0 104 // arg 1 tid already in R0 from gettid 105 MOVW sig+0(FP), R1 // arg 2 - signal 106 MOVW $SYS_tkill, R7 107 SWI $0 108 RET 109 110 TEXT runtime·mmap(SB),NOSPLIT,$0 111 MOVW 0(FP), R0 112 MOVW 4(FP), R1 113 MOVW 8(FP), R2 114 MOVW 12(FP), R3 115 MOVW 16(FP), R4 116 MOVW 20(FP), R5 117 MOVW $SYS_mmap2, R7 118 SWI $0 119 MOVW $0xfffff001, R6 120 CMP R6, R0 121 RSB.HI $0, R0 122 RET 123 124 TEXT runtime·munmap(SB),NOSPLIT,$0 125 MOVW 0(FP), R0 126 MOVW 4(FP), R1 127 MOVW $SYS_munmap, R7 128 SWI $0 129 MOVW $0xfffff001, R6 130 CMP R6, R0 131 MOVW.HI $0, R8 // crash on syscall failure 132 MOVW.HI R8, (R8) 133 RET 134 135 TEXT runtime·madvise(SB),NOSPLIT,$0 136 MOVW 0(FP), R0 137 MOVW 4(FP), R1 138 MOVW 8(FP), R2 139 MOVW $SYS_madvise, R7 140 SWI $0 141 // ignore failure - maybe pages are locked 142 RET 143 144 TEXT runtime·setitimer(SB),NOSPLIT,$0 145 MOVW 0(FP), R0 146 MOVW 4(FP), R1 147 MOVW 8(FP), R2 148 MOVW $SYS_setitimer, R7 149 SWI $0 150 RET 151 152 TEXT runtime·mincore(SB),NOSPLIT,$0 153 MOVW 0(FP), R0 154 MOVW 4(FP), R1 155 MOVW 8(FP), R2 156 MOVW $SYS_mincore, R7 157 SWI $0 158 RET 159 160 TEXT time·now(SB), NOSPLIT, $32 161 MOVW $0, R0 // CLOCK_REALTIME 162 MOVW $8(R13), R1 // timespec 163 MOVW $SYS_clock_gettime, R7 164 SWI $0 165 166 MOVW 8(R13), R0 // sec 167 MOVW 12(R13), R2 // nsec 168 169 MOVW R0, 0(FP) 170 MOVW $0, R1 171 MOVW R1, 4(FP) 172 MOVW R2, 8(FP) 173 RET 174 175 // int64 nanotime(void) so really 176 // void nanotime(int64 *nsec) 177 TEXT runtime·nanotime(SB),NOSPLIT,$32 178 MOVW $0, R0 // CLOCK_REALTIME 179 MOVW $8(R13), R1 // timespec 180 MOVW $SYS_clock_gettime, R7 181 SWI $0 182 183 MOVW 8(R13), R0 // sec 184 MOVW 12(R13), R2 // nsec 185 186 MOVW $1000000000, R3 187 MULLU R0, R3, (R1, R0) 188 MOVW $0, R4 189 ADD.S R2, R0 190 ADC R4, R1 191 192 MOVW 0(FP), R3 193 MOVW R0, 0(R3) 194 MOVW R1, 4(R3) 195 RET 196 197 // int32 futex(int32 *uaddr, int32 op, int32 val, 198 // struct timespec *timeout, int32 *uaddr2, int32 val2); 199 TEXT runtime·futex(SB),NOSPLIT,$0 200 MOVW 4(SP), R0 201 MOVW 8(SP), R1 202 MOVW 12(SP), R2 203 MOVW 16(SP), R3 204 MOVW 20(SP), R4 205 MOVW 24(SP), R5 206 MOVW $SYS_futex, R7 207 SWI $0 208 RET 209 210 211 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void)); 212 TEXT runtime·clone(SB),NOSPLIT,$0 213 MOVW flags+0(FP), R0 214 MOVW stack+4(FP), R1 215 MOVW $0, R2 // parent tid ptr 216 MOVW $0, R3 // tls_val 217 MOVW $0, R4 // child tid ptr 218 MOVW $0, R5 219 220 // Copy mp, gp, fn off parent stack for use by child. 221 // TODO(kaib): figure out which registers are clobbered by clone and avoid stack copying 222 MOVW $-16(R1), R1 223 MOVW mm+8(FP), R6 224 MOVW R6, 0(R1) 225 MOVW gg+12(FP), R6 226 MOVW R6, 4(R1) 227 MOVW fn+16(FP), R6 228 MOVW R6, 8(R1) 229 MOVW $1234, R6 230 MOVW R6, 12(R1) 231 232 MOVW $SYS_clone, R7 233 SWI $0 234 235 // In parent, return. 236 CMP $0, R0 237 BEQ 2(PC) 238 RET 239 240 // Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup' 241 MOVW 12(R13), R0 242 MOVW $1234, R1 243 CMP R0, R1 244 BEQ 2(PC) 245 BL runtime·abort(SB) 246 247 MOVW 0(R13), m 248 MOVW 4(R13), g 249 250 // paranoia; check they are not nil 251 MOVW 0(m), R0 252 MOVW 0(g), R0 253 254 BL runtime·emptyfunc(SB) // fault if stack check is wrong 255 256 // Initialize m->procid to Linux tid 257 MOVW $SYS_gettid, R7 258 SWI $0 259 MOVW R0, m_procid(m) 260 261 // Call fn 262 MOVW 8(R13), R0 263 MOVW $16(R13), R13 264 BL (R0) 265 266 MOVW $0, R0 267 MOVW R0, 4(R13) 268 BL runtime·exit1(SB) 269 270 // It shouldn't return 271 MOVW $1234, R0 272 MOVW $1005, R1 273 MOVW R0, (R1) 274 275 TEXT runtime·sigaltstack(SB),NOSPLIT,$0 276 MOVW 0(FP), R0 277 MOVW 4(FP), R1 278 MOVW $SYS_sigaltstack, R7 279 SWI $0 280 MOVW $0xfffff001, R6 281 CMP R6, R0 282 MOVW.HI $0, R8 // crash on syscall failure 283 MOVW.HI R8, (R8) 284 RET 285 286 TEXT runtime·sigtramp(SB),NOSPLIT,$24 287 // this might be called in external code context, 288 // where g and m are not set. 289 // first save R0, because runtime·load_gm will clobber it 290 MOVW R0, 4(R13) 291 MOVB runtime·iscgo(SB), R0 292 CMP $0, R0 293 BL.NE runtime·load_gm(SB) 294 295 CMP $0, m 296 BNE 4(PC) 297 // signal number is already prepared in 4(R13) 298 MOVW $runtime·badsignal(SB), R11 299 BL (R11) 300 RET 301 302 // save g 303 MOVW g, R3 304 MOVW g, 20(R13) 305 306 // g = m->gsignal 307 MOVW m_gsignal(m), g 308 309 // copy arguments for call to sighandler 310 // R0 is already saved above 311 MOVW R1, 8(R13) 312 MOVW R2, 12(R13) 313 MOVW R3, 16(R13) 314 315 BL runtime·sighandler(SB) 316 317 // restore g 318 MOVW 20(R13), g 319 320 RET 321 322 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0 323 MOVW 0(FP), R0 324 MOVW 4(FP), R1 325 MOVW 8(FP), R2 326 MOVW 12(FP), R3 327 MOVW $SYS_rt_sigprocmask, R7 328 SWI $0 329 RET 330 331 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0 332 MOVW 0(FP), R0 333 MOVW 4(FP), R1 334 MOVW 8(FP), R2 335 MOVW 12(FP), R3 336 MOVW $SYS_rt_sigaction, R7 337 SWI $0 338 RET 339 340 TEXT runtime·sigreturn(SB),NOSPLIT,$0 341 MOVW $SYS_rt_sigreturn, R7 342 SWI $0 343 RET 344 345 TEXT runtime·usleep(SB),NOSPLIT,$12 346 MOVW usec+0(FP), R0 347 MOVW R0, R1 348 MOVW $1000000, R2 349 DIV R2, R0 350 MOD R2, R1 351 MOVW R0, 4(SP) 352 MOVW R1, 8(SP) 353 MOVW $0, R0 354 MOVW $0, R1 355 MOVW $0, R2 356 MOVW $0, R3 357 MOVW $4(SP), R4 358 MOVW $SYS_select, R7 359 SWI $0 360 RET 361 362 // Use kernel version instead of native armcas in asm_arm.s. 363 // See ../sync/atomic/asm_linux_arm.s for details. 364 TEXT cas<>(SB),NOSPLIT,$0 365 MOVW $0xffff0fc0, PC 366 367 TEXT runtime·cas(SB),NOSPLIT,$0 368 MOVW valptr+0(FP), R2 369 MOVW old+4(FP), R0 370 casagain: 371 MOVW new+8(FP), R1 372 BL cas<>(SB) 373 BCC cascheck 374 MOVW $1, R0 375 RET 376 cascheck: 377 // Kernel lies; double-check. 378 MOVW valptr+0(FP), R2 379 MOVW old+4(FP), R0 380 MOVW 0(R2), R3 381 CMP R0, R3 382 BEQ casagain 383 MOVW $0, R0 384 RET 385 386 TEXT runtime·casp(SB),NOSPLIT,$0 387 B runtime·cas(SB) 388 389 TEXT runtime·osyield(SB),NOSPLIT,$0 390 MOVW $SYS_sched_yield, R7 391 SWI $0 392 RET 393 394 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 395 MOVW 0(FP), R0 396 MOVW 4(FP), R1 397 MOVW 8(FP), R2 398 MOVW $SYS_sched_getaffinity, R7 399 SWI $0 400 RET 401 402 // int32 runtime·epollcreate(int32 size) 403 TEXT runtime·epollcreate(SB),NOSPLIT,$0 404 MOVW 0(FP), R0 405 MOVW $SYS_epoll_create, R7 406 SWI $0 407 RET 408 409 // int32 runtime·epollcreate1(int32 flags) 410 TEXT runtime·epollcreate1(SB),NOSPLIT,$0 411 MOVW 0(FP), R0 412 MOVW $SYS_epoll_create1, R7 413 SWI $0 414 RET 415 416 // int32 runtime·epollctl(int32 epfd, int32 op, int32 fd, EpollEvent *ev) 417 TEXT runtime·epollctl(SB),NOSPLIT,$0 418 MOVW 0(FP), R0 419 MOVW 4(FP), R1 420 MOVW 8(FP), R2 421 MOVW 12(FP), R3 422 MOVW $SYS_epoll_ctl, R7 423 SWI $0 424 RET 425 426 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout) 427 TEXT runtime·epollwait(SB),NOSPLIT,$0 428 MOVW 0(FP), R0 429 MOVW 4(FP), R1 430 MOVW 8(FP), R2 431 MOVW 12(FP), R3 432 MOVW $SYS_epoll_wait, R7 433 SWI $0 434 RET 435 436 // void runtime·closeonexec(int32 fd) 437 TEXT runtime·closeonexec(SB),NOSPLIT,$0 438 MOVW 0(FP), R0 // fd 439 MOVW $2, R1 // F_SETFD 440 MOVW $1, R2 // FD_CLOEXEC 441 MOVW $SYS_fcntl, R7 442 SWI $0 443 RET 444 445 // b __kuser_get_tls @ 0xffff0fe0 446 TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4 447 MOVW $0xffff0fe0, R0 448 B (R0)