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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Oct 16 14:21:56 2014 +0200

cobalt/x86: enable 32bit syscall emulation

---

 kernel/cobalt/arch/x86/Kconfig                     |    5 +-
 .../cobalt/arch/x86/include/asm/xenomai/syscall.h  |    8 +-
 .../arch/x86/include/asm/xenomai/syscall32-table.h |   54 ++++---
 .../arch/x86/include/asm/xenomai/syscall32.h       |  147 ++++++++++++++++++--
 4 files changed, 180 insertions(+), 34 deletions(-)

diff --git a/kernel/cobalt/arch/x86/Kconfig b/kernel/cobalt/arch/x86/Kconfig
index 72e539a..9adbbf7 100644
--- a/kernel/cobalt/arch/x86/Kconfig
+++ b/kernel/cobalt/arch/x86/Kconfig
@@ -1,9 +1,8 @@
 config XENO_ARCH_FPU
        def_bool y
 
-config XENO_ARCH_X32
-        def_bool X86_X32
-       select XENO_OPT_SYS3264
+config XENO_ARCH_SYS3264
+        def_bool IA32_EMULATION
 
 source "kernel/xenomai/Kconfig"
 source "drivers/xenomai/Kconfig"
diff --git a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall.h 
b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall.h
index ddbb3df..5901e4d 100644
--- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall.h
+++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall.h
@@ -42,8 +42,12 @@
 #define __xn_reg_sp(regs)     ((regs)->sp)
 
 #define __xn_syscall_p(regs)  (__xn_reg_sys(regs) & __COBALT_SYSCALL_BIT)
-#define __xn_syscall(regs)    (__xn_reg_sys(regs) & \
-                              ~(__COBALT_SYSCALL_BIT|__COBALT_SYSCALL_MASK))
+#ifdef CONFIG_XENO_ARCH_SYS3264
+#define __xn_syscall(regs)    __COBALT_CALL32_SYSNR(__xn_reg_sys(regs) \
+                                   & ~__COBALT_SYSCALL_BIT)
+#else
+#define __xn_syscall(regs)    (__xn_reg_sys(regs) & ~__COBALT_SYSCALL_BIT)
+#endif
 
 static inline void __xn_success_return(struct pt_regs *regs, int v)
 {
diff --git a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h 
b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h
index b7da23b..1c84ef3 100644
--- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h
+++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h
@@ -24,22 +24,42 @@
  * table. Only preprocessor stuff and syscall entries here.
  */
 
-#ifdef CONFIG_X86_X32
-
-/*
- * When x32 support is enabled, we need thunks for dealing with
- * 32<->64 argument conversion. An additional entry for each
- * __COBALT_CALL_X32 syscall is generated into the table, at a
- * position equal to the original syscall number + __COBALT_X32_BASE
- * as defined in asm/xenomai/syscall32.h.
- */
-
-#define __sysx32__(__name)             \
-       ((cobalt_syshand)(cobalt32x_ ## __name))
-
-#define __COBALT_CALL_X32(__name)      \
-       [sc_cobalt_ ## __name + __COBALT_X32_BASE] = __sysx32__(__name),
-
-#endif
+__COBALT_CALL32emu_THUNK(thread_create)
+__COBALT_CALL32emu_THUNK(thread_setschedparam_ex)
+__COBALT_CALL32emu_THUNK(thread_getschedparam_ex)
+__COBALT_CALL32emu_THUNK(sem_open)
+__COBALT_CALL32emu_THUNK(sem_timedwait)
+__COBALT_CALL32emu_THUNK(clock_getres)
+__COBALT_CALL32emu_THUNK(clock_gettime)
+__COBALT_CALL32emu_THUNK(clock_settime)
+__COBALT_CALL32emu_THUNK(clock_nanosleep)
+__COBALT_CALL32emu_THUNK(mutex_timedlock)
+__COBALT_CALL32emu_THUNK(cond_wait_prologue)
+__COBALT_CALL32emu_THUNK(mq_open)
+__COBALT_CALL32emu_THUNK(mq_getattr)
+__COBALT_CALL32emu_THUNK(mq_setattr)
+__COBALT_CALL32emu_THUNK(mq_timedsend)
+__COBALT_CALL32emu_THUNK(mq_timedreceive)
+__COBALT_CALL32emu_THUNK(mq_notify)
+__COBALT_CALL32emu_THUNK(sched_weightprio)
+__COBALT_CALL32emu_THUNK(sched_setconfig_np)
+__COBALT_CALL32emu_THUNK(sched_getconfig_np)
+__COBALT_CALL32emu_THUNK(timer_create)
+__COBALT_CALL32emu_THUNK(timer_settime)
+__COBALT_CALL32emu_THUNK(timer_gettime)
+__COBALT_CALL32emu_THUNK(timerfd_settime)
+__COBALT_CALL32emu_THUNK(timerfd_gettime)
+__COBALT_CALL32emu_THUNK(sigwait)
+__COBALT_CALL32emu_THUNK(sigtimedwait)
+__COBALT_CALL32emu_THUNK(sigwaitinfo)
+__COBALT_CALL32emu_THUNK(sigpending)
+__COBALT_CALL32emu_THUNK(sigqueue)
+__COBALT_CALL32emu_THUNK(monitor_wait)
+__COBALT_CALL32emu_THUNK(event_wait)
+__COBALT_CALL32emu_THUNK(select)
+__COBALT_CALL32emu_THUNK(recvmsg)
+__COBALT_CALL32emu_THUNK(sendmsg)
+__COBALT_CALL32emu_THUNK(mmap)
+__COBALT_CALL32emu_THUNK(backtrace)
 
 #endif /* !_COBALT_X86_ASM_SYSCALL32_TABLE_H */
diff --git a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h 
b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h
index b83aaf4..e4890a6 100644
--- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h
+++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h
@@ -19,26 +19,50 @@
 #ifndef _COBALT_X86_ASM_SYSCALL32_H
 #define _COBALT_X86_ASM_SYSCALL32_H
 
+#include <asm/unistd.h>
+
 #ifdef CONFIG_X86_X32
 
-#include <linux/compat.h>
+#define __COBALT_X32_BASE              128
+
+#define __COBALT_SYSNR32x(__reg)                       \
+       ({                                              \
+               long __nr = __reg;                      \
+               if (__nr & __X32_SYSCALL_BIT) {         \
+                       __nr &= ~__X32_SYSCALL_BIT;     \
+                       __nr += __COBALT_X32_BASE;      \
+               }                                       \
+               __nr;                                   \
+       })
 
-#define __COBALT_X32_BASE      128
-#define __COBALT_SYSCALL_MASK  __X32_SYSCALL_BIT
+#define __COBALT_COMPAT32x(__reg)                      \
+       (((__reg) & __X32_SYSCALL_BIT) ? __COBALT_COMPATX_BIT : 0)
 
-#if __NR_COBALT_SYSCALLS >= __COBALT_X32_BASE
-#error "__NR_COBALT_SYSCALLS >= __COBALT_X32_BASE"
+#if __NR_COBALT_SYSCALLS > __COBALT_X32_BASE
+#error "__NR_COBALT_SYSCALLS > __COBALT_X32_BASE"
 #endif
 
-/* 32bit call entry, assigning __handler to call #__name. */
-#define __COBALT_CALL32_ENTRY(__name, __handler)               \
+#define __syshand32x__(__name) ((cobalt_syshand)(cobalt32x_ ## __name))
+
+#define __COBALT_CALL32x_INITHAND(__handler)   \
+  , [__COBALT_X32_BASE ... __COBALT_X32_BASE + __NR_COBALT_SYSCALLS-1] = 
__handler
+
+#define __COBALT_CALL32x_INITMODE(__mode)      \
+  , [__COBALT_X32_BASE ... __COBALT_X32_BASE + __NR_COBALT_SYSCALLS-1] = __mode
+
+/* x32 default entry (no thunk) */
+#define __COBALT_CALL32x_ENTRY(__name, __handler)              \
        , [sc_cobalt_ ## __name + __COBALT_X32_BASE] = __handler
 
-/* 32bit thunk implementation. */
+/* x32 thunk installation */
+#define __COBALT_CALL32x_THUNK(__name) \
+       __COBALT_CALL32x_ENTRY(__name, __syshand32x__(__name))
+
+/* x32 thunk implementation. */
 #define COBALT_SYSCALL32x(__name, __mode, __type, __args)      \
        __typeof__(__type) cobalt32x_ ## __name __args
 
-/* 32bit thunk declaration. */
+/* x32 thunk declaration. */
 #define COBALT_SYSCALL32x_DECL(__name, __type, __args) \
        __typeof__(__type) cobalt32x_ ## __name __args
 
@@ -46,14 +70,113 @@
 
 /* x32 support disabled. */
 
-#define __COBALT_CALL32_ENTRY(__name, __handler)
+#define __COBALT_SYSNR32x(__reg)       (__reg)
+
+#define __COBALT_COMPAT32x(__reg)      0
+
+#define __COBALT_CALL32x_INITHAND(__handler)
+
+#define __COBALT_CALL32x_INITMODE(__mode)
+
+#define __COBALT_CALL32x_ENTRY(__name, __handler)
+
+#define __COBALT_CALL32x_THUNK(__name)
 
 #define COBALT_SYSCALL32x_DECL(__name, __type, __args)
 
 #endif /* !CONFIG_X86_X32 */
 
-#ifndef __COBALT_SYSCALL_MASK
-#define __COBALT_SYSCALL_MASK  0
+#ifdef CONFIG_IA32_EMULATION
+
+#define __COBALT_IA32_BASE             256 /* Power of two. */
+
+#define __COBALT_SYSNR32emu(__reg)                                     \
+       ({                                                              \
+               long __nr = __reg;                                      \
+               if (current_thread_info()->status & TS_COMPAT)          \
+                       __nr += __COBALT_IA32_BASE;                     \
+               __nr;                                                   \
+       })
+
+#define __COBALT_COMPAT32emu(__reg)                                    \
+       ((current_thread_info()->status & TS_COMPAT) ? __COBALT_COMPAT_BIT : 0)
+
+#if __NR_COBALT_SYSCALLS > __COBALT_IA32_BASE
+#error "__NR_COBALT_SYSCALLS > __COBALT_IA32_BASE"
 #endif
 
+#define __syshand32emu__(__name)       ((cobalt_syshand)(cobalt32emu_ ## 
__name))
+
+#define __COBALT_CALL32emu_INITHAND(__handler) \
+  , [__COBALT_IA32_BASE ... __COBALT_IA32_BASE + __NR_COBALT_SYSCALLS-1] = 
__handler
+
+#define __COBALT_CALL32emu_INITMODE(__mode)    \
+  , [__COBALT_IA32_BASE ... __COBALT_IA32_BASE + __NR_COBALT_SYSCALLS-1] = 
__mode
+
+/* ia32 default entry (no thunk) */
+#define __COBALT_CALL32emu_ENTRY(__name, __handler)            \
+       , [sc_cobalt_ ## __name + __COBALT_IA32_BASE] = __handler
+
+/* ia32 thunk installation */
+#define __COBALT_CALL32emu_THUNK(__name)       \
+       __COBALT_CALL32emu_ENTRY(__name, __syshand32emu__(__name))
+
+/* ia32 thunk implementation. */
+#define COBALT_SYSCALL32emu(__name, __mode, __type, __args)    \
+       __typeof__(__type) cobalt32emu_ ## __name __args
+
+/* ia32 thunk declaration. */
+#define COBALT_SYSCALL32emu_DECL(__name, __type, __args)       \
+       __typeof__(__type) cobalt32emu_ ## __name __args
+
+#else /* !CONFIG_IA32_EMULATION */
+
+/* ia32 emulation support disabled. */
+
+#define __COBALT_SYSNR32emu(__reg)     (__reg)
+
+#define __COBALT_COMPAT32emu(__reg)    0
+
+#define __COBALT_CALL32emu_INITHAND(__handler)
+
+#define __COBALT_CALL32emu_INITMODE(__mode)
+
+#define __COBALT_CALL32emu_ENTRY(__name, __handler)
+
+#define __COBALT_CALL32emu_THUNK(__name)
+
+#define COBALT_SYSCALL32emu_DECL(__name, __type, __args)
+
+#endif /* !CONFIG_IA32_EMULATION */
+
+#define __COBALT_CALL32_ENTRY(__name, __handler)       \
+       __COBALT_CALL32x_ENTRY(__name, __handler)       \
+       __COBALT_CALL32emu_ENTRY(__name, __handler)
+
+#define __COBALT_CALL32_INITHAND(__handler)    \
+       __COBALT_CALL32x_INITHAND(__handler)    \
+       __COBALT_CALL32emu_INITHAND(__handler)
+
+#define __COBALT_CALL32_INITMODE(__mode)       \
+       __COBALT_CALL32x_INITMODE(__mode)       \
+       __COBALT_CALL32emu_INITMODE(__mode)
+
+/* Already checked for __COBALT_SYSCALL_BIT */
+#define __COBALT_CALL32_SYSNR(__reg)                           \
+       ({                                                      \
+               long __nr;                                      \
+               __nr = __COBALT_SYSNR32x(__reg);                \
+               if (__nr == (__reg))                            \
+                       __nr = __COBALT_SYSNR32emu(__reg);      \
+               __nr;                                           \
+       })
+
+#define __COBALT_CALL_COMPAT(__reg)                            \
+       ({                                                      \
+               int __ret = __COBALT_COMPAT32x(__reg);          \
+               if (__ret == 0)                                 \
+                       __ret = __COBALT_COMPAT32emu(__reg);    \
+               __ret;                                          \
+       })
+
 #endif /* !_COBALT_X86_ASM_SYSCALL32_H */


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

Reply via email to