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