1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
|
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// System calls and other sys.stuff for ARM, NetBSD
// /usr/src/sys/kern/syscalls.master for syscall numbers.
//
#include "zasm_GOOS_GOARCH.h"
#include "textflag.h"
// Exit the entire program (like C exit)
TEXT runtime·exit(SB),NOSPLIT,$-4
MOVW 0(FP), R0 // arg 1 exit status
SWI $0xa00001
MOVW.CS $0, R8 // crash on syscall failure
MOVW.CS R8, (R8)
RET
TEXT runtime·exit1(SB),NOSPLIT,$-4
SWI $0xa00136 // sys__lwp_exit
MOVW $1, R8 // crash
MOVW R8, (R8)
RET
TEXT runtime·open(SB),NOSPLIT,$-8
MOVW 0(FP), R0
MOVW 4(FP), R1
MOVW 8(FP), R2
SWI $0xa00005
MOVW R0, ret+12(FP)
RET
TEXT runtime·close(SB),NOSPLIT,$-8
MOVW 0(FP), R0
SWI $0xa00006
MOVW R0, ret+4(FP)
RET
TEXT runtime·read(SB),NOSPLIT,$-8
MOVW 0(FP), R0
MOVW 4(FP), R1
MOVW 8(FP), R2
SWI $0xa00003
MOVW R0, ret+12(FP)
RET
TEXT runtime·write(SB),NOSPLIT,$-4
MOVW 0(FP), R0 // arg 1 - fd
MOVW 4(FP), R1 // arg 2 - buf
MOVW 8(FP), R2 // arg 3 - nbyte
SWI $0xa00004 // sys_write
MOVW R0, ret+12(FP)
RET
// int32 lwp_create(void *context, uintptr flags, void *lwpid)
TEXT runtime·lwp_create(SB),NOSPLIT,$0
MOVW ctxt+0(FP), R0
MOVW flags+4(FP), R1
MOVW lwpid+8(FP), R2
SWI $0xa00135 // sys__lwp_create
MOVW R0, ret+12(FP)
RET
TEXT runtime·osyield(SB),NOSPLIT,$0
SWI $0xa0015e // sys_sched_yield
RET
TEXT runtime·lwp_park(SB),NOSPLIT,$0
MOVW 0(FP), R0 // arg 1 - abstime
MOVW 4(FP), R1 // arg 2 - unpark
MOVW 8(FP), R2 // arg 3 - hint
MOVW 12(FP), R3 // arg 4 - unparkhint
SWI $0xa001b2 // sys__lwp_park
MOVW R0, ret+16(FP)
RET
TEXT runtime·lwp_unpark(SB),NOSPLIT,$0
MOVW 0(FP), R0 // arg 1 - lwp
MOVW 4(FP), R1 // arg 2 - hint
SWI $0xa00141 // sys__lwp_unpark
MOVW R0, ret+8(FP)
RET
TEXT runtime·lwp_self(SB),NOSPLIT,$0
SWI $0xa00137 // sys__lwp_self
MOVW R0, ret+0(FP)
RET
TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
MOVW R0, g_m(R1)
MOVW R1, g
BL runtime·emptyfunc(SB) // fault if stack check is wrong
BL (R2)
MOVW $2, R8 // crash (not reached)
MOVW R8, (R8)
RET
TEXT runtime·usleep(SB),NOSPLIT,$16
MOVW usec+0(FP), R0
MOVW R0, R2
MOVW $1000000, R1
DIV R1, R0
// 0(R13) is the saved LR, don't use it
MOVW R0, 4(R13) // tv_sec.low
MOVW $0, R0
MOVW R0, 8(R13) // tv_sec.high
MOD R1, R2
MOVW $1000, R1
MUL R1, R2
MOVW R2, 12(R13) // tv_nsec
MOVW $4(R13), R0 // arg 1 - rqtp
MOVW $0, R1 // arg 2 - rmtp
SWI $0xa001ae // sys_nanosleep
RET
TEXT runtime·raise(SB),NOSPLIT,$16
SWI $0xa00137 // sys__lwp_self, the returned R0 is arg 1
MOVW sig+0(FP), R1 // arg 2 - signal
SWI $0xa0013e // sys__lwp_kill
RET
TEXT runtime·setitimer(SB),NOSPLIT,$-4
MOVW 0(FP), R0 // arg 1 - which
MOVW 4(FP), R1 // arg 2 - itv
MOVW 8(FP), R2 // arg 3 - oitv
SWI $0xa001a9 // sys_setitimer
RET
// func now() (sec int64, nsec int32)
TEXT time·now(SB), NOSPLIT, $32
MOVW $0, R0 // CLOCK_REALTIME
MOVW $8(R13), R1
SWI $0xa001ab // clock_gettime
MOVW 8(R13), R0 // sec.low
MOVW 12(R13), R1 // sec.high
MOVW 16(R13), R2 // nsec
MOVW R0, 0(FP)
MOVW R1, 4(FP)
MOVW R2, 8(FP)
RET
// int64 nanotime(void) so really
// void nanotime(int64 *nsec)
TEXT runtime·nanotime(SB), NOSPLIT, $32
MOVW $0, R0 // CLOCK_REALTIME
MOVW $8(R13), R1
SWI $0xa001ab // clock_gettime
MOVW 8(R13), R0 // sec.low
MOVW 12(R13), R4 // sec.high
MOVW 16(R13), R2 // nsec
MOVW $1000000000, R3
MULLU R0, R3, (R1, R0)
MUL R3, R4
ADD.S R2, R0
ADC R4, R1
MOVW R0, ret_lo+0(FP)
MOVW R1, ret_hi+4(FP)
RET
TEXT runtime·getcontext(SB),NOSPLIT,$-4
MOVW 0(FP), R0 // arg 1 - context
SWI $0xa00133 // sys_getcontext
MOVW.CS $0, R8 // crash on syscall failure
MOVW.CS R8, (R8)
RET
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
MOVW 0(FP), R0 // arg 1 - how
MOVW 4(FP), R1 // arg 2 - set
MOVW 8(FP), R2 // arg 3 - oset
SWI $0xa00125 // sys_sigprocmask
MOVW.CS $0, R8 // crash on syscall failure
MOVW.CS R8, (R8)
RET
TEXT runtime·sigreturn_tramp(SB),NOSPLIT,$-4
// on entry, SP points to siginfo, we add sizeof(ucontext)
// to SP to get a pointer to ucontext.
ADD $0x80, R13, R0 // 0x80 == sizeof(UcontextT)
SWI $0xa00134 // sys_setcontext
// something failed, we have to exit
MOVW $0x4242, R0 // magic return number
SWI $0xa00001 // sys_exit
B -2(PC) // continue exit
TEXT runtime·sigaction(SB),NOSPLIT,$4
MOVW 0(FP), R0 // arg 1 - signum
MOVW 4(FP), R1 // arg 2 - nsa
MOVW 8(FP), R2 // arg 3 - osa
MOVW $runtime·sigreturn_tramp(SB), R3 // arg 4 - tramp
MOVW $2, R4 // arg 5 - vers
MOVW R4, 4(R13)
ADD $4, R13 // pass arg 5 on stack
SWI $0xa00154 // sys___sigaction_sigtramp
SUB $4, R13
MOVW.CS $3, R8 // crash on syscall failure
MOVW.CS R8, (R8)
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$24
// this might be called in external code context,
// where g is not set.
// first save R0, because runtime·load_g will clobber it
MOVW R0, 4(R13) // signum
MOVB runtime·iscgo(SB), R0
CMP $0, R0
BL.NE runtime·load_g(SB)
CMP $0, g
BNE 4(PC)
// signal number is already prepared in 4(R13)
MOVW $runtime·badsignal(SB), R11
BL (R11)
RET
// save g
MOVW g, R4
MOVW g, 20(R13)
// g = m->signal
MOVW g_m(g), R8
MOVW m_gsignal(R8), g
// R0 is already saved
MOVW R1, 8(R13) // info
MOVW R2, 12(R13) // context
MOVW R4, 16(R13) // gp
BL runtime·sighandler(SB)
// restore g
MOVW 20(R13), g
RET
TEXT runtime·mmap(SB),NOSPLIT,$12
MOVW 0(FP), R0 // arg 1 - addr
MOVW 4(FP), R1 // arg 2 - len
MOVW 8(FP), R2 // arg 3 - prot
MOVW 12(FP), R3 // arg 4 - flags
// arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack
// note the C runtime only passes the 32-bit offset_lo to us
MOVW 16(FP), R4 // arg 5
MOVW R4, 4(R13)
MOVW 20(FP), R5 // arg 6 lower 32-bit
MOVW R5, 8(R13)
MOVW $0, R6 // higher 32-bit for arg 6
MOVW R6, 12(R13)
ADD $4, R13 // pass arg 5 and arg 6 on stack
SWI $0xa000c5 // sys_mmap
SUB $4, R13
MOVW R0, ret+24(FP)
RET
TEXT runtime·munmap(SB),NOSPLIT,$0
MOVW 0(FP), R0 // arg 1 - addr
MOVW 4(FP), R1 // arg 2 - len
SWI $0xa00049 // sys_munmap
MOVW.CS $0, R8 // crash on syscall failure
MOVW.CS R8, (R8)
RET
TEXT runtime·madvise(SB),NOSPLIT,$0
MOVW 0(FP), R0 // arg 1 - addr
MOVW 4(FP), R1 // arg 2 - len
MOVW 8(FP), R2 // arg 3 - behav
SWI $0xa0004b // sys_madvise
// ignore failure - maybe pages are locked
RET
TEXT runtime·sigaltstack(SB),NOSPLIT,$-4
MOVW 0(FP), R0 // arg 1 - nss
MOVW 4(FP), R1 // arg 2 - oss
SWI $0xa00119 // sys___sigaltstack14
MOVW.CS $0, R8 // crash on syscall failure
MOVW.CS R8, (R8)
RET
TEXT runtime·sysctl(SB),NOSPLIT,$8
MOVW 0(FP), R0 // arg 1 - name
MOVW 4(FP), R1 // arg 2 - namelen
MOVW 8(FP), R2 // arg 3 - oldp
MOVW 12(FP), R3 // arg 4 - oldlenp
MOVW 16(FP), R4 // arg 5 - newp
MOVW R4, 4(R13)
MOVW 20(FP), R4 // arg 6 - newlen
MOVW R4, 8(R13)
ADD $4, R13 // pass arg 5 and 6 on stack
SWI $0xa000ca // sys___sysctl
SUB $4, R13
MOVW R0, ret+24(FP)
RET
// int32 runtime·kqueue(void)
TEXT runtime·kqueue(SB),NOSPLIT,$0
SWI $0xa00158 // sys_kqueue
RSB.CS $0, R0
MOVW R0, ret+0(FP)
RET
// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
TEXT runtime·kevent(SB),NOSPLIT,$8
MOVW 0(FP), R0 // kq
MOVW 4(FP), R1 // changelist
MOVW 8(FP), R2 // nchanges
MOVW 12(FP), R3 // eventlist
MOVW 16(FP), R4 // nevents
MOVW R4, 4(R13)
MOVW 20(FP), R4 // timeout
MOVW R4, 8(R13)
ADD $4, R13 // pass arg 5 and 6 on stack
SWI $0xa001b3 // sys___kevent50
RSB.CS $0, R0
SUB $4, R13
MOVW R0, ret+24(FP)
RET
// void runtime·closeonexec(int32 fd)
TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVW 0(FP), R0 // fd
MOVW $2, R1 // F_SETFD
MOVW $1, R2 // FD_CLOEXEC
SWI $0xa0005c // sys_fcntl
RET
TEXT runtime·casp(SB),NOSPLIT,$0
B runtime·cas(SB)
// TODO(minux): this is only valid for ARMv6+
// bool armcas(int32 *val, int32 old, int32 new)
// Atomically:
// if(*val == old){
// *val = new;
// return 1;
// }else
// return 0;
TEXT runtime·cas(SB),NOSPLIT,$0
B runtime·armcas(SB)
TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
MOVM.WP [R1, R2, R3, R12], (R13)
SWI $0x00a0013c // _lwp_getprivate
MOVM.IAW (R13), [R1, R2, R3, R12]
RET
|