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