Commit aa42c69c authored by Kim Phillips's avatar Kim Phillips Committed by Kumar Gala

[POWERPC] Add support for FP emulation for the e300c2 core

The e300c2 has no FPU.  Its MSR[FP] is grounded to zero.  If an attempt
is made to execute a floating point instruction (including floating-point
load, store, or move instructions), the e300c2 takes a floating-point
unavailable interrupt.

This patch adds support for FP emulation on the e300c2 by declaring a
new CPU_FTR_FP_TAKES_FPUNAVAIL, where FP unavail interrupts are
intercepted and redirected to the ProgramCheck exception path for
correct emulation handling.

(If we run out of CPU_FTR bits we could look to reclaim this bit by adding
support to test the cpu_user_features for PPC_FEATURE_HAS_FPU instead)

It adds a nop to the exception path for 32-bit processors with a FPU.
Signed-off-by: default avatarKim Phillips <kim.phillips@freescale.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent c9976797
...@@ -706,7 +706,7 @@ config FORCE_MAX_ZONEORDER ...@@ -706,7 +706,7 @@ config FORCE_MAX_ZONEORDER
config MATH_EMULATION config MATH_EMULATION
bool "Math emulation" bool "Math emulation"
depends on 4xx || 8xx || E200 || E500 depends on 4xx || 8xx || E200 || PPC_83xx || E500
---help--- ---help---
Some PowerPC chips designed for embedded applications do not have Some PowerPC chips designed for embedded applications do not have
a floating-point unit and therefore do not implement the a floating-point unit and therefore do not implement the
......
...@@ -833,7 +833,7 @@ static struct cpu_spec cpu_specs[] = { ...@@ -833,7 +833,7 @@ static struct cpu_spec cpu_specs[] = {
.pvr_mask = 0x7fff0000, .pvr_mask = 0x7fff0000,
.pvr_value = 0x00840000, .pvr_value = 0x00840000,
.cpu_name = "e300c2", .cpu_name = "e300c2",
.cpu_features = CPU_FTRS_E300, .cpu_features = CPU_FTRS_E300C2,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
......
...@@ -437,6 +437,13 @@ Alignment: ...@@ -437,6 +437,13 @@ Alignment:
/* Floating-point unavailable */ /* Floating-point unavailable */
. = 0x800 . = 0x800
FPUnavailable: FPUnavailable:
BEGIN_FTR_SECTION
/*
* Certain Freescale cores don't have a FPU and treat fp instructions
* as a FP Unavailable exception. Redirect to illegal/emulation handling.
*/
b ProgramCheck
END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE)
EXCEPTION_PROLOG EXCEPTION_PROLOG
bne load_up_fpu /* if from user, just load it up */ bne load_up_fpu /* if from user, just load it up */
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
......
...@@ -782,6 +782,8 @@ void __kprobes program_check_exception(struct pt_regs *regs) ...@@ -782,6 +782,8 @@ void __kprobes program_check_exception(struct pt_regs *regs)
unsigned int reason = get_reason(regs); unsigned int reason = get_reason(regs);
extern int do_mathemu(struct pt_regs *regs); extern int do_mathemu(struct pt_regs *regs);
/* We can now get here via a FP Unavailable exception if the core
* has no FPU, in that case no reason flags will be set */
#ifdef CONFIG_MATH_EMULATION #ifdef CONFIG_MATH_EMULATION
/* (reason & REASON_ILLEGAL) would be the obvious thing here, /* (reason & REASON_ILLEGAL) would be the obvious thing here,
* but there seems to be a hardware bug on the 405GP (RevD) * but there seems to be a hardware bug on the 405GP (RevD)
......
...@@ -126,6 +126,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start, ...@@ -126,6 +126,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000) #define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000)
#define CPU_FTR_PPC_LE ASM_CONST(0x0000000000200000) #define CPU_FTR_PPC_LE ASM_CONST(0x0000000000200000)
#define CPU_FTR_REAL_LE ASM_CONST(0x0000000000400000) #define CPU_FTR_REAL_LE ASM_CONST(0x0000000000400000)
#define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x0000000000800000)
/* /*
* Add the 64-bit processor unique features in the top half of the word; * Add the 64-bit processor unique features in the top half of the word;
...@@ -295,6 +296,9 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start, ...@@ -295,6 +296,9 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
#define CPU_FTRS_E300 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \ #define CPU_FTRS_E300 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | \ CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_COMMON) CPU_FTR_COMMON)
#define CPU_FTRS_E300C2 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_COMMON | CPU_FTR_FPU_UNAVAILABLE)
#define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ #define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE) CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE)
#define CPU_FTRS_8XX (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB) #define CPU_FTRS_8XX (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB)
...@@ -364,7 +368,8 @@ enum { ...@@ -364,7 +368,8 @@ enum {
CPU_FTRS_7450_21 | CPU_FTRS_7450_23 | CPU_FTRS_7455_1 | CPU_FTRS_7450_21 | CPU_FTRS_7450_23 | CPU_FTRS_7455_1 |
CPU_FTRS_7455_20 | CPU_FTRS_7455 | CPU_FTRS_7447_10 | CPU_FTRS_7455_20 | CPU_FTRS_7455 | CPU_FTRS_7447_10 |
CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_82XX | CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_82XX |
CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_CLASSIC32 | CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_E300C2 |
CPU_FTRS_CLASSIC32 |
#else #else
CPU_FTRS_GENERIC_32 | CPU_FTRS_GENERIC_32 |
#endif #endif
...@@ -403,7 +408,8 @@ enum { ...@@ -403,7 +408,8 @@ enum {
CPU_FTRS_7450_21 & CPU_FTRS_7450_23 & CPU_FTRS_7455_1 & CPU_FTRS_7450_21 & CPU_FTRS_7450_23 & CPU_FTRS_7455_1 &
CPU_FTRS_7455_20 & CPU_FTRS_7455 & CPU_FTRS_7447_10 & CPU_FTRS_7455_20 & CPU_FTRS_7455 & CPU_FTRS_7447_10 &
CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_82XX & CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_82XX &
CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_CLASSIC32 & CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_E300C2 &
CPU_FTRS_CLASSIC32 &
#else #else
CPU_FTRS_GENERIC_32 & CPU_FTRS_GENERIC_32 &
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment