diff options
| author | bouyer <bouyer@NetBSD.org> | 2008-06-28 17:23:01 +0000 |
|---|---|---|
| committer | bouyer <bouyer@NetBSD.org> | 2008-06-28 17:23:01 +0000 |
| commit | caba2baea2a9e6173fa749da4e624817f44edf71 (patch) | |
| tree | 0264194fc4ecb57ccc6b5f34d7d9d5d3f978afea | |
| parent | b4c1afd422fa9ce2b22fb7c29b99baee8edce85a (diff) | |
port-i386/38935: Add appropriate x86_lfence or x86_mfence calls to
bus_dmamap_sync(), depending on the BUS_DMASYNC flag. This makes sure
that the kernel reads data from main memory in the intended order.
| -rw-r--r-- | sys/arch/x86/x86/bus_dma.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/sys/arch/x86/x86/bus_dma.c b/sys/arch/x86/x86/bus_dma.c index 8d5fe54e1df..9130714874e 100644 --- a/sys/arch/x86/x86/bus_dma.c +++ b/sys/arch/x86/x86/bus_dma.c @@ -1,4 +1,4 @@ -/* $NetBSD: bus_dma.c,v 1.44 2008/06/13 09:53:46 bjs Exp $ */ +/* $NetBSD: bus_dma.c,v 1.45 2008/06/28 17:23:01 bouyer Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2007 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.44 2008/06/13 09:53:46 bjs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.45 2008/06/28 17:23:01 bouyer Exp $"); /* * The following is included because _bus_dma_uiomove is derived from @@ -722,7 +722,7 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, */ if (len == 0 || cookie == NULL || (cookie->id_flags & X86_DMA_IS_BOUNCING) == 0) - return; + goto end; switch (cookie->id_buftype) { case X86_DMA_BUFTYPE_LINEAR: @@ -844,6 +844,21 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, printf("unknown buffer type %d\n", cookie->id_buftype); panic("_bus_dmamap_sync"); } +end: + if (ops & (BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTWRITE)) { + /* + * from the memory POV a load can be reordered before a store + * (a load can fetch data from the write buffers, before + * data hits the cache or memory), a mfence avoids it. + */ + x86_mfence(); + } else if (ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_POSTREAD)) { + /* + * all past reads should have completed at before this point, + * and futur reads should not have started yet. + */ + x86_lfence(); + } } /* |
