diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc64/dev/iommu.c | 23 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/iommuvar.h | 4 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/viommu.c | 26 | ||||
-rw-r--r-- | sys/arch/sparc64/include/bus.h | 29 |
4 files changed, 65 insertions, 17 deletions
diff --git a/sys/arch/sparc64/dev/iommu.c b/sys/arch/sparc64/dev/iommu.c index 13f48d22fbb..66316b1844c 100644 --- a/sys/arch/sparc64/dev/iommu.c +++ b/sys/arch/sparc64/dev/iommu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iommu.c,v 1.72 2015/01/09 14:23:25 kettenis Exp $ */ +/* $OpenBSD: iommu.c,v 1.73 2016/05/04 18:26:12 kettenis Exp $ */ /* $NetBSD: iommu.c,v 1.47 2002/02/08 20:03:45 eeh Exp $ */ /* @@ -195,6 +195,13 @@ iommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase) pmap_update(pmap_kernel()); memset(is->is_tsb, 0, size); + TAILQ_INIT(&mlist); + if (uvm_pglistalloc(PAGE_SIZE, 0, -1, PAGE_SIZE, 0, &mlist, 1, + UVM_PLA_NOWAIT | UVM_PLA_ZERO) != 0) + panic("%s: no memory", __func__); + m = TAILQ_FIRST(&mlist); + is->is_scratch = VM_PAGE_TO_PHYS(m); + #ifdef DEBUG if (iommudebug & IDB_INFO) { /* Probe the iommu */ @@ -734,6 +741,13 @@ iommu_dvmamap_load(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map, } } } + if (flags & BUS_DMA_OVERRUN) { + err = iommu_iomap_insert_page(ims, is->is_scratch); + if (err) { + iommu_iomap_clear_pages(ims); + return (EFBIG); + } + } sgsize = ims->ims_map.ipm_pagecnt * PAGE_SIZE; mtx_enter(&is->is_mtx); @@ -941,6 +955,13 @@ iommu_dvmamap_load_raw(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map, left -= seg_len; } } + if (flags & BUS_DMA_OVERRUN) { + err = iommu_iomap_insert_page(ims, is->is_scratch); + if (err) { + iommu_iomap_clear_pages(ims); + return (EFBIG); + } + } sgsize = ims->ims_map.ipm_pagecnt * PAGE_SIZE; mtx_enter(&is->is_mtx); diff --git a/sys/arch/sparc64/dev/iommuvar.h b/sys/arch/sparc64/dev/iommuvar.h index cc0dab203c9..f0a548079c6 100644 --- a/sys/arch/sparc64/dev/iommuvar.h +++ b/sys/arch/sparc64/dev/iommuvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iommuvar.h,v 1.16 2014/01/22 10:52:35 kettenis Exp $ */ +/* $OpenBSD: iommuvar.h,v 1.17 2016/05/04 18:26:12 kettenis Exp $ */ /* $NetBSD: iommuvar.h,v 1.9 2001/10/07 20:30:41 eeh Exp $ */ /* @@ -117,6 +117,8 @@ struct iommu_state { struct strbuf_ctl *is_sb[2]; /* Streaming buffers if any */ + paddr_t is_scratch; /* Scratch page */ + /* copies of our parents state, to allow us to be self contained */ bus_space_tag_t is_bustag; /* our bus tag */ bus_space_handle_t is_iommu; /* IOMMU registers */ diff --git a/sys/arch/sparc64/dev/viommu.c b/sys/arch/sparc64/dev/viommu.c index 2b95a707488..77362d76eeb 100644 --- a/sys/arch/sparc64/dev/viommu.c +++ b/sys/arch/sparc64/dev/viommu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: viommu.c,v 1.16 2015/01/09 14:23:25 kettenis Exp $ */ +/* $OpenBSD: viommu.c,v 1.17 2016/05/04 18:26:12 kettenis Exp $ */ /* $NetBSD: iommu.c,v 1.47 2002/02/08 20:03:45 eeh Exp $ */ /* @@ -106,6 +106,9 @@ void viommu_init(char *name, struct iommu_state *is, int tsbsize, u_int32_t iovabase) { + struct vm_page *m; + struct pglist mlist; + /* * Setup the iommu. * @@ -121,6 +124,13 @@ viommu_init(char *name, struct iommu_state *is, int tsbsize, is->is_dvmaend = iovabase + IOTSB_VSIZE(tsbsize) - 1; } + TAILQ_INIT(&mlist); + if (uvm_pglistalloc(PAGE_SIZE, 0, -1, PAGE_SIZE, 0, &mlist, 1, + UVM_PLA_NOWAIT | UVM_PLA_ZERO) != 0) + panic("%s: no memory", __func__); + m = TAILQ_FIRST(&mlist); + is->is_scratch = VM_PAGE_TO_PHYS(m); + /* * Allocate a dvma map. */ @@ -341,6 +351,13 @@ viommu_dvmamap_load(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map, } } } + if (flags & BUS_DMA_OVERRUN) { + err = iommu_iomap_insert_page(ims, is->is_scratch); + if (err) { + iommu_iomap_clear_pages(ims); + return (EFBIG); + } + } sgsize = ims->ims_map.ipm_pagecnt * PAGE_SIZE; mtx_enter(&is->is_mtx); @@ -524,6 +541,13 @@ viommu_dvmamap_load_raw(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map, left -= seg_len; } } + if (flags & BUS_DMA_OVERRUN) { + err = iommu_iomap_insert_page(ims, is->is_scratch); + if (err) { + iommu_iomap_clear_pages(ims); + return (EFBIG); + } + } sgsize = ims->ims_map.ipm_pagecnt * PAGE_SIZE; mtx_enter(&is->is_mtx); diff --git a/sys/arch/sparc64/include/bus.h b/sys/arch/sparc64/include/bus.h index bf016a2ab40..a7a88034e0f 100644 --- a/sys/arch/sparc64/include/bus.h +++ b/sys/arch/sparc64/include/bus.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bus.h,v 1.29 2013/05/13 17:46:42 kettenis Exp $ */ +/* $OpenBSD: bus.h,v 1.30 2016/05/04 18:26:12 kettenis Exp $ */ /* $NetBSD: bus.h,v 1.31 2001/09/21 15:30:41 wiz Exp $ */ /*- @@ -356,19 +356,20 @@ bus_space_barrier(t, h, o, s, f) /* * Flags used in various bus DMA methods. */ -#define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */ -#define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */ -#define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */ -#define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */ -#define BUS_DMA_NOWRITE 0x008 /* I suppose the following two should default on */ -#define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */ -#define BUS_DMA_BUS2 0x020 -#define BUS_DMA_BUS3 0x040 -#define BUS_DMA_BUS4 0x080 -#define BUS_DMA_STREAMING 0x100 /* hint: sequential, unidirectional */ -#define BUS_DMA_READ 0x200 /* mapping is device -> memory only */ -#define BUS_DMA_WRITE 0x400 /* mapping is memory -> device only */ -#define BUS_DMA_ZERO 0x800 /* zero memory in dmamem_alloc */ +#define BUS_DMA_WAITOK 0x0000 /* safe to sleep (pseudo-flag) */ +#define BUS_DMA_NOWAIT 0x0001 /* not safe to sleep */ +#define BUS_DMA_ALLOCNOW 0x0002 /* perform resource allocation now */ +#define BUS_DMA_COHERENT 0x0004 /* hint: map memory DMA coherent */ +#define BUS_DMA_NOWRITE 0x0008 /* I suppose the following two should default on */ +#define BUS_DMA_BUS1 0x0010 /* placeholders for bus functions... */ +#define BUS_DMA_BUS2 0x0020 +#define BUS_DMA_BUS3 0x0040 +#define BUS_DMA_BUS4 0x0080 +#define BUS_DMA_STREAMING 0x0100 /* hint: sequential, unidirectional */ +#define BUS_DMA_READ 0x0200 /* mapping is device -> memory only */ +#define BUS_DMA_WRITE 0x0400 /* mapping is memory -> device only */ +#define BUS_DMA_ZERO 0x0800 /* zero memory in dmamem_alloc */ +#define BUS_DMA_OVERRUN 0x1000 /* tolerate DMA overruns */ #define BUS_DMA_NOCACHE BUS_DMA_BUS1 #define BUS_DMA_DVMA BUS_DMA_BUS2 /* Don't bother with alignment */ |