]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: NetBSD/ARM support
authorShenghou Ma <minux.ma@gmail.com>
Tue, 12 Feb 2013 17:00:04 +0000 (01:00 +0800)
committerShenghou Ma <minux.ma@gmail.com>
Tue, 12 Feb 2013 17:00:04 +0000 (01:00 +0800)
R=rsc, dave
CC=golang-dev
https://golang.org/cl/7289044

src/pkg/runtime/asm_arm.s
src/pkg/runtime/defs_netbsd_arm.h [new file with mode: 0644]
src/pkg/runtime/os_netbsd.h
src/pkg/runtime/rt0_netbsd_arm.s [new file with mode: 0644]
src/pkg/runtime/signal_netbsd_arm.c [new file with mode: 0644]
src/pkg/runtime/sys_netbsd_arm.s [new file with mode: 0644]
src/pkg/runtime/thread_netbsd.c

index 57df8c9c634b893a8433e0c9587dd38d84e0d2f0..9af5a8a0dfeaca6dc8cac20bc608d0c22245c077 100644 (file)
@@ -72,8 +72,15 @@ TEXT runtime·breakpoint(SB),7,$0
        WORD    $0xe1200071 // BKPT 0x0001
        RET
 
+GLOBL runtime·goarm(SB), $4
 TEXT runtime·asminit(SB),7,$0
-       // No per-thread init.
+       // disable runfast (flush-to-zero) mode of vfp if runtime.goarm > 5
+       MOVW runtime·goarm(SB), R11
+       CMP $5, R11
+       BLE 4(PC)
+       WORD $0xeef1ba10        // vmrs r11, fpscr
+       BIC $(1<<24), R11
+       WORD $0xeee1ba10        // vmsr fpscr, r11
        RET
 
 /*
diff --git a/src/pkg/runtime/defs_netbsd_arm.h b/src/pkg/runtime/defs_netbsd_arm.h
new file mode 100644 (file)
index 0000000..f67475c
--- /dev/null
@@ -0,0 +1,140 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_netbsd.go
+
+
+enum {
+       PROT_NONE       = 0x0,
+       PROT_READ       = 0x1,
+       PROT_WRITE      = 0x2,
+       PROT_EXEC       = 0x4,
+
+       MAP_ANON        = 0x1000,
+       MAP_PRIVATE     = 0x2,
+       MAP_FIXED       = 0x10,
+
+       MADV_FREE       = 0x6,
+
+       SA_SIGINFO      = 0x40,
+       SA_RESTART      = 0x2,
+       SA_ONSTACK      = 0x1,
+
+       EINTR   = 0x4,
+
+       SIGHUP          = 0x1,
+       SIGINT          = 0x2,
+       SIGQUIT         = 0x3,
+       SIGILL          = 0x4,
+       SIGTRAP         = 0x5,
+       SIGABRT         = 0x6,
+       SIGEMT          = 0x7,
+       SIGFPE          = 0x8,
+       SIGKILL         = 0x9,
+       SIGBUS          = 0xa,
+       SIGSEGV         = 0xb,
+       SIGSYS          = 0xc,
+       SIGPIPE         = 0xd,
+       SIGALRM         = 0xe,
+       SIGTERM         = 0xf,
+       SIGURG          = 0x10,
+       SIGSTOP         = 0x11,
+       SIGTSTP         = 0x12,
+       SIGCONT         = 0x13,
+       SIGCHLD         = 0x14,
+       SIGTTIN         = 0x15,
+       SIGTTOU         = 0x16,
+       SIGIO           = 0x17,
+       SIGXCPU         = 0x18,
+       SIGXFSZ         = 0x19,
+       SIGVTALRM       = 0x1a,
+       SIGPROF         = 0x1b,
+       SIGWINCH        = 0x1c,
+       SIGINFO         = 0x1d,
+       SIGUSR1         = 0x1e,
+       SIGUSR2         = 0x1f,
+
+       FPE_INTDIV      = 0x1,
+       FPE_INTOVF      = 0x2,
+       FPE_FLTDIV      = 0x3,
+       FPE_FLTOVF      = 0x4,
+       FPE_FLTUND      = 0x5,
+       FPE_FLTRES      = 0x6,
+       FPE_FLTINV      = 0x7,
+       FPE_FLTSUB      = 0x8,
+
+       BUS_ADRALN      = 0x1,
+       BUS_ADRERR      = 0x2,
+       BUS_OBJERR      = 0x3,
+
+       SEGV_MAPERR     = 0x1,
+       SEGV_ACCERR     = 0x2,
+
+       ITIMER_REAL     = 0x0,
+       ITIMER_VIRTUAL  = 0x1,
+       ITIMER_PROF     = 0x2,
+};
+
+typedef struct Sigaltstack Sigaltstack;
+typedef struct Sigset Sigset;
+typedef struct Siginfo Siginfo;
+typedef struct StackT StackT;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct McontextT McontextT;
+typedef struct UcontextT UcontextT;
+
+#pragma pack on
+
+struct Sigaltstack {
+       byte    *ss_sp;
+       uint32  ss_size;
+       int32   ss_flags;
+};
+struct Sigset {
+       uint32  __bits[4];
+};
+struct Siginfo {
+       int32   _signo;
+       int32   _code;
+       int32   _errno;
+       byte    _reason[20];
+};
+
+struct StackT {
+       byte    *ss_sp;
+       uint32  ss_size;
+       int32   ss_flags;
+};
+
+struct Timespec {
+       int64   tv_sec;
+       int32   tv_nsec;
+};
+struct Timeval {
+       int64   tv_sec;
+       int32   tv_usec;
+};
+struct Itimerval {
+       Timeval it_interval;
+       Timeval it_value;
+};
+
+struct McontextT {
+       uint32  __gregs[17];
+#ifdef __ARM_EABI__
+       byte    __fpu[4+8*32+4];
+#else
+       byte    __fpu[4+4*33+4];
+#endif
+       uint32  _mc_tlsbase;
+};
+struct UcontextT {
+       uint32  uc_flags;
+       UcontextT       *uc_link;
+       Sigset  uc_sigmask;
+       StackT  uc_stack;
+       McontextT       uc_mcontext;
+       int32   __uc_pad[2];
+};
+
+#pragma pack off
index 794b294ff519e7298d13fe3672ad2d56e2143048..09e68323505e75c3332ead306a4dff7ed23b4fbc 100644 (file)
@@ -24,3 +24,7 @@ int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
 
 #define        NSIG 33
 #define        SI_USER 0
+
+// From NetBSD's <sys/ucontext.h>
+#define _UC_SIGMASK    0x01
+#define _UC_CPU                0x04
diff --git a/src/pkg/runtime/rt0_netbsd_arm.s b/src/pkg/runtime/rt0_netbsd_arm.s
new file mode 100644 (file)
index 0000000..8c1588f
--- /dev/null
@@ -0,0 +1,8 @@
+// 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.
+
+// FreeBSD/NetBSD and Linux use the same linkage to main
+
+TEXT _rt0_arm_netbsd(SB),7,$-4
+       B _rt0_arm(SB)
diff --git a/src/pkg/runtime/signal_netbsd_arm.c b/src/pkg/runtime/signal_netbsd_arm.c
new file mode 100644 (file)
index 0000000..bc39a69
--- /dev/null
@@ -0,0 +1,197 @@
+// 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.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "signals_GOOS.h"
+#include "os_GOOS.h"
+
+#define r0     __gregs[0]
+#define r1     __gregs[1]
+#define r2     __gregs[2]
+#define r3     __gregs[3]
+#define r4     __gregs[4]
+#define r5     __gregs[5]
+#define r6     __gregs[6]
+#define r7     __gregs[7]
+#define r8     __gregs[8]
+#define r9     __gregs[9]
+#define r10    __gregs[10]
+#define r11    __gregs[11]
+#define r12    __gregs[12]
+#define r13    __gregs[13]
+#define r14    __gregs[14]
+#define r15    __gregs[15]
+#define cpsr   __gregs[16]
+
+void
+runtime·dumpregs(McontextT *r)
+{
+       runtime·printf("r0      %x\n", r->r0);
+       runtime·printf("r1      %x\n", r->r1);
+       runtime·printf("r2      %x\n", r->r2);
+       runtime·printf("r3      %x\n", r->r3);
+       runtime·printf("r4      %x\n", r->r4);
+       runtime·printf("r5      %x\n", r->r5);
+       runtime·printf("r6      %x\n", r->r6);
+       runtime·printf("r7      %x\n", r->r7);
+       runtime·printf("r8      %x\n", r->r8);
+       runtime·printf("r9      %x\n", r->r9);
+       runtime·printf("r10     %x\n", r->r10);
+       runtime·printf("fp      %x\n", r->r11);
+       runtime·printf("ip      %x\n", r->r12);
+       runtime·printf("sp      %x\n", r->r13);
+       runtime·printf("lr      %x\n", r->r14);
+       runtime·printf("pc      %x\n", r->r15);
+       runtime·printf("cpsr    %x\n", r->cpsr);
+}
+
+extern void runtime·lwp_tramp(void);
+extern void runtime·sigtramp(void);
+
+typedef struct sigaction {
+       union {
+               void    (*_sa_handler)(int32);
+               void    (*_sa_sigaction)(int32, Siginfo*, void *);
+       } _sa_u;                        /* signal handler */
+       uint32  sa_mask[4];             /* signal mask to apply */
+       int32   sa_flags;               /* see signal options below */
+} Sigaction;
+
+void
+runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
+{
+       UcontextT *uc;
+       McontextT *r;
+       SigTab *t;
+
+       uc = context;
+       r = &uc->uc_mcontext;
+
+       if(sig == SIGPROF) {
+               runtime·sigprof((uint8*)r->r15, (uint8*)r->r13, (uint8*)r->r14, gp);
+               return;
+       }
+
+       t = &runtime·sigtab[sig];
+       if(info->_code != SI_USER && (t->flags & SigPanic)) {
+               if(gp == nil || gp == m->g0)
+                       goto Throw;
+               // Make it look like a call to the signal func.
+               // We have to pass arguments out of band since
+               // augmenting the stack frame would break
+               // the unwinding code.
+               gp->sig = sig;
+               gp->sigcode0 = info->_code;
+               gp->sigcode1 = *(uintptr*)&info->_reason[0]; /* _addr */
+               gp->sigpc = r->r15;
+
+               // We arrange lr, and pc to pretend the panicking
+               // function calls sigpanic directly.
+               // Always save LR to stack so that panics in leaf
+               // functions are correctly handled. This smashes
+               // the stack frame but we're not going back there
+               // anyway.
+               r->r13 -= 4;
+               *(uint32 *)r->r13 = r->r14;
+               // Don't bother saving PC if it's zero, which is
+               // probably a call to a nil func: the old link register
+               // is more useful in the stack trace.
+               if(r->r15 != 0)
+                       r->r14 = r->r15;
+               // In case we are panicking from external C code
+               r->r10 = (uintptr)gp;
+               r->r9 = (uintptr)m;
+               r->r15 = (uintptr)runtime·sigpanic;
+               return;
+       }
+
+       if(info->_code == SI_USER || (t->flags & SigNotify))
+               if(runtime·sigsend(sig))
+                       return;
+       if(t->flags & SigKill)
+               runtime·exit(2);
+       if(!(t->flags & SigThrow))
+               return;
+
+Throw:
+       runtime·startpanic();
+
+       if(sig < 0 || sig >= NSIG)
+               runtime·printf("Signal %d\n", sig);
+       else
+               runtime·printf("%s\n", runtime·sigtab[sig].name);
+
+       runtime·printf("PC=%x\n", r->r15);
+       if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
+               runtime·printf("signal arrived during cgo execution\n");
+               gp = m->lockedg;
+       }
+       runtime·printf("\n");
+
+       if(runtime·gotraceback()){
+               runtime·traceback((void*)r->r15, (void*)r->r13, (void*)r->r14, gp);
+               runtime·tracebackothers(gp);
+               runtime·printf("\n");
+               runtime·dumpregs(r);
+       }
+
+//     breakpoint();
+       runtime·exit(2);
+}
+
+void
+runtime·signalstack(byte *p, int32 n)
+{
+       Sigaltstack st;
+
+       st.ss_sp = (uint8*)p;
+       st.ss_size = n;
+       st.ss_flags = 0;
+       runtime·sigaltstack(&st, nil);
+}
+
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+{
+       Sigaction sa;
+
+       runtime·memclr((byte*)&sa, sizeof sa);
+       sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
+       if(restart)
+               sa.sa_flags |= SA_RESTART;
+       sa.sa_mask[0] = ~0U;
+       sa.sa_mask[1] = ~0U;
+       sa.sa_mask[2] = ~0U;
+       sa.sa_mask[3] = ~0U;
+       if (fn == runtime·sighandler)
+               fn = (void*)runtime·sigtramp;
+       sa._sa_u._sa_sigaction = (void*)fn;
+       runtime·sigaction(i, &sa, nil);
+}
+
+void
+runtime·lwp_mcontext_init(McontextT *mc, void *stack, M *mp, G *gp, void (*fn)(void))
+{
+       mc->r15 = (uint32)runtime·lwp_tramp;
+       mc->r13 = (uint32)stack;
+       mc->r0 = (uint32)mp;
+       mc->r1 = (uint32)gp;
+       mc->r2 = (uint32)fn;
+}
+
+void
+runtime·checkgoarm(void)
+{
+       // TODO(minux)
+}
+
+#pragma textflag 7
+int64
+runtime·cputicks() {
+       // Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
+       // runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
+       // TODO: need more entropy to better seed fastrand1.
+       return runtime·nanotime();
+}
diff --git a/src/pkg/runtime/sys_netbsd_arm.s b/src/pkg/runtime/sys_netbsd_arm.s
new file mode 100644 (file)
index 0000000..fe0c2b2
--- /dev/null
@@ -0,0 +1,293 @@
+// 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"
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),7,$-4
+       MOVW 0(FP), R0  // arg 1 exit status
+       SWI $0xa00001
+       MOVW.CS $0, R9  // crash on syscall failure
+       MOVW.CS R9, (R9)
+       RET
+
+TEXT runtime·exit1(SB),7,$-4
+       SWI $0xa00136   // sys__lwp_exit
+       MOVW $1, R9     // crash
+       MOVW R9, (R9)
+       RET
+
+TEXT runtime·write(SB),7,$-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
+       RET
+
+// int32 lwp_create(void *context, uintptr flags, void *lwpid)
+TEXT runtime·lwp_create(SB),7,$0
+       MOVW context+0(FP), R0
+       MOVW flags+4(FP), R1
+       MOVW lwpid+8(FP), R2
+       SWI $0xa00135   // sys__lwp_create
+       RET
+
+TEXT runtime·osyield(SB),7,$0
+       SWI $0xa0015e   // sys_sched_yield
+       RET
+
+TEXT runtime·lwp_park(SB),7,$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
+       RET
+
+TEXT runtime·lwp_unpark(SB),7,$0
+       MOVW    0(FP), R0       // arg 1 - lwp
+       MOVW    4(FP), R1       // arg 2 - hint
+       SWI $0xa00141 // sys__lwp_unpark
+       RET
+
+TEXT runtime·lwp_self(SB),7,$0
+       SWI $0xa00137   // sys__lwp_self
+       RET
+
+TEXT runtime·lwp_tramp(SB),7,$0
+       MOVW R0, R9 // m
+       MOVW R1, R10 // g
+
+       BL runtime·emptyfunc(SB) // fault if stack check is wrong
+       BL (R2)
+       MOVW $2, R9  // crash (not reached)
+       MOVW R9, (R9)
+       RET
+
+TEXT runtime·usleep(SB),7,$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·raisesigpipe(SB),7,$16
+       SWI $0xa00137   // sys__lwp_self, the returned R0 is arg 1
+       MOVW $13, R1    // arg 2 - signo == SIGPIPE
+       SWI $0xa0013e   // sys__lwp_kill
+       RET
+
+TEXT runtime·setitimer(SB),7,$-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), 7, $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), 7, $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 0(FP), R3
+       MOVW R0, 0(R3)
+       MOVW R1, 4(R3)
+       RET
+
+TEXT runtime·getcontext(SB),7,$-4
+       MOVW 0(FP), R0  // arg 1 - context
+       SWI $0xa00133   // sys_getcontext
+       MOVW.CS $0, R9  // crash on syscall failure
+       MOVW.CS R9, (R9)
+       RET
+
+TEXT runtime·sigprocmask(SB),7,$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, R9  // crash on syscall failure
+       MOVW.CS R9, (R9)
+       RET
+
+TEXT runtime·sigreturn_tramp(SB),7,$-4
+       // in runtime·sigtramp, we saved ucontext into m->tls[0],
+       // here we just load it and call sys_setcontext
+       MOVW m_tls(m), R0
+       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),7,$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, R9  // crash on syscall failure
+       MOVW.CS R9, (R9)
+       RET
+
+TEXT runtime·sigtramp(SB),7,$24
+       // this might be called in external code context,
+       // where g and m are not set.
+       // first save R0, because cgo_load_gm will clobber it
+       // TODO(adonovan): call runtime·badsignal if m=0, like other platforms?
+       MOVW    R0, 4(R13) // signum
+       MOVW    cgo_load_gm(SB), R0
+       CMP     $0, R0
+       BL.NE   (R0)
+
+       // save g
+       MOVW R10, R4
+       MOVW R10, 20(R13)
+
+       // g = m->signal
+       MOVW m_gsignal(R9), R10
+
+       // R0 is already saved
+       MOVW R1, 8(R13) // info
+       MOVW R2, 12(R13) // context
+       MOVW R4, 16(R13) // gp
+       // we also save the ucontext into m->tls[0] for easy
+       // signal return
+       MOVW R2, m_tls(m)
+
+       BL runtime·sighandler(SB)
+
+       // restore g
+       MOVW 20(R13), R10
+       RET
+
+TEXT runtime·mmap(SB),7,$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
+       RET
+
+TEXT runtime·munmap(SB),7,$0
+       MOVW 0(FP), R0  // arg 1 - addr
+       MOVW 4(FP), R1  // arg 2 - len
+       SWI $0xa00049   // sys_munmap
+       MOVW.CS $0, R9  // crash on syscall failure
+       MOVW.CS R9, (R9)
+       RET
+
+TEXT runtime·madvise(SB),7,$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),7,$-4
+       MOVW 0(FP), R0  // arg 1 - nss
+       MOVW 4(FP), R1  // arg 2 - oss
+       SWI $0xa00119   // sys___sigaltstack14
+       MOVW.CS $0, R9  // crash on syscall failure
+       MOVW.CS R9, (R9)
+       RET
+
+TEXT runtime·sysctl(SB),7,$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
+       RET
+
+TEXT runtime·cacheflush(SB),7,$8
+       MOVW $1, R0 // drain_writebuf
+       SWI $0xa000a5 // sysarch
+       MOVW $0, R0 // icacheflush
+       MOVW 0(FP), R1 // start
+       MOVW R1, 4(R13)
+       MOVW 4(FP), R2 // end
+       SUB R1, R2 // R2 = length
+       MOVW R2, 8(R13)
+       MOVW $4(R13), R1
+       SWI $0xa000a5 // sysarch
+       RET
+
+TEXT runtime·casp(SB),7,$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),7,$0
+       B runtime·armcas(SB)
index 195dcfd2c2f05a8cf8631b1938db61c8c274d98a..4d174a537b1b92b0f7fafbc32baf106b3ffe4357 100644 (file)
@@ -144,10 +144,6 @@ runtime·semawakeup(M *mp)
        runtime·atomicstore(&mp->waitsemalock, 0);
 }
 
-// From NetBSD's <sys/ucontext.h>
-#define _UC_SIGMASK    0x01
-#define _UC_CPU                0x04
-
 void
 runtime·newosproc(M *mp, G *gp, void *stk, void (*fn)(void))
 {