Module Name: src Committed By: thorpej Date: Fri Mar 12 04:57:42 UTC 2021
Modified Files: src/sys/arch/powerpc/include/oea: pmap.h src/sys/arch/powerpc/oea: pmap.c Log Message: Re-factor the code in pmap_extract() that checks the 601 I/O segment table and the BAT tables into separate functions that can be called from outside of the pmap module. To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/arch/powerpc/include/oea/pmap.h cvs rdiff -u -r1.103 -r1.104 src/sys/arch/powerpc/oea/pmap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/powerpc/include/oea/pmap.h diff -u src/sys/arch/powerpc/include/oea/pmap.h:1.34 src/sys/arch/powerpc/include/oea/pmap.h:1.35 --- src/sys/arch/powerpc/include/oea/pmap.h:1.34 Tue Mar 2 01:47:44 2021 +++ src/sys/arch/powerpc/include/oea/pmap.h Fri Mar 12 04:57:42 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.h,v 1.34 2021/03/02 01:47:44 thorpej Exp $ */ +/* $NetBSD: pmap.h,v 1.35 2021/03/12 04:57:42 thorpej Exp $ */ /*- * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -158,6 +158,13 @@ int pmap_pte_spill(pmap_t, vaddr_t, bool int pmap_ste_spill(pmap_t, vaddr_t, bool); void pmap_pinit(pmap_t); +#ifdef PPC_OEA601 +bool pmap_extract_ioseg601(vaddr_t, paddr_t *); +#endif /* PPC_OEA601 */ +#ifdef PPC_OEA +bool pmap_extract_battable(vaddr_t, paddr_t *); +#endif /* PPC_OEA */ + u_int powerpc_mmap_flags(paddr_t); #define POWERPC_MMAP_FLAG_MASK 0xf #define POWERPC_MMAP_FLAG_PREFETCHABLE 0x1 Index: src/sys/arch/powerpc/oea/pmap.c diff -u src/sys/arch/powerpc/oea/pmap.c:1.103 src/sys/arch/powerpc/oea/pmap.c:1.104 --- src/sys/arch/powerpc/oea/pmap.c:1.103 Thu Mar 11 04:43:47 2021 +++ src/sys/arch/powerpc/oea/pmap.c Fri Mar 12 04:57:42 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.103 2021/03/11 04:43:47 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.104 2021/03/12 04:57:42 thorpej Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. @@ -63,7 +63,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.103 2021/03/11 04:43:47 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.104 2021/03/12 04:57:42 thorpej Exp $"); #define PMAP_NOOPNAMES @@ -2087,6 +2087,66 @@ pmap_remove(pmap_t pm, vaddr_t va, vaddr PMAP_UNLOCK(); } +#if defined(PMAP_OEA) +#ifdef PPC_OEA601 +bool +pmap_extract_ioseg601(vaddr_t va, paddr_t *pap) +{ + if ((MFPVR() >> 16) != MPC601) + return false; + + const register_t sr = iosrtable[va >> ADDR_SR_SHFT]; + + if (SR601_VALID_P(sr) && SR601_PA_MATCH_P(sr, va)) { + if (pap) + *pap = va; + return true; + } + return false; +} + +static bool +pmap_extract_battable601(vaddr_t va, paddr_t *pap) +{ + const register_t batu = battable[va >> 23].batu; + const register_t batl = battable[va >> 23].batl; + + if (BAT601_VALID_P(batl) && BAT601_VA_MATCH_P(batu, batl, va)) { + const register_t mask = + (~(batl & BAT601_BSM) << 17) & ~0x1ffffL; + if (pap) + *pap = (batl & mask) | (va & ~mask); + return true; + } + return false; +} +#endif /* PPC_OEA601 */ + +bool +pmap_extract_battable(vaddr_t va, paddr_t *pap) +{ +#ifdef PPC_OEA601 + if ((MFPVR() >> 16) == MPC601) + return pmap_extract_battable601(va, pap); +#endif /* PPC_OEA601 */ + + if (oeacpufeat & OEACPU_NOBAT) + return false; + + const register_t batu = battable[BAT_VA2IDX(va)].batu; + + if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, va)) { + const register_t batl = battable[BAT_VA2IDX(va)].batl; + const register_t mask = + (~(batu & (BAT_XBL|BAT_BL)) << 15) & ~0x1ffffL; + if (pap) + *pap = (batl & mask) | (va & ~mask); + return true; + } + return false; +} +#endif /* PMAP_OEA */ + /* * Get the physical page address for the given pmap/virtual address. */ @@ -2099,63 +2159,42 @@ pmap_extract(pmap_t pm, vaddr_t va, padd PMAP_LOCK(); /* - * If this is a kernel pmap lookup, also check the battable - * and if we get a hit, translate the VA to a PA using the - * BAT entries. Don't check for VM_MAX_KERNEL_ADDRESS is - * that will wrap back to 0. + * If this is the kernel pmap, check the battable and I/O + * segments for a hit. This is done only for regions outside + * VM_MIN_KERNEL_ADDRESS-VM_MAX_KERNEL_ADDRESS. + * + * Be careful when checking VM_MAX_KERNEL_ADDRESS; you don't + * want to wrap around to 0. */ if (pm == pmap_kernel() && (va < VM_MIN_KERNEL_ADDRESS || (KERNEL2_SR < 15 && VM_MAX_KERNEL_ADDRESS <= va))) { KASSERT((va >> ADDR_SR_SHFT) != USER_SR); -#if defined (PMAP_OEA) +#if defined(PMAP_OEA) #ifdef PPC_OEA601 - if ((MFPVR() >> 16) == MPC601) { - register_t batu = battable[va >> 23].batu; - register_t batl = battable[va >> 23].batl; - register_t sr = iosrtable[va >> ADDR_SR_SHFT]; - if (BAT601_VALID_P(batl) && - BAT601_VA_MATCH_P(batu, batl, va)) { - register_t mask = - (~(batl & BAT601_BSM) << 17) & ~0x1ffffL; - if (pap) - *pap = (batl & mask) | (va & ~mask); - PMAP_UNLOCK(); - return true; - } else if (SR601_VALID_P(sr) && - SR601_PA_MATCH_P(sr, va)) { - if (pap) - *pap = va; - PMAP_UNLOCK(); - return true; - } - } else + if (pmap_extract_ioseg601(va, pap)) { + PMAP_UNLOCK(); + return true; + } #endif /* PPC_OEA601 */ - { - register_t batu = battable[BAT_VA2IDX(va)].batu; - if (BAT_VALID_P(batu,0) && BAT_VA_MATCH_P(batu,va)) { - register_t batl = battable[BAT_VA2IDX(va)].batl; - register_t mask = - (~(batu & (BAT_XBL|BAT_BL)) << 15) & ~0x1ffffL; - if (pap) - *pap = (batl & mask) | (va & ~mask); - PMAP_UNLOCK(); - return true; - } + if (pmap_extract_battable(va, pap)) { + PMAP_UNLOCK(); + return true; } - PMAP_UNLOCK(); - return false; -#elif defined (PMAP_OEA64_BRIDGE) - if (va >= SEGMENT_LENGTH) - panic("%s: pm: %s va >= SEGMENT_LENGTH, va: 0x%08lx\n", - __func__, (pm == pmap_kernel() ? "kernel" : "user"), va); - else { - if (pap) - *pap = va; + /* + * We still check the HTAB... + */ +#elif defined(PMAP_OEA64_BRIDGE) + if (va < SEGMENT_LENGTH) { + if (pap) + *pap = va; PMAP_UNLOCK(); return true; - } -#elif defined (PMAP_OEA64) + } + /* + * We still check the HTAB... + */ +#elif defined(PMAP_OEA64) #error PPC_OEA64 not supported #endif /* PPC_OEA */ }