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