ia64/xen-unstable
changeset 11505:2ebf55e419c9
[POWERPC][XEN] Track HID4[RM_CI] state for machine check
This patch creates a PIR indexed character array so we can note when a
processor is in RM_CI mode. Machine checks can happen here and we
need to at least report it (and maybe one day) recover from it. Also
some fun with the SCOM.
Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
This patch creates a PIR indexed character array so we can note when a
processor is in RM_CI mode. Machine checks can happen here and we
need to at least report it (and maybe one day) recover from it. Also
some fun with the SCOM.
Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author | Jimi Xenidis <jimix@watson.ibm.com> |
---|---|
date | Thu Sep 07 21:46:33 2006 -0400 (2006-09-07) |
parents | e7c55ba4de2e |
children | a22a7797e0ba |
files | xen/arch/powerpc/powerpc64/exceptions.S xen/arch/powerpc/powerpc64/io.S xen/arch/powerpc/powerpc64/ppc970.c xen/include/asm-powerpc/percpu.h xen/include/asm-powerpc/powerpc64/ppc970-hid.h xen/include/asm-powerpc/processor.h |
line diff
1.1 --- a/xen/arch/powerpc/powerpc64/exceptions.S Thu Sep 07 12:09:18 2006 -0400 1.2 +++ b/xen/arch/powerpc/powerpc64/exceptions.S Thu Sep 07 21:46:33 2006 -0400 1.3 @@ -1,27 +1,30 @@ 1.4 /* 1.5 - * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation 1.6 - * 1.7 * This program is free software; you can redistribute it and/or modify 1.8 * it under the terms of the GNU General Public License as published by 1.9 * the Free Software Foundation; either version 2 of the License, or 1.10 * (at your option) any later version. 1.11 - * 1.12 + * 1.13 * This program is distributed in the hope that it will be useful, 1.14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 * GNU General Public License for more details. 1.17 - * 1.18 + * 1.19 * You should have received a copy of the GNU General Public License 1.20 * along with this program; if not, write to the Free Software 1.21 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1.22 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 1.23 + * 1.24 + * Copyright (C) IBM Corp. 2005, 2006 1.25 * 1.26 + * Authors: Jimi Xenidis <jimix@watson.ibm.com> 1.27 + * Hollis Blanchard <hollisb@us.ibm.com> 1.28 */ 1.29 - 1.30 + 1.31 #include <asm/config.h> 1.32 #include <asm/asm-offsets.h> 1.33 #include <asm/reg_defs.h> 1.34 #include <asm/msr.h> 1.35 #include <asm/processor.h> 1.36 +#include <asm/percpu.h> 1.37 1.38 .macro SAVE_GPR regno uregs 1.39 std \regno, (UREGS_gprs + GPR_WIDTH * \regno)(\uregs) 1.40 @@ -190,6 +193,14 @@ zero: 1.41 li r0, 0x0 /* exception vector for GDB stub */ 1.42 bctr 1.43 1.44 + /* The following byte array is where any per-CPU state flags 1.45 + * that can be be used across interrupts. Currently it is only used 1.46 + * to track Cache Inhibited Mode when a Machine Check occurs. */ 1.47 + /* NOTE: This array is indexed by PIR NOT CPUID */ 1.48 + . = MCK_CPU_STAT_BASE 1.49 + .space NR_CPUS 1.50 + . = MCK_GOOD_HID4 1.51 + .quad 0 1.52 . = 0x100 # System Reset 1.53 ex_reset: 1.54 /* XXX thread initialization */ 1.55 @@ -200,8 +211,19 @@ ex_reset: 1.56 1.57 . = 0x200 # Machine Check 1.58 ex_machcheck: 1.59 + /* Restore HID4 to a known state early, we do not recover from 1.60 + * machine check yet, but when we do we shoul dbe able to restore 1.61 + * HID4 to it proper value */ 1.62 + mtspr SPRN_HSPRG1, r13 1.63 + ld r13, MCK_GOOD_HID4(0) 1.64 + sync 1.65 + mtspr SPRN_HID4, r13 1.66 + isync 1.67 + /* Hopefully we don't have to worry about the ERAT */ 1.68 + mfspr r13, SPRN_HSPRG1 1.69 + /* and now back to our regularly schedualed program */ 1.70 GET_STACK r13 SPRN_SRR1 1.71 - EXCEPTION_HEAD r13 ex_program_continued 1.72 + EXCEPTION_HEAD r13 ex_machcheck_continued 1.73 li r0, 0x200 /* exception vector for GDB stub */ 1.74 bctr 1.75 1.76 @@ -337,6 +359,10 @@ exception_vectors_end: 1.77 b . /* prevent speculative icache fetch */ 1.78 .endm 1.79 1.80 +/* Not a whole lot just yet */ 1.81 +ex_machcheck_continued: 1.82 + 1.83 + 1.84 /* We enter with the exception number in r0. The EXCEPTION_SAVE_STATE macro 1.85 * clobbers r0 though, so we have to move it around a little bit. Not ideal, 1.86 * but hopefully program exception is not performance-critical... Maybe there's
2.1 --- a/xen/arch/powerpc/powerpc64/io.S Thu Sep 07 12:09:18 2006 -0400 2.2 +++ b/xen/arch/powerpc/powerpc64/io.S Thu Sep 07 21:46:33 2006 -0400 2.3 @@ -1,23 +1,27 @@ 2.4 /* 2.5 - * Copyright (C) 2005 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation 2.6 - * 2.7 * This program is free software; you can redistribute it and/or modify 2.8 * it under the terms of the GNU General Public License as published by 2.9 * the Free Software Foundation; either version 2 of the License, or 2.10 * (at your option) any later version. 2.11 - * 2.12 + * 2.13 * This program is distributed in the hope that it will be useful, 2.14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 2.15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2.16 * GNU General Public License for more details. 2.17 - * 2.18 + * 2.19 * You should have received a copy of the GNU General Public License 2.20 * along with this program; if not, write to the Free Software 2.21 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2.22 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 2.23 + * 2.24 + * Copyright (C) IBM Corp. 2005, 2006 2.25 + * 2.26 + * Authors: Jimi Xenidis <jimix@watson.ibm.com> 2.27 + * Hollis Blanchard <hollisb@us.ibm.com> 2.28 */ 2.29 2.30 #include <asm/config.h> 2.31 #include <asm/processor.h> 2.32 +#include <asm/percpu.h> 2.33 2.34 /* Xen runs in real mode (i.e. untranslated, MMU disabled). This avoids TLB 2.35 * flushes and also makes it easy to access all domains' memory. However, on 2.36 @@ -54,6 +58,12 @@ 2.37 sync 2.38 mtspr SPRN_HID4, r5 2.39 isync 2.40 + 2.41 + /* Mark the processor as "in CI mode" */ 2.42 + mfspr r5, SPRN_PIR 2.43 + li r6, MCK_CPU_STAT_CI 2.44 + stb r6, MCK_CPU_STAT_BASE(r5) 2.45 + sync 2.46 .endm 2.47 2.48 .macro ENABLE_DCACHE addr 2.49 @@ -63,6 +73,12 @@ 2.50 mtspr SPRN_HID4, r9 2.51 isync 2.52 2.53 + /* Mark the processor as "out of CI mode" */ 2.54 + mfspr r5, SPRN_PIR 2.55 + li r6, 0 2.56 + stb r6, MCK_CPU_STAT_BASE(r5) 2.57 + sync 2.58 + 2.59 /* re-enable interrupts */ 2.60 mtmsr r8 2.61 .endm
3.1 --- a/xen/arch/powerpc/powerpc64/ppc970.c Thu Sep 07 12:09:18 2006 -0400 3.2 +++ b/xen/arch/powerpc/powerpc64/ppc970.c Thu Sep 07 21:46:33 2006 -0400 3.3 @@ -103,20 +103,29 @@ int cpu_io_mfn(ulong mfn) 3.4 return 0; 3.5 } 3.6 3.7 +#ifdef DEBUG 3.8 +static void scom_init(void) 3.9 +{ 3.10 + write_scom(SCOM_AMCS_AND_MASK, 0); 3.11 + 3.12 + printk("scom MCKE: 0x%016lx\n", read_scom(SCOM_CMCE)); 3.13 + write_scom(SCOM_CMCE, ~0UL); 3.14 + printk("scom MCKE: 0x%016lx\n", read_scom(SCOM_CMCE)); 3.15 +} 3.16 +#else 3.17 +#define scom_init() 3.18 +#endif 3.19 + 3.20 static u64 cpu0_hids[6]; 3.21 static u64 cpu0_hior; 3.22 3.23 void cpu_initialize(int cpuid) 3.24 { 3.25 - ulong r1, r2; 3.26 union hid0 hid0; 3.27 union hid1 hid1; 3.28 union hid4 hid4; 3.29 union hid5 hid5; 3.30 3.31 - __asm__ __volatile__ ("mr %0, 1" : "=r" (r1)); 3.32 - __asm__ __volatile__ ("mr %0, 2" : "=r" (r2)); 3.33 - 3.34 if (cpuid == 0) { 3.35 /* we can assume that these are sane to start with. We 3.36 * _do_not_ store the results in case we want to mess with them 3.37 @@ -139,6 +148,19 @@ void cpu_initialize(int cpuid) 3.38 3.39 mthsprg0((ulong)parea); /* now ready for exceptions */ 3.40 3.41 + printk("CPU[PIR:%u IPI:%u Logical:%u] Hello World!\n", 3.42 + mfpir(), raw_smp_processor_id(), smp_processor_id()); 3.43 + 3.44 +#ifdef DEBUG 3.45 + { 3.46 + ulong r1, r2; 3.47 + 3.48 + asm volatile ("mr %0, 1" : "=r" (r1)); 3.49 + asm volatile ("mr %0, 2" : "=r" (r2)); 3.50 + printk(" SP = %lx TOC = %lx\n", r1, r2); 3.51 + } 3.52 +#endif 3.53 + 3.54 /* Set decrementers for 1 second to keep them out of the way during 3.55 * intialization. */ 3.56 /* XXX make tickless */ 3.57 @@ -147,11 +169,12 @@ void cpu_initialize(int cpuid) 3.58 3.59 hid0.bits.nap = 1; /* NAP */ 3.60 hid0.bits.dpm = 1; /* Dynamic Power Management */ 3.61 - hid0.bits.nhr = 0; /* ! Not Hard Reset */ 3.62 + hid0.bits.nhr = 1; /* Not Hard Reset */ 3.63 hid0.bits.hdice_en = 1; /* enable HDEC */ 3.64 hid0.bits.en_therm = 0; /* ! Enable ext thermal ints */ 3.65 /* onlu debug Xen should do this */ 3.66 - hid0.bits.en_attn = 1; /* Enable attn instruction */ 3.67 + hid0.bits.en_attn = 1; /* Enable attn instruction */ 3.68 + hid0.bits.en_mck = 1; /* Enable external machine check interrupts */ 3.69 3.70 #ifdef SERIALIZE 3.71 hid0.bits.one_ppc = 1; 3.72 @@ -162,9 +185,6 @@ void cpu_initialize(int cpuid) 3.73 hid0.bits.ser-gp = 1; 3.74 #endif 3.75 3.76 - printk("CPU #%d: Hello World! SP = %lx TOC = %lx HID0 = %lx\n", 3.77 - smp_processor_id(), r1, r2, hid0.word); 3.78 - 3.79 mthid0(hid0.word); 3.80 3.81 hid1.bits.bht_pm = 7; /* branch history table prediction mode */ 3.82 @@ -188,6 +208,7 @@ void cpu_initialize(int cpuid) 3.83 hid4.bits.lg_pg_dis = 0; /* make sure we enable large pages */ 3.84 mthid4(hid4.word); 3.85 3.86 + hid5.bits.DC_mck = 1; /* Machine check enabled for dcache errors */ 3.87 hid5.bits.DCBZ_size = 0; /* make dcbz size 32 bytes */ 3.88 hid5.bits.DCBZ32_ill = 0; /* make dzbz 32byte illeagal */ 3.89 mthid5(hid5.word); 3.90 @@ -200,12 +221,27 @@ void cpu_initialize(int cpuid) 3.91 mfhid0(), mfhid1(), mfhid4(), mfhid5()); 3.92 #endif 3.93 3.94 + /* Make sure firmware has not left this dirty */ 3.95 mthior(cpu0_hior); 3.96 3.97 + /* some machine check goodness */ 3.98 + /* save this for checkstop processing */ 3.99 + if (cpuid == 0) 3.100 + *mck_good_hid4 = hid4.word; 3.101 + 3.102 + if (mfpir() > NR_CPUS) 3.103 + panic("we do not expect a processor to have a PIR (%u) " 3.104 + "to be larger that NR_CPUS(%u)\n", 3.105 + mfpir(), NR_CPUS); 3.106 + 3.107 + scom_init(); 3.108 + 3.109 + /* initialize the SLB */ 3.110 #ifdef DEBUG 3.111 dump_segments(1); 3.112 #endif 3.113 flush_segments(); 3.114 + local_flush_tlb(); 3.115 } 3.116 3.117 void cpu_init_vcpu(struct vcpu *v) 3.118 @@ -252,6 +288,9 @@ int cpu_machinecheck(struct cpu_user_reg 3.119 recover = 1; 3.120 3.121 printk("MACHINE CHECK: %s Recoverable\n", recover ? "IS": "NOT"); 3.122 + if (mck_cpu_stats[mfpir()] != 0) 3.123 + printk("While in CI IO\n"); 3.124 + 3.125 printk("SRR1: 0x%016lx\n", regs->msr); 3.126 if (regs->msr & MCK_SRR1_INSN_FETCH_UNIT) 3.127 printk("42: Exception caused by Instruction Fetch Unit (IFU) "
4.1 --- a/xen/include/asm-powerpc/percpu.h Thu Sep 07 12:09:18 2006 -0400 4.2 +++ b/xen/include/asm-powerpc/percpu.h Thu Sep 07 21:46:33 2006 -0400 4.3 @@ -6,6 +6,20 @@ 4.4 #define PERCPU_SHIFT 12 4.5 #define PERCPU_SIZE (1UL << PERCPU_SHIFT) 4.6 4.7 +/* We care out NR_CPUS bytes below the reset vector (0x100) so we can 4.8 + * track per-cpu state that we wish we had a register for. Currently 4.9 + * it is only used to track Cache Inhibited Mode when a Machine Check 4.10 + * occurs. */ 4.11 +/* NOTE: This array is indexed by PIR NOT CPUID */ 4.12 +#define MCK_GOOD_HID4 (0x100 - 8) 4.13 +#define MCK_CPU_STAT_BASE (MCK_GOOD_HID4 - NR_CPUS) /* accomodate a hid4 */ 4.14 +/* Currently, the only state we track, so lets make it easy */ 4.15 +#define MCK_CPU_STAT_CI -1 4.16 + 4.17 +#ifndef __ASSEMBLY__ 4.18 +#define mck_cpu_stats ((char *)MCK_CPU_STAT_BASE) 4.19 +#define mck_good_hid4 ((ulong *)MCK_GOOD_HID4) 4.20 + 4.21 /* Separate out the type, so (int[3], foo) works. */ 4.22 #define DEFINE_PER_CPU(type, name) \ 4.23 __attribute__((__section__(".data.percpu"))) \ 4.24 @@ -18,5 +32,5 @@ 4.25 (per_cpu(var, smp_processor_id())) 4.26 4.27 #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name 4.28 - 4.29 +#endif /* __ASSEMBLY__ */ 4.30 #endif /* __PPC_PERCPU_H__ */
5.1 --- a/xen/include/asm-powerpc/powerpc64/ppc970-hid.h Thu Sep 07 12:09:18 2006 -0400 5.2 +++ b/xen/include/asm-powerpc/powerpc64/ppc970-hid.h Thu Sep 07 21:46:33 2006 -0400 5.3 @@ -158,4 +158,85 @@ union hid5 { 5.4 #define MCK_DSISR_TLB_PAR 0x00000400 /* 21 */ 5.5 #define MCK_DSISR_SLB_PAR 0x00000100 /* 23 */ 5.6 5.7 +#define SPRN_SCOMC 276 5.8 +#define SPRN_SCOMD 277 5.9 + 5.10 +static inline void mtscomc(ulong scomc) 5.11 +{ 5.12 + __asm__ __volatile__ ("mtspr %1, %0" : : "r" (scomc), "i"(SPRN_SCOMC)); 5.13 +} 5.14 + 5.15 +static inline ulong mfscomc(void) 5.16 +{ 5.17 + ulong scomc; 5.18 + __asm__ __volatile__ ("mfspr %0, %1" : "=r" (scomc): "i"(SPRN_SCOMC)); 5.19 + return scomc; 5.20 +} 5.21 + 5.22 +static inline void mtscomd(ulong scomd) 5.23 +{ 5.24 + __asm__ __volatile__ ("mtspr %1, %0" : : "r" (scomd), "i"(SPRN_SCOMD)); 5.25 +} 5.26 + 5.27 +static inline ulong mfscomd(void) 5.28 +{ 5.29 + ulong scomd; 5.30 + __asm__ __volatile__ ("mfspr %0, %1" : "=r" (scomd): "i"(SPRN_SCOMD)); 5.31 + return scomd; 5.32 +} 5.33 + 5.34 +union scomc { 5.35 + struct scomc_bits { 5.36 + ulong _reserved_0_31: 32; 5.37 + ulong addr: 16; 5.38 + ulong RW: 1; 5.39 + ulong _reserved_49_55: 7; 5.40 + ulong _reserved_56_57: 2; 5.41 + ulong addr_error: 1; 5.42 + ulong iface_error: 1; 5.43 + ulong disabled: 1; 5.44 + ulong _reserved_61_62: 2; 5.45 + ulong failure: 1; 5.46 + } bits; 5.47 + ulong word; 5.48 +}; 5.49 + 5.50 + 5.51 +static inline ulong read_scom(ulong addr) 5.52 +{ 5.53 + union scomc c; 5.54 + ulong d; 5.55 + 5.56 + c.word = 0; 5.57 + c.bits.addr = addr; 5.58 + c.bits.RW = 0; 5.59 + 5.60 + mtscomc(c.word); 5.61 + d = mfscomd(); 5.62 + c.word = mfscomc(); 5.63 + if (c.bits.failure) 5.64 + panic("scom status: 0x%016lx\n", c.word); 5.65 + 5.66 + return d; 5.67 +} 5.68 + 5.69 +static inline void write_scom(ulong addr, ulong val) 5.70 +{ 5.71 + union scomc c; 5.72 + 5.73 + c.word = 0; 5.74 + c.bits.addr = addr; 5.75 + c.bits.RW = 0; 5.76 + 5.77 + mtscomd(val); 5.78 + mtscomc(c.word); 5.79 + c.word = mfscomc(); 5.80 + if (c.bits.failure) 5.81 + panic("scom status: 0x%016lx\n", c.word); 5.82 +} 5.83 + 5.84 +#define SCOM_AMCS_REG 0x022601 5.85 +#define SCOM_AMCS_AND_MASK 0x022700 5.86 +#define SCOM_AMCS_OR_MASK 0x022800 5.87 +#define SCOM_CMCE 0x030901 5.88 #endif
6.1 --- a/xen/include/asm-powerpc/processor.h Thu Sep 07 12:09:18 2006 -0400 6.2 +++ b/xen/include/asm-powerpc/processor.h Thu Sep 07 21:46:33 2006 -0400 6.3 @@ -84,6 +84,13 @@ static inline void nop(void) { 6.4 } 6.5 #define cpu_relax() nop() 6.6 6.7 +static inline unsigned int mfpir(void) 6.8 +{ 6.9 + unsigned int pir; 6.10 + __asm__ __volatile__ ("mfspr %0, %1" : "=r" (pir): "i"(SPRN_PIR)); 6.11 + return pir; 6.12 +} 6.13 + 6.14 static inline unsigned int mftbu(void) 6.15 { 6.16 unsigned int tbu;