]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/powerpc/powerpc/bus_machdep.c
Import mandoc snapshot 2017-06-08
[FreeBSD/FreeBSD.git] / sys / powerpc / powerpc / bus_machdep.c
1 /*-
2  * Copyright (c) 2006 Semihalf, Rafal Jaworowski <raj@semihalf.com>
3  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to The NetBSD Foundation
7  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
8  * NASA Ames Research Center.
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 __FBSDID("$FreeBSD$");
34
35 #define KTR_BE_IO       0
36 #define KTR_LE_IO       0
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/bus.h>
41 #include <sys/ktr.h>
42 #include <vm/vm.h>
43 #include <vm/pmap.h>
44
45 #include <machine/bus.h>
46 #include <machine/pio.h>
47 #include <machine/md_var.h>
48
49 #define TODO panic("%s: not implemented", __func__)
50
51 #define MAX_EARLYBOOT_MAPPINGS  6
52
53 static struct {
54         vm_offset_t virt;
55         bus_addr_t addr;
56         bus_size_t size;
57         int flags;
58 } earlyboot_mappings[MAX_EARLYBOOT_MAPPINGS];
59 static int earlyboot_map_idx = 0;
60
61 void bs_remap_earlyboot(void);
62
63 static __inline void *
64 __ppc_ba(bus_space_handle_t bsh, bus_size_t ofs)
65 {
66         return ((void *)(bsh + ofs));
67 }
68
69 static int
70 bs_gen_map(bus_addr_t addr, bus_size_t size, int flags,
71     bus_space_handle_t *bshp)
72 {
73         vm_memattr_t ma;
74
75         /*
76          * Record what we did if we haven't enabled the MMU yet. We
77          * will need to remap it as soon as the MMU comes up.
78          */
79         if (!pmap_bootstrapped) {
80                 KASSERT(earlyboot_map_idx < MAX_EARLYBOOT_MAPPINGS,
81                     ("%s: too many early boot mapping requests", __func__));
82                 earlyboot_mappings[earlyboot_map_idx].addr = addr;
83                 earlyboot_mappings[earlyboot_map_idx].virt =
84                     pmap_early_io_map(addr, size);
85                 earlyboot_mappings[earlyboot_map_idx].size = size;
86                 earlyboot_mappings[earlyboot_map_idx].flags = flags;
87                 *bshp = earlyboot_mappings[earlyboot_map_idx].virt;
88                 earlyboot_map_idx++;
89         } else {
90                 ma = VM_MEMATTR_DEFAULT;
91                 switch (flags) {
92                         case BUS_SPACE_MAP_CACHEABLE:
93                                 ma = VM_MEMATTR_CACHEABLE;
94                                 break;
95                         case BUS_SPACE_MAP_PREFETCHABLE:
96                                 ma = VM_MEMATTR_PREFETCHABLE;
97                                 break;
98                 }
99                 *bshp = (bus_space_handle_t)pmap_mapdev_attr(addr, size, ma);
100         }
101
102         return (0);
103 }
104
105 void
106 bs_remap_earlyboot(void)
107 {
108         vm_paddr_t pa, spa;
109         vm_offset_t va;
110         int i;
111         vm_memattr_t ma;
112
113         for (i = 0; i < earlyboot_map_idx; i++) {
114                 spa = earlyboot_mappings[i].addr;
115                 if (spa == earlyboot_mappings[i].virt &&
116                    pmap_dev_direct_mapped(spa, earlyboot_mappings[i].size) == 0)
117                         continue;
118
119                 ma = VM_MEMATTR_DEFAULT;
120                 switch (earlyboot_mappings[i].flags) {
121                         case BUS_SPACE_MAP_CACHEABLE:
122                                 ma = VM_MEMATTR_CACHEABLE;
123                                 break;
124                         case BUS_SPACE_MAP_PREFETCHABLE:
125                                 ma = VM_MEMATTR_PREFETCHABLE;
126                                 break;
127                 }
128
129                 pa = trunc_page(spa);
130                 va = trunc_page(earlyboot_mappings[i].virt);
131                 while (pa < spa + earlyboot_mappings[i].size) {
132                         pmap_kenter_attr(va, pa, ma);
133                         va += PAGE_SIZE;
134                         pa += PAGE_SIZE;
135                 }
136         }
137 }
138
139 static void
140 bs_gen_unmap(bus_size_t size __unused)
141 {
142 }
143
144 static int
145 bs_gen_subregion(bus_space_handle_t bsh, bus_size_t ofs,
146     bus_size_t size __unused, bus_space_handle_t *nbshp)
147 {
148         *nbshp = bsh + ofs;
149         return (0);
150 }
151
152 static int
153 bs_gen_alloc(bus_addr_t rstart __unused, bus_addr_t rend __unused,
154     bus_size_t size __unused, bus_size_t alignment __unused,
155     bus_size_t boundary __unused, int flags __unused,
156     bus_addr_t *bpap __unused, bus_space_handle_t *bshp __unused)
157 {
158         TODO;
159 }
160
161 static void
162 bs_gen_free(bus_space_handle_t bsh __unused, bus_size_t size __unused)
163 {
164         TODO;
165 }
166
167 static void
168 bs_gen_barrier(bus_space_handle_t bsh __unused, bus_size_t ofs __unused,
169     bus_size_t size __unused, int flags __unused)
170 {
171
172         powerpc_iomb();
173 }
174
175 /*
176  * Big-endian access functions
177  */
178 static uint8_t
179 bs_be_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
180 {
181         volatile uint8_t *addr;
182         uint8_t res;
183
184         addr = __ppc_ba(bsh, ofs);
185         res = *addr;
186         powerpc_iomb();
187         CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
188         return (res);
189 }
190
191 static uint16_t
192 bs_be_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
193 {
194         volatile uint16_t *addr;
195         uint16_t res;
196
197         addr = __ppc_ba(bsh, ofs);
198         res = *addr;
199         powerpc_iomb();
200         CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
201         return (res);
202 }
203
204 static uint32_t
205 bs_be_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
206 {
207         volatile uint32_t *addr;
208         uint32_t res;
209
210         addr = __ppc_ba(bsh, ofs);
211         res = *addr;
212         powerpc_iomb();
213         CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
214         return (res);
215 }
216
217 static uint64_t
218 bs_be_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
219 {
220         volatile uint64_t *addr;
221         uint64_t res;
222
223         addr = __ppc_ba(bsh, ofs);
224         res = *addr;
225         powerpc_iomb();
226         return (res);
227 }
228
229 static void
230 bs_be_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
231 {
232         ins8(__ppc_ba(bsh, ofs), addr, cnt);
233 }
234
235 static void
236 bs_be_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
237 {
238         ins16(__ppc_ba(bsh, ofs), addr, cnt);
239 }
240
241 static void
242 bs_be_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
243 {
244         ins32(__ppc_ba(bsh, ofs), addr, cnt);
245 }
246
247 static void
248 bs_be_rm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
249 {
250         ins64(__ppc_ba(bsh, ofs), addr, cnt);
251 }
252
253 static void
254 bs_be_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
255 {
256         volatile uint8_t *s = __ppc_ba(bsh, ofs);
257
258         while (cnt--)
259                 *addr++ = *s++;
260         powerpc_iomb();
261 }
262
263 static void
264 bs_be_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
265 {
266         volatile uint16_t *s = __ppc_ba(bsh, ofs);
267
268         while (cnt--)
269                 *addr++ = *s++;
270         powerpc_iomb();
271 }
272
273 static void
274 bs_be_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
275 {
276         volatile uint32_t *s = __ppc_ba(bsh, ofs);
277
278         while (cnt--)
279                 *addr++ = *s++;
280         powerpc_iomb();
281 }
282
283 static void
284 bs_be_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
285 {
286         volatile uint64_t *s = __ppc_ba(bsh, ofs);
287
288         while (cnt--)
289                 *addr++ = *s++;
290         powerpc_iomb();
291 }
292
293 static void
294 bs_be_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
295 {
296         volatile uint8_t *addr;
297
298         addr = __ppc_ba(bsh, ofs);
299         *addr = val;
300         powerpc_iomb();
301         CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
302 }
303
304 static void
305 bs_be_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
306 {
307         volatile uint16_t *addr;
308
309         addr = __ppc_ba(bsh, ofs);
310         *addr = val;
311         powerpc_iomb();
312         CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
313 }
314
315 static void
316 bs_be_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
317 {
318         volatile uint32_t *addr;
319
320         addr = __ppc_ba(bsh, ofs);
321         *addr = val;
322         powerpc_iomb();
323         CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
324 }
325
326 static void
327 bs_be_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
328 {
329         volatile uint64_t *addr;
330
331         addr = __ppc_ba(bsh, ofs);
332         *addr = val;
333         powerpc_iomb();
334 }
335
336 static void
337 bs_be_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
338     bus_size_t cnt)
339 {
340         outsb(__ppc_ba(bsh, ofs), addr, cnt);
341 }
342
343 static void
344 bs_be_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
345     bus_size_t cnt)
346 {
347         outsw(__ppc_ba(bsh, ofs), addr, cnt);
348 }
349
350 static void
351 bs_be_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
352     bus_size_t cnt)
353 {
354         outsl(__ppc_ba(bsh, ofs), addr, cnt);
355 }
356
357 static void
358 bs_be_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
359     bus_size_t cnt)
360 {
361         outsll(__ppc_ba(bsh, ofs), addr, cnt);
362 }
363
364 static void
365 bs_be_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
366     size_t cnt)
367 {
368         volatile uint8_t *d = __ppc_ba(bsh, ofs);
369
370         while (cnt--)
371                 *d++ = *addr++;
372         powerpc_iomb();
373 }
374
375 static void
376 bs_be_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
377     size_t cnt)
378 {
379         volatile uint16_t *d = __ppc_ba(bsh, ofs);
380
381         while (cnt--)
382                 *d++ = *addr++;
383         powerpc_iomb();
384 }
385
386 static void
387 bs_be_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
388     size_t cnt)
389 {
390         volatile uint32_t *d = __ppc_ba(bsh, ofs);
391
392         while (cnt--)
393                 *d++ = *addr++;
394         powerpc_iomb();
395 }
396
397 static void
398 bs_be_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
399     size_t cnt)
400 {
401         volatile uint64_t *d = __ppc_ba(bsh, ofs);
402
403         while (cnt--)
404                 *d++ = *addr++;
405         powerpc_iomb();
406 }
407
408 static void
409 bs_be_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
410 {
411         volatile uint8_t *d = __ppc_ba(bsh, ofs);
412
413         while (cnt--)
414                 *d = val;
415         powerpc_iomb();
416 }
417
418 static void
419 bs_be_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
420 {
421         volatile uint16_t *d = __ppc_ba(bsh, ofs);
422
423         while (cnt--)
424                 *d = val;
425         powerpc_iomb();
426 }
427
428 static void
429 bs_be_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
430 {
431         volatile uint32_t *d = __ppc_ba(bsh, ofs);
432
433         while (cnt--)
434                 *d = val;
435         powerpc_iomb();
436 }
437
438 static void
439 bs_be_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
440 {
441         volatile uint64_t *d = __ppc_ba(bsh, ofs);
442
443         while (cnt--)
444                 *d = val;
445         powerpc_iomb();
446 }
447
448 static void
449 bs_be_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
450 {
451         volatile uint8_t *d = __ppc_ba(bsh, ofs);
452
453         while (cnt--)
454                 *d++ = val;
455         powerpc_iomb();
456 }
457
458 static void
459 bs_be_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
460 {
461         volatile uint16_t *d = __ppc_ba(bsh, ofs);
462
463         while (cnt--)
464                 *d++ = val;
465         powerpc_iomb();
466 }
467
468 static void
469 bs_be_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
470 {
471         volatile uint32_t *d = __ppc_ba(bsh, ofs);
472
473         while (cnt--)
474                 *d++ = val;
475         powerpc_iomb();
476 }
477
478 static void
479 bs_be_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
480 {
481         volatile uint64_t *d = __ppc_ba(bsh, ofs);
482
483         while (cnt--)
484                 *d++ = val;
485         powerpc_iomb();
486 }
487
488 /*
489  * Little-endian access functions
490  */
491 static uint8_t
492 bs_le_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
493 {
494         volatile uint8_t *addr;
495         uint8_t res;
496
497         addr = __ppc_ba(bsh, ofs);
498         res = *addr;
499         powerpc_iomb();
500         CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
501         return (res);
502 }
503
504 static uint16_t
505 bs_le_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
506 {
507         volatile uint16_t *addr;
508         uint16_t res;
509
510         addr = __ppc_ba(bsh, ofs);
511         __asm __volatile("lhbrx %0, 0, %1" : "=r"(res) : "r"(addr));
512         powerpc_iomb();
513         CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
514         return (res);
515 }
516
517 static uint32_t
518 bs_le_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
519 {
520         volatile uint32_t *addr;
521         uint32_t res;
522
523         addr = __ppc_ba(bsh, ofs);
524         __asm __volatile("lwbrx %0, 0, %1" : "=r"(res) : "r"(addr));
525         powerpc_iomb();
526         CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
527         return (res);
528 }
529
530 static uint64_t
531 bs_le_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
532 {
533         TODO;
534 }
535
536 static void
537 bs_le_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
538 {
539         ins8(__ppc_ba(bsh, ofs), addr, cnt);
540 }
541
542 static void
543 bs_le_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
544 {
545         ins16rb(__ppc_ba(bsh, ofs), addr, cnt);
546 }
547
548 static void
549 bs_le_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
550 {
551         ins32rb(__ppc_ba(bsh, ofs), addr, cnt);
552 }
553
554 static void
555 bs_le_rm_8(bus_space_handle_t bshh, bus_size_t ofs, uint64_t *addr, size_t cnt)
556 {
557         TODO;
558 }
559
560 static void
561 bs_le_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
562 {
563         volatile uint8_t *s = __ppc_ba(bsh, ofs);
564
565         while (cnt--)
566                 *addr++ = *s++;
567         powerpc_iomb();
568 }
569
570 static void
571 bs_le_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
572 {
573         volatile uint16_t *s = __ppc_ba(bsh, ofs);
574
575         while (cnt--)
576                 *addr++ = in16rb(s++);
577         powerpc_iomb();
578 }
579
580 static void
581 bs_le_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
582 {
583         volatile uint32_t *s = __ppc_ba(bsh, ofs);
584
585         while (cnt--)
586                 *addr++ = in32rb(s++);
587         powerpc_iomb();
588 }
589
590 static void
591 bs_le_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
592 {
593         TODO;
594 }
595
596 static void
597 bs_le_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
598 {
599         volatile uint8_t *addr;
600
601         addr = __ppc_ba(bsh, ofs);
602         *addr = val;
603         powerpc_iomb();
604         CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
605 }
606
607 static void
608 bs_le_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
609 {
610         volatile uint16_t *addr;
611  
612         addr = __ppc_ba(bsh, ofs);
613         __asm __volatile("sthbrx %0, 0, %1" :: "r"(val), "r"(addr));
614         powerpc_iomb();
615         CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
616 }
617
618 static void
619 bs_le_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
620 {
621         volatile uint32_t *addr;
622
623         addr = __ppc_ba(bsh, ofs);
624         __asm __volatile("stwbrx %0, 0, %1" :: "r"(val), "r"(addr));
625         powerpc_iomb();
626         CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
627 }
628
629 static void
630 bs_le_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
631 {
632         TODO;
633 }
634
635 static void
636 bs_le_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
637     bus_size_t cnt)
638 {
639         outs8(__ppc_ba(bsh, ofs), addr, cnt);
640 }
641
642 static void
643 bs_le_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
644     bus_size_t cnt)
645 {
646         outs16rb(__ppc_ba(bsh, ofs), addr, cnt);
647 }
648
649 static void
650 bs_le_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
651     bus_size_t cnt)
652 {
653         outs32rb(__ppc_ba(bsh, ofs), addr, cnt);
654 }
655
656 static void
657 bs_le_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
658     bus_size_t cnt)
659 {
660         TODO;
661 }
662
663 static void
664 bs_le_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
665     size_t cnt)
666 {
667         volatile uint8_t *d = __ppc_ba(bsh, ofs);
668
669         while (cnt--)
670                 *d++ = *addr++;
671         powerpc_iomb();
672 }
673
674 static void
675 bs_le_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
676     size_t cnt)
677 {
678         volatile uint16_t *d = __ppc_ba(bsh, ofs);
679
680         while (cnt--)
681                 out16rb(d++, *addr++);
682         powerpc_iomb();
683 }
684
685 static void
686 bs_le_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
687     size_t cnt)
688 {
689         volatile uint32_t *d = __ppc_ba(bsh, ofs);
690
691         while (cnt--)
692                 out32rb(d++, *addr++);
693         powerpc_iomb();
694 }
695
696 static void
697 bs_le_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
698     size_t cnt)
699 {
700         TODO;
701 }
702
703 static void
704 bs_le_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
705 {
706         volatile uint8_t *d = __ppc_ba(bsh, ofs);
707
708         while (cnt--)
709                 *d = val;
710         powerpc_iomb();
711 }
712
713 static void
714 bs_le_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
715 {
716         volatile uint16_t *d = __ppc_ba(bsh, ofs);
717
718         while (cnt--)
719                 out16rb(d, val);
720         powerpc_iomb();
721 }
722
723 static void
724 bs_le_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
725 {
726         volatile uint32_t *d = __ppc_ba(bsh, ofs);
727
728         while (cnt--)
729                 out32rb(d, val);
730         powerpc_iomb();
731 }
732
733 static void
734 bs_le_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
735 {
736         TODO;
737 }
738
739 static void
740 bs_le_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
741 {
742         volatile uint8_t *d = __ppc_ba(bsh, ofs);
743
744         while (cnt--)
745                 *d++ = val;
746         powerpc_iomb();
747 }
748
749 static void
750 bs_le_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
751 {
752         volatile uint16_t *d = __ppc_ba(bsh, ofs);
753
754         while (cnt--)
755                 out16rb(d++, val);
756         powerpc_iomb();
757 }
758
759 static void
760 bs_le_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
761 {
762         volatile uint32_t *d = __ppc_ba(bsh, ofs);
763
764         while (cnt--)
765                 out32rb(d++, val);
766         powerpc_iomb();
767 }
768
769 static void
770 bs_le_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
771 {
772         TODO;
773 }
774
775 struct bus_space bs_be_tag = {
776         /* mapping/unmapping */
777         bs_gen_map,
778         bs_gen_unmap,
779         bs_gen_subregion,
780
781         /* allocation/deallocation */
782         bs_gen_alloc,
783         bs_gen_free,
784
785         /* barrier */
786         bs_gen_barrier,
787
788         /* read (single) */
789         bs_be_rs_1,
790         bs_be_rs_2,
791         bs_be_rs_4,
792         bs_be_rs_8,
793
794         bs_be_rs_2,
795         bs_be_rs_4,
796         bs_be_rs_8,
797
798         /* read multiple */
799         bs_be_rm_1,
800         bs_be_rm_2,
801         bs_be_rm_4,
802         bs_be_rm_8,
803
804         bs_be_rm_2,
805         bs_be_rm_4,
806         bs_be_rm_8,
807
808         /* read region */
809         bs_be_rr_1,
810         bs_be_rr_2,
811         bs_be_rr_4,
812         bs_be_rr_8,
813
814         bs_be_rr_2,
815         bs_be_rr_4,
816         bs_be_rr_8,
817
818         /* write (single) */
819         bs_be_ws_1,
820         bs_be_ws_2,
821         bs_be_ws_4,
822         bs_be_ws_8,
823
824         bs_be_ws_2,
825         bs_be_ws_4,
826         bs_be_ws_8,
827
828         /* write multiple */
829         bs_be_wm_1,
830         bs_be_wm_2,
831         bs_be_wm_4,
832         bs_be_wm_8,
833
834         bs_be_wm_2,
835         bs_be_wm_4,
836         bs_be_wm_8,
837
838         /* write region */
839         bs_be_wr_1,
840         bs_be_wr_2,
841         bs_be_wr_4,
842         bs_be_wr_8,
843
844         bs_be_wr_2,
845         bs_be_wr_4,
846         bs_be_wr_8,
847
848         /* set multiple */
849         bs_be_sm_1,
850         bs_be_sm_2,
851         bs_be_sm_4,
852         bs_be_sm_8,
853
854         bs_be_sm_2,
855         bs_be_sm_4,
856         bs_be_sm_8,
857
858         /* set region */
859         bs_be_sr_1,
860         bs_be_sr_2,
861         bs_be_sr_4,
862         bs_be_sr_8,
863
864         bs_be_sr_2,
865         bs_be_sr_4,
866         bs_be_sr_8,
867 };
868
869 struct bus_space bs_le_tag = {
870         /* mapping/unmapping */
871         bs_gen_map,
872         bs_gen_unmap,
873         bs_gen_subregion,
874
875         /* allocation/deallocation */
876         bs_gen_alloc,
877         bs_gen_free,
878
879         /* barrier */
880         bs_gen_barrier,
881
882         /* read (single) */
883         bs_le_rs_1,
884         bs_le_rs_2,
885         bs_le_rs_4,
886         bs_le_rs_8,
887
888         bs_be_rs_2,
889         bs_be_rs_4,
890         bs_be_rs_8,
891
892         /* read multiple */
893         bs_le_rm_1,
894         bs_le_rm_2,
895         bs_le_rm_4,
896         bs_le_rm_8,
897
898         bs_be_rm_2,
899         bs_be_rm_4,
900         bs_be_rm_8,
901
902         /* read region */
903         bs_le_rr_1,
904         bs_le_rr_2,
905         bs_le_rr_4,
906         bs_le_rr_8,
907
908         bs_be_rr_2,
909         bs_be_rr_4,
910         bs_be_rr_8,
911
912         /* write (single) */
913         bs_le_ws_1,
914         bs_le_ws_2,
915         bs_le_ws_4,
916         bs_le_ws_8,
917
918         bs_be_ws_2,
919         bs_be_ws_4,
920         bs_be_ws_8,
921
922         /* write multiple */
923         bs_le_wm_1,
924         bs_le_wm_2,
925         bs_le_wm_4,
926         bs_le_wm_8,
927
928         bs_be_wm_2,
929         bs_be_wm_4,
930         bs_be_wm_8,
931
932         /* write region */
933         bs_le_wr_1,
934         bs_le_wr_2,
935         bs_le_wr_4,
936         bs_le_wr_8,
937
938         bs_be_wr_2,
939         bs_be_wr_4,
940         bs_be_wr_8,
941
942         /* set multiple */
943         bs_le_sm_1,
944         bs_le_sm_2,
945         bs_le_sm_4,
946         bs_le_sm_8,
947
948         bs_be_sm_2,
949         bs_be_sm_4,
950         bs_be_sm_8,
951
952         /* set region */
953         bs_le_sr_1,
954         bs_le_sr_2,
955         bs_le_sr_4,
956         bs_le_sr_8,
957
958         bs_be_sr_2,
959         bs_be_sr_4,
960         bs_be_sr_8,
961 };