aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorNicolas Pitre <nico@org.rmk.(none)>2004-08-14 18:38:14 +0100
committerRussell King <rmk@flint.arm.linux.org.uk>2004-08-14 18:38:14 +0100
commit28b3026ec9d0952aad3dfe45e25d05c2d00746c6 (patch)
treea81511fd26cb8352688f3eacc6a8506870da180a /include
parent2ac7b327c67b9843f115ada6fc28f0ca5c21b7bc (diff)
downloadhistory-28b3026ec9d0952aad3dfe45e25d05c2d00746c6.tar.gz
[ARM PATCH] 1866/4: kernel support for iWMMXt present on some XScale cores
Patch from Nicolas Pitre This is required for a system with user space binaries using iWMMXt instructions to even boot (revised again). It also moves defines for thread_info offsets from magic static values to the auto generated asm/constants.h in order to better cope with changing structure offsets and avoid user errors.
Diffstat (limited to 'include')
-rw-r--r--include/asm-arm/elf.h27
-rw-r--r--include/asm-arm/fpstate.h19
-rw-r--r--include/asm-arm/thread_info.h19
3 files changed, 49 insertions, 16 deletions
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index b67e06c0f588e4..29533be8be619e 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -1,6 +1,8 @@
#ifndef __ASMARM_ELF_H
#define __ASMARM_ELF_H
+#include <linux/config.h>
+
/*
* ELF register definitions..
*/
@@ -14,6 +16,7 @@ typedef unsigned long elf_freg_t[3];
#define EM_ARM 40
#define EF_ARM_APCS26 0x08
+#define EF_ARM_SOFT_FLOAT 0x200
#define R_ARM_NONE 0
#define R_ARM_PC24 1
@@ -91,6 +94,8 @@ extern char elf_platform[];
(( (elf_hwcap & HWCAP_26BIT) && (x)->e_flags & EF_ARM_APCS26) || \
((x)->e_flags & EF_ARM_APCS26) == 0)
+#ifndef CONFIG_IWMMXT
+
/* Old NetWinder binaries were compiled in such a way that the iBCS
heuristic always trips on them. Until these binaries become uncommon
enough not to care, don't trust the `ibcs' flag here. In any case
@@ -99,6 +104,28 @@ extern char elf_platform[];
#define SET_PERSONALITY(ex,ibcs2) \
set_personality(((ex).e_flags&EF_ARM_APCS26 ?PER_LINUX :PER_LINUX_32BIT))
+#else
+
+/*
+ * All iWMMXt capable CPUs don't support 26-bit mode. Yet they can run
+ * legacy binaries which used to contain FPA11 floating point instructions
+ * that have always been emulated by the kernel. PFA11 and iWMMXt overlap
+ * on coprocessor 1 space though. We therefore must decide if given task
+ * is allowed to use CP 0 and 1 for iWMMXt, or if they should be blocked
+ * at all times for the prefetch exception handler to catch FPA11 opcodes
+ * and emulate them. The best indication to discriminate those two cases
+ * is the SOFT_FLOAT flag in the ELF header.
+ */
+
+#define SET_PERSONALITY(ex,ibcs2) \
+do { \
+ set_personality(PER_LINUX_32BIT); \
+ if ((ex).e_flags & EF_ARM_SOFT_FLOAT) \
+ set_thread_flag(TIF_USING_IWMMXT); \
+} while (0)
+
+#endif
+
#endif
#endif
diff --git a/include/asm-arm/fpstate.h b/include/asm-arm/fpstate.h
index 7492cfa21f7a57..f7430e3aa55d2e 100644
--- a/include/asm-arm/fpstate.h
+++ b/include/asm-arm/fpstate.h
@@ -11,7 +11,7 @@
#ifndef __ASM_ARM_FPSTATE_H
#define __ASM_ARM_FPSTATE_H
-#define FP_SIZE 35
+#include <linux/config.h>
#ifndef __ASSEMBLY__
@@ -43,19 +43,32 @@ union vfp_state {
extern void vfp_flush_thread(union vfp_state *);
extern void vfp_release_thread(union vfp_state *);
+#define FP_HARD_SIZE 35
+
struct fp_hard_struct {
- unsigned int save[FP_SIZE]; /* as yet undefined */
+ unsigned int save[FP_HARD_SIZE]; /* as yet undefined */
};
+#define FP_SOFT_SIZE 35
+
struct fp_soft_struct {
- unsigned int save[FP_SIZE]; /* undefined information */
+ unsigned int save[FP_SOFT_SIZE]; /* undefined information */
+};
+
+struct iwmmxt_struct {
+ unsigned int save[0x98/sizeof(int) + 1];
};
union fp_state {
struct fp_hard_struct hard;
struct fp_soft_struct soft;
+#ifdef CONFIG_IWMMXT
+ struct iwmmxt_struct iwmmxt;
+#endif
};
+#define FP_SIZE (sizeof(union fp_state) / sizeof(int))
+
#endif
#endif
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index b3ef76481942aa..9f08222633aa04 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -100,19 +100,10 @@ extern void free_thread_info(struct thread_info *);
#define thread_saved_fp(tsk) \
((unsigned long)((tsk)->thread_info->cpu_context.fp))
-#else /* !__ASSEMBLY__ */
-
-#define TI_FLAGS 0
-#define TI_PREEMPT 4
-#define TI_ADDR_LIMIT 8
-#define TI_TASK 12
-#define TI_EXEC_DOMAIN 16
-#define TI_CPU 20
-#define TI_CPU_DOMAIN 24
-#define TI_CPU_SAVE 28
-#define TI_USED_CP 76
-#define TI_FPSTATE (TI_USED_CP+16)
-#define TI_VFPSTATE (TI_FPSTATE+FP_SIZE*4)
+extern void iwmmxt_task_disable(struct thread_info *);
+extern void iwmmxt_task_copy(struct thread_info *, void *);
+extern void iwmmxt_task_restore(struct thread_info *, void *);
+extern void iwmmxt_task_release(struct thread_info *);
#endif
@@ -133,6 +124,7 @@ extern void free_thread_info(struct thread_info *);
#define TIF_SYSCALL_TRACE 8
#define TIF_USED_FPU 16
#define TIF_POLLING_NRFLAG 17
+#define TIF_USING_IWMMXT 18
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -140,6 +132,7 @@ extern void free_thread_info(struct thread_info *);
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_USED_FPU (1 << TIF_USED_FPU)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
/*
* Change these and you break ASM code in entry-common.S