xref: /netbsd/sys/arch/amiga/amiga/simple_busfuncs.c (revision 41ba3596)
1 /* $NetBSD: simple_busfuncs.c,v 1.11 2012/02/12 16:34:06 matt 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 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: simple_busfuncs.c,v 1.11 2012/02/12 16:34:06 matt Exp $");
34 
35 /*
36  * Do NOT use this standalone.
37  * Instead define the stride (linear, not logarithmic!) in the enclosing
38  * file (AMIGA_SIMPLE_BUS_STRIDE), then include this one.
39  * If you want to use it only to provide the functions without creating the
40  * method array, also define AMIGA_SIMPLE_BUS_NO_ARRAY
41  */
42 
43 #ifndef AMIGA_SIMPLE_BUS_STRIDE
44 Error AMIGA_SIMPLE_BUS_STRIDE not defined in __FILE__, line __LINE__ .
45 #endif
46 
47 #include <sys/bus.h>
48 #include <sys/null.h>
49 
50 #define MKN2(x,y) __CONCAT(x, y)
51 #define MKN1(x,y) MKN2(x, y)
52 #define oabs(n) MKN1(n, AMIGA_SIMPLE_BUS_STRIDE)
53 
54 /* function declarations */
55 
56 int oabs(bsm_)(bus_space_tag_t, bus_addr_t, bus_size_t, int,
57 	bus_space_handle_t *);
58 
59 int oabs(bsms_)(bus_space_handle_t, bus_size_t, bus_size_t,
60 	bus_space_handle_t *);
61 
62 void oabs(bsu_)(bus_space_handle_t, bus_size_t);
63 
64 bsr (oabs(bsr1_), u_int8_t);
65 bsw (oabs(bsw1_), u_int8_t);
66 bsrm(oabs(bsrm1_), u_int8_t);
67 bswm(oabs(bswm1_), u_int8_t);
68 bsrm(oabs(bsrr1_), u_int8_t);
69 bswm(oabs(bswr1_), u_int8_t);
70 bssr(oabs(bssr1_), u_int8_t);
71 bscr(oabs(bscr1_), u_int8_t);
72 
73 /* function definitions */
74 /* ARGSUSED */
75 int
oabs(bsm_)76 oabs(bsm_)(
77 	bus_space_tag_t tag,
78 	bus_addr_t address,
79 	bus_size_t size,
80 	int flags,
81 	bus_space_handle_t *handlep)
82 {
83 	*handlep = tag->base + address * AMIGA_SIMPLE_BUS_STRIDE;
84 	return 0;
85 }
86 
87 /* ARGSUSED */
88 int
oabs(bsms_)89 oabs(bsms_)(
90 	bus_space_handle_t handle,
91 	bus_size_t offset,
92 	bus_size_t size,
93 	bus_space_handle_t *nhandlep)
94 {
95 	*nhandlep = handle + offset * AMIGA_SIMPLE_BUS_STRIDE;
96 	return 0;
97 }
98 
99 /* ARGSUSED */
100 void
oabs(bsu_)101 oabs(bsu_)(
102 	bus_space_handle_t handle,
103 	bus_size_t size)
104 {
105 	return;
106 }
107 
108 u_int8_t
oabs(bsr1_)109 oabs(bsr1_)(
110 	bus_space_handle_t handle,
111 	bus_size_t offset)
112 {
113 	u_int8_t *p;
114 	u_int8_t x;
115 
116 	p = (u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
117 	x = *p;
118 	amiga_bus_reorder_protect();
119 	return x;
120 }
121 
122 void
oabs(bsw1_)123 oabs(bsw1_)(
124 	bus_space_handle_t handle,
125 	bus_size_t offset,
126 	unsigned value)
127 {
128 	u_int8_t *p;
129 
130 	p = (u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
131 	*p = (u_int8_t)value;
132 	amiga_bus_reorder_protect();
133 }
134 
135 void
oabs(bsrm1_)136 oabs(bsrm1_)(
137 	bus_space_handle_t handle,
138 	bus_size_t offset,
139 	u_int8_t *pointer,
140 	bus_size_t count)
141 {
142 	volatile u_int8_t *p;
143 
144 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
145 
146 	while (count > 0) {
147 		*pointer++ = *p;
148 		amiga_bus_reorder_protect();
149 		--count;
150 	}
151 }
152 
153 void
oabs(bswm1_)154 oabs(bswm1_)(
155 	bus_space_handle_t handle,
156 	bus_size_t offset,
157 	const u_int8_t *pointer,
158 	bus_size_t count)
159 {
160 	volatile u_int8_t *p;
161 
162 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
163 
164 	while (count > 0) {
165 		*p = *pointer++;
166 		amiga_bus_reorder_protect();
167 		--count;
168 	}
169 }
170 
171 void
oabs(bsrr1_)172 oabs(bsrr1_)(
173 	bus_space_handle_t handle,
174 	bus_size_t offset,
175 	u_int8_t *pointer,
176 	bus_size_t count)
177 {
178 	volatile u_int8_t *p;
179 
180 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
181 
182 	while (count > 0) {
183 		*pointer++ = *p;
184 		amiga_bus_reorder_protect();
185 		p += AMIGA_SIMPLE_BUS_STRIDE;
186 		--count;
187 	}
188 }
189 
190 void
oabs(bswr1_)191 oabs(bswr1_)(
192 	bus_space_handle_t handle,
193 	bus_size_t offset,
194 	const u_int8_t *pointer,
195 	bus_size_t count)
196 {
197 	volatile u_int8_t *p;
198 
199 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
200 
201 	while (count > 0) {
202 		*p = *pointer++;
203 		amiga_bus_reorder_protect();
204 		p += AMIGA_SIMPLE_BUS_STRIDE;
205 		--count;
206 	}
207 }
208 
209 void
oabs(bssr1_)210 oabs(bssr1_)(
211 	bus_space_handle_t handle,
212 	bus_size_t offset,
213 	unsigned value,
214 	bus_size_t count)
215 {
216 	volatile u_int8_t *p;
217 
218 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
219 
220 	while (count > 0) {
221 		*p = value;
222 		amiga_bus_reorder_protect();
223 		p += AMIGA_SIMPLE_BUS_STRIDE;
224 		--count;
225 	}
226 }
227 
228 void
oabs(bscr1_)229 oabs(bscr1_)(
230 	bus_space_handle_t handlefrom,
231 	bus_size_t from,
232 	bus_space_handle_t handleto,
233 	bus_size_t to,
234 	bus_size_t count)
235 {
236 	volatile u_int8_t *p, *q;
237 
238 	p = (volatile u_int8_t *)(handlefrom + from * AMIGA_SIMPLE_BUS_STRIDE);
239 	q = (volatile u_int8_t *)(handleto   +   to * AMIGA_SIMPLE_BUS_STRIDE);
240 
241 	while (count > 0) {
242 		*q = *p;
243 		amiga_bus_reorder_protect();
244 		p += AMIGA_SIMPLE_BUS_STRIDE;
245 		q += AMIGA_SIMPLE_BUS_STRIDE;
246 		--count;
247 	}
248 }
249 
250 
251 #ifdef AMIGA_SIMPLE_BUS_WORD_METHODS
252 
253 /* word methods */
254 
255 bsr (oabs(bsr2_), u_int16_t);
256 bsw (oabs(bsw2_), u_int16_t);
257 bsrm(oabs(bsrm2_), u_int16_t);
258 bswm(oabs(bswm2_), u_int16_t);
259 bsrm(oabs(bsrr2_), u_int16_t);
260 bswm(oabs(bswr2_), u_int16_t);
261 bssr(oabs(bssr2_), u_int16_t);
262 bscr(oabs(bscr2_), u_int16_t);
263 
264 u_int16_t
oabs(bsr2_)265 oabs(bsr2_)(
266 	bus_space_handle_t handle,
267 	bus_size_t offset)
268 {
269 	u_int16_t *p;
270 	u_int16_t x;
271 
272 	p = (u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
273 	x = *p;
274 	amiga_bus_reorder_protect();
275 	return x;
276 }
277 
278 void
oabs(bsw2_)279 oabs(bsw2_)(
280 	bus_space_handle_t handle,
281 	bus_size_t offset,
282 	unsigned value)
283 {
284 	u_int16_t *p;
285 
286 	p = (u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
287 	*p = (u_int16_t)value;
288 	amiga_bus_reorder_protect();
289 }
290 
291 void
oabs(bsrm2_)292 oabs(bsrm2_)(
293 	bus_space_handle_t handle,
294 	bus_size_t offset,
295 	u_int16_t *pointer,
296 	bus_size_t count)
297 {
298 	volatile u_int16_t *p;
299 
300 	p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
301 
302 	while (count > 0) {
303 		*pointer++ = *p;
304 		amiga_bus_reorder_protect();
305 		--count;
306 	}
307 }
308 
309 void
oabs(bswm2_)310 oabs(bswm2_)(
311 	bus_space_handle_t handle,
312 	bus_size_t offset,
313 	const u_int16_t *pointer,
314 	bus_size_t count)
315 {
316 	volatile u_int16_t *p;
317 
318 	p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
319 
320 	while (count > 0) {
321 		*p = *pointer++;
322 		amiga_bus_reorder_protect();
323 		--count;
324 	}
325 }
326 
327 void
oabs(bsrr2_)328 oabs(bsrr2_)(
329 	bus_space_handle_t handle,
330 	bus_size_t offset,
331 	u_int16_t *pointer,
332 	bus_size_t count)
333 {
334 	volatile u_int8_t *p;
335 
336 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
337 
338 	while (count > 0) {
339 		*pointer++ = *(volatile u_int16_t *)p;
340 		amiga_bus_reorder_protect();
341 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
342 		--count;
343 	}
344 }
345 
346 void
oabs(bswr2_)347 oabs(bswr2_)(
348 	bus_space_handle_t handle,
349 	bus_size_t offset,
350 	const u_int16_t *pointer,
351 	bus_size_t count)
352 {
353 	volatile u_int8_t *p;
354 
355 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
356 
357 	while (count > 0) {
358 		*(volatile u_int16_t *)p = *pointer++;
359 		amiga_bus_reorder_protect();
360 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
361 		--count;
362 	}
363 }
364 
365 void
oabs(bssr2_)366 oabs(bssr2_)(
367 	bus_space_handle_t handle,
368 	bus_size_t offset,
369 	unsigned value,
370 	bus_size_t count)
371 {
372 	volatile u_int8_t *p;
373 
374 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
375 
376 	while (count > 0) {
377 		*(volatile u_int16_t *)p = (unsigned)value;
378 		amiga_bus_reorder_protect();
379 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
380 		--count;
381 	}
382 }
383 
384 void
oabs(bscr2_)385 oabs(bscr2_)(
386 	bus_space_handle_t handlefrom,
387 	bus_size_t from,
388 	bus_space_handle_t handleto,
389 	bus_size_t to,
390 	bus_size_t count)
391 {
392 	volatile u_int8_t *p, *q;
393 
394 	p = (volatile u_int8_t *)(handlefrom + from * AMIGA_SIMPLE_BUS_STRIDE);
395 	q = (volatile u_int8_t *)(handleto   +   to * AMIGA_SIMPLE_BUS_STRIDE);
396 
397 	while (count > 0) {
398 		*(volatile u_int16_t *)q = *(volatile u_int16_t *)p;
399 		amiga_bus_reorder_protect();
400 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
401 		q += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
402 		--count;
403 	}
404 }
405 #endif /* AMIGA_SIMPLE_BUS_WORD_METHODS */
406 
407 #ifdef AMIGA_SIMPLE_BUS_LONGWORD_METHODS
408 
409 /* longword methods */
410 
411 bsr (oabs(bsr4_), u_int32_t);
412 bsw (oabs(bsw4_), u_int32_t);
413 bsrm(oabs(bsrm4_), u_int32_t);
414 bswm(oabs(bswm4_), u_int32_t);
415 bsrm(oabs(bsrr4_), u_int32_t);
416 bswm(oabs(bswr4_), u_int32_t);
417 bssr(oabs(bssr4_), u_int32_t);
418 bscr(oabs(bscr4_), u_int32_t);
419 
420 u_int32_t
oabs(bsr4_)421 oabs(bsr4_)(
422 	bus_space_handle_t handle,
423 	bus_size_t offset)
424 {
425 	u_int32_t *p;
426 	u_int32_t x;
427 
428 	p = (u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
429 	x = *p;
430 	amiga_bus_reorder_protect();
431 	return x;
432 }
433 
434 void
oabs(bsw4_)435 oabs(bsw4_)(
436 	bus_space_handle_t handle,
437 	bus_size_t offset,
438 	unsigned value)
439 {
440 	u_int32_t *p;
441 
442 	p = (u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
443 	*p = (u_int32_t)value;
444 	amiga_bus_reorder_protect();
445 }
446 
447 
448 void
oabs(bsrm4_)449 oabs(bsrm4_)(
450 	bus_space_handle_t handle,
451 	bus_size_t offset,
452 	u_int32_t *pointer,
453 	bus_size_t count)
454 {
455 	volatile u_int32_t *p;
456 
457 	p = (volatile u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
458 
459 	while (count > 0) {
460 		*pointer++ = *p;
461 		amiga_bus_reorder_protect();
462 		--count;
463 	}
464 }
465 
466 void
oabs(bswm4_)467 oabs(bswm4_)(
468 	bus_space_handle_t handle,
469 	bus_size_t offset,
470 	const u_int32_t *pointer,
471 	bus_size_t count)
472 {
473 	volatile u_int32_t *p;
474 
475 	p = (volatile u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
476 
477 	while (count > 0) {
478 		*p = *pointer++;
479 		amiga_bus_reorder_protect();
480 		--count;
481 	}
482 }
483 
484 void
oabs(bsrr4_)485 oabs(bsrr4_)(
486 	bus_space_handle_t handle,
487 	bus_size_t offset,
488 	u_int32_t *pointer,
489 	bus_size_t count)
490 {
491 	volatile u_int8_t *p;
492 
493 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
494 
495 	while (count > 0) {
496 		*pointer++ = *(volatile u_int32_t *)p;
497 		amiga_bus_reorder_protect();
498 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
499 		--count;
500 	}
501 }
502 
503 void
oabs(bswr4_)504 oabs(bswr4_)(
505 	bus_space_handle_t handle,
506 	bus_size_t offset,
507 	const u_int32_t *pointer,
508 	bus_size_t count)
509 {
510 	volatile u_int8_t *p;
511 
512 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
513 
514 	while (count > 0) {
515 		*(volatile u_int32_t *)p = *pointer++;
516 		amiga_bus_reorder_protect();
517 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
518 		--count;
519 	}
520 }
521 
522 void
oabs(bssr4_)523 oabs(bssr4_)(
524 	bus_space_handle_t handle,
525 	bus_size_t offset,
526 	unsigned value,
527 	bus_size_t count)
528 {
529 	volatile u_int8_t *p;
530 
531 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
532 
533 	while (count > 0) {
534 		*(volatile u_int32_t *)p = (unsigned)value;
535 		amiga_bus_reorder_protect();
536 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
537 		--count;
538 	}
539 }
540 
541 void
oabs(bscr4_)542 oabs(bscr4_)(
543 	bus_space_handle_t handlefrom,
544 	bus_size_t from,
545 	bus_space_handle_t handleto,
546 	bus_size_t to,
547 	bus_size_t count)
548 {
549 	volatile u_int8_t *p, *q;
550 
551 	p = (volatile u_int8_t *)(handlefrom + from * AMIGA_SIMPLE_BUS_STRIDE);
552 	q = (volatile u_int8_t *)(handleto   +   to * AMIGA_SIMPLE_BUS_STRIDE);
553 
554 	while (count > 0) {
555 		*(volatile u_int32_t *)q = *(volatile u_int32_t *)p;
556 		amiga_bus_reorder_protect();
557 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
558 		q += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
559 		--count;
560 	}
561 }
562 #endif /* AMIGA_SIMPLE_BUS_LONGWORD_METHODS */
563 
564 #ifndef AMIGA_SIMPLE_BUS_NO_ARRAY
565 /* method array */
566 
567 const struct amiga_bus_space_methods oabs(amiga_bus_stride_) = {
568 
569 	.bsm =		oabs(bsm_),
570 	.bsms =		oabs(bsms_),
571 	.bsu =		oabs(bsu_),
572 	.bsa =		NULL,
573 	.bsf =		NULL,
574 
575 	.bsr1 =	oabs(bsr1_),
576 	.bsw1 =		oabs(bsw1_),
577 	.bsrm1 =	oabs(bsrm1_),
578 	.bswm1 =	oabs(bswm1_),
579 	.bsrr1 =	oabs(bsrr1_),
580 	.bswr1 =	oabs(bswr1_),
581 	.bssr1 =	oabs(bssr1_),
582 	.bscr1 =	oabs(bscr1_),
583 
584 #ifdef AMIGA_SIMPLE_BUS_WORD_METHODS
585 	.bsr2 =		oabs(bsr2_),
586 	.bsw2 =		oabs(bsw2_),
587 	.bsrs2 =	oabs(bsr2_),
588 	.bsws2 =	oabs(bsw2_),
589 	.bsrm2 =	oabs(bsrm2_),
590 	.bswm2 =	oabs(bswm2_),
591 	.bsrms2 =	oabs(bsrm2_),
592 	.bswms2 =	oabs(bswm2_),
593 	.bsrr2 =	oabs(bsrr2_),
594 	.bswr2 =	oabs(bswr2_),
595 	.bsrrs2 =	oabs(bsrr2_),
596 	.bswrs2 =	oabs(bswr2_),
597 	.bssr2 =	oabs(bssr2_),
598 	.bscr2 =	oabs(bscr2_),
599 #endif /* AMIGA_SIMPLE_BUS_WORD_METHODS */
600 
601 #ifdef AMIGA_SIMPLE_BUS_LONGWORD_METHODS
602 	.bsr4 =		oabs(bsr4_),
603 	.bsw4 =		oabs(bsw4_),
604 	.bsrs4 =	oabs(bsr4_),
605 	.bsws4 =	oabs(bsw4_),
606 	.bsrm4 =	oabs(bsrm4_),
607 	.bswm4 =	oabs(bswm4_),
608 	.bsrms4 =	oabs(bsrm4_),
609 	.bswms4 =	oabs(bswm4_),
610 	.bsrr4 =	oabs(bsrr4_),
611 	.bswr4 =	oabs(bswr4_),
612 	.bsrrs4 =	oabs(bsrr4_),
613 	.bswrs4 =	oabs(bswr4_),
614 	.bssr4 =	oabs(bssr4_),
615 	.bscr4 =	oabs(bscr4_)
616 #endif /* AMIGA_SIMPLE_BUS_LONGWORD_METHODS */
617 };
618 #endif
619