Index: head/sys/powerpc/include/pmap.h =================================================================== --- head/sys/powerpc/include/pmap.h (revision 318334) +++ head/sys/powerpc/include/pmap.h (revision 318335) @@ -1,287 +1,287 @@ /*- * Copyright (C) 2006 Semihalf, Marian Balakowicz * All rights reserved. * * Adapted for Freescale's e500 core CPUs. * * 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. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. * * $FreeBSD$ */ /*- * Copyright (C) 1995, 1996 Wolfgang Solfrank. * Copyright (C) 1995, 1996 TooLs GmbH. * All rights reserved. * * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by TooLs GmbH. * 4. The name of TooLs GmbH may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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: $NetBSD: pmap.h,v 1.17 2000/03/30 16:18:24 jdolecek Exp $ */ #ifndef _MACHINE_PMAP_H_ #define _MACHINE_PMAP_H_ #include #include #include #include #include #include #include #include #include struct pmap; typedef struct pmap *pmap_t; #if defined(AIM) #if !defined(NPMAPS) #define NPMAPS 32768 #endif /* !defined(NPMAPS) */ struct slbtnode; struct pvo_entry { LIST_ENTRY(pvo_entry) pvo_vlink; /* Link to common virt page */ #ifndef __powerpc64__ LIST_ENTRY(pvo_entry) pvo_olink; /* Link to overflow entry */ #endif RB_ENTRY(pvo_entry) pvo_plink; /* Link to pmap entries */ struct { #ifndef __powerpc64__ /* 32-bit fields */ struct pte pte; #endif /* 64-bit fields */ uintptr_t slot; vm_paddr_t pa; vm_prot_t prot; } pvo_pte; pmap_t pvo_pmap; /* Owning pmap */ vm_offset_t pvo_vaddr; /* VA of entry */ uint64_t pvo_vpn; /* Virtual page number */ }; LIST_HEAD(pvo_head, pvo_entry); RB_HEAD(pvo_tree, pvo_entry); int pvo_vaddr_compare(struct pvo_entry *, struct pvo_entry *); RB_PROTOTYPE(pvo_tree, pvo_entry, pvo_plink, pvo_vaddr_compare); /* Used by 32-bit PMAP */ #define PVO_PTEGIDX_MASK 0x007UL /* which PTEG slot */ #define PVO_PTEGIDX_VALID 0x008UL /* slot is valid */ /* Used by 64-bit PMAP */ #define PVO_HID 0x008UL /* PVO entry in alternate hash*/ /* Used by both */ #define PVO_WIRED 0x010UL /* PVO entry is wired */ #define PVO_MANAGED 0x020UL /* PVO entry is managed */ #define PVO_BOOTSTRAP 0x080UL /* PVO entry allocated during bootstrap */ #define PVO_DEAD 0x100UL /* waiting to be deleted */ #define PVO_LARGE 0x200UL /* large page */ #define PVO_VADDR(pvo) ((pvo)->pvo_vaddr & ~ADDR_POFF) #define PVO_PTEGIDX_GET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK) #define PVO_PTEGIDX_ISSET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_VALID) #define PVO_PTEGIDX_CLR(pvo) \ ((void)((pvo)->pvo_vaddr &= ~(PVO_PTEGIDX_VALID|PVO_PTEGIDX_MASK))) #define PVO_PTEGIDX_SET(pvo, i) \ ((void)((pvo)->pvo_vaddr |= (i)|PVO_PTEGIDX_VALID)) #define PVO_VSID(pvo) ((pvo)->pvo_vpn >> 16) struct pmap { struct pmap_statistics pm_stats; struct mtx pm_mtx; #ifdef __powerpc64__ struct slbtnode *pm_slb_tree_root; struct slb **pm_slb; int pm_slb_len; #else register_t pm_sr[16]; #endif cpuset_t pm_active; struct pmap *pmap_phys; struct pvo_tree pmap_pvo; }; struct md_page { volatile int32_t mdpg_attrs; vm_memattr_t mdpg_cache_attrs; struct pvo_head mdpg_pvoh; }; #define pmap_page_get_memattr(m) ((m)->md.mdpg_cache_attrs) #define pmap_page_is_mapped(m) (!LIST_EMPTY(&(m)->md.mdpg_pvoh)) /* * Return the VSID corresponding to a given virtual address. * If no VSID is currently defined, it will allocate one, and add * it to a free slot if available. * * NB: The PMAP MUST be locked already. */ uint64_t va_to_vsid(pmap_t pm, vm_offset_t va); /* Lock-free, non-allocating lookup routines */ uint64_t kernel_va_to_slbv(vm_offset_t va); struct slb *user_va_to_slb_entry(pmap_t pm, vm_offset_t va); uint64_t allocate_user_vsid(pmap_t pm, uint64_t esid, int large); void free_vsid(pmap_t pm, uint64_t esid, int large); void slb_insert_user(pmap_t pm, struct slb *slb); void slb_insert_kernel(uint64_t slbe, uint64_t slbv); struct slbtnode *slb_alloc_tree(void); void slb_free_tree(pmap_t pm); struct slb **slb_alloc_user_cache(void); void slb_free_user_cache(struct slb **); #elif defined(BOOKE) struct pmap { struct pmap_statistics pm_stats; /* pmap statistics */ struct mtx pm_mtx; /* pmap mutex */ tlbtid_t pm_tid[MAXCPU]; /* TID to identify this pmap entries in TLB */ cpuset_t pm_active; /* active on cpus */ #ifdef __powerpc64__ /* Page table directory, array of pointers to page directories. */ pte_t **pm_pp2d[PP2D_NENTRIES]; /* List of allocated pdir bufs (pdir kva regions). */ TAILQ_HEAD(, ptbl_buf) pm_pdir_list; #else /* Page table directory, array of pointers to page tables. */ pte_t *pm_pdir[PDIR_NENTRIES]; #endif /* List of allocated ptbl bufs (ptbl kva regions). */ TAILQ_HEAD(, ptbl_buf) pm_ptbl_list; }; struct pv_entry { pmap_t pv_pmap; vm_offset_t pv_va; TAILQ_ENTRY(pv_entry) pv_link; }; typedef struct pv_entry *pv_entry_t; struct md_page { TAILQ_HEAD(, pv_entry) pv_list; int pv_tracked; }; #define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT #define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) #else /* * Common pmap members between AIM and BOOKE. * libkvm needs pm_stats at the same location between both, as it doesn't define * AIM nor BOOKE, and is expected to work across all. */ struct pmap { struct pmap_statistics pm_stats; /* pmap statistics */ struct mtx pm_mtx; /* pmap mutex */ }; #endif /* AIM */ extern struct pmap kernel_pmap_store; #define kernel_pmap (&kernel_pmap_store) #ifdef _KERNEL #define PMAP_LOCK(pmap) mtx_lock(&(pmap)->pm_mtx) #define PMAP_LOCK_ASSERT(pmap, type) \ mtx_assert(&(pmap)->pm_mtx, (type)) #define PMAP_LOCK_DESTROY(pmap) mtx_destroy(&(pmap)->pm_mtx) #define PMAP_LOCK_INIT(pmap) mtx_init(&(pmap)->pm_mtx, \ (pmap == kernel_pmap) ? "kernelpmap" : \ "pmap", NULL, MTX_DEF) #define PMAP_LOCKED(pmap) mtx_owned(&(pmap)->pm_mtx) #define PMAP_MTX(pmap) (&(pmap)->pm_mtx) #define PMAP_TRYLOCK(pmap) mtx_trylock(&(pmap)->pm_mtx) #define PMAP_UNLOCK(pmap) mtx_unlock(&(pmap)->pm_mtx) #define pmap_page_is_write_mapped(m) (((m)->aflags & PGA_WRITEABLE) != 0) void pmap_bootstrap(vm_offset_t, vm_offset_t); void pmap_kenter(vm_offset_t va, vm_paddr_t pa); -void pmap_kenter_attr(vm_offset_t va, vm_offset_t pa, vm_memattr_t); +void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, vm_memattr_t); void pmap_kremove(vm_offset_t); void *pmap_mapdev(vm_paddr_t, vm_size_t); void *pmap_mapdev_attr(vm_paddr_t, vm_size_t, vm_memattr_t); void pmap_unmapdev(vm_offset_t, vm_size_t); void pmap_page_set_memattr(vm_page_t, vm_memattr_t); int pmap_change_attr(vm_offset_t, vm_size_t, vm_memattr_t); void pmap_deactivate(struct thread *); vm_paddr_t pmap_kextract(vm_offset_t); int pmap_dev_direct_mapped(vm_paddr_t, vm_size_t); boolean_t pmap_mmu_install(char *name, int prio); #define vtophys(va) pmap_kextract((vm_offset_t)(va)) #define PHYS_AVAIL_SZ 256 /* Allows up to 16GB Ram on pSeries with * logical memory block size of 64MB. * For more Ram increase the lmb or this value. */ extern vm_paddr_t phys_avail[PHYS_AVAIL_SZ]; extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; extern vm_offset_t msgbuf_phys; extern int pmap_bootstrapped; vm_offset_t pmap_early_io_map(vm_paddr_t pa, vm_size_t size); void pmap_early_io_unmap(vm_offset_t va, vm_size_t size); void pmap_track_page(pmap_t pmap, vm_offset_t va); #endif #endif /* !_MACHINE_PMAP_H_ */ Index: head/sys/powerpc/powerpc/bus_machdep.c =================================================================== --- head/sys/powerpc/powerpc/bus_machdep.c (revision 318334) +++ head/sys/powerpc/powerpc/bus_machdep.c (revision 318335) @@ -1,960 +1,961 @@ /*- * 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 #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_offset_t pa, spa, va; vm_memattr_t ma; for (i = 0; i < earlyboot_map_idx; i++) { spa = earlyboot_mappings[i].addr; if (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(); } 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) { TODO; } 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) { TODO; } 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; } struct bus_space bs_be_tag = { /* 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, }; struct bus_space bs_le_tag = { /* 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/pmap_dispatch.c =================================================================== --- head/sys/powerpc/powerpc/pmap_dispatch.c (revision 318334) +++ head/sys/powerpc/powerpc/pmap_dispatch.c (revision 318335) @@ -1,604 +1,604 @@ /*- * Copyright (c) 2005 Peter Grehan * All rights reserved. * * 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 AUTHOR 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 AUTHOR 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$"); /* * Dispatch MI pmap calls to the appropriate MMU implementation * through a previously registered kernel object. * * Before pmap_bootstrap() can be called, a CPU module must have * called pmap_mmu_install(). This may be called multiple times: * the highest priority call will be installed as the default * MMU handler when pmap_bootstrap() is called. * * It is required that mutex_init() be called before pmap_bootstrap(), * as the PMAP layer makes extensive use of mutexes. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mmu_if.h" static mmu_def_t *mmu_def_impl; static mmu_t mmu_obj; static struct mmu_kobj mmu_kernel_obj; static struct kobj_ops mmu_kernel_kops; /* * pmap globals */ struct pmap kernel_pmap_store; struct msgbuf *msgbufp; vm_offset_t msgbuf_phys; vm_offset_t kernel_vm_end; vm_paddr_t phys_avail[PHYS_AVAIL_SZ]; vm_offset_t virtual_avail; vm_offset_t virtual_end; int pmap_bootstrapped; #ifdef AIM int pvo_vaddr_compare(struct pvo_entry *a, struct pvo_entry *b) { if (PVO_VADDR(a) < PVO_VADDR(b)) return (-1); else if (PVO_VADDR(a) > PVO_VADDR(b)) return (1); return (0); } RB_GENERATE(pvo_tree, pvo_entry, pvo_plink, pvo_vaddr_compare); #endif void pmap_advise(pmap_t pmap, vm_offset_t start, vm_offset_t end, int advice) { CTR5(KTR_PMAP, "%s(%p, %#x, %#x, %d)", __func__, pmap, start, end, advice); MMU_ADVISE(mmu_obj, pmap, start, end, advice); } void pmap_clear_modify(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); MMU_CLEAR_MODIFY(mmu_obj, m); } void pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, vm_offset_t src_addr) { CTR6(KTR_PMAP, "%s(%p, %p, %#x, %#x, %#x)", __func__, dst_pmap, src_pmap, dst_addr, len, src_addr); MMU_COPY(mmu_obj, dst_pmap, src_pmap, dst_addr, len, src_addr); } void pmap_copy_page(vm_page_t src, vm_page_t dst) { CTR3(KTR_PMAP, "%s(%p, %p)", __func__, src, dst); MMU_COPY_PAGE(mmu_obj, src, dst); } void pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[], vm_offset_t b_offset, int xfersize) { CTR6(KTR_PMAP, "%s(%p, %#x, %p, %#x, %#x)", __func__, ma, a_offset, mb, b_offset, xfersize); MMU_COPY_PAGES(mmu_obj, ma, a_offset, mb, b_offset, xfersize); } int pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t p, vm_prot_t prot, u_int flags, int8_t psind) { CTR6(KTR_PMAP, "pmap_enter(%p, %#x, %p, %#x, %x, %d)", pmap, va, p, prot, flags, psind); return (MMU_ENTER(mmu_obj, pmap, va, p, prot, flags, psind)); } void pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end, vm_page_t m_start, vm_prot_t prot) { CTR6(KTR_PMAP, "%s(%p, %#x, %#x, %p, %#x)", __func__, pmap, start, end, m_start, prot); MMU_ENTER_OBJECT(mmu_obj, pmap, start, end, m_start, prot); } void pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot) { CTR5(KTR_PMAP, "%s(%p, %#x, %p, %#x)", __func__, pmap, va, m, prot); MMU_ENTER_QUICK(mmu_obj, pmap, va, m, prot); } vm_paddr_t pmap_extract(pmap_t pmap, vm_offset_t va) { CTR3(KTR_PMAP, "%s(%p, %#x)", __func__, pmap, va); return (MMU_EXTRACT(mmu_obj, pmap, va)); } vm_page_t pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) { CTR4(KTR_PMAP, "%s(%p, %#x, %#x)", __func__, pmap, va, prot); return (MMU_EXTRACT_AND_HOLD(mmu_obj, pmap, va, prot)); } void pmap_growkernel(vm_offset_t va) { CTR2(KTR_PMAP, "%s(%#x)", __func__, va); MMU_GROWKERNEL(mmu_obj, va); } void pmap_init(void) { CTR1(KTR_PMAP, "%s()", __func__); MMU_INIT(mmu_obj); } boolean_t pmap_is_modified(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); return (MMU_IS_MODIFIED(mmu_obj, m)); } boolean_t pmap_is_prefaultable(pmap_t pmap, vm_offset_t va) { CTR3(KTR_PMAP, "%s(%p, %#x)", __func__, pmap, va); return (MMU_IS_PREFAULTABLE(mmu_obj, pmap, va)); } boolean_t pmap_is_referenced(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); return (MMU_IS_REFERENCED(mmu_obj, m)); } boolean_t pmap_ts_referenced(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); return (MMU_TS_REFERENCED(mmu_obj, m)); } vm_offset_t pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot) { CTR5(KTR_PMAP, "%s(%p, %#x, %#x, %#x)", __func__, virt, start, end, prot); return (MMU_MAP(mmu_obj, virt, start, end, prot)); } void pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object, vm_pindex_t pindex, vm_size_t size) { CTR6(KTR_PMAP, "%s(%p, %#x, %p, %u, %#x)", __func__, pmap, addr, object, pindex, size); MMU_OBJECT_INIT_PT(mmu_obj, pmap, addr, object, pindex, size); } boolean_t pmap_page_exists_quick(pmap_t pmap, vm_page_t m) { CTR3(KTR_PMAP, "%s(%p, %p)", __func__, pmap, m); return (MMU_PAGE_EXISTS_QUICK(mmu_obj, pmap, m)); } void pmap_page_init(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); MMU_PAGE_INIT(mmu_obj, m); } int pmap_page_wired_mappings(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); return (MMU_PAGE_WIRED_MAPPINGS(mmu_obj, m)); } int pmap_pinit(pmap_t pmap) { CTR2(KTR_PMAP, "%s(%p)", __func__, pmap); MMU_PINIT(mmu_obj, pmap); return (1); } void pmap_pinit0(pmap_t pmap) { CTR2(KTR_PMAP, "%s(%p)", __func__, pmap); MMU_PINIT0(mmu_obj, pmap); } void pmap_protect(pmap_t pmap, vm_offset_t start, vm_offset_t end, vm_prot_t prot) { CTR5(KTR_PMAP, "%s(%p, %#x, %#x, %#x)", __func__, pmap, start, end, prot); MMU_PROTECT(mmu_obj, pmap, start, end, prot); } void pmap_qenter(vm_offset_t start, vm_page_t *m, int count) { CTR4(KTR_PMAP, "%s(%#x, %p, %d)", __func__, start, m, count); MMU_QENTER(mmu_obj, start, m, count); } void pmap_qremove(vm_offset_t start, int count) { CTR3(KTR_PMAP, "%s(%#x, %d)", __func__, start, count); MMU_QREMOVE(mmu_obj, start, count); } void pmap_release(pmap_t pmap) { CTR2(KTR_PMAP, "%s(%p)", __func__, pmap); MMU_RELEASE(mmu_obj, pmap); } void pmap_remove(pmap_t pmap, vm_offset_t start, vm_offset_t end) { CTR4(KTR_PMAP, "%s(%p, %#x, %#x)", __func__, pmap, start, end); MMU_REMOVE(mmu_obj, pmap, start, end); } void pmap_remove_all(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); MMU_REMOVE_ALL(mmu_obj, m); } void pmap_remove_pages(pmap_t pmap) { CTR2(KTR_PMAP, "%s(%p)", __func__, pmap); MMU_REMOVE_PAGES(mmu_obj, pmap); } void pmap_remove_write(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); MMU_REMOVE_WRITE(mmu_obj, m); } void pmap_unwire(pmap_t pmap, vm_offset_t start, vm_offset_t end) { CTR4(KTR_PMAP, "%s(%p, %#x, %#x)", __func__, pmap, start, end); MMU_UNWIRE(mmu_obj, pmap, start, end); } void pmap_zero_page(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); MMU_ZERO_PAGE(mmu_obj, m); } void pmap_zero_page_area(vm_page_t m, int off, int size) { CTR4(KTR_PMAP, "%s(%p, %d, %d)", __func__, m, off, size); MMU_ZERO_PAGE_AREA(mmu_obj, m, off, size); } int pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa) { CTR3(KTR_PMAP, "%s(%p, %#x)", __func__, pmap, addr); return (MMU_MINCORE(mmu_obj, pmap, addr, locked_pa)); } void pmap_activate(struct thread *td) { CTR2(KTR_PMAP, "%s(%p)", __func__, td); MMU_ACTIVATE(mmu_obj, td); } void pmap_deactivate(struct thread *td) { CTR2(KTR_PMAP, "%s(%p)", __func__, td); MMU_DEACTIVATE(mmu_obj, td); } /* * Increase the starting virtual address of the given mapping if a * different alignment might result in more superpage mappings. */ void pmap_align_superpage(vm_object_t object, vm_ooffset_t offset, vm_offset_t *addr, vm_size_t size) { CTR5(KTR_PMAP, "%s(%p, %#x, %p, %#x)", __func__, object, offset, addr, size); MMU_ALIGN_SUPERPAGE(mmu_obj, object, offset, addr, size); } /* * Routines used in machine-dependent code */ void pmap_bootstrap(vm_offset_t start, vm_offset_t end) { mmu_obj = &mmu_kernel_obj; /* * Take care of compiling the selected class, and * then statically initialise the MMU object */ kobj_class_compile_static(mmu_def_impl, &mmu_kernel_kops); kobj_init_static((kobj_t)mmu_obj, mmu_def_impl); MMU_BOOTSTRAP(mmu_obj, start, end); } void pmap_cpu_bootstrap(int ap) { /* * No KTR here because our console probably doesn't work yet */ return (MMU_CPU_BOOTSTRAP(mmu_obj, ap)); } void * pmap_mapdev(vm_paddr_t pa, vm_size_t size) { CTR3(KTR_PMAP, "%s(%#x, %#x)", __func__, pa, size); return (MMU_MAPDEV(mmu_obj, pa, size)); } void * pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, vm_memattr_t attr) { CTR4(KTR_PMAP, "%s(%#x, %#x, %#x)", __func__, pa, size, attr); return (MMU_MAPDEV_ATTR(mmu_obj, pa, size, attr)); } void pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) { CTR3(KTR_PMAP, "%s(%p, %#x)", __func__, m, ma); return (MMU_PAGE_SET_MEMATTR(mmu_obj, m, ma)); } void pmap_unmapdev(vm_offset_t va, vm_size_t size) { CTR3(KTR_PMAP, "%s(%#x, %#x)", __func__, va, size); MMU_UNMAPDEV(mmu_obj, va, size); } vm_paddr_t pmap_kextract(vm_offset_t va) { CTR2(KTR_PMAP, "%s(%#x)", __func__, va); return (MMU_KEXTRACT(mmu_obj, va)); } void pmap_kenter(vm_offset_t va, vm_paddr_t pa) { CTR3(KTR_PMAP, "%s(%#x, %#x)", __func__, va, pa); MMU_KENTER(mmu_obj, va, pa); } void -pmap_kenter_attr(vm_offset_t va, vm_offset_t pa, vm_memattr_t ma) +pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, vm_memattr_t ma) { CTR4(KTR_PMAP, "%s(%#x, %#x, %#x)", __func__, va, pa, ma); MMU_KENTER_ATTR(mmu_obj, va, pa, ma); } void pmap_kremove(vm_offset_t va) { CTR2(KTR_PMAP, "%s(%#x)", __func__, va); return (MMU_KREMOVE(mmu_obj, va)); } boolean_t pmap_dev_direct_mapped(vm_paddr_t pa, vm_size_t size) { CTR3(KTR_PMAP, "%s(%#x, %#x)", __func__, pa, size); return (MMU_DEV_DIRECT_MAPPED(mmu_obj, pa, size)); } void pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz) { CTR4(KTR_PMAP, "%s(%p, %#x, %#x)", __func__, pm, va, sz); return (MMU_SYNC_ICACHE(mmu_obj, pm, va, sz)); } void dumpsys_map_chunk(vm_paddr_t pa, size_t sz, void **va) { CTR4(KTR_PMAP, "%s(%#jx, %#zx, %p)", __func__, (uintmax_t)pa, sz, va); return (MMU_DUMPSYS_MAP(mmu_obj, pa, sz, va)); } void dumpsys_unmap_chunk(vm_paddr_t pa, size_t sz, void *va) { CTR4(KTR_PMAP, "%s(%#jx, %#zx, %p)", __func__, (uintmax_t)pa, sz, va); return (MMU_DUMPSYS_UNMAP(mmu_obj, pa, sz, va)); } void dumpsys_pa_init(void) { CTR1(KTR_PMAP, "%s()", __func__); return (MMU_SCAN_INIT(mmu_obj)); } vm_offset_t pmap_quick_enter_page(vm_page_t m) { CTR2(KTR_PMAP, "%s(%p)", __func__, m); return (MMU_QUICK_ENTER_PAGE(mmu_obj, m)); } void pmap_quick_remove_page(vm_offset_t addr) { CTR2(KTR_PMAP, "%s(%#x)", __func__, addr); MMU_QUICK_REMOVE_PAGE(mmu_obj, addr); } int pmap_change_attr(vm_offset_t addr, vm_size_t size, vm_memattr_t mode) { CTR4(KTR_PMAP, "%s(%#x, %#zx, %d)", __func__, addr, size, mode); return (MMU_CHANGE_ATTR(mmu_obj, addr, size, mode)); } /* * MMU install routines. Highest priority wins, equal priority also * overrides allowing last-set to win. */ SET_DECLARE(mmu_set, mmu_def_t); boolean_t pmap_mmu_install(char *name, int prio) { mmu_def_t **mmupp, *mmup; static int curr_prio = 0; /* * Try and locate the MMU kobj corresponding to the name */ SET_FOREACH(mmupp, mmu_set) { mmup = *mmupp; if (mmup->name && !strcmp(mmup->name, name) && (prio >= curr_prio || mmu_def_impl == NULL)) { curr_prio = prio; mmu_def_impl = mmup; return (TRUE); } } return (FALSE); } int unmapped_buf_allowed;