u64 checkstop_fir; /* 0x0c00 */
u64 recoverable_fir; /* 0x0c08 */
u64 spec_att_mchk_fir; /* 0x0c10 */
- u64 fir_mode_reg; /* 0x0c18 */
+ u32 fir_mode_reg; /* 0x0c18 */
+ u8 pad_0x0c1c_0x0c20 [4]; /* 0x0c1c */
+#define CBE_PMD_FIR_MODE_M8 0x00800
u64 fir_enable_mask; /* 0x0c20 */
- u8 pad_0x0c28_0x1000 [0x1000 - 0x0c28]; /* 0x0c28 */
+ u8 pad_0x0c28_0x0ca8 [0x0ca8 - 0x0c28]; /* 0x0c28 */
+ u64 ras_esc_0; /* 0x0ca8 */
+ u8 pad_0x0cb0_0x1000 [0x1000 - 0x0cb0]; /* 0x0cb0 */
};
extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np);
#include "pervasive.h"
#include "cbe_regs.h"
+static int sysreset_hack;
+
static void cbe_power_save(void)
{
unsigned long ctrl, thread_switch_control;
static int cbe_system_reset_exception(struct pt_regs *regs)
{
+ int cpu;
+ struct cbe_pmd_regs __iomem *pmd;
+
switch (regs->msr & SRR1_WAKEMASK) {
case SRR1_WAKEEE:
do_IRQ(regs);
timer_interrupt(regs);
break;
case SRR1_WAKEMT:
+ /*
+ * The BMC can inject user triggered system reset exceptions,
+ * but cannot set the system reset reason in srr1,
+ * so check an extra register here.
+ */
+ if (sysreset_hack && (cpu = smp_processor_id()) == 0) {
+ pmd = cbe_get_cpu_pmd_regs(cpu);
+ if (in_be64(&pmd->ras_esc_0) & 0xffff) {
+ out_be64(&pmd->ras_esc_0, 0);
+ return 0;
+ }
+ }
break;
#ifdef CONFIG_CBE_RAS
case SRR1_WAKESYSERR:
void __init cbe_pervasive_init(void)
{
int cpu;
+
if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
return;
+ sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
+
for_each_possible_cpu(cpu) {
struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu);
if (!regs)
/* Enable Pause(0) control bit */
out_be64(®s->pmcr, in_be64(®s->pmcr) |
CBE_PMD_PAUSE_ZERO_CONTROL);
+
+ /* Enable JTAG system-reset hack */
+ if (sysreset_hack)
+ out_be32(®s->fir_mode_reg,
+ in_be32(®s->fir_mode_reg) |
+ CBE_PMD_FIR_MODE_M8);
}
ppc_md.power_save = cbe_power_save;