Home | History | Annotate | Download | only in runtime
      1 // Copyright 2012 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, FreeBSD
      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 // for EABI, as we don't support OABI
     14 #define SYS_BASE 0x0
     15 
     16 #define SYS_exit (SYS_BASE + 1)
     17 #define SYS_read (SYS_BASE + 3)
     18 #define SYS_write (SYS_BASE + 4)
     19 #define SYS_open (SYS_BASE + 5)
     20 #define SYS_close (SYS_BASE + 6)
     21 #define SYS_getpid (SYS_BASE + 20)
     22 #define SYS_kill (SYS_BASE + 37)
     23 #define SYS_sigaltstack (SYS_BASE + 53)
     24 #define SYS_munmap (SYS_BASE + 73)
     25 #define SYS_madvise (SYS_BASE + 75)
     26 #define SYS_setitimer (SYS_BASE + 83)
     27 #define SYS_fcntl (SYS_BASE + 92)
     28 #define SYS_getrlimit (SYS_BASE + 194)
     29 #define SYS___sysctl (SYS_BASE + 202)
     30 #define SYS_nanosleep (SYS_BASE + 240)
     31 #define SYS_clock_gettime (SYS_BASE + 232)
     32 #define SYS_sched_yield (SYS_BASE + 331)
     33 #define SYS_sigprocmask (SYS_BASE + 340)
     34 #define SYS_kqueue (SYS_BASE + 362)
     35 #define SYS_kevent (SYS_BASE + 363)
     36 #define SYS_sigaction (SYS_BASE + 416)
     37 #define SYS_thr_exit (SYS_BASE + 431)
     38 #define SYS_thr_self (SYS_BASE + 432)
     39 #define SYS_thr_kill (SYS_BASE + 433)
     40 #define SYS__umtx_op (SYS_BASE + 454)
     41 #define SYS_thr_new (SYS_BASE + 455)
     42 #define SYS_mmap (SYS_BASE + 477)
     43 #define SYS_cpuset_getaffinity (SYS_BASE + 487)
     44 
     45 TEXT runtimesys_umtx_op(SB),NOSPLIT,$0
     46 	MOVW addr+0(FP), R0
     47 	MOVW mode+4(FP), R1
     48 	MOVW val+8(FP), R2
     49 	MOVW uaddr1+12(FP), R3
     50 	ADD $20, R13 // arg 5 is passed on stack
     51 	MOVW $SYS__umtx_op, R7
     52 	SWI $0
     53 	SUB $20, R13
     54 	// BCS error
     55 	MOVW	R0, ret+20(FP)
     56 	RET
     57 
     58 TEXT runtimethr_new(SB),NOSPLIT,$0
     59 	MOVW param+0(FP), R0
     60 	MOVW size+4(FP), R1
     61 	MOVW $SYS_thr_new, R7
     62 	SWI $0
     63 	RET
     64 
     65 TEXT runtimethr_start(SB),NOSPLIT,$0
     66 	// set up g
     67 	MOVW m_g0(R0), g
     68 	MOVW R0, g_m(g)
     69 	BL runtimeemptyfunc(SB) // fault if stack check is wrong
     70 	BL runtimemstart(SB)
     71 
     72 	MOVW $2, R8  // crash (not reached)
     73 	MOVW R8, (R8)
     74 	RET
     75 
     76 // Exit the entire program (like C exit)
     77 TEXT runtimeexit(SB),NOSPLIT,$-8
     78 	MOVW code+0(FP), R0	// arg 1 exit status
     79 	MOVW $SYS_exit, R7
     80 	SWI $0
     81 	MOVW.CS $0, R8 // crash on syscall failure
     82 	MOVW.CS R8, (R8)
     83 	RET
     84 
     85 // func exitThread(wait *uint32)
     86 TEXT runtimeexitThread(SB),NOSPLIT,$0-4
     87 	MOVW	wait+0(FP), R0
     88 	// We're done using the stack.
     89 	MOVW	$0, R2
     90 storeloop:
     91 	LDREX	(R0), R4          // loads R4
     92 	STREX	R2, (R0), R1      // stores R2
     93 	CMP	$0, R1
     94 	BNE	storeloop
     95 	MOVW	$0, R0		// arg 1 long *state
     96 	MOVW	$SYS_thr_exit, R7
     97 	SWI	$0
     98 	MOVW.CS	$0, R8 // crash on syscall failure
     99 	MOVW.CS	R8, (R8)
    100 	JMP	0(PC)
    101 
    102 TEXT runtimeopen(SB),NOSPLIT,$-8
    103 	MOVW name+0(FP), R0	// arg 1 name
    104 	MOVW mode+4(FP), R1	// arg 2 mode
    105 	MOVW perm+8(FP), R2	// arg 3 perm
    106 	MOVW $SYS_open, R7
    107 	SWI $0
    108 	MOVW.CS	$-1, R0
    109 	MOVW	R0, ret+12(FP)
    110 	RET
    111 
    112 TEXT runtimeread(SB),NOSPLIT,$-8
    113 	MOVW fd+0(FP), R0	// arg 1 fd
    114 	MOVW p+4(FP), R1	// arg 2 buf
    115 	MOVW n+8(FP), R2	// arg 3 count
    116 	MOVW $SYS_read, R7
    117 	SWI $0
    118 	MOVW.CS	$-1, R0
    119 	MOVW	R0, ret+12(FP)
    120 	RET
    121 
    122 TEXT runtimewrite(SB),NOSPLIT,$-8
    123 	MOVW fd+0(FP), R0	// arg 1 fd
    124 	MOVW p+4(FP), R1	// arg 2 buf
    125 	MOVW n+8(FP), R2	// arg 3 count
    126 	MOVW $SYS_write, R7
    127 	SWI $0
    128 	MOVW.CS	$-1, R0
    129 	MOVW	R0, ret+12(FP)
    130 	RET
    131 
    132 TEXT runtimeclosefd(SB),NOSPLIT,$-8
    133 	MOVW fd+0(FP), R0	// arg 1 fd
    134 	MOVW $SYS_close, R7
    135 	SWI $0
    136 	MOVW.CS	$-1, R0
    137 	MOVW	R0, ret+4(FP)
    138 	RET
    139 
    140 TEXT runtimegetrlimit(SB),NOSPLIT,$-8
    141 	MOVW kind+0(FP), R0
    142 	MOVW limit+4(FP), R1
    143 	MOVW $SYS_getrlimit, R7
    144 	SWI $0
    145 	MOVW	R0, ret+8(FP)
    146 	RET
    147 
    148 TEXT runtimeraise(SB),NOSPLIT,$8
    149 	// thr_self(&4(R13))
    150 	MOVW $4(R13), R0 // arg 1 &4(R13)
    151 	MOVW $SYS_thr_self, R7
    152 	SWI $0
    153 	// thr_kill(self, SIGPIPE)
    154 	MOVW 4(R13), R0	// arg 1 id
    155 	MOVW sig+0(FP), R1	// arg 2 - signal
    156 	MOVW $SYS_thr_kill, R7
    157 	SWI $0
    158 	RET
    159 
    160 TEXT runtimeraiseproc(SB),NOSPLIT,$0
    161 	// getpid
    162 	MOVW $SYS_getpid, R7
    163 	SWI $0
    164 	// kill(self, sig)
    165 				// arg 1 - pid, now in R0
    166 	MOVW sig+0(FP), R1	// arg 2 - signal
    167 	MOVW $SYS_kill, R7
    168 	SWI $0
    169 	RET
    170 
    171 TEXT runtimesetitimer(SB), NOSPLIT, $-8
    172 	MOVW mode+0(FP), R0
    173 	MOVW new+4(FP), R1
    174 	MOVW old+8(FP), R2
    175 	MOVW $SYS_setitimer, R7
    176 	SWI $0
    177 	RET
    178 
    179 // func walltime() (sec int64, nsec int32)
    180 TEXT runtimewalltime(SB), NOSPLIT, $32
    181 	MOVW $0, R0 // CLOCK_REALTIME
    182 	MOVW $8(R13), R1
    183 	MOVW $SYS_clock_gettime, R7
    184 	SWI $0
    185 
    186 	MOVW 8(R13), R0 // sec.low
    187 	MOVW 12(R13), R1 // sec.high
    188 	MOVW 16(R13), R2 // nsec
    189 
    190 	MOVW R0, sec_lo+0(FP)
    191 	MOVW R1, sec_hi+4(FP)
    192 	MOVW R2, nsec+8(FP)
    193 	RET
    194 
    195 // int64 nanotime(void) so really
    196 // void nanotime(int64 *nsec)
    197 TEXT runtimenanotime(SB), NOSPLIT, $32
    198 	// We can use CLOCK_MONOTONIC_FAST here when we drop
    199 	// support for FreeBSD 8-STABLE.
    200 	MOVW $4, R0 // CLOCK_MONOTONIC
    201 	MOVW $8(R13), R1
    202 	MOVW $SYS_clock_gettime, R7
    203 	SWI $0
    204 
    205 	MOVW 8(R13), R0 // sec.low
    206 	MOVW 12(R13), R4 // sec.high
    207 	MOVW 16(R13), R2 // nsec
    208 
    209 	MOVW $1000000000, R3
    210 	MULLU R0, R3, (R1, R0)
    211 	MUL R3, R4
    212 	ADD.S R2, R0
    213 	ADC R4, R1
    214 
    215 	MOVW R0, ret_lo+0(FP)
    216 	MOVW R1, ret_hi+4(FP)
    217 	RET
    218 
    219 TEXT runtimesigaction(SB),NOSPLIT,$-8
    220 	MOVW sig+0(FP), R0		// arg 1 sig
    221 	MOVW new+4(FP), R1		// arg 2 act
    222 	MOVW old+8(FP), R2		// arg 3 oact
    223 	MOVW $SYS_sigaction, R7
    224 	SWI $0
    225 	MOVW.CS $0, R8 // crash on syscall failure
    226 	MOVW.CS R8, (R8)
    227 	RET
    228 
    229 TEXT runtimesigtramp(SB),NOSPLIT,$12
    230 	// this might be called in external code context,
    231 	// where g is not set.
    232 	// first save R0, because runtimeload_g will clobber it
    233 	MOVW	R0, 4(R13) // signum
    234 	MOVB	runtimeiscgo(SB), R0
    235 	CMP 	$0, R0
    236 	BL.NE	runtimeload_g(SB)
    237 
    238 	MOVW	R1, 8(R13)
    239 	MOVW	R2, 12(R13)
    240 	BL	runtimesigtrampgo(SB)
    241 	RET
    242 
    243 TEXT runtimemmap(SB),NOSPLIT,$16
    244 	MOVW addr+0(FP), R0		// arg 1 addr
    245 	MOVW n+4(FP), R1		// arg 2 len
    246 	MOVW prot+8(FP), R2		// arg 3 prot
    247 	MOVW flags+12(FP), R3		// arg 4 flags
    248 	// arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack
    249 	// note the C runtime only passes the 32-bit offset_lo to us
    250 	MOVW fd+16(FP), R4		// arg 5
    251 	MOVW R4, 4(R13)
    252 	MOVW off+20(FP), R5		// arg 6 lower 32-bit
    253 	// the word at 8(R13) is skipped due to 64-bit argument alignment.
    254 	MOVW R5, 12(R13)
    255 	MOVW $0, R6 		// higher 32-bit for arg 6
    256 	MOVW R6, 16(R13)
    257 	ADD $4, R13
    258 	MOVW $SYS_mmap, R7
    259 	SWI $0
    260 	SUB $4, R13
    261 	MOVW $0, R1
    262 	MOVW.CS R0, R1		// if failed, put in R1
    263 	MOVW.CS $0, R0
    264 	MOVW	R0, p+24(FP)
    265 	MOVW	R1, err+28(FP)
    266 	RET
    267 
    268 TEXT runtimemunmap(SB),NOSPLIT,$0
    269 	MOVW addr+0(FP), R0		// arg 1 addr
    270 	MOVW n+4(FP), R1		// arg 2 len
    271 	MOVW $SYS_munmap, R7
    272 	SWI $0
    273 	MOVW.CS $0, R8 // crash on syscall failure
    274 	MOVW.CS R8, (R8)
    275 	RET
    276 
    277 TEXT runtimemadvise(SB),NOSPLIT,$0
    278 	MOVW addr+0(FP), R0		// arg 1 addr
    279 	MOVW n+4(FP), R1		// arg 2 len
    280 	MOVW flags+8(FP), R2		// arg 3 flags
    281 	MOVW $SYS_madvise, R7
    282 	SWI $0
    283 	// ignore failure - maybe pages are locked
    284 	RET
    285 
    286 TEXT runtimesigaltstack(SB),NOSPLIT,$-8
    287 	MOVW new+0(FP), R0
    288 	MOVW old+4(FP), R1
    289 	MOVW $SYS_sigaltstack, R7
    290 	SWI $0
    291 	MOVW.CS $0, R8 // crash on syscall failure
    292 	MOVW.CS R8, (R8)
    293 	RET
    294 
    295 TEXT runtimesigfwd(SB),NOSPLIT,$0-16
    296 	MOVW	sig+4(FP), R0
    297 	MOVW	info+8(FP), R1
    298 	MOVW	ctx+12(FP), R2
    299 	MOVW	fn+0(FP), R11
    300 	MOVW	R13, R4
    301 	SUB	$24, R13
    302 	BIC	$0x7, R13 // alignment for ELF ABI
    303 	BL	(R11)
    304 	MOVW	R4, R13
    305 	RET
    306 
    307 TEXT runtimeusleep(SB),NOSPLIT,$16
    308 	MOVW usec+0(FP), R0
    309 	CALL runtimeusplitR0(SB)
    310 	// 0(R13) is the saved LR, don't use it
    311 	MOVW R0, 4(R13) // tv_sec.low
    312 	MOVW $0, R0
    313 	MOVW R0, 8(R13) // tv_sec.high
    314 	MOVW $1000, R2
    315 	MUL R1, R2
    316 	MOVW R2, 12(R13) // tv_nsec
    317 
    318 	MOVW $4(R13), R0 // arg 1 - rqtp
    319 	MOVW $0, R1      // arg 2 - rmtp
    320 	MOVW $SYS_nanosleep, R7
    321 	SWI $0
    322 	RET
    323 
    324 TEXT runtimesysctl(SB),NOSPLIT,$0
    325 	MOVW mib+0(FP), R0	// arg 1 - name
    326 	MOVW miblen+4(FP), R1	// arg 2 - namelen
    327 	MOVW out+8(FP), R2	// arg 3 - old
    328 	MOVW size+12(FP), R3	// arg 4 - oldlenp
    329 	// arg 5 (newp) and arg 6 (newlen) are passed on stack
    330 	ADD $20, R13
    331 	MOVW $SYS___sysctl, R7
    332 	SWI $0
    333 	SUB.CS $0, R0, R0
    334 	SUB $20, R13
    335 	MOVW	R0, ret+24(FP)
    336 	RET
    337 
    338 TEXT runtimeosyield(SB),NOSPLIT,$-4
    339 	MOVW $SYS_sched_yield, R7
    340 	SWI $0
    341 	RET
    342 
    343 TEXT runtimesigprocmask(SB),NOSPLIT,$0
    344 	MOVW how+0(FP), R0	// arg 1 - how
    345 	MOVW new+4(FP), R1	// arg 2 - set
    346 	MOVW old+8(FP), R2	// arg 3 - oset
    347 	MOVW $SYS_sigprocmask, R7
    348 	SWI $0
    349 	MOVW.CS $0, R8 // crash on syscall failure
    350 	MOVW.CS R8, (R8)
    351 	RET
    352 
    353 // int32 runtimekqueue(void)
    354 TEXT runtimekqueue(SB),NOSPLIT,$0
    355 	MOVW $SYS_kqueue, R7
    356 	SWI $0
    357 	RSB.CS $0, R0
    358 	MOVW	R0, ret+0(FP)
    359 	RET
    360 
    361 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
    362 TEXT runtimekevent(SB),NOSPLIT,$0
    363 	MOVW kq+0(FP), R0	// kq
    364 	MOVW ch+4(FP), R1	// changelist
    365 	MOVW nch+8(FP), R2	// nchanges
    366 	MOVW ev+12(FP), R3	// eventlist
    367 	ADD $20, R13	// pass arg 5 and 6 on stack
    368 	MOVW $SYS_kevent, R7
    369 	SWI $0
    370 	RSB.CS $0, R0
    371 	SUB $20, R13
    372 	MOVW	R0, ret+24(FP)
    373 	RET
    374 
    375 // void runtimecloseonexec(int32 fd)
    376 TEXT runtimecloseonexec(SB),NOSPLIT,$0
    377 	MOVW fd+0(FP), R0	// fd
    378 	MOVW $2, R1	// F_SETFD
    379 	MOVW $1, R2	// FD_CLOEXEC
    380 	MOVW $SYS_fcntl, R7
    381 	SWI $0
    382 	RET
    383 
    384 // TODO: this is only valid for ARMv7+
    385 TEXT publicationBarrier(SB),NOSPLIT,$-4-0
    386 	B	runtimearmPublicationBarrier(SB)
    387 
    388 // TODO(minux): this only supports ARMv6K+.
    389 TEXT runtimeread_tls_fallback(SB),NOSPLIT,$-4
    390 	WORD $0xee1d0f70 // mrc p15, 0, r0, c13, c0, 3
    391 	RET
    392 
    393 // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
    394 TEXT runtimecpuset_getaffinity(SB), NOSPLIT, $0-28
    395 	MOVW	level+0(FP), R0
    396 	MOVW	which+4(FP), R1
    397 	MOVW	id_lo+8(FP), R2
    398 	MOVW	id_hi+12(FP), R3
    399 	ADD	$20, R13	// Pass size and mask on stack.
    400 	MOVW	$SYS_cpuset_getaffinity, R7
    401 	SWI	$0
    402 	RSB.CS	$0, R0
    403 	SUB	$20, R13
    404 	MOVW	R0, ret+24(FP)
    405 	RET
    406