diff options
-rw-r--r-- | sys/arch/sgi/gio/gioreg.h | 4 | ||||
-rw-r--r-- | sys/arch/sgi/localbus/imc.c | 62 | ||||
-rw-r--r-- | sys/arch/sgi/localbus/imcreg.h | 15 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip22_machdep.c | 4 |
4 files changed, 55 insertions, 30 deletions
diff --git a/sys/arch/sgi/gio/gioreg.h b/sys/arch/sgi/gio/gioreg.h index 7822ce4f0b6..9abc4ff4283 100644 --- a/sys/arch/sgi/gio/gioreg.h +++ b/sys/arch/sgi/gio/gioreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gioreg.h,v 1.3 2012/05/10 21:30:39 miod Exp $ */ +/* $OpenBSD: gioreg.h,v 1.4 2014/07/02 17:44:35 miod Exp $ */ /* $NetBSD: gioreg.h,v 1.4 2006/08/31 00:01:10 rumble Exp $ */ /* @@ -71,3 +71,5 @@ #define GIO_ADDR_EXP0 0x1f400000 /* 2MB */ #define GIO_ADDR_EXP1 0x1f600000 /* 4MB */ #define GIO_ADDR_END 0x1fa00000 + +#define IS_GIO_ADDRESS(pa) ((pa) >= GIO_ADDR_GFX && (pa) < GIO_ADDR_END) diff --git a/sys/arch/sgi/localbus/imc.c b/sys/arch/sgi/localbus/imc.c index 58e78bbd938..04b60273ee7 100644 --- a/sys/arch/sgi/localbus/imc.c +++ b/sys/arch/sgi/localbus/imc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imc.c,v 1.16 2014/05/19 21:18:42 miod Exp $ */ +/* $OpenBSD: imc.c,v 1.17 2014/07/02 17:44:35 miod Exp $ */ /* $NetBSD: imc.c,v 1.32 2011/07/01 18:53:46 dyoung Exp $ */ /* @@ -61,8 +61,10 @@ #include <sgi/sgi/ip22.h> #include <sgi/localbus/imcreg.h> #include <sgi/localbus/imcvar.h> +#include <sgi/localbus/intreg.h> #include <sgi/hpc/hpcreg.h> +#include <sgi/gio/gioreg.h> #include <sgi/gio/giovar.h> #include "eisa.h" @@ -716,10 +718,13 @@ uint32_t imc_bus_error(uint32_t hwpend, struct trap_frame *tf) { uint32_t cpustat, giostat; - int quiet = 0; + paddr_t cpuaddr, gioaddr; + int cpuquiet = 0, gioquiet = 0; cpustat = imc_read(IMC_CPU_ERRSTAT); + cpuaddr = imc_read(IMC_CPU_ERRADDR); giostat = imc_read(IMC_GIO_ERRSTAT); + gioaddr = imc_read(IMC_GIO_ERRADDR); switch (sys_config.system_type) { case SGI_IP28: @@ -728,34 +733,41 @@ imc_bus_error(uint32_t hwpend, struct trap_frame *tf) * non-existing memory when in the kernel. We do not * want to flood the console about those. */ - if ((cpustat & IMC_CPU_ERRSTAT_ADDR) && - IS_XKPHYS((vaddr_t)tf->pc)) - quiet = 1; - /* This happens. No idea why. */ - if (cpustat == 0 && giostat == 0) - quiet = 1; + if (cpustat & IMC_CPU_ERRSTAT_ADDR) { + if (IS_XKPHYS((vaddr_t)tf->pc)) + cpuquiet = 1; + } + if (giostat != 0) { + /* + * Ignore speculative writes to interrupt controller + * registers. + */ + if ((giostat & IMC_ECC_ERRSTAT_FUW) && + (gioaddr & ~0x3f) == INT2_IP22) + gioquiet = 1; + /* XXX is it wise to hide these? */ + if ((giostat & IMC_GIO_ERRSTAT_TMO) && + !IS_GIO_ADDRESS(gioaddr)) + gioquiet = 1; + } break; } - if (quiet == 0) { - printf("bus error:"); - if (cpustat != 0) { - vaddr_t pc = tf->pc; - uint32_t insn = 0xffffffff; + if (cpustat != 0 && cpuquiet == 0) { + vaddr_t pc = tf->pc; + uint32_t insn = 0xffffffff; - if (tf->pc < 0) - guarded_read_4(pc, &insn); - else - copyin((void *)pc, &insn, sizeof insn); + if (tf->pc < 0) + guarded_read_4(pc, &insn); + else + copyin((void *)pc, &insn, sizeof insn); - printf(" cpu_stat %08x addr %08x pc %p insn %08x", - cpustat, imc_read(IMC_CPU_ERRADDR), (void *)pc, - insn); - } - if (giostat != 0) - printf(" gio_stat %08x addr %08x", - giostat, imc_read(IMC_GIO_ERRADDR)); - printf("\n"); + printf("bus error: cpu_stat %08x addr %08lx pc %p insn %08x\n", + cpustat, cpuaddr, (void *)pc, insn); + } + if (giostat != 0 && gioquiet == 0) { + printf("bus error: gio_stat %08x addr %08lx\n", + giostat, gioaddr); } if (cpustat != 0) diff --git a/sys/arch/sgi/localbus/imcreg.h b/sys/arch/sgi/localbus/imcreg.h index 70b80203396..0f7cfa7abb8 100644 --- a/sys/arch/sgi/localbus/imcreg.h +++ b/sys/arch/sgi/localbus/imcreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: imcreg.h,v 1.4 2014/03/27 21:24:22 miod Exp $ */ +/* $OpenBSD: imcreg.h,v 1.5 2014/07/02 17:44:35 miod Exp $ */ /* $NetBSD: imcreg.h,v 1.4 2005/12/11 12:18:52 christos Exp $ */ /* @@ -142,7 +142,18 @@ #define IMC_GIO_ERRADDR 0xf4 /* GIO error address */ #define IMC_GIO_ERRSTAT 0xfc /* GIO error status */ - +#define IMC_GIO_ERRSTAT_RD 0x00000100 /* read parity error */ +#define IMC_GIO_ERRSTAT_WR 0x00000200 /* write parity error */ +#define IMC_GIO_ERRSTAT_TMO 0x00000400 /* bus timeout */ +#define IMC_GIO_ERRSTAT_PROM 0x00000800 /* PROM write while disabled */ +#define IMC_GIO_ERRSTAT_ADDR 0x00001000 /* parity error during */ + /* address cycle */ +#define IMC_GIO_ERRSTAT_BC 0x00002000 /* parity error during */ + /* byte count cycle */ +#define IMC_GIO_ERRSTAT_PIO_RD 0x00004000 /* data parity error during */ + /* PIO read */ +#define IMC_GIO_ERRSTAT_PIO_WR 0x00008000 /* data parity error during */ + /* PIO write */ /* {CPU,GIO}_ERRSTAT bits in ECC mode */ #define IMC_ECC_ERRSTAT_FUW 0x00000001 /* fast mode uncached write */ #define IMC_ECC_ERRSTAT_MULTI 0x00000002 /* multi bit error */ diff --git a/sys/arch/sgi/sgi/ip22_machdep.c b/sys/arch/sgi/sgi/ip22_machdep.c index 39fd2f8d842..2326c50a9a4 100644 --- a/sys/arch/sgi/sgi/ip22_machdep.c +++ b/sys/arch/sgi/sgi/ip22_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip22_machdep.c,v 1.18 2014/05/19 21:18:42 miod Exp $ */ +/* $OpenBSD: ip22_machdep.c,v 1.19 2014/07/02 17:44:35 miod Exp $ */ /* * Copyright (c) 2012 Miodrag Vallat. @@ -352,7 +352,7 @@ ip22_video_setup() else return; - if (fbphys < GIO_ADDR_GFX || fbphys >= GIO_ADDR_END) + if (!IS_GIO_ADDRESS(fbphys)) return; /* |