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_ */