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