These file are no longer used (moved to userland and/or merged into

pmap.c).
This commit is contained in:
Jake Burkholder 2002-07-31 16:23:27 +00:00
parent 43b2936963
commit 055ca86c52
5 changed files with 0 additions and 689 deletions

View File

@ -1,39 +0,0 @@
/*-
* Copyright (c) 2001 by Thomas Moestl <tmm@FreeBSD.org>.
* 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 ``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.
*
* $FreeBSD$
*/
#ifndef _MACHINE_EMUL_H_
#define _MACHINE_EMUL_H_
/* Interfaces for trap.c */
int unaligned_fixup(struct thread *_td, struct trapframe *_tf);
int emul_insn(struct thread *_td, struct trapframe *_tf);
/* Interfaces for emulation code. */
int emul_fetch_reg(struct trapframe *_tf, int _reg, u_long *_val);
int emul_store_reg(struct trapframe *_tf, int _reg, u_long _val);
#endif /* !_MACHINE_EMUL_H_ */

View File

@ -1,54 +0,0 @@
/*-
* Copyright (c) 1991 Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
* Science Department and William Jolitz of UUNET Technologies Inc.
*
* 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 the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $FreeBSD$
*/
#ifndef _MACHINE_PV_H_
#define _MACHINE_PV_H_
struct tte;
void pv_insert(pmap_t pm, vm_page_t m, struct tte *tp);
void pv_remove(pmap_t pm, vm_page_t m, struct tte *tp);
int pv_page_exists(pmap_t pm, vm_page_t m);
void pv_remove_all(vm_page_t m);
void pv_bit_clear(vm_page_t m, u_long bits);
int pv_bit_count(vm_page_t m, u_long bits);
int pv_bit_test(vm_page_t m, u_long bits);
#endif /* !_MACHINE_PV_H_ */

View File

@ -1,294 +0,0 @@
/*-
* Copyright (c) 2001 by Thomas Moestl <tmm@FreeBSD.org>.
* 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 ``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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/proc.h>
#include <sys/signal.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <machine/emul.h>
#include <machine/frame.h>
#include <machine/instr.h>
/*
* Alpha-compatible sysctls to control the alignment fixup.
*/
static int unaligned_print = 0; /* warn about unaligned accesses */
static int unaligned_fix = 1; /* fix up unaligned accesses */
static int unaligned_sigbus = 0; /* don't SIGBUS on fixed-up accesses */
SYSCTL_INT(_machdep, OID_AUTO, unaligned_print, CTLFLAG_RW,
&unaligned_print, 0, "");
SYSCTL_INT(_machdep, OID_AUTO, unaligned_fix, CTLFLAG_RW,
&unaligned_fix, 0, "");
SYSCTL_INT(_machdep, OID_AUTO, unaligned_sigbus, CTLFLAG_RW,
&unaligned_sigbus, 0, "");
int
emul_fetch_reg(struct trapframe *tf, int reg, u_long *val)
{
u_long offs;
CTR1(KTR_TRAP, "emul_fetch_reg: register %d", reg);
if (reg == IREG_G0)
*val = 0;
else if (reg < IREG_O0) /* global */
*val = tf->tf_global[reg];
else if (reg < IREG_L0) /* out */
*val = tf->tf_out[reg - IREG_O0];
else { /* local, in */
/*
* The in registers are immediately after the locals in
* the frame.
*/
offs = offsetof(struct frame, fr_local[reg - IREG_L0]);
return (copyin((void *)(tf->tf_sp + SPOFF + offs), val,
sizeof(*val)));
}
return (0);
}
int
emul_store_reg(struct trapframe *tf, int reg, u_long val)
{
u_long offs;
CTR1(KTR_TRAP, "emul_store_reg: register %d", reg);
if (reg == IREG_G0)
return (0);
if (reg < IREG_O0) /* global */
tf->tf_global[reg] = val;
else if (reg < IREG_L0) /* out */
tf->tf_out[reg - IREG_O0] = val;
else { /* local, in */
/*
* The in registers are immediately after the locals in
* the frame.
*/
offs = offsetof(struct frame, fr_local[reg - IREG_L0]);
return (copyout(&val, (void *)(tf->tf_sp + SPOFF + offs),
sizeof(val)));
}
return (0);
}
/* Retrieve rs2 or use the immediate value from the instruction */
static int
f3_op2(struct trapframe *tf, u_int insn, u_long *op2)
{
int error;
if (IF_F3_I(insn) != 0)
*op2 = IF_SIMM(insn, 13);
else {
if ((error = emul_fetch_reg(tf, IF_F3_RS2(insn), op2)) != 0)
return (error);
}
return (0);
}
/*
* XXX: should the addr from the sfar be used instead of decoding the
* instruction?
*/
static int
f3_memop_addr(struct trapframe *tf, u_int insn, u_long *addr)
{
u_long addr1;
int error;
if ((error = f3_op2(tf, insn, &addr1)) != 0)
return (error);
CTR2(KTR_TRAP, "f3_memop_addr: addr1: %#lx (imm %d)", addr1, IF_F3_I(insn));
error = emul_fetch_reg(tf, IF_F3_RS1(insn), addr);
*addr += addr1;
return (error);
}
static int
fixup_st(struct trapframe *tf, u_int insn, int size)
{
u_long addr, reg;
int error;
if ((error = f3_memop_addr(tf, insn, &addr)) != 0)
return (error);
if ((error = emul_fetch_reg(tf, IF_F3_RD(insn), &reg)) != 0)
return (error);
reg <<= 8 * (8 - size);
CTR1(KTR_TRAP, "fixup_st: writing to %#lx", addr);
return (copyout(&reg, (void *)addr, size));
}
static int
fixup_ld(struct trapframe *tf, u_int insn, int size, int sign)
{
u_long addr, reg;
int error;
if ((error = f3_memop_addr(tf, insn, &addr)) != 0)
return (error);
reg = 0;
CTR1(KTR_TRAP, "fixup_ld: reading from %#lx", addr);
if ((error = copyin((void *)addr, &reg, size)) != 0)
return (error);
reg >>= 8 * (8 - size);
if (sign && size < 8) {
/* Need to sign-extend. */
reg = IF_SEXT(reg, size * 8);
}
return (emul_store_reg(tf, IF_F3_RD(insn), reg));
}
/*
* NOTE: fixed up loads and stores are not atomical any more (in some cases,
* they could be made, though, but that is not implemented yet). This means
* that in some sorts of programs, this emulation could cause bugs.
* XXX: this is still very incomplete!
*/
int
unaligned_fixup(struct thread *td, struct trapframe *tf)
{
struct proc *p;
u_int insn;
int fixed, error;
p = td->td_proc;
if (rwindow_save(td) != 0) {
/*
* The process will need to be killed without sending a
* signal; let the signal code do that.
*/
return (SIGBUS);
}
if (copyin((void *)tf->tf_tpc, &insn, sizeof(insn)) != 0)
return (SIGBUS);
CTR1(KTR_TRAP, "unaligned_fixup: insn %x", insn);
fixed = 0;
if (unaligned_fix) {
error = 0;
if (IF_OP(insn) == IOP_LDST) {
fixed = 1;
switch (IF_F3_OP3(insn)) {
case INS3_LDUH:
error = fixup_ld(tf, insn, 2, 0);
break;
case INS3_LDUW:
error = fixup_ld(tf, insn, 4, 0);
break;
case INS3_LDX:
error = fixup_ld(tf, insn, 8, 0);
break;
case INS3_LDSH:
error = fixup_ld(tf, insn, 2, 1);
break;
case INS3_LDSW:
error = fixup_ld(tf, insn, 4, 1);
break;
case INS3_STH:
error = fixup_st(tf, insn, 2);
break;
case INS3_STW:
error = fixup_st(tf, insn, 4);
break;
case INS3_STX:
error = fixup_st(tf, insn, 8);
break;
default:
fixed = 0;
}
}
if (error != 0)
return (SIGBUS);
}
CTR5(KTR_TRAP, "unaligned_fixup: pid %d, va=%#lx pc=%#lx "
"npc=%#lx, fixed=%d", p->p_pid, tf->tf_sfar, tf->tf_tpc,
tf->tf_tnpc, fixed);
if (unaligned_print || !fixed) {
uprintf("pid %d (%s): unaligned access: va=%#lx pc=%#lx "
"npc=%#lx %s\n", p->p_pid, p->p_comm, tf->tf_sfar,
tf->tf_tpc, tf->tf_tnpc, fixed ? "(fixed)" : "(unfixable)");
}
return (fixed && !unaligned_sigbus ? 0 : SIGBUS);
}
static int
emul_popc(struct trapframe *tf, u_int insn)
{
u_long reg, res;
int i;
if (IF_F3_RS1(insn) != 0)
return (SIGILL);
if (f3_op2(tf, insn, &reg) != 0)
return (SIGBUS);
res = 0;
for (i = 0; i < 64; i++)
res += (reg >> i) & 1;
if (emul_store_reg(tf, IF_F3_RD(insn), res) != 0)
return (SIGBUS);
return (0);
}
/*
* Emulate unimplemented instructions, if applicable.
* Only handles popc right now.
*/
int
emul_insn(struct thread *td, struct trapframe *tf)
{
u_int insn;
if (rwindow_save(td) != 0) {
/*
* The process will need to be killed without sending a
* signal; let the signal code do that.
*/
return (SIGBUS);
}
if (copyin((void *)tf->tf_tpc, &insn, sizeof(insn)) != 0)
return (SIGBUS);
CTR1(KTR_TRAP, "emulate_insn: insn %x", insn);
switch (IF_OP(insn)) {
case IOP_MISC:
switch (IF_F3_OP3(insn)) {
case INS2_POPC:
return (emul_popc(tf, insn));
}
break;
}
return (SIGILL);
}

View File

@ -1,97 +0,0 @@
/*-
* Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. 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 ``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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/ktr.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/user.h>
#include <machine/fp.h>
#include <machine/frame.h>
#include <machine/fsr.h>
#include <machine/pcb.h>
#include <machine/tstate.h>
void
fp_init_thread(struct thread *td)
{
struct trapframe *tf;
struct pcb *pcb;
pcb = td->td_pcb;
tf = td->td_frame;
bzero(&pcb->pcb_fpstate.fp_fb, sizeof(pcb->pcb_fpstate.fp_fb));
#if 0
pcb->pcb_fpstate.fp_fsr = 0;
#else
/*
* This causes subnormal operands to be treated as zeroes, which
* prevents unfinished_FPop traps in this cases, which would require
* emultation that is not yet implemented.
* This does of course reduce the accuracy, so it should be removed
* as soon as possible.
*/
tf->tf_fsr = FSR_NS;
#endif
tf->tf_fprs = 0;
}
int
fp_enable_thread(struct thread *td, struct trapframe *tf)
{
struct pcb *pcb;
pcb = td->td_pcb;
CTR5(KTR_TRAP, "fp_enable_thread: tpc=%#lx, tnpc=%#lx, tstate=%#lx, "
"fprs=%#lx, fsr=%#lx", tf->tf_tpc, tf->tf_tnpc, tf->tf_tstate,
tf->tf_fprs, tf->tf_fsr);
if ((tf->tf_fprs & FPRS_FEF) != 0)
return (0);
/*
* Enable FEF for now. The SCD mandates that this should be
* done when no user trap is set. User traps are not currently
* supported...
*/
tf->tf_fprs |= FPRS_FEF;
mtx_lock_spin(&sched_lock);
restorefpctx(&pcb->pcb_fpstate);
mtx_unlock_spin(&sched_lock);
return (1);
}
int
fp_exception_other(struct thread *td, struct trapframe *tf)
{
CTR4(KTR_TRAP, "fp_exception_other: tpc=%#lx, tnpc=%#lx, ftt=%lx "
"fsr=%lx", tf->tf_tpc, tf->tf_tnpc, FSR_FTT(tf->tf_fsr), tf->tf_fsr);
/* XXX: emulate unimplemented and unfinished instructions. */
return (SIGFPE);
}

View File

@ -1,205 +0,0 @@
/*-
* Copyright (c) 1991 Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
* Science Department and William Jolitz of UUNET Technologies Inc.
*
* 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 the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/smp.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/vm_param.h>
#include <vm/vm_kern.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
#include <vm/uma.h>
#include <machine/asi.h>
#include <machine/frame.h>
#include <machine/pmap.h>
#include <machine/pv.h>
#include <machine/smp.h>
#include <machine/tte.h>
#include <machine/tlb.h>
#include <machine/tsb.h>
/*
* Insert a mapped stte at the tail of an address alias chain.
*/
void
pv_insert(pmap_t pm, vm_page_t m, struct tte *tp)
{
STAILQ_INSERT_TAIL(&m->md.tte_list, tp, tte_link);
tp->tte_pmap = pm;
pm->pm_stats.resident_count++;
}
/*
* Remove a mapped tte from its address alias chain.
*/
void
pv_remove(pmap_t pm, vm_page_t m, struct tte *tp)
{
STAILQ_REMOVE(&m->md.tte_list, tp, tte, tte_link);
if (STAILQ_EMPTY(&m->md.tte_list))
vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
tp->tte_pmap->pm_stats.resident_count--;
}
void
pv_bit_clear(vm_page_t m, u_long bits)
{
struct tte *tp;
STAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
if ((tp->tte_data & bits) != 0) {
if ((bits & TD_SW) != 0 &&
pmap_track_modified(TTE_GET_PMAP(tp),
TTE_GET_VA(tp))) {
if (tp->tte_data & TD_W)
vm_page_dirty(m);
}
tp->tte_data &= ~bits;
tlb_tte_demap(tp, TTE_GET_PMAP(tp));
}
}
}
int
pv_bit_count(vm_page_t m, u_long bits)
{
struct tte *tpf;
struct tte *tpn;
struct tte *tp;
int count;
count = 0;
if ((tp = STAILQ_FIRST(&m->md.tte_list)) != NULL) {
tpf = tp;
do {
tpn = STAILQ_NEXT(tp, tte_link);
STAILQ_REMOVE(&m->md.tte_list, tp, tte, tte_link);
STAILQ_INSERT_TAIL(&m->md.tte_list, tp, tte_link);
if (!pmap_track_modified(TTE_GET_PMAP(tp),
TTE_GET_VA(tp)))
continue;
if ((tp->tte_data & bits) != 0) {
tp->tte_data &= ~bits;
if (++count > 4)
break;
}
} while ((tp = tpn) != NULL && tp != tpf);
}
return (count);
}
int
pv_bit_test(vm_page_t m, u_long bits)
{
struct tte *tp;
STAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
if (bits & (TD_REF | TD_W)) {
if (!pmap_track_modified(TTE_GET_PMAP(tp),
TTE_GET_VA(tp)))
continue;
}
if (tp->tte_data & bits)
return (TRUE);
}
return (FALSE);
}
/*
* See pmap_page_exists_quick for operational explanation of
* pv_page_exists.
*/
int
pv_page_exists(pmap_t pm, vm_page_t m)
{
struct tte *tp;
int loops;
loops = 0;
STAILQ_FOREACH(tp, &m->md.tte_list, tte_link) {
if (TTE_GET_PMAP(tp) == pm)
return (TRUE);
if (++loops >= 16)
break;
}
return (FALSE);
}
void
pv_remove_all(vm_page_t m)
{
struct pmap *pm;
struct tte *tp;
vm_offset_t va;
KASSERT((m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0,
("pv_remove_all: illegal for unmanaged page %#lx",
VM_PAGE_TO_PHYS(m)));
while ((tp = STAILQ_FIRST(&m->md.tte_list)) != NULL) {
pm = TTE_GET_PMAP(tp);
va = TTE_GET_VA(tp);
if ((tp->tte_data & TD_WIRED) != 0)
pm->pm_stats.wired_count--;
if ((tp->tte_data & TD_REF) != 0)
vm_page_flag_set(m, PG_REFERENCED);
if ((tp->tte_data & TD_W) != 0) {
if (pmap_track_modified(pm, va))
vm_page_dirty(m);
}
tp->tte_data &= ~TD_V;
tlb_page_demap(TLB_DTLB | TLB_ITLB, pm, va);
STAILQ_REMOVE(&m->md.tte_list, tp, tte, tte_link);
pm->pm_stats.resident_count--;
pmap_cache_remove(m, va);
TTE_ZERO(tp);
}
KASSERT(STAILQ_EMPTY(&m->md.tte_list),
("pv_remove_all: leaking pv entries"));
vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
}