Implement bus_dmamap_sync properly.

dma_cachectl is now used only for DMAC array chain.
This commit is contained in:
minoura 2001-12-19 14:53:26 +00:00
parent 15c4d1fbda
commit 7a7e9cfe7b
4 changed files with 107 additions and 16 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fd.c,v 1.38 2001/11/25 00:38:50 minoura Exp $ */
/* $NetBSD: fd.c,v 1.39 2001/12/19 14:53:26 minoura Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -327,10 +327,6 @@ fdc_dmastart(fdc, read, addr, count)
DMAC_SCR_DAC_NO_COUNT),
(u_int8_t*) (fdc->sc_addr +
fddata)); /* XXX */
#if defined(M68040) || defined(M68060)
if (mmutype == MMU_68040)
dma_cachectl(addr, count);
#endif
dmac_start_xfer(fdc->sc_dmachan->ch_softc, fdc->sc_xfer);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: mha.c,v 1.25 2001/12/04 15:21:28 minoura Exp $ */
/* $NetBSD: mha.c,v 1.26 2001/12/19 14:53:26 minoura Exp $ */
/*-
* Copyright (c) 1996-1999 The NetBSD Foundation, Inc.
@ -1633,11 +1633,6 @@ mha_dataio_dma(dw, cw, sc, p, n)
#if MHA_DMA_SHORT_BUS_CYCLE == 1
if ((*(int *)&IODEVbase->io_sram[0xac]) & (1 << ((paddr_t)paddr >> 19)))
dw &= ~(1 << 3);
#endif
dma_cachectl((caddr_t) sc->sc_dmabuf, n);
#if 0
printf("(%x,%x)->(%x,%x)\n", p, n, paddr, n);
PCIA(); /* XXX */
#endif
sc->sc_pc[0x80 + (((long)paddr >> 16) & 0xFF)] = 0;
sc->sc_pc[0x180 + (((long)paddr >> 8) & 0xFF)] = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: bus.c,v 1.17 2001/09/28 12:36:50 chs Exp $ */
/* $NetBSD: bus.c,v 1.18 2001/12/19 14:53:26 minoura Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -52,8 +52,14 @@
#include <uvm/uvm_extern.h>
#include <m68k/cacheops.h>
#include <machine/bus.h>
#if defined(M68040) || defined(M68060)
static inline void dmasync_flush(bus_addr_t, bus_size_t);
static inline void dmasync_inval(bus_addr_t, bus_size_t);
#endif
int
x68k_bus_space_alloc(t, rstart, rend, size, alignment, boundary, flags,
bpap, bshp)
@ -318,6 +324,54 @@ x68k_bus_dmamap_unload(t, map)
map->dm_nsegs = 0;
}
#if defined(M68040) || defined(M68060)
static inline void
dmasync_flush(bus_addr_t addr, bus_size_t len)
{
bus_addr_t end = addr+len;
if (len <= 1024) {
addr = addr & ~0xF;
do {
DCFL(addr);
addr += 16;
} while (addr < end);
} else {
addr = m68k_trunc_page(addr);
do {
DCFP(addr);
addr += NBPG;
} while (addr < end);
}
}
static inline void
dmasync_inval(bus_addr_t addr, bus_size_t len)
{
bus_addr_t end = addr+len;
if (len <= 1024) {
addr = addr & ~0xF;
do {
DCFL(addr);
ICPL(addr);
addr += 16;
} while (addr < end);
} else {
addr = m68k_trunc_page(addr);
do {
DCPL(addr);
ICPP(addr);
addr += NBPG;
} while (addr < end);
}
}
#endif
/*
* Common function for DMA map synchronization. May be called
* by bus-specific DMA map synchronization functions.
@ -330,8 +384,50 @@ x68k_bus_dmamap_sync(t, map, offset, len, ops)
bus_size_t len;
int ops;
{
#if defined(M68040) || defined(M68060)
bus_dma_segment_t *ds = map->dm_segs;
bus_addr_t seg;
int i;
/* Nothing to do here. */
if ((ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_POSTWRITE)) == 0)
return;
#if defined(M68020) || defined(M68030)
if (mmutype != MMU_68040) {
if ((ops & BUS_DMASYNC_POSTWRITE) == 0)
return; /* no copyback cache */
ICIA(); /* no per-page/per-line control */
DCIA();
return;
}
#endif
if (offset >= map->dm_mapsize)
return; /* driver bug; warn it? */
if (offset+len > map->dm_mapsize)
len = map->dm_mapsize; /* driver bug; warn it? */
i = 0;
while (ds[i].ds_len <= offset) {
offset -= ds[i++].ds_len;
continue;
}
while (len > 0) {
seg = ds[i].ds_len - offset;
if (seg > len)
seg = len;
if (mmutype == MMU_68040 && (ops & BUS_DMASYNC_PREWRITE))
dmasync_flush(ds[i].ds_addr+offset, seg);
if (ops & BUS_DMASYNC_POSTREAD)
dmasync_inval(ds[i].ds_addr+offset, seg);
offset = 0;
len -= seg;
i++;
}
#else /* no 040/060 */
if ((ops & BUS_DMASYNC_POSTWRITE)) {
ICIA(); /* no per-page/per-line control */
DCIA();
}
#endif
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_machdep.c,v 1.23 2001/02/21 12:39:17 minoura Exp $ */
/* $NetBSD: sys_machdep.c,v 1.24 2001/12/19 14:53:26 minoura Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@ -200,14 +200,16 @@ cachectl1(req, addr, len, p)
* DMA cache control
*/
#if defined(M68040) || defined(M68060)
/*ARGSUSED1*/
int
dma_cachectl(addr, len)
caddr_t addr;
int len;
{
#if defined(M68040) || defined(M68060)
#if defined(M68020) || defined(M68030)
if (mmutype == MMU_68040) {
#endif
int inc = 0;
int pa = 0;
caddr_t end;
@ -237,10 +239,12 @@ dma_cachectl(addr, len)
pa += inc;
addr += inc;
} while (addr < end);
#if defined(M68020) || defined(M68030)
}
#endif /* M68040 || M68060 */
#endif
return(0);
}
#endif /* M68040 || M68060 */
int
sys_sysarch(p, v, retval)