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