From 41754b1fab9c86a32b6804c6f365ddf3a9783322 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 30 Jan 2004 14:49:14 +0000 Subject: [PATCH] [ARM] Eliminate tsk->used_math Remove usage of tsk->used_math on ARM, moving the status to an array of co-processor usage. (ARM can have up to 15 co-processors providing various extra facilities such as SIMD, VFP or FP.) --- arch/arm/kernel/asm-offsets.c | 1 - arch/arm/kernel/entry-armv.S | 50 ++++++++++++++++++++++++++--------- arch/arm/kernel/process.c | 7 +++-- arch/arm/kernel/ptrace.c | 5 ++-- include/asm-arm/thread_info.h | 6 +++-- 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 49562ecdf3650..e2a5e3a76333e 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -45,7 +45,6 @@ int main(void) { - DEFINE(TSK_USED_MATH, offsetof(struct task_struct, used_math)); DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); BLANK(); DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index f20207dede1e9..da2f8fa12d232 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -963,23 +963,46 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go * co-processor instructions. However, we have to watch out * for the ARM6/ARM7 SWI bug. * - * Emulators may wish to make use of the instruction value we - * prepared for them in r0. + * Emulators may wish to make use of the following registers: + * r0 - instruction opcode. + * r10 - this threads thread_info structure. */ call_fpe: enable_irq r10 @ Enable interrupts tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) - and r10, r0, #0x0f000000 @ mask out op-code bits - teqne r10, #0x0f000000 @ SWI (ARM6/7 bug)? + and r8, r0, #0x0f000000 @ mask out op-code bits + teqne r8, #0x0f000000 @ SWI (ARM6/7 bug)? #endif moveq pc, lr -do_fpe: get_thread_info r10 @ get current thread - ldr r4, [r10, #TI_TASK] @ get current task - mov r8, #1 - strb r8, [r4, #TSK_USED_MATH] @ set current->used_math - ldr r4, .LCfp + get_thread_info r10 @ get current thread + and r8, r0, #0x00000f00 @ mask out CP number + mov r7, #1 + add r6, r10, #TI_USED_CP + strb r7, [r6, r8, lsr #8] @ set appropriate used_cp[] + add pc, pc, r8, lsr #6 + mov r0, r0 + + mov pc, lr @ CP#0 + b do_fpe @ CP#1 (FPE) + b do_fpe @ CP#2 (FPE) + mov pc, lr @ CP#3 + mov pc, lr @ CP#4 + mov pc, lr @ CP#5 + mov pc, lr @ CP#6 + mov pc, lr @ CP#7 + mov pc, lr @ CP#8 + mov pc, lr @ CP#9 + mov pc, lr @ CP#10 (VFP) + mov pc, lr @ CP#11 (VFP) + mov pc, lr @ CP#12 + mov pc, lr @ CP#13 + mov pc, lr @ CP#14 (Debug) + mov pc, lr @ CP#15 (Control) + +do_fpe: ldr r4, .LCfp add r10, r10, #TI_FPSTATE @ r10 = workspace ldr pc, [r4] @ Call FP module USR entry point + /* * The FP module is called with these registers set: * r0 = instruction @@ -989,6 +1012,11 @@ do_fpe: get_thread_info r10 @ get current thread * lr = unrecognised FP instruction return address */ + .data +ENTRY(fp_enter) + .word fpe_not_present + .text + fpundefinstr: mov r0, sp adrsvc al, lr, ret_from_exception b do_undefinstr @@ -1016,10 +1044,6 @@ ENTRY(ret_from_exception) mov why, #0 b ret_to_user - .data -ENTRY(fp_enter) - .word fpe_not_present - .text /* * Register switch for ARMv3 and ARMv4 processors * r0 = previous thread_info, r1 = next thread_info diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 5084effd60055..84508f21ff68f 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -307,8 +307,7 @@ void flush_thread(void) struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; - tsk->used_math = 0; - + memset(thread->used_cp, 0, sizeof(thread->used_cp)); memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); fp_init(&thread->fpstate); } @@ -344,12 +343,12 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start, int dump_fpu (struct pt_regs *regs, struct user_fp *fp) { struct thread_info *thread = current_thread_info(); - int used_math = current->used_math; + int used_math = thread->used_cp[1] | thread->used_cp[2]; if (used_math) memcpy(fp, &thread->fpstate.soft, sizeof (*fp)); - return used_math; + return used_math != 0; } /* diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 3fafcf7e9e401..6450f55bd9b9f 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -602,8 +602,9 @@ static int ptrace_getfpregs(struct task_struct *tsk, void *ufp) */ static int ptrace_setfpregs(struct task_struct *tsk, void *ufp) { - tsk->used_math = 1; - return copy_from_user(&tsk->thread_info->fpstate, ufp, + struct thread_info *thread = tsk->thread_info; + thread->used_cp[1] = thread->used_cp[2] = 1; + return copy_from_user(&thread->fpstate, ufp, sizeof(struct user_fp)) ? -EFAULT : 0; } diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h index 642810a9ed84f..16a541206166b 100644 --- a/include/asm-arm/thread_info.h +++ b/include/asm-arm/thread_info.h @@ -51,8 +51,9 @@ struct thread_info { __u32 cpu; /* cpu */ __u32 cpu_domain; /* cpu domain */ struct cpu_context_save cpu_context; /* cpu context */ - struct restart_block restart_block; + __u8 used_cp[16]; /* thread used copro */ union fp_state fpstate; + struct restart_block restart_block; }; #define INIT_THREAD_INFO(tsk) \ @@ -107,7 +108,8 @@ extern void free_thread_info(struct thread_info *); #define TI_CPU 20 #define TI_CPU_DOMAIN 24 #define TI_CPU_SAVE 28 -#define TI_FPSTATE 76 +#define TI_USED_MATH 76 +#define TI_FPSTATE (TI_USED_MATH+16) #endif -- 2.53.0