xref: /freebsd/sys/powerpc/powerpc/bus_machdep.c (revision d6b92ffa)
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 };
962