diff options
| author | Jake Burkholder <jake@FreeBSD.org> | 2002-07-31 16:23:27 +0000 |
|---|---|---|
| committer | Jake Burkholder <jake@FreeBSD.org> | 2002-07-31 16:23:27 +0000 |
| commit | 055ca86c523a0c60638ec6d886a4de85c67c6374 (patch) | |
| tree | 46beecc73458ad00103df893578ae1fee656d2e0 | |
| parent | 43b29369636c186a5c4a944ccc4a7fb36f9edee0 (diff) | |
Notes
| -rw-r--r-- | sys/sparc64/include/emul.h | 39 | ||||
| -rw-r--r-- | sys/sparc64/include/pv.h | 54 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/emul.c | 294 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/fp.c | 97 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/pv.c | 205 |
5 files changed, 0 insertions, 689 deletions
diff --git a/sys/sparc64/include/emul.h b/sys/sparc64/include/emul.h deleted file mode 100644 index dccfa9c1e11d..000000000000 --- a/sys/sparc64/include/emul.h +++ /dev/null @@ -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_ */ diff --git a/sys/sparc64/include/pv.h b/sys/sparc64/include/pv.h deleted file mode 100644 index 5d977d794c0c..000000000000 --- a/sys/sparc64/include/pv.h +++ /dev/null @@ -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_ */ diff --git a/sys/sparc64/sparc64/emul.c b/sys/sparc64/sparc64/emul.c deleted file mode 100644 index 5c163f105907..000000000000 --- a/sys/sparc64/sparc64/emul.c +++ /dev/null @@ -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), ®)) != 0) - return (error); - reg <<= 8 * (8 - size); - CTR1(KTR_TRAP, "fixup_st: writing to %#lx", addr); - return (copyout(®, (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, ®, 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, ®) != 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); -} diff --git a/sys/sparc64/sparc64/fp.c b/sys/sparc64/sparc64/fp.c deleted file mode 100644 index b49cf6b0b132..000000000000 --- a/sys/sparc64/sparc64/fp.c +++ /dev/null @@ -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); -} diff --git a/sys/sparc64/sparc64/pv.c b/sys/sparc64/sparc64/pv.c deleted file mode 100644 index e38c5054d0b1..000000000000 --- a/sys/sparc64/sparc64/pv.c +++ /dev/null @@ -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); -} |
