native: add syscall-leave trampoline

pr/spi.typo
Ludwig Ortmann 8 years ago committed by Ludwig Knüpfer
parent 237340b3e3
commit 0b72be7c87

@ -6,3 +6,7 @@ ifeq ($(BUILDOSXNATIVE),1)
endif
export USEMODULE += periph
ifeq ($(shell uname -s),Darwin)
export CFLAGS += -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE
endif

@ -68,6 +68,7 @@ void native_interrupt_init(void);
void native_irq_handler(void);
extern void _native_sig_leave_tramp(void);
extern void _native_sig_leave_handler(void);
void _native_syscall_leave(void);
void _native_syscall_enter(void);

@ -23,14 +23,14 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define __USE_GNU
#include <signal.h>
#undef __USE_GNU
#ifdef __MACH__
#define _XOPEN_SOURCE
#endif
#include <ucontext.h>
#ifdef __MACH__
#undef _XOPEN_SOURCE
#endif
#include <err.h>
#ifdef HAVE_VALGRIND_H
@ -65,6 +65,28 @@ extern netdev2_tap_t netdev2_tap;
ucontext_t end_context;
char __end_stack[SIGSTKSZ];
/**
* make the new context assign `_native_in_isr = 0` before resuming
*/
static void _native_mod_ctx_leave_sigh(ucontext_t *ctx)
{
#ifdef __MACH__
_native_saved_eip = ((ucontext_t *)ctx)->uc_mcontext->__ss.__eip;
((ucontext_t *)ctx)->uc_mcontext->__ss.__eip = (unsigned int)&_native_sig_leave_handler;
#elif defined(__FreeBSD__)
_native_saved_eip = ((struct sigcontext *)ctx)->sc_eip;
((struct sigcontext *)ctx)->sc_eip = (unsigned int)&_native_sig_leave_handler;
#else /* Linux */
#if defined(__arm__)
_native_saved_eip = ((ucontext_t *)ctx)->uc_mcontext.arm_pc;
((ucontext_t *)ctx)->uc_mcontext.arm_pc = (unsigned int)&_native_sig_leave_handler;
#else /* Linux/x86 */
_native_saved_eip = ctx->uc_mcontext.gregs[REG_EIP];
ctx->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_handler;
#endif
#endif
}
/**
* TODO: implement
*/
@ -127,10 +149,8 @@ void isr_cpu_switch_context_exit(void)
DEBUG("isr_cpu_switch_context_exit: calling setcontext(%" PRIkernel_pid ")\n\n", sched_active_pid);
ctx = (ucontext_t *)(sched_active_thread->sp);
/* the next context will have interrupts enabled due to ucontext */
DEBUG("isr_cpu_switch_context_exit: native_interrupts_enabled = 1;\n");
native_interrupts_enabled = 1;
_native_in_isr = 0;
_native_mod_ctx_leave_sigh(ctx);
if (setcontext(ctx) == -1) {
err(EXIT_FAILURE, "isr_cpu_switch_context_exit: setcontext");
@ -169,12 +189,18 @@ void isr_thread_yield(void)
{
DEBUG("isr_thread_yield\n");
if (_native_sigpend > 0) {
DEBUG("isr_thread_yield(): handling signals\n\n");
native_irq_handler();
}
sched_run();
ucontext_t *ctx = (ucontext_t *)(sched_active_thread->sp);
DEBUG("isr_thread_yield: switching to(%" PRIkernel_pid ")\n\n", sched_active_pid);
native_interrupts_enabled = 1;
_native_in_isr = 0;
_native_mod_ctx_leave_sigh(ctx);
if (setcontext(ctx) == -1) {
err(EXIT_FAILURE, "isr_thread_yield: setcontext");
}

@ -28,6 +28,13 @@ __native_sig_leave_tramp:
popfl
ret
.globl __native_sig_leave_handler
__native_sig_leave_handler:
pushl __native_saved_eip
movl $0x0, __native_in_isr
ret
#elif __arm__
.globl _native_sig_leave_tramp
@ -65,6 +72,26 @@ _native_sig_leave_tramp:
ldmia sp!, {r0-r12}
ldmia sp!, {pc}
.globl _native_sig_leave_handler
_native_sig_leave_handler:
stmdb sp!, {r0}
ldr r0, =_native_saved_eip
ldr r0, [r0]
stmdb sp!, {r0-r12}
stmdb sp!, {lr}
/* exchange r0 and _native_saved_eip */
ldr r0, [sp,#56]
ldr r1, [sp,#4 ]
str r0, [sp,#4 ]
str r1, [sp,#56]
/* _native_in_isr = 0 */
eor r0, r0, r0
ldr r1, =_native_in_isr
str r0, [r1]
ldmia sp!, {lr}
ldmia sp!, {r0-r12}
ldmia sp!, {pc}
#else
.globl _native_sig_leave_tramp
@ -85,4 +112,10 @@ _native_sig_leave_tramp:
popfl
ret
.globl _native_sig_leave_handler
_native_sig_leave_handler:
pushl _native_saved_eip
movl $0x0, _native_in_isr
ret
#endif

Loading…
Cancel
Save