Home | History | Annotate | Download | only in runtime
      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 // System calls and other sys.stuff for ARM, OpenBSD
      6 // /usr/src/sys/kern/syscalls.master for syscall numbers.
      7 //
      8 
      9 #include "go_asm.h"
     10 #include "go_tls.h"
     11 #include "textflag.h"
     12 
     13 #define CLOCK_REALTIME	$0
     14 #define	CLOCK_MONOTONIC	$3
     15 
     16 // Exit the entire program (like C exit)
     17 TEXT runtimeexit(SB),NOSPLIT,$-4
     18 	MOVW	code+0(FP), R0	// arg 1 - status
     19 	MOVW	$1, R12			// sys_exit
     20 	SWI	$0
     21 	MOVW.CS	$0, R8			// crash on syscall failure
     22 	MOVW.CS	R8, (R8)
     23 	RET
     24 
     25 // func exitThread(wait *uint32)
     26 TEXT runtimeexitThread(SB),NOSPLIT,$0-4
     27 	MOVW	wait+0(FP), R0
     28 	// We're done using the stack.
     29 	MOVW	$0, R2
     30 storeloop:
     31 	LDREX	(R0), R4          // loads R4
     32 	STREX	R2, (R0), R1      // stores R2
     33 	CMP	$0, R1
     34 	BNE	storeloop
     35 	MOVW	$0, R0			// arg 1 - notdead
     36 	MOVW	$302, R12		// sys___threxit
     37 	SWI	$0
     38 	MOVW.CS	$1, R8			// crash on syscall failure
     39 	MOVW.CS	R8, (R8)
     40 	JMP	0(PC)
     41 
     42 TEXT runtimeopen(SB),NOSPLIT,$-4
     43 	MOVW	name+0(FP), R0		// arg 1 - path
     44 	MOVW	mode+4(FP), R1		// arg 2 - mode
     45 	MOVW	perm+8(FP), R2		// arg 3 - perm
     46 	MOVW	$5, R12			// sys_open
     47 	SWI	$0
     48 	MOVW.CS	$-1, R0
     49 	MOVW	R0, ret+12(FP)
     50 	RET
     51 
     52 TEXT runtimeclosefd(SB),NOSPLIT,$-4
     53 	MOVW	fd+0(FP), R0		// arg 1 - fd
     54 	MOVW	$6, R12			// sys_close
     55 	SWI	$0
     56 	MOVW.CS	$-1, R0
     57 	MOVW	R0, ret+4(FP)
     58 	RET
     59 
     60 TEXT runtimeread(SB),NOSPLIT,$-4
     61 	MOVW	fd+0(FP), R0		// arg 1 - fd
     62 	MOVW	p+4(FP), R1		// arg 2 - buf
     63 	MOVW	n+8(FP), R2		// arg 3 - nbyte
     64 	MOVW	$3, R12			// sys_read
     65 	SWI	$0
     66 	MOVW.CS	$-1, R0
     67 	MOVW	R0, ret+12(FP)
     68 	RET
     69 
     70 TEXT runtimewrite(SB),NOSPLIT,$-4
     71 	MOVW	fd+0(FP), R0		// arg 1 - fd
     72 	MOVW	p+4(FP), R1		// arg 2 - buf
     73 	MOVW	n+8(FP), R2		// arg 3 - nbyte
     74 	MOVW	$4, R12			// sys_write
     75 	SWI	$0
     76 	MOVW.CS	$-1, R0
     77 	MOVW	R0, ret+12(FP)
     78 	RET
     79 
     80 TEXT runtimeusleep(SB),NOSPLIT,$16
     81 	MOVW	usec+0(FP), R0
     82 	CALL	runtimeusplitR0(SB)
     83 	MOVW	R0, 4(R13)		// tv_sec - l32
     84 	MOVW	$0, R0
     85 	MOVW	R0, 8(R13)		// tv_sec - h32
     86 	MOVW	$1000, R2
     87 	MUL	R1, R2
     88 	MOVW	R2, 12(R13)		// tv_nsec
     89 
     90 	MOVW	$4(R13), R0		// arg 1 - rqtp
     91 	MOVW	$0, R1			// arg 2 - rmtp
     92 	MOVW	$91, R12		// sys_nanosleep
     93 	SWI	$0
     94 	RET
     95 
     96 TEXT runtimeraise(SB),NOSPLIT,$12
     97 	MOVW	$0x12B, R12
     98 	SWI	$0			// sys_getthrid
     99 					// arg 1 - tid, already in R0
    100 	MOVW	sig+0(FP), R1		// arg 2 - signum
    101 	MOVW	$0, R2			// arg 3 - tcb
    102 	MOVW	$119, R12		// sys_thrkill
    103 	SWI	$0
    104 	RET
    105 
    106 TEXT runtimeraiseproc(SB),NOSPLIT,$12
    107 	MOVW	$20, R12
    108 	SWI	$0			// sys_getpid
    109 					// arg 1 - pid, already in R0
    110 	MOVW	sig+0(FP), R1		// arg 2 - signum
    111 	MOVW	$122, R12		// sys_kill
    112 	SWI	$0
    113 	RET
    114 
    115 TEXT runtimemmap(SB),NOSPLIT,$16
    116 	MOVW	addr+0(FP), R0		// arg 1 - addr
    117 	MOVW	n+4(FP), R1		// arg 2 - len
    118 	MOVW	prot+8(FP), R2		// arg 3 - prot
    119 	MOVW	flags+12(FP), R3	// arg 4 - flags
    120 	MOVW	fd+16(FP), R4		// arg 5 - fd (on stack)
    121 	MOVW	R4, 4(R13)
    122 	MOVW	$0, R5			// arg 6 - pad (on stack)
    123 	MOVW	R5, 8(R13)
    124 	MOVW	off+20(FP), R6		// arg 7 - offset (on stack)
    125 	MOVW	R6, 12(R13)		// lower 32 bits (from Go runtime)
    126 	MOVW	$0, R7
    127 	MOVW	R7, 16(R13)		// high 32 bits
    128 	ADD	$4, R13
    129 	MOVW	$197, R12		// sys_mmap
    130 	SWI	$0
    131 	SUB	$4, R13
    132 	MOVW	$0, R1
    133 	MOVW.CS	R0, R1			// if error, move to R1
    134 	MOVW.CS $0, R0
    135 	MOVW	R0, p+24(FP)
    136 	MOVW	R1, err+28(FP)
    137 	RET
    138 
    139 TEXT runtimemunmap(SB),NOSPLIT,$0
    140 	MOVW	addr+0(FP), R0		// arg 1 - addr
    141 	MOVW	n+4(FP), R1		// arg 2 - len
    142 	MOVW	$73, R12		// sys_munmap
    143 	SWI	$0
    144 	MOVW.CS	$0, R8			// crash on syscall failure
    145 	MOVW.CS	R8, (R8)
    146 	RET
    147 
    148 TEXT runtimemadvise(SB),NOSPLIT,$0
    149 	MOVW	addr+0(FP), R0		// arg 1 - addr
    150 	MOVW	n+4(FP), R1		// arg 2 - len
    151 	MOVW	flags+8(FP), R2		// arg 2 - flags
    152 	MOVW	$75, R12		// sys_madvise
    153 	SWI	$0
    154 	MOVW.CS	$0, R8			// crash on syscall failure
    155 	MOVW.CS	R8, (R8)
    156 	RET
    157 
    158 TEXT runtimesetitimer(SB),NOSPLIT,$0
    159 	MOVW	mode+0(FP), R0		// arg 1 - mode
    160 	MOVW	new+4(FP), R1		// arg 2 - new value
    161 	MOVW	old+8(FP), R2		// arg 3 - old value
    162 	MOVW	$69, R12		// sys_setitimer
    163 	SWI	$0
    164 	RET
    165 
    166 // func walltime() (sec int64, nsec int32)
    167 TEXT runtimewalltime(SB), NOSPLIT, $32
    168 	MOVW	CLOCK_REALTIME, R0	// arg 1 - clock_id
    169 	MOVW	$8(R13), R1		// arg 2 - tp
    170 	MOVW	$87, R12		// sys_clock_gettime
    171 	SWI	$0
    172 
    173 	MOVW	8(R13), R0		// sec - l32
    174 	MOVW	12(R13), R1		// sec - h32
    175 	MOVW	16(R13), R2		// nsec
    176 
    177 	MOVW	R0, sec_lo+0(FP)
    178 	MOVW	R1, sec_hi+4(FP)
    179 	MOVW	R2, nsec+8(FP)
    180 
    181 	RET
    182 
    183 // int64 nanotime(void) so really
    184 // void nanotime(int64 *nsec)
    185 TEXT runtimenanotime(SB),NOSPLIT,$32
    186 	MOVW	CLOCK_MONOTONIC, R0	// arg 1 - clock_id
    187 	MOVW	$8(R13), R1		// arg 2 - tp
    188 	MOVW	$87, R12		// sys_clock_gettime
    189 	SWI	$0
    190 
    191 	MOVW	8(R13), R0		// sec - l32
    192 	MOVW	12(R13), R4		// sec - h32
    193 	MOVW	16(R13), R2		// nsec
    194 
    195 	MOVW	$1000000000, R3
    196 	MULLU	R0, R3, (R1, R0)
    197 	MUL	R3, R4
    198 	ADD.S	R2, R0
    199 	ADC	R4, R1
    200 
    201 	MOVW	R0, ret_lo+0(FP)
    202 	MOVW	R1, ret_hi+4(FP)
    203 	RET
    204 
    205 TEXT runtimesigaction(SB),NOSPLIT,$0
    206 	MOVW	sig+0(FP), R0		// arg 1 - signum
    207 	MOVW	new+4(FP), R1		// arg 2 - new sigaction
    208 	MOVW	old+8(FP), R2		// arg 3 - old sigaction
    209 	MOVW	$46, R12		// sys_sigaction
    210 	SWI	$0
    211 	MOVW.CS	$3, R8			// crash on syscall failure
    212 	MOVW.CS	R8, (R8)
    213 	RET
    214 
    215 TEXT runtimeobsdsigprocmask(SB),NOSPLIT,$0
    216 	MOVW	how+0(FP), R0		// arg 1 - mode
    217 	MOVW	new+4(FP), R1		// arg 2 - new
    218 	MOVW	$48, R12		// sys_sigprocmask
    219 	SWI	$0
    220 	MOVW.CS	$3, R8			// crash on syscall failure
    221 	MOVW.CS	R8, (R8)
    222 	MOVW	R0, ret+8(FP)
    223 	RET
    224 
    225 TEXT runtimesigfwd(SB),NOSPLIT,$0-16
    226 	MOVW	sig+4(FP), R0
    227 	MOVW	info+8(FP), R1
    228 	MOVW	ctx+12(FP), R2
    229 	MOVW	fn+0(FP), R11
    230 	MOVW	R13, R4
    231 	SUB	$24, R13
    232 	BIC	$0x7, R13 // alignment for ELF ABI
    233 	BL	(R11)
    234 	MOVW	R4, R13
    235 	RET
    236 
    237 TEXT runtimesigtramp(SB),NOSPLIT,$12
    238 	// If called from an external code context, g will not be set.
    239 	// Save R0, since runtimeload_g will clobber it.
    240 	MOVW	R0, 4(R13)		// signum
    241 	MOVB	runtimeiscgo(SB), R0
    242 	CMP	$0, R0
    243 	BL.NE	runtimeload_g(SB)
    244 
    245 	MOVW	R1, 8(R13)
    246 	MOVW	R2, 12(R13)
    247 	BL	runtimesigtrampgo(SB)
    248 	RET
    249 
    250 // int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
    251 TEXT runtimetfork(SB),NOSPLIT,$0
    252 
    253 	// Copy mp, gp and fn off parent stack for use by child.
    254 	MOVW	mm+8(FP), R4
    255 	MOVW	gg+12(FP), R5
    256 	MOVW	fn+16(FP), R6
    257 
    258 	MOVW	param+0(FP), R0		// arg 1 - param
    259 	MOVW	psize+4(FP), R1		// arg 2 - psize
    260 	MOVW	$8, R12			// sys___tfork
    261 	SWI	$0
    262 
    263 	// Return if syscall failed.
    264 	B.CC	4(PC)
    265 	RSB	$0, R0
    266 	MOVW	R0, ret+20(FP)
    267 	RET
    268 
    269 	// In parent, return.
    270 	CMP	$0, R0
    271 	BEQ	3(PC)
    272 	MOVW	R0, ret+20(FP)
    273 	RET
    274 
    275 	// Initialise m, g.
    276 	MOVW	R5, g
    277 	MOVW	R4, g_m(g)
    278 
    279 	// Paranoia; check that stack splitting code works.
    280 	BL	runtimeemptyfunc(SB)
    281 
    282 	// Call fn.
    283 	BL	(R6)
    284 
    285 	// fn should never return.
    286 	MOVW	$2, R8			// crash if reached
    287 	MOVW	R8, (R8)
    288 	RET
    289 
    290 TEXT runtimesigaltstack(SB),NOSPLIT,$0
    291 	MOVW	new+0(FP), R0		// arg 1 - new sigaltstack
    292 	MOVW	old+4(FP), R1		// arg 2 - old sigaltstack
    293 	MOVW	$288, R12		// sys_sigaltstack
    294 	SWI	$0
    295 	MOVW.CS	$0, R8			// crash on syscall failure
    296 	MOVW.CS	R8, (R8)
    297 	RET
    298 
    299 TEXT runtimeosyield(SB),NOSPLIT,$0
    300 	MOVW	$298, R12		// sys_sched_yield
    301 	SWI	$0
    302 	RET
    303 
    304 TEXT runtimethrsleep(SB),NOSPLIT,$4
    305 	MOVW	ident+0(FP), R0		// arg 1 - ident
    306 	MOVW	clock_id+4(FP), R1	// arg 2 - clock_id
    307 	MOVW	tsp+8(FP), R2		// arg 3 - tsp
    308 	MOVW	lock+12(FP), R3		// arg 4 - lock
    309 	MOVW	abort+16(FP), R4	// arg 5 - abort (on stack)
    310 	MOVW	R4, 4(R13)
    311 	ADD	$4, R13
    312 	MOVW	$94, R12		// sys___thrsleep
    313 	SWI	$0
    314 	SUB	$4, R13
    315 	MOVW	R0, ret+20(FP)
    316 	RET
    317 
    318 TEXT runtimethrwakeup(SB),NOSPLIT,$0
    319 	MOVW	ident+0(FP), R0		// arg 1 - ident
    320 	MOVW	n+4(FP), R1		// arg 2 - n
    321 	MOVW	$301, R12		// sys___thrwakeup
    322 	SWI	$0
    323 	MOVW	R0, ret+8(FP)
    324 	RET
    325 
    326 TEXT runtimesysctl(SB),NOSPLIT,$8
    327 	MOVW	mib+0(FP), R0		// arg 1 - mib
    328 	MOVW	miblen+4(FP), R1	// arg 2 - miblen
    329 	MOVW	out+8(FP), R2		// arg 3 - out
    330 	MOVW	size+12(FP), R3		// arg 4 - size
    331 	MOVW	dst+16(FP), R4		// arg 5 - dest (on stack)
    332 	MOVW	R4, 4(R13)
    333 	MOVW	ndst+20(FP), R5		// arg 6 - newlen (on stack)
    334 	MOVW	R5, 8(R13)
    335 	ADD	$4, R13
    336 	MOVW	$202, R12		// sys___sysctl
    337 	SWI	$0
    338 	SUB	$4, R13
    339 	MOVW.CC	$0, R0
    340 	RSB.CS	$0, R0
    341 	MOVW	R0, ret+24(FP)
    342 	RET
    343 
    344 // int32 runtimekqueue(void);
    345 TEXT runtimekqueue(SB),NOSPLIT,$0
    346 	MOVW	$269, R12		// sys_kqueue
    347 	SWI	$0
    348 	RSB.CS	$0, R0
    349 	MOVW	R0, ret+0(FP)
    350 	RET
    351 
    352 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
    353 TEXT runtimekevent(SB),NOSPLIT,$8
    354 	MOVW	kq+0(FP), R0		// arg 1 - kq
    355 	MOVW	ch+4(FP), R1		// arg 2 - changelist
    356 	MOVW	nch+8(FP), R2		// arg 3 - nchanges
    357 	MOVW	ev+12(FP), R3		// arg 4 - eventlist
    358 	MOVW	nev+16(FP), R4		// arg 5 - nevents (on stack)
    359 	MOVW	R4, 4(R13)
    360 	MOVW	ts+20(FP), R5		// arg 6 - timeout (on stack)
    361 	MOVW	R5, 8(R13)
    362 	ADD	$4, R13
    363 	MOVW	$72, R12		// sys_kevent
    364 	SWI	$0
    365 	RSB.CS	$0, R0
    366 	SUB	$4, R13
    367 	MOVW	R0, ret+24(FP)
    368 	RET
    369 
    370 // func closeonexec(fd int32)
    371 TEXT runtimecloseonexec(SB),NOSPLIT,$0
    372 	MOVW	fd+0(FP), R0		// arg 1 - fd
    373 	MOVW	$2, R1			// arg 2 - cmd (F_SETFD)
    374 	MOVW	$1, R2			// arg 3 - arg (FD_CLOEXEC)
    375 	MOVW	$92, R12		// sys_fcntl
    376 	SWI	$0
    377 	RET
    378 
    379 TEXT publicationBarrier(SB),NOSPLIT,$-4-0
    380 	B	runtimearmPublicationBarrier(SB)
    381 
    382 // TODO(jsing): Implement.
    383 TEXT runtimeread_tls_fallback(SB),NOSPLIT,$-4
    384 	MOVW	$5, R0
    385 	MOVW	R0, (R0)
    386 	RET
    387