Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc64 Avoid data_access_error trap panic when rea...



details:   https://anonhg.NetBSD.org/src/rev/313dc2ef2f1e
branches:  trunk
changeset: 787519:313dc2ef2f1e
user:      nakayama <nakayama%NetBSD.org@localhost>
date:      Fri Jun 21 20:09:58 2013 +0000

description:
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.

diffstat:

 sys/arch/sparc64/dev/psycho.c   |  14 ++++++++++++--
 sys/arch/sparc64/dev/pyro.c     |  17 ++++++++++++++---
 sys/arch/sparc64/dev/schizo.c   |  17 ++++++++++++++---
 sys/arch/sparc64/include/cpu.h  |   6 +++++-
 sys/arch/sparc64/sparc64/trap.c |  27 ++++++++++++++++++++++-----
 5 files changed, 67 insertions(+), 14 deletions(-)

diffs (204 lines):

diff -r 60ff917ae05e -r 313dc2ef2f1e sys/arch/sparc64/dev/psycho.c
--- a/sys/arch/sparc64/dev/psycho.c     Fri Jun 21 19:50:13 2013 +0000
+++ b/sys/arch/sparc64/dev/psycho.c     Fri Jun 21 20:09:58 2013 +0000
@@ -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 @@
 {
        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 @@
                                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__,
diff -r 60ff917ae05e -r 313dc2ef2f1e sys/arch/sparc64/dev/pyro.c
--- a/sys/arch/sparc64/dev/pyro.c       Fri Jun 21 19:50:13 2013 +0000
+++ b/sys/arch/sparc64/dev/pyro.c       Fri Jun 21 20:09:58 2013 +0000
@@ -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 @@
 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);
 }
diff -r 60ff917ae05e -r 313dc2ef2f1e sys/arch/sparc64/dev/schizo.c
--- a/sys/arch/sparc64/dev/schizo.c     Fri Jun 21 19:50:13 2013 +0000
+++ b/sys/arch/sparc64/dev/schizo.c     Fri Jun 21 20:09:58 2013 +0000
@@ -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 @@
 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);
 }
diff -r 60ff917ae05e -r 313dc2ef2f1e sys/arch/sparc64/include/cpu.h
--- a/sys/arch/sparc64/include/cpu.h    Fri Jun 21 19:50:13 2013 +0000
+++ b/sys/arch/sparc64/include/cpu.h    Fri Jun 21 20:09:58 2013 +0000
@@ -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 @@
        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 */
 };
 
diff -r 60ff917ae05e -r 313dc2ef2f1e sys/arch/sparc64/sparc64/trap.c
--- a/sys/arch/sparc64/sparc64/trap.c   Fri Jun 21 19:50:13 2013 +0000
+++ b/sys/arch/sparc64/sparc64/trap.c   Fri Jun 21 20:09:58 2013 +0000
@@ -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 @@
 #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);
 



Home | Main Index | Thread Index | Old Index