summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/linux/arm
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/linux/arm')
-rw-r--r--src/pkg/runtime/linux/arm/defs.h42
-rw-r--r--src/pkg/runtime/linux/arm/signal.c59
-rw-r--r--src/pkg/runtime/linux/arm/sys.s9
3 files changed, 82 insertions, 28 deletions
diff --git a/src/pkg/runtime/linux/arm/defs.h b/src/pkg/runtime/linux/arm/defs.h
index ff43d689a..6b2f22c66 100644
--- a/src/pkg/runtime/linux/arm/defs.h
+++ b/src/pkg/runtime/linux/arm/defs.h
@@ -1,4 +1,4 @@
-// godefs -carm-gcc -f -I/usr/local/google/src/linux-2.6.28/arch/arm/include -f -I/usr/local/google/src/linux-2.6.28/include -f-D__KERNEL__ -f-D__ARCH_SI_UID_T=int defs_arm.c
+// godefs -f-I/usr/src/linux-headers-2.6.26-2-versatile/include defs_arm.c
// MACHINE GENERATED - DO NOT EDIT.
@@ -58,23 +58,15 @@ enum {
BUS_OBJERR = 0x3,
SEGV_MAPERR = 0x1,
SEGV_ACCERR = 0x2,
+ ITIMER_REAL = 0,
+ ITIMER_PROF = 0x2,
+ ITIMER_VIRTUAL = 0x1,
};
// Types
#pragma pack on
-typedef struct Sigset Sigset;
-struct Sigset {
- uint32 sig[2];
-};
-
-typedef struct Sigaction Sigaction;
-struct Sigaction {
- void *sa_handler;
- uint32 sa_flags;
- void *sa_restorer;
- Sigset sa_mask;
-};
+typedef uint32 Sigset;
typedef struct Timespec Timespec;
struct Timespec {
@@ -120,11 +112,23 @@ struct Ucontext {
Ucontext *uc_link;
Sigaltstack uc_stack;
Sigcontext uc_mcontext;
- Sigset uc_sigmask;
- int32 __unused[30];
+ uint32 uc_sigmask;
+ int32 __unused[31];
uint32 uc_regspace[128];
};
+typedef struct Timeval Timeval;
+struct Timeval {
+ int32 tv_sec;
+ int32 tv_usec;
+};
+
+typedef struct Itimerval Itimerval;
+struct Itimerval {
+ Timeval it_interval;
+ Timeval it_value;
+};
+
typedef struct Siginfo Siginfo;
struct Siginfo {
int32 si_signo;
@@ -132,4 +136,12 @@ struct Siginfo {
int32 si_code;
uint8 _sifields[4];
};
+
+typedef struct Sigaction Sigaction;
+struct Sigaction {
+ void *sa_handler;
+ uint32 sa_flags;
+ void *sa_restorer;
+ uint32 sa_mask;
+};
#pragma pack off
diff --git a/src/pkg/runtime/linux/arm/signal.c b/src/pkg/runtime/linux/arm/signal.c
index 843c40b68..05c6b0261 100644
--- a/src/pkg/runtime/linux/arm/signal.c
+++ b/src/pkg/runtime/linux/arm/signal.c
@@ -58,6 +58,11 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
uc = context;
r = &uc->uc_mcontext;
+ if(sig == SIGPROF) {
+ runtime·sigprof((uint8*)r->arm_pc, (uint8*)r->arm_sp, (uint8*)r->arm_lr, gp);
+ return;
+ }
+
if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
// Make it look like a call to the signal func.
// Have to pass arguments out of band since
@@ -119,31 +124,59 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
+static void
+sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+{
+ Sigaction sa;
+
+ runtime·memclr((byte*)&sa, sizeof sa);
+ sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER;
+ if(restart)
+ sa.sa_flags |= SA_RESTART;
+ sa.sa_mask = ~0ULL;
+ sa.sa_restorer = (void*)runtime·sigreturn;
+ if(fn == runtime·sighandler)
+ fn = (void*)runtime·sigtramp;
+ sa.sa_handler = fn;
+ runtime·rt_sigaction(i, &sa, nil, 8);
+}
+
void
runtime·initsig(int32 queue)
{
- static Sigaction sa;
+ int32 i;
+ void *fn;
runtime·siginit();
- int32 i;
- sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER;
- sa.sa_mask.sig[0] = 0xFFFFFFFF;
- sa.sa_mask.sig[1] = 0xFFFFFFFF;
- sa.sa_restorer = (void*)runtime·sigreturn;
for(i = 0; i<NSIG; i++) {
if(runtime·sigtab[i].flags) {
if((runtime·sigtab[i].flags & SigQueue) != queue)
continue;
if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- sa.sa_handler = (void*)runtime·sigtramp;
+ fn = runtime·sighandler;
else
- sa.sa_handler = (void*)runtime·sigignore;
- if(runtime·sigtab[i].flags & SigRestart)
- sa.sa_flags |= SA_RESTART;
- else
- sa.sa_flags &= ~SA_RESTART;
- runtime·rt_sigaction(i, &sa, nil, 8);
+ fn = runtime·sigignore;
+ sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
}
}
}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+ Itimerval it;
+
+ runtime·memclr((byte*)&it, sizeof it);
+ if(hz == 0) {
+ runtime·setitimer(ITIMER_PROF, &it, nil);
+ sigaction(SIGPROF, SIG_IGN, true);
+ } else {
+ sigaction(SIGPROF, runtime·sighandler, true);
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 1000000 / hz;
+ it.it_value = it.it_interval;
+ runtime·setitimer(ITIMER_PROF, &it, nil);
+ }
+ m->profilehz = hz;
+}
diff --git a/src/pkg/runtime/linux/arm/sys.s b/src/pkg/runtime/linux/arm/sys.s
index 9daf9c2e4..b9767a028 100644
--- a/src/pkg/runtime/linux/arm/sys.s
+++ b/src/pkg/runtime/linux/arm/sys.s
@@ -26,6 +26,7 @@
#define SYS_futex (SYS_BASE + 240)
#define SYS_exit_group (SYS_BASE + 248)
#define SYS_munmap (SYS_BASE + 91)
+#define SYS_setitimer (SYS_BASE + 104)
#define ARM_BASE (SYS_BASE + 0x0f0000)
#define SYS_ARM_cacheflush (ARM_BASE + 2)
@@ -72,6 +73,14 @@ TEXT runtime·munmap(SB),7,$0
SWI $0
RET
+TEXT runtime·setitimer(SB),7,$0
+ MOVW 0(FP), R0
+ MOVW 4(FP), R1
+ MOVW 8(FP), R2
+ MOVW $SYS_setitimer, R7
+ SWI $0
+ RET
+
TEXT runtime·gettime(SB),7,$32
/* dummy version - return 0,0 */
MOVW $0, R1