1 /* $NetBSD: amiga_bus_simple_1word.c,v 1.9 2014/08/06 14:23:53 joerg Exp $ */
2 
3 /*-
4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Ignatios Souvatzis.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 #include <sys/param.h>
32 #include <sys/device.h>
33 #include <sys/systm.h>
34 
35 #include <machine/cpu.h>
36 #include <machine/pte.h>
37 
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(1, "$NetBSD: amiga_bus_simple_1word.c,v 1.9 2014/08/06 14:23:53 joerg Exp $");
40 
41 #define AMIGA_SIMPLE_BUS_STRIDE 1		/* 1 byte per byte */
42 #define AMIGA_SIMPLE_BUS_WORD_METHODS
43 #define AMIGA_SIMPLE_BUS_LONGWORD_METHODS
44 
45 #include "simple_busfuncs.c"
46 
47 bsr(oabs(bsr2_swap_), u_int16_t);
48 bsw(oabs(bsw2_swap_), u_int16_t);
49 bsr(oabs(bsr4_swap_), u_int32_t);
50 bsw(oabs(bsw4_swap_), u_int32_t);
51 
52 bsrm(oabs(bsrm2_swap_), u_int16_t);
53 bswm(oabs(bswm2_swap_), u_int16_t);
54 
55 int oabs(bsm_absolute_)(bus_space_tag_t, bus_addr_t, bus_size_t, int,
56 			bus_space_handle_t *);
57 
58 /* ARGSUSED */
59 int
oabs(bsm_absolute_)60 oabs(bsm_absolute_)(bus_space_tag_t tag, bus_addr_t address,
61 	bus_size_t size, int flags, bus_space_handle_t *handlep)
62 {
63 	uint32_t pa = kvtop((void*) tag->base);
64 	*handlep = tag->base + (address - pa) * AMIGA_SIMPLE_BUS_STRIDE;
65 	return 0;
66 }
67 
68 /* ARGSUSED */
69 u_int16_t
oabs(bsr2_swap_)70 oabs(bsr2_swap_)(bus_space_handle_t handle, bus_size_t offset)
71 {
72 	volatile u_int16_t *p;
73 	u_int16_t x;
74 
75 	p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
76 	x = *p;
77 	amiga_bus_reorder_protect();
78 	return bswap16(x);
79 }
80 
81 /* ARGSUSED */
82 void
oabs(bsw2_swap_)83 oabs(bsw2_swap_)(bus_space_handle_t handle, bus_size_t offset, unsigned value)
84 {
85 	volatile u_int16_t *p;
86 
87 	p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
88 	*p = bswap16( (u_int16_t)value );
89 	amiga_bus_reorder_protect();
90 }
91 
92 /* ARGSUSED */
93 u_int32_t
oabs(bsr4_swap_)94 oabs(bsr4_swap_)(bus_space_handle_t handle, bus_size_t offset)
95 {
96 	volatile u_int32_t *p;
97 	u_int32_t x;
98 
99 	p = (volatile u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
100 	x = *p;
101 	amiga_bus_reorder_protect();
102 	return bswap32(x);
103 }
104 
105 /* ARGSUSED */
106 void
oabs(bsw4_swap_)107 oabs(bsw4_swap_)(bus_space_handle_t handle, bus_size_t offset, unsigned value)
108 {
109 	volatile u_int32_t *p;
110 
111 	p = (volatile u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
112 	*p = bswap32( (u_int32_t)value );
113 	amiga_bus_reorder_protect();
114 }
115 
116 /* ARGSUSED */
117 void
oabs(bsrm2_swap_)118 oabs(bsrm2_swap_)(bus_space_handle_t handle, bus_size_t offset,
119 			u_int16_t *pointer, bus_size_t count)
120 {
121 	volatile u_int16_t *p;
122 
123 	p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
124 
125 	while (count > 0) {
126 		*pointer++ = bswap16(*p);
127 		amiga_bus_reorder_protect();
128 		--count;
129 	}
130 }
131 
132 /* ARGSUSED */
133 void
oabs(bswm2_swap_)134 oabs(bswm2_swap_)(bus_space_handle_t handle, bus_size_t offset,
135 			const u_int16_t *pointer, bus_size_t count)
136 {
137         volatile u_int16_t *p;
138 
139         p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
140 
141         while (count > 0) {
142                 *p = bswap16(*pointer);
143                 amiga_bus_reorder_protect();
144                 ++pointer;
145                 --count;
146         }
147 }
148 
149 const struct amiga_bus_space_methods amiga_bus_stride_1swap_abs = {
150 
151 	.bsm =		oabs(bsm_absolute_),
152 	.bsms =		oabs(bsms_),
153 	.bsu =		oabs(bsu_),
154 	.bsa =		NULL,
155 	.bsf =		NULL,
156 
157 	.bsr1 =		oabs(bsr1_),
158 	.bsw1 =		oabs(bsw1_),
159 	.bsrm1 =	oabs(bsrm1_),
160 	.bswm1 =	oabs(bswm1_),
161 	.bsrr1 =	oabs(bsrr1_),
162 	.bswr1 =	oabs(bswr1_),
163 	.bssr1 =	oabs(bssr1_),
164 	.bscr1 =	oabs(bscr1_),
165 
166 	.bsr2 =		oabs(bsr2_),            /* XXX swap? */
167 	.bsw2 =		oabs(bsw2_),            /* XXX swap? */
168 	.bsrs2 =	oabs(bsr2_),
169 	.bsws2 =	oabs(bsw2_),
170 	.bsrm2 =	oabs(bsrm2_swap_),
171 	.bswm2 =	oabs(bswm2_swap_),
172 	.bsrms2 =	oabs(bsrm2_),
173 	.bswms2 =	oabs(bswm2_),
174 	.bsrr2 =	oabs(bsrr2_),           /* XXX swap? */
175 	.bswr2 =	oabs(bswr2_),           /* XXX swap? */
176 	.bssr2 =	oabs(bssr2_),           /* XXX swap? */
177 	.bscr2 =	oabs(bscr2_),           /* XXX swap? */
178 
179 	.bsr4 =		oabs(bsr4_swap_),
180 	.bsw4 =		oabs(bsw4_swap_),
181 	.bsrs4 =	oabs(bsr4_),
182 	.bsws4 =	oabs(bsw4_),
183 	.bsrm4 =	oabs(bsrm4_),		/* XXX swap? */
184 	.bswm4 =	oabs(bswm4_),		/* XXX swap? */
185 	.bsrms4 =	oabs(bsrm4_),
186 	.bswms4 =	oabs(bswm4_),
187 	.bsrr4 =	oabs(bsrr4_),		/* XXX swap? */
188 	.bswr4 =	oabs(bswr4_),		/* XXX swap? */
189 	.bsrrs4 =	oabs(bsrr4_),
190 	.bswrs4 =	oabs(bswr4_),
191 	.bssr4 =	oabs(bssr4_),		/* XXX swap? */
192 	.bscr4 =	oabs(bscr4_)		/* XXX swap? */
193 };
194 
195 const struct amiga_bus_space_methods amiga_bus_stride_1swap = {
196 
197 	.bsm =		oabs(bsm_),
198 	.bsms =		oabs(bsms_),
199 	.bsu =		oabs(bsu_),
200 	.bsa =		NULL,
201 	.bsf =		NULL,
202 
203 	.bsr1 =		oabs(bsr1_),
204 	.bsw1 =		oabs(bsw1_),
205 	.bsrm1 =	oabs(bsrm1_),
206 	.bswm1 =	oabs(bswm1_),
207 	.bsrr1 =	oabs(bsrr1_),
208 	.bswr1 =	oabs(bswr1_),
209 	.bssr1 =	oabs(bssr1_),
210 	.bscr1 =	oabs(bscr1_),
211 
212 	.bsr2 =		oabs(bsr2_swap_),
213 	.bsw2 =		oabs(bsw2_swap_),
214 	.bsrs2 =	oabs(bsr2_),
215 	.bsws2 =	oabs(bsw2_),
216 	.bsrm2 =	oabs(bsrm2_swap_),
217 	.bswm2 =	oabs(bswm2_swap_),
218 	.bsrms2 =	oabs(bsrm2_),
219 	.bswms2 =	oabs(bswm2_),
220 	.bsrr2 =	oabs(bsrr2_),		/* XXX swap? */
221 	.bswr2 =	oabs(bswr2_),		/* XXX swap? */
222 	.bsrrs2 =	oabs(bsrr2_),
223 	.bswrs2 =	oabs(bswr2_),
224 	.bssr2 =	oabs(bssr2_),		/* XXX swap? */
225 	.bscr2 =	oabs(bscr2_),		/* XXX swap? */
226 
227 	.bsr4 =		oabs(bsr4_swap_),
228 	.bsw4 =		oabs(bsw4_swap_),
229 	.bsrs4 =	oabs(bsr4_),
230 	.bsws4 =	oabs(bsw4_),
231 	.bsrm4 =	oabs(bsrm4_),		/* XXX swap? */
232 	.bswm4 =	oabs(bswm4_),		/* XXX swap? */
233 	.bsrms4 =	oabs(bsrm4_),
234 	.bswms4 =	oabs(bswm4_),
235 	.bsrr4 =	oabs(bsrr4_),		/* XXX swap? */
236 	.bswr4 =	oabs(bswr4_),		/* XXX swap? */
237 	.bsrrs4 =	oabs(bsrr4_),
238 	.bswrs4 =	oabs(bswr4_),
239 	.bssr4 = 	oabs(bssr4_),		/* XXX swap? */
240 	.bscr4 =	oabs(bscr4_)		/* XXX swap? */
241 };
242