Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

native: *long* overdue fixes #2071

Merged
merged 5 commits into from
Oct 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may lead to running the wrong thread. After isr_cpu_switch_context_exit() is called, the previous thread is restored before sched_run() is getting called.

}

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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why double underscores on MACH and single underscores on the others?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apple - think different.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha, nice one!

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