summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1996-01-27 02:33:48 +0000
committerbde <bde@FreeBSD.org>1996-01-27 02:33:48 +0000
commitb367666afd7d12a7802e173170448bcd9f13d89b (patch)
tree89c9bb6e9d083a3f547ce32b8b591b9a773993b4 /sys/amd64
parentae64a265a89555df45a3ad36f4cb2ef096386a30 (diff)
downloadFreeBSD-src-b367666afd7d12a7802e173170448bcd9f13d89b.zip
FreeBSD-src-b367666afd7d12a7802e173170448bcd9f13d89b.tar.gz
Allocate DMA bounce buffers only when requested by drivers. Only the
fd and wt drivers need bounce buffers, so this normally saves 32K-1K of kernel memory. Keep track of which DMA channels are busy. isa_dmadone() must now be called when DMA has finished or been aborted. Panic for unallocated and too-small (required) bounce buffers. fd.c: There will be new warnings about isa_dmadone() not being called after DMA has been aborted. sound/dmabuf.c: isa_dmadone() needs more parameters than are available, so temporarily use a new interface isa_dmadone_nobounce() to avoid having to worry about panics for fake parameters. Untested.
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/machdep.c10
-rw-r--r--sys/amd64/include/md_var.h3
-rw-r--r--sys/amd64/isa/isa.c84
3 files changed, 69 insertions, 28 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index ffb0793..aa900e3 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.171 1996/01/21 20:57:03 joerg Exp $
+ * $Id: machdep.c,v 1.172 1996/01/23 02:39:12 davidg Exp $
*/
#include "npx.h"
@@ -400,14 +400,6 @@ again:
*/
vm_bounce_init();
#endif
- /*
- * XXX allocate a contiguous area for ISA (non busmaster) DMA
- * operations. This _should_ only be done if the DMA channels
- * will actually be used, but for now we do it always.
- */
-#define DMAPAGES 8
- isaphysmem =
- vm_page_alloc_contig(DMAPAGES * PAGE_SIZE, 0, 0xfffffful, 64*1024);
printf("avail memory = %d (%dK bytes)\n", ptoa(cnt.v_free_count),
ptoa(cnt.v_free_count) / 1024);
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index cf912f1..67daa03 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: md_var.h,v 1.4 1995/09/03 05:43:25 julian Exp $
+ * $Id: md_var.h,v 1.5 1995/11/21 12:52:57 bde Exp $
*/
#ifndef _MACHINE_MD_VAR_H_
@@ -42,7 +42,6 @@ extern u_long cpu_high;
extern u_long cpu_id;
extern char cpu_vendor[];
extern char etext[];
-extern vm_offset_t isaphysmem;
extern char kstack[];
extern void (*netisrs[32]) __P((void));
extern int nfs_diskless_valid;
diff --git a/sys/amd64/isa/isa.c b/sys/amd64/isa/isa.c
index 10f39ec..3f21cfd 100644
--- a/sys/amd64/isa/isa.c
+++ b/sys/amd64/isa/isa.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id: isa.c,v 1.61 1996/01/19 23:38:06 phk Exp $
+ * $Id: isa.c,v 1.62 1996/01/27 01:56:30 bde Exp $
*/
/*
@@ -561,17 +561,47 @@ isa_defaultirq()
outb(IO_ICU2, 0x0a); /* default to IRR on read */
}
-/* region of physical memory known to be contiguous */
-vm_offset_t isaphysmem;
-static caddr_t dma_bounce[8]; /* XXX */
-static char bounced[8]; /* XXX */
-#define MAXDMASZ 512 /* XXX */
+static caddr_t dma_bouncebuf[8];
+static unsigned dma_bouncebufsize[8];
+static char dma_bounced[8];
+static char dma_busy[8];
/* high byte of address is stored in this port for i-th dma channel */
static short dmapageport[8] =
{ 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
/*
+ * Allocate a DMA channel.
+ */
+void
+isa_dmainit(chan, bouncebufsize)
+ unsigned chan;
+ unsigned bouncebufsize;
+{
+ void *buf;
+
+ if (chan > 7 || dma_bouncebuf[chan] != NULL)
+ panic("isa_dmainit: impossible request");
+ dma_bouncebufsize[chan] = bouncebufsize;
+
+ /* Try malloc() first. It works better if it works. */
+ buf = malloc(bouncebufsize, M_DEVBUF, M_NOWAIT);
+ if (buf != NULL) {
+ if (isa_dmarangecheck(buf, bouncebufsize, chan) == 0) {
+ dma_bouncebuf[chan] = buf;
+ return;
+ }
+ free(buf, M_DEVBUF);
+ }
+ buf = contigmalloc(bouncebufsize, M_DEVBUF, M_NOWAIT, 0ul, 0xfffffful,
+ 1ul, chan & 4 ? 0x20000ul : 0x10000ul);
+ if (buf == NULL)
+ printf("isa_dmainit(%d, %d) failed\n", chan, bouncebufsize);
+ else
+ dma_bouncebuf[chan] = buf;
+}
+
+/*
* isa_dmacascade(): program 8237 DMA controller channel to accept
* external dma control by a board.
*/
@@ -604,13 +634,15 @@ void isa_dmastart(int flags, caddr_t addr, unsigned nbytes, unsigned chan)
|| (chan >= 4 && (nbytes > (1<<17) || (u_int)addr & 1)))
panic("isa_dmastart: impossible request");
+ if (dma_busy[chan])
+ printf("isa_dmastart: channel %u busy\n", chan);
+ dma_busy[chan] = 1;
if (isa_dmarangecheck(addr, nbytes, chan)) {
- if (dma_bounce[chan] == 0)
- dma_bounce[chan] =
- (caddr_t) isaphysmem + NBPG*chan;
- bounced[chan] = 1;
- newaddr = dma_bounce[chan];
- *(int *) newaddr = 0; /* XXX */
+ if (dma_bouncebuf[chan] == NULL
+ || dma_bouncebufsize[chan] < nbytes)
+ panic("isa_dmastart: bad bounce buffer");
+ dma_bounced[chan] = 1;
+ newaddr = dma_bouncebuf[chan];
/* copy bounce buffer on write */
if (!(flags & B_READ))
@@ -694,12 +726,30 @@ void isa_dmastart(int flags, caddr_t addr, unsigned nbytes, unsigned chan)
void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
{
- /* copy bounce buffer on read */
- /*if ((flags & (B_PHYS|B_READ)) == (B_PHYS|B_READ))*/
- if (bounced[chan]) {
- bcopy(dma_bounce[chan], addr, nbytes);
- bounced[chan] = 0;
+ if (!dma_busy[chan])
+ printf("isa_dmadone: channel %d not busy\n", chan);
+ if (dma_bounced[chan]) {
+ /* copy bounce buffer on read */
+ if (flags & B_READ)
+ bcopy(dma_bouncebuf[chan], addr, nbytes);
+
+ dma_bounced[chan] = 0;
+ }
+ dma_busy[chan] = 0;
+}
+
+void
+isa_dmadone_nobounce(chan)
+ unsigned chan;
+{
+
+ if (!dma_busy[chan])
+ printf("isa_dmadone_nobounce: channel %u not busy\n", chan);
+ if (dma_bounced[chan]) {
+ printf("isa_dmadone_nobounce: channel %u bounced\n", chan);
+ dma_bounced[chan] = 0;
}
+ dma_busy[chan] = 0;
}
/*
OpenPOWER on IntegriCloud