Module: xenomai-forge
Branch: master
Commit: c86190d45691c73f66577d993d77ec1cccb46775
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=c86190d45691c73f66577d993d77ec1cccb46775

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon Jan  7 17:53:43 2013 +0100

cobalt/nios2: convert to native linux kthreads

---

 include/asm-nios2/thread.h        |   66 +++------------
 kernel/cobalt/arch/nios2/Kconfig  |    4 -
 kernel/cobalt/arch/nios2/switch.S |   17 +----
 kernel/cobalt/arch/nios2/thread.c |  166 ++++++-------------------------------
 4 files changed, 40 insertions(+), 213 deletions(-)

diff --git a/include/asm-nios2/thread.h b/include/asm-nios2/thread.h
index 0073fd9..d46588d 100644
--- a/include/asm-nios2/thread.h
+++ b/include/asm-nios2/thread.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Philippe Gerum <r...@xenomai.org>.
+ * Copyright (C) 2009,2013 Philippe Gerum <r...@xenomai.org>.
  *
  * Xenomai is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -20,45 +20,21 @@
 #ifndef _XENO_ASM_NIOS2_THREAD_H
 #define _XENO_ASM_NIOS2_THREAD_H
 
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/xenomai/wrappers.h>
+#include <asm-generic/xenomai/thread.h>
 
 #ifndef CONFIG_MMU
 #error "Xenomai: please use Xenomai 2.5.x for MMU-less support"
 #endif
 
-struct xnthread;
-struct task_struct;
-
 struct xnarchtcb {
-       unsigned int stacksize;
-       unsigned long *stackbase;
-       struct task_struct *user_task;
-       struct task_struct *active_task;
-       struct thread_struct *tsp;
-       struct mm_struct *mm;
-       struct mm_struct *active_mm;
-       struct thread_struct ts;
+       struct xntcb core;
        struct {
                unsigned long ea;
                unsigned long r2;
                unsigned long r3;
        } mayday;
-       struct xnthread *self;
-       int imask;
-       const char *name;
-       void (*entry)(void *cookie);
-       void *cookie;
 };
 
-#define XNARCH_THREAD_STACKSZ   4096
-
-#define xnarch_stack_size(tcb)  ((tcb)->stacksize)
-#define xnarch_stack_base(tcb) ((tcb)->stackbase)
-#define xnarch_stack_end(tcb)  ((caddr_t)(tcb)->stackbase - (tcb)->stacksize)
-#define xnarch_user_task(tcb)   ((tcb)->user_task)
-#define xnarch_user_pid(tcb)    ((tcb)->user_task->pid)
 #define xnarch_fpu_ptr(tcb)     NULL
 #define xnarch_fault_trap(d)   ((d)->exception)
 #define xnarch_fault_code(d)   (0) /* None on this arch. */
@@ -70,41 +46,21 @@ struct xnarchtcb {
 
 #define xnarch_fault_notify(d) (xnarch_fault_bp_p(d) == 0)
 
-void xnarch_switch_to(struct xnarchtcb *out_tcb, struct xnarchtcb *in_tcb);
-
-void xnarch_init_thread(struct xnarchtcb *tcb,
-                       void (*entry)(void *),
-                       void *cookie,
-                       int imask,
-                       struct xnthread *thread, char *name);
-
-void xnarch_leave_root(struct xnarchtcb *rootcb);
-
-int xnarch_escalate(void);
-
-void xnarch_init_root_tcb(struct xnarchtcb *tcb,
-                         struct xnthread *thread,
-                         const char *name);
-
-void xnarch_init_shadow_tcb(struct xnarchtcb *tcb,
-                           struct xnthread *thread,
-                           const char *name);
-
-void xnarch_init_tcb(struct xnarchtcb *tcb);
-
-int xnarch_alloc_stack(struct xnarchtcb *tcb, size_t stacksize);
-
-void xnarch_free_stack(struct xnarchtcb *tcb);
-
+static inline void xnarch_init_root_tcb(struct xnarchtcb *tcb) { }
+static inline void xnarch_init_shadow_tcb(struct xnarchtcb *tcb) { }
 static inline void xnarch_enter_root(struct xnarchtcb *rootcb) { }
+static inline void xnarch_leave_root(struct xnarchtcb *rootcb) { }
 static inline void xnarch_enable_fpu(struct xnarchtcb *current_tcb) { }
-static inline void xnarch_init_fpu(struct xnarchtcb *tcb) { }
 static inline void xnarch_save_fpu(struct xnarchtcb *tcb) { }
 static inline void xnarch_restore_fpu(struct xnarchtcb *tcb) { }
 
-static inline int xnarch_fpu_init_p(struct task_struct *task)
+static inline int xnarch_handle_fpu_fault(struct xnarchtcb *tcb)
 {
        return 0;
 }
 
+void xnarch_switch_to(struct xnarchtcb *out_tcb, struct xnarchtcb *in_tcb);
+
+int xnarch_escalate(void);
+
 #endif /* !_XENO_ASM_NIOS2_THREAD_H */
diff --git a/kernel/cobalt/arch/nios2/Kconfig b/kernel/cobalt/arch/nios2/Kconfig
index 7fcaf62..58c85df 100644
--- a/kernel/cobalt/arch/nios2/Kconfig
+++ b/kernel/cobalt/arch/nios2/Kconfig
@@ -1,6 +1,2 @@
-config XENO_GENERIC_STACKPOOL
-       bool
-       default y
-
 source "kernel/xenomai/nucleus/Kconfig"
 source "drivers/xenomai/Kconfig"
diff --git a/kernel/cobalt/arch/nios2/switch.S 
b/kernel/cobalt/arch/nios2/switch.S
index c2192e1..fef6e3d 100644
--- a/kernel/cobalt/arch/nios2/switch.S
+++ b/kernel/cobalt/arch/nios2/switch.S
@@ -26,7 +26,7 @@
 .set noat
 .set nobreak
 
-.macro GET_THREAD_INFO reg 
+.macro GET_THREAD_INFO reg
 .if THREAD_SIZE & 0xffff0000
        andhi   \reg, sp, %hi(~(THREAD_SIZE-1))
 .else
@@ -37,14 +37,9 @@
 
 /*
  * Switch context routine for Xenomai threads.
- * Kernel-based threads are basically seen as co-routines.
- * The context is saved/restored to/from regular thread_structs,
- * so that hybrid scheduling between kernel and user-space Xenomai
- * threads is possible.
  *
  * void __asm_thread_switch(struct thread_struct *prev,
- *                          struct thread_struct *next,
- *                          int kernp)
+ *                          struct thread_struct *next);
  */
 ENTRY(__asm_thread_switch)
        rdctl   r7,status                       /* save thread status reg */
@@ -52,18 +47,10 @@ ENTRY(__asm_thread_switch)
        SAVE_SWITCH_STACK
        stw     sp,THREAD_KSP(r4)               /* save kernel stack pointer */
        ldw     sp,THREAD_KSP(r5)               /* restore new thread stack */
-       bne     r6,r0,no_curr_update            /* switch to kernel Xenomai 
thread */
        movia   r24,_current_thread             /* save thread */
        GET_THREAD_INFO r1
        stw     r1,0(r24)
-no_curr_update:
        RESTORE_SWITCH_STACK
        ldw     r7,THREAD_KPSR(r5)              /* restore thread status reg */
        wrctl   status,r7
        ret
-
-ENTRY(__asm_thread_trampoline)
-       ldw     r4,0(sp)
-       ldw     ra,4(sp)
-       addi    sp,sp,8
-       ret
diff --git a/kernel/cobalt/arch/nios2/thread.c 
b/kernel/cobalt/arch/nios2/thread.c
index 59e31ee..9d5ae1d 100644
--- a/kernel/cobalt/arch/nios2/thread.c
+++ b/kernel/cobalt/arch/nios2/thread.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Philippe Gerum <r...@xenomai.org>.
+ * Copyright (C) 2009,2013 Philippe Gerum <r...@xenomai.org>.
  *
  * Xenomai is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -19,130 +19,40 @@
 
 #include <linux/sched.h>
 #include <linux/ipipe.h>
-#include <nucleus/pod.h>
-#include <nucleus/heap.h>
-#include <asm/xenomai/thread.h>
+#include <linux/mm.h>
+#include <asm/mmu_context.h>
+#include <nucleus/thread.h>
 
-void __asm_thread_switch(struct thread_struct *prev,
-                        struct thread_struct *next,
-                        int kthreadp);
-
-asmlinkage void __asm_thread_trampoline(void);
-
-void xnarch_init_shadow_tcb(struct xnarchtcb *tcb,
-                           struct xnthread *thread, const char *name)
-{
-       struct task_struct *task = current;
-
-       tcb->user_task = task;
-       tcb->active_task = NULL;
-       tcb->tsp = &task->thread;
-       tcb->mm = task->mm;
-       tcb->active_mm = NULL;
-       tcb->entry = NULL;
-       tcb->cookie = NULL;
-       tcb->self = thread;
-       tcb->imask = 0;
-       tcb->name = name;
-}
-
-void xnarch_init_root_tcb(struct xnarchtcb *tcb,
-                         struct xnthread *thread, const char *name)
-{
-       tcb->user_task = current;
-       tcb->active_task = current;
-       tcb->tsp = &tcb->ts;
-       tcb->mm = current->mm;
-       tcb->active_mm = NULL;
-       tcb->entry = NULL;
-       tcb->cookie = NULL;
-       tcb->self = thread;
-       tcb->imask = 0;
-       tcb->name = name;
-}
-
-void xnarch_init_tcb(struct xnarchtcb *tcb)
-{
-       tcb->user_task = NULL;
-       tcb->active_task = NULL;
-       tcb->tsp = &tcb->ts;
-       tcb->mm = NULL;
-       tcb->active_mm = NULL;
-       memset(&tcb->ts, 0, sizeof(tcb->ts));
-}
-
-void xnarch_leave_root(struct xnarchtcb *rootcb)
-{
-       struct task_struct *p = current;
-
-       /* Remember the preempted Linux task pointer. */
-       rootcb->user_task = rootcb->active_task = p;
-       rootcb->tsp = &p->thread;
-       rootcb->mm = rootcb->active_mm = ipipe_get_active_mm();
-}
+asmlinkage void
+__asm_thread_switch(struct thread_struct *prev,
+                   struct thread_struct *next);
 
 void xnarch_switch_to(struct xnarchtcb *out_tcb, struct xnarchtcb *in_tcb)
 {
-       struct mm_struct *prev_mm = out_tcb->active_mm, *next_mm;
-       struct task_struct *prev = out_tcb->active_task;
-       struct task_struct *next = in_tcb->user_task;
+       struct mm_struct *prev_mm, *next_mm;
+       struct task_struct *next;
+
+       next = in_tcb->core.host_task;
+       prev_mm = out_tcb->core.active_mm;
 
-       if (likely(next)) {
-               in_tcb->active_task = next;
-               in_tcb->active_mm = in_tcb->mm;
-               ipipe_clear_foreign_stack(&xnarch_machdata.domain);
+       next_mm = in_tcb->core.mm;
+       if (next_mm == NULL) {
+               in_tcb->core.active_mm = prev_mm;
+               enter_lazy_tlb(prev_mm, next);
        } else {
-               in_tcb->active_task = prev;
-               in_tcb->active_mm = prev_mm;
-               ipipe_set_foreign_stack(&xnarch_machdata.domain);
+               switch_mm(prev_mm, next_mm, next);
+               /*
+                * We might be switching back to the root thread,
+                * which we preempted earlier, shortly after "current"
+                * dropped its mm context in the do_exit() path
+                * (next->mm == NULL). In that particular case, the
+                * kernel expects a lazy TLB state for leaving the mm.
+                */
+               if (next->mm == NULL)
+                       enter_lazy_tlb(prev_mm, next);
        }
 
-       next_mm = in_tcb->active_mm;
-
-       if (next_mm && likely(prev_mm != next_mm))
-               __switch_mm(prev_mm, next_mm, next);
-
-       __asm_thread_switch(out_tcb->tsp, in_tcb->tsp, next == NULL);
-}
-
-asmlinkage static void thread_trampoline(struct xnarchtcb *tcb)
-{
-       xnpod_welcome_thread(tcb->self, tcb->imask);
-       tcb->entry(tcb->cookie);
-       xnpod_delete_thread(tcb->self);
-}
-
-void xnarch_init_thread(struct xnarchtcb *tcb,
-                       void (*entry)(void *),
-                       void *cookie, int imask,
-                       struct xnthread *thread, char *name)
-{
-       register long gp __asm__ ("gp");
-
-       struct tramp_stack {
-               struct switch_stack sw;
-               unsigned long r4; /* to hold tcb pointer arg */
-               unsigned long ra; /* to xnarch_thread_trampoline() */
-       } *childregs;
-
-       childregs = (struct tramp_stack *)
-               ((unsigned long)tcb->stackbase + tcb->stacksize - 
sizeof(*childregs));
-       /*
-        * Stack space is guaranteed to be clean, so no need to zero
-        * it again.
-        */
-       childregs->sw.gp = gp;  /* Inherit GP */
-       childregs->sw.ra = (unsigned long)__asm_thread_trampoline;
-       childregs->ra = (unsigned long)thread_trampoline;
-       childregs->r4 = (unsigned long)tcb;
-
-       tcb->ts.ksp = (unsigned long)childregs;
-       tcb->ts.kpsr = 0;       /* PIE=0, U=0, EH=0 */
-       tcb->entry = entry;
-       tcb->cookie = cookie;
-       tcb->self = thread;
-       tcb->imask = imask;
-       tcb->name = name;
+       __asm_thread_switch(out_tcb->core.tsp, in_tcb->core.tsp);
 }
 
 int xnarch_escalate(void)
@@ -154,25 +64,3 @@ int xnarch_escalate(void)
 
        return 0;
 }
-
-int xnarch_alloc_stack(struct xnarchtcb *tcb, size_t stacksize)
-{
-       int ret = 0;
-
-       tcb->stacksize = stacksize;
-       if (stacksize == 0)
-               tcb->stackbase = NULL;
-       else {
-               tcb->stackbase = xnmalloc(stacksize);
-               if (tcb->stackbase == NULL)
-                       ret = -ENOMEM;
-       }
-
-       return ret;
-}
-
-void xnarch_free_stack(struct xnarchtcb *tcb)
-{
-       if (tcb->stackbase)
-               xnfree(tcb->stackbase);
-}


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to