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 3d36366c95b..95f1e527c14 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 af71a6c4835..c9e893358a9 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 56e64893df6..af2f6ad262e 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_ */