diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-08-23 16:56:19 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-08-23 16:56:19 +0000 |
commit | 3cdce6c7680cd4abc987f2e52bfd42e4e9408aba (patch) | |
tree | 6a11f32fa7a36b5af2660c1826b6c1a3bedd2a51 | |
parent | 025ada3dc16baad85340cb76893e771f9bc5bdc3 (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.h | 16 | ||||
-rw-r--r-- | sys/arch/sgi/localbus/macebus.c | 8 | ||||
-rw-r--r-- | sys/arch/sgi/pci/macepcibridge.c | 8 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/xbow.c | 7 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/xbridge.c | 51 |
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 */ |