aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc/kernel')
-rw-r--r--arch/ppc/kernel/Makefile1
-rw-r--r--arch/ppc/kernel/align.c12
-rw-r--r--arch/ppc/kernel/cpu_setup_6xx.S42
-rw-r--r--arch/ppc/kernel/entry.S59
-rw-r--r--arch/ppc/kernel/fpu.S133
-rw-r--r--arch/ppc/kernel/head.S163
-rw-r--r--arch/ppc/kernel/head_44x.S6
-rw-r--r--arch/ppc/kernel/head_booke.h7
-rw-r--r--arch/ppc/kernel/head_fsl_booke.S8
-rw-r--r--arch/ppc/kernel/misc.S12
-rw-r--r--arch/ppc/kernel/ptrace.c5
-rw-r--r--arch/ppc/kernel/traps.c2
12 files changed, 266 insertions, 184 deletions
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 86bc878cb3ee..b284451802c9 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -9,6 +9,7 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
9extra-$(CONFIG_8xx) := head_8xx.o 9extra-$(CONFIG_8xx) := head_8xx.o
10extra-$(CONFIG_6xx) += idle_6xx.o 10extra-$(CONFIG_6xx) += idle_6xx.o
11extra-$(CONFIG_POWER4) += idle_power4.o 11extra-$(CONFIG_POWER4) += idle_power4.o
12extra-$(CONFIG_PPC_FPU) += fpu.o
12extra-y += vmlinux.lds 13extra-y += vmlinux.lds
13 14
14obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ 15obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c
index 79c929475037..ff81da9598d8 100644
--- a/arch/ppc/kernel/align.c
+++ b/arch/ppc/kernel/align.c
@@ -290,6 +290,10 @@ fix_alignment(struct pt_regs *regs)
290 /* lwm, stmw */ 290 /* lwm, stmw */
291 nb = (32 - reg) * 4; 291 nb = (32 - reg) * 4;
292 } 292 }
293
294 if (!access_ok((flags & ST? VERIFY_WRITE: VERIFY_READ), addr, nb+nb0))
295 return -EFAULT; /* bad address */
296
293 rptr = (unsigned char *) &regs->gpr[reg]; 297 rptr = (unsigned char *) &regs->gpr[reg];
294 if (flags & LD) { 298 if (flags & LD) {
295 for (i = 0; i < nb; ++i) 299 for (i = 0; i < nb; ++i)
@@ -368,16 +372,24 @@ fix_alignment(struct pt_regs *regs)
368 372
369 /* Single-precision FP load and store require conversions... */ 373 /* Single-precision FP load and store require conversions... */
370 case LD+F+S: 374 case LD+F+S:
375#ifdef CONFIG_PPC_FPU
371 preempt_disable(); 376 preempt_disable();
372 enable_kernel_fp(); 377 enable_kernel_fp();
373 cvt_fd(&data.f, &data.d, &current->thread.fpscr); 378 cvt_fd(&data.f, &data.d, &current->thread.fpscr);
374 preempt_enable(); 379 preempt_enable();
380#else
381 return 0;
382#endif
375 break; 383 break;
376 case ST+F+S: 384 case ST+F+S:
385#ifdef CONFIG_PPC_FPU
377 preempt_disable(); 386 preempt_disable();
378 enable_kernel_fp(); 387 enable_kernel_fp();
379 cvt_df(&data.d, &data.f, &current->thread.fpscr); 388 cvt_df(&data.d, &data.f, &current->thread.fpscr);
380 preempt_enable(); 389 preempt_enable();
390#else
391 return 0;
392#endif
381 break; 393 break;
382 } 394 }
383 395
diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S
index 74f781b486a3..468721d9ebd2 100644
--- a/arch/ppc/kernel/cpu_setup_6xx.S
+++ b/arch/ppc/kernel/cpu_setup_6xx.S
@@ -30,12 +30,14 @@ _GLOBAL(__setup_cpu_604)
30 blr 30 blr
31_GLOBAL(__setup_cpu_750) 31_GLOBAL(__setup_cpu_750)
32 mflr r4 32 mflr r4
33 bl __init_fpu_registers
33 bl setup_common_caches 34 bl setup_common_caches
34 bl setup_750_7400_hid0 35 bl setup_750_7400_hid0
35 mtlr r4 36 mtlr r4
36 blr 37 blr
37_GLOBAL(__setup_cpu_750cx) 38_GLOBAL(__setup_cpu_750cx)
38 mflr r4 39 mflr r4
40 bl __init_fpu_registers
39 bl setup_common_caches 41 bl setup_common_caches
40 bl setup_750_7400_hid0 42 bl setup_750_7400_hid0
41 bl setup_750cx 43 bl setup_750cx
@@ -43,6 +45,7 @@ _GLOBAL(__setup_cpu_750cx)
43 blr 45 blr
44_GLOBAL(__setup_cpu_750fx) 46_GLOBAL(__setup_cpu_750fx)
45 mflr r4 47 mflr r4
48 bl __init_fpu_registers
46 bl setup_common_caches 49 bl setup_common_caches
47 bl setup_750_7400_hid0 50 bl setup_750_7400_hid0
48 bl setup_750fx 51 bl setup_750fx
@@ -50,6 +53,7 @@ _GLOBAL(__setup_cpu_750fx)
50 blr 53 blr
51_GLOBAL(__setup_cpu_7400) 54_GLOBAL(__setup_cpu_7400)
52 mflr r4 55 mflr r4
56 bl __init_fpu_registers
53 bl setup_7400_workarounds 57 bl setup_7400_workarounds
54 bl setup_common_caches 58 bl setup_common_caches
55 bl setup_750_7400_hid0 59 bl setup_750_7400_hid0
@@ -57,6 +61,7 @@ _GLOBAL(__setup_cpu_7400)
57 blr 61 blr
58_GLOBAL(__setup_cpu_7410) 62_GLOBAL(__setup_cpu_7410)
59 mflr r4 63 mflr r4
64 bl __init_fpu_registers
60 bl setup_7410_workarounds 65 bl setup_7410_workarounds
61 bl setup_common_caches 66 bl setup_common_caches
62 bl setup_750_7400_hid0 67 bl setup_750_7400_hid0
@@ -80,7 +85,7 @@ setup_common_caches:
80 bne 1f /* don't invalidate the D-cache */ 85 bne 1f /* don't invalidate the D-cache */
81 ori r8,r8,HID0_DCI /* unless it wasn't enabled */ 86 ori r8,r8,HID0_DCI /* unless it wasn't enabled */
821: sync 871: sync
83 mtspr SPRN_HID0,r8 /* enable and invalidate caches */ 88 mtspr SPRN_HID0,r8 /* enable and invalidate caches */
84 sync 89 sync
85 mtspr SPRN_HID0,r11 /* enable caches */ 90 mtspr SPRN_HID0,r11 /* enable caches */
86 sync 91 sync
@@ -152,9 +157,13 @@ setup_7410_workarounds:
152setup_750_7400_hid0: 157setup_750_7400_hid0:
153 mfspr r11,SPRN_HID0 158 mfspr r11,SPRN_HID0
154 ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC 159 ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
160 oris r11,r11,HID0_DPM@h
155BEGIN_FTR_SECTION 161BEGIN_FTR_SECTION
156 oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ 162 xori r11,r11,HID0_BTIC
157END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) 163END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
164BEGIN_FTR_SECTION
165 xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
166END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
158 li r3,HID0_SPD 167 li r3,HID0_SPD
159 andc r11,r11,r3 /* clear SPD: enable speculative */ 168 andc r11,r11,r3 /* clear SPD: enable speculative */
160 li r3,0 169 li r3,0
@@ -218,13 +227,15 @@ setup_745x_specifics:
218 227
219 /* All of the bits we have to set..... 228 /* All of the bits we have to set.....
220 */ 229 */
221 ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_LRSTK | HID0_BTIC 230 ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE
231 ori r11,r11,HID0_LRSTK | HID0_BTIC
232 oris r11,r11,HID0_DPM@h
222BEGIN_FTR_SECTION 233BEGIN_FTR_SECTION
223 xori r11,r11,HID0_BTIC 234 xori r11,r11,HID0_BTIC
224END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) 235END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
225BEGIN_FTR_SECTION 236BEGIN_FTR_SECTION
226 oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ 237 xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
227END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) 238END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
228 239
229 /* All of the bits we have to clear.... 240 /* All of the bits we have to clear....
230 */ 241 */
@@ -248,6 +259,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
248 isync 259 isync
249 blr 260 blr
250 261
262/*
263 * Initialize the FPU registers. This is needed to work around an errata
264 * in some 750 cpus where using a not yet initialized FPU register after
265 * power on reset may hang the CPU
266 */
267_GLOBAL(__init_fpu_registers)
268 mfmsr r10
269 ori r11,r10,MSR_FP
270 mtmsr r11
271 isync
272 addis r9,r3,empty_zero_page@ha
273 addi r9,r9,empty_zero_page@l
274 REST_32FPRS(0,r9)
275 sync
276 mtmsr r10
277 isync
278 blr
279
280
251/* Definitions for the table use to save CPU states */ 281/* Definitions for the table use to save CPU states */
252#define CS_HID0 0 282#define CS_HID0 0
253#define CS_HID1 4 283#define CS_HID1 4
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 035217d6c0f1..5f075dbc4ee7 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -563,6 +563,65 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
563 addi r1,r1,INT_FRAME_SIZE 563 addi r1,r1,INT_FRAME_SIZE
564 blr 564 blr
565 565
566 .globl fast_exception_return
567fast_exception_return:
568#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
569 andi. r10,r9,MSR_RI /* check for recoverable interrupt */
570 beq 1f /* if not, we've got problems */
571#endif
572
5732: REST_4GPRS(3, r11)
574 lwz r10,_CCR(r11)
575 REST_GPR(1, r11)
576 mtcr r10
577 lwz r10,_LINK(r11)
578 mtlr r10
579 REST_GPR(10, r11)
580 mtspr SPRN_SRR1,r9
581 mtspr SPRN_SRR0,r12
582 REST_GPR(9, r11)
583 REST_GPR(12, r11)
584 lwz r11,GPR11(r11)
585 SYNC
586 RFI
587
588#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
589/* check if the exception happened in a restartable section */
5901: lis r3,exc_exit_restart_end@ha
591 addi r3,r3,exc_exit_restart_end@l
592 cmplw r12,r3
593 bge 3f
594 lis r4,exc_exit_restart@ha
595 addi r4,r4,exc_exit_restart@l
596 cmplw r12,r4
597 blt 3f
598 lis r3,fee_restarts@ha
599 tophys(r3,r3)
600 lwz r5,fee_restarts@l(r3)
601 addi r5,r5,1
602 stw r5,fee_restarts@l(r3)
603 mr r12,r4 /* restart at exc_exit_restart */
604 b 2b
605
606 .comm fee_restarts,4
607
608/* aargh, a nonrecoverable interrupt, panic */
609/* aargh, we don't know which trap this is */
610/* but the 601 doesn't implement the RI bit, so assume it's OK */
6113:
612BEGIN_FTR_SECTION
613 b 2b
614END_FTR_SECTION_IFSET(CPU_FTR_601)
615 li r10,-1
616 stw r10,TRAP(r11)
617 addi r3,r1,STACK_FRAME_OVERHEAD
618 lis r10,MSR_KERNEL@h
619 ori r10,r10,MSR_KERNEL@l
620 bl transfer_to_handler_full
621 .long nonrecoverable_exception
622 .long ret_from_except
623#endif
624
566 .globl sigreturn_exit 625 .globl sigreturn_exit
567sigreturn_exit: 626sigreturn_exit:
568 subi r1,r3,STACK_FRAME_OVERHEAD 627 subi r1,r3,STACK_FRAME_OVERHEAD
diff --git a/arch/ppc/kernel/fpu.S b/arch/ppc/kernel/fpu.S
new file mode 100644
index 000000000000..6189b26f640f
--- /dev/null
+++ b/arch/ppc/kernel/fpu.S
@@ -0,0 +1,133 @@
1/*
2 * FPU support code, moved here from head.S so that it can be used
3 * by chips which use other head-whatever.S files.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 */
11
12#include <linux/config.h>
13#include <asm/processor.h>
14#include <asm/page.h>
15#include <asm/mmu.h>
16#include <asm/pgtable.h>
17#include <asm/cputable.h>
18#include <asm/cache.h>
19#include <asm/thread_info.h>
20#include <asm/ppc_asm.h>
21#include <asm/offsets.h>
22
23/*
24 * This task wants to use the FPU now.
25 * On UP, disable FP for the task which had the FPU previously,
26 * and save its floating-point registers in its thread_struct.
27 * Load up this task's FP registers from its thread_struct,
28 * enable the FPU for the current task and return to the task.
29 */
30 .globl load_up_fpu
31load_up_fpu:
32 mfmsr r5
33 ori r5,r5,MSR_FP
34#ifdef CONFIG_PPC64BRIDGE
35 clrldi r5,r5,1 /* turn off 64-bit mode */
36#endif /* CONFIG_PPC64BRIDGE */
37 SYNC
38 MTMSRD(r5) /* enable use of fpu now */
39 isync
40/*
41 * For SMP, we don't do lazy FPU switching because it just gets too
42 * horrendously complex, especially when a task switches from one CPU
43 * to another. Instead we call giveup_fpu in switch_to.
44 */
45#ifndef CONFIG_SMP
46 tophys(r6,0) /* get __pa constant */
47 addis r3,r6,last_task_used_math@ha
48 lwz r4,last_task_used_math@l(r3)
49 cmpwi 0,r4,0
50 beq 1f
51 add r4,r4,r6
52 addi r4,r4,THREAD /* want last_task_used_math->thread */
53 SAVE_32FPRS(0, r4)
54 mffs fr0
55 stfd fr0,THREAD_FPSCR-4(r4)
56 lwz r5,PT_REGS(r4)
57 add r5,r5,r6
58 lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
59 li r10,MSR_FP|MSR_FE0|MSR_FE1
60 andc r4,r4,r10 /* disable FP for previous task */
61 stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
621:
63#endif /* CONFIG_SMP */
64 /* enable use of FP after return */
65 mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
66 lwz r4,THREAD_FPEXC_MODE(r5)
67 ori r9,r9,MSR_FP /* enable FP for current */
68 or r9,r9,r4
69 lfd fr0,THREAD_FPSCR-4(r5)
70 mtfsf 0xff,fr0
71 REST_32FPRS(0, r5)
72#ifndef CONFIG_SMP
73 subi r4,r5,THREAD
74 sub r4,r4,r6
75 stw r4,last_task_used_math@l(r3)
76#endif /* CONFIG_SMP */
77 /* restore registers and return */
78 /* we haven't used ctr or xer or lr */
79 b fast_exception_return
80
81/*
82 * FP unavailable trap from kernel - print a message, but let
83 * the task use FP in the kernel until it returns to user mode.
84 */
85 .globl KernelFP
86KernelFP:
87 lwz r3,_MSR(r1)
88 ori r3,r3,MSR_FP
89 stw r3,_MSR(r1) /* enable use of FP after return */
90 lis r3,86f@h
91 ori r3,r3,86f@l
92 mr r4,r2 /* current */
93 lwz r5,_NIP(r1)
94 bl printk
95 b ret_from_except
9686: .string "floating point used in kernel (task=%p, pc=%x)\n"
97 .align 4,0
98
99/*
100 * giveup_fpu(tsk)
101 * Disable FP for the task given as the argument,
102 * and save the floating-point registers in its thread_struct.
103 * Enables the FPU for use in the kernel on return.
104 */
105 .globl giveup_fpu
106giveup_fpu:
107 mfmsr r5
108 ori r5,r5,MSR_FP
109 SYNC_601
110 ISYNC_601
111 MTMSRD(r5) /* enable use of fpu now */
112 SYNC_601
113 isync
114 cmpwi 0,r3,0
115 beqlr- /* if no previous owner, done */
116 addi r3,r3,THREAD /* want THREAD of task */
117 lwz r5,PT_REGS(r3)
118 cmpwi 0,r5,0
119 SAVE_32FPRS(0, r3)
120 mffs fr0
121 stfd fr0,THREAD_FPSCR-4(r3)
122 beq 1f
123 lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
124 li r3,MSR_FP|MSR_FE0|MSR_FE1
125 andc r4,r4,r3 /* disable FP for previous task */
126 stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1271:
128#ifndef CONFIG_SMP
129 li r5,0
130 lis r4,last_task_used_math@ha
131 stw r5,last_task_used_math@l(r4)
132#endif /* CONFIG_SMP */
133 blr
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 1a89a71e0acc..a931d773715f 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -775,133 +775,6 @@ InstructionSegment:
775 EXC_XFER_STD(0x480, UnknownException) 775 EXC_XFER_STD(0x480, UnknownException)
776#endif /* CONFIG_PPC64BRIDGE */ 776#endif /* CONFIG_PPC64BRIDGE */
777 777
778/*
779 * This task wants to use the FPU now.
780 * On UP, disable FP for the task which had the FPU previously,
781 * and save its floating-point registers in its thread_struct.
782 * Load up this task's FP registers from its thread_struct,
783 * enable the FPU for the current task and return to the task.
784 */
785load_up_fpu:
786 mfmsr r5
787 ori r5,r5,MSR_FP
788#ifdef CONFIG_PPC64BRIDGE
789 clrldi r5,r5,1 /* turn off 64-bit mode */
790#endif /* CONFIG_PPC64BRIDGE */
791 SYNC
792 MTMSRD(r5) /* enable use of fpu now */
793 isync
794/*
795 * For SMP, we don't do lazy FPU switching because it just gets too
796 * horrendously complex, especially when a task switches from one CPU
797 * to another. Instead we call giveup_fpu in switch_to.
798 */
799#ifndef CONFIG_SMP
800 tophys(r6,0) /* get __pa constant */
801 addis r3,r6,last_task_used_math@ha
802 lwz r4,last_task_used_math@l(r3)
803 cmpwi 0,r4,0
804 beq 1f
805 add r4,r4,r6
806 addi r4,r4,THREAD /* want last_task_used_math->thread */
807 SAVE_32FPRS(0, r4)
808 mffs fr0
809 stfd fr0,THREAD_FPSCR-4(r4)
810 lwz r5,PT_REGS(r4)
811 add r5,r5,r6
812 lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
813 li r10,MSR_FP|MSR_FE0|MSR_FE1
814 andc r4,r4,r10 /* disable FP for previous task */
815 stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
8161:
817#endif /* CONFIG_SMP */
818 /* enable use of FP after return */
819 mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
820 lwz r4,THREAD_FPEXC_MODE(r5)
821 ori r9,r9,MSR_FP /* enable FP for current */
822 or r9,r9,r4
823 lfd fr0,THREAD_FPSCR-4(r5)
824 mtfsf 0xff,fr0
825 REST_32FPRS(0, r5)
826#ifndef CONFIG_SMP
827 subi r4,r5,THREAD
828 sub r4,r4,r6
829 stw r4,last_task_used_math@l(r3)
830#endif /* CONFIG_SMP */
831 /* restore registers and return */
832 /* we haven't used ctr or xer or lr */
833 /* fall through to fast_exception_return */
834
835 .globl fast_exception_return
836fast_exception_return:
837 andi. r10,r9,MSR_RI /* check for recoverable interrupt */
838 beq 1f /* if not, we've got problems */
8392: REST_4GPRS(3, r11)
840 lwz r10,_CCR(r11)
841 REST_GPR(1, r11)
842 mtcr r10
843 lwz r10,_LINK(r11)
844 mtlr r10
845 REST_GPR(10, r11)
846 mtspr SPRN_SRR1,r9
847 mtspr SPRN_SRR0,r12
848 REST_GPR(9, r11)
849 REST_GPR(12, r11)
850 lwz r11,GPR11(r11)
851 SYNC
852 RFI
853
854/* check if the exception happened in a restartable section */
8551: lis r3,exc_exit_restart_end@ha
856 addi r3,r3,exc_exit_restart_end@l
857 cmplw r12,r3
858 bge 3f
859 lis r4,exc_exit_restart@ha
860 addi r4,r4,exc_exit_restart@l
861 cmplw r12,r4
862 blt 3f
863 lis r3,fee_restarts@ha
864 tophys(r3,r3)
865 lwz r5,fee_restarts@l(r3)
866 addi r5,r5,1
867 stw r5,fee_restarts@l(r3)
868 mr r12,r4 /* restart at exc_exit_restart */
869 b 2b
870
871 .comm fee_restarts,4
872
873/* aargh, a nonrecoverable interrupt, panic */
874/* aargh, we don't know which trap this is */
875/* but the 601 doesn't implement the RI bit, so assume it's OK */
8763:
877BEGIN_FTR_SECTION
878 b 2b
879END_FTR_SECTION_IFSET(CPU_FTR_601)
880 li r10,-1
881 stw r10,TRAP(r11)
882 addi r3,r1,STACK_FRAME_OVERHEAD
883 li r10,MSR_KERNEL
884 bl transfer_to_handler_full
885 .long nonrecoverable_exception
886 .long ret_from_except
887
888/*
889 * FP unavailable trap from kernel - print a message, but let
890 * the task use FP in the kernel until it returns to user mode.
891 */
892KernelFP:
893 lwz r3,_MSR(r1)
894 ori r3,r3,MSR_FP
895 stw r3,_MSR(r1) /* enable use of FP after return */
896 lis r3,86f@h
897 ori r3,r3,86f@l
898 mr r4,r2 /* current */
899 lwz r5,_NIP(r1)
900 bl printk
901 b ret_from_except
90286: .string "floating point used in kernel (task=%p, pc=%x)\n"
903 .align 4,0
904
905#ifdef CONFIG_ALTIVEC 778#ifdef CONFIG_ALTIVEC
906/* Note that the AltiVec support is closely modeled after the FP 779/* Note that the AltiVec support is closely modeled after the FP
907 * support. Changes to one are likely to be applicable to the 780 * support. Changes to one are likely to be applicable to the
@@ -1016,42 +889,6 @@ giveup_altivec:
1016#endif /* CONFIG_ALTIVEC */ 889#endif /* CONFIG_ALTIVEC */
1017 890
1018/* 891/*
1019 * giveup_fpu(tsk)
1020 * Disable FP for the task given as the argument,
1021 * and save the floating-point registers in its thread_struct.
1022 * Enables the FPU for use in the kernel on return.
1023 */
1024 .globl giveup_fpu
1025giveup_fpu:
1026 mfmsr r5
1027 ori r5,r5,MSR_FP
1028 SYNC_601
1029 ISYNC_601
1030 MTMSRD(r5) /* enable use of fpu now */
1031 SYNC_601
1032 isync
1033 cmpwi 0,r3,0
1034 beqlr- /* if no previous owner, done */
1035 addi r3,r3,THREAD /* want THREAD of task */
1036 lwz r5,PT_REGS(r3)
1037 cmpwi 0,r5,0
1038 SAVE_32FPRS(0, r3)
1039 mffs fr0
1040 stfd fr0,THREAD_FPSCR-4(r3)
1041 beq 1f
1042 lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1043 li r3,MSR_FP|MSR_FE0|MSR_FE1
1044 andc r4,r4,r3 /* disable FP for previous task */
1045 stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
10461:
1047#ifndef CONFIG_SMP
1048 li r5,0
1049 lis r4,last_task_used_math@ha
1050 stw r5,last_task_used_math@l(r4)
1051#endif /* CONFIG_SMP */
1052 blr
1053
1054/*
1055 * This code is jumped to from the startup code to copy 892 * This code is jumped to from the startup code to copy
1056 * the kernel image to physical address 0. 893 * the kernel image to physical address 0.
1057 */ 894 */
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 9ed8165a3d6c..9b6a8e513657 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -426,7 +426,11 @@ interrupt_base:
426 PROGRAM_EXCEPTION 426 PROGRAM_EXCEPTION
427 427
428 /* Floating Point Unavailable Interrupt */ 428 /* Floating Point Unavailable Interrupt */
429#ifdef CONFIG_PPC_FPU
430 FP_UNAVAILABLE_EXCEPTION
431#else
429 EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) 432 EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
433#endif
430 434
431 /* System Call Interrupt */ 435 /* System Call Interrupt */
432 START_EXCEPTION(SystemCall) 436 START_EXCEPTION(SystemCall)
@@ -686,8 +690,10 @@ _GLOBAL(giveup_altivec)
686 * 690 *
687 * The 44x core does not have an FPU. 691 * The 44x core does not have an FPU.
688 */ 692 */
693#ifndef CONFIG_PPC_FPU
689_GLOBAL(giveup_fpu) 694_GLOBAL(giveup_fpu)
690 blr 695 blr
696#endif
691 697
692/* 698/*
693 * extern void abort(void) 699 * extern void abort(void)
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
index 884dac916bce..f213d12eec08 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -337,4 +337,11 @@ label:
337 addi r3,r1,STACK_FRAME_OVERHEAD; \ 337 addi r3,r1,STACK_FRAME_OVERHEAD; \
338 EXC_XFER_LITE(0x0900, timer_interrupt) 338 EXC_XFER_LITE(0x0900, timer_interrupt)
339 339
340#define FP_UNAVAILABLE_EXCEPTION \
341 START_EXCEPTION(FloatingPointUnavailable) \
342 NORMAL_EXCEPTION_PROLOG; \
343 bne load_up_fpu; /* if from user, just load it up */ \
344 addi r3,r1,STACK_FRAME_OVERHEAD; \
345 EXC_XFER_EE_LITE(0x800, KernelFP)
346
340#endif /* __HEAD_BOOKE_H__ */ 347#endif /* __HEAD_BOOKE_H__ */
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index d64bf61d2b1f..f22ddce36135 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -504,7 +504,11 @@ interrupt_base:
504 PROGRAM_EXCEPTION 504 PROGRAM_EXCEPTION
505 505
506 /* Floating Point Unavailable Interrupt */ 506 /* Floating Point Unavailable Interrupt */
507#ifdef CONFIG_PPC_FPU
508 FP_UNAVAILABLE_EXCEPTION
509#else
507 EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) 510 EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
511#endif
508 512
509 /* System Call Interrupt */ 513 /* System Call Interrupt */
510 START_EXCEPTION(SystemCall) 514 START_EXCEPTION(SystemCall)
@@ -916,10 +920,12 @@ _GLOBAL(giveup_spe)
916/* 920/*
917 * extern void giveup_fpu(struct task_struct *prev) 921 * extern void giveup_fpu(struct task_struct *prev)
918 * 922 *
919 * The e500 core does not have an FPU. 923 * Not all FSL Book-E cores have an FPU
920 */ 924 */
925#ifndef CONFIG_PPC_FPU
921_GLOBAL(giveup_fpu) 926_GLOBAL(giveup_fpu)
922 blr 927 blr
928#endif
923 929
924/* 930/*
925 * extern void abort(void) 931 * extern void abort(void)
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 73f7c23b0dd4..e4f1615ec13f 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -1096,17 +1096,7 @@ _GLOBAL(_get_SP)
1096 * and exceptions as if the cpu had performed the load or store. 1096 * and exceptions as if the cpu had performed the load or store.
1097 */ 1097 */
1098 1098
1099#if defined(CONFIG_4xx) || defined(CONFIG_E500) 1099#ifdef CONFIG_PPC_FPU
1100_GLOBAL(cvt_fd)
1101 lfs 0,0(r3)
1102 stfd 0,0(r4)
1103 blr
1104
1105_GLOBAL(cvt_df)
1106 lfd 0,0(r3)
1107 stfs 0,0(r4)
1108 blr
1109#else
1110_GLOBAL(cvt_fd) 1100_GLOBAL(cvt_fd)
1111 lfd 0,-4(r5) /* load up fpscr value */ 1101 lfd 0,-4(r5) /* load up fpscr value */
1112 mtfsf 0xff,0 1102 mtfsf 0xff,0
diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
index 426b6f7d9de3..59d59a8dc249 100644
--- a/arch/ppc/kernel/ptrace.c
+++ b/arch/ppc/kernel/ptrace.c
@@ -26,6 +26,7 @@
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <linux/user.h> 27#include <linux/user.h>
28#include <linux/security.h> 28#include <linux/security.h>
29#include <linux/signal.h>
29 30
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <asm/page.h> 32#include <asm/page.h>
@@ -356,7 +357,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
356 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 357 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
357 case PTRACE_CONT: { /* restart after signal. */ 358 case PTRACE_CONT: { /* restart after signal. */
358 ret = -EIO; 359 ret = -EIO;
359 if ((unsigned long) data > _NSIG) 360 if (!valid_signal(data))
360 break; 361 break;
361 if (request == PTRACE_SYSCALL) { 362 if (request == PTRACE_SYSCALL) {
362 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 363 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -389,7 +390,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
389 390
390 case PTRACE_SINGLESTEP: { /* set the trap flag. */ 391 case PTRACE_SINGLESTEP: { /* set the trap flag. */
391 ret = -EIO; 392 ret = -EIO;
392 if ((unsigned long) data > _NSIG) 393 if (!valid_signal(data))
393 break; 394 break;
394 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 395 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
395 set_single_step(child); 396 set_single_step(child);
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 361865c4bc84..f8e7e324a173 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -176,7 +176,7 @@ static inline int check_io_access(struct pt_regs *regs)
176#else 176#else
177#define get_mc_reason(regs) (mfspr(SPRN_MCSR)) 177#define get_mc_reason(regs) (mfspr(SPRN_MCSR))
178#endif 178#endif
179#define REASON_FP 0 179#define REASON_FP ESR_FP
180#define REASON_ILLEGAL ESR_PIL 180#define REASON_ILLEGAL ESR_PIL
181#define REASON_PRIVILEGED ESR_PPR 181#define REASON_PRIVILEGED ESR_PPR
182#define REASON_TRAP ESR_PTR 182#define REASON_TRAP ESR_PTR