Conform to spec, and make bus_space_copy() handle overlapping copies.

From Jason Thorpe.
This commit is contained in:
scottr 1998-01-13 18:32:15 +00:00
parent 057795048f
commit 5b4a54759d
1 changed files with 95 additions and 55 deletions

View File

@ -1,7 +1,7 @@
/* $NetBSD: bus.h,v 1.8 1997/10/10 05:54:48 scottr Exp $ */
/* $NetBSD: bus.h,v 1.9 1998/01/13 18:32:15 scottr Exp $ */
/*-
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -83,20 +83,76 @@ typedef u_long bus_size_t;
typedef int bus_space_tag_t;
typedef u_long bus_space_handle_t;
/*
* int bus_space_map __P((bus_space_tag_t t, bus_addr_t addr,
* bus_size_t size, int flags, bus_space_handle_t *bshp));
*
* Map a region of bus space.
*/
#define BUS_SPACE_MAP_CACHEABLE 0x01
#define BUS_SPACE_MAP_LINEAR 0x02
int bus_space_map __P((bus_space_tag_t, bus_addr_t, bus_size_t,
int, bus_space_handle_t *));
void bus_space_unmap __P((bus_space_tag_t, bus_space_handle_t,
bus_size_t));
int, bus_space_handle_t *));
/*
* void bus_space_unmap __P((bus_space_tag_t t,
* bus_space_handle_t bsh, bus_size_t size));
*
* Unmap a region of bus space.
*/
void bus_space_unmap __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
/*
* int bus_space_subregion __P((bus_space_tag_t t,
* bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
* bus_space_handle_t *nbshp));
*
* Get a new handle for a subregion of an already-mapped area of bus space.
*/
int bus_space_subregion __P((bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp));
/*
* int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t, rstart,
* bus_addr_t rend, bus_size_t size, bus_size_t align,
* bus_size_t boundary, int flags, bus_addr_t *addrp,
* bus_space_handle_t *bshp));
*
* Allocate a region of bus space.
*/
int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
bus_addr_t rend, bus_size_t size, bus_size_t align,
bus_size_t boundary, int cacheable, bus_addr_t *addrp,
bus_space_handle_t *bshp));
/*
* int bus_space_free __P((bus_space_tag_t t,
* bus_space_handle_t bsh, bus_size_t size));
*
* Free a region of bus space.
*/
void bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t size));
/*
* int mac68k_bus_space_probe __P((bus_space_tag_t t,
* bus_space_handle_t bsh, bus_size_t offset, int sz));
*
* Probe the bus at t/bsh/offset, using sz as the size of the load.
*
* This is a machine-dependent extension, and is not to be used by
* machine-independent code.
*/
int mac68k_bus_space_probe __P((bus_space_tag_t t,
bus_space_handle_t bsh, bus_size_t offset, int sz));
/*
* u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
* bus_space_handle_t bsh, bus_size_t offset));
@ -485,53 +541,43 @@ void bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
* at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
*/
#define bus_space_copy_1(t, h1, o1, h2, o2, c) do { \
(void) t; \
__asm __volatile (" \
movl %0,a0 ; \
movl %1,a1 ; \
movl %2,d0 ; \
1: movb a0@+,a1@+ ; \
subql #1,d0 ; \
jne 1b" : \
: \
"r" ((h1) + (o1)), "r" ((h2) + (o2)), "g" (c) : \
"a0","a1","d0"); \
} while (0);
#define bus_space_copy_2(t, h1, o1, h2, o2, c) do { \
(void) t; \
__asm __volatile (" \
movl %0,a0 ; \
movl %1,a1 ; \
movl %2,d0 ; \
1: movw a0@+,a1@+ ; \
subql #1,d0 ; \
jne 1b" : \
: \
"r" ((h1) + (o1)), "r" ((h2) + (o2)), "g" (c) : \
"a0","a1","d0"); \
} while (0);
#define bus_space_copy_4(t, h1, o1, h2, o2, c) do { \
(void) t; \
__asm __volatile (" \
movl %0,a0 ; \
movl %1,a1 ; \
movl %2,d0 ; \
1: movl a0@+,a1@+ ; \
subql #1,d0 ; \
jne 1b" : \
: \
"r" ((h1) + (o1)), "r" ((h2) + (o2)), "g" (c) : \
"a0","a1","d0"); \
} while (0);
#define __MAC68K_copy_region_N(BYTES) \
static __inline void __CONCAT(bus_space_copy_region_,BYTES) \
__P((bus_space_tag_t, \
bus_space_handle_t bsh1, bus_size_t off1, \
bus_space_handle_t bsh2, bus_size_t off2, \
bus_size_t count)); \
\
static __inline void \
__CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c) \
bus_space_tag_t t; \
bus_space_handle_t h1, h2; \
bus_size_t o1, o2, c; \
{ \
bus_size_t o; \
\
if ((h1 + o1) >= (h2 + o2)) { \
/* src after dest: copy forward */ \
for (o = 0; c != 0; c--, o += BYTES) \
__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
__CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
} else { \
/* dest after src: copy backwards */ \
for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
__CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
} \
}
__MAC68K_copy_region_N(1)
__MAC68K_copy_region_N(2)
__MAC68K_copy_region_N(4)
#if 0 /* Cause a link error for bus_space_copy_8 */
#define bus_space_copy_8 \
!!! bus_space_copy_8 unimplemented !!!
#endif
#undef __MAC68K_copy_region_N
/*
* Bus read/write barrier methods.
*
@ -544,13 +590,7 @@ void bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
*/
#define bus_space_barrier(t, h, o, l, f) \
((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
#define BUS_BARRIER_READ 0x01 /* force read barrier */
#define BUS_BARRIER_WRITE 0x02 /* force write barrier */
/*
* Machine-dependent extensions.
*/
int bus_probe __P((bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, int sz));
#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
#endif /* _MAC68K_BUS_H_ */