Home | History | Annotate | Download | only in runtime
      1 // Copyright 2013 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, NetBSD
      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 // Exit the entire program (like C exit)
     14 TEXT runtimeexit(SB),NOSPLIT,$-4
     15 	MOVW code+0(FP), R0	// arg 1 exit status
     16 	SWI $0xa00001
     17 	MOVW.CS $0, R8	// crash on syscall failure
     18 	MOVW.CS R8, (R8)
     19 	RET
     20 
     21 // func exitThread(wait *uint32)
     22 TEXT runtimeexitThread(SB),NOSPLIT,$0-4
     23 	MOVW wait+0(FP), R0
     24 	// We're done using the stack.
     25 	MOVW $0, R2
     26 storeloop:
     27 	LDREX (R0), R4          // loads R4
     28 	STREX R2, (R0), R1      // stores R2
     29 	CMP $0, R1
     30 	BNE storeloop
     31 	SWI $0xa00136	// sys__lwp_exit
     32 	MOVW $1, R8	// crash
     33 	MOVW R8, (R8)
     34 	JMP 0(PC)
     35 
     36 TEXT runtimeopen(SB),NOSPLIT,$-8
     37 	MOVW name+0(FP), R0
     38 	MOVW mode+4(FP), R1
     39 	MOVW perm+8(FP), R2
     40 	SWI $0xa00005
     41 	MOVW.CS	$-1, R0
     42 	MOVW	R0, ret+12(FP)
     43 	RET
     44 
     45 TEXT runtimeclosefd(SB),NOSPLIT,$-8
     46 	MOVW fd+0(FP), R0
     47 	SWI $0xa00006
     48 	MOVW.CS	$-1, R0
     49 	MOVW	R0, ret+4(FP)
     50 	RET
     51 
     52 TEXT runtimeread(SB),NOSPLIT,$-8
     53 	MOVW fd+0(FP), R0
     54 	MOVW p+4(FP), R1
     55 	MOVW n+8(FP), R2
     56 	SWI $0xa00003
     57 	MOVW.CS	$-1, R0
     58 	MOVW	R0, ret+12(FP)
     59 	RET
     60 
     61 TEXT runtimewrite(SB),NOSPLIT,$-4
     62 	MOVW	fd+0(FP), R0	// arg 1 - fd
     63 	MOVW	p+4(FP), R1	// arg 2 - buf
     64 	MOVW	n+8(FP), R2	// arg 3 - nbyte
     65 	SWI $0xa00004	// sys_write
     66 	MOVW.CS	$-1, R0
     67 	MOVW	R0, ret+12(FP)
     68 	RET
     69 
     70 // int32 lwp_create(void *context, uintptr flags, void *lwpid)
     71 TEXT runtimelwp_create(SB),NOSPLIT,$0
     72 	MOVW ctxt+0(FP), R0
     73 	MOVW flags+4(FP), R1
     74 	MOVW lwpid+8(FP), R2
     75 	SWI $0xa00135	// sys__lwp_create
     76 	MOVW	R0, ret+12(FP)
     77 	RET
     78 
     79 TEXT runtimeosyield(SB),NOSPLIT,$0
     80 	SWI $0xa0015e	// sys_sched_yield
     81 	RET
     82 
     83 TEXT runtimelwp_park(SB),NOSPLIT,$8
     84 	MOVW clockid+0(FP), R0		// arg 1 - clock_id
     85 	MOVW flags+4(FP), R1		// arg 2 - flags
     86 	MOVW ts+8(FP), R2		// arg 3 - ts
     87 	MOVW unpark+12(FP), R3		// arg 4 - unpark
     88 	MOVW hint+16(FP), R4		// arg 5 - hint
     89 	MOVW R4, 4(R13)
     90 	MOVW unparkhint+20(FP), R5	// arg 6 - unparkhint
     91 	MOVW R5, 8(R13)
     92 	SWI $0xa001de			// sys__lwp_park
     93 	MOVW	R0, ret+24(FP)
     94 	RET
     95 
     96 TEXT runtimelwp_unpark(SB),NOSPLIT,$0
     97 	MOVW	lwp+0(FP), R0	// arg 1 - lwp
     98 	MOVW	hint+4(FP), R1	// arg 2 - hint
     99 	SWI $0xa00141 // sys__lwp_unpark
    100 	MOVW	R0, ret+8(FP)
    101 	RET
    102 
    103 TEXT runtimelwp_self(SB),NOSPLIT,$0
    104 	SWI $0xa00137	// sys__lwp_self
    105 	MOVW	R0, ret+0(FP)
    106 	RET
    107 
    108 TEXT runtimelwp_tramp(SB),NOSPLIT,$0
    109 	MOVW R0, g_m(R1)
    110 	MOVW R1, g
    111 
    112 	BL runtimeemptyfunc(SB) // fault if stack check is wrong
    113 	BL (R2)
    114 	MOVW $2, R8  // crash (not reached)
    115 	MOVW R8, (R8)
    116 	RET
    117 
    118 TEXT runtimeusleep(SB),NOSPLIT,$16
    119 	MOVW usec+0(FP), R0
    120 	CALL runtimeusplitR0(SB)
    121 	// 0(R13) is the saved LR, don't use it
    122 	MOVW R0, 4(R13) // tv_sec.low
    123 	MOVW $0, R0
    124 	MOVW R0, 8(R13) // tv_sec.high
    125 	MOVW $1000, R2
    126 	MUL R1, R2
    127 	MOVW R2, 12(R13) // tv_nsec
    128 
    129 	MOVW $4(R13), R0 // arg 1 - rqtp
    130 	MOVW $0, R1      // arg 2 - rmtp
    131 	SWI $0xa001ae	// sys_nanosleep
    132 	RET
    133 
    134 TEXT runtimeraise(SB),NOSPLIT,$16
    135 	SWI $0xa00137	// sys__lwp_self, the returned R0 is arg 1
    136 	MOVW	sig+0(FP), R1	// arg 2 - signal
    137 	SWI $0xa0013e	// sys__lwp_kill
    138 	RET
    139 
    140 TEXT runtimeraiseproc(SB),NOSPLIT,$16
    141 	SWI $0xa00014	// sys_getpid, the returned R0 is arg 1
    142 	MOVW	sig+0(FP), R1	// arg 2 - signal
    143 	SWI $0xa00025	// sys_kill
    144 	RET
    145 
    146 TEXT runtimesetitimer(SB),NOSPLIT,$-4
    147 	MOVW mode+0(FP), R0	// arg 1 - which
    148 	MOVW new+4(FP), R1	// arg 2 - itv
    149 	MOVW old+8(FP), R2	// arg 3 - oitv
    150 	SWI $0xa001a9	// sys_setitimer
    151 	RET
    152 
    153 // func walltime() (sec int64, nsec int32)
    154 TEXT runtimewalltime(SB), NOSPLIT, $32
    155 	MOVW $0, R0	// CLOCK_REALTIME
    156 	MOVW $8(R13), R1
    157 	SWI $0xa001ab	// clock_gettime
    158 
    159 	MOVW 8(R13), R0	// sec.low
    160 	MOVW 12(R13), R1 // sec.high
    161 	MOVW 16(R13), R2 // nsec
    162 
    163 	MOVW R0, sec_lo+0(FP)
    164 	MOVW R1, sec_hi+4(FP)
    165 	MOVW R2, nsec+8(FP)
    166 	RET
    167 
    168 // int64 nanotime(void) so really
    169 // void nanotime(int64 *nsec)
    170 TEXT runtimenanotime(SB), NOSPLIT, $32
    171 	MOVW $3, R0 // CLOCK_MONOTONIC
    172 	MOVW $8(R13), R1
    173 	SWI $0xa001ab	// clock_gettime
    174 
    175 	MOVW 8(R13), R0 // sec.low
    176 	MOVW 12(R13), R4 // sec.high
    177 	MOVW 16(R13), R2 // nsec
    178 
    179 	MOVW $1000000000, R3
    180 	MULLU R0, R3, (R1, R0)
    181 	MUL R3, R4
    182 	ADD.S R2, R0
    183 	ADC R4, R1
    184 
    185 	MOVW R0, ret_lo+0(FP)
    186 	MOVW R1, ret_hi+4(FP)
    187 	RET
    188 
    189 TEXT runtimegetcontext(SB),NOSPLIT,$-4
    190 	MOVW ctxt+0(FP), R0	// arg 1 - context
    191 	SWI $0xa00133	// sys_getcontext
    192 	MOVW.CS $0, R8	// crash on syscall failure
    193 	MOVW.CS R8, (R8)
    194 	RET
    195 
    196 TEXT runtimesigprocmask(SB),NOSPLIT,$0
    197 	MOVW how+0(FP), R0	// arg 1 - how
    198 	MOVW new+4(FP), R1	// arg 2 - set
    199 	MOVW old+8(FP), R2	// arg 3 - oset
    200 	SWI $0xa00125	// sys_sigprocmask
    201 	MOVW.CS $0, R8	// crash on syscall failure
    202 	MOVW.CS R8, (R8)
    203 	RET
    204 
    205 TEXT runtimesigreturn_tramp(SB),NOSPLIT,$-4
    206 	// on entry, SP points to siginfo, we add sizeof(ucontext)
    207 	// to SP to get a pointer to ucontext.
    208 	ADD $0x80, R13, R0 // 0x80 == sizeof(UcontextT)
    209 	SWI $0xa00134	// sys_setcontext
    210 	// something failed, we have to exit
    211 	MOVW $0x4242, R0 // magic return number
    212 	SWI $0xa00001	// sys_exit
    213 	B -2(PC)	// continue exit
    214 
    215 TEXT runtimesigaction(SB),NOSPLIT,$4
    216 	MOVW sig+0(FP), R0	// arg 1 - signum
    217 	MOVW new+4(FP), R1	// arg 2 - nsa
    218 	MOVW old+8(FP), R2	// arg 3 - osa
    219 	MOVW $runtimesigreturn_tramp(SB), R3	// arg 4 - tramp
    220 	MOVW $2, R4	// arg 5 - vers
    221 	MOVW R4, 4(R13)
    222 	ADD $4, R13	// pass arg 5 on stack
    223 	SWI $0xa00154	// sys___sigaction_sigtramp
    224 	SUB $4, R13
    225 	MOVW.CS $3, R8	// crash on syscall failure
    226 	MOVW.CS R8, (R8)
    227 	RET
    228 
    229 TEXT runtimesigfwd(SB),NOSPLIT,$0-16
    230 	MOVW	sig+4(FP), R0
    231 	MOVW	info+8(FP), R1
    232 	MOVW	ctx+12(FP), R2
    233 	MOVW	fn+0(FP), R11
    234 	MOVW	R13, R4
    235 	SUB	$24, R13
    236 	BIC	$0x7, R13 // alignment for ELF ABI
    237 	BL	(R11)
    238 	MOVW	R4, R13
    239 	RET
    240 
    241 TEXT runtimesigtramp(SB),NOSPLIT,$12
    242 	// this might be called in external code context,
    243 	// where g is not set.
    244 	// first save R0, because runtimeload_g will clobber it
    245 	MOVW	R0, 4(R13) // signum
    246 	MOVB	runtimeiscgo(SB), R0
    247 	CMP 	$0, R0
    248 	BL.NE	runtimeload_g(SB)
    249 
    250 	MOVW	R1, 8(R13)
    251 	MOVW	R2, 12(R13)
    252 	BL	runtimesigtrampgo(SB)
    253 	RET
    254 
    255 TEXT runtimemmap(SB),NOSPLIT,$12
    256 	MOVW addr+0(FP), R0	// arg 1 - addr
    257 	MOVW n+4(FP), R1	// arg 2 - len
    258 	MOVW prot+8(FP), R2	// arg 3 - prot
    259 	MOVW flags+12(FP), R3	// arg 4 - flags
    260 	// arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack
    261 	// note the C runtime only passes the 32-bit offset_lo to us
    262 	MOVW fd+16(FP), R4		// arg 5
    263 	MOVW R4, 4(R13)
    264 	MOVW off+20(FP), R5		// arg 6 lower 32-bit
    265 	MOVW R5, 8(R13)
    266 	MOVW $0, R6 // higher 32-bit for arg 6
    267 	MOVW R6, 12(R13)
    268 	ADD $4, R13 // pass arg 5 and arg 6 on stack
    269 	SWI $0xa000c5	// sys_mmap
    270 	SUB $4, R13
    271 	MOVW	$0, R1
    272 	MOVW.CS R0, R1	// if error, move to R1
    273 	MOVW.CS $0, R0
    274 	MOVW	R0, p+24(FP)
    275 	MOVW	R1, err+28(FP)
    276 	RET
    277 
    278 TEXT runtimemunmap(SB),NOSPLIT,$0
    279 	MOVW addr+0(FP), R0	// arg 1 - addr
    280 	MOVW n+4(FP), R1	// arg 2 - len
    281 	SWI $0xa00049	// sys_munmap
    282 	MOVW.CS $0, R8	// crash on syscall failure
    283 	MOVW.CS R8, (R8)
    284 	RET
    285 
    286 TEXT runtimemadvise(SB),NOSPLIT,$0
    287 	MOVW addr+0(FP), R0	// arg 1 - addr
    288 	MOVW n+4(FP), R1	// arg 2 - len
    289 	MOVW flags+8(FP), R2	// arg 3 - behav
    290 	SWI $0xa0004b	// sys_madvise
    291 	// ignore failure - maybe pages are locked
    292 	RET
    293 
    294 TEXT runtimesigaltstack(SB),NOSPLIT,$-4
    295 	MOVW new+0(FP), R0	// arg 1 - nss
    296 	MOVW old+4(FP), R1	// arg 2 - oss
    297 	SWI $0xa00119	// sys___sigaltstack14
    298 	MOVW.CS $0, R8	// crash on syscall failure
    299 	MOVW.CS R8, (R8)
    300 	RET
    301 
    302 TEXT runtimesysctl(SB),NOSPLIT,$8
    303 	MOVW mib+0(FP), R0	// arg 1 - name
    304 	MOVW miblen+4(FP), R1	// arg 2 - namelen
    305 	MOVW out+8(FP), R2	// arg 3 - oldp
    306 	MOVW size+12(FP), R3	// arg 4 - oldlenp
    307 	MOVW dst+16(FP), R4	// arg 5 - newp
    308 	MOVW R4, 4(R13)
    309 	MOVW ndst+20(FP), R4	// arg 6 - newlen
    310 	MOVW R4, 8(R13)
    311 	ADD $4, R13	// pass arg 5 and 6 on stack
    312 	SWI $0xa000ca	// sys___sysctl
    313 	SUB $4, R13
    314 	MOVW	R0, ret+24(FP)
    315 	RET
    316 
    317 // int32 runtimekqueue(void)
    318 TEXT runtimekqueue(SB),NOSPLIT,$0
    319 	SWI $0xa00158	// sys_kqueue
    320 	RSB.CS $0, R0
    321 	MOVW	R0, ret+0(FP)
    322 	RET
    323 
    324 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
    325 TEXT runtimekevent(SB),NOSPLIT,$8
    326 	MOVW kq+0(FP), R0	// kq
    327 	MOVW ch+4(FP), R1	// changelist
    328 	MOVW nch+8(FP), R2	// nchanges
    329 	MOVW ev+12(FP), R3	// eventlist
    330 	MOVW nev+16(FP), R4	// nevents
    331 	MOVW R4, 4(R13)
    332 	MOVW ts+20(FP), R4	// timeout
    333 	MOVW R4, 8(R13)
    334 	ADD $4, R13	// pass arg 5 and 6 on stack
    335 	SWI $0xa001b3	// sys___kevent50
    336 	RSB.CS $0, R0
    337 	SUB $4, R13
    338 	MOVW	R0, ret+24(FP)
    339 	RET
    340 
    341 // void runtimecloseonexec(int32 fd)
    342 TEXT runtimecloseonexec(SB),NOSPLIT,$0
    343 	MOVW fd+0(FP), R0	// fd
    344 	MOVW $2, R1	// F_SETFD
    345 	MOVW $1, R2	// FD_CLOEXEC
    346 	SWI $0xa0005c	// sys_fcntl
    347 	RET
    348 
    349 // TODO: this is only valid for ARMv7+
    350 TEXT publicationBarrier(SB),NOSPLIT,$-4-0
    351 	B	runtimearmPublicationBarrier(SB)
    352 
    353 TEXT runtimeread_tls_fallback(SB),NOSPLIT,$-4
    354 	MOVM.WP [R1, R2, R3, R12], (R13)
    355 	SWI $0x00a0013c // _lwp_getprivate
    356 	MOVM.IAW    (R13), [R1, R2, R3, R12]
    357 	RET
    358