Skip to content

Commit

Permalink
Merge pull request #2071 from LudwigKnuepfer/2071
Browse files Browse the repository at this point in the history
native: *long* overdue fixes
  • Loading branch information
OlegHahm authored Oct 30, 2016
2 parents 04f8cc2 + 0b72be7 commit 3aab6bb
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 23 deletions.
4 changes: 4 additions & 0 deletions cpu/native/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions cpu/native/include/native_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
16 changes: 8 additions & 8 deletions cpu/native/irq_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
#define ENABLE_DEBUG (0)
#include "debug.h"

volatile int native_interrupts_enabled;
volatile int native_interrupts_enabled = 0;
volatile int _native_in_isr;
volatile int _native_in_syscall;

Expand Down Expand Up @@ -279,6 +279,7 @@ void native_irq_handler(void)
void isr_set_sigmask(ucontext_t *ctx)
{
ctx->uc_sigmask = _native_sig_set_dint;
native_interrupts_enabled = 0;
}

/**
Expand Down Expand Up @@ -323,7 +324,7 @@ void native_isr_entry(int sig, siginfo_t *info, void *context)
}

native_isr_context.uc_stack.ss_sp = __isr_stack;
native_isr_context.uc_stack.ss_size = SIGSTKSZ;
native_isr_context.uc_stack.ss_size = sizeof(__isr_stack);
native_isr_context.uc_stack.ss_flags = 0;
makecontext(&native_isr_context, native_irq_handler, 0);
_native_cur_ctx = (ucontext_t *)sched_active_thread->sp;
Expand All @@ -343,11 +344,11 @@ void native_isr_entry(int sig, siginfo_t *info, void *context)
#elif defined(__FreeBSD__)
_native_saved_eip = ((struct sigcontext *)context)->sc_eip;
((struct sigcontext *)context)->sc_eip = (unsigned int)&_native_sig_leave_tramp;
#else
#ifdef __arm__
#else /* Linux */
#if defined(__arm__)
_native_saved_eip = ((ucontext_t *)context)->uc_mcontext.arm_pc;
((ucontext_t *)context)->uc_mcontext.arm_pc = (unsigned int)&_native_sig_leave_tramp;
#else
#else /* Linux/x86 */
//printf("\n\033[31mEIP:\t%p\ngo switching\n\n\033[0m", (void*)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]);
_native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP];
((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_tramp;
Expand Down Expand Up @@ -465,7 +466,6 @@ void native_interrupt_init(void)
VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n",
(void *)__isr_stack, (void*)((int)__isr_stack + sizeof(__isr_stack)));

native_interrupts_enabled = 1;
_native_sigpend = 0;

for (int i = 0; i < 255; i++) {
Expand Down Expand Up @@ -509,13 +509,13 @@ void native_interrupt_init(void)
}

native_isr_context.uc_stack.ss_sp = __isr_stack;
native_isr_context.uc_stack.ss_size = SIGSTKSZ;
native_isr_context.uc_stack.ss_size = sizeof(__isr_stack);
native_isr_context.uc_stack.ss_flags = 0;
_native_isr_ctx = &native_isr_context;

static stack_t sigstk;
sigstk.ss_sp = sigalt_stk;
sigstk.ss_size = SIGSTKSZ;
sigstk.ss_size = sizeof(__isr_stack);
sigstk.ss_flags = 0;

if (sigaltstack(&sigstk, NULL) < 0) {
Expand Down
55 changes: 42 additions & 13 deletions cpu/native/native_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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");
Expand All @@ -151,11 +171,11 @@ void cpu_switch_context_exit(void)
irq_disable();
_native_in_isr = 1;
native_isr_context.uc_stack.ss_sp = __isr_stack;
native_isr_context.uc_stack.ss_size = SIGSTKSZ;
native_isr_context.uc_stack.ss_size = sizeof(__isr_stack);
native_isr_context.uc_stack.ss_flags = 0;
makecontext(&native_isr_context, isr_cpu_switch_context_exit, 0);
if (setcontext(&native_isr_context) == -1) {
err(EXIT_FAILURE, "cpu_switch_context_exit: swapcontext");
err(EXIT_FAILURE, "cpu_switch_context_exit: setcontext");
}
errx(EXIT_FAILURE, "1 this should have never been reached!!");
}
Expand All @@ -169,22 +189,31 @@ 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");
}
}

void thread_yield_higher(void)
{
ucontext_t *ctx = (ucontext_t *)(sched_active_thread->sp);
if (_native_in_isr == 0) {
ucontext_t *ctx = (ucontext_t *)(sched_active_thread->sp);
_native_in_isr = 1;
if (!native_interrupts_enabled) {
warnx("thread_yield_higher: interrupts are disabled - this should not be");
}
irq_disable();
native_isr_context.uc_stack.ss_sp = __isr_stack;
native_isr_context.uc_stack.ss_size = SIGSTKSZ;
Expand Down
2 changes: 2 additions & 0 deletions cpu/native/startup.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include "kernel_init.h"
#include "cpu.h"
#include "irq.h"

#include "board_internal.h"
#include "native_internal.h"
Expand Down Expand Up @@ -334,5 +335,6 @@ __attribute__((constructor)) static void startup(int argc, char **argv)
board_init();

puts("RIOT native hardware initialization complete.\n");
irq_enable();
kernel_init();
}
3 changes: 1 addition & 2 deletions cpu/native/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,15 @@ void _native_syscall_leave(void)
)
{
_native_in_isr = 1;
unsigned int mask = irq_disable();
_native_cur_ctx = (ucontext_t *)sched_active_thread->sp;
native_isr_context.uc_stack.ss_sp = __isr_stack;
native_isr_context.uc_stack.ss_size = SIGSTKSZ;
native_isr_context.uc_stack.ss_flags = 0;
native_interrupts_enabled = 0;
makecontext(&native_isr_context, native_irq_handler, 0);
if (swapcontext(_native_cur_ctx, &native_isr_context) == -1) {
err(EXIT_FAILURE, "_native_syscall_leave: swapcontext");
}
irq_restore(mask);
}
}

Expand Down
33 changes: 33 additions & 0 deletions cpu/native/tramp.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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

0 comments on commit 3aab6bb

Please sign in to comment.