diff options
-rw-r--r-- | arch/powerpc/kernel/Makefile | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/fpu.S | 31 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_32.S | 27 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_64.S | 19 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/ppc/kernel/align.c | 4 | ||||
-rw-r--r-- | arch/ppc/kernel/misc.S | 27 | ||||
-rw-r--r-- | arch/ppc/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/ppc/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/ppc/math-emu/sfp-machine.h | 2 | ||||
-rw-r--r-- | arch/ppc64/Kconfig | 3 | ||||
-rw-r--r-- | arch/ppc64/Makefile | 1 | ||||
-rw-r--r-- | arch/ppc64/kernel/align.c | 4 | ||||
-rw-r--r-- | arch/ppc64/kernel/head.S | 59 | ||||
-rw-r--r-- | arch/ppc64/kernel/misc.S | 51 | ||||
-rw-r--r-- | arch/ppc64/kernel/signal.c | 2 | ||||
-rw-r--r-- | include/asm-powerpc/processor.h | 11 | ||||
-rw-r--r-- | include/asm-powerpc/system.h | 4 | ||||
-rw-r--r-- | include/asm-ppc/system.h | 4 | ||||
-rw-r--r-- | include/asm-ppc64/system.h | 4 |
22 files changed, 59 insertions, 209 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index a733347964a0..94cf917b7854 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -29,7 +29,6 @@ extra-$(CONFIG_44x) := head_44x.o | |||
29 | extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o | 29 | extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o |
30 | extra-$(CONFIG_8xx) := head_8xx.o | 30 | extra-$(CONFIG_8xx) := head_8xx.o |
31 | extra-$(CONFIG_PPC64) += entry_64.o | 31 | extra-$(CONFIG_PPC64) += entry_64.o |
32 | extra-$(CONFIG_PPC_FPU) += fpu.o | ||
33 | extra-y += vmlinux.lds | 32 | extra-y += vmlinux.lds |
34 | 33 | ||
35 | obj-y += process.o init_task.o time.o \ | 34 | obj-y += process.o init_task.o time.o \ |
@@ -49,7 +48,7 @@ else | |||
49 | # stuff used from here for ARCH=ppc or ARCH=ppc64 | 48 | # stuff used from here for ARCH=ppc or ARCH=ppc64 |
50 | obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o | 49 | obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o |
51 | 50 | ||
52 | fpux-$(CONFIG_PPC32) += fpu.o | ||
53 | extra-$(CONFIG_PPC_FPU) += $(fpux-y) | ||
54 | 51 | ||
55 | endif | 52 | endif |
53 | |||
54 | extra-$(CONFIG_PPC_FPU) += fpu.o | ||
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 563d445ff584..51fd78da25b7 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S | |||
@@ -48,7 +48,7 @@ _GLOBAL(load_up_fpu) | |||
48 | addi r4,r4,THREAD /* want last_task_used_math->thread */ | 48 | addi r4,r4,THREAD /* want last_task_used_math->thread */ |
49 | SAVE_32FPRS(0, r4) | 49 | SAVE_32FPRS(0, r4) |
50 | mffs fr0 | 50 | mffs fr0 |
51 | stfd fr0,THREAD_FPSCR-4(r4) | 51 | stfd fr0,THREAD_FPSCR(r4) |
52 | LDL r5,PT_REGS(r4) | 52 | LDL r5,PT_REGS(r4) |
53 | tophys(r5,r5) | 53 | tophys(r5,r5) |
54 | LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | 54 | LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) |
@@ -71,7 +71,7 @@ _GLOBAL(load_up_fpu) | |||
71 | or r12,r12,r4 | 71 | or r12,r12,r4 |
72 | std r12,_MSR(r1) | 72 | std r12,_MSR(r1) |
73 | #endif | 73 | #endif |
74 | lfd fr0,THREAD_FPSCR-4(r5) | 74 | lfd fr0,THREAD_FPSCR(r5) |
75 | mtfsf 0xff,fr0 | 75 | mtfsf 0xff,fr0 |
76 | REST_32FPRS(0, r5) | 76 | REST_32FPRS(0, r5) |
77 | #ifndef CONFIG_SMP | 77 | #ifndef CONFIG_SMP |
@@ -104,7 +104,7 @@ _GLOBAL(giveup_fpu) | |||
104 | CMPI 0,r5,0 | 104 | CMPI 0,r5,0 |
105 | SAVE_32FPRS(0, r3) | 105 | SAVE_32FPRS(0, r3) |
106 | mffs fr0 | 106 | mffs fr0 |
107 | stfd fr0,THREAD_FPSCR-4(r3) | 107 | stfd fr0,THREAD_FPSCR(r3) |
108 | beq 1f | 108 | beq 1f |
109 | LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | 109 | LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5) |
110 | li r3,MSR_FP|MSR_FE0|MSR_FE1 | 110 | li r3,MSR_FP|MSR_FE0|MSR_FE1 |
@@ -117,3 +117,28 @@ _GLOBAL(giveup_fpu) | |||
117 | STL r5,OFF(last_task_used_math)(r4) | 117 | STL r5,OFF(last_task_used_math)(r4) |
118 | #endif /* CONFIG_SMP */ | 118 | #endif /* CONFIG_SMP */ |
119 | blr | 119 | blr |
120 | |||
121 | /* | ||
122 | * These are used in the alignment trap handler when emulating | ||
123 | * single-precision loads and stores. | ||
124 | * We restore and save the fpscr so the task gets the same result | ||
125 | * and exceptions as if the cpu had performed the load or store. | ||
126 | */ | ||
127 | |||
128 | _GLOBAL(cvt_fd) | ||
129 | lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */ | ||
130 | mtfsf 0xff,0 | ||
131 | lfs 0,0(r3) | ||
132 | stfd 0,0(r4) | ||
133 | mffs 0 | ||
134 | stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */ | ||
135 | blr | ||
136 | |||
137 | _GLOBAL(cvt_df) | ||
138 | lfd 0,THREAD_FPSCR(r5) /* load up fpscr value */ | ||
139 | mtfsf 0xff,0 | ||
140 | lfd 0,0(r3) | ||
141 | stfs 0,0(r4) | ||
142 | mffs 0 | ||
143 | stfd 0,THREAD_FPSCR(r5) /* save new fpscr value */ | ||
144 | blr | ||
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 303229b090b8..3bedb532aed9 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -993,33 +993,6 @@ _GLOBAL(_get_SP) | |||
993 | blr | 993 | blr |
994 | 994 | ||
995 | /* | 995 | /* |
996 | * These are used in the alignment trap handler when emulating | ||
997 | * single-precision loads and stores. | ||
998 | * We restore and save the fpscr so the task gets the same result | ||
999 | * and exceptions as if the cpu had performed the load or store. | ||
1000 | */ | ||
1001 | |||
1002 | #ifdef CONFIG_PPC_FPU | ||
1003 | _GLOBAL(cvt_fd) | ||
1004 | lfd 0,-4(r5) /* load up fpscr value */ | ||
1005 | mtfsf 0xff,0 | ||
1006 | lfs 0,0(r3) | ||
1007 | stfd 0,0(r4) | ||
1008 | mffs 0 /* save new fpscr value */ | ||
1009 | stfd 0,-4(r5) | ||
1010 | blr | ||
1011 | |||
1012 | _GLOBAL(cvt_df) | ||
1013 | lfd 0,-4(r5) /* load up fpscr value */ | ||
1014 | mtfsf 0xff,0 | ||
1015 | lfd 0,0(r3) | ||
1016 | stfs 0,0(r4) | ||
1017 | mffs 0 /* save new fpscr value */ | ||
1018 | stfd 0,-4(r5) | ||
1019 | blr | ||
1020 | #endif | ||
1021 | |||
1022 | /* | ||
1023 | * Create a kernel thread | 996 | * Create a kernel thread |
1024 | * kernel_thread(fn, arg, flags) | 997 | * kernel_thread(fn, arg, flags) |
1025 | */ | 998 | */ |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 4775bed42cac..b3e95ff0dba0 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -462,25 +462,6 @@ _GLOBAL(_outsl_ns) | |||
462 | sync | 462 | sync |
463 | blr | 463 | blr |
464 | 464 | ||
465 | |||
466 | _GLOBAL(cvt_fd) | ||
467 | lfd 0,0(r5) /* load up fpscr value */ | ||
468 | mtfsf 0xff,0 | ||
469 | lfs 0,0(r3) | ||
470 | stfd 0,0(r4) | ||
471 | mffs 0 /* save new fpscr value */ | ||
472 | stfd 0,0(r5) | ||
473 | blr | ||
474 | |||
475 | _GLOBAL(cvt_df) | ||
476 | lfd 0,0(r5) /* load up fpscr value */ | ||
477 | mtfsf 0xff,0 | ||
478 | lfd 0,0(r3) | ||
479 | stfs 0,0(r4) | ||
480 | mffs 0 /* save new fpscr value */ | ||
481 | stfd 0,0(r5) | ||
482 | blr | ||
483 | |||
484 | /* | 465 | /* |
485 | * identify_cpu and calls setup_cpu | 466 | * identify_cpu and calls setup_cpu |
486 | * In: r3 = base of the cpu_specs array | 467 | * In: r3 = base of the cpu_specs array |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 047da1ae21fe..8f85dabe4df3 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -665,7 +665,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) | |||
665 | #endif | 665 | #endif |
666 | #endif /* CONFIG_SMP */ | 666 | #endif /* CONFIG_SMP */ |
667 | memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); | 667 | memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); |
668 | current->thread.fpscr = 0; | 668 | current->thread.fpscr.val = 0; |
669 | #ifdef CONFIG_ALTIVEC | 669 | #ifdef CONFIG_ALTIVEC |
670 | memset(current->thread.vr, 0, sizeof(current->thread.vr)); | 670 | memset(current->thread.vr, 0, sizeof(current->thread.vr)); |
671 | memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); | 671 | memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 92452b2db26a..444c3e81884c 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -403,7 +403,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, | |||
403 | ELF_NFPREG * sizeof(double))) | 403 | ELF_NFPREG * sizeof(double))) |
404 | return 1; | 404 | return 1; |
405 | 405 | ||
406 | current->thread.fpscr = 0; /* turn off all fp exceptions */ | 406 | current->thread.fpscr.val = 0; /* turn off all fp exceptions */ |
407 | 407 | ||
408 | #ifdef CONFIG_ALTIVEC | 408 | #ifdef CONFIG_ALTIVEC |
409 | /* save altivec registers */ | 409 | /* save altivec registers */ |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index f87580382da4..5d638ecddbd0 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -549,7 +549,7 @@ static void parse_fpe(struct pt_regs *regs) | |||
549 | 549 | ||
550 | flush_fp_to_thread(current); | 550 | flush_fp_to_thread(current); |
551 | 551 | ||
552 | fpscr = current->thread.fpscr; | 552 | fpscr = current->thread.fpscr.val; |
553 | 553 | ||
554 | /* Invalid operation */ | 554 | /* Invalid operation */ |
555 | if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) | 555 | if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) |
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c index ff81da9598d8..ab398c4b70b6 100644 --- a/arch/ppc/kernel/align.c +++ b/arch/ppc/kernel/align.c | |||
@@ -375,7 +375,7 @@ fix_alignment(struct pt_regs *regs) | |||
375 | #ifdef CONFIG_PPC_FPU | 375 | #ifdef CONFIG_PPC_FPU |
376 | preempt_disable(); | 376 | preempt_disable(); |
377 | enable_kernel_fp(); | 377 | enable_kernel_fp(); |
378 | cvt_fd(&data.f, &data.d, ¤t->thread.fpscr); | 378 | cvt_fd(&data.f, &data.d, ¤t->thread); |
379 | preempt_enable(); | 379 | preempt_enable(); |
380 | #else | 380 | #else |
381 | return 0; | 381 | return 0; |
@@ -385,7 +385,7 @@ fix_alignment(struct pt_regs *regs) | |||
385 | #ifdef CONFIG_PPC_FPU | 385 | #ifdef CONFIG_PPC_FPU |
386 | preempt_disable(); | 386 | preempt_disable(); |
387 | enable_kernel_fp(); | 387 | enable_kernel_fp(); |
388 | cvt_df(&data.d, &data.f, ¤t->thread.fpscr); | 388 | cvt_df(&data.d, &data.f, ¤t->thread); |
389 | preempt_enable(); | 389 | preempt_enable(); |
390 | #else | 390 | #else |
391 | return 0; | 391 | return 0; |
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 2350f3e09f95..3056ede2424d 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
@@ -968,33 +968,6 @@ _GLOBAL(_get_SP) | |||
968 | blr | 968 | blr |
969 | 969 | ||
970 | /* | 970 | /* |
971 | * These are used in the alignment trap handler when emulating | ||
972 | * single-precision loads and stores. | ||
973 | * We restore and save the fpscr so the task gets the same result | ||
974 | * and exceptions as if the cpu had performed the load or store. | ||
975 | */ | ||
976 | |||
977 | #ifdef CONFIG_PPC_FPU | ||
978 | _GLOBAL(cvt_fd) | ||
979 | lfd 0,-4(r5) /* load up fpscr value */ | ||
980 | mtfsf 0xff,0 | ||
981 | lfs 0,0(r3) | ||
982 | stfd 0,0(r4) | ||
983 | mffs 0 /* save new fpscr value */ | ||
984 | stfd 0,-4(r5) | ||
985 | blr | ||
986 | |||
987 | _GLOBAL(cvt_df) | ||
988 | lfd 0,-4(r5) /* load up fpscr value */ | ||
989 | mtfsf 0xff,0 | ||
990 | lfd 0,0(r3) | ||
991 | stfs 0,0(r4) | ||
992 | mffs 0 /* save new fpscr value */ | ||
993 | stfd 0,-4(r5) | ||
994 | blr | ||
995 | #endif | ||
996 | |||
997 | /* | ||
998 | * Create a kernel thread | 971 | * Create a kernel thread |
999 | * kernel_thread(fn, arg, flags) | 972 | * kernel_thread(fn, arg, flags) |
1000 | */ | 973 | */ |
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 6d60c40598e7..78ea10197a0b 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c | |||
@@ -542,7 +542,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) | |||
542 | last_task_used_spe = NULL; | 542 | last_task_used_spe = NULL; |
543 | #endif | 543 | #endif |
544 | memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); | 544 | memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); |
545 | current->thread.fpscr = 0; | 545 | current->thread.fpscr.val = 0; |
546 | #ifdef CONFIG_ALTIVEC | 546 | #ifdef CONFIG_ALTIVEC |
547 | memset(current->thread.vr, 0, sizeof(current->thread.vr)); | 547 | memset(current->thread.vr, 0, sizeof(current->thread.vr)); |
548 | memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); | 548 | memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); |
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 5e4bf88a1ef5..f265b81e7008 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
@@ -659,7 +659,7 @@ void program_check_exception(struct pt_regs *regs) | |||
659 | giveup_fpu(current); | 659 | giveup_fpu(current); |
660 | preempt_enable(); | 660 | preempt_enable(); |
661 | 661 | ||
662 | fpscr = current->thread.fpscr; | 662 | fpscr = current->thread.fpscr.val; |
663 | fpscr &= fpscr << 22; /* mask summary bits with enables */ | 663 | fpscr &= fpscr << 22; /* mask summary bits with enables */ |
664 | if (fpscr & FPSCR_VX) | 664 | if (fpscr & FPSCR_VX) |
665 | code = FPE_FLTINV; | 665 | code = FPE_FLTINV; |
diff --git a/arch/ppc/math-emu/sfp-machine.h b/arch/ppc/math-emu/sfp-machine.h index 686e06d29186..4b17d83cfcdd 100644 --- a/arch/ppc/math-emu/sfp-machine.h +++ b/arch/ppc/math-emu/sfp-machine.h | |||
@@ -166,7 +166,7 @@ extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long); | |||
166 | #include <linux/kernel.h> | 166 | #include <linux/kernel.h> |
167 | #include <linux/sched.h> | 167 | #include <linux/sched.h> |
168 | 168 | ||
169 | #define __FPU_FPSCR (current->thread.fpscr) | 169 | #define __FPU_FPSCR (current->thread.fpscr.val) |
170 | 170 | ||
171 | /* We only actually write to the destination register | 171 | /* We only actually write to the destination register |
172 | * if exceptions signalled (if any) will not trap. | 172 | * if exceptions signalled (if any) will not trap. |
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 8cc73cc1b4c4..b889277ab7de 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig | |||
@@ -197,6 +197,9 @@ config BOOTX_TEXT | |||
197 | config POWER4 | 197 | config POWER4 |
198 | def_bool y | 198 | def_bool y |
199 | 199 | ||
200 | config PPC_FPU | ||
201 | def_bool y | ||
202 | |||
200 | config POWER4_ONLY | 203 | config POWER4_ONLY |
201 | bool "Optimize for POWER4" | 204 | bool "Optimize for POWER4" |
202 | default n | 205 | default n |
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 4d18bdb680f0..ba59225fd373 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile | |||
@@ -80,6 +80,7 @@ endif | |||
80 | CFLAGS += $(call cc-option,-funit-at-a-time) | 80 | CFLAGS += $(call cc-option,-funit-at-a-time) |
81 | 81 | ||
82 | head-y := arch/ppc64/kernel/head.o | 82 | head-y := arch/ppc64/kernel/head.o |
83 | head-y += arch/powerpc/kernel/fpu.o | ||
83 | 84 | ||
84 | libs-y += arch/ppc64/lib/ | 85 | libs-y += arch/ppc64/lib/ |
85 | core-y += arch/ppc64/kernel/ arch/powerpc/kernel/ | 86 | core-y += arch/ppc64/kernel/ arch/powerpc/kernel/ |
diff --git a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c index 330e7ef81427..256d5b592aa1 100644 --- a/arch/ppc64/kernel/align.c +++ b/arch/ppc64/kernel/align.c | |||
@@ -313,7 +313,7 @@ fix_alignment(struct pt_regs *regs) | |||
313 | /* Doing stfs, have to convert to single */ | 313 | /* Doing stfs, have to convert to single */ |
314 | preempt_disable(); | 314 | preempt_disable(); |
315 | enable_kernel_fp(); | 315 | enable_kernel_fp(); |
316 | cvt_df(¤t->thread.fpr[reg], (float *)&data.v[4], ¤t->thread.fpscr); | 316 | cvt_df(¤t->thread.fpr[reg], (float *)&data.v[4], ¤t->thread); |
317 | disable_kernel_fp(); | 317 | disable_kernel_fp(); |
318 | preempt_enable(); | 318 | preempt_enable(); |
319 | } | 319 | } |
@@ -349,7 +349,7 @@ fix_alignment(struct pt_regs *regs) | |||
349 | /* Doing lfs, have to convert to double */ | 349 | /* Doing lfs, have to convert to double */ |
350 | preempt_disable(); | 350 | preempt_disable(); |
351 | enable_kernel_fp(); | 351 | enable_kernel_fp(); |
352 | cvt_fd((float *)&data.v[4], ¤t->thread.fpr[reg], ¤t->thread.fpscr); | 352 | cvt_fd((float *)&data.v[4], ¤t->thread.fpr[reg], ¤t->thread); |
353 | disable_kernel_fp(); | 353 | disable_kernel_fp(); |
354 | preempt_enable(); | 354 | preempt_enable(); |
355 | } | 355 | } |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index f58af9c246cb..929f9f42cf7a 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -81,7 +81,7 @@ _stext: | |||
81 | _GLOBAL(__start) | 81 | _GLOBAL(__start) |
82 | /* NOP this out unconditionally */ | 82 | /* NOP this out unconditionally */ |
83 | BEGIN_FTR_SECTION | 83 | BEGIN_FTR_SECTION |
84 | b .__start_initialization_multiplatform | 84 | b .__start_initialization_multiplatform |
85 | END_FTR_SECTION(0, 1) | 85 | END_FTR_SECTION(0, 1) |
86 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 86 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
87 | 87 | ||
@@ -747,6 +747,7 @@ bad_stack: | |||
747 | * any task or sent any task a signal, you should use | 747 | * any task or sent any task a signal, you should use |
748 | * ret_from_except or ret_from_except_lite instead of this. | 748 | * ret_from_except or ret_from_except_lite instead of this. |
749 | */ | 749 | */ |
750 | .globl fast_exception_return | ||
750 | fast_exception_return: | 751 | fast_exception_return: |
751 | ld r12,_MSR(r1) | 752 | ld r12,_MSR(r1) |
752 | ld r11,_NIP(r1) | 753 | ld r11,_NIP(r1) |
@@ -858,62 +859,6 @@ fp_unavailable_common: | |||
858 | bl .kernel_fp_unavailable_exception | 859 | bl .kernel_fp_unavailable_exception |
859 | BUG_OPCODE | 860 | BUG_OPCODE |
860 | 861 | ||
861 | /* | ||
862 | * load_up_fpu(unused, unused, tsk) | ||
863 | * Disable FP for the task which had the FPU previously, | ||
864 | * and save its floating-point registers in its thread_struct. | ||
865 | * Enables the FPU for use in the kernel on return. | ||
866 | * On SMP we know the fpu is free, since we give it up every | ||
867 | * switch (ie, no lazy save of the FP registers). | ||
868 | * On entry: r13 == 'current' && last_task_used_math != 'current' | ||
869 | */ | ||
870 | _STATIC(load_up_fpu) | ||
871 | mfmsr r5 /* grab the current MSR */ | ||
872 | ori r5,r5,MSR_FP | ||
873 | mtmsrd r5 /* enable use of fpu now */ | ||
874 | isync | ||
875 | /* | ||
876 | * For SMP, we don't do lazy FPU switching because it just gets too | ||
877 | * horrendously complex, especially when a task switches from one CPU | ||
878 | * to another. Instead we call giveup_fpu in switch_to. | ||
879 | * | ||
880 | */ | ||
881 | #ifndef CONFIG_SMP | ||
882 | ld r3,last_task_used_math@got(r2) | ||
883 | ld r4,0(r3) | ||
884 | cmpdi 0,r4,0 | ||
885 | beq 1f | ||
886 | /* Save FP state to last_task_used_math's THREAD struct */ | ||
887 | addi r4,r4,THREAD | ||
888 | SAVE_32FPRS(0, r4) | ||
889 | mffs fr0 | ||
890 | stfd fr0,THREAD_FPSCR(r4) | ||
891 | /* Disable FP for last_task_used_math */ | ||
892 | ld r5,PT_REGS(r4) | ||
893 | ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
894 | li r6,MSR_FP|MSR_FE0|MSR_FE1 | ||
895 | andc r4,r4,r6 | ||
896 | std r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
897 | 1: | ||
898 | #endif /* CONFIG_SMP */ | ||
899 | /* enable use of FP after return */ | ||
900 | ld r4,PACACURRENT(r13) | ||
901 | addi r5,r4,THREAD /* Get THREAD */ | ||
902 | ld r4,THREAD_FPEXC_MODE(r5) | ||
903 | ori r12,r12,MSR_FP | ||
904 | or r12,r12,r4 | ||
905 | std r12,_MSR(r1) | ||
906 | lfd fr0,THREAD_FPSCR(r5) | ||
907 | mtfsf 0xff,fr0 | ||
908 | REST_32FPRS(0, r5) | ||
909 | #ifndef CONFIG_SMP | ||
910 | /* Update last_task_used_math to 'current' */ | ||
911 | subi r4,r5,THREAD /* Back to 'current' */ | ||
912 | std r4,0(r3) | ||
913 | #endif /* CONFIG_SMP */ | ||
914 | /* restore registers and return */ | ||
915 | b fast_exception_return | ||
916 | |||
917 | .align 7 | 862 | .align 7 |
918 | .globl altivec_unavailable_common | 863 | .globl altivec_unavailable_common |
919 | altivec_unavailable_common: | 864 | altivec_unavailable_common: |
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index a33448c2bd91..9cae3d5c40e6 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
@@ -451,25 +451,6 @@ _GLOBAL(_outsl_ns) | |||
451 | sync | 451 | sync |
452 | blr | 452 | blr |
453 | 453 | ||
454 | |||
455 | _GLOBAL(cvt_fd) | ||
456 | lfd 0,0(r5) /* load up fpscr value */ | ||
457 | mtfsf 0xff,0 | ||
458 | lfs 0,0(r3) | ||
459 | stfd 0,0(r4) | ||
460 | mffs 0 /* save new fpscr value */ | ||
461 | stfd 0,0(r5) | ||
462 | blr | ||
463 | |||
464 | _GLOBAL(cvt_df) | ||
465 | lfd 0,0(r5) /* load up fpscr value */ | ||
466 | mtfsf 0xff,0 | ||
467 | lfd 0,0(r3) | ||
468 | stfs 0,0(r4) | ||
469 | mffs 0 /* save new fpscr value */ | ||
470 | stfd 0,0(r5) | ||
471 | blr | ||
472 | |||
473 | /* | 454 | /* |
474 | * identify_cpu and calls setup_cpu | 455 | * identify_cpu and calls setup_cpu |
475 | * In: r3 = base of the cpu_specs array | 456 | * In: r3 = base of the cpu_specs array |
@@ -655,38 +636,6 @@ _GLOBAL(disable_kernel_fp) | |||
655 | isync | 636 | isync |
656 | blr | 637 | blr |
657 | 638 | ||
658 | /* | ||
659 | * giveup_fpu(tsk) | ||
660 | * Disable FP for the task given as the argument, | ||
661 | * and save the floating-point registers in its thread_struct. | ||
662 | * Enables the FPU for use in the kernel on return. | ||
663 | */ | ||
664 | _GLOBAL(giveup_fpu) | ||
665 | mfmsr r5 | ||
666 | ori r5,r5,MSR_FP | ||
667 | mtmsrd r5 /* enable use of fpu now */ | ||
668 | isync | ||
669 | cmpdi 0,r3,0 | ||
670 | beqlr- /* if no previous owner, done */ | ||
671 | addi r3,r3,THREAD /* want THREAD of task */ | ||
672 | ld r5,PT_REGS(r3) | ||
673 | cmpdi 0,r5,0 | ||
674 | SAVE_32FPRS(0, r3) | ||
675 | mffs fr0 | ||
676 | stfd fr0,THREAD_FPSCR(r3) | ||
677 | beq 1f | ||
678 | ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
679 | li r3,MSR_FP|MSR_FE0|MSR_FE1 | ||
680 | andc r4,r4,r3 /* disable FP for previous task */ | ||
681 | std r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
682 | 1: | ||
683 | #ifndef CONFIG_SMP | ||
684 | li r5,0 | ||
685 | ld r4,last_task_used_math@got(r2) | ||
686 | std r5,0(r4) | ||
687 | #endif /* CONFIG_SMP */ | ||
688 | blr | ||
689 | |||
690 | #ifdef CONFIG_ALTIVEC | 639 | #ifdef CONFIG_ALTIVEC |
691 | 640 | ||
692 | #if 0 /* this has no callers for now */ | 641 | #if 0 /* this has no callers for now */ |
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index 347112cca3c0..ec9d0984b6a0 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c | |||
@@ -133,7 +133,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
133 | flush_fp_to_thread(current); | 133 | flush_fp_to_thread(current); |
134 | 134 | ||
135 | /* Make sure signal doesn't get spurrious FP exceptions */ | 135 | /* Make sure signal doesn't get spurrious FP exceptions */ |
136 | current->thread.fpscr = 0; | 136 | current->thread.fpscr.val = 0; |
137 | 137 | ||
138 | #ifdef CONFIG_ALTIVEC | 138 | #ifdef CONFIG_ALTIVEC |
139 | err |= __put_user(v_regs, &sc->v_regs); | 139 | err |= __put_user(v_regs, &sc->v_regs); |
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h index 9592f533e058..eee954a001fd 100644 --- a/include/asm-powerpc/processor.h +++ b/include/asm-powerpc/processor.h | |||
@@ -162,10 +162,11 @@ struct thread_struct { | |||
162 | unsigned long dbcr1; | 162 | unsigned long dbcr1; |
163 | #endif | 163 | #endif |
164 | double fpr[32]; /* Complete floating point set */ | 164 | double fpr[32]; /* Complete floating point set */ |
165 | #ifdef CONFIG_PPC32 | 165 | struct { /* fpr ... fpscr must be contiguous */ |
166 | unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */ | 166 | |
167 | #endif | 167 | unsigned int pad; |
168 | unsigned long fpscr; /* Floating point status */ | 168 | unsigned int val; /* Floating point status */ |
169 | } fpscr; | ||
169 | int fpexc_mode; /* floating-point exception mode */ | 170 | int fpexc_mode; /* floating-point exception mode */ |
170 | #ifdef CONFIG_PPC64 | 171 | #ifdef CONFIG_PPC64 |
171 | unsigned long start_tb; /* Start purr when proc switched in */ | 172 | unsigned long start_tb; /* Start purr when proc switched in */ |
@@ -207,7 +208,7 @@ struct thread_struct { | |||
207 | .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ | 208 | .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ |
208 | .fs = KERNEL_DS, \ | 209 | .fs = KERNEL_DS, \ |
209 | .fpr = {0}, \ | 210 | .fpr = {0}, \ |
210 | .fpscr = 0, \ | 211 | .fpscr = { .val = 0, }, \ |
211 | .fpexc_mode = MSR_FE0|MSR_FE1, \ | 212 | .fpexc_mode = MSR_FE0|MSR_FE1, \ |
212 | } | 213 | } |
213 | #endif | 214 | #endif |
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h index d60c8c928922..e926e43c4ae6 100644 --- a/include/asm-powerpc/system.h +++ b/include/asm-powerpc/system.h | |||
@@ -132,8 +132,8 @@ extern int emulate_altivec(struct pt_regs *); | |||
132 | extern void giveup_spe(struct task_struct *); | 132 | extern void giveup_spe(struct task_struct *); |
133 | extern void load_up_spe(struct task_struct *); | 133 | extern void load_up_spe(struct task_struct *); |
134 | extern int fix_alignment(struct pt_regs *); | 134 | extern int fix_alignment(struct pt_regs *); |
135 | extern void cvt_fd(float *from, double *to, unsigned long *fpscr); | 135 | extern void cvt_fd(float *from, double *to, struct thread_struct *thread); |
136 | extern void cvt_df(double *from, float *to, unsigned long *fpscr); | 136 | extern void cvt_df(double *from, float *to, struct thread_struct *thread); |
137 | 137 | ||
138 | #ifdef CONFIG_ALTIVEC | 138 | #ifdef CONFIG_ALTIVEC |
139 | extern void flush_altivec_to_thread(struct task_struct *); | 139 | extern void flush_altivec_to_thread(struct task_struct *); |
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index 1f310783757e..eb30c09516ae 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h | |||
@@ -82,8 +82,8 @@ extern int emulate_altivec(struct pt_regs *); | |||
82 | extern void giveup_spe(struct task_struct *); | 82 | extern void giveup_spe(struct task_struct *); |
83 | extern void load_up_spe(struct task_struct *); | 83 | extern void load_up_spe(struct task_struct *); |
84 | extern int fix_alignment(struct pt_regs *); | 84 | extern int fix_alignment(struct pt_regs *); |
85 | extern void cvt_fd(float *from, double *to, unsigned long *fpscr); | 85 | extern void cvt_fd(float *from, double *to, struct thread_struct *thread); |
86 | extern void cvt_df(double *from, float *to, unsigned long *fpscr); | 86 | extern void cvt_df(double *from, float *to, struct thread_struct *thread); |
87 | 87 | ||
88 | #ifdef CONFIG_ALTIVEC | 88 | #ifdef CONFIG_ALTIVEC |
89 | extern void flush_altivec_to_thread(struct task_struct *); | 89 | extern void flush_altivec_to_thread(struct task_struct *); |
diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h index 2e17ef7dbeb4..fd7c1f890c45 100644 --- a/include/asm-ppc64/system.h +++ b/include/asm-ppc64/system.h | |||
@@ -120,8 +120,8 @@ extern void giveup_altivec(struct task_struct *); | |||
120 | extern void disable_kernel_altivec(void); | 120 | extern void disable_kernel_altivec(void); |
121 | extern void enable_kernel_altivec(void); | 121 | extern void enable_kernel_altivec(void); |
122 | extern int emulate_altivec(struct pt_regs *); | 122 | extern int emulate_altivec(struct pt_regs *); |
123 | extern void cvt_fd(float *from, double *to, unsigned long *fpscr); | 123 | extern void cvt_fd(float *from, double *to, struct thread_struct *thread); |
124 | extern void cvt_df(double *from, float *to, unsigned long *fpscr); | 124 | extern void cvt_df(double *from, float *to, struct thread_struct *thread); |
125 | 125 | ||
126 | #ifdef CONFIG_ALTIVEC | 126 | #ifdef CONFIG_ALTIVEC |
127 | extern void flush_altivec_to_thread(struct task_struct *); | 127 | extern void flush_altivec_to_thread(struct task_struct *); |