TESTERS NEEDED: PCI trap improvements

John-Mark Gurney gurney_j at efn.org
Mon Jun 16 16:16:12 PDT 2003


Attached is a patch to trap reads from PCI configuration registers that
don't exist.  It doesn't use global variables now.

This will pave the way to integrating the PCI Multifunction patch to
make all multifuntion devices probe properly.

Thanks.

-- 
  John-Mark Gurney				Voice: +1 415 225 5579

     "All that I will do, has been done, All that I have, has not."
-------------- next part --------------
? conf/LINT
? conf/sp
Index: include/bus.h
===================================================================
RCS file: /home/ncvs/src/sys/sparc64/include/bus.h,v
retrieving revision 1.26
diff -u -r1.26 bus.h
--- include/bus.h	2003/05/30 20:40:33	1.26
+++ include/bus.h	2003/06/16 08:27:01
@@ -820,6 +820,36 @@
 	    bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2));
 }
 
+int fasword8(u_long asi, void *addr, uint8_t *val);
+static __inline int
+bus_space_readms_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+	u_int8_t *a)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "read", 1);
+	return (fasword8(bus_type_asi[t->bst_type], (caddr_t)(h + o), a));
+}
+
+int fasword16(u_long asi, void *addr, uint16_t *val);
+static __inline int
+bus_space_readms_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+	u_int16_t *a)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "readms", 2);
+	return (fasword16(bus_type_asi[t->bst_type], (caddr_t)(h + o), a));
+}
+
+int fasword32(u_long asi, void *addr, uint32_t *val);
+static __inline int
+bus_space_readms_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+	u_int32_t *a)
+{
+
+	__BUS_DEBUG_ACCESS(h, o, "readms", 4);
+	return (fasword32(bus_type_asi[t->bst_type], (caddr_t)(h + o), a));
+}
+
 /* Back-compat functions for old ISA drivers */
 extern bus_space_tag_t isa_io_bt;
 extern bus_space_handle_t isa_io_hdl;
Index: pci/psycho.c
===================================================================
RCS file: /home/ncvs/src/sys/sparc64/pci/psycho.c,v
retrieving revision 1.37
diff -u -r1.37 psycho.c
--- pci/psycho.c	2003/06/12 15:00:34	1.37
+++ pci/psycho.c	2003/06/16 08:27:04
@@ -879,33 +879,42 @@
 	bus_space_handle_t bh;
 	u_long offset = 0;
 	u_int32_t r, devid;
+	u_int8_t	byte;
+	u_int16_t	shrt;
+	u_int32_t	wrd;
 	int i;
 
-	/*
-	 * The psycho bridge does not tolerate accesses to unconfigured PCI
-	 * devices' or function's config space, so look up the device in the
-	 * firmware device tree first, and if it is not present, return a value
-	 * that will make the detection code think that there is no device here.
-	 * This is ugly...
-	 */
-	if (reg == 0 && ofw_pci_find_node(bus, slot, func) == 0)
-		return (0xffffffff);
 	sc = (struct psycho_softc *)device_get_softc(dev);
 	offset = PSYCHO_CONF_OFF(bus, slot, func, reg);
 	bh = sc->sc_bh[PCI_CS_CONFIG];
+#ifdef PSYCHO_DEBUG
+	printf("psycho_read_config expecting data error: %d.%d.%d: 0x%x\n",
+	    bus, slot, func, reg);
+#endif
 	switch (width) {
 	case 1:
-		r = bus_space_read_1(sc->sc_cfgt, bh, offset);
+		i = bus_space_readms_1(sc->sc_cfgt, bh, offset, &byte);
+		r = byte;
 		break;
 	case 2:
-		r = bus_space_read_2(sc->sc_cfgt, bh, offset);
+		i = bus_space_readms_2(sc->sc_cfgt, bh, offset, &shrt);
+		r = shrt;
 		break;
 	case 4:
-		r = bus_space_read_4(sc->sc_cfgt, bh, offset);
+		i = bus_space_readms_4(sc->sc_cfgt, bh, offset, &wrd);
+		r = wrd;
 		break;
 	default:
 		panic("psycho_read_config: bad width");
 	}
+
+	if (i) {
+#ifdef PSYCHO_DEBUG
+		printf("read data error trapped\n");
+#endif
+		r = -1;
+	}
+
 	if (reg == PCIR_INTPIN && r == 0) {
 		/* Check for DQT_BAD_INTPIN quirk. */
 		devid = psycho_read_config(dev, bus, slot, func,
Index: sparc64/support.S
===================================================================
RCS file: /home/ncvs/src/sys/sparc64/sparc64/support.S,v
retrieving revision 1.25
diff -u -r1.25 support.S
--- sparc64/support.S	2003/04/29 00:53:13	1.25
+++ sparc64/support.S	2003/06/16 08:27:04
@@ -527,6 +527,59 @@
 	 mov	-1, %o0
 END(fsfault)
 
+	.globl	fas_nofault_begin
+	.globl	fasword32, fasword16, fasword8
+fas_nofault_begin:
+
+/*
+ * int fasword32(u_long asi, uint64_t addr, uint32_t *val)
+ */
+ENTRY(fasword32)
+	wr	%o0, 0, %asi
+	membar	#Sync
+	lduwa	[%o1] %asi, %o3
+	membar	#Sync
+	stw	%o3, [%o2]
+	retl
+	clr	%o0
+END(fasword32)
+
+/*
+ * int fasword16(u_long asi, uint64_t addr, uint16_t *val)
+ */
+ENTRY(fasword16)
+	wr	%o0, 0, %asi
+	membar	#Sync
+	lduha	[%o1] %asi, %o3
+	membar	#Sync
+	sth	%o3, [%o2]
+	retl
+	clr	%o0
+END(fasword16)
+
+/*
+ * int fasword8(u_long asi, uint64_t addr, uint8_t *val)
+ */
+ENTRY(fasword8)
+	wr	%o0, 0, %asi
+	membar	#Sync
+	lduba	[%o1] %asi, %o3
+	membar	#Sync
+	stb	%o3, [%o2]
+	retl
+	clr	%o0
+END(fasword8)
+
+	.globl	fas_nofault_end
+fas_nofault_end:
+	nop
+
+	.globl	fas_fault
+ENTRY(fas_fault)
+	retl
+	 mov	-1, %o0
+END(fas_fault)
+
 	.globl	fpu_fault_begin
 fpu_fault_begin:
 	nop
Index: sparc64/trap.c
===================================================================
RCS file: /home/ncvs/src/sys/sparc64/sparc64/trap.c,v
retrieving revision 1.63
diff -u -r1.63 trap.c
--- sparc64/trap.c	2003/06/15 00:31:24	1.63
+++ sparc64/trap.c	2003/06/16 08:27:05
@@ -101,6 +101,10 @@
 extern char fs_nofault_intr_begin[];
 extern char fs_nofault_intr_end[];
 
+extern char fas_fault[];
+extern char fas_nofault_begin[];
+extern char fas_nofault_end[];
+
 extern char *syscallnames[];
 
 const char *trap_msg[] = {
@@ -328,6 +332,27 @@
 				}
 			}
 			error = 1;	
+			break;
+		case T_DATA_ERROR:
+			/*
+			 * handle PCI poke/peek as per UltraSPARC IIi
+			 * User's Manual 16.2.1.
+			 *
+			 * XXX - We really should make sure that tpc is
+			 * pointing to the membar #Sync we are expecting.
+			 */
+#define MEMBARSYNC_INST	((u_int32_t)0x8143e040)
+			if ((char *)tf->tf_tpc > fas_nofault_begin &&
+			    (char *)tf->tf_tpc < fas_nofault_end &&
+			    *(u_int32_t *)tf->tf_tpc == MEMBARSYNC_INST &&
+			    ((u_int32_t *)tf->tf_tpc)[-2] == MEMBARSYNC_INST) {
+				tf->tf_tpc = (uintptr_t)(((u_int32_t *)fas_fault) - 1);
+				tf->tf_tnpc = (uintptr_t)fas_fault;
+				error = 0;
+				break;
+			}
+#undef MEMBARSYNC_INST
+			error = 1;
 			break;
 		default:
 			error = 1;


More information about the freebsd-sparc64 mailing list