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