Home | History | Annotate | Line # | Download | only in mips
      1 /*	$NetBSD: pmap_machdep.c,v 1.41 2026/09/28 18:56:17 skrll Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9  * NASA Ames Research Center and by Chris G. Demetriou.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 /*
     34  * Copyright (c) 1992, 1993
     35  *	The Regents of the University of California.  All rights reserved.
     36  *
     37  * This code is derived from software contributed to Berkeley by
     38  * the Systems Programming Group of the University of Utah Computer
     39  * Science Department and Ralph Campbell.
     40  *
     41  * Redistribution and use in source and binary forms, with or without
     42  * modification, are permitted provided that the following conditions
     43  * are met:
     44  * 1. Redistributions of source code must retain the above copyright
     45  *    notice, this list of conditions and the following disclaimer.
     46  * 2. Redistributions in binary form must reproduce the above copyright
     47  *    notice, this list of conditions and the following disclaimer in the
     48  *    documentation and/or other materials provided with the distribution.
     49  * 3. Neither the name of the University nor the names of its contributors
     50  *    may be used to endorse or promote products derived from this software
     51  *    without specific prior written permission.
     52  *
     53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     63  * SUCH DAMAGE.
     64  *
     65  *	@(#)pmap.c	8.4 (Berkeley) 1/26/94
     66  */
     67 
     68 #include <sys/cdefs.h>
     69 
     70 __KERNEL_RCSID(0, "$NetBSD: pmap_machdep.c,v 1.41 2026/09/28 18:56:17 skrll Exp $");
     71 
     72 /*
     73  *	Manages physical address maps.
     74  *
     75  *	In addition to hardware address maps, this
     76  *	module is called upon to provide software-use-only
     77  *	maps which may or may not be stored in the same
     78  *	form as hardware maps.  These pseudo-maps are
     79  *	used to store intermediate results from copy
     80  *	operations to and from address spaces.
     81  *
     82  *	Since the information managed by this module is
     83  *	also stored by the logical address mapping module,
     84  *	this module may throw away valid virtual-to-physical
     85  *	mappings at almost any time.  However, invalidations
     86  *	of virtual-to-physical mappings must be done as
     87  *	requested.
     88  *
     89  *	In order to cope with hardware architectures which
     90  *	make virtual-to-physical map invalidates expensive,
     91  *	this module may delay invalidate or reduced protection
     92  *	operations until such time as they are actually
     93  *	necessary.  This module is given full information as
     94  *	to which processors are currently using which maps,
     95  *	and to when physical maps must be made correct.
     96  */
     97 
     98 /* XXX simonb 2002/02/26
     99  *
    100  * MIPS3_PLUS is used to conditionally compile the r4k MMU support.
    101  * This is bogus - for example, some IDT MIPS-II CPUs have r4k style
    102  * MMUs (and 32-bit ones at that).
    103  *
    104  * On the other hand, it's not likely that we'll ever support the R6000
    105  * (is it?), so maybe that can be an "if MIPS2 or greater" check.
    106  *
    107  * Also along these lines are using totally separate functions for
    108  * r3k-style and r4k-style MMUs and removing all the MIPS_HAS_R4K_MMU
    109  * checks in the current functions.
    110  *
    111  * These warnings probably applies to other files under sys/arch/mips.
    112  */
    113 
    114 #include "opt_cputype.h"
    115 #include "opt_mips_cache.h"
    116 #include "opt_multiprocessor.h"
    117 #include "opt_sysv.h"
    118 
    119 #define __MUTEX_PRIVATE
    120 #define __PMAP_PRIVATE
    121 
    122 #include <sys/param.h>
    123 #include <sys/atomic.h>
    124 #include <sys/buf.h>
    125 #include <sys/cpu.h>
    126 #include <sys/kernel.h>
    127 #include <sys/mutex.h>
    128 #include <sys/pool.h>
    129 #include <sys/proc.h>
    130 #include <sys/systm.h>
    131 #ifdef SYSVSHM
    132 #include <sys/shm.h>
    133 #endif
    134 
    135 #include <uvm/uvm.h>
    136 #include <uvm/uvm_physseg.h>
    137 
    138 #include <mips/cache.h>
    139 #include <mips/cpuregs.h>
    140 #include <mips/locore.h>
    141 #include <mips/pte.h>
    142 
    143 CTASSERT(MIPS_KSEG0_START < 0);
    144 CTASSERT((intptr_t)MIPS_PHYS_TO_KSEG0(0x1000) < 0);
    145 CTASSERT(MIPS_KSEG1_START < 0);
    146 CTASSERT((intptr_t)MIPS_PHYS_TO_KSEG1(0x1000) < 0);
    147 CTASSERT(MIPS_KSEG2_START < 0);
    148 CTASSERT(MIPS_MAX_MEM_ADDR < 0);
    149 CTASSERT(MIPS_RESERVED_ADDR < 0);
    150 CTASSERT((uint32_t)MIPS_KSEG0_START == 0x80000000);
    151 CTASSERT((uint32_t)MIPS_KSEG1_START == 0xa0000000);
    152 CTASSERT((uint32_t)MIPS_KSEG2_START == 0xc0000000);
    153 CTASSERT((uint32_t)MIPS_MAX_MEM_ADDR == 0xbe000000);
    154 CTASSERT((uint32_t)MIPS_RESERVED_ADDR == 0xbfc80000);
    155 CTASSERT(MIPS_KSEG0_P(MIPS_PHYS_TO_KSEG0(0)));
    156 CTASSERT(MIPS_KSEG1_P(MIPS_PHYS_TO_KSEG1(0)));
    157 #ifdef _LP64
    158 CTASSERT(VM_MIN_KERNEL_ADDRESS % NBXSEG == 0);
    159 #else
    160 CTASSERT(VM_MIN_KERNEL_ADDRESS % NBSEG == 0);
    161 #endif
    162 
    163 //PMAP_COUNTER(idlezeroed_pages, "pages idle zeroed");
    164 PMAP_COUNTER(zeroed_pages, "pages zeroed");
    165 PMAP_COUNTER(copied_pages, "pages copied");
    166 extern struct evcnt pmap_evcnt_page_cache_evictions;
    167 
    168 u_int pmap_page_cache_alias_mask;
    169 
    170 #define pmap_md_cache_indexof(x)	(((vaddr_t)(x)) & pmap_page_cache_alias_mask)
    171 
    172 static register_t
    173 pmap_md_map_ephemeral_page(struct vm_page_md *mdpg, bool locked_p, int prot,
    174     pt_entry_t *old_pte_p)
    175 {
    176 	KASSERT(VM_PAGEMD_VMPAGE_P(mdpg));
    177 
    178 	struct vm_page *pg = VM_MD_TO_PAGE(mdpg);
    179 	const paddr_t pa = VM_PAGE_TO_PHYS(pg);
    180 	pv_entry_t pv = &mdpg->mdpg_first;
    181 	register_t va = 0;
    182 
    183 	UVMHIST_FUNC(__func__);
    184 	UVMHIST_CALLARGS(pmaphist, "(pg=%#jx, prot=%d, ptep=%#jx)",
    185 	    (uintptr_t)pg, prot, (uintptr_t)old_pte_p, 0);
    186 
    187 	KASSERT(!locked_p || VM_PAGEMD_PVLIST_LOCKED_P(mdpg));
    188 
    189 	if (!MIPS_CACHE_VIRTUAL_ALIAS || !mips_cache_badalias(pv->pv_va, pa)) {
    190 #ifdef _LP64
    191 		va = MIPS_PHYS_TO_XKPHYS_CACHED(pa);
    192 #else
    193 		if (pa < MIPS_PHYS_MASK) {
    194 			va = MIPS_PHYS_TO_KSEG0(pa);
    195 		}
    196 #endif
    197 	}
    198 	if (va == 0) {
    199 		/*
    200 		 * Make sure to use a congruent mapping to the last mapped
    201 		 * address so we don't have to worry about virtual aliases.
    202 		 */
    203 		kpreempt_disable(); // paired with the one in unmap
    204 		struct cpu_info * const ci = curcpu();
    205 		if (MIPS_CACHE_VIRTUAL_ALIAS) {
    206 			KASSERT(ci->ci_pmap_dstbase != 0);
    207 			KASSERT(ci->ci_pmap_srcbase != 0);
    208 
    209 			const u_int __diagused mask = pmap_page_cache_alias_mask;
    210 			KASSERTMSG((ci->ci_pmap_dstbase & mask) == 0,
    211 			    "%#"PRIxVADDR, ci->ci_pmap_dstbase);
    212 			KASSERTMSG((ci->ci_pmap_srcbase & mask) == 0,
    213 			    "%#"PRIxVADDR, ci->ci_pmap_srcbase);
    214 		}
    215 		vaddr_t nva = (prot & VM_PROT_WRITE
    216 			? ci->ci_pmap_dstbase
    217 			: ci->ci_pmap_srcbase)
    218 		    + pmap_md_cache_indexof(MIPS_CACHE_VIRTUAL_ALIAS
    219 			? pv->pv_va
    220 			: pa);
    221 
    222 		va = (intptr_t)nva;
    223 		/*
    224 		 * Now to make and write the new PTE to map the PA.
    225 		 */
    226 		const pt_entry_t npte = pte_make_kenter_pa(pa, mdpg, prot, 0);
    227 		pt_entry_t * const ptep = pmap_pte_lookup(pmap_kernel(), va);
    228 		*old_pte_p = *ptep;		// save
    229 		bool rv __diagused;
    230 		*ptep = npte;			// update page table
    231 
    232 		// update the TLB directly making sure we force the new entry
    233 		// into it.
    234 		rv = tlb_update_addr(va, KERNEL_PID, npte, true);
    235 		KASSERTMSG(rv == 1, "va %#"PRIxREGISTER" pte=%#"PRIxPTE" rv=%d",
    236 		    va, pte_value(npte), rv);
    237 	}
    238 	if (MIPS_CACHE_VIRTUAL_ALIAS) {
    239 		/*
    240 		 * If we are forced to use an incompatible alias, flush the
    241 		 * page from the cache so we will copy the correct contents.
    242 		 */
    243 		if (!locked_p)
    244 			(void)VM_PAGEMD_PVLIST_READLOCK(mdpg);
    245 		if (VM_PAGEMD_CACHED_P(mdpg)
    246 		    && mips_cache_badalias(pv->pv_va, va)) {
    247 			register_t ova = (intptr_t)trunc_page(pv->pv_va);
    248 			mips_dcache_wbinv_range_index(ova, PAGE_SIZE);
    249 			/*
    250 			 * If there is no active mapping, remember this new one.
    251 			 */
    252 			if (pv->pv_pmap == NULL)
    253 				pv->pv_va = va;
    254 		}
    255 		if (!locked_p)
    256 			VM_PAGEMD_PVLIST_UNLOCK(mdpg);
    257 	}
    258 
    259 	UVMHIST_LOG(pmaphist, " <-- done (va=%#lx)", va, 0, 0, 0);
    260 
    261 	return va;
    262 }
    263 
    264 static void
    265 pmap_md_unmap_ephemeral_page(struct vm_page_md *mdpg, bool locked_p,
    266     register_t va, pt_entry_t old_pte)
    267 {
    268 	KASSERT(VM_PAGEMD_VMPAGE_P(mdpg));
    269 
    270 	pv_entry_t pv = &mdpg->mdpg_first;
    271 
    272 	UVMHIST_FUNC(__func__);
    273 	UVMHIST_CALLARGS(pmaphist, "(pg=%#jx, va=%#lx, pte=%#"PRIxPTE")",
    274 	    (uintptr_t)VM_MD_TO_PAGE(mdpg), va, pte_value(old_pte), 0);
    275 
    276 	KASSERT(!locked_p || VM_PAGEMD_PVLIST_LOCKED_P(mdpg));
    277 
    278 	if (MIPS_CACHE_VIRTUAL_ALIAS) {
    279 		if (!locked_p)
    280 			(void)VM_PAGEMD_PVLIST_READLOCK(mdpg);
    281 		/*
    282 		 * If this page was previously uncached or we had to use an
    283 		 * incompatible alias, flush it from the cache.
    284 		 */
    285 		if (VM_PAGEMD_UNCACHED_P(mdpg)
    286 		    || (pv->pv_pmap != NULL
    287 			&& mips_cache_badalias(pv->pv_va, va))) {
    288 			mips_dcache_wbinv_range(va, PAGE_SIZE);
    289 		}
    290 		if (!locked_p)
    291 			VM_PAGEMD_PVLIST_UNLOCK(mdpg);
    292 	}
    293 	/*
    294 	 * If we had to map using a page table entry, restore it now.
    295 	 */
    296 	if (!pmap_md_direct_mapped_vaddr_p(va)) {
    297 		*pmap_pte_lookup(pmap_kernel(), va) = old_pte;
    298 		if (pte_valid_p(old_pte)) {
    299 			// Update the TLB with the old mapping.
    300 			tlb_update_addr(va, KERNEL_PID, old_pte, 0);
    301 		} else {
    302 			// Invalidate TLB entry if the old pte wasn't valid.
    303 			tlb_invalidate_addr(va, KERNEL_PID);
    304 		}
    305 		kpreempt_enable();	// Restore preemption
    306 	}
    307 	UVMHIST_LOG(pmaphist, " <-- done", 0, 0, 0, 0);
    308 }
    309 
    310 static void
    311 pmap_md_vca_page_wbinv(struct vm_page_md *mdpg, bool locked_p)
    312 {
    313 	UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
    314 	pt_entry_t pte;
    315 
    316 	const register_t va = pmap_md_map_ephemeral_page(mdpg, locked_p,
    317 	    VM_PROT_READ, &pte);
    318 
    319 	mips_dcache_wbinv_range(va, PAGE_SIZE);
    320 
    321 	pmap_md_unmap_ephemeral_page(mdpg, locked_p, va, pte);
    322 }
    323 
    324 bool
    325 pmap_md_ok_to_steal_p(const uvm_physseg_t bank, size_t npgs)
    326 {
    327 #ifndef _LP64
    328 	if (uvm_physseg_get_avail_start(bank) + npgs >= atop(MIPS_PHYS_MASK + 1)) {
    329 		aprint_debug("%s: seg not enough in KSEG0 for %zu pages\n",
    330 		    __func__, npgs);
    331 		return false;
    332 	}
    333 #endif
    334 	return true;
    335 }
    336 
    337 /*
    338  *	Bootstrap the system enough to run with virtual memory.
    339  */
    340 void
    341 pmap_bootstrap(void)
    342 {
    343 	vsize_t bufsz;
    344 	size_t sysmap_size;
    345 	pt_entry_t *sysmap;
    346 
    347 	if (MIPS_CACHE_VIRTUAL_ALIAS && uvmexp.ncolors) {
    348 		pmap_page_colormask = (uvmexp.ncolors - 1) << PAGE_SHIFT;
    349 		pmap_page_cache_alias_mask = uimax(
    350 		    mips_cache_info.mci_cache_alias_mask,
    351 		    mips_cache_info.mci_icache_alias_mask);
    352 	}
    353 
    354 #ifdef MULTIPROCESSOR
    355 	pmap_t pm = pmap_kernel();
    356 	kcpuset_create(&pm->pm_onproc, true);
    357 	kcpuset_create(&pm->pm_active, true);
    358 	KASSERT(pm->pm_onproc != NULL);
    359 	KASSERT(pm->pm_active != NULL);
    360 	kcpuset_set(pm->pm_onproc, cpu_number());
    361 	kcpuset_set(pm->pm_active, cpu_number());
    362 #endif
    363 
    364 	pmap_bootstrap_common();
    365 
    366 #ifdef MULTIPROCESSOR
    367 	struct cpu_info * const ci = curcpu();
    368 	kcpuset_create(&ci->ci_shootdowncpus, true);
    369 	KASSERT(ci->ci_shootdowncpus != NULL);
    370 #endif
    371 
    372 	pmap_tlb_info_init(&pmap_tlb0_info);		/* init the lock */
    373 
    374 	/*
    375 	 * Compute the number of pages kmem_arena will have.
    376 	 */
    377 	kmeminit_nkmempages();
    378 
    379 	/*
    380 	 * Figure out how many PTE's are necessary to map the kernel.
    381 	 * We also reserve space for kmem_alloc_pageable() for vm_fork().
    382 	 */
    383 
    384 	/* Get size of buffer cache and set an upper limit */
    385 	buf_setvalimit((VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / 8);
    386 	bufsz = buf_memcalc();
    387 	buf_setvalimit(bufsz);
    388 
    389 	sysmap_size = (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
    390 	    bufsz + 16 * NCARGS + pager_map_size) / NBPG +
    391 	    (maxproc * UPAGES) + nkmempages;
    392 
    393 #ifdef SYSVSHM
    394 	sysmap_size += shminfo.shmall;
    395 #endif
    396 #ifdef KSEG2IOBUFSIZE
    397 	sysmap_size += (KSEG2IOBUFSIZE >> PGSHIFT);
    398 #endif
    399 #ifdef _LP64
    400 	/*
    401 	 * If we are using tmpfs, then we might want to use a great deal of
    402 	 * our memory with it.  Make sure we have enough VM to do that.
    403 	 */
    404 	sysmap_size += physmem;
    405 #else
    406 	/* XXX: else runs out of space on 256MB sbmips!! */
    407 	sysmap_size += 20000;
    408 #endif
    409 	/* Roundup to a even number of pte page tables */
    410 	sysmap_size = (sysmap_size + NPTEPG - 1) & -NPTEPG;
    411 
    412 	/*
    413 	 * Initialize `FYI' variables.	Note we're relying on
    414 	 * the fact that BSEARCH sorts the vm_physmem[] array
    415 	 * for us.  Must do this before uvm_pageboot_alloc()
    416 	 * can be called.
    417 	 */
    418 	pmap_limits.avail_start = ptoa(uvm_physseg_get_start(uvm_physseg_get_first()));
    419 	pmap_limits.avail_end = ptoa(uvm_physseg_get_end(uvm_physseg_get_last()));
    420 	pmap_limits.virtual_end = pmap_limits.virtual_start + (vaddr_t)sysmap_size * NBPG;
    421 
    422 #ifndef _LP64
    423 	if (pmap_limits.virtual_end > VM_MAX_KERNEL_ADDRESS
    424 	    || pmap_limits.virtual_end < VM_MIN_KERNEL_ADDRESS) {
    425 		printf("%s: changing last kernel VA from %#"PRIxVADDR
    426 		    " to %#"PRIxVADDR"\n", __func__,
    427 		    pmap_limits.virtual_end, VM_MAX_KERNEL_ADDRESS);
    428 		pmap_limits.virtual_end = VM_MAX_KERNEL_ADDRESS;
    429 		sysmap_size =
    430 		    (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / NBPG;
    431 	}
    432 #endif
    433 	pmap_pvlist_lock_init(mips_cache_info.mci_pdcache_line_size);
    434 
    435 	/*
    436 	 * Now actually allocate the kernel PTE array (must be done
    437 	 * after pmap_limits.virtual_end is initialized).
    438 	 */
    439 	sysmap = (pt_entry_t *)
    440 	    uvm_pageboot_alloc(sizeof(pt_entry_t) * sysmap_size);
    441 
    442 	vaddr_t va = VM_MIN_KERNEL_ADDRESS;
    443 #ifdef _LP64
    444 	/*
    445 	 * Do we need more than one XSEG's worth virtual address space?
    446 	 * If so, we have to allocate the additional pmap_segtab_t's for them
    447 	 * and insert them into the kernel's top level segtab.
    448 	 */
    449 	const size_t xsegs = (sysmap_size * NBPG + NBXSEG - 1) / NBXSEG;
    450 	if (xsegs > 1) {
    451 		printf("%s: %zu xsegs required for %zu pages\n",
    452 		    __func__, xsegs, sysmap_size);
    453 		pmap_segtab_t *stb = (pmap_segtab_t *)
    454 		    uvm_pageboot_alloc(sizeof(pmap_segtab_t) * (xsegs - 1));
    455 		for (size_t i = 1; i <= xsegs; i++, stb++) {
    456 			pmap_kern_segtab.seg_seg[i] = stb;
    457 		}
    458 	}
    459 	pmap_segtab_t ** const xstb = pmap_kern_segtab.seg_seg;
    460 #else
    461 	const size_t xsegs = 1;
    462 	pmap_segtab_t * const stb = &pmap_kern_segtab;
    463 #endif
    464 	KASSERT(curcpu()->ci_pmap_kern_segtab == &pmap_kern_segtab);
    465 
    466 	for (size_t k = 0, i = 0; k < xsegs; k++) {
    467 #ifdef _LP64
    468 		pmap_segtab_t * const stb =
    469 		    xstb[(va >> XSEGSHIFT) & (NSEGPG - 1)];
    470 #endif
    471 		bool done = false;
    472 
    473 		for (size_t j = (va >> SEGSHIFT) & (NSEGPG - 1);
    474 		     !done && i < sysmap_size;
    475 		     i += NPTEPG, j++, va += NBSEG) {
    476 			/*
    477 			 * Now set the page table pointer...
    478 			 */
    479 			stb->seg_ppg[j] = (pmap_ptpage_t *)&sysmap[i];
    480 #ifdef _LP64
    481 			/*
    482 			 * If we are at end of this XSEG, terminate the loop
    483 			 * so we advance to the next one.
    484 			 */
    485 			done = (j + 1 == NSEGPG);
    486 #endif
    487 		}
    488 	}
    489 	KASSERT(pmap_pte_lookup(pmap_kernel(), VM_MIN_KERNEL_ADDRESS) == sysmap);
    490 
    491 	/* update the top of the kernel VM - pmap_growkernel not required */
    492 	pmap_curmaxkvaddr = pmap_limits.virtual_end;
    493 	/*
    494 	 * Initialize the pools.
    495 	 */
    496 	pool_init(&pmap_pmap_pool, PMAP_SIZE, 0, 0, 0, "pmappl",
    497 	    &pool_allocator_nointr, IPL_NONE);
    498 	pool_init(&pmap_pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pvpl",
    499 	    &pmap_pv_page_allocator, IPL_NONE);
    500 
    501 	tlb_set_asid(KERNEL_PID, pmap_kernel());
    502 
    503 #ifdef MIPS3_PLUS	/* XXX mmu XXX */
    504 	/*
    505 	 * The R4?00 stores only one copy of the Global bit in the
    506 	 * translation lookaside buffer for each 2 page entry.
    507 	 * Thus invalid entries must have the Global bit set so
    508 	 * when Entry LO and Entry HI G bits are anded together
    509 	 * they will produce a global bit to store in the tlb.
    510 	 */
    511 	if (MIPS_HAS_R4K_MMU) {
    512 		while (sysmap_size-- > 0) {
    513 			*sysmap++ = MIPS3_PG_G;
    514 		}
    515 	}
    516 #endif	/* MIPS3_PLUS */
    517 }
    518 
    519 void
    520 pmap_md_alloc_ephemeral_address_space(struct cpu_info *ci)
    521 {
    522 	struct mips_cache_info * const mci = &mips_cache_info;
    523 
    524 	/*
    525 	 * If we have more memory than can be mapped by KSEG0, we need to
    526 	 * allocate enough VA so we can map pages with the right color
    527 	 * (to avoid cache alias problems).
    528 	 */
    529 	if (false
    530 #ifndef _LP64
    531 	    || pmap_limits.avail_end > MIPS_KSEG1_START - MIPS_KSEG0_START
    532 #endif
    533 	    || MIPS_CACHE_VIRTUAL_ALIAS
    534 	    || MIPS_ICACHE_VIRTUAL_ALIAS) {
    535 		vsize_t size = uimax(mci->mci_pdcache_way_size, mci->mci_picache_way_size);
    536 		const u_int __diagused mask = pmap_page_cache_alias_mask;
    537 
    538 		ci->ci_pmap_dstbase = uvm_km_alloc(kernel_map, size, size,
    539 		    UVM_KMF_VAONLY);
    540 
    541 		KASSERT(ci->ci_pmap_dstbase);
    542 		KASSERT(!pmap_md_direct_mapped_vaddr_p(ci->ci_pmap_dstbase));
    543 		KASSERTMSG((ci->ci_pmap_dstbase & mask) == 0, "%#"PRIxVADDR,
    544 		    ci->ci_pmap_dstbase);
    545 
    546 		ci->ci_pmap_srcbase = uvm_km_alloc(kernel_map, size, size,
    547 		    UVM_KMF_VAONLY);
    548 		KASSERT(ci->ci_pmap_srcbase);
    549 		KASSERT(!pmap_md_direct_mapped_vaddr_p(ci->ci_pmap_srcbase));
    550 		KASSERTMSG((ci->ci_pmap_srcbase & mask) == 0, "%#"PRIxVADDR,
    551 		    ci->ci_pmap_srcbase);
    552 	}
    553 }
    554 
    555 void
    556 pmap_md_init(void)
    557 {
    558 	pmap_md_alloc_ephemeral_address_space(curcpu());
    559 
    560 #if defined(MIPS3) && 0
    561 	if (MIPS_HAS_R4K_MMU) {
    562 		/*
    563 		 * XXX
    564 		 * Disable sosend_loan() in src/sys/kern/uipc_socket.c
    565 		 * on MIPS3 CPUs to avoid possible virtual cache aliases
    566 		 * and uncached mappings in pmap_enter_pv().
    567 		 *
    568 		 * Ideally, read only shared mapping won't cause aliases
    569 		 * so pmap_enter_pv() should handle any shared read only
    570 		 * mappings without uncached ops like ARM pmap.
    571 		 *
    572 		 * On the other hand, R4000 and R4400 have the virtual
    573 		 * coherency exceptions which will happen even on read only
    574 		 * mappings, so we always have to disable sosend_loan()
    575 		 * on such CPUs.
    576 		 */
    577 		sock_loan_thresh = -1;
    578 	}
    579 #endif
    580 }
    581 
    582 /*
    583  * XXXJRT -- need a version for each cache type.
    584  */
    585 void
    586 pmap_procwr(struct proc *p, vaddr_t va, size_t len)
    587 {
    588 	if (MIPS_HAS_R4K_MMU) {
    589 		/*
    590 		 * XXX
    591 		 * shouldn't need to do this for physical d$?
    592 		 * should need to do this for virtual i$ if prot == EXEC?
    593 		 */
    594 		if (p == curlwp->l_proc
    595 		    && mips_cache_info.mci_pdcache_way_mask < PAGE_SIZE)
    596 		    /* XXX check icache mask too? */
    597 			mips_icache_sync_range((intptr_t)va, len);
    598 		else
    599 			mips_icache_sync_range_index((intptr_t)va, len);
    600 	} else {
    601 		pmap_t pmap = p->p_vmspace->vm_map.pmap;
    602 		kpreempt_disable();
    603 		pt_entry_t * const ptep = pmap_pte_lookup(pmap, va);
    604 		pt_entry_t entry = (ptep != NULL ? *ptep : 0);
    605 		kpreempt_enable();
    606 		if (!pte_valid_p(entry))
    607 			return;
    608 
    609 		mips_icache_sync_range(
    610 		    MIPS_PHYS_TO_KSEG0(pte_to_paddr(entry) + (va & PGOFSET)),
    611 		    len);
    612 	}
    613 }
    614 
    615 /*
    616  *	pmap_zero_page zeros the specified page.
    617  */
    618 void
    619 pmap_zero_page(paddr_t dst_pa)
    620 {
    621 	pt_entry_t dst_pte;
    622 
    623 	UVMHIST_FUNC(__func__);
    624 	UVMHIST_CALLARGS(pmaphist, "(pa=%#"PRIxPADDR")", dst_pa, 0, 0, 0);
    625 	PMAP_COUNT(zeroed_pages);
    626 
    627 	struct vm_page * const dst_pg = PHYS_TO_VM_PAGE(dst_pa);
    628 	struct vm_page_md * const dst_mdpg = VM_PAGE_TO_MD(dst_pg);
    629 
    630 	KASSERT(!VM_PAGEMD_EXECPAGE_P(dst_mdpg));
    631 
    632 	const register_t dst_va = pmap_md_map_ephemeral_page(dst_mdpg, false,
    633 	    VM_PROT_READ|VM_PROT_WRITE, &dst_pte);
    634 
    635 	mips_pagezero(dst_va);
    636 
    637 	pmap_md_unmap_ephemeral_page(dst_mdpg, false, dst_va, dst_pte);
    638 
    639 	UVMHIST_LOG(pmaphist, " <-- done", 0, 0, 0, 0);
    640 }
    641 
    642 /*
    643  *	pmap_copy_page copies the specified page.
    644  */
    645 void
    646 pmap_copy_page(paddr_t src_pa, paddr_t dst_pa)
    647 {
    648 	pt_entry_t src_pte, dst_pte;
    649 
    650 	UVMHIST_FUNC(__func__);
    651 	UVMHIST_CALLARGS(pmaphist, "(src_pa=%#lx, dst_pa=%#lx)", src_pa, dst_pa,
    652 	    0, 0);
    653 	PMAP_COUNT(copied_pages);
    654 
    655 	struct vm_page * const src_pg = PHYS_TO_VM_PAGE(src_pa);
    656 	struct vm_page * const dst_pg = PHYS_TO_VM_PAGE(dst_pa);
    657 
    658 	struct vm_page_md * const src_mdpg = VM_PAGE_TO_MD(src_pg);
    659 	struct vm_page_md * const dst_mdpg = VM_PAGE_TO_MD(dst_pg);
    660 
    661 	const register_t src_va = pmap_md_map_ephemeral_page(src_mdpg, false,
    662 	    VM_PROT_READ, &src_pte);
    663 
    664 	KASSERT(VM_PAGEMD_PVLIST_EMPTY_P(dst_mdpg));
    665 	KASSERT(!VM_PAGEMD_EXECPAGE_P(dst_mdpg));
    666 	const register_t dst_va = pmap_md_map_ephemeral_page(dst_mdpg, false,
    667 	    VM_PROT_READ|VM_PROT_WRITE, &dst_pte);
    668 
    669 	mips_pagecopy(dst_va, src_va);
    670 
    671 	pmap_md_unmap_ephemeral_page(dst_mdpg, false, dst_va, dst_pte);
    672 	pmap_md_unmap_ephemeral_page(src_mdpg, false, src_va, src_pte);
    673 
    674 	UVMHIST_LOG(pmaphist, " <-- done", 0, 0, 0, 0);
    675 }
    676 
    677 void
    678 pmap_md_page_syncicache(struct vm_page_md *mdpg, const kcpuset_t *onproc)
    679 {
    680 	UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
    681 	struct mips_options * const opts = &mips_options;
    682 	if (opts->mips_cpu_flags & CPU_MIPS_I_D_CACHE_COHERENT)
    683 		return;
    684 
    685 	/*
    686 	 * If onproc is empty, we could do a
    687 	 * pmap_page_protect(pg, VM_PROT_NONE) and remove all
    688 	 * mappings of the page and clear its execness.  Then
    689 	 * the next time page is faulted, it will get icache
    690 	 * synched.  But this is easier. :)
    691 	 */
    692 	if (MIPS_HAS_R4K_MMU) {
    693 		if (VM_PAGEMD_CACHED_P(mdpg)) {
    694 			/* This was probably mapped cached by UBC so flush it */
    695 			pt_entry_t pte;
    696 			const register_t tva = pmap_md_map_ephemeral_page(mdpg,
    697 			    false, VM_PROT_READ, &pte);
    698 
    699 			UVMHIST_LOG(pmaphist, "  va %#"PRIxVADDR, tva, 0, 0, 0);
    700 			mips_dcache_wbinv_range(tva, PAGE_SIZE);
    701 			mips_icache_sync_range(tva, PAGE_SIZE);
    702 
    703 			pmap_md_unmap_ephemeral_page(mdpg, false, tva, pte);
    704 		}
    705 	} else {
    706 		KASSERT(VM_PAGEMD_VMPAGE_P(mdpg));
    707 
    708 		struct vm_page *pg = VM_MD_TO_PAGE(mdpg);
    709 		mips_icache_sync_range(MIPS_PHYS_TO_KSEG0(VM_PAGE_TO_PHYS(pg)),
    710 		    PAGE_SIZE);
    711 	}
    712 #ifdef MULTIPROCESSOR
    713 	pv_entry_t pv = &mdpg->mdpg_first;
    714 	const register_t va = (intptr_t)trunc_page(pv->pv_va);
    715 	pmap_tlb_syncicache(va, onproc);
    716 #endif
    717 }
    718 
    719 struct vm_page *
    720 pmap_md_alloc_poolpage(int flags)
    721 {
    722 	/*
    723 	 * The VM_FREELIST used for pool pages is only set on 32bit
    724 	 * kernels.  This is to make sure that we only allocate pages
    725 	 * that can be mapped via KSEG0.  On 64bit kernels, all memory
    726 	 * can be mapped via XKPHYS so just use the default freelist.
    727 	 */
    728 	if (mips_poolpage_vmfreelist != VM_FREELIST_DEFAULT)
    729 		return uvm_pagealloc_strat(NULL, 0, NULL, flags,
    730 		    UVM_PGA_STRAT_ONLY, mips_poolpage_vmfreelist);
    731 
    732 	return uvm_pagealloc(NULL, 0, NULL, flags);
    733 }
    734 
    735 vaddr_t
    736 pmap_md_map_poolpage(paddr_t pa, size_t len)
    737 {
    738 
    739 	struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
    740 	vaddr_t va = pmap_md_pool_phystov(pa);
    741 	KASSERT(cold || pg != NULL);
    742 	if (pg != NULL) {
    743 		struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
    744 		pv_entry_t pv = &mdpg->mdpg_first;
    745 		vaddr_t last_va = trunc_page(pv->pv_va);
    746 
    747 		KASSERT(len == PAGE_SIZE || last_va == pa);
    748 		KASSERT(pv->pv_pmap == NULL);
    749 		KASSERT(pv->pv_next == NULL);
    750 		KASSERT(!VM_PAGEMD_EXECPAGE_P(mdpg));
    751 
    752 		/*
    753 		 * If this page was last mapped with an address that
    754 		 * might cause aliases, flush the page from the cache.
    755 		 */
    756 		if (MIPS_CACHE_VIRTUAL_ALIAS
    757 		    && mips_cache_badalias(last_va, va)) {
    758 			pmap_md_vca_page_wbinv(mdpg, false);
    759 		}
    760 
    761 		pv->pv_va = va;
    762 	}
    763 	return va;
    764 }
    765 
    766 paddr_t
    767 pmap_md_unmap_poolpage(vaddr_t va, size_t len)
    768 {
    769 	KASSERT(len == PAGE_SIZE);
    770 	KASSERT(pmap_md_direct_mapped_vaddr_p(va));
    771 
    772 	const paddr_t pa = pmap_md_direct_mapped_vaddr_to_paddr(va);
    773 	struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
    774 
    775 	KASSERT(pg);
    776 	struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
    777 
    778 	KASSERT(VM_PAGEMD_CACHED_P(mdpg));
    779 	KASSERT(!VM_PAGEMD_EXECPAGE_P(mdpg));
    780 
    781 	pv_entry_t pv = &mdpg->mdpg_first;
    782 
    783 	/* Note last mapped address for future color check */
    784 	pv->pv_va = va;
    785 
    786 	KASSERT(pv->pv_pmap == NULL);
    787 	KASSERT(pv->pv_next == NULL);
    788 
    789 	return pa;
    790 }
    791 
    792 bool
    793 pmap_md_direct_mapped_vaddr_p(register_t va)
    794 {
    795 #ifndef __mips_o32
    796 	if (MIPS_XKPHYS_P(va))
    797 		return true;
    798 #endif
    799 	return MIPS_KSEG0_P(va);
    800 }
    801 
    802 paddr_t
    803 pmap_md_direct_mapped_vaddr_to_paddr(register_t va)
    804 {
    805 	if (MIPS_KSEG0_P(va)) {
    806 		return MIPS_KSEG0_TO_PHYS(va);
    807 	}
    808 #ifndef __mips_o32
    809 	if (MIPS_XKPHYS_P(va)) {
    810 		return MIPS_XKPHYS_TO_PHYS(va);
    811 	}
    812 #endif
    813 	panic("%s: va %#"PRIxREGISTER" not direct mapped!", __func__, va);
    814 }
    815 
    816 bool
    817 pmap_md_io_vaddr_p(vaddr_t va)
    818 {
    819 #ifdef _LP64
    820 	if (MIPS_XKPHYS_P(va)) {
    821 		return MIPS_XKPHYS_TO_CCA(va) == CCA_UNCACHED;
    822 	}
    823 #endif
    824 	return MIPS_KSEG1_P(va);
    825 }
    826 
    827 void
    828 pmap_md_icache_sync_range_index(vaddr_t va, vsize_t len)
    829 {
    830 	UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
    831 	mips_icache_sync_range_index(va, len);
    832 }
    833 
    834 void
    835 pmap_md_icache_sync_all(void)
    836 {
    837 	UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
    838 	mips_icache_sync_all();
    839 }
    840 
    841 #ifdef MULTIPROCESSOR
    842 void
    843 pmap_md_tlb_info_attach(struct pmap_tlb_info *ti, struct cpu_info *ci)
    844 {
    845 	if (ci->ci_index != 0)
    846 		return;
    847 	const u_int icache_way_pages =
    848 	    mips_cache_info.mci_picache_way_size >> PGSHIFT;
    849 
    850 	KASSERT(icache_way_pages <= 8*sizeof(pmap_tlb_synci_page_mask));
    851 	pmap_tlb_synci_page_mask = icache_way_pages - 1;
    852 	pmap_tlb_synci_map_mask = ~(~0 << icache_way_pages);
    853 	printf("tlb0: synci page mask %#x and map mask %#x used for %u pages\n",
    854 	    pmap_tlb_synci_page_mask, pmap_tlb_synci_map_mask, icache_way_pages);
    855 }
    856 #endif
    857 
    858 
    859 bool
    860 pmap_md_tlb_check_entry(void *ctx, vaddr_t va, tlb_asid_t asid, pt_entry_t pte)
    861 {
    862 	pmap_t pm = ctx;
    863 	struct pmap_tlb_info * const ti = cpu_tlb_info(curcpu());
    864 	struct pmap_asid_info * const pai = PMAP_PAI(pm, ti);
    865 
    866 	if (asid != pai->pai_asid)
    867 		return true;
    868 	if (!pte_valid_p(pte)) {
    869 		KASSERT(MIPS_HAS_R4K_MMU);
    870 		KASSERTMSG(pte == MIPS3_PG_G, "va %#"PRIxVADDR" pte %#"PRIxPTE,
    871 		    va, pte_value(pte));
    872 		return true;
    873 	}
    874 
    875 	const pt_entry_t * const ptep = pmap_pte_lookup(pm, va);
    876 	KASSERTMSG(ptep != NULL, "va %#"PRIxVADDR" asid %u pte %#"PRIxPTE,
    877 	    va, asid, pte_value(pte));
    878 	const pt_entry_t opte = *ptep;
    879 	pt_entry_t xpte = opte;
    880 	if (MIPS_HAS_R4K_MMU) {
    881 		xpte &= ~(MIPS3_PG_WIRED|MIPS3_PG_RO);
    882 	} else {
    883 		xpte &= ~(MIPS1_PG_WIRED|MIPS1_PG_RO);
    884 	}
    885 	/*
    886 	 * Don't check for differences in the TLB entry modified status for
    887 	 * kernel mappings as they can be modified while the kernel pmap is
    888 	 * being updated, see PR59518.
    889 	 */
    890 	if (pm == pmap_kernel()) {
    891 		if (MIPS_HAS_R4K_MMU) {
    892 			xpte ^= (pte ^ xpte) & MIPS3_PG_D;
    893 		} else {
    894 			xpte ^= (pte ^ xpte) & MIPS1_PG_D;
    895 		}
    896 	}
    897 
    898         KASSERTMSG(pte == xpte,
    899             "pmap=%p va=%#"PRIxVADDR" asid=%u: TLB pte (%#"PRIxPTE
    900 	    ") != real pte (%#"PRIxPTE"/%#"PRIxPTE") @ %p",
    901             pm, va, asid, pte_value(pte), pte_value(xpte), pte_value(opte),
    902 	    ptep);
    903 
    904         return true;
    905 }
    906 
    907 void
    908 tlb_walk(void *ctx, tlb_walkfunc_t func)
    909 {
    910 	kpreempt_disable();
    911 	for (size_t i = 0; i < mips_options.mips_num_tlb_entries; i++) {
    912 		struct tlbmask tlbmask;
    913 		tlb_asid_t asid;
    914 		vaddr_t va;
    915 		tlb_read_entry(i, &tlbmask);
    916 		if (MIPS_HAS_R4K_MMU) {
    917 			asid = __SHIFTOUT(tlbmask.tlb_hi, MIPS3_PG_ASID);
    918 			va = tlbmask.tlb_hi & MIPS3_PG_HVPN;
    919 		} else {
    920 			asid = __SHIFTOUT(tlbmask.tlb_hi, MIPS1_TLB_PID);
    921 			va = tlbmask.tlb_hi & MIPS1_PG_FRAME;
    922 		}
    923 		if ((pt_entry_t)tlbmask.tlb_lo0 != 0) {
    924 			pt_entry_t pte = tlbmask.tlb_lo0;
    925 			tlb_asid_t asid0 = (pte_global_p(pte) ? KERNEL_PID : asid);
    926 			if (!(*func)(ctx, va, asid0, pte))
    927 				break;
    928 		}
    929 #if (PGSHIFT & 1) == 0
    930 		if (MIPS_HAS_R4K_MMU && (pt_entry_t)tlbmask.tlb_lo1 != 0) {
    931 			pt_entry_t pte = tlbmask.tlb_lo1;
    932 			tlb_asid_t asid1 = (pte_global_p(pte) ? KERNEL_PID : asid);
    933 			if (!(*func)(ctx, va + MIPS3_PG_ODDPG, asid1, pte))
    934 				break;
    935 		}
    936 #endif
    937 	}
    938 	kpreempt_enable();
    939 }
    940 
    941 bool
    942 pmap_md_vca_add(struct vm_page_md *mdpg, vaddr_t va, pt_entry_t *ptep)
    943 {
    944 	UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
    945 	if (!MIPS_HAS_R4K_MMU || !MIPS_CACHE_VIRTUAL_ALIAS)
    946 		return false;
    947 
    948 	/*
    949 	 * There is at least one other VA mapping this page.
    950 	 * Check if they are cache index compatible.
    951 	 */
    952 
    953 	KASSERT(VM_PAGEMD_PVLIST_LOCKED_P(mdpg));
    954 	pv_entry_t pv = &mdpg->mdpg_first;
    955 #if defined(PMAP_NO_PV_UNCACHED)
    956 	/*
    957 	 * Instead of mapping uncached, which some platforms
    958 	 * cannot support, remove incompatible mappings from others pmaps.
    959 	 * When this address is touched again, the uvm will
    960 	 * fault it in.  Because of this, each page will only
    961 	 * be mapped with one index at any given time.
    962 	 *
    963 	 * We need to deal with all entries on the list - if the first is
    964 	 * incompatible with the new mapping then they all will be.
    965 	 */
    966 	if (__predict_true(!mips_cache_badalias(pv->pv_va, va))) {
    967 		return false;
    968 	}
    969 	KASSERT(pv->pv_pmap != NULL);
    970 	bool ret = false;
    971 	for (pv_entry_t npv = pv; npv && npv->pv_pmap;) {
    972 		if (PV_ISKENTER_P(npv)) {
    973 			npv = npv->pv_next;
    974 			continue;
    975 		}
    976 		ret = true;
    977 		vaddr_t nva = trunc_page(npv->pv_va);
    978 		pmap_t npm = npv->pv_pmap;
    979 		VM_PAGEMD_PVLIST_UNLOCK(mdpg);
    980 		pmap_remove(npm, nva, nva + PAGE_SIZE);
    981 
    982 		/*
    983 		 * pmap_update is not required here as we're the pmap
    984 		 * and we know that the invalidation happened or the
    985 		 * asid has been released (and activation is deferred)
    986 		 *
    987 		 * A deferred activation should NOT occur here.
    988 		 */
    989 		(void)VM_PAGEMD_PVLIST_LOCK(mdpg);
    990 
    991 		npv = pv;
    992 	}
    993 	KASSERT(ret == true);
    994 
    995 	return ret;
    996 #else	/* !PMAP_NO_PV_UNCACHED */
    997 	if (VM_PAGEMD_CACHED_P(mdpg)) {
    998 		/*
    999 		 * If this page is cached, then all mappings
   1000 		 * have the same cache alias so we only need
   1001 		 * to check the first page to see if it's
   1002 		 * incompatible with the new mapping.
   1003 		 *
   1004 		 * If the mappings are incompatible, map this
   1005 		 * page as uncached and re-map all the current
   1006 		 * mapping as uncached until all pages can
   1007 		 * share the same cache index again.
   1008 		 */
   1009 		if (mips_cache_badalias(pv->pv_va, va)) {
   1010 			pmap_page_cache(mdpg, false);
   1011 			pmap_md_vca_page_wbinv(mdpg, true);
   1012 			*ptep = pte_cached_change(*ptep, false);
   1013 			PMAP_COUNT(page_cache_evictions);
   1014 		}
   1015 	} else {
   1016 		*ptep = pte_cached_change(*ptep, false);
   1017 		PMAP_COUNT(page_cache_evictions);
   1018 	}
   1019 	return false;
   1020 #endif	/* !PMAP_NO_PV_UNCACHED */
   1021 }
   1022 
   1023 void
   1024 pmap_md_vca_clean(struct vm_page_md *mdpg, int op)
   1025 {
   1026 	UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
   1027 	if (!MIPS_HAS_R4K_MMU || !MIPS_CACHE_VIRTUAL_ALIAS)
   1028 		return;
   1029 
   1030 	UVMHIST_LOG(pmaphist, "(mdpg=%#jx, op=%d)", (uintptr_t)mdpg, op, 0, 0);
   1031 	KASSERT(VM_PAGEMD_PVLIST_LOCKED_P(mdpg));
   1032 
   1033 	if (op == PMAP_WB || op == PMAP_WBINV) {
   1034 		pmap_md_vca_page_wbinv(mdpg, true);
   1035 	} else if (op == PMAP_INV) {
   1036 		KASSERT(op == PMAP_INV && false);
   1037 		//mips_dcache_inv_range_index(va, PAGE_SIZE);
   1038 	}
   1039 }
   1040 
   1041 /*
   1042  * In the PMAP_NO_PV_CACHED case, all conflicts are resolved at mapping
   1043  * so nothing needs to be done in removal.
   1044  */
   1045 void
   1046 pmap_md_vca_remove(struct vm_page *pg, vaddr_t va, bool dirty, bool last)
   1047 {
   1048 #if !defined(PMAP_NO_PV_UNCACHED)
   1049 	struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg);
   1050 	if (!MIPS_HAS_R4K_MMU
   1051 	    || !MIPS_CACHE_VIRTUAL_ALIAS
   1052 	    || !VM_PAGEMD_UNCACHED_P(mdpg))
   1053 		return;
   1054 
   1055 	KASSERT(kpreempt_disabled());
   1056 	KASSERT((va & PAGE_MASK) == 0);
   1057 
   1058 	/*
   1059 	 * Page is currently uncached, check if alias mapping has been
   1060 	 * removed.  If it was, then reenable caching.
   1061 	 */
   1062 	(void)VM_PAGEMD_PVLIST_READLOCK(mdpg);
   1063 	pv_entry_t pv = &mdpg->mdpg_first;
   1064 	pv_entry_t pv0 = pv->pv_next;
   1065 
   1066 	for (; pv0; pv0 = pv0->pv_next) {
   1067 		if (mips_cache_badalias(pv->pv_va, pv0->pv_va))
   1068 			break;
   1069 	}
   1070 	if (pv0 == NULL)
   1071 		pmap_page_cache(mdpg, true);
   1072 	VM_PAGEMD_PVLIST_UNLOCK(mdpg);
   1073 #endif
   1074 }
   1075 
   1076 paddr_t
   1077 pmap_md_pool_vtophys(vaddr_t va)
   1078 {
   1079 #ifdef _LP64
   1080 	if (MIPS_XKPHYS_P(va))
   1081 		return MIPS_XKPHYS_TO_PHYS(va);
   1082 #endif
   1083 	KASSERT(MIPS_KSEG0_P(va));
   1084 	return MIPS_KSEG0_TO_PHYS(va);
   1085 }
   1086 
   1087 vaddr_t
   1088 pmap_md_pool_phystov(paddr_t pa)
   1089 {
   1090 #ifdef _LP64
   1091 	KASSERT(mips_options.mips3_xkphys_cached);
   1092 	return MIPS_PHYS_TO_XKPHYS_CACHED(pa);
   1093 #else
   1094 	KASSERT((pa & ~MIPS_PHYS_MASK) == 0);
   1095 	return MIPS_PHYS_TO_KSEG0(pa);
   1096 #endif
   1097 }
   1098