diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-18 20:48:56 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-18 20:48:56 +0000 |
commit | a21e48ecc1227742fb0e02b4d8ee2342fb72b97c (patch) | |
tree | a2a4c4a63c4ef8bde6c1810da69c5b3c22bee4dd | |
parent | 975a37533326b572d52e5b0c92855b5eedd3fb65 (diff) |
Better bus_dmamap_sync() routine, lets vsbic(4) run on 68060 systems, so
let it attach on them now.
-rw-r--r-- | sys/arch/mvme68k/dev/vsbic.c | 8 | ||||
-rw-r--r-- | sys/arch/mvme68k/mvme68k/bus_dma.c | 70 |
2 files changed, 48 insertions, 30 deletions
diff --git a/sys/arch/mvme68k/dev/vsbic.c b/sys/arch/mvme68k/dev/vsbic.c index b4f72b79d93..ba1c32c2147 100644 --- a/sys/arch/mvme68k/dev/vsbic.c +++ b/sys/arch/mvme68k/dev/vsbic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vsbic.c,v 1.1 2009/02/17 22:28:41 miod Exp $ */ +/* $OpenBSD: vsbic.c,v 1.2 2009/02/18 20:48:53 miod Exp $ */ /* * Copyright (c) 2008, 2009 Miodrag Vallat. @@ -426,7 +426,7 @@ struct cfdriver vsbic_cd = { struct scsi_adapter vsbic_swtch = { vsbic_scsicmd, - minphys + scsi_minphys }; struct scsi_device vsbic_scsidev = { @@ -448,10 +448,6 @@ vsbic_match(struct device *device, void *cf, void *args) int rc; uint8_t id; - /* XXX does not work on 68060 yet, likely a cache handling bug */ - if (mmutype == MMU_68060) - return 0; - if (bus_space_map(iot, ca->ca_paddr, MVME327_CSR_SIZE, 0, &ioh) != 0) return 0; diff --git a/sys/arch/mvme68k/mvme68k/bus_dma.c b/sys/arch/mvme68k/mvme68k/bus_dma.c index fd5ae7f3920..cdb73e4fc75 100644 --- a/sys/arch/mvme68k/mvme68k/bus_dma.c +++ b/sys/arch/mvme68k/mvme68k/bus_dma.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bus_dma.c,v 1.1 2009/02/17 22:28:41 miod Exp $ */ +/* $OpenBSD: bus_dma.c,v 1.2 2009/02/18 20:48:55 miod Exp $ */ /* $NetBSD: bus_dma.c,v 1.2 2001/06/10 02:31:25 briggs Exp $ */ /*- @@ -55,7 +55,7 @@ int _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *, int _bus_dmamem_alloc_range(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t, bus_dma_segment_t *, int, int *, int, paddr_t, paddr_t); -void cachectl_pa(paddr_t, psize_t, int); +int cachectl_pa(paddr_t, psize_t, int); /* * Common function for DMA map creation. May be called by bus-specific @@ -426,11 +426,8 @@ bus_dmamap_sync(t, map, offset, len, op) u_int nsegs; bus_dma_segment_t *seg; - if (op & BUS_DMASYNC_PREREAD) - op = CC_PURGE; - else if (op & BUS_DMASYNC_PREWRITE) - op = CC_FLUSH; - else + /* nothing to do for POSTWRITE */ + if ((op & ~BUS_DMASYNC_POSTWRITE) == 0) return; nsegs = map->dm_nsegs; @@ -447,7 +444,8 @@ bus_dmamap_sync(t, map, offset, len, op) if (sublen > len) sublen = len; - cachectl_pa(addr, sublen, op); + if (cachectl_pa(addr, sublen, op) != 0) + break; offset = 0; len -= sublen; @@ -680,49 +678,73 @@ _bus_dmamem_alloc_range(t, size, alignment, boundary, segs, nsegs, rsegs, } /* - * A variant of cachectl(), but which directly takes physical addresses, and - * only CC_PURGE or CC_FLUSH. + * Helper function for bus_dmamap_sync(). Returns nonzero if the whole + * cache has been affected. */ -void -cachectl_pa(paddr_t pa, psize_t len, int req) +int +cachectl_pa(paddr_t pa, psize_t len, int op) { #if defined(M68040) || defined(M68060) if (mmutype <= MMU_68040) { int inc; paddr_t end; - if (len > 2 * PAGE_SIZE) { + /* + * 68040 and 68060 only have the ``write back and + * invalidate'' (flush) and ``invalidate'' cache operations. + * + * The logic is thus: + * BUS_DMASYNC_PREREAD: flush D$, purge I$ + * BUS_DMASYNC_PREWRITE: flush D$ (only write back necessary) + * BUS_DMASYNC_POSTREAD: purge D$ and I$ + */ + + /* + * If the size is larger than two pages, don't try + * to be smart and operate on the whole cache. + * Remember the largest L1 cache is 8KB anyway (on 68060). + */ + if (len >= 2 * PAGE_SIZE) { DCFA(); - return; + if (op & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD)) + ICPA(); + return 1; } end = pa + len; if (len <= 1024) { - if (((pa | len) & 0x0f) != 0) - req = CC_FLUSH; pa = pa & ~0x0f; inc = 16; } else { - if (((pa | len) & PAGE_MASK) != 0) - req = CC_FLUSH; pa = pa & ~PAGE_MASK; inc = PAGE_SIZE; } do { - if (req == CC_PURGE) { + if (op & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)) { + if (inc == 16) + DCFL(pa); + else + DCFP(pa); + } else { if (inc == 16) DCPL(pa); else DCPP(pa); - } else { + } + if (op & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD)) { if (inc == 16) - DCFL(pa); + ICPL(pa); else - DCFP(pa); + ICPP(pa); } pa += inc; } while (pa < end); - } else + + return 0; + } #endif - DCIA(); + + DCIA(); + ICIA(); + return 1; } |