On Sun, Jul 09, 2017 at 11:37:44AM +0300, Artturi Alm wrote: > Hi, > > ok, the previous version of this was crap, i must admit having gone > through what i sent, since i got no comments for it. > i'll retry w/version i think should be simple enough, with almost > no cleanup done, so rather minimal, for the simple review needed, > for the comment that's enough for me to drop this diff; "No.", > and if it's not too much to ask, some reasoning why this would > not be wanted or appropriate. > > this one does work w/BUS_SPACE_NEW, and without. cubieboard2 > exercises the a4x bs hack, + this kind of includes the dsb sy > a4x fixes i sent separately, which might help out w/fifo probes > or whatever, i haven't looked at current com.c, but i recall > something related from experiments i did years ago, maybe. > > some compile stats: > ________before first diff(-current GENERIC): > ________________________________CA7/cubieboard2: > cc -g -Werror -Wall -Wimplicit-function-declaration -Wno-uninitialized > -Wno-pointer-sign -Wframe-larger-than=2047 -msoft-float -march=armv6 > -Wa,-march=armv7a -ffreestanding -fno-pie -O2 -pipe -nostdinc -I/usr/src/sys > -I. -I/usr/src/sys/arch -DDDB -DDIAGNOSTIC -DKTRACE -DACCOUNTING -DKMEMSTATS > -DPTRACE -DPOOL_DEBUG -DCRYPTO -DSYSVMSG -DSYSVSEM -DSYSVSHM > -DUVM_SWAP_ENCRYPT -DFFS -DFFS2 -DFFS_SOFTUPDATES -DUFS_DIRHASH -DQUOTA > -DEXT2FS -DMFS -DNFSCLIENT -DNFSSERVER -DCD9660 -DUDF -DMSDOSFS -DFIFO -DFUSE > -DSOCKET_SPLICE -DTCP_SACK -DTCP_ECN -DTCP_SIGNATURE -DART -DINET6 -DIPSEC > -DPPP_BSDCOMP -DPPP_DEFLATE -DPIPEX -DMROUTING -DMPLS -DBOOT_CONFIG > -DCPU_ARMv7 -DWSDISPLAY_COMPAT_RAWKBD -DWSDISPLAY_DEFAULTSCREENS="1" > -DCONF_HAVE_GPIO -DUSBVERBOSE -DONEWIREVERBOSE -DMAXUSERS=32 -D_KERNEL > -D__armv7__ -MD -MP -c vers.c > ld -T ld.script --warn-common -nopie -o bsd ${SYSTEM_HEAD} vers.o ${OBJS} > text data bss dec hex > 3880128 164656 495352 4540136 4546e8 > > ________________________________CA9/wandboard: > cc -g -Werror -Wall -Wimplicit-function-declaration -Wno-uninitialized > -Wno-pointer-sign -Wframe-larger-than=2047 -msoft-float -march=armv6 > -Wa,-march=armv7a -ffreestanding -fno-pie -O2 -pipe -nostdinc -I/usr/src/sys > -I. -I/usr/src/sys/arch -DDDB -DDIAGNOSTIC -DKTRACE -DACCOUNTING -DKMEMSTATS > -DPTRACE -DPOOL_DEBUG -DCRYPTO -DSYSVMSG -DSYSVSEM -DSYSVSHM > -DUVM_SWAP_ENCRYPT -DFFS -DFFS2 -DFFS_SOFTUPDATES -DUFS_DIRHASH -DQUOTA > -DEXT2FS -DMFS -DNFSCLIENT -DNFSSERVER -DCD9660 -DUDF -DMSDOSFS -DFIFO -DFUSE > -DSOCKET_SPLICE -DTCP_SACK -DTCP_ECN -DTCP_SIGNATURE -DART -DINET6 -DIPSEC > -DPPP_BSDCOMP -DPPP_DEFLATE -DPIPEX -DMROUTING -DMPLS -DBOOT_CONFIG > -DCPU_ARMv7 -DWSDISPLAY_COMPAT_RAWKBD -DWSDISPLAY_DEFAULTSCREENS="1" > -DCONF_HAVE_GPIO -DUSBVERBOSE -DONEWIREVERBOSE -DMAXUSERS=32 -D_KERNEL > -D__armv7__ -MD -MP -c vers.c > ld -T ld.script --warn-common -nopie -o bsd ${SYSTEM_HEAD} vers.o ${OBJS} > text data bss dec hex > 3884076 164724 494160 4542960 4551f0 > > ________before last diff(#option BUS_SPACE_NEW #=disabled): > ________________________________CA7/cubieboard2: > cc -g -Werror -Wall -Wimplicit-function-declaration -Wno-uninitialized > -Wno-pointer-sign -Wframe-larger-than=2047 -msoft-float -march=armv6 > -Wa,-march=armv7a -ffreestanding -fno-pie -O2 -pipe -nostdinc -I/usr/src/sys > -I. -I/usr/src/sys/arch -DDDB -DDIAGNOSTIC -DKTRACE -DACCOUNTING -DKMEMSTATS > -DPTRACE -DPOOL_DEBUG -DCRYPTO -DSYSVMSG -DSYSVSEM -DSYSVSHM > -DUVM_SWAP_ENCRYPT -DFFS -DFFS2 -DFFS_SOFTUPDATES -DUFS_DIRHASH -DQUOTA > -DEXT2FS -DMFS -DNFSCLIENT -DNFSSERVER -DCD9660 -DUDF -DMSDOSFS -DFIFO -DFUSE > -DSOCKET_SPLICE -DTCP_SACK -DTCP_ECN -DTCP_SIGNATURE -DART -DINET6 -DIPSEC > -DPPP_BSDCOMP -DPPP_DEFLATE -DPIPEX -DMROUTING -DMPLS -DBOOT_CONFIG > -DCPU_ARMv7 -DWSDISPLAY_COMPAT_RAWKBD -DWSDISPLAY_DEFAULTSCREENS="1" > -DCONF_HAVE_GPIO -DUSBVERBOSE -DONEWIREVERBOSE -DMAXUSERS=32 -D_KERNEL > -D__armv7__ -MD -MP -c vers.c > ld -T ld.script --warn-common -nopie -o bsd ${SYSTEM_HEAD} vers.o ${OBJS} > text data bss dec hex > 3880656 162676 497688 4541020 454a5c > > ________________________________CA9/wandboard: > cc -g -Werror -Wall -Wimplicit-function-declaration -Wno-uninitialized > -Wno-pointer-sign -Wframe-larger-than=2047 -msoft-float -march=armv6 > -Wa,-march=armv7a -ffreestanding -fno-pie -O2 -pipe -nostdinc -I/usr/src/sys > -I. -I/usr/src/sys/arch -DDDB -DDIAGNOSTIC -DKTRACE -DACCOUNTING -DKMEMSTATS > -DPTRACE -DPOOL_DEBUG -DCRYPTO -DSYSVMSG -DSYSVSEM -DSYSVSHM > -DUVM_SWAP_ENCRYPT -DFFS -DFFS2 -DFFS_SOFTUPDATES -DUFS_DIRHASH -DQUOTA > -DEXT2FS -DMFS -DNFSCLIENT -DNFSSERVER -DCD9660 -DUDF -DMSDOSFS -DFIFO -DFUSE > -DSOCKET_SPLICE -DTCP_SACK -DTCP_ECN -DTCP_SIGNATURE -DART -DINET6 -DIPSEC > -DPPP_BSDCOMP -DPPP_DEFLATE -DPIPEX -DMROUTING -DMPLS -DBOOT_CONFIG > -DCPU_ARMv7 -DWSDISPLAY_COMPAT_RAWKBD -DWSDISPLAY_DEFAULTSCREENS="1" > -DCONF_HAVE_GPIO -DUSBVERBOSE -DONEWIREVERBOSE -DMAXUSERS=32 -D_KERNEL > -D__armv7__ -MD -MP -c vers.c > ld -T ld.script --warn-common -nopie -o bsd ${SYSTEM_HEAD} vers.o ${OBJS} > text data bss dec hex > 3880172 163552 494448 4538172 453f3c > > > ________after last diff(option BUS_SPACE_NEW #=enabled): > ________________________________CA7/cubieboard2: > cc -g -Werror -Wall -Wimplicit-function-declaration -Wno-uninitialized > -Wno-pointer-sign -Wframe-larger-than=2047 -msoft-float -march=armv6 > -Wa,-march=armv7a -ffreestanding -fno-pie -O2 -pipe -nostdinc -I/usr/src/sys > -I. -I/usr/src/sys/arch -DDDB -DDIAGNOSTIC -DKTRACE -DACCOUNTING -DKMEMSTATS > -DPTRACE -DPOOL_DEBUG -DCRYPTO -DSYSVMSG -DSYSVSEM -DSYSVSHM > -DUVM_SWAP_ENCRYPT -DFFS -DFFS2 -DFFS_SOFTUPDATES -DUFS_DIRHASH -DQUOTA > -DEXT2FS -DMFS -DNFSCLIENT -DNFSSERVER -DCD9660 -DUDF -DMSDOSFS -DFIFO -DFUSE > -DSOCKET_SPLICE -DTCP_SACK -DTCP_ECN -DTCP_SIGNATURE -DART -DINET6 -DIPSEC > -DPPP_BSDCOMP -DPPP_DEFLATE -DPIPEX -DMROUTING -DMPLS -DBOOT_CONFIG > -DCPU_ARMv7 -DBUS_SPACE_NEW -DWSDISPLAY_COMPAT_RAWKBD > -DWSDISPLAY_DEFAULTSCREENS="1" -DCONF_HAVE_GPIO -DUSBVERBOSE -DONEWIREVERBOSE > -DMAXUSERS=32 -D_KERNEL -D__armv7__ -MD -MP -c vers.c > ld -T ld.script --warn-common -nopie -o bsd ${SYSTEM_HEAD} vers.o ${OBJS} > text data bss dec hex > 3843676 164732 495528 4503936 44b980 > > ________________________________CA9/wandboard: > cc -g -Werror -Wall -Wimplicit-function-declaration -Wno-uninitialized > -Wno-pointer-sign -Wframe-larger-than=2047 -msoft-float -march=armv6 > -Wa,-march=armv7a -ffreestanding -fno-pie -O2 -pipe -nostdinc -I/usr/src/sys > -I. -I/usr/src/sys/arch -DDDB -DDIAGNOSTIC -DKTRACE -DACCOUNTING -DKMEMSTATS > -DPTRACE -DPOOL_DEBUG -DCRYPTO -DSYSVMSG -DSYSVSEM -DSYSVSHM > -DUVM_SWAP_ENCRYPT -DFFS -DFFS2 -DFFS_SOFTUPDATES -DUFS_DIRHASH -DQUOTA > -DEXT2FS -DMFS -DNFSCLIENT -DNFSSERVER -DCD9660 -DUDF -DMSDOSFS -DFIFO -DFUSE > -DSOCKET_SPLICE -DTCP_SACK -DTCP_ECN -DTCP_SIGNATURE -DART -DINET6 -DIPSEC > -DPPP_BSDCOMP -DPPP_DEFLATE -DPIPEX -DMROUTING -DMPLS -DBOOT_CONFIG > -DCPU_ARMv7 -DBUS_SPACE_NEW -DWSDISPLAY_COMPAT_RAWKBD > -DWSDISPLAY_DEFAULTSCREENS="1" -DCONF_HAVE_GPIO -DUSBVERBOSE -DONEWIREVERBOSE > -DMAXUSERS=32 -D_KERNEL -D__armv7__ -MD -MP -c vers.c > ld -T ld.script --warn-common -nopie -o bsd ${SYSTEM_HEAD} vers.o ${OBJS} > text data bss dec hex > 3845564 164188 497360 4507112 44c5e8 > > to my surprise, the sizes didn't get bigger w/inlined bs:) > > first diff out of 5 below, rest will come separately, sorry for the noise. > -Artturi > >
0 comments so far,=wasted effort because it's cool to branch around indirectly for every single bus_space op even w/memory mapped devices like armv7 has, or? rebased diffs below. -Artturi _______________________________________________________________________ 0/4: separate bus_dma defines out of arm/bus.h into arm/bus_dma.h, and include it in from arm/bus.h, no functional change should yet occur with this diff. diff --git a/sys/arch/arm/include/bus.h b/sys/arch/arm/include/bus.h index bb540d8acac..b2c75cfdf76 100644 --- a/sys/arch/arm/include/bus.h +++ b/sys/arch/arm/include/bus.h @@ -599,236 +599,8 @@ bs_c_2_proto(f); \ bs_c_4_proto(f); \ bs_c_8_proto(f); -/* Bus Space DMA macros */ +#include <arm/bus_dma.h> -/* - * Flags used in various bus DMA methods. - */ -#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_STREAMING 0x0008 /* hint: sequential, unidirectional */ -#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_READ 0x0100 /* mapping is device -> memory only */ -#define BUS_DMA_WRITE 0x0200 /* mapping is memory -> device only */ -#define BUS_DMA_NOCACHE 0x0400 /* hint: map non-cached memory */ -#define BUS_DMA_ZERO 0x0800 /* dmamem_alloc returns zeroed mem */ -#define BUS_DMA_64BIT 0x1000 /* device handles 64bit dva */ - -/* - * Private flags stored in the DMA map. - */ -#define ARM32_DMAMAP_COHERENT 0x10000 /* no cache flush necessary on sync */ - -/* Forwards needed by prototypes below. */ -struct mbuf; -struct uio; - -/* - * Operations performed by bus_dmamap_sync(). - */ -#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ -#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ -#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ -#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ - -typedef struct arm32_bus_dma_tag *bus_dma_tag_t; -typedef struct arm32_bus_dmamap *bus_dmamap_t; - -#define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0) - -/* - * bus_dma_segment_t - * - * Describes a single contiguous DMA transaction. Values - * are suitable for programming into DMA registers. - */ -struct arm32_bus_dma_segment { - /* - * PUBLIC MEMBERS: these are used by machine-independent code. - */ - bus_addr_t ds_addr; /* DMA address */ - bus_size_t ds_len; /* length of transfer */ - /* - * PRIVATE MEMBERS: not for use by machine-independent code. - */ - bus_addr_t _ds_vaddr; /* Virtual mapped address - * Used by bus_dmamem_sync() */ - int _ds_coherent; /* Coherently mapped */ -}; -typedef struct arm32_bus_dma_segment bus_dma_segment_t; - -/* - * arm32_dma_range - * - * This structure describes a valid DMA range. - */ -struct arm32_dma_range { - bus_addr_t dr_sysbase; /* system base address */ - bus_addr_t dr_busbase; /* appears here on bus */ - bus_size_t dr_len; /* length of range */ -}; - -/* - * bus_dma_tag_t - * - * A machine-dependent opaque type describing the implementation of - * DMA for a given bus. - */ - -struct arm32_bus_dma_tag { - /* - * DMA range for this tag. If the page doesn't fall within - * one of these ranges, an error is returned. The caller - * may then decide what to do with the transfer. If the - * range pointer is NULL, it is ignored. - */ - struct arm32_dma_range *_ranges; - int _nranges; - - /* - * Opaque cookie for use by back-end. - */ - void *_cookie; - - /* - * DMA mapping methods. - */ - int (*_dmamap_create) (bus_dma_tag_t, bus_size_t, int, - bus_size_t, bus_size_t, int, bus_dmamap_t *); - void (*_dmamap_destroy) (bus_dma_tag_t, bus_dmamap_t); - int (*_dmamap_load) (bus_dma_tag_t, bus_dmamap_t, void *, - bus_size_t, struct proc *, int); - int (*_dmamap_load_mbuf) (bus_dma_tag_t, bus_dmamap_t, - struct mbuf *, int); - int (*_dmamap_load_uio) (bus_dma_tag_t, bus_dmamap_t, - struct uio *, int); - int (*_dmamap_load_raw) (bus_dma_tag_t, bus_dmamap_t, - bus_dma_segment_t *, int, bus_size_t, int); - void (*_dmamap_unload) (bus_dma_tag_t, bus_dmamap_t); - void (*_dmamap_sync) (bus_dma_tag_t, bus_dmamap_t, - bus_addr_t, bus_size_t, int); - - /* - * DMA memory utility functions. - */ - int (*_dmamem_alloc) (bus_dma_tag_t, bus_size_t, bus_size_t, - bus_size_t, bus_dma_segment_t *, int, int *, int); - void (*_dmamem_free) (bus_dma_tag_t, - bus_dma_segment_t *, int); - int (*_dmamem_map) (bus_dma_tag_t, bus_dma_segment_t *, - int, size_t, caddr_t *, int); - void (*_dmamem_unmap) (bus_dma_tag_t, caddr_t, size_t); - paddr_t (*_dmamem_mmap) (bus_dma_tag_t, bus_dma_segment_t *, - int, off_t, int, int); -}; - -#define bus_dmamap_create(t, s, n, m, b, f, p) \ - (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) -#define bus_dmamap_destroy(t, p) \ - (*(t)->_dmamap_destroy)((t), (p)) -#define bus_dmamap_load(t, m, b, s, p, f) \ - (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) -#define bus_dmamap_load_mbuf(t, m, b, f) \ - (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) -#define bus_dmamap_load_uio(t, m, u, f) \ - (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) -#define bus_dmamap_load_raw(t, m, sg, n, s, f) \ - (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) -#define bus_dmamap_unload(t, p) \ - (*(t)->_dmamap_unload)((t), (p)) -#define bus_dmamap_sync(t, p, o, l, ops) \ - (void)((t)->_dmamap_sync ? \ - (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0) - -#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ - (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) -#define bus_dmamem_free(t, sg, n) \ - (*(t)->_dmamem_free)((t), (sg), (n)) -#define bus_dmamem_map(t, sg, n, s, k, f) \ - (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) -#define bus_dmamem_unmap(t, k, s) \ - (*(t)->_dmamem_unmap)((t), (k), (s)) -#define bus_dmamem_mmap(t, sg, n, o, p, f) \ - (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) - -/* - * bus_dmamap_t - * - * Describes a DMA mapping. - */ -struct arm32_bus_dmamap { - /* - * PRIVATE MEMBERS: not for use by machine-independent code. - */ - bus_size_t _dm_size; /* largest DMA transfer mappable */ - int _dm_segcnt; /* number of segs this map can map */ - bus_size_t _dm_maxsegsz; /* largest possible segment */ - bus_size_t _dm_boundary; /* don't cross this */ - int _dm_flags; /* misc. flags */ - - void *_dm_origbuf; /* pointer to original buffer */ - int _dm_buftype; /* type of buffer */ - struct proc *_dm_proc; /* proc that owns the mapping */ - - void *_dm_cookie; /* cookie for bus-specific functions */ - - /* - * PUBLIC MEMBERS: these are used by machine-independent code. - */ - bus_size_t dm_mapsize; /* size of the mapping */ - int dm_nsegs; /* # valid segments in mapping */ - bus_dma_segment_t dm_segs[1]; /* segments; variable length */ -}; - -#ifdef _ARM32_BUS_DMA_PRIVATE - -/* _dm_buftype */ -#define ARM32_BUFTYPE_INVALID 0 -#define ARM32_BUFTYPE_LINEAR 1 -#define ARM32_BUFTYPE_MBUF 2 -#define ARM32_BUFTYPE_UIO 3 -#define ARM32_BUFTYPE_RAW 4 - -int arm32_dma_range_intersect(struct arm32_dma_range *, int, - paddr_t pa, psize_t size, paddr_t *pap, psize_t *sizep); - -int _bus_dmamap_create (bus_dma_tag_t, bus_size_t, int, bus_size_t, - bus_size_t, int, bus_dmamap_t *); -void _bus_dmamap_destroy (bus_dma_tag_t, bus_dmamap_t); -int _bus_dmamap_load (bus_dma_tag_t, bus_dmamap_t, void *, - bus_size_t, struct proc *, int); -int _bus_dmamap_load_mbuf (bus_dma_tag_t, bus_dmamap_t, - struct mbuf *, int); -int _bus_dmamap_load_uio (bus_dma_tag_t, bus_dmamap_t, - struct uio *, int); -int _bus_dmamap_load_raw (bus_dma_tag_t, bus_dmamap_t, - bus_dma_segment_t *, int, bus_size_t, int); -void _bus_dmamap_unload (bus_dma_tag_t, bus_dmamap_t); -void _bus_dmamap_sync (bus_dma_tag_t, bus_dmamap_t, bus_addr_t, - bus_size_t, int); - -int _bus_dmamem_alloc (bus_dma_tag_t tag, bus_size_t size, - bus_size_t alignment, bus_size_t boundary, - bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags); -void _bus_dmamem_free (bus_dma_tag_t tag, bus_dma_segment_t *segs, - int nsegs); -int _bus_dmamem_map (bus_dma_tag_t tag, bus_dma_segment_t *segs, - int nsegs, size_t size, caddr_t *kvap, int flags); -void _bus_dmamem_unmap (bus_dma_tag_t tag, caddr_t kva, - size_t size); -paddr_t _bus_dmamem_mmap (bus_dma_tag_t tag, bus_dma_segment_t *segs, - int nsegs, off_t off, int prot, int flags); - -int _bus_dmamem_alloc_range (bus_dma_tag_t tag, bus_size_t size, - bus_size_t alignment, bus_size_t boundary, - bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, - vaddr_t low, vaddr_t high); -#endif /* _ARM32_BUS_DMA_PRIVATE */ /* These are OpenBSD extensions to the general NetBSD bus interface. */ void bus_space_read_raw_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh, diff --git a/sys/arch/arm/include/bus_dma.h b/sys/arch/arm/include/bus_dma.h new file mode 100644 index 00000000000..29e649f508f --- /dev/null +++ b/sys/arch/arm/include/bus_dma.h @@ -0,0 +1,299 @@ +/* $OpenBSD: bus.h,v 1.17 2017/05/08 00:27:45 dlg Exp $ */ +/* $NetBSD: bus.h,v 1.12 2003/10/23 15:03:24 scw Exp $ */ + +/*- + * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1996 Charles M. Hannum. All rights reserved. + * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christopher G. Demetriou + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARM_BUS_DMA_H_ +#define _ARM_BUS_DMA_H_ + +/* Bus Space DMA macros */ + +/* + * Flags used in various bus DMA methods. + */ +#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_STREAMING 0x0008 /* hint: sequential, unidirectional */ +#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_READ 0x0100 /* mapping is device -> memory only */ +#define BUS_DMA_WRITE 0x0200 /* mapping is memory -> device only */ +#define BUS_DMA_NOCACHE 0x0400 /* hint: map non-cached memory */ +#define BUS_DMA_ZERO 0x0800 /* dmamem_alloc returns zeroed mem */ +#define BUS_DMA_64BIT 0x1000 /* device handles 64bit dva */ + +/* + * Private flags stored in the DMA map. + */ +#define ARM32_DMAMAP_COHERENT 0x10000 /* no cache flush necessary on sync */ + +/* Forwards needed by prototypes below. */ +struct mbuf; +struct uio; + +/* + * Operations performed by bus_dmamap_sync(). + */ +#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ +#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ +#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ +#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ + +typedef struct arm32_bus_dma_tag *bus_dma_tag_t; +typedef struct arm32_bus_dmamap *bus_dmamap_t; + +#define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0) + +/* + * bus_dma_segment_t + * + * Describes a single contiguous DMA transaction. Values + * are suitable for programming into DMA registers. + */ +struct arm32_bus_dma_segment { + /* + * PUBLIC MEMBERS: these are used by machine-independent code. + */ + bus_addr_t ds_addr; /* DMA address */ + bus_size_t ds_len; /* length of transfer */ + /* + * PRIVATE MEMBERS: not for use by machine-independent code. + */ + bus_addr_t _ds_vaddr; /* Virtual mapped address + * Used by bus_dmamem_sync() */ + int _ds_coherent; /* Coherently mapped */ +}; +typedef struct arm32_bus_dma_segment bus_dma_segment_t; + +/* + * arm32_dma_range + * + * This structure describes a valid DMA range. + */ +struct arm32_dma_range { + bus_addr_t dr_sysbase; /* system base address */ + bus_addr_t dr_busbase; /* appears here on bus */ + bus_size_t dr_len; /* length of range */ +}; + +/* + * bus_dma_tag_t + * + * A machine-dependent opaque type describing the implementation of + * DMA for a given bus. + */ + +struct arm32_bus_dma_tag { + /* + * DMA range for this tag. If the page doesn't fall within + * one of these ranges, an error is returned. The caller + * may then decide what to do with the transfer. If the + * range pointer is NULL, it is ignored. + */ + struct arm32_dma_range *_ranges; + int _nranges; + + /* + * Opaque cookie for use by back-end. + */ + void *_cookie; + + /* + * DMA mapping methods. + */ + int (*_dmamap_create) (bus_dma_tag_t, bus_size_t, int, + bus_size_t, bus_size_t, int, bus_dmamap_t *); + void (*_dmamap_destroy) (bus_dma_tag_t, bus_dmamap_t); + int (*_dmamap_load) (bus_dma_tag_t, bus_dmamap_t, void *, + bus_size_t, struct proc *, int); + int (*_dmamap_load_mbuf) (bus_dma_tag_t, bus_dmamap_t, + struct mbuf *, int); + int (*_dmamap_load_uio) (bus_dma_tag_t, bus_dmamap_t, + struct uio *, int); + int (*_dmamap_load_raw) (bus_dma_tag_t, bus_dmamap_t, + bus_dma_segment_t *, int, bus_size_t, int); + void (*_dmamap_unload) (bus_dma_tag_t, bus_dmamap_t); + void (*_dmamap_sync) (bus_dma_tag_t, bus_dmamap_t, + bus_addr_t, bus_size_t, int); + + /* + * DMA memory utility functions. + */ + int (*_dmamem_alloc) (bus_dma_tag_t, bus_size_t, bus_size_t, + bus_size_t, bus_dma_segment_t *, int, int *, int); + void (*_dmamem_free) (bus_dma_tag_t, + bus_dma_segment_t *, int); + int (*_dmamem_map) (bus_dma_tag_t, bus_dma_segment_t *, + int, size_t, caddr_t *, int); + void (*_dmamem_unmap) (bus_dma_tag_t, caddr_t, size_t); + paddr_t (*_dmamem_mmap) (bus_dma_tag_t, bus_dma_segment_t *, + int, off_t, int, int); +}; + +#define bus_dmamap_create(t, s, n, m, b, f, p) \ + (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) +#define bus_dmamap_destroy(t, p) \ + (*(t)->_dmamap_destroy)((t), (p)) +#define bus_dmamap_load(t, m, b, s, p, f) \ + (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) +#define bus_dmamap_load_mbuf(t, m, b, f) \ + (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) +#define bus_dmamap_load_uio(t, m, u, f) \ + (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) +#define bus_dmamap_load_raw(t, m, sg, n, s, f) \ + (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) +#define bus_dmamap_unload(t, p) \ + (*(t)->_dmamap_unload)((t), (p)) +#define bus_dmamap_sync(t, p, o, l, ops) \ + (void)((t)->_dmamap_sync ? \ + (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0) + +#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ + (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) +#define bus_dmamem_free(t, sg, n) \ + (*(t)->_dmamem_free)((t), (sg), (n)) +#define bus_dmamem_map(t, sg, n, s, k, f) \ + (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) +#define bus_dmamem_unmap(t, k, s) \ + (*(t)->_dmamem_unmap)((t), (k), (s)) +#define bus_dmamem_mmap(t, sg, n, o, p, f) \ + (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) + +/* + * bus_dmamap_t + * + * Describes a DMA mapping. + */ +struct arm32_bus_dmamap { + /* + * PRIVATE MEMBERS: not for use by machine-independent code. + */ + bus_size_t _dm_size; /* largest DMA transfer mappable */ + int _dm_segcnt; /* number of segs this map can map */ + bus_size_t _dm_maxsegsz; /* largest possible segment */ + bus_size_t _dm_boundary; /* don't cross this */ + int _dm_flags; /* misc. flags */ + + void *_dm_origbuf; /* pointer to original buffer */ + int _dm_buftype; /* type of buffer */ + struct proc *_dm_proc; /* proc that owns the mapping */ + + void *_dm_cookie; /* cookie for bus-specific functions */ + + /* + * PUBLIC MEMBERS: these are used by machine-independent code. + */ + bus_size_t dm_mapsize; /* size of the mapping */ + int dm_nsegs; /* # valid segments in mapping */ + bus_dma_segment_t dm_segs[1]; /* segments; variable length */ +}; + +#ifdef _ARM32_BUS_DMA_PRIVATE + +/* _dm_buftype */ +#define ARM32_BUFTYPE_INVALID 0 +#define ARM32_BUFTYPE_LINEAR 1 +#define ARM32_BUFTYPE_MBUF 2 +#define ARM32_BUFTYPE_UIO 3 +#define ARM32_BUFTYPE_RAW 4 + +int arm32_dma_range_intersect(struct arm32_dma_range *, int, + paddr_t pa, psize_t size, paddr_t *pap, psize_t *sizep); + +int _bus_dmamap_create (bus_dma_tag_t, bus_size_t, int, bus_size_t, + bus_size_t, int, bus_dmamap_t *); +void _bus_dmamap_destroy (bus_dma_tag_t, bus_dmamap_t); +int _bus_dmamap_load (bus_dma_tag_t, bus_dmamap_t, void *, + bus_size_t, struct proc *, int); +int _bus_dmamap_load_mbuf (bus_dma_tag_t, bus_dmamap_t, + struct mbuf *, int); +int _bus_dmamap_load_uio (bus_dma_tag_t, bus_dmamap_t, + struct uio *, int); +int _bus_dmamap_load_raw (bus_dma_tag_t, bus_dmamap_t, + bus_dma_segment_t *, int, bus_size_t, int); +void _bus_dmamap_unload (bus_dma_tag_t, bus_dmamap_t); +void _bus_dmamap_sync (bus_dma_tag_t, bus_dmamap_t, bus_addr_t, + bus_size_t, int); + +int _bus_dmamem_alloc (bus_dma_tag_t tag, bus_size_t size, + bus_size_t alignment, bus_size_t boundary, + bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags); +void _bus_dmamem_free (bus_dma_tag_t tag, bus_dma_segment_t *segs, + int nsegs); +int _bus_dmamem_map (bus_dma_tag_t tag, bus_dma_segment_t *segs, + int nsegs, size_t size, caddr_t *kvap, int flags); +void _bus_dmamem_unmap (bus_dma_tag_t tag, caddr_t kva, + size_t size); +paddr_t _bus_dmamem_mmap (bus_dma_tag_t tag, bus_dma_segment_t *segs, + int nsegs, off_t off, int prot, int flags); + +int _bus_dmamem_alloc_range (bus_dma_tag_t tag, bus_size_t size, + bus_size_t alignment, bus_size_t boundary, + bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, + vaddr_t low, vaddr_t high); +#endif /* _ARM32_BUS_DMA_PRIVATE */ + +#endif /* !_ARM_BUS_DMA_H_ */ _______________________________________________________________________ 1/4: remove duplicate bus_dma_tags, and convert to using the existing mainbus_dma_tag, now exported via arm/mainbus/mainbus.h, to allow the death of arm/armv7/armv7var.h, eventually, i hope. diff --git a/sys/arch/arm/cortex/cortex.c b/sys/arch/arm/cortex/cortex.c index d2d6aa508b6..ec61887783a 100644 --- a/sys/arch/arm/cortex/cortex.c +++ b/sys/arch/arm/cortex/cortex.c @@ -46,32 +46,14 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/device.h> -#define _ARM32_BUS_DMA_PRIVATE + #include <machine/bus.h> + #include <arm/cpufunc.h> #include <arm/armv7/armv7var.h> #include <arm/cortex/cortex.h> #include <arm/mainbus/mainbus.h> -struct arm32_bus_dma_tag cortex_bus_dma_tag = { - 0, - 0, - NULL, - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap, -}; - /* Prototypes for functions provided */ int cortexmatch(struct device *, void *, void *); @@ -137,7 +119,7 @@ cortexsearch(struct device *parent, void *vcf, void *aux) ca.ca_name = cf->cf_driver->cd_name; ca.ca_iot = &armv7_bs_tag; - ca.ca_dmat = &cortex_bus_dma_tag; + ca.ca_dmat = &mainbus_dma_tag; ca.ca_periphbase = armv7_periphbase(); /* allow for devices to be disabled in UKC */ diff --git a/sys/arch/arm/mainbus/mainbus.h b/sys/arch/arm/mainbus/mainbus.h index 059ca2550e8..7783791ce76 100644 --- a/sys/arch/arm/mainbus/mainbus.h +++ b/sys/arch/arm/mainbus/mainbus.h @@ -28,4 +28,6 @@ union mainbus_attach_args { void mainbus_legacy_found(struct device *, char *); +extern struct arm32_bus_dma_tag mainbus_dma_tag; + #endif /* __MAINBUS_H__ */ diff --git a/sys/arch/armv7/armv7/armv7.c b/sys/arch/armv7/armv7/armv7.c index 6a70df184b7..48b0a0c2b52 100644 --- a/sys/arch/armv7/armv7/armv7.c +++ b/sys/arch/armv7/armv7/armv7.c @@ -20,31 +20,13 @@ #include <sys/systm.h> #include <sys/malloc.h> -#define _ARM32_BUS_DMA_PRIVATE #include <machine/bus.h> + #include <arm/armv7/armv7var.h> +#include <arm/mainbus/mainbus.h> #include <armv7/armv7/armv7var.h> #include <armv7/armv7/armv7_machdep.h> -struct arm32_bus_dma_tag armv7_bus_dma_tag = { - 0, - 0, - NULL, - _bus_dmamap_create, - _bus_dmamap_destroy, - _bus_dmamap_load, - _bus_dmamap_load_mbuf, - _bus_dmamap_load_uio, - _bus_dmamap_load_raw, - _bus_dmamap_unload, - _bus_dmamap_sync, - _bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap, -}; - struct armv7_dev *armv7_devs = NULL; #define DEVNAME(sc) (sc)->sc_dv.dv_xname @@ -115,7 +97,7 @@ armv7_attach(struct device *parent, struct device *self, void *aux) memset(&aa, 0, sizeof(aa)); aa.aa_dev = ad; aa.aa_iot = &armv7_bs_tag; - aa.aa_dmat = &armv7_bus_dma_tag; + aa.aa_dmat = &mainbus_dma_tag; if (config_found_sm(self, &aa, NULL, armv7_submatch) == NULL) printf("%s: device %s unit %d not configured\n", _______________________________________________________________________ 2/4: replaces the early bus space map support with ways more elegant approach, by checking in the one-and-only bus_space_map function used by armv7 (simplebus_bs_map essentially uses the the same *bs_map()). also removes the unnecessary bs_protos(bs_notimpl); from armv7_machdep.c, which might break the build later, if left around. diff --git a/sys/arch/arm/armv7/armv7_space.c b/sys/arch/arm/armv7/armv7_space.c index c7e9b686b8f..64907252b76 100644 --- a/sys/arch/arm/armv7/armv7_space.c +++ b/sys/arch/arm/armv7/armv7_space.c @@ -170,7 +170,16 @@ armv7_bs_map(void *t, uint64_t bpa, bus_size_t size, { u_long startpa, endpa, pa; vaddr_t va; - int pmap_flags = PMAP_DEVICE; + int pmap_flags; + extern int bootstrap_bs_map(void *, uint64_t, bus_size_t, + int, bus_space_handle_t *); + + /* + * Once pmap_bootstrap() has ran, pm_refs will be > 0, + * and we should be ready to provide non-bootstrap mappings + */ + if (pmap_kernel()->pm_refs == 0) + return bootstrap_bs_map(t, bpa, size, flags, bshp); startpa = trunc_page(bpa); endpa = round_page(bpa + size); @@ -183,8 +192,7 @@ armv7_bs_map(void *t, uint64_t bpa, bus_size_t size, *bshp = (bus_space_handle_t)(va + (bpa - startpa)); - if (flags & BUS_SPACE_MAP_CACHEABLE) - pmap_flags = 0; + pmap_flags = (flags & BUS_SPACE_MAP_CACHEABLE) ? 0 : PMAP_DEVICE; for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) pmap_kenter_pa(va, pa | pmap_flags, PROT_READ | PROT_WRITE); diff --git a/sys/arch/armv7/armv7/armv7_machdep.c b/sys/arch/armv7/armv7/armv7_machdep.c index aa1c549b29b..f7b3f6baf83 100644 --- a/sys/arch/armv7/armv7/armv7_machdep.c +++ b/sys/arch/armv7/armv7/armv7_machdep.c @@ -204,8 +204,6 @@ int bootstrap_bs_map(void *, uint64_t, bus_size_t, int, void process_kernel_args(char *); void consinit(void); -bs_protos(bs_notimpl); - #ifndef CONSPEED #define CONSPEED B115200 /* What u-boot */ #endif @@ -384,11 +382,6 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t loadaddr) void *node; extern uint32_t esym; /* &_end if no symbols are loaded */ - /* early bus_space_map support */ - struct bus_space tmp_bs_tag; - int (*map_func_save)(void *, uint64_t, bus_size_t, int, - bus_space_handle_t *); - if (arg0) esym = (uint32_t)arg0; @@ -406,19 +399,6 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t loadaddr) if (set_cpufuncs()) panic("cpu not recognized!"); - /* - * Temporarily replace bus_space_map() functions so that - * console devices can get mapped. - * - * Note that this relies upon the fact that both regular - * and a4x bus_space tags use the same map function. - */ - tmp_bs_tag = armv7_bs_tag; - map_func_save = armv7_bs_tag.bs_map; - armv7_bs_tag.bs_map = bootstrap_bs_map; - armv7_a4x_bs_tag.bs_map = bootstrap_bs_map; - tmp_bs_tag.bs_map = bootstrap_bs_map; - /* * Now, map the FDT area. * @@ -772,12 +752,6 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t loadaddr) vector_page_setprot(PROT_READ | PROT_EXEC); - /* - * Restore proper bus_space operation, now that pmap is initialized. - */ - armv7_bs_tag.bs_map = map_func_save; - armv7_a4x_bs_tag.bs_map = map_func_save; - #ifdef DDB db_machine_init(); _______________________________________________________________________ 3/4: The actual BUS_SPACE_NEW implementation, with some of the needed hacks/ifndef protections included, and the kernel config option to enable it. i do consider the hack to replace armv7_a4x_bs_tag as armv7_bs_tag really ugly, but necessary to not clutter the diff w/renames, so i chose those, over other options. While the cleanup diff to convert into mainbus_tag is not big, it touches around 10files or so(the removal of arm/armv7/armv7var.h, even if !bus_space_new would be around, it'd be cleaner to bring those old tags in via arm/mainbus/mainbus.h fwiw. imo.(there's header in armv7/armv7/ named as armv7var.h already, and it's being used like ^2 than arm/armv7/ one, and the dup-naming irritates.)). Still disabled from the build. diff --git a/sys/arch/arm/arm/bus_dma.c b/sys/arch/arm/arm/bus_dma.c index ce637651800..eb4d1547a23 100644 --- a/sys/arch/arm/arm/bus_dma.c +++ b/sys/arch/arm/arm/bus_dma.c @@ -1237,6 +1237,7 @@ arm32_dma_range_intersect(struct arm32_dma_range *ranges, int nranges, return (0); } +#ifndef BUS_SPACE_NEW /* * probably should be ppc_space_copy */ @@ -1277,3 +1278,4 @@ __C(bus_space_write_raw_multi_,BYTES)( bus_space_tag_t bst, \ BUS_SPACE_WRITE_RAW_MULTI_N(2,1,u_int16_t) BUS_SPACE_WRITE_RAW_MULTI_N(4,2,u_int32_t) +#endif /* !BUS_SPACE_NEW */ diff --git a/sys/arch/arm/armv7/armv7var.h b/sys/arch/arm/armv7/armv7var.h index 926bfaf9f83..25883d68f67 100644 --- a/sys/arch/arm/armv7/armv7var.h +++ b/sys/arch/arm/armv7/armv7var.h @@ -1,4 +1,10 @@ +#ifndef BUS_SPACE_NEW extern struct bus_space armv7_bs_tag; extern struct bus_space armv7_a4x_bs_tag; void armv7_intr_bootstrap(vaddr_t); +#else /* BUS_SPACE_NEW */ +/* XXX 'for now'-hack below.. minimal diffs ftw.? */ +#define armv7_a4x_bs_tag armv7_bs_tag +extern struct bus_space armv7_bs_tag; +#endif /* !BUS_SPACE_NEW */ diff --git a/sys/arch/arm/conf/files.arm b/sys/arch/arm/conf/files.arm index 9dae5a17689..31083d2e11c 100644 --- a/sys/arch/arm/conf/files.arm +++ b/sys/arch/arm/conf/files.arm @@ -37,8 +37,8 @@ attach cpu at mainbus # bus_space(9) define bus_space_generic -file arch/arm/arm/bus_space_asm_generic.S -file arch/arm/arm/bus_space_notimpl.S +file arch/arm/arm/bus_space_asm_generic.S !bus_space_new +file arch/arm/arm/bus_space_notimpl.S !bus_space_new file arch/arm/arm/arm_machdep.c file arch/arm/arm/ast.c @@ -68,11 +68,11 @@ file arch/arm/arm/stubs.c file arch/arm/arm/sys_machdep.c file arch/arm/arm/vm_machdep.c -file arch/arm/armv7/armv7_space.c cpu_armv7 -file arch/arm/armv7/armv7_a4x_space.c cpu_armv7 -file arch/arm/armv7/armv7_a4x_io.S cpu_armv7 +file arch/arm/armv7/armv7_space.c !bus_space_new +file arch/arm/armv7/armv7_a4x_space.c !bus_space_new +file arch/arm/armv7/armv7_a4x_io.S !bus_space_new file arch/arm/armv7/armv7_mutex.c cpu_armv7 -file arch/arm/armv7/bus_space_asm_armv7.S cpu_armv7 +file arch/arm/armv7/bus_space_asm_armv7.S !bus_space_new pseudo-device openprom file arch/arm/arm/openprom.c openprom needs-flag diff --git a/sys/arch/arm/include/bus.h b/sys/arch/arm/include/bus.h index b2c75cfdf76..cb27e3677c0 100644 --- a/sys/arch/arm/include/bus.h +++ b/sys/arch/arm/include/bus.h @@ -65,6 +65,8 @@ #ifndef _ARM_BUS_H_ #define _ARM_BUS_H_ +#ifndef BUS_SPACE_NEW + /* * Addresses (in bus space). */ @@ -664,4 +666,12 @@ bus_space_write_raw_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh, !!! bus_space_write_raw_region_8 unimplemented !!! #endif +#else /* BUS_SPACE_NEW */ +/* + * didn't bother figuring out the distrib/sets/lists/comp/md.armv7 + * as it's something i've never had to mess w/.. + */ +#include <machine/bus.h> +#endif /* !BUS_SPACE_NEW */ + #endif /* _ARM_BUS_H_ */ diff --git a/sys/arch/arm/mainbus/mainbus.c b/sys/arch/arm/mainbus/mainbus.c index bbe8f12385c..069e1c498ba 100644 --- a/sys/arch/arm/mainbus/mainbus.c +++ b/sys/arch/arm/mainbus/mainbus.c @@ -16,15 +16,22 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define _ARM32_BUS_DMA_PRIVATE + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/device.h> #include <sys/malloc.h> +#include <uvm/uvm_extern.h> + +#include <machine/bus.h> + #include <dev/ofw/openfirm.h> #include <dev/ofw/fdt.h> +#include <arm/armv7/armv7var.h> /* XXX */ #include <arm/mainbus/mainbus.h> int mainbus_match(struct device *, void *, void *); @@ -58,6 +65,18 @@ struct cfdriver mainbus_cd = { NULL, "mainbus", DV_DULL }; +#ifdef BUS_SPACE_NEW +vaddr_t mapiodev(paddr_t, psize_t, u_int); +int mainbus_map(void *, uint64_t, bus_size_t, int, bus_space_handle_t *); +void mainbus_unmap(void *, bus_space_handle_t, bus_size_t); + +struct bus_space /* XXX mainbus_bustag*/armv7_bs_tag = { + NULL, /* cookie */ + mainbus_map, + mainbus_unmap +}; +#endif /* BUS_SPACE_NEW */ + struct arm32_bus_dma_tag mainbus_dma_tag = { 0, 0, @@ -301,3 +320,77 @@ mainbus_legacy_found(struct device *self, char *name) config_found(self, &ma, NULL); } + +#ifdef BUS_SPACE_NEW +/* + * Map a range [pa, pa+size) in the given map to a kernel address + * in iomap space. + * + * Note: To be flexible, I did not put a restriction on the alignment + * of pa. However, it is advisable to have pa page aligned since otherwise, + * we might have several mappings for a given chunk of the IO page. + */ +vaddr_t +mapiodev(paddr_t addr, psize_t _size, u_int pa_flags) +{ + vaddr_t va, iova, off; + paddr_t pa, epa; + + /* sanity checks */ + if (_size <= 0) + return 0; + + epa = round_page(addr + _size); + if (epa < addr && epa != 0) + return 0; + pa = trunc_page(addr); + off = addr - pa; + + va = uvm_km_valloc(kernel_map, (_size = epa - pa)); + if (va == 0) + return 0; + iova = va + off; + + for (pa |= pa_flags, off = 0; off < _size; off += PAGE_SIZE) + pmap_kenter_pa(va + off, pa + off, PROT_READ | PROT_WRITE); + pmap_update(pmap_kernel()); + + return iova; +} + +int +mainbus_map(void *tag, uint64_t addr, bus_size_t size, int flags, + bus_space_handle_t *ret) +{ + vaddr_t map; + extern int bootstrap_bs_map(void *, uint64_t, bus_size_t, + int, bus_space_handle_t *); + + /* + * Once pmap_bootstrap() has ran, pm_refs will be > 0, + * and we should be ready to provide non-bootstrap mappings + */ + if (pmap_kernel()->pm_refs == 0) + return bootstrap_bs_map(tag, addr, size, flags, ret); + + /* XXX how about PMAP_NOCACHE here ?! */ + map = mapiodev(addr, size, (flags & BUS_SPACE_MAP_CACHEABLE) + ? 0 : PMAP_DEVICE); + if (map == 0) + return ENOMEM; + + *ret = (bus_space_handle_t)map; + return 0; +} + +void +mainbus_unmap(void *tag, bus_space_handle_t handle, bus_size_t size) +{ + vaddr_t va = trunc_page((vaddr_t)handle); + vaddr_t eva = round_page((vaddr_t)handle + size); + + pmap_kremove(va, eva - va); + pmap_update(pmap_kernel()); + uvm_km_free(kernel_map, handle, size); +} +#endif /* BUS_SPACE_NEW */ diff --git a/sys/arch/arm/simplebus/simplebus.c b/sys/arch/arm/simplebus/simplebus.c index 9385954cc87..cd6c4dfcce6 100644 --- a/sys/arch/arm/simplebus/simplebus.c +++ b/sys/arch/arm/simplebus/simplebus.c @@ -21,6 +21,8 @@ #include <sys/device.h> #include <sys/malloc.h> +#include <machine/bus.h> + #include <dev/ofw/openfirm.h> #include <dev/ofw/fdt.h> diff --git a/sys/arch/armv7/conf/GENERIC b/sys/arch/armv7/conf/GENERIC index ac19567c520..f8114052a53 100644 --- a/sys/arch/armv7/conf/GENERIC +++ b/sys/arch/armv7/conf/GENERIC @@ -16,6 +16,7 @@ makeoptions KERNEL_BASE_VIRT="0xc0300000" maxusers 32 # estimated number of users option CPU_ARMv7 # Support the ARMv7 +#option BUS_SPACE_NEW # Support the inline bus space #option WSDISPLAY_COMPAT_USL # VT handling option WSDISPLAY_COMPAT_RAWKBD # can get raw scancodes diff --git a/sys/arch/armv7/conf/RAMDISK b/sys/arch/armv7/conf/RAMDISK index 5a30802a377..af01c7f0df8 100644 --- a/sys/arch/armv7/conf/RAMDISK +++ b/sys/arch/armv7/conf/RAMDISK @@ -6,6 +6,7 @@ makeoptions KERNEL_BASE_VIRT="0xc0300000" maxusers 4 # estimated number of users option CPU_ARMv7 # Support the ARMv7 +#option BUS_SPACE_NEW # Support the inline bus space option TIMEZONE=0 option DST=0 diff --git a/sys/arch/armv7/include/bus.h b/sys/arch/armv7/include/bus.h index ed737761885..e7e5214f4e1 100644 --- a/sys/arch/armv7/include/bus.h +++ b/sys/arch/armv7/include/bus.h @@ -1,4 +1,670 @@ /* $OpenBSD: bus.h,v 1.1 2013/09/04 14:38:26 patrick Exp $ */ /* $NetBSD: bus.h,v 1.3 2001/11/25 15:55:55 thorpej Exp $ */ +/* + * Copyright (c) 2004, Miodrag Vallat. + * Copyright (c) 2017 Artturi Alm. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _MACHINE_BUS_H_ +#define _MACHINE_BUS_H_ + +#ifndef BUS_SPACE_NEW #include <arm/bus.h> +#else /* BUS_SPACE_NEW */ + +/* + * Simple ARMv7 bus_space and bus_dma implementation. + * + * Currently, we only need specific handling for a4x bus space, + * and this choice is made at compile time. As a result, all the + * implementation can go through macros or inline functions, except for + * the management functions bs_map() and bs_unmap(), of which currently + * only bs_map() is overloaded by simplebus. + */ + +#include <sys/types.h> + +/* + * 'neat' a4x-space hack.. + * "too much MD" to include .h w/addresses<<2 in com.c (o_O), oh well. + * XXX _bs_off() used where not necessary. + */ +#ifdef COM_CONSOLE +#define _BUS_SPACE_A4X_ +#endif +#ifdef _BUS_SPACE_A4X_ +#define _bs_off(o) ((o) << 2) +#ifndef COM_CONSOLE /* stupid, but just in case. */ +#warning " >> _BUS_SPACE_A4X_ << ?!?" +#endif +#else /* !_BUS_SPACE_A4X_ */ +#define _bs_off(o) (o) +#endif /* _BUS_SPACE_A4X_ */ + +#define _cpu_dsb() asm volatile("dsb sy\n") +#define _cpu_isb() asm volatile("isb sy\n") + +typedef u_long bus_addr_t; +typedef u_long bus_size_t; + +typedef u_long bus_space_handle_t; + +#define BUS_SPACE_BARRIER_READ 0x01 +#define BUS_SPACE_BARRIER_WRITE 0x02 + +#define BUS_SPACE_MAP_CACHEABLE 0x01 +#define BUS_SPACE_MAP_LINEAR 0x02 +#define BUS_SPACE_MAP_PREFETCHABLE 0x04 + + +/* + * General bus_space function set + */ + +typedef struct bus_space { + void *bs_cookie; + int (*bs_map)(void *, uint64_t, bus_size_t, int, + bus_space_handle_t *); + void (*bs_unmap)(void *, bus_space_handle_t, bus_size_t); +} *bus_space_tag_t; + +#define bus_space_map(t,a,s,f,r) \ + (*(t)->bs_map)((t)->bs_cookie,(a),(s),(f),(r)) +#define bus_space_unmap(t,h,s) \ + (*(t)->bs_unmap)((t)->bs_cookie,(h),(s)) +static inline int bus_space_subregion(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, bus_size_t, bus_space_handle_t *); +static inline void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t); +static inline void bus_space_barrier(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, bus_size_t, int); + +int +bus_space_subregion(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, bus_size_t size, bus_space_handle_t *ret) +{ + *ret = handle + offset; + return 0; +} + +void * +bus_space_vaddr(bus_space_tag_t tag, bus_space_handle_t handle) +{ + return (void *)handle; +} + +void +bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, bus_size_t size, int flags) +{ + _cpu_dsb(); + _cpu_isb(); /* overkill? */ +} + +#define _bus_space_read_1(handle, offset) \ + (*(volatile u_int8_t *)((handle) + (offset))) +#define _bus_space_read_2(handle, offset) \ + (*(volatile u_int16_t *)((handle) + (offset))) +#define _bus_space_read_4(handle, offset) \ + (*(volatile u_int32_t *)((handle) + (offset))) + +#define _bus_space_write_1(hdl, off, val) \ + (*(volatile u_int8_t *)((hdl) + (off)) = (val)) +#define _bus_space_write_2(hdl, off, val) \ + (*(volatile u_int16_t *)((hdl) + (off)) = (val)) +#define _bus_space_write_4(hdl, off, val) \ + (*(volatile u_int32_t *)((hdl) + (off)) = (val)) + + +/* + * Read/Write/Set/Multi/Region/RawMulti/RawRegion functions. + * Most of these are straightforward and assume that everything is properly + * aligned. + */ +static inline uint8_t bus_space_read_1(bus_space_tag_t, bus_space_handle_t, + bus_addr_t); +static inline uint16_t bus_space_read_2(bus_space_tag_t, bus_space_handle_t, + bus_addr_t); +static inline uint32_t bus_space_read_4(bus_space_tag_t, bus_space_handle_t, + bus_addr_t); + + +static inline void bus_space_read_multi_1(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int8_t *, size_t); +static inline void bus_space_read_multi_2(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int16_t *, size_t); +static inline void bus_space_read_multi_4(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int32_t *, size_t); + + +static inline void bus_space_read_raw_multi_2(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int8_t *, size_t); +static inline void bus_space_read_raw_multi_4(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int8_t *, size_t); + + +static inline void bus_space_read_region_1(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int8_t *, size_t); +static inline void bus_space_read_region_2(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int16_t *, size_t); +static inline void bus_space_read_region_4(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int32_t *, size_t); + + +static inline void bus_space_read_raw_region_2(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int8_t *, size_t); +static inline void bus_space_read_raw_region_4(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int8_t *, size_t); + + +static inline void bus_space_write_1(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, uint8_t); +static inline void bus_space_write_2(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, uint16_t); +static inline void bus_space_write_4(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, uint32_t); + + +static inline void bus_space_write_multi_1(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, uint8_t *, size_t); +static inline void bus_space_write_multi_2(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, uint16_t *, size_t); +static inline void bus_space_write_multi_4(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, uint32_t *, size_t); + + +static inline void bus_space_write_raw_multi_2(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, uint8_t *, size_t); +static inline void bus_space_write_raw_multi_4(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int8_t *, size_t); + + +static inline void bus_space_set_multi_1(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int8_t, size_t); +static inline void bus_space_set_multi_2(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int16_t, size_t); +static inline void bus_space_set_multi_4(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int32_t, size_t); + + +static inline void bus_space_write_region_1(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int8_t *, size_t); +static inline void bus_space_write_region_2(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int16_t *, size_t); +static inline void bus_space_write_region_4(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int32_t *, size_t); + + +static inline void bus_space_write_raw_region_2(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int8_t *, size_t); +static inline void bus_space_write_raw_region_4(bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int8_t *, size_t); + + +static inline void bus_space_set_region_1(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int8_t, size_t); +static inline void bus_space_set_region_2(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int16_t, size_t); +static inline void bus_space_set_region_4(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, u_int32_t, size_t); + + +static inline void bus_space_copy_1(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, bus_space_handle_t, bus_addr_t, bus_size_t); +static inline void bus_space_copy_2(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, bus_space_handle_t, bus_addr_t, bus_size_t); +static inline void bus_space_copy_4(bus_space_tag_t, bus_space_handle_t, + bus_addr_t, bus_space_handle_t, bus_addr_t, bus_size_t); + + +/* + * read 1/2/4 + */ +uint8_t +bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset) +{ + _cpu_dsb(); + return _bus_space_read_1(handle, _bs_off(offset)); +} +uint16_t +bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset) +{ + _cpu_dsb(); + return _bus_space_read_2(handle, _bs_off(offset)); +} +uint32_t +bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset) +{ + _cpu_dsb(); + return _bus_space_read_4(handle, _bs_off(offset)); +} + + +/* + * read multi 1/2/4 + */ +void +bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + *dest++ = _bus_space_read_1(handle, offset); + _cpu_dsb(); +} +void +bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int16_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + *dest++ = _bus_space_read_2(handle, offset); + _cpu_dsb(); +} +void +bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int32_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + *dest++ = _bus_space_read_4(handle, offset); + _cpu_dsb(); +} + + +/* + * read raw multi 2/4 + */ +void +bus_space_read_raw_multi_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t size) +{ + offset = _bs_off(offset); + size >>= 1; + while ((int)--size >= 0) { + *(u_int16_t *)dest = _bus_space_read_2(handle, offset); + dest += 2; + } + _cpu_dsb(); +} +void +bus_space_read_raw_multi_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t size) +{ + offset = _bs_off(offset); + size >>= 2; + while ((int)--size >= 0) { + *(u_int32_t *)dest = _bus_space_read_4(handle, offset); + dest += 4; + } + _cpu_dsb(); +} +#define bus_space_read_raw_multi_8 \ + !!! bus_space_read_raw_multi_8 ERROR !!! + + +/* + * read region 1/2/4 + */ +void +bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + *dest++ = _bus_space_read_1(handle, offset++); + _cpu_dsb(); +} +void +bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int16_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) { + *dest++ = _bus_space_read_2(handle, offset); + offset += 2; + } + _cpu_dsb(); +} +void +bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int32_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) { + *dest++ = _bus_space_read_4(handle, offset); + offset += 4; + } + _cpu_dsb(); +} + + +/* + * read raw region 2/4 + */ +void +bus_space_read_raw_region_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t size) +{ + offset = _bs_off(offset); + size >>= 1; + while ((int)--size >= 0) { + *(u_int16_t *)dest = _bus_space_read_2(handle, offset); + offset += 2; + dest += 2; + } + _cpu_dsb(); +} +void +bus_space_read_raw_region_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t size) +{ + offset = _bs_off(offset); + size >>= 2; + while ((int)--size >= 0) { + *(u_int32_t *)dest = _bus_space_read_4(handle, offset); + offset += 4; + dest += 4; + } + _cpu_dsb(); +} +#define bus_space_read_raw_region_8 \ + !!! bus_space_read_raw_region_8 ERROR !!! + +/* + * write 1/2/4 + */ +void +bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, uint8_t value) +{ + _bus_space_write_1(handle, _bs_off(offset), value); + _cpu_dsb(); +} +void +bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, uint16_t value) +{ + _bus_space_write_2(handle, _bs_off(offset), value); + _cpu_dsb(); +} +void +bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, uint32_t value) +{ + _bus_space_write_4(handle, _bs_off(offset), value); + _cpu_dsb(); +} + + +/* + * write multi 1/2/4 + */ +void +bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, uint8_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + _bus_space_write_1(handle, offset, *dest++); + _cpu_dsb(); +} +void +bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, uint16_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + _bus_space_write_2(handle, offset, *dest++); + _cpu_dsb(); +} +void +bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, uint32_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + _bus_space_write_4(handle, offset, *dest++); + _cpu_dsb(); +} + + +/* + * write raw multi 2/4 + */ +void +bus_space_write_raw_multi_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, uint8_t *dest, size_t size) +{ + offset = _bs_off(offset); + size >>= 1; + while ((int)--size >= 0) { + _bus_space_write_2(handle, offset, *(uint16_t *)dest); + dest += 2; + } + _cpu_dsb(); +} +void +bus_space_write_raw_multi_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t size) +{ + offset = _bs_off(offset); + size >>= 2; + while ((int)--size >= 0) { + _bus_space_write_4(handle, offset, *(u_int32_t *)dest); + dest += 4; + } + _cpu_dsb(); +} +#define bus_space_write_raw_multi_8 \ + !!! bus_space_write_raw_multi_8 ERROR !!! + +/* + * set multi 1/2/4 + */ +void +bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t value, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + _bus_space_write_1(handle, offset, value); + _cpu_dsb(); +} +void +bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int16_t value, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + _bus_space_write_2(handle, offset, value); + _cpu_dsb(); +} +void +bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int32_t value, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + _bus_space_write_4(handle, offset, value); + _cpu_dsb(); +} + + +/* + * write region 1/2/4 + */ +void +bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + _bus_space_write_1(handle, offset++, *dest++); + _cpu_dsb(); +} +void +bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int16_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) { + _bus_space_write_2(handle, offset, *dest++); + offset += 2; + } + _cpu_dsb(); +} +void +bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int32_t *dest, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) { + _bus_space_write_4(handle, offset, *dest++); + offset += 4; + } + _cpu_dsb(); +} + + +/* + * write raw region 2/4 + */ +void +bus_space_write_raw_region_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t size) +{ + offset = _bs_off(offset); + size >>= 1; + while ((int)--size >= 0) { + _bus_space_write_2(handle, offset, *(u_int16_t *)dest); + offset += 2; + dest += 2; + } + _cpu_dsb(); +} +void +bus_space_write_raw_region_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t *dest, size_t size) +{ + offset = _bs_off(offset); + size >>= 2; + while ((int)--size >= 0) { + _bus_space_write_4(handle, offset, *(u_int32_t *)dest); + offset += 4; + dest += 4; + } + _cpu_dsb(); +} +#define bus_space_write_raw_region_8 \ + !!! bus_space_write_raw_region_8 ERROR !!! + +/* + * set region 1/2/4 + */ +void +bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int8_t value, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) + _bus_space_write_1(handle, offset++, value); + _cpu_dsb(); +} +void +bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int16_t value, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) { + _bus_space_write_2(handle, offset, value); + offset += 2; + } + _cpu_dsb(); +} +void +bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t handle, + bus_addr_t offset, u_int32_t value, size_t count) +{ + offset = _bs_off(offset); + while ((int)--count >= 0) { + _bus_space_write_4(handle, offset, value); + offset += 4; + } + _cpu_dsb(); +} + + +/* + * copy 1/2/4 + */ +void +bus_space_copy_1(bus_space_tag_t tag, bus_space_handle_t h1, bus_addr_t o1, + bus_space_handle_t h2, bus_addr_t o2, bus_size_t count) +{ + o1 = h1 + _bs_off(o1); + o2 = h2 + _bs_off(o2); + while ((int)--count >= 0) { + *(volatile u_int8_t *)o1 = *(volatile u_int8_t *)o2; + _cpu_dsb(); + o1++; + o2++; + } +} +void +bus_space_copy_2(bus_space_tag_t tag, bus_space_handle_t h1, bus_addr_t o1, + bus_space_handle_t h2, bus_addr_t o2, bus_size_t count) +{ + o1 = h1 + _bs_off(o1); + o2 = h2 + _bs_off(o2); + while ((int)--count >= 0) { + *(volatile u_int16_t *)o1 = *(volatile u_int16_t *)o2; + _cpu_dsb(); + o1 += 2; + o2 += 2; + } +} +void +bus_space_copy_4(bus_space_tag_t tag, bus_space_handle_t h1, bus_addr_t o1, + bus_space_handle_t h2, bus_addr_t o2, bus_size_t count) +{ + o1 = h1 + _bs_off(o1); + o2 = h2 + _bs_off(o2); + while ((int)--count >= 0) { + *(volatile u_int32_t *)o1 = *(volatile u_int32_t *)o2; + _cpu_dsb(); + o1 += 4; + o2 += 4; + } +} + +/* + * Bus DMA + */ +#include <arm/bus_dma.h> + +#endif /* !BUS_SPACE_NEW */ +#endif /* _MACHINE_BUS_H_ */ _______________________________________________________________________ 4/4: use COM_CONSOLE define as trigger for 'a4x bus space', and enable for build. This is likely the most controversial part of the diffs to bring in the inline bus space support.. diff --git a/sys/arch/armv7/conf/GENERIC b/sys/arch/armv7/conf/GENERIC index f8114052a53..6f64d66a71c 100644 --- a/sys/arch/armv7/conf/GENERIC +++ b/sys/arch/armv7/conf/GENERIC @@ -16,7 +16,7 @@ makeoptions KERNEL_BASE_VIRT="0xc0300000" maxusers 32 # estimated number of users option CPU_ARMv7 # Support the ARMv7 -#option BUS_SPACE_NEW # Support the inline bus space +option BUS_SPACE_NEW # Support the inline bus space #option WSDISPLAY_COMPAT_USL # VT handling option WSDISPLAY_COMPAT_RAWKBD # can get raw scancodes diff --git a/sys/arch/armv7/conf/RAMDISK b/sys/arch/armv7/conf/RAMDISK index af01c7f0df8..db30ac4e216 100644 --- a/sys/arch/armv7/conf/RAMDISK +++ b/sys/arch/armv7/conf/RAMDISK @@ -6,7 +6,7 @@ makeoptions KERNEL_BASE_VIRT="0xc0300000" maxusers 4 # estimated number of users option CPU_ARMv7 # Support the ARMv7 -#option BUS_SPACE_NEW # Support the inline bus space +option BUS_SPACE_NEW # Support the inline bus space option TIMEZONE=0 option DST=0 diff --git a/sys/arch/armv7/dev/com_fdt.c b/sys/arch/armv7/dev/com_fdt.c index 00504801850..d269a9d6366 100644 --- a/sys/arch/armv7/dev/com_fdt.c +++ b/sys/arch/armv7/dev/com_fdt.c @@ -21,6 +21,7 @@ #include <sys/tty.h> #include <machine/intr.h> +#define COM_CONSOLE #include <machine/bus.h> #include <machine/fdt.h> diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c index ba3dfce322a..a9543b5938b 100644 --- a/sys/dev/ic/com.c +++ b/sys/dev/ic/com.c @@ -78,10 +78,10 @@ #include <ddb/db_var.h> #endif +#define COM_CONSOLE #include <machine/bus.h> #include <machine/intr.h> -#define COM_CONSOLE #include <dev/cons.h> #include <dev/ic/comreg.h>