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. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * 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 int bus_space_tag_t;
typedef u_long bus_space_handle_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_map __P((bus_space_tag_t, bus_addr_t, bus_size_t,
int, bus_space_handle_t *)); int, bus_space_handle_t *));
void bus_space_unmap __P((bus_space_tag_t, bus_space_handle_t,
bus_size_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, 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)); 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, 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_addr_t rend, bus_size_t size, bus_size_t align,
bus_size_t boundary, int cacheable, bus_addr_t *addrp, bus_size_t boundary, int cacheable, bus_addr_t *addrp,
bus_space_handle_t *bshp)); 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, void bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t size)); 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, * u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
* bus_space_handle_t bsh, bus_size_t offset)); * 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. * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
*/ */
#define bus_space_copy_1(t, h1, o1, h2, o2, c) do { \ #define __MAC68K_copy_region_N(BYTES) \
(void) t; \ static __inline void __CONCAT(bus_space_copy_region_,BYTES) \
__asm __volatile (" \ __P((bus_space_tag_t, \
movl %0,a0 ; \ bus_space_handle_t bsh1, bus_size_t off1, \
movl %1,a1 ; \ bus_space_handle_t bsh2, bus_size_t off2, \
movl %2,d0 ; \ bus_size_t count)); \
1: movb a0@+,a1@+ ; \ \
subql #1,d0 ; \ static __inline void \
jne 1b" : \ __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c) \
: \ bus_space_tag_t t; \
"r" ((h1) + (o1)), "r" ((h2) + (o2)), "g" (c) : \ bus_space_handle_t h1, h2; \
"a0","a1","d0"); \ bus_size_t o1, o2, c; \
} while (0); { \
bus_size_t o; \
#define bus_space_copy_2(t, h1, o1, h2, o2, c) do { \ \
(void) t; \ if ((h1 + o1) >= (h2 + o2)) { \
__asm __volatile (" \ /* src after dest: copy forward */ \
movl %0,a0 ; \ for (o = 0; c != 0; c--, o += BYTES) \
movl %1,a1 ; \ __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
movl %2,d0 ; \ __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
1: movw a0@+,a1@+ ; \ } else { \
subql #1,d0 ; \ /* dest after src: copy backwards */ \
jne 1b" : \ for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
: \ __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
"r" ((h1) + (o1)), "r" ((h2) + (o2)), "g" (c) : \ __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
"a0","a1","d0"); \ } \
} while (0); }
__MAC68K_copy_region_N(1)
#define bus_space_copy_4(t, h1, o1, h2, o2, c) do { \ __MAC68K_copy_region_N(2)
(void) t; \ __MAC68K_copy_region_N(4)
__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);
#if 0 /* Cause a link error for bus_space_copy_8 */ #if 0 /* Cause a link error for bus_space_copy_8 */
#define bus_space_copy_8 \ #define bus_space_copy_8 \
!!! bus_space_copy_8 unimplemented !!! !!! bus_space_copy_8 unimplemented !!!
#endif #endif
#undef __MAC68K_copy_region_N
/* /*
* Bus read/write barrier methods. * 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) \ #define bus_space_barrier(t, h, o, l, f) \
((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
#define BUS_BARRIER_READ 0x01 /* force read barrier */ #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
#define BUS_BARRIER_WRITE 0x02 /* force write barrier */ #define BUS_SPACE_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));
#endif /* _MAC68K_BUS_H_ */ #endif /* _MAC68K_BUS_H_ */