Index: head/sys/powerpc/powerpc/bus_machdep.c =================================================================== --- head/sys/powerpc/powerpc/bus_machdep.c (revision 365696) +++ head/sys/powerpc/powerpc/bus_machdep.c (revision 365697) @@ -1,979 +1,987 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2006 Semihalf, Rafal Jaworowski * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, * NASA Ames Research Center. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #define KTR_BE_IO 0 #define KTR_LE_IO 0 #include #include #include #include #include #include #include #include #include #include #define TODO panic("%s: not implemented", __func__) #define MAX_EARLYBOOT_MAPPINGS 6 static struct { vm_offset_t virt; bus_addr_t addr; bus_size_t size; int flags; } earlyboot_mappings[MAX_EARLYBOOT_MAPPINGS]; static int earlyboot_map_idx = 0; void bs_remap_earlyboot(void); static __inline void * __ppc_ba(bus_space_handle_t bsh, bus_size_t ofs) { return ((void *)(bsh + ofs)); } static int bs_gen_map(bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *bshp) { vm_memattr_t ma; /* * Record what we did if we haven't enabled the MMU yet. We * will need to remap it as soon as the MMU comes up. */ if (!pmap_bootstrapped) { KASSERT(earlyboot_map_idx < MAX_EARLYBOOT_MAPPINGS, ("%s: too many early boot mapping requests", __func__)); earlyboot_mappings[earlyboot_map_idx].addr = addr; earlyboot_mappings[earlyboot_map_idx].virt = pmap_early_io_map(addr, size); earlyboot_mappings[earlyboot_map_idx].size = size; earlyboot_mappings[earlyboot_map_idx].flags = flags; *bshp = earlyboot_mappings[earlyboot_map_idx].virt; earlyboot_map_idx++; } else { ma = VM_MEMATTR_DEFAULT; switch (flags) { case BUS_SPACE_MAP_CACHEABLE: ma = VM_MEMATTR_CACHEABLE; break; case BUS_SPACE_MAP_PREFETCHABLE: ma = VM_MEMATTR_PREFETCHABLE; break; } *bshp = (bus_space_handle_t)pmap_mapdev_attr(addr, size, ma); } return (0); } void bs_remap_earlyboot(void) { vm_paddr_t pa, spa; vm_offset_t va; int i; vm_memattr_t ma; for (i = 0; i < earlyboot_map_idx; i++) { spa = earlyboot_mappings[i].addr; if (hw_direct_map && PHYS_TO_DMAP(spa) == earlyboot_mappings[i].virt && pmap_dev_direct_mapped(spa, earlyboot_mappings[i].size) == 0) continue; ma = VM_MEMATTR_DEFAULT; switch (earlyboot_mappings[i].flags) { case BUS_SPACE_MAP_CACHEABLE: ma = VM_MEMATTR_CACHEABLE; break; case BUS_SPACE_MAP_PREFETCHABLE: ma = VM_MEMATTR_PREFETCHABLE; break; } pa = trunc_page(spa); va = trunc_page(earlyboot_mappings[i].virt); while (pa < spa + earlyboot_mappings[i].size) { pmap_kenter_attr(va, pa, ma); va += PAGE_SIZE; pa += PAGE_SIZE; } } } static void bs_gen_unmap(bus_size_t size __unused) { } static int bs_gen_subregion(bus_space_handle_t bsh, bus_size_t ofs, bus_size_t size __unused, bus_space_handle_t *nbshp) { *nbshp = bsh + ofs; return (0); } static int bs_gen_alloc(bus_addr_t rstart __unused, bus_addr_t rend __unused, bus_size_t size __unused, bus_size_t alignment __unused, bus_size_t boundary __unused, int flags __unused, bus_addr_t *bpap __unused, bus_space_handle_t *bshp __unused) { TODO; } static void bs_gen_free(bus_space_handle_t bsh __unused, bus_size_t size __unused) { TODO; } static void bs_gen_barrier(bus_space_handle_t bsh __unused, bus_size_t ofs __unused, bus_size_t size __unused, int flags __unused) { powerpc_iomb(); } /* * Big-endian access functions */ static uint8_t bs_be_rs_1(bus_space_handle_t bsh, bus_size_t ofs) { volatile uint8_t *addr; uint8_t res; addr = __ppc_ba(bsh, ofs); res = *addr; powerpc_iomb(); CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res); return (res); } static uint16_t bs_be_rs_2(bus_space_handle_t bsh, bus_size_t ofs) { volatile uint16_t *addr; uint16_t res; addr = __ppc_ba(bsh, ofs); res = *addr; powerpc_iomb(); CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res); return (res); } static uint32_t bs_be_rs_4(bus_space_handle_t bsh, bus_size_t ofs) { volatile uint32_t *addr; uint32_t res; addr = __ppc_ba(bsh, ofs); res = *addr; powerpc_iomb(); CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res); return (res); } static uint64_t bs_be_rs_8(bus_space_handle_t bsh, bus_size_t ofs) { volatile uint64_t *addr; uint64_t res; addr = __ppc_ba(bsh, ofs); res = *addr; powerpc_iomb(); return (res); } static void bs_be_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt) { ins8(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_be_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt) { ins16(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_be_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt) { ins32(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_be_rm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt) { ins64(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_be_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt) { volatile uint8_t *s = __ppc_ba(bsh, ofs); while (cnt--) *addr++ = *s++; powerpc_iomb(); } static void bs_be_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt) { volatile uint16_t *s = __ppc_ba(bsh, ofs); while (cnt--) *addr++ = *s++; powerpc_iomb(); } static void bs_be_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt) { volatile uint32_t *s = __ppc_ba(bsh, ofs); while (cnt--) *addr++ = *s++; powerpc_iomb(); } static void bs_be_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt) { volatile uint64_t *s = __ppc_ba(bsh, ofs); while (cnt--) *addr++ = *s++; powerpc_iomb(); } static void bs_be_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val) { volatile uint8_t *addr; addr = __ppc_ba(bsh, ofs); *addr = val; powerpc_iomb(); CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val); } static void bs_be_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val) { volatile uint16_t *addr; addr = __ppc_ba(bsh, ofs); *addr = val; powerpc_iomb(); CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val); } static void bs_be_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val) { volatile uint32_t *addr; addr = __ppc_ba(bsh, ofs); *addr = val; powerpc_iomb(); CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val); } static void bs_be_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val) { volatile uint64_t *addr; addr = __ppc_ba(bsh, ofs); *addr = val; powerpc_iomb(); CTR4(KTR_BE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val); } static void bs_be_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr, bus_size_t cnt) { outsb(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_be_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr, bus_size_t cnt) { outsw(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_be_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr, bus_size_t cnt) { outsl(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_be_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr, bus_size_t cnt) { outsll(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_be_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr, size_t cnt) { volatile uint8_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = *addr++; powerpc_iomb(); } static void bs_be_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr, size_t cnt) { volatile uint16_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = *addr++; powerpc_iomb(); } static void bs_be_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr, size_t cnt) { volatile uint32_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = *addr++; powerpc_iomb(); } static void bs_be_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr, size_t cnt) { volatile uint64_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = *addr++; powerpc_iomb(); } static void bs_be_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt) { volatile uint8_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d = val; powerpc_iomb(); } static void bs_be_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt) { volatile uint16_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d = val; powerpc_iomb(); } static void bs_be_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt) { volatile uint32_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d = val; powerpc_iomb(); } static void bs_be_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt) { volatile uint64_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d = val; powerpc_iomb(); } static void bs_be_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt) { volatile uint8_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = val; powerpc_iomb(); } static void bs_be_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt) { volatile uint16_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = val; powerpc_iomb(); } static void bs_be_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt) { volatile uint32_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = val; powerpc_iomb(); } static void bs_be_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt) { volatile uint64_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = val; powerpc_iomb(); } /* * Little-endian access functions */ static uint8_t bs_le_rs_1(bus_space_handle_t bsh, bus_size_t ofs) { volatile uint8_t *addr; uint8_t res; addr = __ppc_ba(bsh, ofs); res = *addr; powerpc_iomb(); CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res); return (res); } static uint16_t bs_le_rs_2(bus_space_handle_t bsh, bus_size_t ofs) { volatile uint16_t *addr; uint16_t res; addr = __ppc_ba(bsh, ofs); __asm __volatile("lhbrx %0, 0, %1" : "=r"(res) : "r"(addr)); powerpc_iomb(); CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res); return (res); } static uint32_t bs_le_rs_4(bus_space_handle_t bsh, bus_size_t ofs) { volatile uint32_t *addr; uint32_t res; addr = __ppc_ba(bsh, ofs); __asm __volatile("lwbrx %0, 0, %1" : "=r"(res) : "r"(addr)); powerpc_iomb(); CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res); return (res); } static uint64_t bs_le_rs_8(bus_space_handle_t bsh, bus_size_t ofs) { volatile uint64_t *addr; uint64_t res; addr = __ppc_ba(bsh, ofs); res = le64toh(*addr); powerpc_iomb(); CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x) = %#x", __func__, bsh, ofs, res); return (res); } static void bs_le_rm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt) { ins8(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_le_rm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt) { ins16rb(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_le_rm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt) { ins32rb(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_le_rm_8(bus_space_handle_t bshh, bus_size_t ofs, uint64_t *addr, size_t cnt) { TODO; } static void bs_le_rr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t *addr, size_t cnt) { volatile uint8_t *s = __ppc_ba(bsh, ofs); while (cnt--) *addr++ = *s++; powerpc_iomb(); } static void bs_le_rr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t *addr, size_t cnt) { volatile uint16_t *s = __ppc_ba(bsh, ofs); while (cnt--) *addr++ = in16rb(s++); powerpc_iomb(); } static void bs_le_rr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t *addr, size_t cnt) { volatile uint32_t *s = __ppc_ba(bsh, ofs); while (cnt--) *addr++ = in32rb(s++); powerpc_iomb(); } static void bs_le_rr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t *addr, size_t cnt) { TODO; } static void bs_le_ws_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val) { volatile uint8_t *addr; addr = __ppc_ba(bsh, ofs); *addr = val; powerpc_iomb(); CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val); } static void bs_le_ws_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val) { volatile uint16_t *addr; addr = __ppc_ba(bsh, ofs); __asm __volatile("sthbrx %0, 0, %1" :: "r"(val), "r"(addr)); powerpc_iomb(); CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val); } static void bs_le_ws_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val) { volatile uint32_t *addr; addr = __ppc_ba(bsh, ofs); __asm __volatile("stwbrx %0, 0, %1" :: "r"(val), "r"(addr)); powerpc_iomb(); CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val); } static void bs_le_ws_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val) { volatile uint64_t *addr; addr = __ppc_ba(bsh, ofs); *addr = htole64(val); powerpc_iomb(); CTR4(KTR_LE_IO, "%s(bsh=%#x, ofs=%#x, val=%#x)", __func__, bsh, ofs, val); } static void bs_le_wm_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr, bus_size_t cnt) { outs8(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_le_wm_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr, bus_size_t cnt) { outs16rb(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_le_wm_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr, bus_size_t cnt) { outs32rb(__ppc_ba(bsh, ofs), addr, cnt); } static void bs_le_wm_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr, bus_size_t cnt) { TODO; } static void bs_le_wr_1(bus_space_handle_t bsh, bus_size_t ofs, const uint8_t *addr, size_t cnt) { volatile uint8_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = *addr++; powerpc_iomb(); } static void bs_le_wr_2(bus_space_handle_t bsh, bus_size_t ofs, const uint16_t *addr, size_t cnt) { volatile uint16_t *d = __ppc_ba(bsh, ofs); while (cnt--) out16rb(d++, *addr++); powerpc_iomb(); } static void bs_le_wr_4(bus_space_handle_t bsh, bus_size_t ofs, const uint32_t *addr, size_t cnt) { volatile uint32_t *d = __ppc_ba(bsh, ofs); while (cnt--) out32rb(d++, *addr++); powerpc_iomb(); } static void bs_le_wr_8(bus_space_handle_t bsh, bus_size_t ofs, const uint64_t *addr, size_t cnt) { TODO; } static void bs_le_sm_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt) { volatile uint8_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d = val; powerpc_iomb(); } static void bs_le_sm_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt) { volatile uint16_t *d = __ppc_ba(bsh, ofs); while (cnt--) out16rb(d, val); powerpc_iomb(); } static void bs_le_sm_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt) { volatile uint32_t *d = __ppc_ba(bsh, ofs); while (cnt--) out32rb(d, val); powerpc_iomb(); } static void bs_le_sm_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt) { TODO; } static void bs_le_sr_1(bus_space_handle_t bsh, bus_size_t ofs, uint8_t val, size_t cnt) { volatile uint8_t *d = __ppc_ba(bsh, ofs); while (cnt--) *d++ = val; powerpc_iomb(); } static void bs_le_sr_2(bus_space_handle_t bsh, bus_size_t ofs, uint16_t val, size_t cnt) { volatile uint16_t *d = __ppc_ba(bsh, ofs); while (cnt--) out16rb(d++, val); powerpc_iomb(); } static void bs_le_sr_4(bus_space_handle_t bsh, bus_size_t ofs, uint32_t val, size_t cnt) { volatile uint32_t *d = __ppc_ba(bsh, ofs); while (cnt--) out32rb(d++, val); powerpc_iomb(); } static void bs_le_sr_8(bus_space_handle_t bsh, bus_size_t ofs, uint64_t val, size_t cnt) { TODO; } +#if BYTE_ORDER == LITTLE_ENDIAN +struct bus_space bs_le_tag = { +#else struct bus_space bs_be_tag = { +#endif /* mapping/unmapping */ bs_gen_map, bs_gen_unmap, bs_gen_subregion, /* allocation/deallocation */ bs_gen_alloc, bs_gen_free, /* barrier */ bs_gen_barrier, /* read (single) */ bs_be_rs_1, bs_be_rs_2, bs_be_rs_4, bs_be_rs_8, bs_be_rs_2, bs_be_rs_4, bs_be_rs_8, /* read multiple */ bs_be_rm_1, bs_be_rm_2, bs_be_rm_4, bs_be_rm_8, bs_be_rm_2, bs_be_rm_4, bs_be_rm_8, /* read region */ bs_be_rr_1, bs_be_rr_2, bs_be_rr_4, bs_be_rr_8, bs_be_rr_2, bs_be_rr_4, bs_be_rr_8, /* write (single) */ bs_be_ws_1, bs_be_ws_2, bs_be_ws_4, bs_be_ws_8, bs_be_ws_2, bs_be_ws_4, bs_be_ws_8, /* write multiple */ bs_be_wm_1, bs_be_wm_2, bs_be_wm_4, bs_be_wm_8, bs_be_wm_2, bs_be_wm_4, bs_be_wm_8, /* write region */ bs_be_wr_1, bs_be_wr_2, bs_be_wr_4, bs_be_wr_8, bs_be_wr_2, bs_be_wr_4, bs_be_wr_8, /* set multiple */ bs_be_sm_1, bs_be_sm_2, bs_be_sm_4, bs_be_sm_8, bs_be_sm_2, bs_be_sm_4, bs_be_sm_8, /* set region */ bs_be_sr_1, bs_be_sr_2, bs_be_sr_4, bs_be_sr_8, bs_be_sr_2, bs_be_sr_4, bs_be_sr_8, }; +#if BYTE_ORDER == LITTLE_ENDIAN +struct bus_space bs_be_tag = { +#else struct bus_space bs_le_tag = { +#endif /* mapping/unmapping */ bs_gen_map, bs_gen_unmap, bs_gen_subregion, /* allocation/deallocation */ bs_gen_alloc, bs_gen_free, /* barrier */ bs_gen_barrier, /* read (single) */ bs_le_rs_1, bs_le_rs_2, bs_le_rs_4, bs_le_rs_8, bs_be_rs_2, bs_be_rs_4, bs_be_rs_8, /* read multiple */ bs_le_rm_1, bs_le_rm_2, bs_le_rm_4, bs_le_rm_8, bs_be_rm_2, bs_be_rm_4, bs_be_rm_8, /* read region */ bs_le_rr_1, bs_le_rr_2, bs_le_rr_4, bs_le_rr_8, bs_be_rr_2, bs_be_rr_4, bs_be_rr_8, /* write (single) */ bs_le_ws_1, bs_le_ws_2, bs_le_ws_4, bs_le_ws_8, bs_be_ws_2, bs_be_ws_4, bs_be_ws_8, /* write multiple */ bs_le_wm_1, bs_le_wm_2, bs_le_wm_4, bs_le_wm_8, bs_be_wm_2, bs_be_wm_4, bs_be_wm_8, /* write region */ bs_le_wr_1, bs_le_wr_2, bs_le_wr_4, bs_le_wr_8, bs_be_wr_2, bs_be_wr_4, bs_be_wr_8, /* set multiple */ bs_le_sm_1, bs_le_sm_2, bs_le_sm_4, bs_le_sm_8, bs_be_sm_2, bs_be_sm_4, bs_be_sm_8, /* set region */ bs_le_sr_1, bs_le_sr_2, bs_le_sr_4, bs_le_sr_8, bs_be_sr_2, bs_be_sr_4, bs_be_sr_8, }; Index: head/sys/powerpc/powerpc/nexus.c =================================================================== --- head/sys/powerpc/powerpc/nexus.c (revision 365696) +++ head/sys/powerpc/powerpc/nexus.c (revision 365697) @@ -1,265 +1,270 @@ /*- * Copyright 1998 Massachusetts Institute of Technology * Copyright 2001 by Thomas Moestl . * Copyright 2006 by Marius Strobl . * All rights reserved. * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. M.I.T. makes * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: FreeBSD: src/sys/i386/i386/nexus.c,v 1.43 2001/02/09 */ #include __FBSDID("$FreeBSD$"); +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * The nexus handles root-level resource allocation requests and interrupt * mapping. All direct subdevices of nexus are attached by DEVICE_IDENTIFY(). */ static device_probe_t nexus_probe; static device_attach_t nexus_attach; static bus_setup_intr_t nexus_setup_intr; static bus_teardown_intr_t nexus_teardown_intr; static bus_activate_resource_t nexus_activate_resource; static bus_deactivate_resource_t nexus_deactivate_resource; static bus_space_tag_t nexus_get_bus_tag(device_t, device_t); static int nexus_get_cpus(device_t, device_t, enum cpu_sets, size_t, cpuset_t *); #ifdef SMP static bus_bind_intr_t nexus_bind_intr; #endif static bus_config_intr_t nexus_config_intr; static ofw_bus_map_intr_t nexus_ofw_map_intr; static device_method_t nexus_methods[] = { /* Device interface */ DEVMETHOD(device_probe, nexus_probe), DEVMETHOD(device_attach, nexus_attach), /* Bus interface */ DEVMETHOD(bus_add_child, bus_generic_add_child), DEVMETHOD(bus_activate_resource, nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), #ifdef SMP DEVMETHOD(bus_bind_intr, nexus_bind_intr), #endif DEVMETHOD(bus_config_intr, nexus_config_intr), DEVMETHOD(bus_get_bus_tag, nexus_get_bus_tag), DEVMETHOD(bus_get_cpus, nexus_get_cpus), /* ofw_bus interface */ DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr), DEVMETHOD_END }; static devclass_t nexus_devclass; DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, 1); EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0, BUS_PASS_BUS); MODULE_VERSION(nexus, 1); static int nexus_probe(device_t dev) { device_quiet(dev); /* suppress attach message for neatness */ return (BUS_PROBE_DEFAULT); } static int nexus_attach(device_t dev) { bus_generic_probe(dev); bus_generic_attach(dev); return (0); } static int nexus_setup_intr(device_t bus __unused, device_t child, struct resource *r, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { int error, domain; if (r == NULL) panic("%s: NULL interrupt resource!", __func__); if (cookiep != NULL) *cookiep = NULL; if ((rman_get_flags(r) & RF_SHAREABLE) == 0) flags |= INTR_EXCL; /* We depend here on rman_activate_resource() being idempotent. */ error = rman_activate_resource(r); if (error) return (error); if (bus_get_domain(child, &domain) != 0) { if(bootverbose) device_printf(child, "no domain found\n"); domain = 0; } error = powerpc_setup_intr(device_get_nameunit(child), rman_get_start(r), filt, intr, arg, flags, cookiep, domain); return (error); } static int nexus_teardown_intr(device_t bus __unused, device_t child __unused, struct resource *r, void *ih) { if (r == NULL) return (EINVAL); return (powerpc_teardown_intr(ih)); } static bus_space_tag_t nexus_get_bus_tag(device_t bus __unused, device_t child __unused) { +#if BYTE_ORDER == LITTLE_ENDIAN + return(&bs_le_tag); +#else return(&bs_be_tag); +#endif } static int nexus_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize, cpuset_t *cpuset) { switch (op) { #ifdef SMP case INTR_CPUS: if (setsize != sizeof(cpuset_t)) return (EINVAL); *cpuset = all_cpus; return (0); #endif default: return (bus_generic_get_cpus(dev, child, op, setsize, cpuset)); } } #ifdef SMP static int nexus_bind_intr(device_t bus __unused, device_t child __unused, struct resource *r, int cpu) { return (powerpc_bind_intr(rman_get_start(r), cpu)); } #endif static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, enum intr_polarity pol) { return (powerpc_config_intr(irq, trig, pol)); } static int nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells, pcell_t *irq) { u_int intr = MAP_IRQ(iparent, irq[0]); if (icells > 1) powerpc_fw_config_intr(intr, irq[1]); return (intr); } static int nexus_activate_resource(device_t bus __unused, device_t child __unused, int type, int rid __unused, struct resource *r) { if (type == SYS_RES_MEMORY) { vm_paddr_t start; void *p; start = (vm_paddr_t) rman_get_start(r); if (bootverbose) printf("nexus mapdev: start %jx, len %jd\n", (uintmax_t)start, rman_get_size(r)); p = pmap_mapdev(start, (vm_size_t) rman_get_size(r)); if (p == NULL) return (ENOMEM); rman_set_virtual(r, p); rman_set_bustag(r, &bs_be_tag); rman_set_bushandle(r, (u_long)p); } return (rman_activate_resource(r)); } static int nexus_deactivate_resource(device_t bus __unused, device_t child __unused, int type __unused, int rid __unused, struct resource *r) { /* * If this is a memory resource, unmap it. */ if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) { bus_size_t psize; psize = rman_get_size(r); pmap_unmapdev((vm_offset_t)rman_get_virtual(r), psize); } return (rman_deactivate_resource(r)); }