Module Name: src Committed By: nakayama Date: Fri Jun 21 20:09:59 UTC 2013
Modified Files: src/sys/arch/sparc64/dev: psycho.c pyro.c schizo.c src/sys/arch/sparc64/include: cpu.h src/sys/arch/sparc64/sparc64: trap.c Log Message: Avoid data_access_error trap panic when reading unused PCI configuration space. This method is described in UltraSPARC IIi User's Manual "16.2.1 Probing PCI during boot using deferred errors", and refer to the implementation of OpenBSD. To generate a diff of this commit: cvs rdiff -u -r1.112 -r1.113 src/sys/arch/sparc64/dev/psycho.c cvs rdiff -u -r1.12 -r1.13 src/sys/arch/sparc64/dev/pyro.c cvs rdiff -u -r1.30 -r1.31 src/sys/arch/sparc64/dev/schizo.c cvs rdiff -u -r1.101 -r1.102 src/sys/arch/sparc64/include/cpu.h cvs rdiff -u -r1.177 -r1.178 src/sys/arch/sparc64/sparc64/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc64/dev/psycho.c diff -u src/sys/arch/sparc64/dev/psycho.c:1.112 src/sys/arch/sparc64/dev/psycho.c:1.113 --- src/sys/arch/sparc64/dev/psycho.c:1.112 Fri Jan 27 18:53:03 2012 +++ src/sys/arch/sparc64/dev/psycho.c Fri Jun 21 20:09:58 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: psycho.c,v 1.112 2012/01/27 18:53:03 para Exp $ */ +/* $NetBSD: psycho.c,v 1.113 2013/06/21 20:09:58 nakayama Exp $ */ /* * Copyright (c) 1999, 2000 Matthew R. Green @@ -55,7 +55,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.112 2012/01/27 18:53:03 para Exp $"); +__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.113 2013/06/21 20:09:58 nakayama Exp $"); #include "opt_ddb.h" @@ -1350,7 +1350,9 @@ psycho_pci_conf_read(pci_chipset_tag_t p { struct psycho_pbm *pp = pc->cookie; struct psycho_softc *sc = pp->pp_sc; + struct cpu_info *ci = curcpu(); pcireg_t val = (pcireg_t)~0; + int s; DPRINTF(PDB_CONF, ("%s: tag %lx reg %x ", __func__, (long)tag, reg)); @@ -1362,8 +1364,16 @@ psycho_pci_conf_read(pci_chipset_tag_t p PCITAG_OFFSET(tag) + reg), (int)PCITAG_OFFSET(tag) + reg)); + s = splhigh(); + ci->ci_pci_probe = true; + membar_Sync(); val = bus_space_read_4(sc->sc_configtag, sc->sc_configaddr, PCITAG_OFFSET(tag) + reg); + membar_Sync(); + if (ci->ci_pci_fault) + val = (pcireg_t)~0; + ci->ci_pci_probe = ci->ci_pci_fault = false; + splx(s); } #ifdef DEBUG else DPRINTF(PDB_CONF, ("%s: bogus pcitag %x\n", __func__, Index: src/sys/arch/sparc64/dev/pyro.c diff -u src/sys/arch/sparc64/dev/pyro.c:1.12 src/sys/arch/sparc64/dev/pyro.c:1.13 --- src/sys/arch/sparc64/dev/pyro.c:1.12 Sat Oct 27 17:18:12 2012 +++ src/sys/arch/sparc64/dev/pyro.c Fri Jun 21 20:09:58 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: pyro.c,v 1.12 2012/10/27 17:18:12 chs Exp $ */ +/* $NetBSD: pyro.c,v 1.13 2013/06/21 20:09:58 nakayama Exp $ */ /* from: $OpenBSD: pyro.c,v 1.20 2010/12/05 15:15:14 kettenis Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pyro.c,v 1.12 2012/10/27 17:18:12 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pyro.c,v 1.13 2013/06/21 20:09:58 nakayama Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -290,12 +290,23 @@ pcireg_t pyro_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) { struct pyro_pbm *pp = pc->cookie; + struct cpu_info *ci = curcpu(); pcireg_t val = (pcireg_t)~0; + int s; DPRINTF(PDB_CONF, ("%s: tag %lx reg %x ", __func__, (long)tag, reg)); - if (PCITAG_NODE(tag) != -1) + if (PCITAG_NODE(tag) != -1) { + s = splhigh(); + ci->ci_pci_probe = true; + membar_Sync(); val = bus_space_read_4(pp->pp_cfgt, pp->pp_cfgh, (PCITAG_OFFSET(tag) << 4) + reg); + membar_Sync(); + if (ci->ci_pci_fault) + val = (pcireg_t)~0; + ci->ci_pci_probe = ci->ci_pci_fault = false; + splx(s); + } DPRINTF(PDB_CONF, (" returning %08x\n", (u_int)val)); return (val); } Index: src/sys/arch/sparc64/dev/schizo.c diff -u src/sys/arch/sparc64/dev/schizo.c:1.30 src/sys/arch/sparc64/dev/schizo.c:1.31 --- src/sys/arch/sparc64/dev/schizo.c:1.30 Sat Oct 27 17:18:12 2012 +++ src/sys/arch/sparc64/dev/schizo.c Fri Jun 21 20:09:58 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: schizo.c,v 1.30 2012/10/27 17:18:12 chs Exp $ */ +/* $NetBSD: schizo.c,v 1.31 2013/06/21 20:09:58 nakayama Exp $ */ /* $OpenBSD: schizo.c,v 1.55 2008/08/18 20:29:37 brad Exp $ */ /* @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: schizo.c,v 1.30 2012/10/27 17:18:12 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: schizo.c,v 1.31 2013/06/21 20:09:58 nakayama Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -491,12 +491,23 @@ pcireg_t schizo_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) { struct schizo_pbm *sp = pc->cookie; + struct cpu_info *ci = curcpu(); pcireg_t val = (pcireg_t)~0; + int s; DPRINTF(SDB_CONF, ("%s: tag %lx reg %x ", __func__, (long)tag, reg)); - if (PCITAG_NODE(tag) != -1) + if (PCITAG_NODE(tag) != -1) { + s = splhigh(); + ci->ci_pci_probe = true; + membar_Sync(); val = bus_space_read_4(sp->sp_cfgt, sp->sp_cfgh, PCITAG_OFFSET(tag) + reg); + membar_Sync(); + if (ci->ci_pci_fault) + val = (pcireg_t)~0; + ci->ci_pci_probe = ci->ci_pci_fault = false; + splx(s); + } DPRINTF(SDB_CONF, (" returning %08x\n", (u_int)val)); return (val); } Index: src/sys/arch/sparc64/include/cpu.h diff -u src/sys/arch/sparc64/include/cpu.h:1.101 src/sys/arch/sparc64/include/cpu.h:1.102 --- src/sys/arch/sparc64/include/cpu.h:1.101 Mon Feb 4 22:19:43 2013 +++ src/sys/arch/sparc64/include/cpu.h Fri Jun 21 20:09:59 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.101 2013/02/04 22:19:43 macallan Exp $ */ +/* $NetBSD: cpu.h,v 1.102 2013/06/21 20:09:59 nakayama Exp $ */ /* * Copyright (c) 1992, 1993 @@ -174,6 +174,10 @@ struct cpu_info { pte_t *ci_tsb_dmmu; pte_t *ci_tsb_immu; + /* probe fault in PCI config space reads */ + bool ci_pci_probe; + bool ci_pci_fault; + volatile void *ci_ddb_regs; /* DDB regs */ }; Index: src/sys/arch/sparc64/sparc64/trap.c diff -u src/sys/arch/sparc64/sparc64/trap.c:1.177 src/sys/arch/sparc64/sparc64/trap.c:1.178 --- src/sys/arch/sparc64/sparc64/trap.c:1.177 Wed Aug 1 09:07:35 2012 +++ src/sys/arch/sparc64/sparc64/trap.c Fri Jun 21 20:09:59 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.177 2012/08/01 09:07:35 martin Exp $ */ +/* $NetBSD: trap.c,v 1.178 2013/06/21 20:09:59 nakayama Exp $ */ /* * Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved. @@ -50,7 +50,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.177 2012/08/01 09:07:35 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.178 2013/06/21 20:09:59 nakayama Exp $"); #include "opt_ddb.h" #include "opt_multiprocessor.h" @@ -1288,14 +1288,31 @@ data_access_error(struct trapframe64 *tf #endif curcpu()->ci_data.cpu_ntrap++; + pc = tf->tf_pc; + tstate = tf->tf_tstate; + + /* + * Catch PCI config space reads. + */ + if (curcpu()->ci_pci_probe) { +#ifdef DIAGNOSTIC + printf("data_access_error in pci_conf_read: pc=%lx addr=%lx\n", + pc, afva); +#endif + curcpu()->ci_pci_fault = true; + /* + * The contents of TNPC are undefined, so make it points to + * the next instruction. + */ + tf->tf_npc = pc + 4; + return; + } + l = curlwp; pcb = lwp_getpcb(l); LWP_CACHE_CREDS(l, l->l_proc); sticks = l->l_proc->p_sticks; - pc = tf->tf_pc; - tstate = tf->tf_tstate; - printf("data error type %x sfsr=%lx sfva=%lx afsr=%lx afva=%lx tf=%p\n", type, sfsr, sfva, afsr, afva, tf);