Home | History | Annotate | Download | only in runtime
      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