summaryrefslogtreecommitdiff
path: root/sys/arch/hppa
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2002-02-16 02:21:57 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2002-02-16 02:21:57 +0000
commiteadcff049d974abe9350fd75e593d967e45a3c55 (patch)
treef1f8fd841002aa5d415533d123a5ba696a28349e /sys/arch/hppa
parent12acc88e100b6f8b64ad0526f76e907c1b9cfc97 (diff)
implement a few dma methods; from fredette@. some fixes from me
Diffstat (limited to 'sys/arch/hppa')
-rw-r--r--sys/arch/hppa/hppa/mainbus.c97
-rw-r--r--sys/arch/hppa/include/bus.h4
2 files changed, 68 insertions, 33 deletions
diff --git a/sys/arch/hppa/hppa/mainbus.c b/sys/arch/hppa/hppa/mainbus.c
index 1bf03e967a4..94cdfd93fa8 100644
--- a/sys/arch/hppa/hppa/mainbus.c
+++ b/sys/arch/hppa/hppa/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.23 2002/02/12 02:44:00 mickey Exp $ */
+/* $OpenBSD: mainbus.c,v 1.24 2002/02/16 02:21:56 mickey Exp $ */
/*
* Copyright (c) 1998-2001 Michael Shalayeff
@@ -151,7 +151,7 @@ mbus_add_mapping(bus_addr_t bpa, bus_size_t size, int cachable,
/* register vaddr_t va; */
#ifdef PMAPDEBUG
- printf ("%d, %d, %x\n", bank, off, vm_physmem[0].end);
+ printf ("%d, %d, %lx\n", bank, off, vm_physmem[0].end);
#endif
spa = hppa_trunc_page(bpa);
epa = hppa_round_page(bpa + size);
@@ -268,7 +268,8 @@ int
mbus_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
bus_size_t size, bus_space_handle_t *nbshp)
{
- panic("mbus_subregion: unimplemented");
+ *nbshp = bsh + offset;
+ return (0);
}
void
@@ -638,14 +639,26 @@ mbus_dmamap_create(void *v, bus_size_t size, int nsegments,
map->_dm_maxsegsz = maxsegsz;
map->_dm_boundary = boundary;
map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
*dmamp = map;
return (0);
}
void
+mbus_dmamap_unload(void *v, bus_dmamap_t map)
+{
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+}
+
+void
mbus_dmamap_destroy(void *v, bus_dmamap_t map)
{
+ if (map->dm_mapsize != 0)
+ mbus_dmamap_unload(v, map);
+
free(map, M_DEVBUF);
}
@@ -653,7 +666,48 @@ int
mbus_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
struct proc *p, int flags)
{
- panic("_dmamap_load: not implemented");
+ paddr_t pa, pa_next;
+ bus_size_t mapsize;
+ bus_size_t off, pagesz;
+ int seg;
+
+ /*
+ * Make sure that on error condition we return "no valid mappings".
+ */
+ map->dm_nsegs = 0;
+ map->dm_mapsize = 0;
+ map->_dm_va = (vaddr_t)addr;
+
+ /* Load the memory. */
+ pa_next = 0;
+ seg = -1;
+ mapsize = size;
+ off = (bus_size_t)addr & (PAGE_SIZE - 1);
+ addr = (void *) ((caddr_t)addr - off);
+ for(; size > 0; ) {
+
+ pmap_extract(pmap_kernel(), (vaddr_t)addr, &pa);
+ if (pa != pa_next) {
+ if (++seg >= map->_dm_segcnt)
+ panic("mbus_dmamap_load: nsegs botch");
+ map->dm_segs[seg].ds_addr = pa + off;
+ map->dm_segs[seg].ds_len = 0;
+ }
+ pa_next = pa + PAGE_SIZE;
+ pagesz = PAGE_SIZE - off;
+ if (size < pagesz)
+ pagesz = size;
+ map->dm_segs[seg].ds_len += pagesz;
+ size -= pagesz;
+ addr = (caddr_t)addr + off + pagesz;
+ off = 0;
+ }
+
+ /* Make the map truly valid. */
+ map->dm_nsegs = seg + 1;
+ map->dm_mapsize = mapsize;
+
+ return (0);
}
int
@@ -676,38 +730,17 @@ mbus_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
}
void
-mbus_dmamap_unload(void *v, bus_dmamap_t map)
-{
- panic("_dmamap_unload: not implemented");
-}
-
-void
mbus_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t offset, bus_size_t len,
int ops)
{
- int i;
- switch (ops) {
- case BUS_DMASYNC_POSTREAD:
- case BUS_DMASYNC_POSTWRITE:
+
+ if (ops & (BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE))
__asm __volatile ("syncdma");
- break;
-
- case BUS_DMASYNC_PREREAD:
- for (i = map->dm_nsegs; i--; )
- pdcache(HPPA_SID_KERNEL,
- map->dm_segs[i].ds_addr + offset,
- len);
- sync_caches();
- break;
-
- case BUS_DMASYNC_PREWRITE:
- for (i = map->dm_nsegs; i--; )
- fdcache(HPPA_SID_KERNEL,
- map->dm_segs[i].ds_addr + offset,
- len);
- sync_caches();
- break;
- }
+
+ if (ops & BUS_DMASYNC_PREREAD)
+ pdcache(HPPA_SID_KERNEL, map->_dm_va + offset, len);
+ else if (ops & BUS_DMASYNC_PREWRITE)
+ fdcache(HPPA_SID_KERNEL, map->_dm_va + offset, len);
}
int
diff --git a/sys/arch/hppa/include/bus.h b/sys/arch/hppa/include/bus.h
index 4465645ca40..f965c60e552 100644
--- a/sys/arch/hppa/include/bus.h
+++ b/sys/arch/hppa/include/bus.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus.h,v 1.14 2001/11/05 17:25:57 art Exp $ */
+/* $OpenBSD: bus.h,v 1.15 2002/02/16 02:21:56 mickey Exp $ */
/*
* Copyright (c) 1998,1999 Michael Shalayeff
@@ -403,6 +403,7 @@ struct hppa_bus_dmamap {
bus_size_t _dm_maxsegsz; /* largest possible segment */
bus_size_t _dm_boundary; /* don't cross this */
int _dm_flags; /* misc. flags */
+ vaddr_t _dm_va; /* needed for syncing */
void *_dm_cookie; /* cookie for bus-specific functions */
@@ -411,6 +412,7 @@ struct hppa_bus_dmamap {
*/
int dm_nsegs; /* # valid segments in mapping */
bus_dma_segment_t dm_segs[1]; /* segments; variable length */
+ bus_size_t dm_mapsize; /* size of the mapping */
};
#endif /* _MACHINE_BUS_H_ */