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