2 * Copyright (c) 2006 Semihalf, Rafal Jaworowski <raj@semihalf.com>
3 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
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.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD$");
45 #include <sys/param.h>
46 #include <sys/systm.h>
52 #include <machine/bus.h>
53 #include <machine/pio.h>
54 #include <machine/md_var.h>
56 #define TODO panic("%s: not implemented", __func__)
58 #define MAX_EARLYBOOT_MAPPINGS 6
63 } earlyboot_mappings[MAX_EARLYBOOT_MAPPINGS];
64 static int earlyboot_map_idx = 0;
66 void bs_remap_earlyboot(void);
68 static __inline void *
69 __ppc_ba(bus_space_handle_t bsh, bus_size_t ofs)
71 return ((void *)(bsh + ofs));
75 bs_gen_map(bus_addr_t addr, bus_size_t size __unused, int flags __unused,
76 bus_space_handle_t *bshp)
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.
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].size = size;
90 *bshp = (bus_space_handle_t)pmap_mapdev(addr,size);
97 bs_remap_earlyboot(void)
105 for (i = 0; i < earlyboot_map_idx; i++) {
106 spa = earlyboot_mappings[i].addr;
108 pa = trunc_page(spa);
109 while (pa < spa + earlyboot_mappings[i].size) {
117 bs_gen_unmap(bus_size_t size __unused)
122 bs_gen_subregion(bus_space_handle_t bsh, bus_size_t ofs,
123 bus_size_t size __unused, bus_space_handle_t *nbshp)
130 bs_gen_alloc(bus_addr_t rstart __unused, bus_addr_t rend __unused,
131 bus_size_t size __unused, bus_size_t alignment __unused,
132 bus_size_t boundary __unused, int flags __unused,
133 bus_addr_t *bpap __unused, bus_space_handle_t *bshp __unused)
139 bs_gen_free(bus_space_handle_t bsh __unused, bus_size_t size __unused)
145 bs_gen_barrier(bus_space_handle_t bsh __unused, bus_size_t ofs __unused,
146 bus_size_t size __unused, int flags __unused)
148 __asm __volatile("eieio; sync" : : : "memory");
152 * Big-endian access functions
155 bs_be_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
157 volatile uint8_t *addr;
160 addr = __ppc_ba(bsh, ofs);
162 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
167 bs_be_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
169 volatile uint16_t *addr;
172 addr = __ppc_ba(bsh, ofs);
174 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
179 bs_be_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
181 volatile uint32_t *addr;
184 addr = __ppc_ba(bsh, ofs);
186 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
191 bs_be_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
193 volatile uint64_t *addr;
196 addr = __ppc_ba(bsh, ofs);
202 bs_be_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
204 ins8(__ppc_ba(bsh, ofs), addr, cnt);
208 bs_be_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
210 ins16(__ppc_ba(bsh, ofs), addr, cnt);
214 bs_be_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
216 ins32(__ppc_ba(bsh, ofs), addr, cnt);
220 bs_be_rm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
222 ins64(__ppc_ba(bsh, ofs), addr, cnt);
226 bs_be_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
228 volatile uint8_t *s = __ppc_ba(bsh, ofs);
232 __asm __volatile("eieio; sync");
236 bs_be_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
238 volatile uint16_t *s = __ppc_ba(bsh, ofs);
242 __asm __volatile("eieio; sync");
246 bs_be_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
248 volatile uint32_t *s = __ppc_ba(bsh, ofs);
252 __asm __volatile("eieio; sync");
256 bs_be_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
258 volatile uint64_t *s = __ppc_ba(bsh, ofs);
262 __asm __volatile("eieio; sync");
266 bs_be_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
268 volatile uint8_t *addr;
270 addr = __ppc_ba(bsh, ofs);
272 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
276 bs_be_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
278 volatile uint16_t *addr;
280 addr = __ppc_ba(bsh, ofs);
282 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
286 bs_be_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
288 volatile uint32_t *addr;
290 addr = __ppc_ba(bsh, ofs);
292 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
296 bs_be_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
298 volatile uint64_t *addr;
300 addr = __ppc_ba(bsh, ofs);
305 bs_be_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
308 outsb(__ppc_ba(bsh, ofs), addr, cnt);
312 bs_be_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
315 outsw(__ppc_ba(bsh, ofs), addr, cnt);
319 bs_be_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
322 outsl(__ppc_ba(bsh, ofs), addr, cnt);
326 bs_be_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
329 outsll(__ppc_ba(bsh, ofs), addr, cnt);
333 bs_be_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
336 volatile uint8_t *d = __ppc_ba(bsh, ofs);
340 __asm __volatile("eieio; sync");
344 bs_be_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
347 volatile uint16_t *d = __ppc_ba(bsh, ofs);
351 __asm __volatile("eieio; sync");
355 bs_be_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
358 volatile uint32_t *d = __ppc_ba(bsh, ofs);
362 __asm __volatile("eieio; sync");
366 bs_be_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
369 volatile uint64_t *d = __ppc_ba(bsh, ofs);
373 __asm __volatile("eieio; sync");
377 bs_be_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
379 volatile uint8_t *d = __ppc_ba(bsh, ofs);
383 __asm __volatile("eieio; sync");
387 bs_be_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
389 volatile uint16_t *d = __ppc_ba(bsh, ofs);
393 __asm __volatile("eieio; sync");
397 bs_be_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
399 volatile uint32_t *d = __ppc_ba(bsh, ofs);
403 __asm __volatile("eieio; sync");
407 bs_be_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
409 volatile uint64_t *d = __ppc_ba(bsh, ofs);
413 __asm __volatile("eieio; sync");
417 bs_be_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
419 volatile uint8_t *d = __ppc_ba(bsh, ofs);
423 __asm __volatile("eieio; sync");
427 bs_be_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
429 volatile uint16_t *d = __ppc_ba(bsh, ofs);
433 __asm __volatile("eieio; sync");
437 bs_be_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
439 volatile uint32_t *d = __ppc_ba(bsh, ofs);
443 __asm __volatile("eieio; sync");
447 bs_be_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
449 volatile uint64_t *d = __ppc_ba(bsh, ofs);
453 __asm __volatile("eieio; sync");
457 * Little-endian access functions
460 bs_le_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
462 volatile uint8_t *addr;
465 addr = __ppc_ba(bsh, ofs);
467 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
472 bs_le_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
474 volatile uint16_t *addr;
477 addr = __ppc_ba(bsh, ofs);
478 __asm __volatile("lhbrx %0, 0, %1" : "=r"(res) : "r"(addr));
479 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
484 bs_le_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
486 volatile uint32_t *addr;
489 addr = __ppc_ba(bsh, ofs);
490 __asm __volatile("lwbrx %0, 0, %1" : "=r"(res) : "r"(addr));
491 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
496 bs_le_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
502 bs_le_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
504 ins8(__ppc_ba(bsh, ofs), addr, cnt);
508 bs_le_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
510 ins16rb(__ppc_ba(bsh, ofs), addr, cnt);
514 bs_le_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
516 ins32rb(__ppc_ba(bsh, ofs), addr, cnt);
520 bs_le_rm_8(bus_space_handle_t bshh, bus_size_t ofs, uint64_t *addr, size_t cnt)
526 bs_le_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
528 volatile uint8_t *s = __ppc_ba(bsh, ofs);
532 __asm __volatile("eieio; sync");
536 bs_le_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
538 volatile uint16_t *s = __ppc_ba(bsh, ofs);
541 *addr++ = in16rb(s++);
542 __asm __volatile("eieio; sync");
546 bs_le_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
548 volatile uint32_t *s = __ppc_ba(bsh, ofs);
551 *addr++ = in32rb(s++);
552 __asm __volatile("eieio; sync");
556 bs_le_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
562 bs_le_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
564 volatile uint8_t *addr;
566 addr = __ppc_ba(bsh, ofs);
568 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
572 bs_le_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
574 volatile uint16_t *addr;
576 addr = __ppc_ba(bsh, ofs);
577 __asm __volatile("sthbrx %0, 0, %1" :: "r"(val), "r"(addr));
578 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
582 bs_le_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
584 volatile uint32_t *addr;
586 addr = __ppc_ba(bsh, ofs);
587 __asm __volatile("stwbrx %0, 0, %1" :: "r"(val), "r"(addr));
588 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
592 bs_le_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
598 bs_le_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
601 outs8(__ppc_ba(bsh, ofs), addr, cnt);
605 bs_le_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
608 outs16rb(__ppc_ba(bsh, ofs), addr, cnt);
612 bs_le_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
615 outs32rb(__ppc_ba(bsh, ofs), addr, cnt);
619 bs_le_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
626 bs_le_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
629 volatile uint8_t *d = __ppc_ba(bsh, ofs);
633 __asm __volatile("eieio; sync");
637 bs_le_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
640 volatile uint16_t *d = __ppc_ba(bsh, ofs);
643 out16rb(d++, *addr++);
644 __asm __volatile("eieio; sync");
648 bs_le_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
651 volatile uint32_t *d = __ppc_ba(bsh, ofs);
654 out32rb(d++, *addr++);
655 __asm __volatile("eieio; sync");
659 bs_le_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
666 bs_le_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
668 volatile uint8_t *d = __ppc_ba(bsh, ofs);
672 __asm __volatile("eieio; sync");
676 bs_le_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
678 volatile uint16_t *d = __ppc_ba(bsh, ofs);
682 __asm __volatile("eieio; sync");
686 bs_le_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
688 volatile uint32_t *d = __ppc_ba(bsh, ofs);
692 __asm __volatile("eieio; sync");
696 bs_le_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
702 bs_le_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
704 volatile uint8_t *d = __ppc_ba(bsh, ofs);
708 __asm __volatile("eieio; sync");
712 bs_le_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
714 volatile uint16_t *d = __ppc_ba(bsh, ofs);
718 __asm __volatile("eieio; sync");
722 bs_le_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
724 volatile uint32_t *d = __ppc_ba(bsh, ofs);
728 __asm __volatile("eieio; sync");
732 bs_le_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
737 struct bus_space bs_be_tag = {
738 /* mapping/unmapping */
743 /* allocation/deallocation */
831 struct bus_space bs_le_tag = {
832 /* mapping/unmapping */
837 /* allocation/deallocation */