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

Author: Dmitriy Cherkasov <dmit...@mperpetuo.com>
Date:   Wed May  6 15:27:23 2015 -0700

cobalt/arm64: populate arch/arm64 with a copy of arch/arm.

kernel/cobalt/arch/arm -> kernel/cobalt/arch/arm64
lib/cobalt/arch/arm -> lib/cobalt/arch/arm64

---

 configure.ac                                       |   12 +-
 kernel/cobalt/arch/arm64/Kconfig                   |   40 +++
 kernel/cobalt/arch/arm64/Makefile                  |    5 +
 .../arch/arm64/include/asm/xenomai/calibration.h   |   59 ++++
 .../arch/arm64/include/asm/xenomai/features.h      |   30 ++
 .../cobalt/arch/arm64/include/asm/xenomai/fptest.h |   52 +++
 .../arch/arm64/include/asm/xenomai/machine.h       |   85 +++++
 .../arch/arm64/include/asm/xenomai/syscall.h       |   74 ++++
 .../arch/arm64/include/asm/xenomai/syscall32.h     |   24 ++
 .../cobalt/arch/arm64/include/asm/xenomai/thread.h |  123 +++++++
 .../arch/arm64/include/asm/xenomai/uapi/arith.h    |  142 ++++++++
 .../arch/arm64/include/asm/xenomai/uapi/features.h |   43 +++
 .../arch/arm64/include/asm/xenomai/uapi/fptest.h   |   61 ++++
 .../arch/arm64/include/asm/xenomai/uapi/syscall.h  |   34 ++
 .../arch/arm64/include/asm/xenomai/uapi/tsc.h      |   25 ++
 .../arch/arm64/include/asm/xenomai/wrappers.h      |   27 ++
 kernel/cobalt/arch/arm64/machine.c                 |  119 +++++++
 kernel/cobalt/arch/arm64/mayday.c                  |  146 ++++++++
 kernel/cobalt/arch/arm64/switch.S                  |  167 +++++++++
 kernel/cobalt/arch/arm64/syscall.c                 |   53 +++
 kernel/cobalt/arch/arm64/thread.c                  |  355 ++++++++++++++++++++
 lib/cobalt/arch/Makefile.am                        |    2 +-
 lib/cobalt/arch/arm64/Makefile.am                  |   13 +
 lib/cobalt/arch/arm64/features.c                   |  102 ++++++
 lib/cobalt/arch/arm64/include/Makefile.am          |    2 +
 lib/cobalt/arch/arm64/include/asm/Makefile.am      |    2 +
 .../arch/arm64/include/asm/xenomai/Makefile.am     |    5 +
 .../arch/arm64/include/asm/xenomai/features.h      |   62 ++++
 .../arch/arm64/include/asm/xenomai/syscall.h       |  138 ++++++++
 lib/cobalt/arch/arm64/include/asm/xenomai/tsc.h    |   48 +++
 30 files changed, 2047 insertions(+), 3 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6593f5d..97bebf0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -139,6 +139,10 @@ case "$build_for" in
        target_cpu_arch=arm
        CONFIG_XENO_DEFAULT_PERIOD=1000000
        ;;
+ aarch64-*)
+       target_cpu_arch=arm64
+       CONFIG_XENO_DEFAULT_PERIOD=1000000
+       ;;
  x86_64-*|amd64-*)
        use_tls=yes
        target_cpu_arch=x86
@@ -361,7 +365,7 @@ fi
 
 dnl VSYSCALL (default: enabled) for Cobalt/x86
 
-if test $XENO_TARGET_ARCH = x86 -a $rtcore_type = cobalt; then
+if test $target_cpu_arch = x86 -a $rtcore_type = cobalt; then
   CONFIG_XENO_X86_VSYSCALL=y
   AC_MSG_CHECKING(for x86 VSYSCALL availability)
   AC_ARG_ENABLE(x86-vsyscall,
@@ -788,7 +792,7 @@ dnl Autoconf-generated symbols have been listed.
 AH_BOTTOM([#endif /* __IN_XENO__ */])
 
 if test $rtcore_type = cobalt; then
-   XENO_USER_CFLAGS="-I$topdir/lib/cobalt/arch/$XENO_TARGET_ARCH/include 
-I$topdir/kernel/cobalt/arch/$XENO_TARGET_ARCH/include $XENO_USER_CFLAGS"
+   XENO_USER_CFLAGS="-I$topdir/lib/cobalt/arch/$target_cpu_arch/include 
-I$topdir/kernel/cobalt/arch/$target_cpu_arch/include $XENO_USER_CFLAGS"
    XENO_COBALT_CFLAGS="$XENO_USER_CFLAGS"
    case "$build_for" in
     i*86*-*) XENO_COBALT_CFLAGS="$XENO_COBALT_CFLAGS -fno-omit-frame-pointer";;
@@ -868,6 +872,10 @@ AC_CONFIG_FILES([ \
        lib/cobalt/arch/arm/include/Makefile \
        lib/cobalt/arch/arm/include/asm/Makefile \
        lib/cobalt/arch/arm/include/asm/xenomai/Makefile \
+       lib/cobalt/arch/arm64/Makefile \
+       lib/cobalt/arch/arm64/include/Makefile \
+       lib/cobalt/arch/arm64/include/asm/Makefile \
+       lib/cobalt/arch/arm64/include/asm/xenomai/Makefile \
        lib/cobalt/arch/powerpc/Makefile \
        lib/cobalt/arch/powerpc/include/Makefile \
        lib/cobalt/arch/powerpc/include/asm/Makefile \
diff --git a/kernel/cobalt/arch/arm64/Kconfig b/kernel/cobalt/arch/arm64/Kconfig
new file mode 100644
index 0000000..dc6485d
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/Kconfig
@@ -0,0 +1,40 @@
+source "kernel/xenomai/Kconfig"
+source "drivers/xenomai/Kconfig"
+
+menu "Machine/platform-specific options"
+
+config XENO_ARCH_UNLOCKED_SWITCH
+       bool "Unlocked context switch"
+       default y
+       help
+       The Cobalt core may allow non-atomic execution of the
+       machine-dependent context switching code, so that other CPUs
+       and/or local interrupts may execute concurrently.
+
+       This option reduces interrupt latency when costly cache and
+       TLB flushes are required to switch context.
+
+       You definitely want to enable that option on low-end ARM
+       platforms.
+endmenu
+
+config IPIPE_WANT_PREEMPTIBLE_SWITCH
+       bool
+       default y if XENO_ARCH_UNLOCKED_SWITCH
+       default n if !XENO_ARCH_UNLOCKED_SWITCH
+
+config IPIPE_WANT_ACTIVE_MM
+       def_bool y
+
+config XENO_ARCH_WANT_TIP
+       def_bool y
+
+config XENO_ARCH_FPU
+       def_bool VFP
+
+config XENO_ARCH_SYS3264
+        def_bool n
+
+config XENO_ARCH_OUTOFLINE_XNLOCK
+       bool
+       default y
diff --git a/kernel/cobalt/arch/arm64/Makefile 
b/kernel/cobalt/arch/arm64/Makefile
new file mode 100644
index 0000000..f2e4e20
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_XENOMAI) += xenomai.o
+
+xenomai-y := machine.o mayday.o thread.o switch.o syscall.o
+
+ccflags-y := -Iarch/arm/xenomai/include -Iinclude/xenomai
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/calibration.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/calibration.h
new file mode 100644
index 0000000..e303a04
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/calibration.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2001,2002,2003,2004,2005 Philippe Gerum <r...@xenomai.org>.
+ *
+ * ARM port
+ *   Copyright (C) 2005 Stelian Pop
+ *
+ * Xenomai is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_ARM_ASM_CALIBRATION_H
+#define _COBALT_ARM_ASM_CALIBRATION_H
+
+unsigned int omap_rev(void);
+#define cpu_is_omap44xx() ((omap_rev() & 0xff) == 0x44)
+
+static inline void xnarch_get_latencies(struct xnclock_gravity *p)
+{
+       unsigned int ulat;
+#if CONFIG_XENO_OPT_TIMING_SCHEDLAT != 0
+       ulat = CONFIG_XENO_OPT_TIMING_SCHEDLAT;
+#elif defined(CONFIG_ARCH_AT91RM9200)
+       ulat = 8500;
+#elif defined(CONFIG_ARCH_AT91SAM9263)
+       ulat = 11000;
+#elif defined(CONFIG_SOC_IMX6Q)
+       ulat = 6000;
+#elif defined(CONFIG_ARCH_MX51)
+       ulat = 5000;
+#elif defined(CONFIG_ARCH_MX53)
+       ulat = 5000;
+#elif defined(CONFIG_ARCH_MX6)
+       ulat = 2000;
+#elif defined(CONFIG_SOC_IMX7)
+       ulat = 2000;
+#elif defined(CONFIG_SOC_LS1021A)
+       ulat = 2800;
+#elif defined(CONFIG_ARCH_OMAP)
+       ulat = cpu_is_omap44xx() ? 2500 : 5000;
+#else
+       ulat = 9500;    /* XXX sane? */
+#endif
+       p->user = xnclock_ns_to_ticks(&nkclock, ulat);
+       p->kernel = xnclock_ns_to_ticks(&nkclock, 
CONFIG_XENO_OPT_TIMING_KSCHEDLAT);
+       p->irq = xnclock_ns_to_ticks(&nkclock, CONFIG_XENO_OPT_TIMING_IRQLAT);
+}
+
+#endif /* !_COBALT_ARM_ASM_CALIBRATION_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/features.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/features.h
new file mode 100644
index 0000000..d485286
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/features.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2005 Philippe Gerum <r...@xenomai.org>.
+ *
+ * ARM port
+ *   Copyright (C) 2005 Stelian Pop
+ *
+ * Xenomai is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_ARM_ASM_FEATURES_H
+#define _COBALT_ARM_ASM_FEATURES_H
+
+struct cobalt_featinfo;
+static inline void collect_arch_features(struct cobalt_featinfo *p) { }
+
+#include <asm/xenomai/uapi/features.h>
+
+#endif /* !_COBALT_ARM_ASM_FEATURES_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/fptest.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/fptest.h
new file mode 100644
index 0000000..a76f1e6
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/fptest.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperd...@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 the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_ARM_ASM_FPTEST_H
+#define _COBALT_ARM_ASM_FPTEST_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
+#endif /* !CONFIG_VFP */
+
+#include <asm/xenomai/uapi/fptest.h>
+
+static inline int fp_kernel_supported(void)
+{
+       return 1;
+}
+
+static inline int fp_linux_begin(void)
+{
+       return -ENOSYS;
+}
+
+static inline void fp_linux_end(void)
+{
+}
+
+static inline int fp_detect(void)
+{
+       return have_vfp ? __COBALT_HAVE_VFP : 0;
+}
+
+#endif /* _COBALT_ARM_ASM_FPTEST_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/machine.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/machine.h
new file mode 100644
index 0000000..d6e965f
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/machine.h
@@ -0,0 +1,85 @@
+/**
+ *   Copyright &copy; 2002-2004 Philippe Gerum.
+ *
+ *   ARM port
+ *     Copyright (C) 2005 Stelian Pop
+ *
+ *   Xenomai is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation, Inc., 675 Mass Ave,
+ *   Cambridge MA 02139, USA; either version 2 of the License, or (at
+ *   your option) any later version.
+ *
+ *   Xenomai 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
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Xenomai; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ *   02111-1307, USA.
+ */
+#ifndef _COBALT_ARM_ASM_MACHINE_H
+#define _COBALT_ARM_ASM_MACHINE_H
+
+#include <linux/version.h>
+#include <asm/byteorder.h>
+
+#define XNARCH_HOST_TICK_IRQ __ipipe_hrtimer_irq
+
+#include <asm/barrier.h>
+#include <asm/compiler.h>
+#include <asm/cmpxchg.h>
+#include <asm/switch_to.h>
+#include <asm/system_info.h>
+#include <asm/system_misc.h>
+#include <asm/timex.h>
+#include <asm/processor.h>
+#include <asm/ipipe.h>
+#include <asm/mach/irq.h>
+#include <asm/cacheflush.h>
+
+#define xnarch_cache_aliasing() cache_is_vivt()
+
+#if __LINUX_ARM_ARCH__ < 5
+static inline __attribute_const__ unsigned long ffnz(unsigned long x)
+{
+       int r = 0;
+
+       if (!x)
+               return 0;
+       if (!(x & 0xffff)) {
+               x >>= 16;
+               r += 16;
+       }
+       if (!(x & 0xff)) {
+               x >>= 8;
+               r += 8;
+       }
+       if (!(x & 0xf)) {
+               x >>= 4;
+               r += 4;
+       }
+       if (!(x & 3)) {
+               x >>= 2;
+               r += 2;
+       }
+       if (!(x & 1)) {
+               x >>= 1;
+               r += 1;
+       }
+       return r;
+}
+#else
+static inline __attribute_const__ unsigned long ffnz(unsigned long ul)
+{
+       int __r;
+       __asm__("clz\t%0, %1" : "=r" (__r) : "r"(ul & (-ul)) : "cc");
+       return 31 - __r;
+}
+#endif
+
+#include <asm-generic/xenomai/machine.h>
+
+#endif /* !_COBALT_ARM_ASM_MACHINE_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/syscall.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/syscall.h
new file mode 100644
index 0000000..d80df77
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/syscall.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2001,2002,2003,2004 Philippe Gerum <r...@xenomai.org>.
+ *
+ * ARM port
+ *   Copyright (C) 2005 Stelian Pop
+ *
+ * Xenomai is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_ARM_ASM_SYSCALL_H
+#define _COBALT_ARM_ASM_SYSCALL_H
+
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+#include <asm/ptrace.h>
+#include <asm-generic/xenomai/syscall.h>
+
+#ifndef __ARM_NR_ipipe
+/* Legacy pipelines do not define this. */
+#define __ARM_NR_ipipe (__NR_SYSCALL_BASE + XENO_ARM_SYSCALL)
+#endif
+
+#define __xn_reg_sys(__regs)   ((__regs)->ARM_ORIG_r0)
+/* In OABI_COMPAT mode, handle both OABI and EABI userspace syscalls */
+#ifdef CONFIG_OABI_COMPAT
+#define __xn_syscall_p(__regs) (((__regs)->ARM_r7 == __NR_OABI_SYSCALL_BASE + 
XENO_ARM_SYSCALL) || \
+                                ((__regs)->ARM_r7 == __ARM_NR_ipipe))
+#else /* !CONFIG_OABI_COMPAT */
+#define __xn_syscall_p(__regs) ((__regs)->ARM_r7 == __ARM_NR_ipipe)
+#endif /* !CONFIG_OABI_COMPAT */
+#define __xn_syscall(__regs)   (__xn_reg_sys(__regs) & ~__COBALT_SYSCALL_BIT)
+
+#define __xn_reg_rval(__regs)  ((__regs)->ARM_r0)
+#define __xn_reg_arg1(__regs)  ((__regs)->ARM_r1)
+#define __xn_reg_arg2(__regs)  ((__regs)->ARM_r2)
+#define __xn_reg_arg3(__regs)  ((__regs)->ARM_r3)
+#define __xn_reg_arg4(__regs)  ((__regs)->ARM_r4)
+#define __xn_reg_arg5(__regs)  ((__regs)->ARM_r5)
+#define __xn_reg_pc(__regs)    ((__regs)->ARM_ip)
+#define __xn_reg_sp(__regs)    ((__regs)->ARM_sp)
+
+static inline void __xn_error_return(struct pt_regs *regs, int v)
+{
+       __xn_reg_rval(regs) = v;
+}
+
+static inline void __xn_status_return(struct pt_regs *regs, long v)
+{
+       __xn_reg_rval(regs) = v;
+}
+
+static inline int __xn_interrupted_p(struct pt_regs *regs)
+{
+       return __xn_reg_rval(regs) == -EINTR;
+}
+
+int xnarch_local_syscall(unsigned long a1, unsigned long a2,
+                        unsigned long a3, unsigned long a4,
+                        unsigned long a5);
+
+#endif /* !_COBALT_ARM_ASM_SYSCALL_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/syscall32.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/syscall32.h
new file mode 100644
index 0000000..95c5a11
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/syscall32.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 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 the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_ARM_ASM_SYSCALL32_H
+#define _COBALT_ARM_ASM_SYSCALL32_H
+
+#include <asm-generic/xenomai/syscall32.h>
+
+#endif /* !_COBALT_ARM_ASM_SYSCALL32_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/thread.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/thread.h
new file mode 100644
index 0000000..11439a3
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/thread.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2005 Stelian Pop
+ *
+ * Xenomai is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_ARM_ASM_THREAD_H
+#define _COBALT_ARM_ASM_THREAD_H
+
+#include <asm-generic/xenomai/thread.h>
+
+#ifdef CONFIG_XENO_ARCH_FPU
+#ifdef CONFIG_VFP
+#include <asm/vfp.h>
+#endif /* CONFIG_VFP */
+#endif /* !CONFIG_XENO_ARCH_FPU */
+
+struct xnarchtcb {
+       struct xntcb core;
+#ifdef CONFIG_XENO_ARCH_FPU
+#ifdef CONFIG_VFP
+       union vfp_state *fpup;
+#define xnarch_fpu_ptr(tcb)     ((tcb)->fpup)
+#else
+#define xnarch_fpu_ptr(tcb)     NULL
+#endif
+#endif
+       struct {
+               unsigned long pc;
+               unsigned long r0;
+#ifdef __ARM_EABI__
+               unsigned long r7;
+#endif
+#ifdef CONFIG_ARM_THUMB
+               unsigned long psr;
+#endif
+       } mayday;
+};
+
+#define xnarch_fault_regs(d)   ((d)->regs)
+#define xnarch_fault_trap(d)   ((d)->exception)
+#define xnarch_fault_code(d)   (0)
+#define xnarch_fault_pc(d)     ((d)->regs->ARM_pc - (thumb_mode((d)->regs) ? 2 
: 4)) /* XXX ? */
+
+#define xnarch_fault_pf_p(d)   ((d)->exception == IPIPE_TRAP_ACCESS)
+#define xnarch_fault_bp_p(d)   ((current->ptrace & PT_PTRACED) &&      \
+                                ((d)->exception == IPIPE_TRAP_BREAK || \
+                                 (d)->exception == IPIPE_TRAP_UNDEFINSTR))
+
+#define xnarch_fault_notify(d) (!xnarch_fault_bp_p(d))
+
+void xnarch_switch_to(struct xnthread *out, struct xnthread *in);
+
+static inline void xnarch_enter_root(struct xnthread *root) { }
+
+int xnarch_escalate(void);
+
+#if defined(CONFIG_XENO_ARCH_FPU) && defined(CONFIG_VFP)
+
+static inline void xnarch_init_root_tcb(struct xnthread *thread)
+{
+       struct xnarchtcb *tcb = xnthread_archtcb(thread);
+       tcb->fpup = NULL;
+}
+
+void xnarch_init_shadow_tcb(struct xnthread *thread);
+
+int xnarch_fault_fpu_p(struct ipipe_trap_data *d);
+
+void xnarch_leave_root(struct xnthread *root);
+
+void xnarch_save_fpu(struct xnthread *thread);
+
+void xnarch_switch_fpu(struct xnthread *from, struct xnthread *thread);
+
+int xnarch_handle_fpu_fault(struct xnthread *from, 
+                       struct xnthread *to, struct ipipe_trap_data *d);
+
+#else /* !CONFIG_XENO_ARCH_FPU || !CONFIG_VFP */
+
+static inline void xnarch_init_root_tcb(struct xnthread *thread) { }
+static inline void xnarch_init_shadow_tcb(struct xnthread *thread) { }
+
+/*
+ * Userland may raise FPU faults with FPU-enabled kernels, regardless
+ * of whether real-time threads actually use FPU, so we simply ignore
+ * these faults.
+ */
+static inline int xnarch_fault_fpu_p(struct ipipe_trap_data *d)
+{
+       return 0;
+}
+
+static inline void xnarch_leave_root(struct xnthread *root) { }
+
+static inline void xnarch_save_fpu(struct xnthread *thread) { }
+
+static inline void xnarch_switch_fpu(struct xnthread *f, struct xnthread *t) { 
}
+
+static inline int xnarch_handle_fpu_fault(struct xnthread *from, 
+                                       struct xnthread *to, struct 
ipipe_trap_data *d)
+{
+       return 0;
+}
+#endif /*  !CONFIG_XENO_ARCH_FPU || !CONFIG_VFP */
+
+static inline void xnarch_enable_kfpu(void) { }
+
+static inline void xnarch_disable_kfpu(void) { }
+
+#endif /* !_COBALT_ARM_ASM_THREAD_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/arith.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/arith.h
new file mode 100644
index 0000000..cf897b4
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/arith.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2008 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_ARM_ASM_UAPI_ARITH_H
+#define _COBALT_ARM_ASM_UAPI_ARITH_H
+
+#include <asm/xenomai/uapi/features.h>
+
+#if __LINUX_ARM_ARCH__ >= 4 && (!defined(CONFIG_THUMB2_KERNEL) || 
!defined(CONFIG_FTRACE))
+static inline __attribute__((__const__)) unsigned long long
+mach_arm_nodiv_ullimd(const unsigned long long op,
+                      const unsigned long long frac,
+                      const unsigned rhs_integ);
+
+#define xnarch_nodiv_ullimd(op, frac, integ) \
+       mach_arm_nodiv_ullimd((op), (frac), (integ))
+
+static inline __attribute__((__const__)) long long
+mach_arm_nodiv_llimd(const long long op,
+                      const unsigned long long frac,
+                      const unsigned rhs_integ);
+
+#define xnarch_nodiv_llimd(op, frac, integ) \
+       mach_arm_nodiv_llimd((op), (frac), (integ))
+#else /* arm <= v3 */
+#define xnarch_add96and64(l0, l1, l2, s0, s1)          \
+       do {                                            \
+               __asm__ ("adds %2, %2, %4\n\t"          \
+                        "adcs %1, %1, %3\n\t"          \
+                        "adc %0, %0, #0\n\t"           \
+                        : "+r"(l0), "+r"(l1), "+r"(l2) \
+                        : "r"(s0), "r"(s1): "cc");     \
+       } while (0)
+#endif /* arm <= v3 */
+
+#include <cobalt/uapi/asm-generic/arith.h>
+
+#if __LINUX_ARM_ARCH__ >= 4 && (!defined(CONFIG_THUMB2_KERNEL) || 
!defined(CONFIG_FTRACE))
+#define mach_arm_nodiv_ullimd_str                      \
+       "umull %[tl], %[rl], %[opl], %[fracl]\n\t"      \
+       "umull %[rm], %[rh], %[oph], %[frach]\n\t"      \
+       "adds %[rl], %[rl], %[tl], lsr #31\n\t"         \
+       "adcs %[rm], %[rm], #0\n\t"                     \
+       "adc %[rh], %[rh], #0\n\t"                      \
+       "umull %[tl], %[th], %[oph], %[fracl]\n\t"      \
+       "adds %[rl], %[rl], %[tl]\n\t"                  \
+       "adcs %[rm], %[rm], %[th]\n\t"                  \
+       "adc %[rh], %[rh], #0\n\t"                      \
+       "umull %[tl], %[th], %[opl], %[frach]\n\t"      \
+       "adds %[rl], %[rl], %[tl]\n\t"                  \
+       "adcs %[rm], %[rm], %[th]\n\t"                  \
+       "adc %[rh], %[rh], #0\n\t"                      \
+       "umlal %[rm], %[rh], %[opl], %[integ]\n\t"      \
+       "mla %[rh], %[oph], %[integ], %[rh]\n\t"
+
+static inline __attribute__((__const__)) unsigned long long
+mach_arm_nodiv_ullimd(const unsigned long long op,
+                      const unsigned long long frac,
+                      const unsigned rhs_integ)
+{
+       register unsigned rl __asm__("r5");
+       register unsigned rm __asm__("r0");
+       register unsigned rh __asm__("r1");
+       register unsigned fracl __asm__ ("r2");
+       register unsigned frach __asm__ ("r3");
+       register unsigned integ __asm__("r4") = rhs_integ;
+       register unsigned opl __asm__ ("r6");
+       register unsigned oph __asm__ ("r7");
+       register unsigned tl __asm__("r8");
+       register unsigned th __asm__("r9");
+
+       xnarch_u64tou32(op, oph, opl);
+       xnarch_u64tou32(frac, frach, fracl);
+
+       __asm__ (mach_arm_nodiv_ullimd_str
+                : [rl]"=r"(rl), [rm]"=r"(rm), [rh]"=r"(rh),
+                  [tl]"=r"(tl), [th]"=r"(th)
+                : [opl]"r"(opl), [oph]"r"(oph),
+                  [fracl]"r"(fracl), [frach]"r"(frach),
+                  [integ]"r"(integ)
+                : "cc");
+
+       return xnarch_u64fromu32(rh, rm);
+}
+
+static inline __attribute__((__const__)) long long
+mach_arm_nodiv_llimd(const long long op,
+                      const unsigned long long frac,
+                      const unsigned rhs_integ)
+{
+       register unsigned rl __asm__("r5");
+       register unsigned rm __asm__("r0");
+       register unsigned rh __asm__("r1");
+       register unsigned fracl __asm__ ("r2");
+       register unsigned frach __asm__ ("r3");
+       register unsigned integ __asm__("r4") = rhs_integ;
+       register unsigned opl __asm__ ("r6");
+       register unsigned oph __asm__ ("r7");
+       register unsigned tl __asm__("r8");
+       register unsigned th __asm__("r9");
+       register unsigned s __asm__("r10");
+
+       xnarch_u64tou32(op, oph, opl);
+       xnarch_u64tou32(frac, frach, fracl);
+
+       __asm__ ("movs %[s], %[oph], lsr #30\n\t"
+                "beq 1f\n\t"
+                "rsbs  %[opl], %[opl], #0\n\t"
+                "sbc  %[oph], %[oph], %[oph], lsl #1\n"
+                "1:\t"
+                mach_arm_nodiv_ullimd_str
+                "teq %[s], #0\n\t"
+                "beq 2f\n\t"
+                "rsbs  %[rm], %[rm], #0\n\t"
+                "sbc  %[rh], %[rh], %[rh], lsl #1\n"
+                "2:\t"
+                : [rl]"=r"(rl), [rm]"=r"(rm), [rh]"=r"(rh),
+                  [tl]"=r"(tl), [th]"=r"(th), [s]"=r"(s)
+                : [opl]"r"(opl), [oph]"r"(oph),
+                  [fracl]"r"(fracl), [frach]"r"(frach),
+                  [integ]"r"(integ)
+                : "cc");
+
+       return xnarch_u64fromu32(rh, rm);
+}
+#endif /* arm >= v4 */
+
+#endif /* _COBALT_ARM_ASM_UAPI_ARITH_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/features.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/features.h
new file mode 100644
index 0000000..2dd1ada
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/features.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005 Philippe Gerum <r...@xenomai.org>.
+ *
+ * ARM port
+ *   Copyright (C) 2005 Stelian Pop
+ *
+ * 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_ARM_ASM_UAPI_FEATURES_H
+#define _COBALT_ARM_ASM_UAPI_FEATURES_H
+
+/* The ABI revision level we use on this arch. */
+#define XENOMAI_ABI_REV   1UL
+
+#define XENOMAI_FEAT_DEP (__xn_feat_generic_mask)
+
+#define XENOMAI_FEAT_MAN (__xn_feat_generic_man_mask)
+
+#define XNARCH_HAVE_LLMULSHFT    1
+#define XNARCH_HAVE_NODIV_LLIMD  1
+
+struct cobalt_featinfo_archdep { /* no arch-specific feature */ };
+
+#include <cobalt/uapi/asm-generic/features.h>
+
+static inline const char *get_feature_label(unsigned int feature)
+{
+       return get_generic_feature_label(feature);
+}
+
+#endif /* !_COBALT_ARM_ASM_UAPI_FEATURES_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/fptest.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/fptest.h
new file mode 100644
index 0000000..b81d109
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/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_ARM_ASM_UAPI_FPTEST_H
+#define _COBALT_ARM_ASM_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_ARM_ASM_UAPI_FPTEST_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/syscall.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/syscall.h
new file mode 100644
index 0000000..c4e3593
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/syscall.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2001,2002,2003,2004 Philippe Gerum <r...@xenomai.org>.
+ *
+ * ARM port
+ *   Copyright (C) 2005 Stelian Pop
+ *
+ * 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_ARM_ASM_UAPI_SYSCALL_H
+#define _COBALT_ARM_ASM_UAPI_SYSCALL_H
+
+#define __xn_syscode(__nr)     (__COBALT_SYSCALL_BIT | (__nr))
+
+#define XENO_ARM_SYSCALL        0x000F0042     /* carefully chosen... */
+
+#define XENOMAI_SYSARCH_ATOMIC_ADD_RETURN      0
+#define XENOMAI_SYSARCH_ATOMIC_SET_MASK                1
+#define XENOMAI_SYSARCH_ATOMIC_CLEAR_MASK      2
+#define XENOMAI_SYSARCH_XCHG                   3
+#define XENOMAI_SYSARCH_TSCINFO                 4
+
+#endif /* !_COBALT_ARM_ASM_UAPI_SYSCALL_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/tsc.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/tsc.h
new file mode 100644
index 0000000..b17cfb2
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/uapi/tsc.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Gilles Chanteperdrix <g...@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_ARM_ASM_UAPI_TSC_H
+#define _COBALT_ARM_ASM_UAPI_TSC_H
+
+struct __xn_tscinfo {
+       volatile unsigned int *counter;
+};
+
+#endif /* !_COBALT_ARM_ASM_UAPI_TSC_H */
diff --git a/kernel/cobalt/arch/arm64/include/asm/xenomai/wrappers.h 
b/kernel/cobalt/arch/arm64/include/asm/xenomai/wrappers.h
new file mode 100644
index 0000000..fe59896
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/include/asm/xenomai/wrappers.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2005 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 the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_ARM_ASM_WRAPPERS_H
+#define _COBALT_ARM_ASM_WRAPPERS_H
+
+#include <asm-generic/xenomai/wrappers.h> /* Read the generic portion. */
+
+#define __put_user_inatomic __put_user
+#define __get_user_inatomic __get_user
+
+#endif /* _COBALT_ARM_ASM_WRAPPERS_H */
diff --git a/kernel/cobalt/arch/arm64/machine.c 
b/kernel/cobalt/arch/arm64/machine.c
new file mode 100644
index 0000000..f48d4a8
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/machine.c
@@ -0,0 +1,119 @@
+/**
+ *   Copyright (C) 2005 Stelian Pop
+ *
+ *   Xenomai is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation, Inc., 675 Mass Ave,
+ *   Cambridge MA 02139, USA; either version 2 of the License, or (at
+ *   your option) any later version.
+ *
+ *   Xenomai 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
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ *   02111-1307, USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/ipipe_tickdev.h>
+#include <cobalt/kernel/arith.h>
+#include <asm/cacheflush.h>
+#include <asm/xenomai/machine.h>
+
+#define CALIBRATION_LOOPS 10
+
+static void mach_arm_prefault(struct vm_area_struct *vma)
+{
+       unsigned long addr;
+       unsigned int flags;
+
+       if ((vma->vm_flags & VM_MAYREAD)) {
+               flags = (vma->vm_flags & VM_MAYWRITE) ? FAULT_FLAG_WRITE : 0;
+               for (addr = vma->vm_start;
+                    addr != vma->vm_end; addr += PAGE_SIZE)
+                       handle_mm_fault(vma->vm_mm, vma, addr, flags);
+       }
+}
+
+static unsigned long mach_arm_calibrate(void)
+{
+       unsigned long long start, end, sum = 0, sum_sq = 0;
+       volatile unsigned const_delay = 0xffffffff;
+       unsigned long result, flags, tsc_lat;
+       unsigned int delay = const_delay;
+       long long diff;
+       int i, j;
+
+       flags = ipipe_critical_enter(NULL);
+
+       /*
+        * Hw interrupts off, other CPUs quiesced, no migration
+        * possible. We can now fiddle with the timer chip (per-cpu
+        * local or global, ipipe_timer_set() will handle this
+        * transparently).
+        */
+       ipipe_read_tsc(start);
+       barrier();
+       ipipe_read_tsc(end);
+       tsc_lat = end - start;
+       barrier();
+
+       for (i = 0; i < CALIBRATION_LOOPS; i++) {
+               flush_cache_all();
+               for (j = 0; j < CALIBRATION_LOOPS; j++) {
+                       ipipe_read_tsc(start);
+                       barrier();
+                       ipipe_timer_set(delay);
+                       barrier();
+                       ipipe_read_tsc(end);
+                       diff = end - start - tsc_lat;
+                       if (diff > 0) {
+                               sum += diff;
+                               sum_sq += diff * diff;
+                       }
+               }
+       }
+
+       ipipe_critical_exit(flags);
+
+       /* Use average + standard deviation as timer programming latency. */
+       do_div(sum, CALIBRATION_LOOPS * CALIBRATION_LOOPS);
+       do_div(sum_sq, CALIBRATION_LOOPS * CALIBRATION_LOOPS);
+       result = sum + int_sqrt(sum_sq - sum * sum) + 1;
+       /*
+        * Reset the max trace, since it contains the calibration time
+        * now.
+        */
+       ipipe_trace_max_reset();
+
+       return result;
+}
+
+static const char *const fault_labels[] = {
+       [IPIPE_TRAP_ACCESS] = "Data or instruction access",
+       [IPIPE_TRAP_SECTION] = "Section fault",
+       [IPIPE_TRAP_DABT] = "Generic data abort",
+       [IPIPE_TRAP_UNKNOWN] = "Unknown exception",
+       [IPIPE_TRAP_BREAK] = "Instruction breakpoint",
+       [IPIPE_TRAP_FPU] = "Floating point exception",
+       [IPIPE_TRAP_VFP] = "VFP Floating point exception",
+       [IPIPE_TRAP_UNDEFINSTR] = "Undefined instruction",
+#ifdef IPIPE_TRAP_ALIGNMENT
+       [IPIPE_TRAP_ALIGNMENT] = "Unaligned access exception",
+#endif /* IPIPE_TRAP_ALIGNMENT */
+       [IPIPE_NR_FAULTS] = NULL
+};
+
+struct cobalt_machine cobalt_machine = {
+       .name = "arm",
+       .init = NULL,
+       .late_init = NULL,
+       .cleanup = NULL,
+       .calibrate = mach_arm_calibrate,
+       .prefault = mach_arm_prefault,
+       .fault_labels = fault_labels,
+};
diff --git a/kernel/cobalt/arch/arm64/mayday.c 
b/kernel/cobalt/arch/arm64/mayday.c
new file mode 100644
index 0000000..20e4559
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/mayday.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/ipipe.h>
+#include <linux/vmalloc.h>
+#include <cobalt/kernel/thread.h>
+#include <cobalt/uapi/syscall.h>
+#include <asm/cacheflush.h>
+#include <asm/ptrace.h>
+
+static void *mayday;
+
+static inline void setup_mayday(void *page)
+{
+       /*
+        * We want this code to appear at the top of the MAYDAY page:
+        *
+        * ifdef ARM_EABI
+        *
+        * e59f000c     ldr     r0, [pc, #12]
+        * e59f700c     ldr     r7, [pc, #12]
+        * ef000000     svc     0x00000000
+        * e3a00000     mov     r0, #0
+        * e5800000     str     r0, [r0]        ; <bug>
+        * 1000005e     .word   0x1000005e      ; sc_cobalt_mayday | 
__COBALT_SYSCALL_BIT
+        * 000f0042     .word   0x000f0042
+        *
+        * elif ARM_OABI
+        *
+        * e59f0008     ldr     r0, [pc, #8]
+        * ef9f0042     swi     0x009f0042
+        * e3a00000     mov     r0, #0
+        * e5800000     str     r0, [r0]        ; <bug>
+        * 1000005e     .word   0x1000005e      ; sc_cobalt_mayday | 
__COBALT_SYSCALL_BIT
+        *
+        * endif
+        *
+        * 32bit instruction words will be laid out by the compiler as
+        * the target endianness requires.
+        *
+        * We don't mess with CPSR here, so no need to save/restore it
+        * in handle/fixup code.
+        */
+#ifdef __ARM_EABI__
+       static const struct {
+               u32 ldr_r0;
+               u32 ldr_r7;
+               u32 swi_0;
+               u32 mov_r0;
+               u32 str_r0;
+               u32 cst_r0;
+               u32 cst_r7;
+       } code = {
+               .ldr_r0 = 0xe59f000c,
+               .ldr_r7 = 0xe59f700c,
+               .swi_0 = 0xef000000,
+               .mov_r0 = 0xe3a00000,
+               .str_r0 = 0xe5800000,
+               .cst_r0 =  __xn_syscode(sc_cobalt_mayday),
+               .cst_r7 = 0x000f0042,
+       };
+#else /* OABI */
+       static const struct {
+               u32 ldr_r0;
+               u32 swi_syscall;
+               u32 mov_r0;
+               u32 str_r0;
+               u32 cst_r0;
+       } code = {
+               .ldr_r0 = 0xe59f0008,
+               .swi_syscall = 0xef9f0042,
+               .mov_r0 = 0xe3a00000,
+               .str_r0 = 0xe5800000,
+               .cst_r0 =  __xn_syscode(sc_cobalt_mayday),
+       };
+#endif /* OABI */
+
+       memcpy(page, &code, sizeof(code));
+
+       flush_dcache_page(vmalloc_to_page(page));
+}
+
+int xnarch_init_mayday(void)
+{
+       mayday = vmalloc(PAGE_SIZE);
+       if (mayday == NULL)
+               return -ENOMEM;
+
+       setup_mayday(mayday);
+
+       return 0;
+}
+
+void xnarch_cleanup_mayday(void)
+{
+       vfree(mayday);
+}
+
+void *xnarch_get_mayday_page(void)
+{
+       return mayday;
+}
+
+void xnarch_handle_mayday(struct xnarchtcb *tcb, struct pt_regs *regs,
+                         unsigned long tramp)
+{
+       tcb->mayday.pc = regs->ARM_pc;
+       tcb->mayday.r0 = regs->ARM_r0;
+#ifdef __ARM_EABI__
+       tcb->mayday.r7 = regs->ARM_r7;
+#endif
+#ifdef CONFIG_ARM_THUMB
+       /* The code on the mayday page must be run in ARM mode */
+       tcb->mayday.psr = regs->ARM_cpsr;
+       regs->ARM_cpsr &= ~PSR_T_BIT;
+#endif
+       regs->ARM_pc = tramp;
+}
+
+void xnarch_fixup_mayday(struct xnarchtcb *tcb, struct pt_regs *regs)
+{
+       regs->ARM_pc = tcb->mayday.pc;
+       regs->ARM_r0 = tcb->mayday.r0;
+#ifdef __ARM_EABI__
+       regs->ARM_r7 = tcb->mayday.r7;
+#endif
+#ifdef CONFIG_ARM_THUMB
+       regs->ARM_cpsr = tcb->mayday.psr;
+#endif
+}
diff --git a/kernel/cobalt/arch/arm64/switch.S 
b/kernel/cobalt/arch/arm64/switch.S
new file mode 100644
index 0000000..505fd5a
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/switch.S
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2005 Stelian Pop.
+ *
+ * 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
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/linkage.h>
+#include <linux/version.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/tls.h>
+#ifdef CONFIG_VFP
+#include <asm/vfpmacros.h>
+#endif
+
+       .macro fpu_switch tmp
+#ifdef CONFIG_VFP
+#if __LINUX_ARM_ARCH__ <= 6
+#ifdef CONFIG_JUMP_LABEL
+9998:  nop
+       .pushsection __jump_table, "aw"
+       .word   9998b, 9999f, __xeno_vfp_key
+       .popsection
+#else
+       ldr     \tmp, =elf_hwcap
+       ldr     \tmp, [\tmp]
+       tst     \tmp, #HWCAP_VFP
+       beq     9999f
+#endif
+#endif
+       @ Always disable VFP so we can lazily save/restore the old
+       @ state. This occurs in the context of the previous thread.
+       VFPFMRX \tmp, FPEXC
+       bic     \tmp, \tmp, #FPEXC_EN
+       VFPFMXR FPEXC, \tmp
+#if __LINUX_ARM_ARCH__ <= 6
+9999:
+#endif
+#endif
+       .endm
+
+       .text
+
+#if defined(CONFIG_VFP) && defined(CONFIG_XENO_ARCH_FPU)
+/* Copied from vfp_save_state in arch/arm/vfp/vfphw.S
+ * r0 = pointer to union vfp_state, r1 = fpexc
+ */
+ENTRY(__asm_vfp_save)
+       VFPFSTMIA       r0, r2          @ save the working registers
+       VFPFMRX         r2, FPSCR       @ current status
+       tst             r1, #FPEXC_EX   @ is there additional state to save?
+       beq             1f
+       VFPFMRX         r3, FPINST      @ FPINST (only if FPEXC.EX is set)
+       tst             r1, #FPEXC_FP2V @ is there an FPINST2 to read?
+       beq             1f
+       VFPFMRX         r12, FPINST2    @ FPINST2 if needed (and present)
+1:
+       stmia           r0, {r1, r2, r3, r12}   @ save FPEXC, FPSCR, FPINST, 
FPINST2
+       mov             pc, lr
+ENDPROC(__asm_vfp_save)
+
+/* Copied from no_old_VFP_process in arch/arm/vfp/vfphw.S
+ * r0 = pointer to union vfp_state
+ * r1 = current cpu
+ */
+ENTRY(__asm_vfp_load)
+#ifdef CONFIG_SMP
+       str             r1, [r0, #VFP_CPU]
+#endif
+       VFPFLDMIA       r0, r2          @ reload the working registers while
+                                       @ FPEXC is in a safe state
+       ldmia           r0, {r1, r2, r3, r12}   @ load FPEXC, FPSCR, FPINST, 
FPINST2
+       tst             r1, #FPEXC_EX   @ is there additional state to restore?
+       beq             1f
+       VFPFMXR         FPINST, r3      @ restore FPINST (only if FPEXC.EX is 
set)
+       tst             r1, #FPEXC_FP2V @ is there an FPINST2 to write?
+       beq             1f
+       VFPFMXR         FPINST2, r12    @ FPINST2 if needed (and present)
+1:
+       VFPFMXR         FPSCR, r2       @ restore status
+       mov             pc, lr
+ENDPROC(__asm_vfp_load)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
+       .macro load_tls base, tp, tpuser
+       ldr     \tp, [\base, #TI_TP_VALUE]
+       .endm
+
+       .macro switch_tls base, tp, tpuser, tmp1, tmp2
+       set_tls \tp, \tmp1, \tmp2
+       .endm
+#else
+       .macro load_tls base, tp, tpuser
+       ldr     \tp, [\base, #TI_TP_VALUE]
+       ldr     \tpuser, [\base, #TI_TP_VALUE + 4]
+       .endm
+#endif
+
+/*
+/*
+ * Switch context routine.
+ *
+ * Registers according to the ARM procedure call standard:
+ *   Reg    Description
+ *   r0-r3  argument/scratch registers
+ *   r4-r9  variable register
+ *   r10=sl stack limit/variable register
+ *   r11=fp frame pointer/variable register
+ *   r12=ip intra-procedure-call scratch register
+ *   r13=sp stack pointer (auto preserved)
+ *   r14=lr link register
+ *   r15=pc program counter (auto preserved)
+ *
+ * Copied from __switch_to, arch/arm/kernel/entry-armv.S.
+ * Right now it is identical, but who knows what the
+ * future reserves us...
+ *
+ * XXX: All the following config options are NOT tested:
+ *      CONFIG_IWMMXT
+ *
+ *  Calling args:
+ * r0 = previous thread_info, r1 = next thread_info
+ */
+ENTRY(__asm_thread_switch)
+       add     ip, r0, #TI_CPU_SAVE
+ ARM(  stmia   ip!, {r4 - sl, fp, sp, lr} )    @ Store most regs on stack
+ THUMB(        stmia   ip!, {r4 - sl, fp}         )    @ Store most regs on 
stack
+ THUMB(        str     sp, [ip], #4               )
+ THUMB(        str     lr, [ip], #4               )
+       load_tls r1, r4, r5
+#ifdef CONFIG_CPU_USE_DOMAINS
+       ldr     r6, [r1, #TI_CPU_DOMAIN]
+#endif
+       switch_tls r0, r4, r5, r3, r7
+#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
+       ldr     r7, [r1, #TI_TASK]
+       ldr     r8, =__stack_chk_guard
+       ldr     r7, [r7, #TSK_STACK_CANARY]
+#endif
+#ifdef CONFIG_CPU_USE_DOMAINS
+       mcr     p15, 0, r6, c3, c0, 0           @ Set domain register
+#endif
+       fpu_switch r4
+#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
+       str     r7, [r8]
+#endif
+ ARM(  add     r4, r1, #TI_CPU_SAVE       )
+ ARM(  ldmia   r4, {r4 - sl, fp, sp, pc}  )    @ Load all regs saved previously
+ THUMB(        add     ip, r1, #TI_CPU_SAVE       )
+ THUMB(        ldmia   ip!, {r4 - sl, fp}         )    @ Load all regs saved 
previously
+ THUMB(        ldr     sp, [ip], #4               )
+ THUMB(        ldr     pc, [ip]                   )
+ENDPROC(__asm_thread_switch)
diff --git a/kernel/cobalt/arch/arm64/syscall.c 
b/kernel/cobalt/arch/arm64/syscall.c
new file mode 100644
index 0000000..ee78243
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/syscall.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005 Stelian Pop
+ * Copyright (C) 2010 Gilles Chanteperdrix <gilles.chanteperd...@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/ipipe.h>
+#include <asm/xenomai/syscall.h>
+#include <asm/xenomai/uapi/tsc.h>
+
+int xnarch_local_syscall(unsigned long a1, unsigned long a2,
+                        unsigned long a3, unsigned long a4,
+                        unsigned long a5)
+{
+       struct ipipe_sysinfo ipipe_info;
+       struct __ipipe_tscinfo *p = &ipipe_info.arch.tsc;
+       struct __xn_tscinfo info;
+       int ret;
+
+       if (a1 != XENOMAI_SYSARCH_TSCINFO)
+               return -EINVAL;
+
+       ret = ipipe_get_sysinfo(&ipipe_info);
+       if (ret)
+               return ret;
+
+       switch (p->type) {
+       case IPIPE_TSC_TYPE_DECREMENTER:
+               info.counter = p->u.dec.counter;
+               break;
+       case IPIPE_TSC_TYPE_NONE:
+               return -ENOSYS;
+       default:
+               info.counter = p->u.fr.counter;
+               break;
+       }
+
+       return cobalt_copy_to_user((void *)a2, &info, sizeof(info));
+}
diff --git a/kernel/cobalt/arch/arm64/thread.c 
b/kernel/cobalt/arch/arm64/thread.c
new file mode 100644
index 0000000..825926c
--- /dev/null
+++ b/kernel/cobalt/arch/arm64/thread.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2001,2002,2003,2004 Philippe Gerum <r...@xenomai.org>.
+ *
+ * ARM port
+ *   Copyright (C) 2005 Stelian Pop
+ *
+ * Xenomai is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <linux/sched.h>
+#include <linux/ipipe.h>
+#include <linux/mm.h>
+#include <linux/jump_label.h>
+#include <asm/mmu_context.h>
+#include <cobalt/kernel/thread.h>
+
+struct static_key __xeno_vfp_key = STATIC_KEY_INIT_TRUE;
+
+asmlinkage void __asm_thread_switch(struct thread_info *out,
+                                   struct thread_info *in);
+
+asmlinkage void __asm_thread_trampoline(void);
+
+#if defined(CONFIG_XENO_ARCH_FPU) && defined(CONFIG_VFP)
+
+static unsigned int vfp_checked;
+static DEFINE_MUTEX(vfp_check_lock);
+
+asmlinkage void __asm_vfp_save(union vfp_state *vfp, unsigned int fpexc);
+
+asmlinkage void __asm_vfp_load(union vfp_state *vfp, unsigned int cpu);
+
+#define do_vfp_fmrx(_vfp_)                                             \
+       ({                                                              \
+               u32 __v;                                                \
+               asm volatile("mrc p10, 7, %0, " __stringify(_vfp_)      \
+                            ", cr0, 0 @ fmrx %0, " #_vfp_:             \
+                            "=r" (__v));                               \
+               __v;                                                    \
+       })
+
+#define do_vfp_fmxr(_vfp_,_var_)                               \
+       asm volatile("mcr p10, 7, %0, " __stringify(_vfp_)      \
+                    ", cr0, 0 @ fmxr " #_vfp_ ", %0":          \
+                    /* */ : "r" (_var_))
+
+extern union vfp_state *vfp_current_hw_state[NR_CPUS];
+
+static inline union vfp_state *get_fpu_owner(void)
+{
+       union vfp_state *vfp_owner;
+       unsigned int cpu;
+#ifdef CONFIG_SMP
+       unsigned int fpexc;
+#endif
+
+#if __LINUX_ARM_ARCH__ <= 6
+       if (!static_key_true(&__xeno_vfp_key))
+               return NULL;
+#endif
+
+#ifdef CONFIG_SMP
+       fpexc = do_vfp_fmrx(FPEXC);
+       if (!(fpexc & FPEXC_EN))
+               return NULL;
+#endif
+
+       cpu = ipipe_processor_id();
+       vfp_owner = vfp_current_hw_state[cpu];
+       if (!vfp_owner)
+               return NULL;
+
+#ifdef CONFIG_SMP
+       if (vfp_owner->hard.cpu != cpu)
+               return NULL;
+#endif /* SMP */
+
+       return vfp_owner;
+}
+
+#define do_disable_vfp(fpexc)                                  \
+       do_vfp_fmxr(FPEXC, fpexc & ~FPEXC_EN)
+
+#define XNARCH_VFP_ANY_EXC                                             \
+       (FPEXC_EX|FPEXC_DEX|FPEXC_FP2V|FPEXC_VV|FPEXC_TRAP_MASK)
+
+#define do_enable_vfp()                                                        
\
+       ({                                                              \
+               unsigned _fpexc = do_vfp_fmrx(FPEXC) | FPEXC_EN;        \
+               do_vfp_fmxr(FPEXC, _fpexc & ~XNARCH_VFP_ANY_EXC);       \
+               _fpexc;                                                 \
+       })
+
+int xnarch_fault_fpu_p(struct ipipe_trap_data *d)
+{
+       /* This function does the same thing to decode the faulting instruct as
+          "call_fpe" in arch/arm/entry-armv.S */
+       static unsigned copro_to_exc[16] = {
+               IPIPE_TRAP_UNDEFINSTR,
+               /* FPE */
+               IPIPE_TRAP_FPU, IPIPE_TRAP_FPU,
+               IPIPE_TRAP_UNDEFINSTR,
+#ifdef CONFIG_CRUNCH
+               IPIPE_TRAP_FPU, IPIPE_TRAP_FPU, IPIPE_TRAP_FPU,
+#else /* !CONFIG_CRUNCH */
+               IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, 
IPIPE_TRAP_UNDEFINSTR,
+#endif /* !CONFIG_CRUNCH */
+               IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, 
IPIPE_TRAP_UNDEFINSTR,
+#ifdef CONFIG_VFP
+               IPIPE_TRAP_VFP, IPIPE_TRAP_VFP,
+#else /* !CONFIG_VFP */
+               IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR,
+#endif /* !CONFIG_VFP */
+               IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR,
+               IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR,
+       };
+       unsigned instr, exc, cp;
+       char *pc;
+
+       if (d->exception == IPIPE_TRAP_FPU)
+               return 1;
+
+       if (d->exception == IPIPE_TRAP_VFP)
+               goto trap_vfp;
+
+       if (d->exception != IPIPE_TRAP_UNDEFINSTR)
+               return 0;
+
+       pc = (char *) xnarch_fault_pc(d);
+       if (unlikely(thumb_mode(d->regs))) {
+               unsigned short thumbh, thumbl;
+
+#if defined(CONFIG_ARM_THUMB) && __LINUX_ARM_ARCH__ >= 6 && 
defined(CONFIG_CPU_V7)
+#if __LINUX_ARM_ARCH__ < 7
+               if (cpu_architecture() < CPU_ARCH_ARMv7)
+#else
+               if (0)
+#endif /* arch < 7 */
+#endif /* thumb && arch >= 6 && cpu_v7 */
+                       return 0;
+
+               thumbh = *(unsigned short *) pc;
+               thumbl = *((unsigned short *) pc + 1);
+
+               if ((thumbh & 0x0000f800) < 0x0000e800)
+                       return 0;
+               instr = (thumbh << 16) | thumbl;
+
+#ifdef CONFIG_NEON
+               if ((instr & 0xef000000) == 0xef000000
+                   || (instr & 0xff100000) == 0xf9000000)
+                       goto trap_vfp;
+#endif
+       } else {
+               instr = *(unsigned *) pc;
+
+#ifdef CONFIG_NEON
+               if ((instr & 0xfe000000) == 0xf2000000
+                   || (instr & 0xff100000) == 0xf4000000)
+                       goto trap_vfp;
+#endif
+       }
+
+       if ((instr & 0x0c000000) != 0x0c000000)
+               return 0;
+
+       cp = (instr & 0x00000f00) >> 8;
+#ifdef CONFIG_IWMMXT
+       /* We need something equivalent to _TIF_USING_IWMMXT for Xenomai kernel
+          threads */
+       if (cp <= 1) {
+               d->exception = IPIPE_TRAP_FPU;
+               return 1;
+       }
+#endif
+
+       exc = copro_to_exc[cp];
+       if (exc == IPIPE_TRAP_VFP) {
+         trap_vfp:
+               /* If an exception is pending, the VFP fault is not really an
+                  "FPU unavailable" fault, so we return undefinstr in that
+                  case, the nucleus will let linux handle the fault. */
+               exc = do_vfp_fmrx(FPEXC);
+               if (exc & (FPEXC_EX|FPEXC_DEX)
+                   || ((exc & FPEXC_EN) && do_vfp_fmrx(FPSCR) & FPSCR_IXE))
+                       exc = IPIPE_TRAP_UNDEFINSTR;
+               else
+                       exc = IPIPE_TRAP_VFP;
+       }
+
+       d->exception = exc;
+       return exc != IPIPE_TRAP_UNDEFINSTR;
+}
+
+void xnarch_leave_root(struct xnthread *root)
+{
+       struct xnarchtcb *rootcb = xnthread_archtcb(root);
+       rootcb->fpup = get_fpu_owner();
+}
+
+void xnarch_save_fpu(struct xnthread *thread)
+{
+       struct xnarchtcb *tcb = &thread->tcb;
+       if (tcb->fpup)
+               __asm_vfp_save(tcb->fpup, do_enable_vfp());
+}
+
+void xnarch_switch_fpu(struct xnthread *from, struct xnthread *to)
+{
+       union vfp_state *const from_fpup = from ? from->tcb.fpup : NULL;
+       unsigned cpu = ipipe_processor_id();
+       
+       if (xnthread_test_state(to, XNROOT) == 0) {
+               union vfp_state *const to_fpup = to->tcb.fpup;
+               unsigned fpexc = do_enable_vfp();
+
+               if (from_fpup == to_fpup)
+                       return;
+
+               if (from_fpup)
+                       __asm_vfp_save(from_fpup, fpexc);
+
+               __asm_vfp_load(to_fpup, cpu);
+       } else {
+               /*
+                * We are restoring the Linux current thread. The FPU
+                * can be disabled, so that a fault will occur if the
+                * newly switched thread uses the FPU, to allow the
+                * kernel handler to pick the correct FPU context, and
+                * save in the same move the last used RT context.
+                */
+               vfp_current_hw_state[cpu] = from_fpup;
+#ifdef CONFIG_SMP
+               /*
+                * On SMP, since returning to FPU disabled mode means
+                * that we have to save fpu, avoid doing it if
+                * current FPU context belongs to the task we are
+                * switching to.
+                */
+               if (from_fpup) {
+                       union vfp_state *const current_task_fpup =
+                               &to->tcb.core.tip->vfpstate;
+                       const unsigned fpdis = do_vfp_fmrx(FPEXC);
+                       const unsigned fpen = fpdis | FPEXC_EN;
+
+                       do_vfp_fmxr(FPEXC, fpen & ~XNARCH_VFP_ANY_EXC);
+                       if (from_fpup == current_task_fpup)
+                               return;
+                       
+                       __asm_vfp_save(from_fpup, fpen);
+                       do_vfp_fmxr(FPEXC, fpdis);
+               }
+#endif
+       }
+}
+
+int xnarch_handle_fpu_fault(struct xnthread *from, 
+                       struct xnthread *to, struct ipipe_trap_data *d)
+{
+       spl_t s;
+
+       if (xnthread_test_state(to, XNFPU))
+               /* FPU is already enabled, probably an exception */
+               return 0;
+
+#if __LINUX_ARM_ARCH__ <= 6
+       if (!static_key_true(&__xeno_vfp_key))
+               /* VFP instruction emitted, on a cpu without VFP, this
+                  is an error */
+               return 0;
+#endif
+
+       xnlock_get_irqsave(&nklock, s);
+       xnthread_set_state(to, XNFPU);
+       xnlock_put_irqrestore(&nklock, s);
+
+       xnarch_switch_fpu(from, to);
+
+       /* Retry faulting instruction */
+       d->regs->ARM_pc = xnarch_fault_pc(d);
+       return 1;
+}
+
+void xnarch_init_shadow_tcb(struct xnthread *thread)
+{
+       struct xnarchtcb *tcb = xnthread_archtcb(thread);
+
+       tcb->fpup = &task_thread_info(tcb->core.host_task)->vfpstate;
+
+       if (vfp_checked == 0) {
+               mutex_lock(&vfp_check_lock);
+               if (vfp_checked == 0) {
+                       if ((elf_hwcap & HWCAP_VFP) == 0)
+                               static_key_slow_dec(&__xeno_vfp_key);
+                       vfp_checked = 1;
+               }
+               mutex_unlock(&vfp_check_lock);
+       }
+
+       /* XNFPU is set upon first FPU fault */
+       xnthread_clear_state(thread, XNFPU);
+}
+#endif /* CONFIG_XENO_ARCH_FPU && CONFIG_VFP*/
+
+void xnarch_switch_to(struct xnthread *out, struct xnthread *in)
+{
+       struct xnarchtcb *out_tcb = &out->tcb, *in_tcb = &in->tcb;
+       struct mm_struct *prev_mm, *next_mm;
+       struct task_struct *next;
+
+       next = in_tcb->core.host_task;
+       prev_mm = out_tcb->core.active_mm;
+
+       next_mm = in_tcb->core.mm;
+       if (next_mm == NULL) {
+               in_tcb->core.active_mm = prev_mm;
+               enter_lazy_tlb(prev_mm, next);
+       } else {
+               ipipe_switch_mm_head(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);
+       }
+
+       __asm_thread_switch(out_tcb->core.tip, in_tcb->core.tip);
+}
+
+int xnarch_escalate(void)
+{
+       if (ipipe_root_p) {
+               ipipe_raise_irq(cobalt_pipeline.escalate_virq);
+               return 1;
+       }
+
+       return 0;
+}
diff --git a/lib/cobalt/arch/Makefile.am b/lib/cobalt/arch/Makefile.am
index 3073a3f..608cda1 100644
--- a/lib/cobalt/arch/Makefile.am
+++ b/lib/cobalt/arch/Makefile.am
@@ -1,4 +1,4 @@
 
 SUBDIRS = @XENO_TARGET_ARCH@
 
-DIST_SUBDIRS = arm blackfin powerpc x86
+DIST_SUBDIRS = arm arm64 blackfin powerpc x86
diff --git a/lib/cobalt/arch/arm64/Makefile.am 
b/lib/cobalt/arch/arm64/Makefile.am
new file mode 100644
index 0000000..0aa02d6
--- /dev/null
+++ b/lib/cobalt/arch/arm64/Makefile.am
@@ -0,0 +1,13 @@
+noinst_LTLIBRARIES = libarch.la
+
+libarch_la_LDFLAGS = @XENO_LIB_LDFLAGS@ -version-info 0:0:0
+
+libarch_la_SOURCES = features.c
+
+libarch_la_CPPFLAGS =                  \
+       @XENO_COBALT_CFLAGS@            \
+       -I$(srcdir)/../..               \
+       -I$(top_srcdir)/include/cobalt  \
+       -I$(top_srcdir)/include
+
+SUBDIRS = include
diff --git a/lib/cobalt/arch/arm64/features.c b/lib/cobalt/arch/arm64/features.c
new file mode 100644
index 0000000..edabcf2
--- /dev/null
+++ b/lib/cobalt/arch/arm64/features.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011 Gilles Chanteperdrix <g...@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.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <cobalt/wrappers.h>
+#include <asm/xenomai/syscall.h>
+#include <asm/xenomai/tsc.h>
+#include <asm/xenomai/features.h>
+#include <asm/xenomai/uapi/fptest.h>
+#include "internal.h"
+
+struct __xn_full_tscinfo __xn_tscinfo = {
+       .kinfo = {
+               .counter = NULL,
+       },
+};
+
+void cobalt_check_features(struct cobalt_featinfo *finfo)
+{
+       unsigned long phys_addr;
+       unsigned page_size;
+       int err, fd;
+       void *addr;
+
+       if (__xn_tscinfo.kinfo.counter != NULL)
+               return;
+
+       err = XENOMAI_SYSCALL2(sc_cobalt_archcall,
+                              XENOMAI_SYSARCH_TSCINFO, &__xn_tscinfo.kinfo);
+       if (err)
+               early_panic("missing TSC emulation: %s",
+                            strerror(-err));
+
+       fd = __STD(open("/dev/mem", O_RDONLY | O_SYNC));
+       if (fd == -1)
+               early_panic("failed open(/dev/mem): %s", strerror(errno));
+
+       page_size = sysconf(_SC_PAGESIZE);
+
+       __xn_tscinfo.kuser_tsc_get =
+               (__xn_rdtsc_t *)(0xffff1004 -
+                               ((*(unsigned *)(0xffff0ffc) + 3) << 5));
+
+       phys_addr = (unsigned long)__xn_tscinfo.kinfo.counter;
+
+       addr = __STD(mmap(NULL, page_size, PROT_READ, MAP_SHARED,
+                         fd, phys_addr & ~(page_size - 1)));
+       if (addr == MAP_FAILED)
+               early_panic("failed mmap(/dev/mem): %s", strerror(errno));
+
+       __xn_tscinfo.kinfo.counter =
+               ((volatile unsigned *)
+                ((char *) addr + (phys_addr & (page_size - 1))));
+
+       __STD(close(fd));
+}
+
+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/arch/arm64/include/Makefile.am 
b/lib/cobalt/arch/arm64/include/Makefile.am
new file mode 100644
index 0000000..5cac5d2
--- /dev/null
+++ b/lib/cobalt/arch/arm64/include/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = asm
diff --git a/lib/cobalt/arch/arm64/include/asm/Makefile.am 
b/lib/cobalt/arch/arm64/include/asm/Makefile.am
new file mode 100644
index 0000000..55ea661
--- /dev/null
+++ b/lib/cobalt/arch/arm64/include/asm/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = xenomai
diff --git a/lib/cobalt/arch/arm64/include/asm/xenomai/Makefile.am 
b/lib/cobalt/arch/arm64/include/asm/xenomai/Makefile.am
new file mode 100644
index 0000000..d308b06
--- /dev/null
+++ b/lib/cobalt/arch/arm64/include/asm/xenomai/Makefile.am
@@ -0,0 +1,5 @@
+
+noinst_HEADERS =       \
+       features.h      \
+       syscall.h       \
+       tsc.h
diff --git a/lib/cobalt/arch/arm64/include/asm/xenomai/features.h 
b/lib/cobalt/arch/arm64/include/asm/xenomai/features.h
new file mode 100644
index 0000000..10bd0c7
--- /dev/null
+++ b/lib/cobalt/arch/arm64/include/asm/xenomai/features.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2005 Philippe Gerum <r...@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 _LIB_COBALT_ARM_FEATURES_H
+#define _LIB_COBALT_ARM_FEATURES_H
+
+#include_next <features.h>
+#include <xeno_config.h>
+
+#if defined(__ARM_ARCH_2__)
+#define __LINUX_ARM_ARCH__ 2
+#endif /* armv2 */
+
+#if defined(__ARM_ARCH_3__)
+#define __LINUX_ARM_ARCH__ 3
+#endif /* armv3 */
+
+#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+#define __LINUX_ARM_ARCH__ 4
+#endif /* armv4 */
+
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+       || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__)
+#define __LINUX_ARM_ARCH__ 5
+#endif /* armv5 */
+
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6K__) \
+       || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
+#define __LINUX_ARM_ARCH__ 6
+#endif /* armv6 */
+
+#if defined(__ARM_ARCH_7A__)
+#define __LINUX_ARM_ARCH__ 7
+#endif /* armv7 */
+
+#ifndef __LINUX_ARM_ARCH__
+#error "Could not find current ARM architecture"
+#endif
+
+#if __LINUX_ARM_ARCH__ < 6 && defined(CONFIG_SMP)
+#error "SMP not supported below armv6, compile with -march=armv6 or above"
+#endif
+
+#include <asm/xenomai/uapi/features.h>
+
+int cobalt_fp_detect(void);
+
+#endif /* !_LIB_COBALT_ARM_FEATURES_H */
diff --git a/lib/cobalt/arch/arm64/include/asm/xenomai/syscall.h 
b/lib/cobalt/arch/arm64/include/asm/xenomai/syscall.h
new file mode 100644
index 0000000..8f48eb1
--- /dev/null
+++ b/lib/cobalt/arch/arm64/include/asm/xenomai/syscall.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2001,2002,2003,2004 Philippe Gerum <r...@xenomai.org>.
+ *
+ * ARM port
+ *   Copyright (C) 2005 Stelian Pop
+ *
+ * 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 _LIB_COBALT_ARM_SYSCALL_H
+#define _LIB_COBALT_ARM_SYSCALL_H
+
+#include <xeno_config.h>
+#include <errno.h>
+#include <cobalt/uapi/syscall.h>
+
+/*
+ * Some of the following macros have been adapted from Linux's
+ * implementation of the syscall mechanism in <asm-arm/unistd.h>:
+ */
+#if defined(HAVE_TLS) && __GNUC__ == 4 && __GNUC_MINOR__ >= 3
+#error TLS support (__thread) is broken with GCC >= 4.3, use --disable-tls 
when configuring
+#endif
+
+#define LOADARGS_0(syscode, dummy...)  \
+       __a0 = (unsigned long) (syscode)
+#define LOADARGS_1(syscode, arg1)      \
+       LOADARGS_0(syscode);            \
+       __a1 = (unsigned long) (arg1)
+#define LOADARGS_2(syscode, arg1, arg2)        \
+       LOADARGS_1(syscode, arg1);      \
+       __a2 = (unsigned long) (arg2)
+#define LOADARGS_3(syscode, arg1, arg2, arg3)  \
+       LOADARGS_2(syscode,  arg1, arg2);       \
+       __a3 = (unsigned long) (arg3)
+#define LOADARGS_4(syscode,  arg1, arg2, arg3, arg4)   \
+       LOADARGS_3(syscode,  arg1, arg2, arg3);         \
+       __a4 = (unsigned long) (arg4)
+#define LOADARGS_5(syscode, arg1, arg2, arg3, arg4, arg5)      \
+       LOADARGS_4(syscode, arg1, arg2, arg3, arg4);            \
+       __a5 = (unsigned long) (arg5)
+
+#define CLOBBER_REGS_0 "r0"
+#define CLOBBER_REGS_1 CLOBBER_REGS_0, "r1"
+#define CLOBBER_REGS_2 CLOBBER_REGS_1, "r2"
+#define CLOBBER_REGS_3 CLOBBER_REGS_2, "r3"
+#define CLOBBER_REGS_4 CLOBBER_REGS_3, "r4"
+#define CLOBBER_REGS_5 CLOBBER_REGS_4, "r5"
+
+#define LOADREGS_0 __r0 = __a0
+#define LOADREGS_1 LOADREGS_0; __r1 = __a1
+#define LOADREGS_2 LOADREGS_1; __r2 = __a2
+#define LOADREGS_3 LOADREGS_2; __r3 = __a3
+#define LOADREGS_4 LOADREGS_3; __r4 = __a4
+#define LOADREGS_5 LOADREGS_4; __r5 = __a5
+
+#define ASM_INDECL_0                                                   \
+       unsigned long __a0; register unsigned long __r0  __asm__ ("r0");
+#define ASM_INDECL_1 ASM_INDECL_0;                                     \
+       unsigned long __a1; register unsigned long __r1  __asm__ ("r1")
+#define ASM_INDECL_2 ASM_INDECL_1;                                     \
+       unsigned long __a2; register unsigned long __r2  __asm__ ("r2")
+#define ASM_INDECL_3 ASM_INDECL_2;                                     \
+       unsigned long __a3; register unsigned long __r3  __asm__ ("r3")
+#define ASM_INDECL_4 ASM_INDECL_3;                                     \
+       unsigned long __a4; register unsigned long __r4  __asm__ ("r4")
+#define ASM_INDECL_5 ASM_INDECL_4;                                     \
+       unsigned long __a5; register unsigned long __r5  __asm__ ("r5")
+
+#define ASM_INPUT_0 "0" (__r0)
+#define ASM_INPUT_1 ASM_INPUT_0, "r" (__r1)
+#define ASM_INPUT_2 ASM_INPUT_1, "r" (__r2)
+#define ASM_INPUT_3 ASM_INPUT_2, "r" (__r3)
+#define ASM_INPUT_4 ASM_INPUT_3, "r" (__r4)
+#define ASM_INPUT_5 ASM_INPUT_4, "r" (__r5)
+
+#define __sys2(x)      #x
+#define __sys1(x)      __sys2(x)
+
+#ifdef __ARM_EABI__
+#define __SYS_REG , "r7"
+#define __SYS_REG_DECL register unsigned long __r7 __asm__ ("r7")
+#define __SYS_REG_SET __r7 = XENO_ARM_SYSCALL
+#define __SYS_REG_INPUT ,"r" (__r7)
+#define __SYS_CALLOP "swi\t0"
+#else
+#define __SYS_REG
+#define __SYS_REG_DECL
+#define __SYS_REG_SET
+#define __SYS_REG_INPUT
+#define __NR_OABI_SYSCALL_BASE 0x900000
+#define __SYS_CALLOP "swi\t" __sys1(__NR_OABI_SYSCALL_BASE + XENO_ARM_SYSCALL) 
""
+#endif
+
+#define XENOMAI_DO_SYSCALL(nr, op, args...)                            \
+       ({                                                              \
+               ASM_INDECL_##nr;                                        \
+               __SYS_REG_DECL;                                         \
+               LOADARGS_##nr(__xn_syscode(op), args);                  \
+               __asm__ __volatile__ ("" : /* */ : /* */ :              \
+                                     CLOBBER_REGS_##nr __SYS_REG);     \
+               LOADREGS_##nr;                                          \
+               __SYS_REG_SET;                                          \
+               __asm__ __volatile__ (                                  \
+                       __SYS_CALLOP                                    \
+                       : "=r" (__r0)                                   \
+                       : ASM_INPUT_##nr __SYS_REG_INPUT                \
+                       : "memory");                                    \
+               (int) __r0;                                             \
+       })
+
+#define XENOMAI_SYSCALL0(op)                   \
+       XENOMAI_DO_SYSCALL(0,op)
+#define XENOMAI_SYSCALL1(op,a1)                        \
+       XENOMAI_DO_SYSCALL(1,op,a1)
+#define XENOMAI_SYSCALL2(op,a1,a2)             \
+       XENOMAI_DO_SYSCALL(2,op,a1,a2)
+#define XENOMAI_SYSCALL3(op,a1,a2,a3)          \
+       XENOMAI_DO_SYSCALL(3,op,a1,a2,a3)
+#define XENOMAI_SYSCALL4(op,a1,a2,a3,a4)       \
+       XENOMAI_DO_SYSCALL(4,op,a1,a2,a3,a4)
+#define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5)    \
+       XENOMAI_DO_SYSCALL(5,op,a1,a2,a3,a4,a5)
+#define XENOMAI_SYSBIND(breq)                  \
+       XENOMAI_DO_SYSCALL(1,sc_cobalt_bind,breq)
+
+#endif /* !_LIB_COBALT_ARM_SYSCALL_H */
diff --git a/lib/cobalt/arch/arm64/include/asm/xenomai/tsc.h 
b/lib/cobalt/arch/arm64/include/asm/xenomai/tsc.h
new file mode 100644
index 0000000..594c4ad
--- /dev/null
+++ b/lib/cobalt/arch/arm64/include/asm/xenomai/tsc.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2001,2002,2003,2004 Philippe Gerum <r...@xenomai.org>.
+ * Copyright (C) 2013 Gilles Chanteperdrix <g...@xenomai.org>.
+ *
+ * ARM port
+ *   Copyright (C) 2005 Stelian Pop
+ *
+ * Copyright (C) 2007 Sebastian Smolorz <se...@gmx.net>
+ *     Support for TSC emulation in user space for decrementing counters
+ *
+ * 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 _LIB_COBALT_ARM_TSC_H
+#define _LIB_COBALT_ARM_TSC_H
+
+#include <asm/xenomai/uapi/tsc.h>
+#include <asm/xenomai/features.h>
+
+/*
+ * Putting kuser_tsc_get and kinfo.counter in the same struct results
+ * in less operations in PIC code, thus optimizes.
+ */
+typedef unsigned long long __xn_rdtsc_t(volatile unsigned *vaddr);
+struct __xn_full_tscinfo {
+       __xn_rdtsc_t *kuser_tsc_get;
+       struct __xn_tscinfo kinfo;
+};
+extern struct __xn_full_tscinfo __xn_tscinfo;
+
+static inline __attribute__((always_inline))
+unsigned long long cobalt_read_tsc(void)
+{
+       return __xn_tscinfo.kuser_tsc_get(__xn_tscinfo.kinfo.counter);
+}
+
+#endif /* !_LIB_COBALT_ARM_TSC_H */


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

Reply via email to