]> git.neil.brown.name Git - history.git/commitdiff
[ARM] Eliminate tsk->used_math
authorRussell King <rmk@flint.arm.linux.org.uk>
Fri, 30 Jan 2004 14:49:14 +0000 (14:49 +0000)
committerRussell King <rmk@flint.arm.linux.org.uk>
Fri, 30 Jan 2004 14:49:14 +0000 (14:49 +0000)
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
arch/arm/kernel/entry-armv.S
arch/arm/kernel/process.c
arch/arm/kernel/ptrace.c
include/asm-arm/thread_info.h

index 49562ecdf3650bb56053ef07babb028933899a3b..e2a5e3a76333e3a8af8779ef84ab6ed41cb751ec 100644 (file)
@@ -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));
index f20207dede1e9d42b13abf535586850881af2a99..da2f8fa12d232c46a21dcf8f577b155fb009a324 100644 (file)
@@ -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
index 5084effd60055ce3e620ea172e85e6d865972801..84508f21ff68f4ef897c56ffa1424e5b1487f6ba 100644 (file)
@@ -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;
 }
 
 /*
index 3fafcf7e9e401f13c545ceb9eda1514f27a093eb..6450f55bd9b9f8ba07cc7b15a627bc2999b85e3c 100644 (file)
@@ -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;
 }
 
index 642810a9ed84ffe7db8a0420c57f947b4d6f8d9f..16a541206166b1cf5a3acad6857314348ba4e8bd 100644 (file)
@@ -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