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
64 } earlyboot_mappings[MAX_EARLYBOOT_MAPPINGS];
65 static int earlyboot_map_idx = 0;
67 void bs_remap_earlyboot(void);
69 static __inline void *
70 __ppc_ba(bus_space_handle_t bsh, bus_size_t ofs)
72 return ((void *)(bsh + ofs));
76 bs_gen_map(bus_addr_t addr, bus_size_t size, int flags,
77 bus_space_handle_t *bshp)
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.
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;
94 ma = VM_MEMATTR_DEFAULT;
96 case BUS_SPACE_MAP_CACHEABLE:
97 ma = VM_MEMATTR_CACHEABLE;
99 case BUS_SPACE_MAP_PREFETCHABLE:
100 ma = VM_MEMATTR_PREFETCHABLE;
103 *bshp = (bus_space_handle_t)pmap_mapdev_attr(addr, size, ma);
110 bs_remap_earlyboot(void)
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)
122 ma = VM_MEMATTR_DEFAULT;
123 switch (earlyboot_mappings[i].flags) {
124 case BUS_SPACE_MAP_CACHEABLE:
125 ma = VM_MEMATTR_CACHEABLE;
127 case BUS_SPACE_MAP_PREFETCHABLE:
128 ma = VM_MEMATTR_PREFETCHABLE;
132 pa = trunc_page(spa);
133 while (pa < spa + earlyboot_mappings[i].size) {
134 pmap_kenter_attr(pa, pa, ma);
141 bs_gen_unmap(bus_size_t size __unused)
146 bs_gen_subregion(bus_space_handle_t bsh, bus_size_t ofs,
147 bus_size_t size __unused, bus_space_handle_t *nbshp)
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)
163 bs_gen_free(bus_space_handle_t bsh __unused, bus_size_t size __unused)
169 bs_gen_barrier(bus_space_handle_t bsh __unused, bus_size_t ofs __unused,
170 bus_size_t size __unused, int flags __unused)
177 * Big-endian access functions
180 bs_be_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
182 volatile uint8_t *addr;
185 addr = __ppc_ba(bsh, ofs);
188 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
193 bs_be_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
195 volatile uint16_t *addr;
198 addr = __ppc_ba(bsh, ofs);
201 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
206 bs_be_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
208 volatile uint32_t *addr;
211 addr = __ppc_ba(bsh, ofs);
214 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
219 bs_be_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
221 volatile uint64_t *addr;
224 addr = __ppc_ba(bsh, ofs);
231 bs_be_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
233 ins8(__ppc_ba(bsh, ofs), addr, cnt);
237 bs_be_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
239 ins16(__ppc_ba(bsh, ofs), addr, cnt);
243 bs_be_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
245 ins32(__ppc_ba(bsh, ofs), addr, cnt);
249 bs_be_rm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
251 ins64(__ppc_ba(bsh, ofs), addr, cnt);
255 bs_be_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
257 volatile uint8_t *s = __ppc_ba(bsh, ofs);
265 bs_be_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
267 volatile uint16_t *s = __ppc_ba(bsh, ofs);
275 bs_be_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
277 volatile uint32_t *s = __ppc_ba(bsh, ofs);
285 bs_be_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
287 volatile uint64_t *s = __ppc_ba(bsh, ofs);
295 bs_be_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
297 volatile uint8_t *addr;
299 addr = __ppc_ba(bsh, ofs);
302 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
306 bs_be_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
308 volatile uint16_t *addr;
310 addr = __ppc_ba(bsh, ofs);
313 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
317 bs_be_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
319 volatile uint32_t *addr;
321 addr = __ppc_ba(bsh, ofs);
324 CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
328 bs_be_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
330 volatile uint64_t *addr;
332 addr = __ppc_ba(bsh, ofs);
338 bs_be_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
341 outsb(__ppc_ba(bsh, ofs), addr, cnt);
345 bs_be_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
348 outsw(__ppc_ba(bsh, ofs), addr, cnt);
352 bs_be_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
355 outsl(__ppc_ba(bsh, ofs), addr, cnt);
359 bs_be_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
362 outsll(__ppc_ba(bsh, ofs), addr, cnt);
366 bs_be_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
369 volatile uint8_t *d = __ppc_ba(bsh, ofs);
377 bs_be_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
380 volatile uint16_t *d = __ppc_ba(bsh, ofs);
388 bs_be_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
391 volatile uint32_t *d = __ppc_ba(bsh, ofs);
399 bs_be_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
402 volatile uint64_t *d = __ppc_ba(bsh, ofs);
410 bs_be_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
412 volatile uint8_t *d = __ppc_ba(bsh, ofs);
420 bs_be_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
422 volatile uint16_t *d = __ppc_ba(bsh, ofs);
430 bs_be_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
432 volatile uint32_t *d = __ppc_ba(bsh, ofs);
440 bs_be_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
442 volatile uint64_t *d = __ppc_ba(bsh, ofs);
450 bs_be_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
452 volatile uint8_t *d = __ppc_ba(bsh, ofs);
460 bs_be_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
462 volatile uint16_t *d = __ppc_ba(bsh, ofs);
470 bs_be_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
472 volatile uint32_t *d = __ppc_ba(bsh, ofs);
480 bs_be_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
482 volatile uint64_t *d = __ppc_ba(bsh, ofs);
490 * Little-endian access functions
493 bs_le_rs_1(bus_space_handle_t bsh, bus_size_t ofs)
495 volatile uint8_t *addr;
498 addr = __ppc_ba(bsh, ofs);
501 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
506 bs_le_rs_2(bus_space_handle_t bsh, bus_size_t ofs)
508 volatile uint16_t *addr;
511 addr = __ppc_ba(bsh, ofs);
512 __asm __volatile("lhbrx %0, 0, %1" : "=r"(res) : "r"(addr));
514 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
519 bs_le_rs_4(bus_space_handle_t bsh, bus_size_t ofs)
521 volatile uint32_t *addr;
524 addr = __ppc_ba(bsh, ofs);
525 __asm __volatile("lwbrx %0, 0, %1" : "=r"(res) : "r"(addr));
527 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res);
532 bs_le_rs_8(bus_space_handle_t bsh, bus_size_t ofs)
538 bs_le_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
540 ins8(__ppc_ba(bsh, ofs), addr, cnt);
544 bs_le_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
546 ins16rb(__ppc_ba(bsh, ofs), addr, cnt);
550 bs_le_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
552 ins32rb(__ppc_ba(bsh, ofs), addr, cnt);
556 bs_le_rm_8(bus_space_handle_t bshh, bus_size_t ofs, uint64_t *addr, size_t cnt)
562 bs_le_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt)
564 volatile uint8_t *s = __ppc_ba(bsh, ofs);
572 bs_le_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt)
574 volatile uint16_t *s = __ppc_ba(bsh, ofs);
577 *addr++ = in16rb(s++);
582 bs_le_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt)
584 volatile uint32_t *s = __ppc_ba(bsh, ofs);
587 *addr++ = in32rb(s++);
592 bs_le_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt)
598 bs_le_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val)
600 volatile uint8_t *addr;
602 addr = __ppc_ba(bsh, ofs);
605 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
609 bs_le_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val)
611 volatile uint16_t *addr;
613 addr = __ppc_ba(bsh, ofs);
614 __asm __volatile("sthbrx %0, 0, %1" :: "r"(val), "r"(addr));
616 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
620 bs_le_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val)
622 volatile uint32_t *addr;
624 addr = __ppc_ba(bsh, ofs);
625 __asm __volatile("stwbrx %0, 0, %1" :: "r"(val), "r"(addr));
627 CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val);
631 bs_le_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val)
637 bs_le_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
640 outs8(__ppc_ba(bsh, ofs), addr, cnt);
644 bs_le_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
647 outs16rb(__ppc_ba(bsh, ofs), addr, cnt);
651 bs_le_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
654 outs32rb(__ppc_ba(bsh, ofs), addr, cnt);
658 bs_le_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
665 bs_le_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr,
668 volatile uint8_t *d = __ppc_ba(bsh, ofs);
676 bs_le_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr,
679 volatile uint16_t *d = __ppc_ba(bsh, ofs);
682 out16rb(d++, *addr++);
687 bs_le_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr,
690 volatile uint32_t *d = __ppc_ba(bsh, ofs);
693 out32rb(d++, *addr++);
698 bs_le_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr,
705 bs_le_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
707 volatile uint8_t *d = __ppc_ba(bsh, ofs);
715 bs_le_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
717 volatile uint16_t *d = __ppc_ba(bsh, ofs);
725 bs_le_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
727 volatile uint32_t *d = __ppc_ba(bsh, ofs);
735 bs_le_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
741 bs_le_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt)
743 volatile uint8_t *d = __ppc_ba(bsh, ofs);
751 bs_le_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt)
753 volatile uint16_t *d = __ppc_ba(bsh, ofs);
761 bs_le_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt)
763 volatile uint32_t *d = __ppc_ba(bsh, ofs);
771 bs_le_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt)
776 struct bus_space bs_be_tag = {
777 /* mapping/unmapping */
782 /* allocation/deallocation */
870 struct bus_space bs_le_tag = {
871 /* mapping/unmapping */
876 /* allocation/deallocation */