summaryrefslogtreecommitdiffstats
path: root/sys/sparc64/pci
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2008-10-28 22:05:20 +0000
committermarius <marius@FreeBSD.org>2008-10-28 22:05:20 +0000
commit6d1fb102aad6fcea826a67f736e81d23ba535fa9 (patch)
treedb06eff5dc7b5ad057d74ef4550973675c82085d /sys/sparc64/pci
parent4e57a801475ee0dc3cfd53a524f9ed95d767a8a5 (diff)
downloadFreeBSD-src-6d1fb102aad6fcea826a67f736e81d23ba535fa9.zip
FreeBSD-src-6d1fb102aad6fcea826a67f736e81d23ba535fa9.tar.gz
- Turn off interrupts instead of only entering a critical section
while doing the block store workaround so we restore the correct floating-point registers state in case of nested floating-point operations resulting from nested interrupts. This allows the VIS-based block copy/zero functions to be used on machines requiring this workaround. Alternatively, we could take care of saving the floating-point registers here, which would be more inefficiently though and also involves turning off interrupts. - It turns out that the SCZ_PCI_DMA_SYNC register doesn't work like the TOMXMS_PCI_DMA_SYNC_PEND one (but more like the corresponding register in of Hummingbird and Sabre bridges) and writing the INO of the respective device to it causes a Safari bus error. However, due to the Schizo errata I-23, SCZ_PCI_DMA_SYNC can't be used as intended either, so remove consistent DMA syncing for Schzio bridges for now, which means that add-on cards with non-"sun4u compliant" (whatever that means exactly) PCI-PCI-bridges should be avoided until the proper workaround is implemented. [1] Reported by: Michael Moll [1]
Diffstat (limited to 'sys/sparc64/pci')
-rw-r--r--sys/sparc64/pci/schizo.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index 214fb92..7093507 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -175,7 +175,6 @@ struct schizo_dmasync {
driver_filter_t *sds_handler;
void *sds_arg;
void *sds_cookie;
- bus_size_t sds_syncreg;
uint64_t sds_syncval;
u_int sds_bswar;
};
@@ -955,25 +954,25 @@ schizo_dmasync(void *arg)
static u_char buf[VIS_BLOCKSIZE] __aligned(VIS_BLOCKSIZE);
struct schizo_dmasync *sds = arg;
struct schizo_softc *sc = sds->sds_sc;
- uint64_t reg;
+ register_t reg, s;
int timeout;
- SCHIZO_PCI_WRITE_8(sc, sds->sds_syncreg, sds->sds_syncval);
+ SCHIZO_PCI_WRITE_8(sc, TOMXMS_PCI_DMA_SYNC_PEND, sds->sds_syncval);
timeout = 1000000;
- for (; (SCHIZO_PCI_READ_8(sc, sds->sds_syncreg) &
+ for (; (SCHIZO_PCI_READ_8(sc, TOMXMS_PCI_DMA_SYNC_PEND) &
sds->sds_syncval) != 0;)
if (--timeout < 0)
panic("%s: DMA does not sync", __func__);
if (sds->sds_bswar != 0) {
- critical_enter();
+ s = intr_disable();
reg = rd(fprs);
wr(fprs, reg | FPRS_FEF, 0);
- __asm__ __volatile__("stda %%f0, [%0] %1"
+ __asm __volatile("stda %%f0, [%0] %1"
: : "r" (buf), "n" (ASI_BLK_COMMIT_S));
- wr(fprs, reg, 0);
membar(Sync);
- critical_exit();
+ wr(fprs, reg, 0);
+ intr_restore(s);
}
return (sds->sds_handler(sds->sds_arg));
}
@@ -1039,8 +1038,8 @@ schizo_setup_intr(device_t dev, device_t child, struct resource *ires,
}
/*
- * Schizo revision >= 2.3 (i.e. version >= 5) and Tomatillo bridges
- * need to be manually told to sync DMA writes.
+ * Tomatillo and XMITS bridges need to be told to sync DMA writes
+ * based on the INO of the respective device.
* Tomatillo revision <= 2.3 (i.e. version <= 4) bridges additionally
* need a block store as a workaround for a hardware bug.
* XXX setup of the wrapper and the contents of schizo_dmasync()
@@ -1049,15 +1048,12 @@ schizo_setup_intr(device_t dev, device_t child, struct resource *ires,
* is newbus'ified, so the wrapper isn't only applied for interrupt
* handlers but also for polling(4) callbacks.
*/
- if ((sc->sc_mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 5) ||
- sc->sc_mode == SCHIZO_MODE_TOM) {
+ if (sc->sc_mode == SCHIZO_MODE_TOM || sc->sc_mode == SCHIZO_MODE_XMS) {
sds = malloc(sizeof(*sds), M_DEVBUF, M_NOWAIT | M_ZERO);
if (sds == NULL)
return (ENOMEM);
sds->sds_sc = sc;
sds->sds_arg = arg;
- sds->sds_syncreg = sc->sc_mode == SCHIZO_MODE_SCZ ?
- SCZ_PCI_DMA_SYNC : TOMXMS_PCI_DMA_SYNC_PEND;
sds->sds_syncval = 1ULL << INTINO(vec);
if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4)
sds->sds_bswar = 1;
OpenPOWER on IntegriCloud