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