powerpc: Fix 44x Machine Check handling
Subsystems (2)
PATCH 1/1 powerpc: Fix 44x Machine Check handling
This removes the old CONFIG_440A which was a pain for multiplatform kernel and wasn't set properly by default and replaces it with a CPU feature. This makes Machine Check reporting work correctly on my Ebony (440GP) board.
---
Note: I'm only setting it for 440GX and EPx as the old code did, I haven't checked whether other new 440 chips such as SPe also need that bit set.
arch/powerpc/kernel/cputable.c | 10 +++++----- arch/powerpc/kernel/head_44x.S | 11 ++++++----- arch/powerpc/kernel/traps.c | 19 ++++++++----------- arch/powerpc/platforms/44x/Kconfig | 5 ----- include/asm-powerpc/cputable.h | 3 ++- include/asm-powerpc/reg_booke.h | 2 +- 6 files changed, 22 insertions(+), 28 deletions(-)
arch/powerpc/kernel/cputable.c +5 -5
@@ -1158,7 +1158,7 @@ static struct cpu_spec __initdata cpu_sp .pvr_mask = 0xf0000ffb, .pvr_value = 0x200008D8, .cpu_name = "440EPX", - .cpu_features = CPU_FTRS_44X, + .cpu_features = CPU_FTRS_44X | CPU_FTR_440A, .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, .icache_bsize = 32, .dcache_bsize = 32,
@@ -1189,7 +1189,7 @@ static struct cpu_spec __initdata cpu_sp .pvr_mask = 0xf0000fff, .pvr_value = 0x50000850, .cpu_name = "440GX Rev. A", - .cpu_features = CPU_FTRS_44X, + .cpu_features = CPU_FTRS_44X | CPU_FTR_440A, .cpu_user_features = COMMON_USER_BOOKE, .icache_bsize = 32, .dcache_bsize = 32,
@@ -1199,7 +1199,7 @@ static struct cpu_spec __initdata cpu_sp .pvr_mask = 0xf0000fff, .pvr_value = 0x50000851, .cpu_name = "440GX Rev. B", - .cpu_features = CPU_FTRS_44X, + .cpu_features = CPU_FTRS_44X | CPU_FTR_440A, .cpu_user_features = COMMON_USER_BOOKE, .icache_bsize = 32, .dcache_bsize = 32,
@@ -1209,7 +1209,7 @@ static struct cpu_spec __initdata cpu_sp .pvr_mask = 0xf0000fff, .pvr_value = 0x50000892, .cpu_name = "440GX Rev. C", - .cpu_features = CPU_FTRS_44X, + .cpu_features = CPU_FTRS_44X | CPU_FTR_440A, .cpu_user_features = COMMON_USER_BOOKE, .icache_bsize = 32, .dcache_bsize = 32,
@@ -1219,7 +1219,7 @@ static struct cpu_spec __initdata cpu_sp .pvr_mask = 0xf0000fff, .pvr_value = 0x50000894, .cpu_name = "440GX Rev. F", - .cpu_features = CPU_FTRS_44X, + .cpu_features = CPU_FTRS_44X | CPU_FTR_440A, .cpu_user_features = COMMON_USER_BOOKE, .icache_bsize = 32, .dcache_bsize = 32,
arch/powerpc/kernel/head_44x.S +6 -5
@@ -197,7 +197,7 @@ skpinv: addi r4,r4,1 /* Increment */ /* Establish the interrupt vector offsets */ SET_IVOR(0, CriticalInput); - SET_IVOR(1, MachineCheck); + SET_IVOR(1, MachineCheck); /* patched later on 440A */ SET_IVOR(2, DataStorage); SET_IVOR(3, InstructionStorage); SET_IVOR(4, ExternalInput);
@@ -237,6 +237,10 @@ skpinv: addi r4,r4,1 /* Increment */ bl early_init +BEGIN_FTR_SECTION + SET_IVOR(1, MachineCheckA); +END_FTR_SECTION_IFSET(CPU_FTR_440A) + /* * Decide what sort of machine this is and initialize the MMU. */
@@ -289,11 +293,8 @@ interrupt_base: CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) /* Machine Check Interrupt */ -#ifdef CONFIG_440A - MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception) -#else CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) -#endif + MCHECK_EXCEPTION(0x0200, MachineCheckA, machine_check_exception) /* Data Storage Interrupt */ START_EXCEPTION(DataStorage)
arch/powerpc/kernel/traps.c +8 -11
@@ -338,20 +338,16 @@ static int generic_machine_check_excepti {unsigned long reason =get_mc_reason (regs); -#if defined(CONFIG_4xx) && !defined(CONFIG_440A ) -if (reason &ESR_IMCP ) { -printk ("Instruction" ); -mtspr (SPRN_ESR , reason & ~ESR_IMCP ); - }else -printk ("Data" ); -printk (" machine check in kernel mode.\n" ); -#elif defined(CONFIG_440A ) +#if defined(CONFIG_4xx)printk ("Machine check in kernel mode.\n" );if (reason &ESR_IMCP ){ -printk ("Instruction Synchronous Machine Check exception\n" ); +if (cpu_has_feature (CPU_FTR_440A )) +printk ("Instruction Synchronous Machine Check exception\n" ); +else +printk ("Instruction Machine Check exception\n" );mtspr (SPRN_ESR , reason & ~ESR_IMCP ); } -else { +else if (cpu_has_feature (CPU_FTR_440A )) {u32 mcsr =mfspr (SPRN_MCSR );if (mcsr &MCSR_IB )printk ("Instruction Read PLB Error\n" );
@@ -374,7 +370,8 @@ static int generic_machine_check_excepti/* Clear MCSR */ mtspr(SPRN_MCSR, mcsr); - } + }else +printk ("Data Machine Check exception\n" );#elif defined (CONFIG_E500)printk ("Machine check in kernel mode.\n" );printk ("Caused by (from MCSR=%lx): " , reason);
arch/powerpc/platforms/44x/Kconfig +0 -5
@@ -62,11 +62,6 @@ config 440GX config 440SP bool -config 440A - bool - depends on 440GX || 440EPX - default y - # 44x errata/workaround config symbols, selected by the CPU models above config IBM440EP_ERR42 bool
include/asm-powerpc/cputable.h +2 -1
@@ -138,6 +138,7 @@ extern void do_feature_fixups(unsigned l#define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x0000000000800000)#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x0000000001000000)#define CPU_FTR_SPE ASM_CONST(0x0000000002000000) +#define CPU_FTR_440A ASM_CONST(0x0000000004000000)/* * Add the 64-bit processor unique features in the top half of the word;
@@ -400,7 +401,7 @@ enum { CPU_FTRS_40X |#endif #ifdef CONFIG_44x - CPU_FTRS_44X | + CPU_FTRS_44X | CPU_FTR_440A |#endif #ifdef CONFIG_E200 CPU_FTRS_E200 |
include/asm-powerpc/reg_booke.h +1 -1
@@ -207,7 +207,7 @@#define CCR1_TCS 0x00000080/* Timer Clock Select */ /* Bit definitions for the MCSR. */ -#ifdef CONFIG_440A +#ifdef CONFIG_4xx#define MCSR_MCS 0x80000000/* Machine Check Summary */ #define MCSR_IB 0x40000000/* Instruction PLB Error */ #define MCSR_DRB 0x20000000/* Data Read PLB Error */
Quoted 4 lines · Benjamin Herrenschmidt
This removes the old
CONFIG_440Awhich was a pain for multiplatform kernel and wasn't set properly by default and replaces it with a CPU feature. This makes Machine Check reporting work correctly on my Ebony (440GP) board.
I'm not sure I like this. It introduces another cpu feature flag, that we'll soon run out of if it's used to signify version info per implementation like this.
1) The SET_IVOR could be done from the cpu_setups for 440A instead (i.e. introduce one).
2) Please just move the machine check handlers out to individual ones instead of using the generic one. That way you don't need runtime checks between the two (they don't seem to share much of it as-is anyway).
With the above two changes, you shouldn't need the feature bit any more.
-Olof
Quoted 4 lines · Olof Johansson
I'm not sure I like this. It introduces another cpu feature flag, that we'll soon run out of if it's used to signify version info per implementation like this.
Quoted 8 lines
1) The
SET_IVORcould be done from thecpu_setupsfor 440A instead (i.e. introduce one).2) Please just move the machine check handlers out to individual ones instead of using the generic one. That way you don't need runtime checks between the two (they don't seem to share much of it as-is anyway).
With the above two changes, you shouldn't need the feature bit any more.
We can easily make the cpu features bigger ... But ok, I'll have a look at doing it the way you suggest.
Cheers,
Ben.
Quoted 8 lines · Benjamin Herrenschmidt
Quoted 7 lines · Olof Johansson
I'm not sure I like this. It introduces another cpu feature flag, that we'll soon run out of if it's used to signify version info per implementation like this.
1) The
SET_IVORcould be done from thecpu_setupsfor 440A instead (i.e. introduce one).
Quoted 8 lines
Quoted 5 lines
2) Please just move the machine check handlers out to individual ones instead of using the generic one. That way you don't need runtime checks between the two (they don't seem to share much of it as-is anyway).
With the above two changes, you shouldn't need the feature bit any more.
We can easily make the cpu features bigger ... But ok, I'll have a look at doing it the way you suggest.
Note that first, I'd like to figure out if there are other relevant differences with 440A ... arch/ppc didn't list any and diff'ing PDFs is not fun but if people around here know, please speak up
Ben.
Quoted 14 lines · Benjamin Herrenschmidt
Quoted 12 lines · Benjamin Herrenschmidt
Quoted 11 lines · Olof Johansson
I'm not sure I like this. It introduces another cpu feature flag, that we'll soon run out of if it's used to signify version info per implementation like this.
1) The
SET_IVORcould be done from thecpu_setupsfor 440A instead (i.e. introduce one).2) Please just move the machine check handlers out to individual ones instead of using the generic one. That way you don't need runtime checks between the two (they don't seem to share much of it as-is anyway).
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
With the above two changes, you shouldn't need the feature bit any more.
We can easily make the cpu features bigger ... But ok, I'll have a look at doing it the way you suggest.
Note that first, I'd like to figure out if there are other relevant differences with 440A ...
arch/ppcdidn't list any and diff'ing PDFs is not fun but if people around here know, please speak up
I think it added isel support.
- k
Quoted 26 lines · On Fri, 16 Nov 2007 15:55:25 -0600 Kumar Gala <[email protected]> wrote:
Quoted 23 lines · Benjamin Herrenschmidt
Quoted 20 lines · Benjamin Herrenschmidt
Quoted 7 lines · Olof Johansson
I'm not sure I like this. It introduces another cpu feature flag, that we'll soon run out of if it's used to signify version info per implementation like this.
1) The
SET_IVORcould be done from thecpu_setupsfor 440A instead (i.e. introduce one).Quoted 8 lines
2) Please just move the machine check handlers out to individual ones
instead of using the generic one. That way you don't need runtime checks
between the two (they don't seem to share much of it as-is anyway).With the above two changes, you shouldn't need the feature bit any more.
We can easily make the cpu features bigger ... But ok, I'll have a look
at doing it the way you suggest.
Quoted 7 lines
Quoted 4 lines
Note that first, I'd like to figure out if there are other relevant differences with 440A ...
arch/ppcdidn't list any and diff'ing PDFs is
not fun but if people around here know, please speak upI think it added isel support.
I'm not entirely sure about that, but I'll check. 440x4 cores lack isel, 440x5, 440x6 have it. I don't think it was tied to the 'A' moniker.
josh
Quoted 6 lines · On Fri, 16 Nov 2007 01:40:25 -0600 Olof Johansson <[email protected]> wrote:
Quoted 4 lines · Benjamin Herrenschmidt
This removes the old
CONFIG_440Awhich was a pain for multiplatform kernel and wasn't set properly by default and replaces it with a CPU feature. This makes Machine Check reporting work correctly on my Ebony (440GP) board.
Quoted 6 lines
I'm not sure I like this. It introduces another cpu feature flag, that we'll soon run out of if it's used to signify version info per implementation like this.
1) The
SET_IVORcould be done from thecpu_setupsfor 440A instead (i.e. introduce one).
Yeah, that might work. I'm wondering if either method needs to take arch/ppc into account, as the cputable is shared.
Quoted 3 lines
2) Please just move the machine check handlers out to individual ones instead of using the generic one. That way you don't need runtime checks between the two (they don't seem to share much of it as-is anyway).
Anton pinged me about cleaning that up a couple months ago. I have a half-baked patch for it somewhere, but I agree having 4xx set a ppc_md specific handler would be a good idea.
josh
Quoted 9 lines · Josh Boyer
Quoted 1 line
2) Please just move the machine check handlers out to individual
ones
Quoted 1 line
instead of using the generic one. That way you don't need runtime
checks
Quoted 1 line
between the two (they don't seem to share much of it as-is anyway).
Anton pinged me about cleaning that up a couple months ago. I have a half-baked patch for it somewhere, but I agree having 4xx set a
ppc_mdspecific handler would be a good idea.
No need. The 2 asm implementation can branch to 2 different C functions and the IVOR will be set to the right one.
Ben.
Quoted 20 lines · Benjamin Herrenschmidt
This removes the old
CONFIG_440Awhich was a pain for multiplatform kernel and wasn't set properly by default and replaces it with a CPU feature. This makes Machine Check reporting work correctly on my Ebony (440GP) board.Signed-off-by Benjamin Herrenschmidt <[email protected]>---
Note: I'm only setting it for 440GX and EPx as the old code did, I haven't checked whether other new 440 chips such as SPe also need that bit set.
arch/powerpc/kernel/cputable.c | 10 +++++----- arch/powerpc/kernel/head_44x.S | 11 ++++++----- arch/powerpc/kernel/traps.c | 19 ++++++++----------- arch/powerpc/platforms/44x/Kconfig | 5 ----- include/asm-powerpc/cputable.h | 3 ++- include/asm-powerpc/reg_booke.h | 2 +- 6 files changed, 22 insertions(+), 28 deletions(-)
[snip]
include/asm-powerpc/cputable.h extern void do_feature_fixups(unsigned l · line 141
Quoted 11 lines
Index:
linux-work/include/asm-powerpc/cputable.h
===================================================================
---linux-work.orig/include/asm-powerpc/cputable.h2007-11-16
16:14:29.000000000 +1100
+++linux-work/include/asm-powerpc/cputable.h2007-11-16
16:19:35.000000000 +1100include/asm-powerpc/cputable.h +1
-0@@ -138,6 +138,7 @@ extern void do_feature_fixups(unsigned l#define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x0000000000800000)#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x0000000001000000)#define CPU_FTR_SPE ASM_CONST(0x0000000002000000) +#define CPU_FTR_440A ASM_CONST(0x0000000004000000)
Can we be more specific about what this feature really means.
How about something like CPU_FTR_ENH_MCHCK or something like that.
- k
Quoted 15 lines
include/asm-powerpc/cputable.h extern void do_feature_fixups(unsigned l · line 141
Quoted 12 lines
Index:
linux-work/include/asm-powerpc/cputable.h
===================================================================
---linux-work.orig/include/asm-powerpc/cputable.h2007-11-16
16:14:29.000000000 +1100
+++linux-work/include/asm-powerpc/cputable.h2007-11-16
16:19:35.000000000 +1100include/asm-powerpc/cputable.h +1
-0@@ -138,6 +138,7 @@ extern void do_feature_fixups(unsigned l#define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x0000000000800000)#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x0000000001000000)#define CPU_FTR_SPE ASM_CONST(0x0000000002000000) +#define CPU_FTR_440A ASM_CONST(0x0000000004000000)Can we be more specific about what this feature really means.
Quoted 1 line
How about something like
CPU_FTR_ENH_MCHCKor something like that.
Did that at first, then figured out that I indeed had 2 core manuals one of them being labelled "A"... I'm trying to figure out what other differences they may have to see whether I should stick to that CPU feature or just remove it completely and do as Olof suggested.
Ben.