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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Jul 15 12:31:04 2009 +0200

powerpc: sanitize FPU handling helpers

---

 include/asm-powerpc/bits/pod.h    |   38 +++++++++---------
 include/asm-powerpc/bits/shadow.h |    2 +-
 include/asm-powerpc/bits/thread.h |    4 +-
 include/asm-powerpc/hal.h         |   26 ++----------
 include/asm-powerpc/system.h      |    8 ++-
 include/asm-powerpc/wrappers.h    |    4 --
 ksrc/arch/powerpc/fpu.S           |   75 +++++++++++++++++++------------------
 7 files changed, 71 insertions(+), 86 deletions(-)

diff --git a/include/asm-powerpc/bits/pod.h b/include/asm-powerpc/bits/pod.h
index 5710f8f..495ff0b 100644
--- a/include/asm-powerpc/bits/pod.h
+++ b/include/asm-powerpc/bits/pod.h
@@ -48,10 +48,8 @@ static inline void xnarch_leave_root(xnarchtcb_t * rootcb)
 #ifdef CONFIG_XENO_HW_FPU
        rootcb->user_fpu_owner = rthal_get_fpu_owner(rootcb->user_task);
        /* So that xnarch_save_fpu() will operate on the right FPU area. */
-       rootcb->fpup = (rootcb->user_fpu_owner
-                       ? (rthal_fpenv_t *) & rootcb->user_fpu_owner->thread.
-                       fpr[0]
-                       : NULL);
+       rootcb->fpup = rootcb->user_fpu_owner ?
+               &rootcb->user_fpu_owner->thread : NULL;
 #endif /* CONFIG_XENO_HW_FPU */
 }
 
@@ -209,20 +207,22 @@ static inline void xnarch_enable_fpu(xnarchtcb_t * 
current_tcb)
 #endif /* CONFIG_XENO_HW_FPU */
 }
 
-static inline void xnarch_init_fpu(xnarchtcb_t * tcb)
+static void xnarch_init_fpu(xnarchtcb_t * tcb)
 {
 #ifdef CONFIG_XENO_HW_FPU
-       /* Initialize the FPU for an emerging kernel-based RT thread. This
-          must be run on behalf of the emerging thread. */
-       memset(&tcb->ts.fpr[0], 0, sizeof(rthal_fpenv_t));
-       rthal_init_fpu((rthal_fpenv_t *) & tcb->ts.fpr[0]);
+       /*
+        * Initialize the FPU for an emerging kernel-based RT
+        * thread. This must be run on behalf of the emerging thread.
+        * xnarch_init_tcb() guarantees that all FPU regs are zeroed
+        * in tcb.
+        */
+       rthal_init_fpu(&tcb->ts);
 #endif /* CONFIG_XENO_HW_FPU */
 }
 
-static inline void xnarch_save_fpu(xnarchtcb_t * tcb)
+static void xnarch_save_fpu(xnarchtcb_t * tcb)
 {
 #ifdef CONFIG_XENO_HW_FPU
-
        if (tcb->fpup) {
                rthal_save_fpu(tcb->fpup);
 
@@ -233,23 +233,23 @@ static inline void xnarch_save_fpu(xnarchtcb_t * tcb)
 #endif /* CONFIG_XENO_HW_FPU */
 }
 
-static inline void xnarch_restore_fpu(xnarchtcb_t * tcb)
+static void xnarch_restore_fpu(xnarchtcb_t * tcb)
 {
 #ifdef CONFIG_XENO_HW_FPU
-
        if (tcb->fpup) {
                rthal_restore_fpu(tcb->fpup);
-
-               /* Note: Only enable FP in MSR, if it was enabled when we saved 
the
-                * fpu state.
+               /*
+                * Note: Only enable FP in MSR, if it was enabled when
+                * we saved the fpu state.
                 */
                if (tcb->user_fpu_owner &&
                    tcb->user_fpu_owner->thread.regs)
                        tcb->user_fpu_owner->thread.regs->msr |= 
(MSR_FP|MSR_FE0|MSR_FE1);
        }
-
-       /* FIXME: We restore FPU "as it was" when Xenomai preempted Linux,
-          whereas we could be much lazier. */
+       /*
+        * FIXME: We restore FPU "as it was" when Xenomai preempted Linux,
+        * whereas we could be much lazier.
+        */
         if (tcb->user_task && tcb->user_task != tcb->user_fpu_owner)
                rthal_disable_fpu();
 
diff --git a/include/asm-powerpc/bits/shadow.h 
b/include/asm-powerpc/bits/shadow.h
index 71ae4d9..832ce26 100644
--- a/include/asm-powerpc/bits/shadow.h
+++ b/include/asm-powerpc/bits/shadow.h
@@ -38,7 +38,7 @@ static inline void xnarch_init_shadow_tcb(xnarchtcb_t * tcb,
        tcb->tsp = &task->thread;
 #ifdef CONFIG_XENO_HW_FPU
        tcb->user_fpu_owner = task;
-       tcb->fpup = (rthal_fpenv_t *) & task->thread.fpr[0];
+       tcb->fpup = &task->thread;
 #endif /* CONFIG_XENO_HW_FPU */
        tcb->entry = NULL;
        tcb->cookie = NULL;
diff --git a/include/asm-powerpc/bits/thread.h 
b/include/asm-powerpc/bits/thread.h
index 4ed9564..ebe1c11 100644
--- a/include/asm-powerpc/bits/thread.h
+++ b/include/asm-powerpc/bits/thread.h
@@ -27,7 +27,7 @@
 #error "Pure kernel header included from user-space!"
 #endif
 
-static inline void xnarch_init_tcb(xnarchtcb_t * tcb)
+static inline void xnarch_init_tcb(xnarchtcb_t *tcb)
 {
        tcb->user_task = NULL;
        tcb->active_task = NULL;
@@ -36,7 +36,7 @@ static inline void xnarch_init_tcb(xnarchtcb_t * tcb)
        memset(&tcb->ts, 0, sizeof(tcb->ts));
 #ifdef CONFIG_XENO_HW_FPU
        tcb->user_fpu_owner = NULL;
-       tcb->fpup = (rthal_fpenv_t *) & tcb->ts.fpr[0];
+       tcb->fpup = &tcb->ts;
 #endif /* CONFIG_XENO_HW_FPU */
        /* Must be followed by xnarch_init_thread(). */
 }
diff --git a/include/asm-powerpc/hal.h b/include/asm-powerpc/hal.h
index afd061a..9a2123f 100644
--- a/include/asm-powerpc/hal.h
+++ b/include/asm-powerpc/hal.h
@@ -120,27 +120,11 @@ asmlinkage void rthal_thread_trampoline(void);
 
 #ifdef CONFIG_XENO_HW_FPU
 
-typedef struct rthal_fpenv {
-       /*
-        * This layout must follow exactely the definition of the FPU
-        * backup area in a PPC thread struct available from
-        * <arch/powerpc/include/asm/processor.h>. Specifically, fpr[]
-        * an fpscr struct must be contiguous in memory (see
-        * ksrc/arch/powerpc/fpu.S).
-        */
-       double          fpr[32][TS_FPRWIDTH];
-       struct {
-
-               unsigned int pad;
-               unsigned int val;       /* Floating point status */
-       } fpscr;
-} rthal_fpenv_t;
-
-void rthal_init_fpu(rthal_fpenv_t * fpuenv);
-
-void rthal_save_fpu(rthal_fpenv_t * fpuenv);
-
-void rthal_restore_fpu(rthal_fpenv_t * fpuenv);
+void rthal_init_fpu(struct thread_struct *ts);
+
+void rthal_save_fpu(struct thread_struct *ts);
+
+void rthal_restore_fpu(struct thread_struct *ts);
 
 #ifndef CONFIG_SMP
 #define rthal_get_fpu_owner(cur) last_task_used_math
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index f30198c..939a1a7 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -53,9 +53,11 @@ typedef struct xnarchtcb {   /* Per-thread arch-dependent 
block */
        /* Kernel mode side */
        struct thread_struct ts;        /* Holds kernel-based thread context. */
 #ifdef CONFIG_XENO_HW_FPU
-       /* We only care for basic FPU handling in kernel-space; Altivec
-          and SPE are not available to kernel-based nucleus threads. */
-       rthal_fpenv_t *fpup;    /* Pointer to the FPU backup area */
+       /*
+        * We only care for basic FPU handling in kernel-space; Altivec
+        * and SPE are not available to kernel-based nucleus threads.
+        */
+       struct thread_struct *fpup;     /* Pointer to the FPU backup container 
*/
        struct task_struct *user_fpu_owner;
        /*
         * Pointer to the FPU owner in userspace:
diff --git a/include/asm-powerpc/wrappers.h b/include/asm-powerpc/wrappers.h
index d518a04..b242729 100644
--- a/include/asm-powerpc/wrappers.h
+++ b/include/asm-powerpc/wrappers.h
@@ -177,8 +177,4 @@ typedef irq_handler_t rthal_irq_host_handler_t;
 #define rthal_irq_chip_end(irq)      ({ rthal_irq_descp(irq)->ipipe_end(irq, 
rthal_irq_descp(irq)); 0; })
 #endif
 
-#ifndef TS_FPRWIDTH
-#define TS_FPRWIDTH  1
-#endif
-
 #endif /* _XENO_ASM_POWERPC_WRAPPERS_H */
diff --git a/ksrc/arch/powerpc/fpu.S b/ksrc/arch/powerpc/fpu.S
index 87147d1..e0adf90 100644
--- a/ksrc/arch/powerpc/fpu.S
+++ b/ksrc/arch/powerpc/fpu.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001,2002,2003,2004 Philippe Gerum.
+ * Copyright (C) 2004-2009 Philippe Gerum.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,9 +17,17 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#include <linux/version.h>
 #include <asm/processor.h>
 #include <asm/cputable.h>
 #include <asm/ppc_asm.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#include "ppc_defs.h"
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
+#include <asm/offsets.h>
+#else
+#include <asm/asm-offsets.h>
+#endif
 
 #ifdef CONFIG_PPC601_SYNC_FIX
 #define SYNC                           \
@@ -31,44 +39,42 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
 #define        SYNC
 #endif /* CONFIG_PPC601_SYNC_FIX */
 
+#ifdef CONFIG_PPC64
+#ifndef MTMSRD
+#define MTMSRD(r)      mtmsrd  r
+#endif
+#ifndef MTFSF_L
+#define MTFSF_L(REG) \
+       .long (0xfc00058e | ((0xff) << 17) | ((REG) << 11) | (1 << 25))
+#endif
+#else /* !CONFIG_PPC64 */
 #ifndef MTMSRD
-#if defined(CONFIG_PPC64) || defined(CONFIG_PPC64BRIDGE)
-#define MTMSRD(r)      .long   (0x7c000164 + ((r) << 21))      /* mtmsrd */
-#else
 #define MTMSRD(r)      mtmsr   r
-#endif /* CONFIG_PPC64 || CONFIG_PPC64BRIDGE */
 #endif
+#ifndef MTFSF_L
+#define MTFSF_L(REG)   mtfsf   0xff, (REG)
+#endif
+#endif /* !CONFIG_PPC64 */
 
-#define RTHAL_FPSAVE(n, base)  stfd n,8*(n)(base)
-#define RTHAL_FPSAVE2(n, base) RTHAL_FPSAVE(n, base); RTHAL_FPSAVE(n+1, base)
-#define RTHAL_FPSAVE4(n, base) RTHAL_FPSAVE2(n, base); RTHAL_FPSAVE2(n+2, base)
-#define RTHAL_FPSAVE8(n, base) RTHAL_FPSAVE4(n, base); RTHAL_FPSAVE4(n+4, base)
-#define RTHAL_FPSAVE16(n, base)        RTHAL_FPSAVE8(n, base); 
RTHAL_FPSAVE8(n+8, base)
-#define RTHAL_FPSAVE32(n, base)        RTHAL_FPSAVE16(n, base); 
RTHAL_FPSAVE16(n+16, base)
+/*
+ * The following accessor has to work with ancient kernel versions,
+ * for which THREAD_FPSCR is not usable for 64bit save/restore.
+ */
+#define __FPSCR(base)  THREAD_FPR0+32*8(base)
 
-/* r3 = &tcb->fpuenv */
+/* r3 = &thread_struct (tcb->fpup) */
 _GLOBAL(rthal_save_fpu)
        mfmsr   r5
-       ori     r5,r5,MSR_FP            /* Re-enable use of FPU. */
-#ifdef CONFIG_PPC64BRIDGE
-       clrldi  r5,r5,1                 /* Turn off 64-bit mode. */
-#endif /* CONFIG_PPC64BRIDGE */
+       ori     r5,r5,MSR_FP
        SYNC
-       MTMSRD(r5)                      /* Enable use of fpu. */
+       MTMSRD(r5)
        isync
-       RTHAL_FPSAVE32(0,r3)
+       SAVE_32FPRS(0,r3)
        mffs    fr0
-       stfd    fr0,8*32(r3)
+       stfd    fr0,__FPSCR(r3)
        blr
 
-#define RTHAL_FPLOAD(n, base)  lfd n,8*(n)(base)
-#define RTHAL_FPLOAD2(n, base) RTHAL_FPLOAD(n, base); RTHAL_FPLOAD(n+1, base)
-#define RTHAL_FPLOAD4(n, base) RTHAL_FPLOAD2(n, base); RTHAL_FPLOAD2(n+2, base)
-#define RTHAL_FPLOAD8(n, base) RTHAL_FPLOAD4(n, base); RTHAL_FPLOAD4(n+4, base)
-#define RTHAL_FPLOAD16(n, base)        RTHAL_FPLOAD8(n, base); 
RTHAL_FPLOAD8(n+8, base)
-#define RTHAL_FPLOAD32(n, base)        RTHAL_FPLOAD16(n, base); 
RTHAL_FPLOAD16(n+16, base)
-
-/* r3 = &tcb->fpuenv */
+/* r3 = &thread_struct */
 _GLOBAL(rthal_init_fpu)
        mfmsr   r5
        ori     r5,r5,MSR_FP|MSR_FE0|MSR_FE1
@@ -77,17 +83,14 @@ _GLOBAL(rthal_init_fpu)
 
        /* Fallback wanted. */
        
-/* r3 = &tcb->fpuenv */
+/* r3 = &thread_struct (tcb->fpup) */
 _GLOBAL(rthal_restore_fpu)
        mfmsr   r5
-       ori     r5,r5,MSR_FP            /* Re-enable use of FPU. */
-#ifdef CONFIG_PPC64BRIDGE
-       clrldi  r5,r5,1                 /* Turn off 64-bit mode. */
-#endif /* CONFIG_PPC64BRIDGE */
+       ori     r5,r5,MSR_FP
        SYNC
-       MTMSRD(r5)                      /* Enable use of fpu. */
+       MTMSRD(r5)
        isync
-       lfd     fr0,8*32(r3)
-       mtfsf   0xff,0
-       RTHAL_FPLOAD32(0,r3)
+       lfd     fr0,__FPSCR(r3)
+       MTFSF_L(fr0)
+       REST_32FPRS(0,r3)
        blr


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to