diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-01-20 16:26:54 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-01-20 16:26:54 +0000 |
commit | b66f071513c2b2fdec943187190a5d73d8576f55 (patch) | |
tree | 4440832ff7096a8b90bea63303fcdef0aa4264a2 /sys/arch/sparc64/dev | |
parent | 51407b5525d8285b5c186dd3ca912056e93a69e8 (diff) |
Do not panic on non-fatal iommu errors.
Diffstat (limited to 'sys/arch/sparc64/dev')
-rw-r--r-- | sys/arch/sparc64/dev/schizo.c | 23 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/schizoreg.h | 11 |
2 files changed, 31 insertions, 3 deletions
diff --git a/sys/arch/sparc64/dev/schizo.c b/sys/arch/sparc64/dev/schizo.c index 4624cd0246b..10fc53ba859 100644 --- a/sys/arch/sparc64/dev/schizo.c +++ b/sys/arch/sparc64/dev/schizo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: schizo.c,v 1.43 2007/01/16 11:10:53 kettenis Exp $ */ +/* $OpenBSD: schizo.c,v 1.44 2007/01/20 16:26:53 kettenis Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -288,7 +288,7 @@ schizo_pci_error(void *vpbm) { struct schizo_pbm *sp = vpbm; struct schizo_softc *sc = sp->sp_sc; - u_int64_t afsr, afar, ctrl, tfar; + u_int64_t afsr, afar, ctrl; u_int32_t csr; afsr = schizo_pbm_read(sp, SCZ_PCI_AFSR); @@ -305,17 +305,36 @@ schizo_pci_error(void *vpbm) printf("PCICSR=%lb\n", csr, PCI_COMMAND_STATUS_BITS); if (ctrl & SCZ_PCICTRL_MMU_ERR) { + u_int32_t ctrl, tfar; + ctrl = schizo_pbm_read(sp, SCZ_PCI_IOMMU_CTRL); printf("IOMMUCTRL=%lx\n", ctrl); + if ((ctrl & TOM_IOMMU_ERR) == 0) + goto clear_error; + if (sc->sc_tomatillo) { tfar = schizo_pbm_read(sp, TOM_PCI_IOMMU_TFAR); printf("IOMMUTFAR=%lx\n", tfar); } + + /* These are non-fatal if target abort was signalled. */ + if ((ctrl & TOM_IOMMU_ERR_MASK) == TOM_IOMMU_INV_ERR || + ctrl & TOM_IOMMU_ILLTSBTBW_ERR || + ctrl & TOM_IOMMU_BADVA_ERR) { + if (csr & PCI_STATUS_TARGET_TARGET_ABORT) { + schizo_pbm_write(sp, SCZ_PCI_IOMMU_CTRL, ctrl); + goto clear_error; + } + } } panic("%s: fatal", sc->sc_dv.dv_xname); + clear_error: + schizo_cfg_write(sp, PCI_COMMAND_STATUS_REG, csr); + schizo_pbm_write(sp, SCZ_PCI_CTRL, ctrl); + schizo_pbm_write(sp, SCZ_PCI_AFSR, afsr); return (1); } diff --git a/sys/arch/sparc64/dev/schizoreg.h b/sys/arch/sparc64/dev/schizoreg.h index 10ac5957848..f55b6c7cd66 100644 --- a/sys/arch/sparc64/dev/schizoreg.h +++ b/sys/arch/sparc64/dev/schizoreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: schizoreg.h,v 1.17 2007/01/14 16:18:56 kettenis Exp $ */ +/* $OpenBSD: schizoreg.h,v 1.18 2007/01/20 16:26:53 kettenis Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -232,6 +232,15 @@ struct schizo_regs { #define SCZ_PCIDIAG_I_PIODPAR (1UL << 2UL) /* invert pio data parity */ #define SCZ_PCIDIAG_I_PIOAPAR (1UL << 1UL) /* invert pio addr parity */ +#define TOM_IOMMU_ERR (1UL << 24) +#define TOM_IOMMU_ERR_MASK (3UL << 25) +#define TOM_IOMMU_PROT_ERR (0UL << 25) +#define TOM_IOMMU_INV_ERR (1UL << 25) +#define TOM_IOMMU_TO_ERR (2UL << 25) +#define TOM_IOMMU_ECC_ERR (3UL << 25) +#define TOM_IOMMU_ILLTSBTBW_ERR (1UL << 27) +#define TOM_IOMMU_BADVA_ERR (1UL << 28) + #define SCZ_PBM_A_REGS (0x600000UL - 0x400000UL) #define SCZ_PBM_B_REGS (0x700000UL - 0x400000UL) |