summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgallatin <gallatin@FreeBSD.org>2000-06-19 18:41:27 +0000
committergallatin <gallatin@FreeBSD.org>2000-06-19 18:41:27 +0000
commitccfeb47d98df65abb9bc01f29fb2da0a88dd4d83 (patch)
treed825e4455c867bd8bc4781e256435b6ee9942f38
parentcf9d5ec1797dcd397de2af6e7b1fbfd360baf401 (diff)
downloadFreeBSD-src-ccfeb47d98df65abb9bc01f29fb2da0a88dd4d83.zip
FreeBSD-src-ccfeb47d98df65abb9bc01f29fb2da0a88dd4d83.tar.gz
Support bounce buffers for ISA DMA on the alpha. This is required for the
irongate chipset (used in the UP1000) which does not support scatter/gather DMA. We'll still use scatter gather if the core logic chipset supports it. Reviewed by: dfr
-rw-r--r--sys/alpha/alpha/busdma_machdep.c16
-rw-r--r--sys/alpha/alpha/vm_machdep.c2
-rw-r--r--sys/alpha/include/md_var.h1
-rw-r--r--sys/alpha/isa/isa_dma.c31
-rw-r--r--sys/powerpc/aim/vm_machdep.c2
-rw-r--r--sys/powerpc/include/md_var.h1
-rw-r--r--sys/powerpc/powerpc/vm_machdep.c2
7 files changed, 39 insertions, 16 deletions
diff --git a/sys/alpha/alpha/busdma_machdep.c b/sys/alpha/alpha/busdma_machdep.c
index d01433b..aa92602 100644
--- a/sys/alpha/alpha/busdma_machdep.c
+++ b/sys/alpha/alpha/busdma_machdep.c
@@ -240,7 +240,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
error = 0;
- if (dmat->flags & BUS_DMA_ISA) {
+ if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) {
bus_dmamap_t map;
map = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF,
M_NOWAIT);
@@ -290,10 +290,12 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
panic("bus_dmamap_create: page reallocation "
"not implemented");
}
- pages = atop(dmat->maxsize);
+ pages = atop(dmat->maxsize) + 1;
pages = MIN(maxpages - total_bpages, pages);
- error = alloc_bounce_pages(dmat, pages);
+ if (alloc_bounce_pages(dmat, pages) < pages)
+ error = ENOMEM;
+
if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) {
if (error == 0)
dmat->flags |= BUS_DMA_MIN_ALLOC_COMP;
@@ -316,7 +318,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
int
bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
{
- if (dmat->flags & BUS_DMA_ISA) {
+ if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) {
sgmap_free_region(chipset.sgmap, map->sgmaphandle);
}
@@ -404,7 +406,7 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
error = 0;
- if (dmat->flags & BUS_DMA_ISA) {
+ if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) {
/*
* For ISA dma, we use the chipset's scatter-gather
* map to map the tranfer into the ISA reachable range
@@ -529,7 +531,7 @@ _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
{
struct bounce_page *bpage;
- if (dmat->flags & BUS_DMA_ISA) {
+ if ((dmat->flags & BUS_DMA_ISA) && chipset.sgmap != NULL) {
sgmap_unload_region(chipset.sgmap,
map->busaddress,
map->buflen);
@@ -606,7 +608,7 @@ alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages)
M_NOWAIT, 0ul,
dmat->lowaddr,
PAGE_SIZE,
- 0);
+ dmat->boundary);
if (bpage->vaddr == NULL) {
free(bpage, M_DEVBUF);
break;
diff --git a/sys/alpha/alpha/vm_machdep.c b/sys/alpha/alpha/vm_machdep.c
index 68bbf29..8baea02 100644
--- a/sys/alpha/alpha/vm_machdep.c
+++ b/sys/alpha/alpha/vm_machdep.c
@@ -462,10 +462,8 @@ vm_page_zero_idle()
void
swi_vm()
{
-#if 0
if (busdma_swi_pending != 0)
busdma_swi();
-#endif
}
/*
diff --git a/sys/alpha/include/md_var.h b/sys/alpha/include/md_var.h
index 4595c8a..740d40b 100644
--- a/sys/alpha/include/md_var.h
+++ b/sys/alpha/include/md_var.h
@@ -37,6 +37,7 @@ extern char sigcode[];
extern char esigcode[];
extern int szsigcode;
extern int Maxmem;
+extern int busdma_swi_pending;
extern void (*netisrs[32]) __P((void));
struct fpreg;
diff --git a/sys/alpha/isa/isa_dma.c b/sys/alpha/isa/isa_dma.c
index 8b5e64b..5864c7a 100644
--- a/sys/alpha/isa/isa_dma.c
+++ b/sys/alpha/isa/isa_dma.c
@@ -83,6 +83,7 @@ static bus_dmamap_t dma_map[8];
static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */
static u_int8_t dma_inuse = 0; /* User for acquire/release */
static u_int8_t dma_auto_mode = 0;
+static u_int8_t dma_bounced = 0;
#define VALID_DMA_MASK (7)
@@ -105,6 +106,7 @@ isa_dmainit(chan, bouncebufsize)
* Reset the DMA hardware.
*/
outb(DMA1_RESET, 0);
+ outb((IO_DMA1 + 1*14), 0);
outb(DMA2_RESET, 0);
isa_dmacascade(4);
@@ -122,7 +124,7 @@ isa_dmainit(chan, bouncebufsize)
if (bus_dma_tag_create(/*parent*/NULL,
/*alignment*/2,
/*boundary*/boundary,
- /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+ /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
/*highaddr*/BUS_SPACE_MAXADDR,
/*filter*/NULL, /*filterarg*/NULL,
/*maxsize*/bouncebufsize,
@@ -219,13 +221,15 @@ isa_dmacascade(chan)
*/
struct isa_dmastart_arg {
- int chan;
- int flags;
+ caddr_t addr;
+ int chan;
+ int flags;
};
static void isa_dmastart_cb(void *arg, bus_dma_segment_t *segs, int nseg,
int error)
{
+ caddr_t addr = ((struct isa_dmastart_arg *) arg)->addr;
int chan = ((struct isa_dmastart_arg *) arg)->chan;
int flags = ((struct isa_dmastart_arg *) arg)->flags;
bus_addr_t phys = segs->ds_addr;
@@ -235,6 +239,17 @@ static void isa_dmastart_cb(void *arg, bus_dma_segment_t *segs, int nseg,
if (nseg != 1)
panic("isa_dmastart: transfer mapping not contiguous");
+ if ((chipset.sgmap == NULL) &&
+ (pmap_extract(pmap_kernel(), (vm_offset_t)addr)
+ > BUS_SPACE_MAXADDR_24BIT)) {
+ /* we bounced */
+ dma_bounced |= (1 << chan);
+ /* copy bounce buffer on write */
+ if (!(flags & ISADMA_READ))
+ bus_dmamap_sync(dma_tag[chan], dma_map[chan],
+ BUS_DMASYNC_PREWRITE);
+ }
+
if ((chan & 4) == 0) {
/*
* Program one of DMA channels 0..3. These are
@@ -348,6 +363,7 @@ isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
*/
outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
+ args.addr = addr;
args.chan = chan;
args.flags = flags;
bus_dmamap_load(dma_tag[chan], dma_map[chan], addr, nbytes,
@@ -369,6 +385,15 @@ isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
(dma_auto_mode & (1 << chan)) == 0 )
printf("isa_dmadone: channel %d not busy\n", chan);
+ if (dma_bounced & (1 << chan)) {
+ /* copy bounce buffer on read */
+ if (flags & ISADMA_READ) {
+ bus_dmamap_sync(dma_tag[chan], dma_map[chan],
+ BUS_DMASYNC_POSTREAD);
+ }
+ dma_bounced &= ~(1 << chan);
+ }
+
if ((dma_auto_mode & (1 << chan)) == 0) {
outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
bus_dmamap_unload(dma_tag[chan], dma_map[chan]);
diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c
index 68bbf29..8baea02 100644
--- a/sys/powerpc/aim/vm_machdep.c
+++ b/sys/powerpc/aim/vm_machdep.c
@@ -462,10 +462,8 @@ vm_page_zero_idle()
void
swi_vm()
{
-#if 0
if (busdma_swi_pending != 0)
busdma_swi();
-#endif
}
/*
diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h
index 4595c8a..740d40b 100644
--- a/sys/powerpc/include/md_var.h
+++ b/sys/powerpc/include/md_var.h
@@ -37,6 +37,7 @@ extern char sigcode[];
extern char esigcode[];
extern int szsigcode;
extern int Maxmem;
+extern int busdma_swi_pending;
extern void (*netisrs[32]) __P((void));
struct fpreg;
diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c
index 68bbf29..8baea02 100644
--- a/sys/powerpc/powerpc/vm_machdep.c
+++ b/sys/powerpc/powerpc/vm_machdep.c
@@ -462,10 +462,8 @@ vm_page_zero_idle()
void
swi_vm()
{
-#if 0
if (busdma_swi_pending != 0)
busdma_swi();
-#endif
}
/*
OpenPOWER on IntegriCloud