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