Module: xenomai-jki
Branch: for-upstream
Commit: 902679fa73a7491ca4802673a9ea1b77e0cf5d1c
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=902679fa73a7491ca4802673a9ea1b77e0cf5d1c

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Wed Jan 30 14:33:03 2013 +0100

x86: Implement xsave-based FPU context switching

The ifdef-ery is necessary to consolidate 32 and 64 bit as well as
handle older gas versions without AVX instruction support.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 include/asm-x86/bits/pod.h    |   38 ++++++++++++++++++++++++++++++++++++++
 include/asm-x86/bits/thread.h |    2 ++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/include/asm-x86/bits/pod.h b/include/asm-x86/bits/pod.h
index 49c57a7..90e36f0 100644
--- a/include/asm-x86/bits/pod.h
+++ b/include/asm-x86/bits/pod.h
@@ -227,8 +227,31 @@ static inline void xnarch_init_fpu(xnarchtcb_t * tcb)
        }
 }
 
+#ifdef CONFIG_X86_64
+#define XSAVE_PREFIX   "0x48,"
+#define XSAVE_SUFFIX   "q"
+#else
+#define XSAVE_PREFIX
+#define XSAVE_SUFFIX
+#endif
+
 static inline void __save_i387(x86_fpustate *fpup)
 {
+#ifdef cpu_has_xsave
+       if (cpu_has_xsave) {
+#if defined(CONFIG_AS_AVX) || defined CONFIG_X86_32
+               asm volatile("xsave" XSAVE_SUFFIX " %0"
+                            : "=m" (fpup->xsave) : "a" (-1), "d" (-1)
+                            : "memory");
+#else /* !CONFIG_AS_AVX */
+               asm volatile(".byte " XSAVE_PREFIX "0x0f,0xae,0x27"
+                            : : "D" (&fpup->xsave), "m" (fpup->xsave),
+                                "a" (-1), "d" (-1)
+                            : "memory");
+#endif /* !CONFIG_AS_AVX */
+               return;
+       }
+#endif /* cpu_has_xsave */
 #ifdef CONFIG_X86_32
        if (cpu_has_fxsr)
                __asm__ __volatile__("fxsave %0; fnclex":"=m"(*fpup));
@@ -274,6 +297,21 @@ static inline void xnarch_save_fpu(xnarchtcb_t *tcb)
 
 static inline void __restore_i387(x86_fpustate *fpup)
 {
+#ifdef cpu_has_xsave
+       if (cpu_has_xsave) {
+#if defined(CONFIG_AS_AVX) || defined CONFIG_X86_32
+               asm volatile("xrstor" XSAVE_SUFFIX " %0"
+                            : : "m" (fpup->xsave), "a" (-1), "d" (-1)
+                            : "memory");
+#else /* !CONFIG_AS_AVX */
+               asm volatile(".byte " XSAVE_PREFIX "0x0f,0xae,0x2f"
+                            : : "D" (&fpup->xsave), "m" (fpup->xsave),
+                                "a" (-1), "d" (-1)
+                            : "memory");
+#endif /* !CONFIG_AS_AVX */
+               return;
+       }
+#endif /* cpu_has_xsave */
 #ifdef CONFIG_X86_32
        if (cpu_has_fxsr)
                __asm__ __volatile__("fxrstor %0": /* no output */
diff --git a/include/asm-x86/bits/thread.h b/include/asm-x86/bits/thread.h
index a23b94f..4099c69 100644
--- a/include/asm-x86/bits/thread.h
+++ b/include/asm-x86/bits/thread.h
@@ -34,6 +34,8 @@ static inline void xnarch_init_tcb(xnarchtcb_t * tcb)
        tcb->fpup = &tcb->i387;
        tcb->is_root = 0;
        tcb->mayday.ip = 0;
+       /* Required to initialize the xsave header */
+       memset(&tcb->i387, 0, sizeof(tcb->i387));
        /* Must be followed by xnarch_init_thread(). */
 }
 


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

Reply via email to