X86: Split out the internal memory space from the regular translate() and precompute mode.
This commit is contained in:
parent
4ee34dfb4e
commit
b6bfe8af26
4 changed files with 382 additions and 373 deletions
|
@ -118,6 +118,8 @@ void MiscRegFile::updateHandyM5Reg(Efer efer, CR0 cr0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m5reg.cpl = csAttr.dpl;
|
m5reg.cpl = csAttr.dpl;
|
||||||
|
m5reg.paging = cr0.pg;
|
||||||
|
m5reg.prot = cr0.pe;
|
||||||
regVal[MISCREG_M5_REG] = m5reg;
|
regVal[MISCREG_M5_REG] = m5reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -518,6 +518,8 @@ namespace X86ISA
|
||||||
Bitfield<0> mode;
|
Bitfield<0> mode;
|
||||||
Bitfield<3, 1> submode;
|
Bitfield<3, 1> submode;
|
||||||
Bitfield<5, 4> cpl;
|
Bitfield<5, 4> cpl;
|
||||||
|
Bitfield<6> paging;
|
||||||
|
Bitfield<7> prot;
|
||||||
EndBitUnion(HandyM5Reg)
|
EndBitUnion(HandyM5Reg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -186,21 +186,10 @@ TLB::demapPage(Addr va, uint64_t asn)
|
||||||
}
|
}
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
|
TLB::translateInt(RequestPtr req, ThreadContext *tc)
|
||||||
Mode mode, bool &delayedResponse, bool timing)
|
|
||||||
{
|
{
|
||||||
delayedResponse = false;
|
|
||||||
Addr vaddr = req->getVaddr();
|
|
||||||
DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr);
|
|
||||||
uint32_t flags = req->getFlags();
|
|
||||||
bool storeCheck = flags & (StoreCheck << FlagShift);
|
|
||||||
|
|
||||||
int seg = flags & SegmentFlagMask;
|
|
||||||
|
|
||||||
// If this is true, we're dealing with a request to read an internal
|
|
||||||
// value.
|
|
||||||
if (seg == SEGMENT_REG_MS) {
|
|
||||||
DPRINTF(TLB, "Addresses references internal memory.\n");
|
DPRINTF(TLB, "Addresses references internal memory.\n");
|
||||||
|
Addr vaddr = req->getVaddr();
|
||||||
Addr prefix = (vaddr >> 3) & IntAddrPrefixMask;
|
Addr prefix = (vaddr >> 3) & IntAddrPrefixMask;
|
||||||
if (prefix == IntAddrPrefixCPUID) {
|
if (prefix == IntAddrPrefixCPUID) {
|
||||||
panic("CPUID memory space not yet implemented!\n");
|
panic("CPUID memory space not yet implemented!\n");
|
||||||
|
@ -555,22 +544,35 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get cr0. This will tell us how to do translation. We'll assume it was
|
Fault
|
||||||
// verified to be correct and consistent when set.
|
TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
|
||||||
CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0);
|
Mode mode, bool &delayedResponse, bool timing)
|
||||||
|
{
|
||||||
|
uint32_t flags = req->getFlags();
|
||||||
|
int seg = flags & SegmentFlagMask;
|
||||||
|
bool storeCheck = flags & (StoreCheck << FlagShift);
|
||||||
|
|
||||||
|
// If this is true, we're dealing with a request to a non-memory address
|
||||||
|
// space.
|
||||||
|
if (seg == SEGMENT_REG_MS) {
|
||||||
|
return translateInt(req, tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
delayedResponse = false;
|
||||||
|
Addr vaddr = req->getVaddr();
|
||||||
|
DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr);
|
||||||
|
|
||||||
|
HandyM5Reg m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||||
|
|
||||||
// If protected mode has been enabled...
|
// If protected mode has been enabled...
|
||||||
if (cr0.pe) {
|
if (m5Reg.prot) {
|
||||||
DPRINTF(TLB, "In protected mode.\n");
|
DPRINTF(TLB, "In protected mode.\n");
|
||||||
Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER);
|
|
||||||
SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
|
|
||||||
// If we're not in 64-bit mode, do protection/limit checks
|
// If we're not in 64-bit mode, do protection/limit checks
|
||||||
if (!efer.lma || !csAttr.longMode) {
|
if (m5Reg.mode != LongMode) {
|
||||||
DPRINTF(TLB, "Not in long mode. Checking segment protection.\n");
|
DPRINTF(TLB, "Not in long mode. Checking segment protection.\n");
|
||||||
// Check for a NULL segment selector.
|
// Check for a NULL segment selector.
|
||||||
if (!(seg == SEGMENT_REG_TSG || seg == SYS_SEGMENT_REG_IDTR ||
|
if (!(seg == SEGMENT_REG_TSG || seg == SYS_SEGMENT_REG_IDTR ||
|
||||||
seg == SEGMENT_REG_HS || seg == SEGMENT_REG_LS ||
|
seg == SEGMENT_REG_HS || seg == SEGMENT_REG_LS)
|
||||||
seg == SEGMENT_REG_MS)
|
|
||||||
&& !tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg)))
|
&& !tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg)))
|
||||||
return new GeneralProtection(0);
|
return new GeneralProtection(0);
|
||||||
bool expandDown = false;
|
bool expandDown = false;
|
||||||
|
@ -589,6 +591,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
|
||||||
// address size is 64 bits, overridable to 32.
|
// address size is 64 bits, overridable to 32.
|
||||||
int size = 32;
|
int size = 32;
|
||||||
bool sizeOverride = (flags & (AddrSizeFlagBit << FlagShift));
|
bool sizeOverride = (flags & (AddrSizeFlagBit << FlagShift));
|
||||||
|
SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
|
||||||
if ((csAttr.defaultSize && sizeOverride) ||
|
if ((csAttr.defaultSize && sizeOverride) ||
|
||||||
(!csAttr.defaultSize && !sizeOverride))
|
(!csAttr.defaultSize && !sizeOverride))
|
||||||
size = 16;
|
size = 16;
|
||||||
|
@ -605,7 +608,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If paging is enabled, do the translation.
|
// If paging is enabled, do the translation.
|
||||||
if (cr0.pg) {
|
if (m5Reg.paging) {
|
||||||
DPRINTF(TLB, "Paging enabled.\n");
|
DPRINTF(TLB, "Paging enabled.\n");
|
||||||
// The vaddr already has the segment base applied.
|
// The vaddr already has the segment base applied.
|
||||||
TlbEntry *entry = lookup(vaddr);
|
TlbEntry *entry = lookup(vaddr);
|
||||||
|
@ -643,7 +646,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// Do paging protection checks.
|
// Do paging protection checks.
|
||||||
bool inUser = (csAttr.dpl == 3 &&
|
bool inUser = (m5Reg.cpl == 3 &&
|
||||||
!(flags & (CPL0FlagBit << FlagShift)));
|
!(flags & (CPL0FlagBit << FlagShift)));
|
||||||
if ((inUser && !entry->user) ||
|
if ((inUser && !entry->user) ||
|
||||||
(mode == Write && !entry->writable)) {
|
(mode == Write && !entry->writable)) {
|
||||||
|
|
|
@ -124,6 +124,8 @@ namespace X86ISA
|
||||||
EntryList freeList;
|
EntryList freeList;
|
||||||
EntryList entryList;
|
EntryList entryList;
|
||||||
|
|
||||||
|
Fault translateInt(RequestPtr req, ThreadContext *tc);
|
||||||
|
|
||||||
Fault translate(RequestPtr req, ThreadContext *tc,
|
Fault translate(RequestPtr req, ThreadContext *tc,
|
||||||
Translation *translation, Mode mode,
|
Translation *translation, Mode mode,
|
||||||
bool &delayedResponse, bool timing);
|
bool &delayedResponse, bool timing);
|
||||||
|
|
Loading…
Reference in a new issue