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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Jul  4 17:32:59 2013 +0200

cobalt: move fp test helpers to the uapi section

---

 include/cobalt/asm-arm/fptest.h              |   77 +-----------
 include/cobalt/asm-arm/uapi/Makefile.am      |    1 +
 include/cobalt/asm-arm/uapi/Makefile.in      |    1 +
 include/cobalt/asm-arm/uapi/fptest.h         |   61 +++++++++
 include/cobalt/asm-blackfin/fptest.h         |   22 +---
 include/cobalt/asm-blackfin/uapi/Makefile.am |    1 +
 include/cobalt/asm-blackfin/uapi/Makefile.in |    1 +
 include/cobalt/asm-blackfin/uapi/fptest.h    |   31 +++++
 include/cobalt/asm-nios2/fptest.h            |   22 +---
 include/cobalt/asm-nios2/uapi/Makefile.am    |    1 +
 include/cobalt/asm-nios2/uapi/Makefile.in    |    1 +
 include/cobalt/asm-nios2/uapi/fptest.h       |   31 +++++
 include/cobalt/asm-powerpc/fptest.h          |  103 +---------------
 include/cobalt/asm-powerpc/uapi/Makefile.am  |    1 +
 include/cobalt/asm-powerpc/uapi/Makefile.in  |    1 +
 include/cobalt/asm-powerpc/uapi/fptest.h     |  113 +++++++++++++++++
 include/cobalt/asm-sh/fptest.h               |   22 +---
 include/cobalt/asm-sh/uapi/Makefile.am       |    1 +
 include/cobalt/asm-sh/uapi/Makefile.in       |    1 +
 include/cobalt/asm-sh/uapi/fptest.h          |   31 +++++
 include/cobalt/asm-x86/fptest.h              |  168 +++-----------------------
 include/cobalt/asm-x86/uapi/Makefile.am      |    1 +
 include/cobalt/asm-x86/uapi/Makefile.in      |    1 +
 include/cobalt/asm-x86/uapi/fptest.h         |  132 ++++++++++++++++++++
 kernel/drivers/testing/switchtest.c          |   16 ++-
 lib/cobalt/arm/features.c                    |   27 ++++
 lib/cobalt/arm/xenomai/features.h            |    2 +
 lib/cobalt/blackfin/xenomai/features.h       |    5 +
 lib/cobalt/nios2/features.c                  |    3 +-
 lib/cobalt/nios2/xenomai/features.h          |    5 +
 lib/cobalt/powerpc/xenomai/features.h        |    5 +
 lib/cobalt/sh/xenomai/features.h             |    5 +
 lib/cobalt/x86/features.c                    |   28 ++++-
 lib/cobalt/x86/xenomai/features.h            |    2 +
 testsuite/switchtest/switchtest.c            |   27 ++--
 35 files changed, 548 insertions(+), 402 deletions(-)

diff --git a/include/cobalt/asm-arm/fptest.h b/include/cobalt/asm-arm/fptest.h
index 9bc4ced..af92b86 100644
--- a/include/cobalt/asm-arm/fptest.h
+++ b/include/cobalt/asm-arm/fptest.h
@@ -19,16 +19,17 @@
 #ifndef _COBALT_ASM_ARM_FPTEST_H
 #define _COBALT_ASM_ARM_FPTEST_H
 
-#ifdef __KERNEL__
-#include <linux/module.h>
+#include <linux/errno.h>
 #include <asm/hwcap.h>
 
 #ifdef CONFIG_VFP
 #define have_vfp (elf_hwcap & HWCAP_VFP)
 #else /* !CONFIG_VFP */
-#define have_vfp (0)
+#define have_vfp 0
 #endif /* !CONFIG_VFP */
 
+#include <asm/xenomai/uapi/fptest.h>
+
 static inline int fp_kernel_supported(void)
 {
        return 1;
@@ -43,75 +44,9 @@ static inline void fp_linux_end(void)
 {
 }
 
-static inline void fp_features_init(void)
+static inline int fp_detect(void)
 {
+       return have_vfp ? __COBALT_HAVE_VFP : 0;
 }
 
-#else /* !__KERNEL__ */
-#include <stdio.h>
-#include <string.h>
-#define printk(fmt, args...) fprintf(stderr, fmt, ## args)
-
-static int have_vfp;
-
-static void fp_features_init(void)
-{
-       char buffer[1024];
-       FILE *f = fopen("/proc/cpuinfo", "r");
-       if(!f)
-               return;
-
-       while(fgets(buffer, sizeof(buffer), f)) {
-               if(strncmp(buffer, "Features", sizeof("Features") - 1))
-                       continue;
-
-               if (strstr(buffer, "vfp")) {
-                       have_vfp = 1;
-                       break;
-               }
-       }
-
-       fclose(f);
-}
-
-#endif /* !__KERNEL__ */
-
-static inline void fp_regs_set(unsigned val)
-{
-       if (have_vfp) {
-               unsigned long long e[16];
-               unsigned i;
-
-               for (i = 0; i < 16; i++)
-                       e[i] = val;
-
-               /* vldm %0!, {d0-d15},
-                  AKA fldmiax %0!, {d0-d15} */
-               __asm__ __volatile__("ldc p11, cr0, [%0],#32*4":
-                                    "=r"(i): "0"(&e[0]): "memory");
-       }
-}
-
-static inline unsigned fp_regs_check(unsigned val)
-{
-       unsigned result = val;
-
-       if (have_vfp) {
-               unsigned long long e[16];
-               unsigned i;
-
-               /* vstm %0!, {d0-d15},
-                  AKA fstmiax %0!, {d0-d15} */
-               __asm__ __volatile__("stc p11, cr0, [%0],#32*4":
-                                    "=r"(i): "0"(&e[0]): "memory");
-
-               for (i = 0; i < 16; i++)
-                       if (e[i] != val) {
-                               printk("d%d: %llu != %u\n", i, e[i], val);
-                               result = e[i];
-                       }
-       }
-
-       return result;
-}
 #endif /* _COBALT_ASM_ARM_FPTEST_H */
diff --git a/include/cobalt/asm-arm/uapi/Makefile.am 
b/include/cobalt/asm-arm/uapi/Makefile.am
index eb7d364..feaf288 100644
--- a/include/cobalt/asm-arm/uapi/Makefile.am
+++ b/include/cobalt/asm-arm/uapi/Makefile.am
@@ -3,5 +3,6 @@ includesubdir = $(includedir)/asm-arm/uapi
 includesub_HEADERS =   \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h       \
        tsc.h
diff --git a/include/cobalt/asm-arm/uapi/Makefile.in 
b/include/cobalt/asm-arm/uapi/Makefile.in
index 759ca12..0b8c14e 100644
--- a/include/cobalt/asm-arm/uapi/Makefile.in
+++ b/include/cobalt/asm-arm/uapi/Makefile.in
@@ -276,6 +276,7 @@ includesubdir = $(includedir)/asm-arm/uapi
 includesub_HEADERS = \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h       \
        tsc.h
 
diff --git a/include/cobalt/asm-arm/uapi/fptest.h 
b/include/cobalt/asm-arm/uapi/fptest.h
new file mode 100644
index 0000000..ee52843
--- /dev/null
+++ b/include/cobalt/asm-arm/uapi/fptest.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#ifndef _COBALT_ASM_ARM_UAPI_FPTEST_H
+#define _COBALT_ASM_ARM_UAPI_FPTEST_H
+
+#define __COBALT_HAVE_VFP  0x1
+
+static inline void fp_regs_set(int features, unsigned int val)
+{
+       unsigned long long e[16];
+       unsigned int i;
+
+       if (features & __COBALT_HAVE_VFP) {
+               for (i = 0; i < 16; i++)
+                       e[i] = val;
+
+               /* vldm %0!, {d0-d15},
+                  AKA fldmiax %0!, {d0-d15} */
+               __asm__ __volatile__("ldc p11, cr0, [%0],#32*4":
+                                    "=r"(i): "0"(&e[0]): "memory");
+       }
+}
+
+static inline unsigned int fp_regs_check(int features, unsigned int val,
+                                        int (*report)(const char *fmt, ...))
+{
+       unsigned int result = val, i;
+       unsigned long long e[16];
+
+       if (features & __COBALT_HAVE_VFP) {
+               /* vstm %0!, {d0-d15},
+                  AKA fstmiax %0!, {d0-d15} */
+               __asm__ __volatile__("stc p11, cr0, [%0],#32*4":
+                                    "=r"(i): "0"(&e[0]): "memory");
+
+               for (i = 0; i < 16; i++)
+                       if (e[i] != val) {
+                               report("d%d: %llu != %u\n", i, e[i], val);
+                               result = e[i];
+                       }
+       }
+
+       return result;
+}
+
+#endif /* !_COBALT_ASM_ARM_UAPI_FPTEST_H */
diff --git a/include/cobalt/asm-blackfin/fptest.h 
b/include/cobalt/asm-blackfin/fptest.h
index 4bc0c9c..35ad84e 100644
--- a/include/cobalt/asm-blackfin/fptest.h
+++ b/include/cobalt/asm-blackfin/fptest.h
@@ -19,8 +19,8 @@
 #ifndef _COBALT_ASM_BLACKFIN_FPTEST_H
 #define _COBALT_ASM_BLACKFIN_FPTEST_H
 
-#ifdef __KERNEL__
-#include <linux/module.h>
+#include <linux/errno.h>
+#include <asm/xenomai/uapi/fptest.h>
 
 static inline int fp_kernel_supported(void)
 {
@@ -36,22 +36,4 @@ static inline void fp_linux_end(void)
 {
 }
 
-#else /* !__KERNEL__ */
-#include <stdio.h>
-#define printk printf
-#endif /* !__KERNEL__ */
-
-static inline void fp_features_init(void)
-{
-}
-
-static inline void fp_regs_set(unsigned val)
-{
-}
-
-static inline unsigned fp_regs_check(unsigned val)
-{
-    return val;
-}
-
 #endif /* _COBALT_ASM_BLACKFIN_FPTEST_H */
diff --git a/include/cobalt/asm-blackfin/uapi/Makefile.am 
b/include/cobalt/asm-blackfin/uapi/Makefile.am
index e07a3bb..fbc7e01 100644
--- a/include/cobalt/asm-blackfin/uapi/Makefile.am
+++ b/include/cobalt/asm-blackfin/uapi/Makefile.am
@@ -3,4 +3,5 @@ includesubdir = $(includedir)/asm-blackfin/uapi
 includesub_HEADERS =   \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
diff --git a/include/cobalt/asm-blackfin/uapi/Makefile.in 
b/include/cobalt/asm-blackfin/uapi/Makefile.in
index 5af6c48..da23dbe 100644
--- a/include/cobalt/asm-blackfin/uapi/Makefile.in
+++ b/include/cobalt/asm-blackfin/uapi/Makefile.in
@@ -276,6 +276,7 @@ includesubdir = $(includedir)/asm-blackfin/uapi
 includesub_HEADERS = \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
 
 all: all-am
diff --git a/include/cobalt/asm-blackfin/uapi/fptest.h 
b/include/cobalt/asm-blackfin/uapi/fptest.h
new file mode 100644
index 0000000..025051e
--- /dev/null
+++ b/include/cobalt/asm-blackfin/uapi/fptest.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#ifndef _COBALT_ASM_BLACKFIN_UAPI_FPTEST_H
+#define _COBALT_ASM_BLACKFIN_UAPI_FPTEST_H
+
+static inline void fp_regs_set(int features, unsigned int val)
+{
+}
+
+static inline unsigned int fp_regs_check(int features, unsigned int val,
+                                        int (*report)(const char *fmt, ...))
+{
+       return val;
+}
+
+#endif /* !_COBALT_ASM_BLACKFIN_UAPI_FPTEST_H */
diff --git a/include/cobalt/asm-nios2/fptest.h 
b/include/cobalt/asm-nios2/fptest.h
index 68f19e0..7fa6e7b 100644
--- a/include/cobalt/asm-nios2/fptest.h
+++ b/include/cobalt/asm-nios2/fptest.h
@@ -19,8 +19,8 @@
 #ifndef _COBALT_ASM_NIOS2_FPTEST_H
 #define _COBALT_ASM_NIOS2_FPTEST_H
 
-#ifdef __KERNEL__
-#include <linux/module.h>
+#include <linux/errno.h>
+#include <asm/xenomai/uapi/fptest.h>
 
 static inline int fp_kernel_supported(void)
 {
@@ -36,22 +36,4 @@ static inline void fp_linux_end(void)
 {
 }
 
-#else /* !__KERNEL__ */
-#include <stdio.h>
-#define printk printf
-#endif /* !__KERNEL__ */
-
-static inline void fp_features_init(void)
-{
-}
-
-static inline void fp_regs_set(unsigned val)
-{
-}
-
-static inline unsigned fp_regs_check(unsigned val)
-{
-    return val;
-}
-
 #endif /* _COBALT_ASM_NIOS2_FPTEST_H */
diff --git a/include/cobalt/asm-nios2/uapi/Makefile.am 
b/include/cobalt/asm-nios2/uapi/Makefile.am
index 8a3fc2a..85c500c 100644
--- a/include/cobalt/asm-nios2/uapi/Makefile.am
+++ b/include/cobalt/asm-nios2/uapi/Makefile.am
@@ -3,4 +3,5 @@ includesubdir = $(includedir)/asm-nios2/uapi
 includesub_HEADERS =   \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
diff --git a/include/cobalt/asm-nios2/uapi/Makefile.in 
b/include/cobalt/asm-nios2/uapi/Makefile.in
index 578775a..e0a9d48 100644
--- a/include/cobalt/asm-nios2/uapi/Makefile.in
+++ b/include/cobalt/asm-nios2/uapi/Makefile.in
@@ -276,6 +276,7 @@ includesubdir = $(includedir)/asm-nios2/uapi
 includesub_HEADERS = \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
 
 all: all-am
diff --git a/include/cobalt/asm-nios2/uapi/fptest.h 
b/include/cobalt/asm-nios2/uapi/fptest.h
new file mode 100644
index 0000000..1f0cd39
--- /dev/null
+++ b/include/cobalt/asm-nios2/uapi/fptest.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#ifndef _COBALT_ASM_NIOS2_UAPI_FPTEST_H
+#define _COBALT_ASM_NIOS2_UAPI_FPTEST_H
+
+static inline void fp_regs_set(int features, unsigned int val)
+{
+}
+
+static inline unsigned int fp_regs_check(int features, unsigned int val,
+                                        int (*report)(const char *fmt, ...))
+{
+       return val;
+}
+
+#endif /* !_COBALT_ASM_NIOS2_UAPI_FPTEST_H */
diff --git a/include/cobalt/asm-powerpc/fptest.h 
b/include/cobalt/asm-powerpc/fptest.h
index a7d5fdd..5113f3d 100644
--- a/include/cobalt/asm-powerpc/fptest.h
+++ b/include/cobalt/asm-powerpc/fptest.h
@@ -19,8 +19,8 @@
 #ifndef _COBALT_ASM_POWERPC_FPTEST_H
 #define _COBALT_ASM_POWERPC_FPTEST_H
 
-#ifdef __KERNEL__
-#include <linux/module.h>
+#include <linux/errno.h>
+#include <asm/xenomai/uapi/fptest.h>
 
 static inline int fp_kernel_supported(void)
 {
@@ -48,104 +48,9 @@ static inline void fp_linux_end(void)
 {
 }
 
-#else /* !__KERNEL__ */
-#include <stdint.h>
-#include <stdio.h>
-#define printk printf
-#endif /* !__KERNEL__ */
-
-static inline void fp_features_init(void)
-{
-}
-
-static inline void fp_regs_set(unsigned val)
+static inline int fp_detect(void)
 {
-       uint64_t fpval = val;
-       __asm__ __volatile__("lfd       0, %0\n"
-                            "  fmr     1, 0\n"
-                            "  fmr     2, 0\n"
-                            "  fmr     3, 0\n"
-                            "  fmr     4, 0\n"
-                            "  fmr     5, 0\n"
-                            "  fmr     6, 0\n"
-                            "  fmr     7, 0\n"
-                            "  fmr     8, 0\n"
-                            "  fmr     9, 0\n"
-                            "  fmr     10, 0\n"
-                            "  fmr     11, 0\n"
-                            "  fmr     12, 0\n"
-                            "  fmr     13, 0\n"
-                            "  fmr     14, 0\n"
-                            "  fmr     15, 0\n"
-                            "  fmr     16, 0\n"
-                            "  fmr     17, 0\n"
-                            "  fmr     18, 0\n"
-                            "  fmr     19, 0\n"
-                            "  fmr     20, 0\n"
-                            "  fmr     21, 0\n"
-                            "  fmr     22, 0\n"
-                            "  fmr     23, 0\n"
-                            "  fmr     24, 0\n"
-                            "  fmr     25, 0\n"
-                            "  fmr     26, 0\n"
-                            "  fmr     27, 0\n"
-                            "  fmr     28, 0\n"
-                            "  fmr     29, 0\n"
-                            "  fmr     30, 0\n"
-                            "  fmr     31, 0\n"::"m"(fpval));
-}
-
-#define FPTEST_REGVAL(n) {                                             \
-       uint64_t t;                                                     \
-       __asm__ __volatile__("  stfd    " #n ", %0" : "=m" (t));        \
-       e[n] = (unsigned)t;                                             \
-       }
-
-static inline unsigned fp_regs_check(unsigned val)
-{
-       unsigned i, result = val;
-       uint32_t e[32];
-
-       FPTEST_REGVAL(0);
-       FPTEST_REGVAL(1);
-       FPTEST_REGVAL(2);
-       FPTEST_REGVAL(3);
-       FPTEST_REGVAL(4);
-       FPTEST_REGVAL(5);
-       FPTEST_REGVAL(6);
-       FPTEST_REGVAL(7);
-       FPTEST_REGVAL(8);
-       FPTEST_REGVAL(9);
-       FPTEST_REGVAL(10);
-       FPTEST_REGVAL(11);
-       FPTEST_REGVAL(12);
-       FPTEST_REGVAL(13);
-       FPTEST_REGVAL(14);
-       FPTEST_REGVAL(15);
-       FPTEST_REGVAL(16);
-       FPTEST_REGVAL(17);
-       FPTEST_REGVAL(18);
-       FPTEST_REGVAL(19);
-       FPTEST_REGVAL(20);
-       FPTEST_REGVAL(21);
-       FPTEST_REGVAL(22);
-       FPTEST_REGVAL(23);
-       FPTEST_REGVAL(24);
-       FPTEST_REGVAL(25);
-       FPTEST_REGVAL(26);
-       FPTEST_REGVAL(27);
-       FPTEST_REGVAL(28);
-       FPTEST_REGVAL(29);
-       FPTEST_REGVAL(30);
-       FPTEST_REGVAL(31);
-
-       for (i = 0; i < 32; i++)
-               if (e[i] != val) {
-                       printk("r%d: %u != %u\n", i, e[i], val);
-                       result = e[i];
-               }
-
-       return result;
+       return 0;
 }
 
 #endif /* !_COBALT_ASM_POWERPC_FPTEST_H */
diff --git a/include/cobalt/asm-powerpc/uapi/Makefile.am 
b/include/cobalt/asm-powerpc/uapi/Makefile.am
index 3856607..c7d6946 100644
--- a/include/cobalt/asm-powerpc/uapi/Makefile.am
+++ b/include/cobalt/asm-powerpc/uapi/Makefile.am
@@ -3,4 +3,5 @@ includesubdir = $(includedir)/asm-powerpc/uapi
 includesub_HEADERS =   \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
diff --git a/include/cobalt/asm-powerpc/uapi/Makefile.in 
b/include/cobalt/asm-powerpc/uapi/Makefile.in
index f89ad75..ad1dd3a 100644
--- a/include/cobalt/asm-powerpc/uapi/Makefile.in
+++ b/include/cobalt/asm-powerpc/uapi/Makefile.in
@@ -276,6 +276,7 @@ includesubdir = $(includedir)/asm-powerpc/uapi
 includesub_HEADERS = \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
 
 all: all-am
diff --git a/include/cobalt/asm-powerpc/uapi/fptest.h 
b/include/cobalt/asm-powerpc/uapi/fptest.h
new file mode 100644
index 0000000..50f2394
--- /dev/null
+++ b/include/cobalt/asm-powerpc/uapi/fptest.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#ifndef _COBALT_ASM_POWERPC_UAPI_FPTEST_H
+#define _COBALT_ASM_POWERPC_UAPI_FPTEST_H
+
+static inline void fp_regs_set(int features, unsigned int val)
+{
+       unsigned long long fpval = val;
+
+       __asm__ __volatile__("lfd       0, %0\n"
+                            "  fmr     1, 0\n"
+                            "  fmr     2, 0\n"
+                            "  fmr     3, 0\n"
+                            "  fmr     4, 0\n"
+                            "  fmr     5, 0\n"
+                            "  fmr     6, 0\n"
+                            "  fmr     7, 0\n"
+                            "  fmr     8, 0\n"
+                            "  fmr     9, 0\n"
+                            "  fmr     10, 0\n"
+                            "  fmr     11, 0\n"
+                            "  fmr     12, 0\n"
+                            "  fmr     13, 0\n"
+                            "  fmr     14, 0\n"
+                            "  fmr     15, 0\n"
+                            "  fmr     16, 0\n"
+                            "  fmr     17, 0\n"
+                            "  fmr     18, 0\n"
+                            "  fmr     19, 0\n"
+                            "  fmr     20, 0\n"
+                            "  fmr     21, 0\n"
+                            "  fmr     22, 0\n"
+                            "  fmr     23, 0\n"
+                            "  fmr     24, 0\n"
+                            "  fmr     25, 0\n"
+                            "  fmr     26, 0\n"
+                            "  fmr     27, 0\n"
+                            "  fmr     28, 0\n"
+                            "  fmr     29, 0\n"
+                            "  fmr     30, 0\n"
+                            "  fmr     31, 0\n"::"m"(fpval));
+}
+
+#define FPTEST_REGVAL(n) {                                             \
+       unsigned long long t;                                           \
+       __asm__ __volatile__("  stfd    " #n ", %0" : "=m" (t));        \
+       e[n] = (unsigned)t;                                             \
+       }
+
+static inline unsigned int fp_regs_check(int features, unsigned int val,
+                                        int (*report)(const char *fmt, ...))
+{
+       unsigned int i, result = val;
+       unsigned int e[32];
+
+       FPTEST_REGVAL(0);
+       FPTEST_REGVAL(1);
+       FPTEST_REGVAL(2);
+       FPTEST_REGVAL(3);
+       FPTEST_REGVAL(4);
+       FPTEST_REGVAL(5);
+       FPTEST_REGVAL(6);
+       FPTEST_REGVAL(7);
+       FPTEST_REGVAL(8);
+       FPTEST_REGVAL(9);
+       FPTEST_REGVAL(10);
+       FPTEST_REGVAL(11);
+       FPTEST_REGVAL(12);
+       FPTEST_REGVAL(13);
+       FPTEST_REGVAL(14);
+       FPTEST_REGVAL(15);
+       FPTEST_REGVAL(16);
+       FPTEST_REGVAL(17);
+       FPTEST_REGVAL(18);
+       FPTEST_REGVAL(19);
+       FPTEST_REGVAL(20);
+       FPTEST_REGVAL(21);
+       FPTEST_REGVAL(22);
+       FPTEST_REGVAL(23);
+       FPTEST_REGVAL(24);
+       FPTEST_REGVAL(25);
+       FPTEST_REGVAL(26);
+       FPTEST_REGVAL(27);
+       FPTEST_REGVAL(28);
+       FPTEST_REGVAL(29);
+       FPTEST_REGVAL(30);
+       FPTEST_REGVAL(31);
+
+       for (i = 0; i < 32; i++)
+               if (e[i] != val) {
+                       report("r%d: %u != %u\n", i, e[i], val);
+                       result = e[i];
+               }
+
+       return result;
+}
+
+#endif /* !_COBALT_ASM_POWERPC_UAPI_FPTEST_H */
diff --git a/include/cobalt/asm-sh/fptest.h b/include/cobalt/asm-sh/fptest.h
index 0a5aef8..b7fed69 100644
--- a/include/cobalt/asm-sh/fptest.h
+++ b/include/cobalt/asm-sh/fptest.h
@@ -19,8 +19,8 @@
 #ifndef _COBALT_ASM_SH_FPTEST_H
 #define _COBALT_ASM_SH_FPTEST_H
 
-#ifdef __KERNEL__
-#include <linux/module.h>
+#include <linux/errno.h>
+#include <asm/xenomai/uapi/fptest.h>
 
 static inline int fp_kernel_supported(void)
 {
@@ -36,22 +36,4 @@ static inline void fp_linux_end(void)
 {
 }
 
-#else /* !__KERNEL__ */
-#include <stdio.h>
-#define printk printf
-#endif /* !__KERNEL__ */
-
-static inline void fp_features_init(void)
-{
-}
-
-static inline void fp_regs_set(unsigned val)
-{
-}
-
-static inline unsigned fp_regs_check(unsigned val)
-{
-       return val;
-}
-
 #endif /* _COBALT_ASM_SH_FPTEST_H */
diff --git a/include/cobalt/asm-sh/uapi/Makefile.am 
b/include/cobalt/asm-sh/uapi/Makefile.am
index 4362d26..8ec4989 100644
--- a/include/cobalt/asm-sh/uapi/Makefile.am
+++ b/include/cobalt/asm-sh/uapi/Makefile.am
@@ -3,4 +3,5 @@ includesubdir = $(includedir)/asm-sh/uapi
 includesub_HEADERS =   \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
diff --git a/include/cobalt/asm-sh/uapi/Makefile.in 
b/include/cobalt/asm-sh/uapi/Makefile.in
index ac581d8..4182f99 100644
--- a/include/cobalt/asm-sh/uapi/Makefile.in
+++ b/include/cobalt/asm-sh/uapi/Makefile.in
@@ -276,6 +276,7 @@ includesubdir = $(includedir)/asm-sh/uapi
 includesub_HEADERS = \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
 
 all: all-am
diff --git a/include/cobalt/asm-sh/uapi/fptest.h 
b/include/cobalt/asm-sh/uapi/fptest.h
new file mode 100644
index 0000000..cf42d1b
--- /dev/null
+++ b/include/cobalt/asm-sh/uapi/fptest.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#ifndef _COBALT_ASM_SH_UAPI_FPTEST_H
+#define _COBALT_ASM_SH_UAPI_FPTEST_H
+
+static inline void fp_regs_set(int features, unsigned int val)
+{
+}
+
+static inline unsigned int fp_regs_check(int features, unsigned int val,
+                                        int (*report)(const char *fmt, ...))
+{
+       return val;
+}
+
+#endif /* !_COBALT_ASM_SH_UAPI_FPTEST_H */
diff --git a/include/cobalt/asm-x86/fptest.h b/include/cobalt/asm-x86/fptest.h
index b4c9ce0..7de65da 100644
--- a/include/cobalt/asm-x86/fptest.h
+++ b/include/cobalt/asm-x86/fptest.h
@@ -19,22 +19,10 @@
 #ifndef _COBALT_ASM_X86_FPTEST_H
 #define _COBALT_ASM_X86_FPTEST_H
 
-#ifdef __KERNEL__
-#include <linux/module.h>
+#include <linux/errno.h>
 #include <asm/i387.h>
 #include <asm/processor.h>
-
-#ifndef cpu_has_xmm2
-#ifdef cpu_has_sse2
-#define cpu_has_xmm2 cpu_has_sse2
-#else
-#define cpu_has_xmm2 0
-#endif
-#endif
-
-#ifndef cpu_has_avx
-#define cpu_has_avx 0
-#endif
+#include <asm/xenomai/uapi/fptest.h>
 
 static inline int fp_kernel_supported(void)
 {
@@ -70,147 +58,27 @@ static inline void fp_linux_end(void)
        kernel_fpu_end();
 }
 
-static inline void fp_features_init(void)
+static inline int fp_detect(void)
 {
-}
-
-#else /* !__KERNEL__ */
-#include <stdio.h>
-#include <stdint.h>
-#define printk printf
-
-#define FP_FEATURE_SSE2                        0x01
-#define FP_FEATURE_AVX                 0x02
-
-static unsigned long fp_features;
-
-#define cpu_has_xmm2 (fp_features & FP_FEATURE_SSE2)
-#define cpu_has_avx (fp_features & FP_FEATURE_AVX)
-
-static void fp_features_init(void)
-{
-       char buffer[1024];
-       FILE *f = fopen("/proc/cpuinfo", "r");
-       if(!f)
-               return;
-
-       while(fgets(buffer, sizeof(buffer), f)) {
-               if(strncmp(buffer, "flags", sizeof("flags") - 1))
-                       continue;
-
-               if (strstr(buffer, "sse2"))
-                       fp_features |= FP_FEATURE_SSE2;
-               if (strstr(buffer, "avx"))
-                       fp_features |= FP_FEATURE_AVX;
-               break;
-       }
+       int features = 0;
 
-       fclose(f);
-}
-#endif /* !__KERNEL__ */
-
-static inline void fp_regs_set(unsigned val)
-{
-       uint64_t vec[4] = { val, 0, val, 0 };
-       unsigned i;
+#ifndef cpu_has_xmm2
+#ifdef cpu_has_sse2
+#define cpu_has_xmm2 cpu_has_sse2
+#else
+#define cpu_has_xmm2 0
+#endif
+#endif
+       if (cpu_has_xmm2)
+               features |= __COBALT_HAVE_SSE2;
 
-       for (i = 0; i < 8; i++)
-               __asm__ __volatile__("fildl %0": /* no output */ :"m"(val));
+#ifndef cpu_has_avx
+#define cpu_has_avx 0
+#endif
        if (cpu_has_avx)
-               __asm__ __volatile__(
-                       "vmovupd %0,%%ymm0;"
-                       "vmovupd %0,%%ymm1;"
-                       "vmovupd %0,%%ymm2;"
-                       "vmovupd %0,%%ymm3;"
-                       "vmovupd %0,%%ymm4;"
-                       "vmovupd %0,%%ymm5;"
-                       "vmovupd %0,%%ymm6;"
-                       "vmovupd %0,%%ymm7;"
-                       : : "m" (vec[0]));
-       else if (cpu_has_xmm2)
-               __asm__ __volatile__(
-                       "movupd %0,%%xmm0;"
-                       "movupd %0,%%xmm1;"
-                       "movupd %0,%%xmm2;"
-                       "movupd %0,%%xmm3;"
-                       "movupd %0,%%xmm4;"
-                       "movupd %0,%%xmm5;"
-                       "movupd %0,%%xmm6;"
-                       "movupd %0,%%xmm7;"
-                       : : "m" (vec[0]));
-}
-
-static inline unsigned fp_regs_check(unsigned val)
-{
-       unsigned i, result = val;
-       uint64_t vec[8][4];
-       unsigned e[8];
-
-       for (i = 0; i < 8; i++)
-               __asm__ __volatile__("fistpl %0":"=m"(e[7 - i]));
-       if (cpu_has_avx) {
-               __asm__ __volatile__(
-                       "vmovupd %%ymm0,%0;"
-                       "vmovupd %%ymm1,%1;"
-                       "vmovupd %%ymm2,%2;"
-                       "vmovupd %%ymm3,%3;"
-                       "vmovupd %%ymm4,%4;"
-                       "vmovupd %%ymm5,%5;"
-                       "vmovupd %%ymm6,%6;"
-                       "vmovupd %%ymm7,%7;"
-                       : "=m" (vec[0][0]), "=m" (vec[1][0]),
-                         "=m" (vec[2][0]), "=m" (vec[3][0]),
-                         "=m" (vec[4][0]), "=m" (vec[5][0]),
-                         "=m" (vec[6][0]), "=m" (vec[7][0]));
-       } else if (cpu_has_xmm2) {
-               __asm__ __volatile__(
-                       "movupd %%xmm0,%0;"
-                       "movupd %%xmm1,%1;"
-                       "movupd %%xmm2,%2;"
-                       "movupd %%xmm3,%3;"
-                       "movupd %%xmm4,%4;"
-                       "movupd %%xmm5,%5;"
-                       "movupd %%xmm6,%6;"
-                       "movupd %%xmm7,%7;"
-                       : "=m" (vec[0][0]), "=m" (vec[1][0]),
-                         "=m" (vec[2][0]), "=m" (vec[3][0]),
-                         "=m" (vec[4][0]), "=m" (vec[5][0]),
-                         "=m" (vec[6][0]), "=m" (vec[7][0]));
-       }
-
-       for (i = 0; i < 8; i++)
-               if (e[i] != val) {
-                       printk("r%d: %u != %u\n", i, e[i], val);
-                       result = e[i];
-               }
-
-       if (cpu_has_avx) {
-               for (i = 0; i < 8; i++) {
-                       int error = 0;
-                       if (vec[i][0] != val) {
-                               result = vec[i][0];
-                               error = 1;
-                       }
-                       if (vec[i][2] != val) {
-                               result = vec[i][2];
-                               error = 1;
-                       }
-                       if (error)
-                               printk("ymm%d: %llu/%llu != %u/%u\n",
-                                      i, (unsigned long long)vec[i][0],
-                                      (unsigned long long)vec[i][2],
-                                      val, val);
-               }
-       } else if (cpu_has_xmm2) {
-               for (i = 0; i < 8; i++)
-                       if (vec[i][0] != val) {
-                               printk("xmm%d: %llu != %u\n",
-                                      i, (unsigned long long)vec[i][0], val);
-                               result = vec[i][0];
-                       }
-       }
+               features |= __COBALT_HAVE_AVX;
 
-       return result;
+       return features;
 }
 
 #endif /* _COBALT_ASM_X86_FPTEST_H */
diff --git a/include/cobalt/asm-x86/uapi/Makefile.am 
b/include/cobalt/asm-x86/uapi/Makefile.am
index 51dfb2f..d245edf 100644
--- a/include/cobalt/asm-x86/uapi/Makefile.am
+++ b/include/cobalt/asm-x86/uapi/Makefile.am
@@ -3,4 +3,5 @@ includesubdir = $(includedir)/asm-x86/uapi
 includesub_HEADERS =   \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
diff --git a/include/cobalt/asm-x86/uapi/Makefile.in 
b/include/cobalt/asm-x86/uapi/Makefile.in
index 58ce511..cea3267 100644
--- a/include/cobalt/asm-x86/uapi/Makefile.in
+++ b/include/cobalt/asm-x86/uapi/Makefile.in
@@ -276,6 +276,7 @@ includesubdir = $(includedir)/asm-x86/uapi
 includesub_HEADERS = \
        arith.h         \
        features.h      \
+       fptest.h        \
        syscall.h
 
 all: all-am
diff --git a/include/cobalt/asm-x86/uapi/fptest.h 
b/include/cobalt/asm-x86/uapi/fptest.h
new file mode 100644
index 0000000..2753332
--- /dev/null
+++ b/include/cobalt/asm-x86/uapi/fptest.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#ifndef _COBALT_ASM_X86_UAPI_FPTEST_H
+#define _COBALT_ASM_X86_UAPI_FPTEST_H
+
+#define __COBALT_HAVE_SSE2     0x1
+#define __COBALT_HAVE_AVX      0x2
+
+static inline void fp_regs_set(int features, unsigned int val)
+{
+       unsigned long long vec[4] = { val, 0, val, 0 };
+       unsigned i;
+
+       for (i = 0; i < 8; i++)
+               __asm__ __volatile__("fildl %0": /* no output */ :"m"(val));
+
+       if (features & __COBALT_HAVE_AVX) {
+               __asm__ __volatile__(
+                       "vmovupd %0,%%ymm0;"
+                       "vmovupd %0,%%ymm1;"
+                       "vmovupd %0,%%ymm2;"
+                       "vmovupd %0,%%ymm3;"
+                       "vmovupd %0,%%ymm4;"
+                       "vmovupd %0,%%ymm5;"
+                       "vmovupd %0,%%ymm6;"
+                       "vmovupd %0,%%ymm7;"
+                       : : "m" (vec[0]));
+       } else if (features & __COBALT_HAVE_SSE2) {
+               __asm__ __volatile__(
+                       "movupd %0,%%xmm0;"
+                       "movupd %0,%%xmm1;"
+                       "movupd %0,%%xmm2;"
+                       "movupd %0,%%xmm3;"
+                       "movupd %0,%%xmm4;"
+                       "movupd %0,%%xmm5;"
+                       "movupd %0,%%xmm6;"
+                       "movupd %0,%%xmm7;"
+                       : : "m" (vec[0]));
+       }
+}
+
+static inline unsigned int fp_regs_check(int features, unsigned int val,
+                                        int (*report)(const char *fmt, ...))
+{
+       unsigned long long vec[8][4];
+       unsigned int i, result = val;
+       unsigned e[8];
+
+       for (i = 0; i < 8; i++)
+               __asm__ __volatile__("fistpl %0":"=m"(e[7 - i]));
+
+       if (features & __COBALT_HAVE_AVX) {
+               __asm__ __volatile__(
+                       "vmovupd %%ymm0,%0;"
+                       "vmovupd %%ymm1,%1;"
+                       "vmovupd %%ymm2,%2;"
+                       "vmovupd %%ymm3,%3;"
+                       "vmovupd %%ymm4,%4;"
+                       "vmovupd %%ymm5,%5;"
+                       "vmovupd %%ymm6,%6;"
+                       "vmovupd %%ymm7,%7;"
+                       : "=m" (vec[0][0]), "=m" (vec[1][0]),
+                         "=m" (vec[2][0]), "=m" (vec[3][0]),
+                         "=m" (vec[4][0]), "=m" (vec[5][0]),
+                         "=m" (vec[6][0]), "=m" (vec[7][0]));
+       } else if (features & __COBALT_HAVE_SSE2) {
+               __asm__ __volatile__(
+                       "movupd %%xmm0,%0;"
+                       "movupd %%xmm1,%1;"
+                       "movupd %%xmm2,%2;"
+                       "movupd %%xmm3,%3;"
+                       "movupd %%xmm4,%4;"
+                       "movupd %%xmm5,%5;"
+                       "movupd %%xmm6,%6;"
+                       "movupd %%xmm7,%7;"
+                       : "=m" (vec[0][0]), "=m" (vec[1][0]),
+                         "=m" (vec[2][0]), "=m" (vec[3][0]),
+                         "=m" (vec[4][0]), "=m" (vec[5][0]),
+                         "=m" (vec[6][0]), "=m" (vec[7][0]));
+       }
+
+       for (i = 0; i < 8; i++)
+               if (e[i] != val) {
+                       report("r%d: %u != %u\n", i, e[i], val);
+                       result = e[i];
+               }
+
+       if (features & __COBALT_HAVE_AVX) {
+               for (i = 0; i < 8; i++) {
+                       int error = 0;
+                       if (vec[i][0] != val) {
+                               result = vec[i][0];
+                               error = 1;
+                       }
+                       if (vec[i][2] != val) {
+                               result = vec[i][2];
+                               error = 1;
+                       }
+                       if (error)
+                               report("ymm%d: %llu/%llu != %u/%u\n",
+                                      i, (unsigned long long)vec[i][0],
+                                      (unsigned long long)vec[i][2],
+                                      val, val);
+               }
+       } else if (features & __COBALT_HAVE_SSE2) {
+               for (i = 0; i < 8; i++)
+                       if (vec[i][0] != val) {
+                               report("xmm%d: %llu != %u\n",
+                                      i, (unsigned long long)vec[i][0], val);
+                               result = vec[i][0];
+                       }
+       }
+
+       return result;
+}
+
+#endif /* _COBALT_ASM_X86_UAPI_FPTEST_H */
diff --git a/kernel/drivers/testing/switchtest.c 
b/kernel/drivers/testing/switchtest.c
index 381bce9..fe996cf 100644
--- a/kernel/drivers/testing/switchtest.c
+++ b/kernel/drivers/testing/switchtest.c
@@ -43,6 +43,8 @@ static unsigned int start_index;
 module_param(start_index, uint, 0400);
 MODULE_PARM_DESC(start_index, "First device instance number to be used");
 
+static int fp_features;
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("gilles.chanteperd...@laposte.net");
 
@@ -253,9 +255,9 @@ static int rtswitch_to_nrt(rtswitch_context_t *ctx,
                        expected = from_idx + 500 +
                                (ctx->switches_count % 4000000) * 1000;
 
-                       fp_regs_set(expected);
+                       fp_regs_set(fp_features, expected);
                        rtdm_event_signal(&to->rt_synch);
-                       fp_val = fp_regs_check(expected);
+                       fp_val = fp_regs_check(fp_features, expected, printk);
                        fp_linux_end();
 
                        if(down_interruptible(&from->nrt_synch))
@@ -278,9 +280,9 @@ static int rtswitch_to_nrt(rtswitch_context_t *ctx,
                        barrier();
 
                        fp_linux_begin();
-                       fp_regs_set(expected);
+                       fp_regs_set(fp_features, expected);
                        rtdm_event_signal(&to->rt_synch);
-                       fp_val = fp_regs_check(expected);
+                       fp_val = fp_regs_check(fp_features, expected, printk);
                        fp_linux_end();
 
                        if (down_interruptible(&from->nrt_synch))
@@ -386,7 +388,7 @@ static void rtswitch_ktask(void *cookie)
 
        for(;;) {
                if (task->base.flags & RTTST_SWTEST_USE_FPU)
-                       fp_regs_set(task->base.index + i * 1000);
+                       fp_regs_set(fp_features, task->base.index + i * 1000);
 
                switch(i % 3) {
                case 0:
@@ -410,7 +412,7 @@ static void rtswitch_ktask(void *cookie)
                        unsigned fp_val, expected;
 
                        expected = task->base.index + i * 1000;
-                       fp_val = fp_regs_check(expected);
+                       fp_val = fp_regs_check(fp_features, expected, printk);
 
                        if (fp_val != expected) {
                                if (task->base.flags & RTTST_SWTEST_FREEZE)
@@ -750,7 +752,7 @@ int __init __switchtest_init(void)
 {
        int err;
 
-       fp_features_init();
+       fp_features = fp_detect();
 
        do {
                snprintf(device.device_name, RTDM_MAX_DEVNAME_LEN,
diff --git a/lib/cobalt/arm/features.c b/lib/cobalt/arm/features.c
index b740288..027107c 100644
--- a/lib/cobalt/arm/features.c
+++ b/lib/cobalt/arm/features.c
@@ -21,11 +21,14 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <string.h>
+#include <string.h>
 #include <unistd.h>
 #include <limits.h>
 #include <cobalt/wrappers.h>
 #include <xenomai/syscall.h>
 #include <xenomai/tsc.h>
+#include <xenomai/features.h>
+#include <asm/xenomai/uapi/fptest.h>
 #include "internal.h"
 
 struct __xn_full_tscinfo __xn_tscinfo = {
@@ -119,3 +122,27 @@ void cobalt_check_features(struct xnfeatinfo *finfo)
        __STD(close(fd));
 #endif /* CONFIG_XENO_ARM_TSC_TYPE */
 }
+
+int cobalt_fp_detect(void)
+{
+       char buffer[1024];
+       int features = 0;
+       FILE *fp;
+
+       fp = fopen("/proc/cpuinfo", "r");
+       if (fp == NULL)
+               return 0;
+
+       while (fgets(buffer, sizeof(buffer), fp)) {
+               if(strncmp(buffer, "Features", sizeof("Features") - 1))
+                       continue;
+               if (strstr(buffer, "vfp")) {
+                       features |= __COBALT_HAVE_VFP;
+                       break;
+               }
+       }
+
+       fclose(fp);
+
+       return features;
+}
diff --git a/lib/cobalt/arm/xenomai/features.h 
b/lib/cobalt/arm/xenomai/features.h
index 185ac55..44c6b3f 100644
--- a/lib/cobalt/arm/xenomai/features.h
+++ b/lib/cobalt/arm/xenomai/features.h
@@ -61,4 +61,6 @@
 
 #include <asm/xenomai/uapi/features.h>
 
+int cobalt_fp_detect(void);
+
 #endif /* !_LIB_COBALT_ARM_FEATURES_H */
diff --git a/lib/cobalt/blackfin/xenomai/features.h 
b/lib/cobalt/blackfin/xenomai/features.h
index 97c8566..908e97a 100644
--- a/lib/cobalt/blackfin/xenomai/features.h
+++ b/lib/cobalt/blackfin/xenomai/features.h
@@ -22,4 +22,9 @@
 #include <xeno_config.h>
 #include <asm/xenomai/uapi/features.h>
 
+static inline int cobalt_fp_detect(void)
+{
+       return 0;
+}
+
 #endif /* !_LIB_COBALT_BLACKFIN_FEATURES_H */
diff --git a/lib/cobalt/nios2/features.c b/lib/cobalt/nios2/features.c
index af1a028..9eda8ea 100644
--- a/lib/cobalt/nios2/features.c
+++ b/lib/cobalt/nios2/features.c
@@ -24,7 +24,8 @@
 #include <unistd.h>
 #include <limits.h>
 #include <cobalt/wrappers.h>
-#include <asm/xenomai/uapi/features.h>
+#include <xenomai/features.h>
+#include <asm/xenomai/uapi/fptest.h>
 #include "internal.h"
 
 __attribute__((weak)) volatile void *__cobalt_nios2_hrclock = NULL;
diff --git a/lib/cobalt/nios2/xenomai/features.h 
b/lib/cobalt/nios2/xenomai/features.h
index 0b1e82b..6fa7842 100644
--- a/lib/cobalt/nios2/xenomai/features.h
+++ b/lib/cobalt/nios2/xenomai/features.h
@@ -22,4 +22,9 @@
 #include <xeno_config.h>
 #include <asm/xenomai/uapi/features.h>
 
+static inline int cobalt_fp_detect(void)
+{
+       return 0;
+}
+
 #endif /* !_LIB_COBALT_NIOS2_FEATURES_H */
diff --git a/lib/cobalt/powerpc/xenomai/features.h 
b/lib/cobalt/powerpc/xenomai/features.h
index 70e32d2..4b75707 100644
--- a/lib/cobalt/powerpc/xenomai/features.h
+++ b/lib/cobalt/powerpc/xenomai/features.h
@@ -22,4 +22,9 @@
 #include <xeno_config.h>
 #include <asm/xenomai/uapi/features.h>
 
+static inline int cobalt_fp_detect(void)
+{
+       return 0;
+}
+
 #endif /* !_LIB_COBALT_POWERPC_FEATURES_H */
diff --git a/lib/cobalt/sh/xenomai/features.h b/lib/cobalt/sh/xenomai/features.h
index 14548a7..1a3f6e1 100644
--- a/lib/cobalt/sh/xenomai/features.h
+++ b/lib/cobalt/sh/xenomai/features.h
@@ -22,4 +22,9 @@
 #include <xeno_config.h>
 #include <asm/xenomai/uapi/features.h>
 
+static inline int cobalt_fp_detect(void)
+{
+       return 0;
+}
+
 #endif /* !_LIB_COBALT_SH_FEATURES_H */
diff --git a/lib/cobalt/x86/features.c b/lib/cobalt/x86/features.c
index f2bd8ef..ff34fac 100644
--- a/lib/cobalt/x86/features.c
+++ b/lib/cobalt/x86/features.c
@@ -20,7 +20,8 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
-#include <asm/xenomai/uapi/features.h>
+#include <xenomai/features.h>
+#include <asm/xenomai/uapi/fptest.h>
 #include "internal.h"
 
 void cobalt_check_features(struct xnfeatinfo *finfo)
@@ -42,3 +43,28 @@ void cobalt_check_features(struct xnfeatinfo *finfo)
        exit(1);
 #endif /* __i386__ && CONFIG_XENO_X86_VSYSCALL */
 }
+
+int cobalt_fp_detect(void)
+{
+       char buffer[1024];
+       int features = 0;
+       FILE *fp;
+
+       fp = fopen("/proc/cpuinfo", "r");
+       if(fp == NULL)
+               return 0;
+
+       while (fgets(buffer, sizeof(buffer), fp)) {
+               if(strncmp(buffer, "flags", sizeof("flags") - 1))
+                       continue;
+               if (strstr(buffer, "sse2"))
+                       features |= __COBALT_HAVE_SSE2;
+               if (strstr(buffer, "avx"))
+                       features |= __COBALT_HAVE_AVX;
+               break;
+       }
+
+       fclose(fp);
+
+       return features;
+}
diff --git a/lib/cobalt/x86/xenomai/features.h 
b/lib/cobalt/x86/xenomai/features.h
index cea4cfd..9a54339 100644
--- a/lib/cobalt/x86/xenomai/features.h
+++ b/lib/cobalt/x86/xenomai/features.h
@@ -22,4 +22,6 @@
 #include <xeno_config.h>
 #include <asm/xenomai/uapi/features.h>
 
+int cobalt_fp_detect(void);
+
 #endif /* !_LIB_COBALT_X86_FEATURES_H */
diff --git a/testsuite/switchtest/switchtest.c 
b/testsuite/switchtest/switchtest.c
index c271025..013f150 100644
--- a/testsuite/switchtest/switchtest.c
+++ b/testsuite/switchtest/switchtest.c
@@ -12,8 +12,8 @@
 #include <semaphore.h>
 #include <setjmp.h>
 #include <getopt.h>
-#include <xeno_config.h>
-#include <asm/xenomai/fptest.h>
+#include <xenomai/features.h>
+#include <asm/xenomai/uapi/fptest.h>
 #include <cobalt/trace.h>
 #include <rtdm/rttesting.h>
 
@@ -83,6 +83,7 @@ static struct timespec start;
 static pthread_mutex_t headers_lock;
 static unsigned long data_lines = 21;
 static unsigned freeze_on_error;
+static int fp_features;
 
 static inline void clean_exit(int retval)
 {
@@ -333,7 +334,7 @@ static void *sleeper_switcher(void *cookie)
 
                expected = rtsw.from + i * 1000;
                if (param->fp & UFPS)
-                       fp_regs_set(expected);
+                       fp_regs_set(fp_features, expected);
                err = ioctl(fd, RTTST_RTIOC_SWTEST_SWITCH_TO, &rtsw);
                while (err == -1 && errno == EINTR)
                        err = ioctl(fd, RTTST_RTIOC_SWTEST_PEND, &param->swt);
@@ -347,7 +348,7 @@ static void *sleeper_switcher(void *cookie)
                        clean_exit(EXIT_FAILURE);
                }
                if (param->fp & UFPS) {
-                       fp_val = fp_regs_check(expected);
+                       fp_val = fp_regs_check(fp_features, expected, printf);
                        if (fp_val != expected)
                                handle_bad_fpreg(param->cpu, fp_val);
                }
@@ -459,7 +460,7 @@ static void *rtup(void *cookie)
 
                expected = rtsw.from + i * 1000;
                if (param->fp & UFPP)
-                       fp_regs_set(expected);
+                       fp_regs_set(fp_features, expected);
                err = ioctl(fd, RTTST_RTIOC_SWTEST_SWITCH_TO, &rtsw);
                while (err == -1 && errno == EINTR)
                        err = ioctl(fd, RTTST_RTIOC_SWTEST_PEND, &param->swt);
@@ -473,7 +474,7 @@ static void *rtup(void *cookie)
                        clean_exit(EXIT_FAILURE);
                }
                if (param->fp & UFPP) {
-                       fp_val = fp_regs_check(expected);
+                       fp_val = fp_regs_check(fp_features, expected, printf);
                        if (fp_val != expected)
                                handle_bad_fpreg(param->cpu, fp_val);
                }
@@ -545,7 +546,7 @@ static void *rtus(void *cookie)
 
                expected = rtsw.from + i * 1000;
                if (param->fp & UFPS)
-                       fp_regs_set(expected);
+                       fp_regs_set(fp_features, expected);
                err = ioctl(fd, RTTST_RTIOC_SWTEST_SWITCH_TO, &rtsw);
                while (err == -1 && errno == EINTR)
                        err = ioctl(fd, RTTST_RTIOC_SWTEST_PEND, &param->swt);
@@ -559,7 +560,7 @@ static void *rtus(void *cookie)
                        clean_exit(EXIT_FAILURE);
                }
                if (param->fp & UFPS) {
-                       fp_val = fp_regs_check(expected);
+                       fp_val = fp_regs_check(fp_features, expected, printf);
                        if (fp_val != expected)
                                handle_bad_fpreg(param->cpu, fp_val);
                }
@@ -631,7 +632,7 @@ static void *rtuo(void *cookie)
 
                expected = rtsw.from + i * 1000;
                if ((mode && param->fp & UFPP) || (!mode && param->fp & UFPS))
-                       fp_regs_set(expected);
+                       fp_regs_set(fp_features, expected);
                err = ioctl(fd, RTTST_RTIOC_SWTEST_SWITCH_TO, &rtsw);
                while (err == -1 && errno == EINTR)
                        err = ioctl(fd, RTTST_RTIOC_SWTEST_PEND, &param->swt);
@@ -645,7 +646,7 @@ static void *rtuo(void *cookie)
                        clean_exit(EXIT_FAILURE);
                }
                if ((mode && param->fp & UFPP) || (!mode && param->fp & UFPS)) {
-                       fp_val = fp_regs_check(expected);
+                       fp_val = fp_regs_check(fp_features, expected, printf);
                        if (fp_val != expected)
                                handle_bad_fpreg(param->cpu, fp_val);
                }
@@ -1072,8 +1073,8 @@ static void *check_fpu_thread(void *cookie)
                return NULL;
        }
        signal(SIGILL, illegal_instruction);
-       fp_regs_set(1);
-       check = fp_regs_check(2);
+       fp_regs_set(fp_features, 1);
+       check = fp_regs_check(fp_features, 2, printf);
        signal(SIGILL, SIG_DFL);
        if (check != 1) {
                fprintf(stderr,
@@ -1145,7 +1146,7 @@ int main(int argc, const char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       fp_features_init();
+       fp_features = cobalt_fp_detect();
 
        /* Parse command line options. */
        opterr = 0;


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

Reply via email to