diff --git a/sys/arch/amiga/amiga/busfuncs.c b/sys/arch/amiga/amiga/busfuncs.c new file mode 100644 index 000000000000..a991c145d4b5 --- /dev/null +++ b/sys/arch/amiga/amiga/busfuncs.c @@ -0,0 +1,294 @@ +/* $NetBSD: busfuncs.c,v 1.1 1998/10/08 21:46:39 is Exp $ */ + +/* + * Copyright (c) 1998 Ignatios Souvatzis. 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 Ignatios Souvatzis 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. + */ + +/* + * Amiga bus access methods for data widths > 1 + * XXX currently, only 16bit methods are defined + */ + +#include + +bsr(amiga_contiguous_read_2, u_int16_t); +bsw(amiga_contiguous_write_2, u_int16_t); +bsrm(amiga_contiguous_read_multi_2, u_int16_t); +bswm(amiga_contiguous_write_multi_2, u_int16_t); +bsrm(amiga_contiguous_read_region_2, u_int16_t); +bswm(amiga_contiguous_write_region_2, u_int16_t); + +bsr(amiga_interleaved_read_2, u_int16_t); +bsw(amiga_interleaved_write_2, u_int16_t); +bsrm(amiga_interleaved_read_multi_2, u_int16_t); +bswm(amiga_interleaved_write_multi_2, u_int16_t); +bsrm(amiga_interleaved_read_region_2, u_int16_t); +bswm(amiga_interleaved_write_region_2, u_int16_t); + +const struct amiga_bus_space_methods amiga_contiguous_methods = { + amiga_contiguous_read_2, + amiga_contiguous_write_2, + amiga_contiguous_read_multi_2, + amiga_contiguous_write_multi_2, + amiga_contiguous_read_region_2, + amiga_contiguous_write_region_2, + /* identical to the above here */ + amiga_contiguous_read_region_2, + amiga_contiguous_write_region_2 +}; + +const struct amiga_bus_space_methods amiga_interleaved_methods = { + amiga_interleaved_read_2, + amiga_interleaved_write_2, + amiga_interleaved_read_multi_2, + amiga_interleaved_write_multi_2, + amiga_interleaved_read_region_2, + amiga_interleaved_write_region_2, + /* identical to the above here */ + amiga_interleaved_read_region_2, + amiga_interleaved_write_region_2 +}; + +/* + * Contiguous methods + * Be sure to only create word accesses. + * For busses that _need_ split byte accesses, use the interleaved functions. + */ + +u_int16_t +amiga_contiguous_read_2(t, h, o) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; +{ + /* ARGSUSED */ + return (* (u_int16_t *) (h + o)); /* only used if t->stride == 0 */ +} + +void +amiga_contiguous_write_2(t, h, o, v) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t v; +{ + /* ARGSUSED */ + * (u_int16_t *) (h + o) = v; +} + +void +amiga_contiguous_read_multi_2(t, h, o, p, s) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t *p; + bus_size_t s; +{ + /* ARGSUSED */ + volatile u_int16_t *q = (volatile u_int16_t *)(h + o); + + while (s-- > 0) { + *p++ = *q; + } +} + +void +amiga_contiguous_write_multi_2(t, h, o, p, s) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t *p; + bus_size_t s; +{ + /* ARGSUSED */ + volatile u_int16_t *q = (volatile u_int16_t *)(h + o); + + while (s-- > 0) { + *q = *p++; + } +} + +void +amiga_contiguous_read_region_2(t, h, o, p, s) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t *p; + bus_size_t s; +{ + /* ARGSUSED */ + volatile u_int16_t *q = (volatile u_int16_t *)(h + o); + + while (s-- > 0) { + *p++ = *q++; + } +} + +void +amiga_contiguous_write_region_2(t, h, o, p, s) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t *p; + bus_size_t s; +{ + /* ARGSUSED */ + volatile u_int16_t *q = (volatile u_int16_t *)(h + o); + + while (s-- > 0) { + *q++ = *p++; + } +} + +/* + * Interleaved methods. + * These use single-byte acceses. In case of stride = 0, the contiguous + * methods are preferred, as they only create word accesses. + */ + +u_int16_t +amiga_interleaved_read_2(t, h, o) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; +{ + volatile u_int8_t *q; + int step; + + step = 1 << t->stride; + q = (volatile u_int8_t *)(h + (o << t->stride)); + + return ((*q) << 8) | *(q + step); +} + +void +amiga_interleaved_write_2(t, h, o, v) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t v; +{ + volatile u_int8_t *q; + int step; + + step = 1 << t->stride; + q = (volatile u_int8_t *)(h + (o << t->stride)); + + *q = v >> 8; + *(q+step) = v; +} + +void +amiga_interleaved_read_multi_2(t, h, o, p, s) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t *p; + bus_size_t s; +{ + volatile u_int8_t *q; + int step; + + step = 1 << t->stride; + q = (volatile u_int8_t *)(h + (o << t->stride)); + + while (s-- > 0) { + *p++ = ((*q)<<8) | *(q+step); + } +} + +void +amiga_interleaved_write_multi_2(t, h, o, p, s) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t *p; + bus_size_t s; +{ + volatile u_int8_t *q; + int step; + u_int16_t v; + + step = 1 << t->stride; + q = (volatile u_int8_t *)(h + (o << t->stride)); + + while (s-- > 0) { + v = *p++; + *q = v>>8; + *(q + step) = v; + } +} + +void +amiga_interleaved_read_region_2(t, h, o, p, s) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t *p; + bus_size_t s; +{ + volatile u_int8_t *q; + int step; + u_int16_t v; + + step = 1 << t->stride; + q = (volatile u_int8_t *)(h + (o << t->stride)); + + while (s-- > 0) { + v = (*q) << 8; + q += step; + v |= *q; + q += step; + *p++ = v; + } +} + +void +amiga_interleaved_write_region_2(t, h, o, p, s) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o; + u_int16_t *p; + bus_size_t s; +{ + volatile u_int8_t *q; + int step; + u_int16_t v; + + step = 1 << t->stride; + q = (volatile u_int8_t *)(h + (o << t->stride)); + + while (s-- > 0) { + v = *p++; + *q = v >> 8; + q += step; + *q = v; + q += step; + } +} diff --git a/sys/arch/amiga/conf/files.amiga b/sys/arch/amiga/conf/files.amiga index 4ae3c40ab7c5..4b8c2201a93e 100644 --- a/sys/arch/amiga/conf/files.amiga +++ b/sys/arch/amiga/conf/files.amiga @@ -1,4 +1,4 @@ -# $NetBSD: files.amiga,v 1.76 1998/09/02 22:32:08 is Exp $ +# $NetBSD: files.amiga,v 1.77 1998/10/08 21:46:39 is Exp $ # maxpartitions must be first item in files.${ARCH}.newconf maxpartitions 16 # NOTE THAT AMIGA IS SPECIAL! @@ -190,7 +190,7 @@ device drsupio: supio attach drsupio at mainbus file arch/amiga/dev/drsupio.c drsupio -# Hypercom 3/4 +# ZBus HyperComs: HyperCom Z3, HyperCom 4 device hyper: supio attach hyper at zbus file arch/amiga/dev/hyper.c hyper @@ -350,6 +350,7 @@ file dev/cons.c ite | ser file dev/cninit.c ite | ser file arch/amiga/amiga/amiga_init.c file arch/amiga/amiga/autoconf.c +file arch/amiga/amiga/busfuncs.c file arch/amiga/amiga/cia.c file arch/amiga/amiga/conf.c file arch/amiga/amiga/disksubr.c diff --git a/sys/arch/amiga/include/bus.h b/sys/arch/amiga/include/bus.h index bc93a5926594..bd66520f6ce8 100644 --- a/sys/arch/amiga/include/bus.h +++ b/sys/arch/amiga/include/bus.h @@ -1,4 +1,4 @@ -/* $NetBSD: bus.h,v 1.3 1998/09/02 23:00:04 is Exp $ */ +/* $NetBSD: bus.h,v 1.4 1998/10/08 21:46:39 is Exp $ */ /* * Copyright (c) 1996 Leo Weppelman. All rights reserved. @@ -33,51 +33,88 @@ #ifndef _AMIGA_BUS_H_ #define _AMIGA_BUS_H_ +#include /* * Memory addresses (in bus space) */ -typedef u_long bus_addr_t; -typedef u_long bus_size_t; +typedef u_int32_t bus_addr_t; +typedef u_int32_t bus_size_t; /* * Access methods for bus resources and address space. */ -typedef struct bus_space_tag { - bus_addr_t base; - u_char stride; -} *bus_space_tag_t; - +typedef struct bus_space_tag *bus_space_tag_t; typedef u_long bus_space_handle_t; +#define bsr(what, typ) \ + typ (what)(bus_space_tag_t, bus_space_handle_t, bus_size_t) + +#define bsw(what, typ) \ + void (what)(bus_space_tag_t, bus_space_handle_t, bus_size_t, typ) + +#define bsrm(what, typ) \ + void (what)(bus_space_tag_t, bus_space_handle_t, bus_size_t, \ + typ *, bus_size_t) + +#define bswm(what, typ) \ + void (what)(bus_space_tag_t, bus_space_handle_t, bus_size_t, \ + typ *, bus_size_t) + +struct amiga_bus_space_methods { + /* 16bit methods */ + bsr(*bsr2, u_int16_t); + bsw(*bsw2, u_int16_t); + bsrm(*bsrm2, u_int16_t); + bswm(*bswm2, u_int16_t); + bsrm(*bsrr2, u_int16_t); + bswm(*bswr2, u_int16_t); + bsrm(*bsrs2, u_int16_t); + bswm(*bsws2, u_int16_t); +}; + +struct bus_space_tag { + bus_addr_t base; + u_int8_t stride; + u_int8_t dum[3]; + struct amiga_bus_space_methods *absm; +}; + +#define bus_space_read_2(t, h, o) ((t)->bsr2)((t), (h), (o)) +#define bus_space_write_2(t, h, o, v) ((t)->bsw2)((t), (h), (o), (v)) + +#define bus_space_read_multi_2(t, h, o, p, c) \ + ((t)->absm->bsrm2)((t), (h), (o), (p), (c)) + +#define bus_space_write_multi_2(t, h, o, p, c) \ + ((t)->absm->bswm2)((t), (h), (o), (p), (c)) + +#define bus_space_read_region_2(t, h, o, p, c) \ + ((t)->absm->bsrr2)((t), (h), (o), (p), (c)) + +#define bus_space_write_region_2(t, h, o, p, c) \ + ((t)->absm->bswr2)((t), (h), (o), (p), (c)) + +#define bus_space_read_stream_2(t, h, o, p, c) \ + ((t)->absm->bsrs2)((t), (h), (o), (p), (c)) + +#define bus_space_write_stream_2(t, h, o, p, c) \ + ((t)->absm->bsws2)((t), (h), (o), (p), (c)) + + void bus_space_read_multi_1 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); -void bus_space_read_multi_2 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); -void bus_space_read_multi_4 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); -void bus_space_read_multi_8 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); + bus_size_t, u_int8_t *, bus_size_t)); void bus_space_write_multi_1 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); -void bus_space_write_multi_2 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); -void bus_space_write_multi_4 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); -void bus_space_write_multi_8 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); + bus_size_t, u_int8_t *, bus_size_t)); void bus_space_read_region_1 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); - + bus_size_t, u_int8_t *, bus_size_t)); void bus_space_write_region_1 __P((bus_space_tag_t, bus_space_handle_t, - int, caddr_t, int)); + bus_size_t, u_int8_t *, bus_size_t)); -#if 0 -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)); -#endif +void bus_space_read_stream_1 __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t *, bus_size_t)); +void bus_space_write_stream_1 __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t, u_int8_t *, bus_size_t)); #define bus_space_map(tag,off,size,cache,handle) \ (*(handle) = (tag)->base + ((off)<<(tag)->stride), 0) @@ -97,112 +134,65 @@ extern __inline__ void bus_space_read_multi_1(t, h, o, a, c) bus_space_tag_t t; bus_space_handle_t h; - int o, c; - caddr_t a; + bus_size_t o, c; + u_int8_t *a; { for (; c; a++, c--) - *(u_int8_t *)a = bus_space_read_1(t, h, o); + *a = bus_space_read_1(t, h, o); } -#ifdef notyet -extern __inline__ void -bus_space_read_multi_2(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - int o, c; - caddr_t a; -{ - for (; c; a += 2, c--) - *(u_int16_t *)a = bus_space_read_2(t, h, o); -} - -extern __inline__ void -bus_space_read_multi_4(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - int o, c; - caddr_t a; -{ - for (; c; a += 4, c--) - *(u_int32_t *)a = bus_space_read_4(t, h, o); -} - -extern __inline__ void -bus_space_read_multi_8(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - int o, c; - caddr_t a; -{ - for (; c; a += 8, c--) - *(u_int64_t *)a = bus_space_read_8(t, h, o); -} -#endif extern __inline__ void bus_space_write_multi_1(t, h, o, a, c) bus_space_tag_t t; bus_space_handle_t h; - int o, c; - caddr_t a; + bus_size_t o, c; + u_int8_t *a; { for (; c; a++, c--) - bus_space_write_1(t, h, o, *(u_int8_t *)a); + bus_space_write_1(t, h, o, *a); } -#ifdef notyet -extern __inline__ void -bus_space_write_multi_2(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - int o, c; - caddr_t a; -{ - for (; c; a += 2, c--) - bus_space_write_2(t, h, o, *(u_int16_t *)a); -} - -extern __inline__ void -bus_space_write_multi_4(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - int o, c; - caddr_t a; -{ - for (; c; a += 4, c--) - bus_space_write_4(t, h, o, *(u_int32_t *)a); -} - -extern __inline__ void -bus_space_write_multi_8(t, h, o, a, c) - bus_space_tag_t t; - bus_space_handle_t h; - int o, c; - caddr_t a; -{ - for (; c; a += 8, c--) - bus_space_write_8(t, h, o, *(u_int64_t *)a); -} -#endif - extern __inline__ void bus_space_read_region_1(t, h, o, a, c) bus_space_tag_t t; bus_space_handle_t h; - int o, c; - caddr_t a; + bus_size_t o, c; + u_int8_t *a; { for (; c; a++, c--) - *(u_int8_t *)a = bus_space_read_1(t, h, o++); + *a = bus_space_read_1(t, h, o++); } extern __inline__ void bus_space_write_region_1(t, h, o, a, c) bus_space_tag_t t; bus_space_handle_t h; - int o, c; - caddr_t a; + bus_size_t o, c; + u_int8_t *a; { for (; c; a++, c--) - bus_space_write_1(t, h, o++, *(u_int8_t *)a); + bus_space_write_1(t, h, o++, *a); +} + +extern __inline__ void +bus_space_read_stream_1(t, h, o, a, c) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o, c; + u_int8_t *a; +{ + for (; c; a++, c--) + *a = bus_space_read_1(t, h, o++); +} + +extern __inline__ void +bus_space_write_stream_1(t, h, o, a, c) + bus_space_tag_t t; + bus_space_handle_t h; + bus_size_t o, c; + u_int8_t *a; +{ + for (; c; a++, c--) + bus_space_write_1(t, h, o++, *a); } #endif /* _AMIGA_BUS_H_ */