diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-02-16 02:21:57 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-02-16 02:21:57 +0000 |
commit | eadcff049d974abe9350fd75e593d967e45a3c55 (patch) | |
tree | f1f8fd841002aa5d415533d123a5ba696a28349e /sys/arch/hppa | |
parent | 12acc88e100b6f8b64ad0526f76e907c1b9cfc97 (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.c | 97 | ||||
-rw-r--r-- | sys/arch/hppa/include/bus.h | 4 |
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_ */ |