summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2010-08-23 16:56:19 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2010-08-23 16:56:19 +0000
commit3cdce6c7680cd4abc987f2e52bfd42e4e9408aba (patch)
tree6a11f32fa7a36b5af2660c1826b6c1a3bedd2a51
parent025ada3dc16baad85340cb76893e771f9bc5bdc3 (diff)
Implement bus_space_barrier() on sgi; on xbridge, this will also flush
the pci write buffers.
-rw-r--r--sys/arch/sgi/include/bus.h16
-rw-r--r--sys/arch/sgi/localbus/macebus.c8
-rw-r--r--sys/arch/sgi/pci/macepcibridge.c8
-rw-r--r--sys/arch/sgi/xbow/xbow.c7
-rw-r--r--sys/arch/sgi/xbow/xbridge.c51
5 files changed, 77 insertions, 13 deletions
diff --git a/sys/arch/sgi/include/bus.h b/sys/arch/sgi/include/bus.h
index 9772ca857f2..11231ce7429 100644
--- a/sys/arch/sgi/include/bus.h
+++ b/sys/arch/sgi/include/bus.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus.h,v 1.23 2010/04/04 11:24:30 miod Exp $ */
+/* $OpenBSD: bus.h,v 1.24 2010/08/23 16:56:15 miod Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB Sweden. All rights reserved.
@@ -83,6 +83,8 @@ struct mips_bus_space {
int (*_space_subregion)(bus_space_tag_t, bus_space_handle_t,
bus_size_t, bus_size_t, bus_space_handle_t *);
void * (*_space_vaddr)(bus_space_tag_t, bus_space_handle_t);
+ void (*_space_barrier)(bus_space_tag_t, bus_space_handle_t,
+ bus_size_t, bus_size_t, int);
};
#define bus_space_read_1(t, h, o) (*(t)->_space_read_1)((t), (h), (o))
@@ -293,8 +295,16 @@ bus_space_copy_8(void *v, bus_space_handle_t h1, bus_size_t o1,
* bus_size_t len, int flags);
*
*/
-#define bus_space_barrier(t, h, o, l, f) \
- ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
+static __inline void
+bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offs,
+ bus_size_t len, int flags)
+{
+ if (t->_space_barrier != NULL)
+ (*(t)->_space_barrier)(t, h, offs, len, flags);
+ else
+ __asm__ __volatile__ ("sync" ::: "memory");
+}
+
#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
diff --git a/sys/arch/sgi/localbus/macebus.c b/sys/arch/sgi/localbus/macebus.c
index 349dc3da8ee..1c2421b4b8b 100644
--- a/sys/arch/sgi/localbus/macebus.c
+++ b/sys/arch/sgi/localbus/macebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: macebus.c,v 1.56 2009/11/25 17:39:51 syuu Exp $ */
+/* $OpenBSD: macebus.c,v 1.57 2010/08/23 16:56:18 miod Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -118,7 +118,8 @@ bus_space_t macebus_tag = {
mace_read_raw_4, mace_write_raw_4,
mace_read_raw_8, mace_write_raw_8,
mace_space_map, mace_space_unmap, mace_space_region,
- mace_space_vaddr
+ mace_space_vaddr,
+ NULL
};
bus_space_t crimebus_tag = {
@@ -132,7 +133,8 @@ bus_space_t crimebus_tag = {
mace_read_raw_4, mace_write_raw_4,
mace_read_raw_8, mace_write_raw_8,
mace_space_map, mace_space_unmap, mace_space_region,
- mace_space_vaddr
+ mace_space_vaddr,
+ NULL
};
bus_space_handle_t crime_h;
diff --git a/sys/arch/sgi/pci/macepcibridge.c b/sys/arch/sgi/pci/macepcibridge.c
index 5feaa065973..23676894114 100644
--- a/sys/arch/sgi/pci/macepcibridge.c
+++ b/sys/arch/sgi/pci/macepcibridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: macepcibridge.c,v 1.38 2010/04/06 19:12:34 miod Exp $ */
+/* $OpenBSD: macepcibridge.c,v 1.39 2010/08/23 16:56:18 miod Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -131,7 +131,8 @@ bus_space_t mace_pcibbus_mem_tag = {
mace_pcib_read_raw_4, mace_pcib_write_raw_4,
mace_pcib_read_raw_8, mace_pcib_write_raw_8,
mace_pcib_space_map, mace_pcib_space_unmap, mace_pcib_space_region,
- mace_pcib_space_vaddr
+ mace_pcib_space_vaddr,
+ NULL
};
bus_space_t mace_pcibbus_io_tag = {
@@ -145,7 +146,8 @@ bus_space_t mace_pcibbus_io_tag = {
mace_pcib_read_raw_4, mace_pcib_write_raw_4,
mace_pcib_read_raw_8, mace_pcib_write_raw_8,
mace_pcib_space_map, mace_pcib_space_unmap, mace_pcib_space_region,
- mace_pcib_space_vaddr
+ mace_pcib_space_vaddr,
+ NULL
};
/*
diff --git a/sys/arch/sgi/xbow/xbow.c b/sys/arch/sgi/xbow/xbow.c
index 61746ecd4b0..0f40ac9ef01 100644
--- a/sys/arch/sgi/xbow/xbow.c
+++ b/sys/arch/sgi/xbow/xbow.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xbow.c,v 1.29 2010/04/06 19:02:57 miod Exp $ */
+/* $OpenBSD: xbow.c,v 1.30 2010/08/23 16:56:18 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -137,8 +137,9 @@ static const bus_space_t xbowbus_tag = {
xbow_write_raw_8,
xbow_space_map,
xbow_space_unmap,
- xbow_space_region
-
+ xbow_space_region,
+ xbow_space_vaddr,
+ NULL
};
/*
diff --git a/sys/arch/sgi/xbow/xbridge.c b/sys/arch/sgi/xbow/xbridge.c
index 39e6222d2c8..188fcc047e8 100644
--- a/sys/arch/sgi/xbow/xbridge.c
+++ b/sys/arch/sgi/xbow/xbridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xbridge.c,v 1.73 2010/08/23 16:55:07 miod Exp $ */
+/* $OpenBSD: xbridge.c,v 1.74 2010/08/23 16:56:18 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -254,6 +254,9 @@ int xbridge_space_region_io(bus_space_tag_t, bus_space_handle_t,
int xbridge_space_region_mem(bus_space_tag_t, bus_space_handle_t,
bus_size_t, bus_size_t, bus_space_handle_t *);
+void xbridge_space_barrier(bus_space_tag_t, bus_space_handle_t,
+ bus_size_t, bus_size_t, int);
+
int xbridge_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *,
bus_size_t, struct proc *, int, paddr_t *, int *, int);
void xbridge_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
@@ -544,6 +547,7 @@ xbpci_attach(struct device *parent, struct device *self, void *aux)
xb->xb_mem_bus_space->_space_write_raw_4 = xbridge_write_raw_4;
xb->xb_mem_bus_space->_space_read_raw_8 = xbridge_read_raw_8;
xb->xb_mem_bus_space->_space_write_raw_8 = xbridge_write_raw_8;
+ xb->xb_mem_bus_space->_space_barrier = xbridge_space_barrier;
bcopy(xb->xb_regt, xb->xb_io_bus_space, sizeof(*xb->xb_io_bus_space));
xb->xb_io_bus_space->bus_private = xb;
@@ -559,6 +563,7 @@ xbpci_attach(struct device *parent, struct device *self, void *aux)
xb->xb_io_bus_space->_space_write_raw_4 = xbridge_write_raw_4;
xb->xb_io_bus_space->_space_read_raw_8 = xbridge_read_raw_8;
xb->xb_io_bus_space->_space_write_raw_8 = xbridge_write_raw_8;
+ xb->xb_io_bus_space->_space_barrier = xbridge_space_barrier;
xb->xb_dmat = malloc(sizeof (*xb->xb_dmat), M_DEVBUF, M_NOWAIT);
if (xb->xb_dmat == NULL)
@@ -1587,6 +1592,50 @@ xbridge_space_region_mem(bus_space_tag_t t, bus_space_handle_t bsh,
return 0;
}
+void
+xbridge_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offs,
+ bus_size_t len, int flags)
+{
+ struct xbpci_softc *xb = (struct xbpci_softc *)t->bus_private;
+ bus_addr_t bpa, start, end;
+ uint d, devmin, devmax;
+
+ __asm__ __volatile__ ("sync" ::: "memory");
+
+ if (flags & BUS_SPACE_BARRIER_WRITE) {
+ /*
+ * Try to figure out which device we are working for, and
+ * flush its PCI write buffer.
+ * This is ugly; we really need to be able to provide a
+ * different bus_space_tag_t to each slot, to be able
+ * to tell them apart.
+ */
+ if (t->_space_map == xbridge_space_map_devio) {
+ bpa = (bus_addr_t)h - xb->xb_regt->bus_base;
+ for (d = 0; d < xb->xb_nslots; d++) {
+ start = PIC_DEVIO_OFFS(xb->xb_busno, d);
+ end = start + BRIDGE_DEVIO_SIZE(d);
+ if (bpa >= start && bpa < end)
+ break;
+ }
+ devmin = d;
+ devmax = d + 1;
+ /* should not happen */
+ if (d == xb->xb_nslots) {
+ devmin = 0;
+ devmax = xb->xb_nslots;
+ }
+ } else {
+ /* nothing better came up my sleeve... */
+ devmin = 0;
+ devmax = xb->xb_nslots;
+ }
+ for (d = devmin; d < devmax; d++)
+ xbridge_read_reg(xb, BRIDGE_DEVICE_WBFLUSH(d));
+ (void)xbridge_read_reg(xb, WIDGET_TFLUSH);
+ }
+}
+
/*
********************* bus_dma helpers
*/