These file are no longer used (moved to userland and/or merged into
pmap.c).
This commit is contained in:
parent
43b2936963
commit
055ca86c52
@ -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_ */
|
@ -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_ */
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user