- define framework for >8bit transfers

- implement 16 bit contiguous and 16 bit interleaved, both big-endian
This commit is contained in:
is 1998-10-08 21:46:39 +00:00
parent 0a70a74239
commit 6662b5ed74
3 changed files with 399 additions and 114 deletions

View File

@ -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 <machine/bus.h>
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;
}
}

View File

@ -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

View File

@ -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 <sys/types.h>
/*
* 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_ */