diff options
author | Nicolas Pitre <nico@org.rmk.(none)> | 2004-08-14 18:38:14 +0100 |
---|---|---|
committer | Russell King <rmk@flint.arm.linux.org.uk> | 2004-08-14 18:38:14 +0100 |
commit | 28b3026ec9d0952aad3dfe45e25d05c2d00746c6 (patch) | |
tree | a81511fd26cb8352688f3eacc6a8506870da180a /include | |
parent | 2ac7b327c67b9843f115ada6fc28f0ca5c21b7bc (diff) | |
download | history-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.h | 27 | ||||
-rw-r--r-- | include/asm-arm/fpstate.h | 19 | ||||
-rw-r--r-- | include/asm-arm/thread_info.h | 19 |
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 |