1 // Copyright 2014 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 // +build linux 6 // +build ppc64 ppc64le 7 8 // 9 // System calls and other sys.stuff for ppc64, Linux 10 // 11 12 #include "go_asm.h" 13 #include "go_tls.h" 14 #include "textflag.h" 15 16 #define SYS_exit 1 17 #define SYS_read 3 18 #define SYS_write 4 19 #define SYS_open 5 20 #define SYS_close 6 21 #define SYS_getpid 20 22 #define SYS_kill 37 23 #define SYS_fcntl 55 24 #define SYS_gettimeofday 78 25 #define SYS_select 82 // always return -ENOSYS 26 #define SYS_mmap 90 27 #define SYS_munmap 91 28 #define SYS_setitimer 104 29 #define SYS_clone 120 30 #define SYS_newselect 142 31 #define SYS_sched_yield 158 32 #define SYS_rt_sigreturn 172 33 #define SYS_rt_sigaction 173 34 #define SYS_rt_sigprocmask 174 35 #define SYS_sigaltstack 185 36 #define SYS_ugetrlimit 190 37 #define SYS_madvise 205 38 #define SYS_mincore 206 39 #define SYS_gettid 207 40 #define SYS_tkill 208 41 #define SYS_futex 221 42 #define SYS_sched_getaffinity 223 43 #define SYS_exit_group 234 44 #define SYS_epoll_create 236 45 #define SYS_epoll_ctl 237 46 #define SYS_epoll_wait 238 47 #define SYS_clock_gettime 246 48 #define SYS_epoll_create1 315 49 50 TEXT runtimeexit(SB),NOSPLIT,$-8-4 51 MOVW code+0(FP), R3 52 SYSCALL $SYS_exit_group 53 RET 54 55 TEXT runtimeexit1(SB),NOSPLIT,$-8-4 56 MOVW code+0(FP), R3 57 SYSCALL $SYS_exit 58 RET 59 60 TEXT runtimeopen(SB),NOSPLIT,$-8-20 61 MOVD name+0(FP), R3 62 MOVW mode+8(FP), R4 63 MOVW perm+12(FP), R5 64 SYSCALL $SYS_open 65 BVC 2(PC) 66 MOVW $-1, R3 67 MOVW R3, ret+16(FP) 68 RET 69 70 TEXT runtimeclosefd(SB),NOSPLIT,$-8-12 71 MOVW fd+0(FP), R3 72 SYSCALL $SYS_close 73 BVC 2(PC) 74 MOVW $-1, R3 75 MOVW R3, ret+8(FP) 76 RET 77 78 TEXT runtimewrite(SB),NOSPLIT,$-8-28 79 MOVD fd+0(FP), R3 80 MOVD p+8(FP), R4 81 MOVW n+16(FP), R5 82 SYSCALL $SYS_write 83 BVC 2(PC) 84 MOVW $-1, R3 85 MOVW R3, ret+24(FP) 86 RET 87 88 TEXT runtimeread(SB),NOSPLIT,$-8-28 89 MOVW fd+0(FP), R3 90 MOVD p+8(FP), R4 91 MOVW n+16(FP), R5 92 SYSCALL $SYS_read 93 BVC 2(PC) 94 MOVW $-1, R3 95 MOVW R3, ret+24(FP) 96 RET 97 98 TEXT runtimegetrlimit(SB),NOSPLIT,$-8-20 99 MOVW kind+0(FP), R3 100 MOVD limit+8(FP), R4 101 SYSCALL $SYS_ugetrlimit 102 MOVW R3, ret+16(FP) 103 RET 104 105 TEXT runtimeusleep(SB),NOSPLIT,$16-4 106 MOVW usec+0(FP), R3 107 MOVD R3, R5 108 MOVW $1000000, R4 109 DIVD R4, R3 110 MOVD R3, 8(R1) 111 MULLD R3, R4 112 SUB R4, R5 113 MOVD R5, 16(R1) 114 115 // select(0, 0, 0, 0, &tv) 116 MOVW $0, R3 117 MOVW $0, R4 118 MOVW $0, R5 119 MOVW $0, R6 120 ADD $8, R1, R7 121 SYSCALL $SYS_newselect 122 RET 123 124 TEXT runtimegettid(SB),NOSPLIT,$0-4 125 SYSCALL $SYS_gettid 126 MOVW R3, ret+0(FP) 127 RET 128 129 TEXT runtimeraise(SB),NOSPLIT,$-8 130 SYSCALL $SYS_gettid 131 MOVW R3, R3 // arg 1 tid 132 MOVW sig+0(FP), R4 // arg 2 133 SYSCALL $SYS_tkill 134 RET 135 136 TEXT runtimeraiseproc(SB),NOSPLIT,$-8 137 SYSCALL $SYS_getpid 138 MOVW R3, R3 // arg 1 pid 139 MOVW sig+0(FP), R4 // arg 2 140 SYSCALL $SYS_kill 141 RET 142 143 TEXT runtimesetitimer(SB),NOSPLIT,$-8-24 144 MOVW mode+0(FP), R3 145 MOVD new+8(FP), R4 146 MOVD old+16(FP), R5 147 SYSCALL $SYS_setitimer 148 RET 149 150 TEXT runtimemincore(SB),NOSPLIT,$-8-28 151 MOVD addr+0(FP), R3 152 MOVD n+8(FP), R4 153 MOVD dst+16(FP), R5 154 SYSCALL $SYS_mincore 155 MOVW R3, ret+24(FP) 156 RET 157 158 // func now() (sec int64, nsec int32) 159 TEXT timenow(SB),NOSPLIT,$16 160 MOVD $0(R1), R3 161 MOVD $0, R4 162 SYSCALL $SYS_gettimeofday 163 MOVD 0(R1), R3 // sec 164 MOVD 8(R1), R5 // usec 165 MOVD $1000, R4 166 MULLD R4, R5 167 MOVD R3, sec+0(FP) 168 MOVW R5, nsec+8(FP) 169 RET 170 171 TEXT runtimenanotime(SB),NOSPLIT,$16 172 MOVW $1, R3 // CLOCK_MONOTONIC 173 MOVD $0(R1), R4 174 SYSCALL $SYS_clock_gettime 175 MOVD 0(R1), R3 // sec 176 MOVD 8(R1), R5 // nsec 177 // sec is in R3, nsec in R5 178 // return nsec in R3 179 MOVD $1000000000, R4 180 MULLD R4, R3 181 ADD R5, R3 182 MOVD R3, ret+0(FP) 183 RET 184 185 TEXT runtimertsigprocmask(SB),NOSPLIT,$-8-28 186 MOVW sig+0(FP), R3 187 MOVD new+8(FP), R4 188 MOVD old+16(FP), R5 189 MOVW size+24(FP), R6 190 SYSCALL $SYS_rt_sigprocmask 191 BVC 2(PC) 192 MOVD R0, 0xf1(R0) // crash 193 RET 194 195 TEXT runtimert_sigaction(SB),NOSPLIT,$-8-36 196 MOVD sig+0(FP), R3 197 MOVD new+8(FP), R4 198 MOVD old+16(FP), R5 199 MOVD size+24(FP), R6 200 SYSCALL $SYS_rt_sigaction 201 MOVW R3, ret+32(FP) 202 RET 203 204 TEXT runtimesigfwd(SB),NOSPLIT,$0-32 205 MOVW sig+8(FP), R3 206 MOVD info+16(FP), R4 207 MOVD ctx+24(FP), R5 208 MOVD fn+0(FP), R31 209 MOVD R31, CTR 210 BL (CTR) 211 RET 212 213 #ifdef GOARCH_ppc64le 214 // ppc64le doesn't need function descriptors 215 TEXT runtimesigtramp(SB),NOSPLIT,$64 216 #else 217 // function descriptor for the real sigtramp 218 TEXT runtimesigtramp(SB),NOSPLIT,$-8 219 DWORD $runtime_sigtramp(SB) 220 DWORD $0 221 DWORD $0 222 TEXT runtime_sigtramp(SB),NOSPLIT,$64 223 #endif 224 // initialize essential registers (just in case) 225 BL runtimereginit(SB) 226 227 // this might be called in external code context, 228 // where g is not set. 229 MOVB runtimeiscgo(SB), R6 230 CMP R6, $0 231 BEQ 2(PC) 232 BL runtimeload_g(SB) 233 234 MOVW R3, 8(R1) 235 MOVD R4, 16(R1) 236 MOVD R5, 24(R1) 237 MOVD $runtimesigtrampgo(SB), R31 238 MOVD R31, CTR 239 BL (CTR) 240 RET 241 242 TEXT runtimemmap(SB),NOSPLIT,$-8 243 MOVD addr+0(FP), R3 244 MOVD n+8(FP), R4 245 MOVW prot+16(FP), R5 246 MOVW flags+20(FP), R6 247 MOVW fd+24(FP), R7 248 MOVW off+28(FP), R8 249 250 SYSCALL $SYS_mmap 251 MOVD R3, ret+32(FP) 252 RET 253 254 TEXT runtimemunmap(SB),NOSPLIT,$-8 255 MOVD addr+0(FP), R3 256 MOVD n+8(FP), R4 257 SYSCALL $SYS_munmap 258 BVC 2(PC) 259 MOVD R0, 0xf3(R0) 260 RET 261 262 TEXT runtimemadvise(SB),NOSPLIT,$-8 263 MOVD addr+0(FP), R3 264 MOVD n+8(FP), R4 265 MOVW flags+16(FP), R5 266 SYSCALL $SYS_madvise 267 // ignore failure - maybe pages are locked 268 RET 269 270 // int64 futex(int32 *uaddr, int32 op, int32 val, 271 // struct timespec *timeout, int32 *uaddr2, int32 val2); 272 TEXT runtimefutex(SB),NOSPLIT,$-8 273 MOVD addr+0(FP), R3 274 MOVW op+8(FP), R4 275 MOVW val+12(FP), R5 276 MOVD ts+16(FP), R6 277 MOVD addr2+24(FP), R7 278 MOVW val3+32(FP), R8 279 SYSCALL $SYS_futex 280 MOVW R3, ret+40(FP) 281 RET 282 283 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 284 TEXT runtimeclone(SB),NOSPLIT,$-8 285 MOVW flags+0(FP), R3 286 MOVD stk+8(FP), R4 287 288 // Copy mp, gp, fn off parent stack for use by child. 289 // Careful: Linux system call clobbers ???. 290 MOVD mm+16(FP), R7 291 MOVD gg+24(FP), R8 292 MOVD fn+32(FP), R12 293 294 MOVD R7, -8(R4) 295 MOVD R8, -16(R4) 296 MOVD R12, -24(R4) 297 MOVD $1234, R7 298 MOVD R7, -32(R4) 299 300 SYSCALL $SYS_clone 301 302 // In parent, return. 303 CMP R3, $0 304 BEQ 3(PC) 305 MOVW R3, ret+40(FP) 306 RET 307 308 // In child, on new stack. 309 // initialize essential registers 310 BL runtimereginit(SB) 311 MOVD -32(R1), R7 312 CMP R7, $1234 313 BEQ 2(PC) 314 MOVD R0, 0(R0) 315 316 // Initialize m->procid to Linux tid 317 SYSCALL $SYS_gettid 318 319 MOVD -24(R1), R12 // fn 320 MOVD -16(R1), R8 // g 321 MOVD -8(R1), R7 // m 322 323 CMP R7, $0 324 BEQ nog 325 CMP R8, $0 326 BEQ nog 327 328 MOVD R3, m_procid(R7) 329 330 // TODO: setup TLS. 331 332 // In child, set up new stack 333 MOVD R7, g_m(R8) 334 MOVD R8, g 335 //CALL runtimestackcheck(SB) 336 337 nog: 338 // Call fn 339 MOVD R12, CTR 340 BL (CTR) 341 342 // It shouldn't return. If it does, exit that thread. 343 MOVW $111, R3 344 SYSCALL $SYS_exit 345 BR -2(PC) // keep exiting 346 347 TEXT runtimesigaltstack(SB),NOSPLIT,$-8 348 MOVD new+0(FP), R3 349 MOVD old+8(FP), R4 350 SYSCALL $SYS_sigaltstack 351 BVC 2(PC) 352 MOVD R0, 0xf1(R0) // crash 353 RET 354 355 TEXT runtimeosyield(SB),NOSPLIT,$-8 356 SYSCALL $SYS_sched_yield 357 RET 358 359 TEXT runtimesched_getaffinity(SB),NOSPLIT,$-8 360 MOVD pid+0(FP), R3 361 MOVD len+8(FP), R4 362 MOVD buf+16(FP), R5 363 SYSCALL $SYS_sched_getaffinity 364 MOVW R3, ret+24(FP) 365 RET 366 367 // int32 runtimeepollcreate(int32 size); 368 TEXT runtimeepollcreate(SB),NOSPLIT,$-8 369 MOVW size+0(FP), R3 370 SYSCALL $SYS_epoll_create 371 MOVW R3, ret+8(FP) 372 RET 373 374 // int32 runtimeepollcreate1(int32 flags); 375 TEXT runtimeepollcreate1(SB),NOSPLIT,$-8 376 MOVW flags+0(FP), R3 377 SYSCALL $SYS_epoll_create1 378 MOVW R3, ret+8(FP) 379 RET 380 381 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 382 TEXT runtimeepollctl(SB),NOSPLIT,$-8 383 MOVW epfd+0(FP), R3 384 MOVW op+4(FP), R4 385 MOVW fd+8(FP), R5 386 MOVD ev+16(FP), R6 387 SYSCALL $SYS_epoll_ctl 388 MOVW R3, ret+24(FP) 389 RET 390 391 // int32 runtimeepollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 392 TEXT runtimeepollwait(SB),NOSPLIT,$-8 393 MOVW epfd+0(FP), R3 394 MOVD ev+8(FP), R4 395 MOVW nev+16(FP), R5 396 MOVW timeout+20(FP), R6 397 SYSCALL $SYS_epoll_wait 398 MOVW R3, ret+24(FP) 399 RET 400 401 // void runtimecloseonexec(int32 fd); 402 TEXT runtimecloseonexec(SB),NOSPLIT,$-8 403 MOVW fd+0(FP), R3 // fd 404 MOVD $2, R4 // F_SETFD 405 MOVD $1, R5 // FD_CLOEXEC 406 SYSCALL $SYS_fcntl 407 RET 408