--- zzzz-none-000/linux-2.4.17/arch/mips/kernel/process.c 2001-09-09 17:43:01.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/arch/mips/kernel/process.c 2004-11-24 13:22:35.000000000 +0000 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,8 @@ #include #include +#include + void cpu_idle(void) { /* endless idle loop with no priority at all */ @@ -40,6 +43,13 @@ init_idle(); while (1) { +#if 0 +{ + int cpu = smp_processor_id(); + if(softirq_pending(cpu)) + do_softirq(); +} +#endif while (!current->need_resched) if (cpu_wait) (*cpu_wait)(); @@ -55,8 +65,8 @@ void exit_thread(void) { /* Forget lazy fpu state */ - if (last_task_used_math == current) { - set_cp0_status(ST0_CU1); + if (last_task_used_math == current && mips_cpu.options & MIPS_CPU_FPU) { + __enable_fpu(); __asm__ __volatile__("cfc1\t$0,$31"); last_task_used_math = NULL; } @@ -65,8 +75,8 @@ void flush_thread(void) { /* Forget lazy fpu state */ - if (last_task_used_math == current) { - set_cp0_status(ST0_CU1); + if (last_task_used_math == current && mips_cpu.options & MIPS_CPU_FPU) { + __enable_fpu(); __asm__ __volatile__("cfc1\t$0,$31"); last_task_used_math = NULL; } @@ -84,7 +94,7 @@ if (last_task_used_math == current) if (mips_cpu.options & MIPS_CPU_FPU) { - set_cp0_status(ST0_CU1); + __enable_fpu(); save_fp(p); } /* set up new TSS. */ @@ -123,17 +133,62 @@ return 0; } +extern struct pt_regs *get_task_registers (struct task_struct *task); +extern void save_fp(struct task_struct *); +int dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r) +{ + unsigned long long *fregs; + int i; + unsigned long tmp; + + if (!task->used_math) + return 0; + if(!(mips_cpu.options & MIPS_CPU_FPU)) { + fregs = (unsigned long long *) + task->thread.fpu.soft.regs; + } else { + fregs = (unsigned long long *) + &task->thread.fpu.hard.fp_regs[0]; + if (last_task_used_math == task) { + __enable_fpu(); + save_fp (task); + __disable_fpu(); + last_task_used_math = NULL; + regs->cp0_status &= ~ST0_CU1; + } + } + /* + * The odd registers are actually the high + * order bits of the values stored in the even + * registers - unless we're using r2k_switch.S. + */ + for (i = 0; i < 32; i++) + { +#ifdef CONFIG_CPU_R3000 + if (mips_cpu.options & MIPS_CPU_FPU) + tmp = *(unsigned long *)(fregs + i); + else +#endif + if (i & 1) + tmp = (unsigned long) (fregs[(i & ~1)] >> 32); + else + tmp = (unsigned long) (fregs[i] & 0xffffffff); + + *(unsigned long *)(&(*r)[i]) = tmp; + } + + if (mips_cpu.options & MIPS_CPU_FPU) + tmp = task->thread.fpu.hard.control; + else + tmp = task->thread.fpu.soft.sr; + *(unsigned long *)(&(*r)[32]) = tmp; + return 1; +} + /* Fill in the fpu structure for a core dump.. */ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { - /* We actually store the FPU info in the task->thread - * area. - */ - if(regs->cp0_status & ST0_CU1) { - memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); - return 1; - } - return 0; /* Task didn't use the fpu at all. */ + return dump_task_fpu (regs, current, r); } /* Fill in the user structure for a core dump.. */ @@ -174,16 +229,15 @@ "1: addiu $sp,32 \n" " move %0,$2 \n" ".set reorder" - :"=r" (retval) - :"i" (__NR_clone), "i" (__NR_exit), - "r" (arg), "r" (fn), - "r" (flags | CLONE_VM) + : "=r" (retval) + : "i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), + "r" (flags | CLONE_VM) /* * The called subroutine might have destroyed any of the * at, result, argument or temporary registers ... */ - :"$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$9","$10","$11","$12","$13","$14","$15","$24","$25"); + : "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$9","$10","$11","$12","$13","$14","$15","$24","$25"); return retval; }