Move TLB faults into the normal fault classes. Now they are executed when the fault is invoked.
--HG-- extra : convert_revision : b5f00fff277e863b3fe43422bc39d0487c482e60
This commit is contained in:
parent
6f590b4ddc
commit
bd38b56774
4 changed files with 167 additions and 86 deletions
|
@ -30,6 +30,9 @@
|
||||||
#include "cpu/exec_context.hh"
|
#include "cpu/exec_context.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
#include "arch/alpha/ev5.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace AlphaISA
|
namespace AlphaISA
|
||||||
{
|
{
|
||||||
|
@ -70,6 +73,10 @@ FaultName DtbAcvFault::_name = "dfault";
|
||||||
FaultVect DtbAcvFault::_vect = 0x0381;
|
FaultVect DtbAcvFault::_vect = 0x0381;
|
||||||
FaultStat DtbAcvFault::_count;
|
FaultStat DtbAcvFault::_count;
|
||||||
|
|
||||||
|
FaultName DtbAlignmentFault::_name = "unalign";
|
||||||
|
FaultVect DtbAlignmentFault::_vect = 0x0301;
|
||||||
|
FaultStat DtbAlignmentFault::_count;
|
||||||
|
|
||||||
FaultName ItbMissFault::_name = "itbmiss";
|
FaultName ItbMissFault::_name = "itbmiss";
|
||||||
FaultVect ItbMissFault::_vect = 0x0181;
|
FaultVect ItbMissFault::_vect = 0x0181;
|
||||||
FaultStat ItbMissFault::_count;
|
FaultStat ItbMissFault::_count;
|
||||||
|
@ -125,6 +132,44 @@ void ArithmeticFault::invoke(ExecContext * xc)
|
||||||
panic("Arithmetic traps are unimplemented!");
|
panic("Arithmetic traps are unimplemented!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DtbFault::invoke(ExecContext * xc)
|
||||||
|
{
|
||||||
|
// Set fault address and flags. Even though we're modeling an
|
||||||
|
// EV5, we use the EV6 technique of not latching fault registers
|
||||||
|
// on VPTE loads (instead of locking the registers until IPR_VA is
|
||||||
|
// read, like the EV5). The EV6 approach is cleaner and seems to
|
||||||
|
// work with EV5 PAL code, but not the other way around.
|
||||||
|
if (!xc->misspeculating()
|
||||||
|
&& !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
|
||||||
|
// set VA register with faulting address
|
||||||
|
xc->setMiscReg(AlphaISA::IPR_VA, vaddr);
|
||||||
|
|
||||||
|
// set MM_STAT register flags
|
||||||
|
xc->setMiscReg(AlphaISA::IPR_MM_STAT,
|
||||||
|
(((EV5::Opcode(xc->getInst()) & 0x3f) << 11)
|
||||||
|
| ((EV5::Ra(xc->getInst()) & 0x1f) << 6)
|
||||||
|
| (flags & 0x3f)));
|
||||||
|
|
||||||
|
// set VA_FORM register with faulting formatted address
|
||||||
|
xc->setMiscReg(AlphaISA::IPR_VA_FORM,
|
||||||
|
xc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
AlphaFault::invoke(xc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItbFault::invoke(ExecContext * xc)
|
||||||
|
{
|
||||||
|
if (!xc->misspeculating()) {
|
||||||
|
xc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc);
|
||||||
|
xc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM,
|
||||||
|
xc->readMiscReg(AlphaISA::IPR_IVPTBR) |
|
||||||
|
(AlphaISA::VAddr(pc).vpn() << 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
AlphaFault::invoke(xc);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace AlphaISA
|
} // namespace AlphaISA
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#ifndef __ALPHA_FAULTS_HH__
|
#ifndef __ALPHA_FAULTS_HH__
|
||||||
#define __ALPHA_FAULTS_HH__
|
#define __ALPHA_FAULTS_HH__
|
||||||
|
|
||||||
|
#include "arch/alpha/isa_traits.hh"
|
||||||
#include "sim/faults.hh"
|
#include "sim/faults.hh"
|
||||||
|
|
||||||
// The design of the "name" and "vect" functions is in sim/faults.hh
|
// The design of the "name" and "vect" functions is in sim/faults.hh
|
||||||
|
@ -130,85 +131,167 @@ class InterruptFault : public AlphaFault
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NDtbMissFault : public AlphaFault
|
class DtbFault : public AlphaFault
|
||||||
|
{
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
private:
|
||||||
|
AlphaISA::VAddr vaddr;
|
||||||
|
uint32_t reqFlags;
|
||||||
|
uint64_t flags;
|
||||||
|
public:
|
||||||
|
DtbFault(AlphaISA::VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags)
|
||||||
|
: vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags)
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
FaultName name() = 0;
|
||||||
|
FaultVect vect() = 0;
|
||||||
|
FaultStat & countStat() = 0;
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
void invoke(ExecContext * xc);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class NDtbMissFault : public DtbFault
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
public:
|
public:
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
NDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||||
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
FaultName name() {return _name;}
|
FaultName name() {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PDtbMissFault : public AlphaFault
|
class PDtbMissFault : public DtbFault
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
public:
|
public:
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
PDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||||
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
FaultName name() {return _name;}
|
FaultName name() {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DtbPageFault : public AlphaFault
|
class DtbPageFault : public DtbFault
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
public:
|
public:
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
DtbPageFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||||
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
FaultName name() {return _name;}
|
FaultName name() {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DtbAcvFault : public AlphaFault
|
class DtbAcvFault : public DtbFault
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
public:
|
public:
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
DtbAcvFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||||
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
FaultName name() {return _name;}
|
FaultName name() {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ItbMissFault : public AlphaFault
|
class DtbAlignmentFault : public DtbFault
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
public:
|
public:
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
DtbAlignmentFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||||
|
: DtbFault(vaddr, reqFlags, flags)
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
FaultName name() {return _name;}
|
FaultName name() {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ItbPageFault : public AlphaFault
|
class ItbFault : public AlphaFault
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Addr pc;
|
||||||
|
public:
|
||||||
|
ItbFault(Addr _pc)
|
||||||
|
: pc(_pc)
|
||||||
|
{ }
|
||||||
|
FaultName name() = 0;
|
||||||
|
FaultVect vect() = 0;
|
||||||
|
FaultStat & countStat() = 0;
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
void invoke(ExecContext * xc);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class ItbMissFault : public ItbFault
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
public:
|
public:
|
||||||
|
ItbMissFault(Addr pc)
|
||||||
|
: ItbFault(pc)
|
||||||
|
{ }
|
||||||
FaultName name() {return _name;}
|
FaultName name() {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ItbAcvFault : public AlphaFault
|
class ItbPageFault : public ItbFault
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static FaultName _name;
|
static FaultName _name;
|
||||||
static FaultVect _vect;
|
static FaultVect _vect;
|
||||||
static FaultStat _count;
|
static FaultStat _count;
|
||||||
public:
|
public:
|
||||||
|
ItbPageFault(Addr pc)
|
||||||
|
: ItbFault(pc)
|
||||||
|
{ }
|
||||||
|
FaultName name() {return _name;}
|
||||||
|
FaultVect vect() {return _vect;}
|
||||||
|
FaultStat & countStat() {return _count;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ItbAcvFault : public ItbFault
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static FaultName _name;
|
||||||
|
static FaultVect _vect;
|
||||||
|
static FaultStat _count;
|
||||||
|
public:
|
||||||
|
ItbAcvFault(Addr pc)
|
||||||
|
: ItbFault(pc)
|
||||||
|
{ }
|
||||||
FaultName name() {return _name;}
|
FaultName name() {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
FaultStat & countStat() {return _count;}
|
||||||
|
|
|
@ -290,17 +290,6 @@ AlphaITB::regStats()
|
||||||
accesses = hits + misses;
|
accesses = hits + misses;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
AlphaITB::fault(Addr pc, ExecContext *xc) const
|
|
||||||
{
|
|
||||||
if (!xc->misspeculating()) {
|
|
||||||
xc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc);
|
|
||||||
xc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM,
|
|
||||||
xc->readMiscReg(AlphaISA::IPR_IVPTBR) |
|
|
||||||
(AlphaISA::VAddr(pc).vpn() << 3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
AlphaITB::translate(MemReqPtr &req) const
|
AlphaITB::translate(MemReqPtr &req) const
|
||||||
|
@ -319,9 +308,8 @@ AlphaITB::translate(MemReqPtr &req) const
|
||||||
} else {
|
} else {
|
||||||
// verify that this is a good virtual address
|
// verify that this is a good virtual address
|
||||||
if (!validVirtualAddress(req->vaddr)) {
|
if (!validVirtualAddress(req->vaddr)) {
|
||||||
fault(req->vaddr, req->xc);
|
|
||||||
acv++;
|
acv++;
|
||||||
return new ItbAcvFault;
|
return new ItbAcvFault(req->vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -336,9 +324,8 @@ AlphaITB::translate(MemReqPtr &req) const
|
||||||
// only valid in kernel mode
|
// only valid in kernel mode
|
||||||
if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) !=
|
if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) !=
|
||||||
AlphaISA::mode_kernel) {
|
AlphaISA::mode_kernel) {
|
||||||
fault(req->vaddr, req->xc);
|
|
||||||
acv++;
|
acv++;
|
||||||
return new ItbAcvFault;
|
return new ItbAcvFault(req->vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
req->paddr = req->vaddr & PAddrImplMask;
|
req->paddr = req->vaddr & PAddrImplMask;
|
||||||
|
@ -358,9 +345,8 @@ AlphaITB::translate(MemReqPtr &req) const
|
||||||
asn);
|
asn);
|
||||||
|
|
||||||
if (!pte) {
|
if (!pte) {
|
||||||
fault(req->vaddr, req->xc);
|
|
||||||
misses++;
|
misses++;
|
||||||
return new ItbPageFault;
|
return new ItbPageFault(req->vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
req->paddr = (pte->ppn << AlphaISA::PageShift) +
|
req->paddr = (pte->ppn << AlphaISA::PageShift) +
|
||||||
|
@ -370,9 +356,8 @@ AlphaITB::translate(MemReqPtr &req) const
|
||||||
if (!(pte->xre &
|
if (!(pte->xre &
|
||||||
(1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) {
|
(1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) {
|
||||||
// instruction access fault
|
// instruction access fault
|
||||||
fault(req->vaddr, req->xc);
|
|
||||||
acv++;
|
acv++;
|
||||||
return new ItbAcvFault;
|
return new ItbAcvFault(req->vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
hits++;
|
hits++;
|
||||||
|
@ -465,34 +450,6 @@ AlphaDTB::regStats()
|
||||||
accesses = read_accesses + write_accesses;
|
accesses = read_accesses + write_accesses;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const
|
|
||||||
{
|
|
||||||
ExecContext *xc = req->xc;
|
|
||||||
AlphaISA::VAddr vaddr = req->vaddr;
|
|
||||||
|
|
||||||
// Set fault address and flags. Even though we're modeling an
|
|
||||||
// EV5, we use the EV6 technique of not latching fault registers
|
|
||||||
// on VPTE loads (instead of locking the registers until IPR_VA is
|
|
||||||
// read, like the EV5). The EV6 approach is cleaner and seems to
|
|
||||||
// work with EV5 PAL code, but not the other way around.
|
|
||||||
if (!xc->misspeculating()
|
|
||||||
&& !(req->flags & VPTE) && !(req->flags & NO_FAULT)) {
|
|
||||||
// set VA register with faulting address
|
|
||||||
xc->setMiscReg(AlphaISA::IPR_VA, req->vaddr);
|
|
||||||
|
|
||||||
// set MM_STAT register flags
|
|
||||||
xc->setMiscReg(AlphaISA::IPR_MM_STAT,
|
|
||||||
(((Opcode(xc->getInst()) & 0x3f) << 11)
|
|
||||||
| ((Ra(xc->getInst()) & 0x1f) << 6)
|
|
||||||
| (flags & 0x3f)));
|
|
||||||
|
|
||||||
// set VA_FORM register with faulting formatted address
|
|
||||||
xc->setMiscReg(AlphaISA::IPR_VA_FORM,
|
|
||||||
xc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
AlphaDTB::translate(MemReqPtr &req, bool write) const
|
AlphaDTB::translate(MemReqPtr &req, bool write) const
|
||||||
{
|
{
|
||||||
|
@ -507,10 +464,10 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
|
||||||
* Check for alignment faults
|
* Check for alignment faults
|
||||||
*/
|
*/
|
||||||
if (req->vaddr & (req->size - 1)) {
|
if (req->vaddr & (req->size - 1)) {
|
||||||
fault(req, write ? MM_STAT_WR_MASK : 0);
|
|
||||||
DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr,
|
DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr,
|
||||||
req->size);
|
req->size);
|
||||||
return genAlignmentFault();
|
uint64_t flags = write ? MM_STAT_WR_MASK : 0;
|
||||||
|
return new DtbAlignmentFault(req->vaddr, req->flags, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pc & 0x1) {
|
if (pc & 0x1) {
|
||||||
|
@ -525,12 +482,11 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
|
||||||
} else {
|
} else {
|
||||||
// verify that this is a good virtual address
|
// verify that this is a good virtual address
|
||||||
if (!validVirtualAddress(req->vaddr)) {
|
if (!validVirtualAddress(req->vaddr)) {
|
||||||
fault(req, (write ? MM_STAT_WR_MASK : 0) |
|
|
||||||
MM_STAT_BAD_VA_MASK |
|
|
||||||
MM_STAT_ACV_MASK);
|
|
||||||
|
|
||||||
if (write) { write_acv++; } else { read_acv++; }
|
if (write) { write_acv++; } else { read_acv++; }
|
||||||
return new DtbPageFault;
|
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
|
||||||
|
MM_STAT_BAD_VA_MASK |
|
||||||
|
MM_STAT_ACV_MASK;
|
||||||
|
return new DtbPageFault(req->vaddr, req->flags, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for "superpage" mapping
|
// Check for "superpage" mapping
|
||||||
|
@ -544,10 +500,10 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
|
||||||
// only valid in kernel mode
|
// only valid in kernel mode
|
||||||
if (DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)) !=
|
if (DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)) !=
|
||||||
AlphaISA::mode_kernel) {
|
AlphaISA::mode_kernel) {
|
||||||
fault(req, ((write ? MM_STAT_WR_MASK : 0) |
|
|
||||||
MM_STAT_ACV_MASK));
|
|
||||||
if (write) { write_acv++; } else { read_acv++; }
|
if (write) { write_acv++; } else { read_acv++; }
|
||||||
return new DtbAcvFault;
|
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
|
||||||
|
MM_STAT_ACV_MASK);
|
||||||
|
return new DtbAcvFault(req->vaddr, req->flags, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
req->paddr = req->vaddr & PAddrImplMask;
|
req->paddr = req->vaddr & PAddrImplMask;
|
||||||
|
@ -574,12 +530,14 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
|
||||||
|
|
||||||
if (!pte) {
|
if (!pte) {
|
||||||
// page fault
|
// page fault
|
||||||
fault(req, (write ? MM_STAT_WR_MASK : 0) |
|
|
||||||
MM_STAT_DTB_MISS_MASK);
|
|
||||||
if (write) { write_misses++; } else { read_misses++; }
|
if (write) { write_misses++; } else { read_misses++; }
|
||||||
|
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
|
||||||
|
MM_STAT_DTB_MISS_MASK;
|
||||||
return (req->flags & VPTE) ?
|
return (req->flags & VPTE) ?
|
||||||
(Fault)(new PDtbMissFault) :
|
(Fault)(new PDtbMissFault(req->vaddr, req->flags,
|
||||||
(Fault)(new NDtbMissFault);
|
flags)) :
|
||||||
|
(Fault)(new NDtbMissFault(req->vaddr, req->flags,
|
||||||
|
flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
req->paddr = (pte->ppn << AlphaISA::PageShift) +
|
req->paddr = (pte->ppn << AlphaISA::PageShift) +
|
||||||
|
@ -588,29 +546,29 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
|
||||||
if (write) {
|
if (write) {
|
||||||
if (!(pte->xwe & MODE2MASK(mode))) {
|
if (!(pte->xwe & MODE2MASK(mode))) {
|
||||||
// declare the instruction access fault
|
// declare the instruction access fault
|
||||||
fault(req, MM_STAT_WR_MASK |
|
|
||||||
MM_STAT_ACV_MASK |
|
|
||||||
(pte->fonw ? MM_STAT_FONW_MASK : 0));
|
|
||||||
write_acv++;
|
write_acv++;
|
||||||
return new DtbPageFault;
|
uint64_t flags = MM_STAT_WR_MASK |
|
||||||
|
MM_STAT_ACV_MASK |
|
||||||
|
(pte->fonw ? MM_STAT_FONW_MASK : 0);
|
||||||
|
return new DtbPageFault(req->vaddr, req->flags, flags);
|
||||||
}
|
}
|
||||||
if (pte->fonw) {
|
if (pte->fonw) {
|
||||||
fault(req, MM_STAT_WR_MASK |
|
|
||||||
MM_STAT_FONW_MASK);
|
|
||||||
write_acv++;
|
write_acv++;
|
||||||
return new DtbPageFault;
|
uint64_t flags = MM_STAT_WR_MASK |
|
||||||
|
MM_STAT_FONW_MASK;
|
||||||
|
return new DtbPageFault(req->vaddr, req->flags, flags);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(pte->xre & MODE2MASK(mode))) {
|
if (!(pte->xre & MODE2MASK(mode))) {
|
||||||
fault(req, MM_STAT_ACV_MASK |
|
|
||||||
(pte->fonr ? MM_STAT_FONR_MASK : 0));
|
|
||||||
read_acv++;
|
read_acv++;
|
||||||
return new DtbAcvFault;
|
uint64_t flags = MM_STAT_ACV_MASK |
|
||||||
|
(pte->fonr ? MM_STAT_FONR_MASK : 0);
|
||||||
|
return new DtbAcvFault(req->vaddr, req->flags, flags);
|
||||||
}
|
}
|
||||||
if (pte->fonr) {
|
if (pte->fonr) {
|
||||||
fault(req, MM_STAT_FONR_MASK);
|
|
||||||
read_acv++;
|
read_acv++;
|
||||||
return new DtbPageFault;
|
uint64_t flags = MM_STAT_FONR_MASK;
|
||||||
|
return new DtbPageFault(req->vaddr, req->flags, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "arch/alpha/ev5.hh"
|
||||||
#include "arch/alpha/isa_traits.hh"
|
#include "arch/alpha/isa_traits.hh"
|
||||||
#include "arch/alpha/faults.hh"
|
#include "arch/alpha/faults.hh"
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
|
@ -87,9 +88,6 @@ class AlphaITB : public AlphaTLB
|
||||||
mutable Stats::Scalar<> acv;
|
mutable Stats::Scalar<> acv;
|
||||||
mutable Stats::Formula accesses;
|
mutable Stats::Formula accesses;
|
||||||
|
|
||||||
protected:
|
|
||||||
void fault(Addr pc, ExecContext *xc) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AlphaITB(const std::string &name, int size);
|
AlphaITB(const std::string &name, int size);
|
||||||
virtual void regStats();
|
virtual void regStats();
|
||||||
|
@ -113,9 +111,6 @@ class AlphaDTB : public AlphaTLB
|
||||||
Stats::Formula acv;
|
Stats::Formula acv;
|
||||||
Stats::Formula accesses;
|
Stats::Formula accesses;
|
||||||
|
|
||||||
protected:
|
|
||||||
void fault(MemReqPtr &req, uint64_t flags) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AlphaDTB(const std::string &name, int size);
|
AlphaDTB(const std::string &name, int size);
|
||||||
virtual void regStats();
|
virtual void regStats();
|
||||||
|
|
Loading…
Reference in a new issue