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);
 

Reply via email to