From 4099f70e94789731c3a20f89be058cfb2bfed836 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Sat, 2 Mar 2013 08:50:33 +0000 Subject: powerpc/e500: work around erratum A-006184 Erratum A-006184 says that a hang can happen under certain circumstances when taking an exception. The erratum workaround gives the use of a watchdog as an option, to get unstuck if a hang does occur. Signed-off-by: Scott Wood Change-Id: Ib63bea70bb2ad7ea4cee9b96ec4f7aefc21ea3b3 Reviewed-on: http://git.am.freescale.net:8181/1113 Tested-by: Fleming Andrew-AFLEMING Reviewed-by: Fleming Andrew-AFLEMING diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 39308c7..5e6a242 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -444,6 +444,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) fixed_interval, .unknown_exception, ACK_FIT) /* Watchdog Timer Interrupt */ +#ifdef CONFIG_FSL_ERRATUM_A_006184 + START_EXCEPTION(watchdog) + mtspr SPRN_SPRG_CRIT_SCRATCH, r3 + lis r3, TSR_WIS@h + mtspr SPRN_TSR, r3 + mfspr r3, SPRN_SPRG_CRIT_SCRATCH + rfci +#else START_EXCEPTION(watchdog); CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG, PROLOG_ADDITION_NONE) @@ -454,6 +462,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) // bl .unknown_exception // b ret_from_crit_except b . +#endif /* System Call Interrupt */ START_EXCEPTION(system_call) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 58925b6..987a3f1 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -369,7 +369,15 @@ interrupt_base: unknown_exception, EXC_XFER_EE) /* Watchdog Timer Interrupt */ -#ifdef CONFIG_BOOKE_WDT +#ifdef CONFIG_FSL_ERRATUM_A_006184 + START_EXCEPTION(WatchdogTimer) + mtspr SPRN_SPRG_WSCRATCH_CRIT, r3 + lis r3, TSR_WIS@h + mtspr SPRN_TSR, r3 + /* use WSCRATCH to avoid any potential problems with KVM paravirt */ + mfspr r3, SPRN_SPRG_WSCRATCH_CRIT + rfci +#elif defined(CONFIG_BOOKE_WDT) CRITICAL_EXCEPTION(0x3200, WATCHDOG, WatchdogTimer, WatchdogException) #else CRITICAL_EXCEPTION(0x3200, WATCHDOG, WatchdogTimer, unknown_exception) diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index ea78761..c6ac64b 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c @@ -102,6 +102,9 @@ void cpu_idle(void) ppc64_runlatch_on(); rcu_idle_exit(); tick_nohz_idle_exit(); +#ifdef CONFIG_FSL_ERRATUM_A_006184 + mtspr(SPRN_TSR, TSR_ENW); +#endif if (cpu_should_die()) { sched_preempt_enable_no_resched(); cpu_die(); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 127361e..9a9112f 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -488,6 +488,9 @@ void timer_interrupt(struct pt_regs * regs) struct clock_event_device *evt = &__get_cpu_var(decrementers); u64 now; +#ifdef CONFIG_FSL_ERRATUM_A_006184 + mtspr(SPRN_TSR, TSR_ENW); +#endif /* Ensure a positive value is written to the decrementer, or else * some CPUs will continue to take decrementer exceptions. */ @@ -638,7 +641,15 @@ void start_cpu_decrementer(void) mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); /* Enable decrementer interrupt */ +#ifdef CONFIG_FSL_ERRATUM_A_006184 +#define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15)) + { + u32 period = WDTP(CONFIG_FSL_ERRATUM_A_006184_PERIOD); + mtspr(SPRN_TCR, TCR_DIE | TCR_WIE | period); + } +#else mtspr(SPRN_TCR, TCR_DIE); +#endif #endif /* defined(CONFIG_BOOKE) || defined(CONFIG_40x) */ } diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 421bae9..550ceba 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -174,6 +174,48 @@ config PPC_E6500_REV1_BUGS Do not define this if you are running on a simulator or rev2, and want features like hardware tablewalk. +config FSL_ERRATUM_A_006184 + bool "Work around erratum A-006184" + help + Define this to work around erratum A-006184 ("Simultaneous + Instruction L1 MMU miss (due to eviction) and interrupt + servicing can cause a core hang"). This erratum affects + e500v1, e500v2, e500mc, and e5500. The workaround will + cause a watchdog interrupt to occur periodically. It will + not avoid the hang described by the erratum, but it will + recover from it when the next watchdog interrupt expires. + + The normal watchdog functionality cannot be used when this + workaround is enabled. + + If you are running Linux as the guest of a hypervisor, you + should enable this (or a similar workaround) in the host + instead. + + Note that it is believed that it is unlikely that the hang + will be encountered in normal Linux operation. Running KVM + or using hugetlbfs could increase the chance of seeing the + hang. + +config FSL_ERRATUM_A_006184_PERIOD + int "Watchdog period for A-006184 workaround" + range 32 52 + default 43 + help + This is the watchdog period to be used for the A-006184 + workaround. The watchdog will fire whenever the bit selected + transitions from 0 to 1 in the time base. The bits are + numbered with 0 starting at the most-signficant end -- + larger numbers give a more frequent period. + + The period must be set longer than the non-idle decrementer + period, to ensure that the watchdog interrupt only actually + happens when stuck -- but the longer the period, the worse the + latency will be if a hang does occur. Long decrementer + timeouts when idle due to CONFIG_NO_HZ should not be a problem, + since when idle we will always have just executed from the main + kernel mapping, so it should not be absent from the L1 I-MMU. + config FSL_ERRATUM_A_006198 bool "Work around e6500 rev1 erratum A-006198" depends on PPC_E500MC diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 19fa73a..391ee8c 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1119,7 +1119,7 @@ config PIKA_WDT config BOOKE_WDT tristate "PowerPC Book-E Watchdog Timer" - depends on BOOKE || 4xx + depends on (BOOKE || 4xx) && !FSL_ERRATUM_A_006184 ---help--- Watchdog driver for PowerPC Book-E chips, such as the Freescale MPC85xx SOCs and the IBM PowerPC 440. -- cgit v0.10.2