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