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)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -185,392 +185,394 @@ TLB::demapPage(Addr va, uint64_t asn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fault
|
||||||
|
TLB::translateInt(RequestPtr req, ThreadContext *tc)
|
||||||
|
{
|
||||||
|
DPRINTF(TLB, "Addresses references internal memory.\n");
|
||||||
|
Addr vaddr = req->getVaddr();
|
||||||
|
Addr prefix = (vaddr >> 3) & IntAddrPrefixMask;
|
||||||
|
if (prefix == IntAddrPrefixCPUID) {
|
||||||
|
panic("CPUID memory space not yet implemented!\n");
|
||||||
|
} else if (prefix == IntAddrPrefixMSR) {
|
||||||
|
vaddr = vaddr >> 3;
|
||||||
|
req->setMmapedIpr(true);
|
||||||
|
Addr regNum = 0;
|
||||||
|
switch (vaddr & ~IntAddrPrefixMask) {
|
||||||
|
case 0x10:
|
||||||
|
regNum = MISCREG_TSC;
|
||||||
|
break;
|
||||||
|
case 0x1B:
|
||||||
|
regNum = MISCREG_APIC_BASE;
|
||||||
|
break;
|
||||||
|
case 0xFE:
|
||||||
|
regNum = MISCREG_MTRRCAP;
|
||||||
|
break;
|
||||||
|
case 0x174:
|
||||||
|
regNum = MISCREG_SYSENTER_CS;
|
||||||
|
break;
|
||||||
|
case 0x175:
|
||||||
|
regNum = MISCREG_SYSENTER_ESP;
|
||||||
|
break;
|
||||||
|
case 0x176:
|
||||||
|
regNum = MISCREG_SYSENTER_EIP;
|
||||||
|
break;
|
||||||
|
case 0x179:
|
||||||
|
regNum = MISCREG_MCG_CAP;
|
||||||
|
break;
|
||||||
|
case 0x17A:
|
||||||
|
regNum = MISCREG_MCG_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x17B:
|
||||||
|
regNum = MISCREG_MCG_CTL;
|
||||||
|
break;
|
||||||
|
case 0x1D9:
|
||||||
|
regNum = MISCREG_DEBUG_CTL_MSR;
|
||||||
|
break;
|
||||||
|
case 0x1DB:
|
||||||
|
regNum = MISCREG_LAST_BRANCH_FROM_IP;
|
||||||
|
break;
|
||||||
|
case 0x1DC:
|
||||||
|
regNum = MISCREG_LAST_BRANCH_TO_IP;
|
||||||
|
break;
|
||||||
|
case 0x1DD:
|
||||||
|
regNum = MISCREG_LAST_EXCEPTION_FROM_IP;
|
||||||
|
break;
|
||||||
|
case 0x1DE:
|
||||||
|
regNum = MISCREG_LAST_EXCEPTION_TO_IP;
|
||||||
|
break;
|
||||||
|
case 0x200:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_BASE_0;
|
||||||
|
break;
|
||||||
|
case 0x201:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_MASK_0;
|
||||||
|
break;
|
||||||
|
case 0x202:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_BASE_1;
|
||||||
|
break;
|
||||||
|
case 0x203:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_MASK_1;
|
||||||
|
break;
|
||||||
|
case 0x204:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_BASE_2;
|
||||||
|
break;
|
||||||
|
case 0x205:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_MASK_2;
|
||||||
|
break;
|
||||||
|
case 0x206:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_BASE_3;
|
||||||
|
break;
|
||||||
|
case 0x207:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_MASK_3;
|
||||||
|
break;
|
||||||
|
case 0x208:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_BASE_4;
|
||||||
|
break;
|
||||||
|
case 0x209:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_MASK_4;
|
||||||
|
break;
|
||||||
|
case 0x20A:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_BASE_5;
|
||||||
|
break;
|
||||||
|
case 0x20B:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_MASK_5;
|
||||||
|
break;
|
||||||
|
case 0x20C:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_BASE_6;
|
||||||
|
break;
|
||||||
|
case 0x20D:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_MASK_6;
|
||||||
|
break;
|
||||||
|
case 0x20E:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_BASE_7;
|
||||||
|
break;
|
||||||
|
case 0x20F:
|
||||||
|
regNum = MISCREG_MTRR_PHYS_MASK_7;
|
||||||
|
break;
|
||||||
|
case 0x250:
|
||||||
|
regNum = MISCREG_MTRR_FIX_64K_00000;
|
||||||
|
break;
|
||||||
|
case 0x258:
|
||||||
|
regNum = MISCREG_MTRR_FIX_16K_80000;
|
||||||
|
break;
|
||||||
|
case 0x259:
|
||||||
|
regNum = MISCREG_MTRR_FIX_16K_A0000;
|
||||||
|
break;
|
||||||
|
case 0x268:
|
||||||
|
regNum = MISCREG_MTRR_FIX_4K_C0000;
|
||||||
|
break;
|
||||||
|
case 0x269:
|
||||||
|
regNum = MISCREG_MTRR_FIX_4K_C8000;
|
||||||
|
break;
|
||||||
|
case 0x26A:
|
||||||
|
regNum = MISCREG_MTRR_FIX_4K_D0000;
|
||||||
|
break;
|
||||||
|
case 0x26B:
|
||||||
|
regNum = MISCREG_MTRR_FIX_4K_D8000;
|
||||||
|
break;
|
||||||
|
case 0x26C:
|
||||||
|
regNum = MISCREG_MTRR_FIX_4K_E0000;
|
||||||
|
break;
|
||||||
|
case 0x26D:
|
||||||
|
regNum = MISCREG_MTRR_FIX_4K_E8000;
|
||||||
|
break;
|
||||||
|
case 0x26E:
|
||||||
|
regNum = MISCREG_MTRR_FIX_4K_F0000;
|
||||||
|
break;
|
||||||
|
case 0x26F:
|
||||||
|
regNum = MISCREG_MTRR_FIX_4K_F8000;
|
||||||
|
break;
|
||||||
|
case 0x277:
|
||||||
|
regNum = MISCREG_PAT;
|
||||||
|
break;
|
||||||
|
case 0x2FF:
|
||||||
|
regNum = MISCREG_DEF_TYPE;
|
||||||
|
break;
|
||||||
|
case 0x400:
|
||||||
|
regNum = MISCREG_MC0_CTL;
|
||||||
|
break;
|
||||||
|
case 0x404:
|
||||||
|
regNum = MISCREG_MC1_CTL;
|
||||||
|
break;
|
||||||
|
case 0x408:
|
||||||
|
regNum = MISCREG_MC2_CTL;
|
||||||
|
break;
|
||||||
|
case 0x40C:
|
||||||
|
regNum = MISCREG_MC3_CTL;
|
||||||
|
break;
|
||||||
|
case 0x410:
|
||||||
|
regNum = MISCREG_MC4_CTL;
|
||||||
|
break;
|
||||||
|
case 0x414:
|
||||||
|
regNum = MISCREG_MC5_CTL;
|
||||||
|
break;
|
||||||
|
case 0x418:
|
||||||
|
regNum = MISCREG_MC6_CTL;
|
||||||
|
break;
|
||||||
|
case 0x41C:
|
||||||
|
regNum = MISCREG_MC7_CTL;
|
||||||
|
break;
|
||||||
|
case 0x401:
|
||||||
|
regNum = MISCREG_MC0_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x405:
|
||||||
|
regNum = MISCREG_MC1_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x409:
|
||||||
|
regNum = MISCREG_MC2_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x40D:
|
||||||
|
regNum = MISCREG_MC3_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x411:
|
||||||
|
regNum = MISCREG_MC4_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x415:
|
||||||
|
regNum = MISCREG_MC5_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x419:
|
||||||
|
regNum = MISCREG_MC6_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x41D:
|
||||||
|
regNum = MISCREG_MC7_STATUS;
|
||||||
|
break;
|
||||||
|
case 0x402:
|
||||||
|
regNum = MISCREG_MC0_ADDR;
|
||||||
|
break;
|
||||||
|
case 0x406:
|
||||||
|
regNum = MISCREG_MC1_ADDR;
|
||||||
|
break;
|
||||||
|
case 0x40A:
|
||||||
|
regNum = MISCREG_MC2_ADDR;
|
||||||
|
break;
|
||||||
|
case 0x40E:
|
||||||
|
regNum = MISCREG_MC3_ADDR;
|
||||||
|
break;
|
||||||
|
case 0x412:
|
||||||
|
regNum = MISCREG_MC4_ADDR;
|
||||||
|
break;
|
||||||
|
case 0x416:
|
||||||
|
regNum = MISCREG_MC5_ADDR;
|
||||||
|
break;
|
||||||
|
case 0x41A:
|
||||||
|
regNum = MISCREG_MC6_ADDR;
|
||||||
|
break;
|
||||||
|
case 0x41E:
|
||||||
|
regNum = MISCREG_MC7_ADDR;
|
||||||
|
break;
|
||||||
|
case 0x403:
|
||||||
|
regNum = MISCREG_MC0_MISC;
|
||||||
|
break;
|
||||||
|
case 0x407:
|
||||||
|
regNum = MISCREG_MC1_MISC;
|
||||||
|
break;
|
||||||
|
case 0x40B:
|
||||||
|
regNum = MISCREG_MC2_MISC;
|
||||||
|
break;
|
||||||
|
case 0x40F:
|
||||||
|
regNum = MISCREG_MC3_MISC;
|
||||||
|
break;
|
||||||
|
case 0x413:
|
||||||
|
regNum = MISCREG_MC4_MISC;
|
||||||
|
break;
|
||||||
|
case 0x417:
|
||||||
|
regNum = MISCREG_MC5_MISC;
|
||||||
|
break;
|
||||||
|
case 0x41B:
|
||||||
|
regNum = MISCREG_MC6_MISC;
|
||||||
|
break;
|
||||||
|
case 0x41F:
|
||||||
|
regNum = MISCREG_MC7_MISC;
|
||||||
|
break;
|
||||||
|
case 0xC0000080:
|
||||||
|
regNum = MISCREG_EFER;
|
||||||
|
break;
|
||||||
|
case 0xC0000081:
|
||||||
|
regNum = MISCREG_STAR;
|
||||||
|
break;
|
||||||
|
case 0xC0000082:
|
||||||
|
regNum = MISCREG_LSTAR;
|
||||||
|
break;
|
||||||
|
case 0xC0000083:
|
||||||
|
regNum = MISCREG_CSTAR;
|
||||||
|
break;
|
||||||
|
case 0xC0000084:
|
||||||
|
regNum = MISCREG_SF_MASK;
|
||||||
|
break;
|
||||||
|
case 0xC0000100:
|
||||||
|
regNum = MISCREG_FS_BASE;
|
||||||
|
break;
|
||||||
|
case 0xC0000101:
|
||||||
|
regNum = MISCREG_GS_BASE;
|
||||||
|
break;
|
||||||
|
case 0xC0000102:
|
||||||
|
regNum = MISCREG_KERNEL_GS_BASE;
|
||||||
|
break;
|
||||||
|
case 0xC0000103:
|
||||||
|
regNum = MISCREG_TSC_AUX;
|
||||||
|
break;
|
||||||
|
case 0xC0010000:
|
||||||
|
regNum = MISCREG_PERF_EVT_SEL0;
|
||||||
|
break;
|
||||||
|
case 0xC0010001:
|
||||||
|
regNum = MISCREG_PERF_EVT_SEL1;
|
||||||
|
break;
|
||||||
|
case 0xC0010002:
|
||||||
|
regNum = MISCREG_PERF_EVT_SEL2;
|
||||||
|
break;
|
||||||
|
case 0xC0010003:
|
||||||
|
regNum = MISCREG_PERF_EVT_SEL3;
|
||||||
|
break;
|
||||||
|
case 0xC0010004:
|
||||||
|
regNum = MISCREG_PERF_EVT_CTR0;
|
||||||
|
break;
|
||||||
|
case 0xC0010005:
|
||||||
|
regNum = MISCREG_PERF_EVT_CTR1;
|
||||||
|
break;
|
||||||
|
case 0xC0010006:
|
||||||
|
regNum = MISCREG_PERF_EVT_CTR2;
|
||||||
|
break;
|
||||||
|
case 0xC0010007:
|
||||||
|
regNum = MISCREG_PERF_EVT_CTR3;
|
||||||
|
break;
|
||||||
|
case 0xC0010010:
|
||||||
|
regNum = MISCREG_SYSCFG;
|
||||||
|
break;
|
||||||
|
case 0xC0010016:
|
||||||
|
regNum = MISCREG_IORR_BASE0;
|
||||||
|
break;
|
||||||
|
case 0xC0010017:
|
||||||
|
regNum = MISCREG_IORR_BASE1;
|
||||||
|
break;
|
||||||
|
case 0xC0010018:
|
||||||
|
regNum = MISCREG_IORR_MASK0;
|
||||||
|
break;
|
||||||
|
case 0xC0010019:
|
||||||
|
regNum = MISCREG_IORR_MASK1;
|
||||||
|
break;
|
||||||
|
case 0xC001001A:
|
||||||
|
regNum = MISCREG_TOP_MEM;
|
||||||
|
break;
|
||||||
|
case 0xC001001D:
|
||||||
|
regNum = MISCREG_TOP_MEM2;
|
||||||
|
break;
|
||||||
|
case 0xC0010114:
|
||||||
|
regNum = MISCREG_VM_CR;
|
||||||
|
break;
|
||||||
|
case 0xC0010115:
|
||||||
|
regNum = MISCREG_IGNNE;
|
||||||
|
break;
|
||||||
|
case 0xC0010116:
|
||||||
|
regNum = MISCREG_SMM_CTL;
|
||||||
|
break;
|
||||||
|
case 0xC0010117:
|
||||||
|
regNum = MISCREG_VM_HSAVE_PA;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return new GeneralProtection(0);
|
||||||
|
}
|
||||||
|
//The index is multiplied by the size of a MiscReg so that
|
||||||
|
//any memory dependence calculations will not see these as
|
||||||
|
//overlapping.
|
||||||
|
req->setPaddr(regNum * sizeof(MiscReg));
|
||||||
|
return NoFault;
|
||||||
|
} else if (prefix == IntAddrPrefixIO) {
|
||||||
|
// TODO If CPL > IOPL or in virtual mode, check the I/O permission
|
||||||
|
// bitmap in the TSS.
|
||||||
|
|
||||||
|
Addr IOPort = vaddr & ~IntAddrPrefixMask;
|
||||||
|
// Make sure the address fits in the expected 16 bit IO address
|
||||||
|
// space.
|
||||||
|
assert(!(IOPort & ~0xFFFF));
|
||||||
|
if (IOPort == 0xCF8 && req->getSize() == 4) {
|
||||||
|
req->setMmapedIpr(true);
|
||||||
|
req->setPaddr(MISCREG_PCI_CONFIG_ADDRESS * sizeof(MiscReg));
|
||||||
|
} else if ((IOPort & ~mask(2)) == 0xCFC) {
|
||||||
|
Addr configAddress =
|
||||||
|
tc->readMiscRegNoEffect(MISCREG_PCI_CONFIG_ADDRESS);
|
||||||
|
if (bits(configAddress, 31, 31)) {
|
||||||
|
req->setPaddr(PhysAddrPrefixPciConfig |
|
||||||
|
mbits(configAddress, 30, 2) |
|
||||||
|
(IOPort & mask(2)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
req->setPaddr(PhysAddrPrefixIO | IOPort);
|
||||||
|
}
|
||||||
|
return NoFault;
|
||||||
|
} else {
|
||||||
|
panic("Access to unrecognized internal address space %#x.\n",
|
||||||
|
prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Fault
|
Fault
|
||||||
TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
|
TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
|
||||||
Mode mode, bool &delayedResponse, bool timing)
|
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;
|
delayedResponse = false;
|
||||||
Addr vaddr = req->getVaddr();
|
Addr vaddr = req->getVaddr();
|
||||||
DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr);
|
DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr);
|
||||||
uint32_t flags = req->getFlags();
|
|
||||||
bool storeCheck = flags & (StoreCheck << FlagShift);
|
|
||||||
|
|
||||||
int seg = flags & SegmentFlagMask;
|
HandyM5Reg m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||||
|
|
||||||
// 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");
|
|
||||||
Addr prefix = (vaddr >> 3) & IntAddrPrefixMask;
|
|
||||||
if (prefix == IntAddrPrefixCPUID) {
|
|
||||||
panic("CPUID memory space not yet implemented!\n");
|
|
||||||
} else if (prefix == IntAddrPrefixMSR) {
|
|
||||||
vaddr = vaddr >> 3;
|
|
||||||
req->setMmapedIpr(true);
|
|
||||||
Addr regNum = 0;
|
|
||||||
switch (vaddr & ~IntAddrPrefixMask) {
|
|
||||||
case 0x10:
|
|
||||||
regNum = MISCREG_TSC;
|
|
||||||
break;
|
|
||||||
case 0x1B:
|
|
||||||
regNum = MISCREG_APIC_BASE;
|
|
||||||
break;
|
|
||||||
case 0xFE:
|
|
||||||
regNum = MISCREG_MTRRCAP;
|
|
||||||
break;
|
|
||||||
case 0x174:
|
|
||||||
regNum = MISCREG_SYSENTER_CS;
|
|
||||||
break;
|
|
||||||
case 0x175:
|
|
||||||
regNum = MISCREG_SYSENTER_ESP;
|
|
||||||
break;
|
|
||||||
case 0x176:
|
|
||||||
regNum = MISCREG_SYSENTER_EIP;
|
|
||||||
break;
|
|
||||||
case 0x179:
|
|
||||||
regNum = MISCREG_MCG_CAP;
|
|
||||||
break;
|
|
||||||
case 0x17A:
|
|
||||||
regNum = MISCREG_MCG_STATUS;
|
|
||||||
break;
|
|
||||||
case 0x17B:
|
|
||||||
regNum = MISCREG_MCG_CTL;
|
|
||||||
break;
|
|
||||||
case 0x1D9:
|
|
||||||
regNum = MISCREG_DEBUG_CTL_MSR;
|
|
||||||
break;
|
|
||||||
case 0x1DB:
|
|
||||||
regNum = MISCREG_LAST_BRANCH_FROM_IP;
|
|
||||||
break;
|
|
||||||
case 0x1DC:
|
|
||||||
regNum = MISCREG_LAST_BRANCH_TO_IP;
|
|
||||||
break;
|
|
||||||
case 0x1DD:
|
|
||||||
regNum = MISCREG_LAST_EXCEPTION_FROM_IP;
|
|
||||||
break;
|
|
||||||
case 0x1DE:
|
|
||||||
regNum = MISCREG_LAST_EXCEPTION_TO_IP;
|
|
||||||
break;
|
|
||||||
case 0x200:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_BASE_0;
|
|
||||||
break;
|
|
||||||
case 0x201:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_MASK_0;
|
|
||||||
break;
|
|
||||||
case 0x202:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_BASE_1;
|
|
||||||
break;
|
|
||||||
case 0x203:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_MASK_1;
|
|
||||||
break;
|
|
||||||
case 0x204:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_BASE_2;
|
|
||||||
break;
|
|
||||||
case 0x205:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_MASK_2;
|
|
||||||
break;
|
|
||||||
case 0x206:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_BASE_3;
|
|
||||||
break;
|
|
||||||
case 0x207:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_MASK_3;
|
|
||||||
break;
|
|
||||||
case 0x208:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_BASE_4;
|
|
||||||
break;
|
|
||||||
case 0x209:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_MASK_4;
|
|
||||||
break;
|
|
||||||
case 0x20A:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_BASE_5;
|
|
||||||
break;
|
|
||||||
case 0x20B:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_MASK_5;
|
|
||||||
break;
|
|
||||||
case 0x20C:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_BASE_6;
|
|
||||||
break;
|
|
||||||
case 0x20D:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_MASK_6;
|
|
||||||
break;
|
|
||||||
case 0x20E:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_BASE_7;
|
|
||||||
break;
|
|
||||||
case 0x20F:
|
|
||||||
regNum = MISCREG_MTRR_PHYS_MASK_7;
|
|
||||||
break;
|
|
||||||
case 0x250:
|
|
||||||
regNum = MISCREG_MTRR_FIX_64K_00000;
|
|
||||||
break;
|
|
||||||
case 0x258:
|
|
||||||
regNum = MISCREG_MTRR_FIX_16K_80000;
|
|
||||||
break;
|
|
||||||
case 0x259:
|
|
||||||
regNum = MISCREG_MTRR_FIX_16K_A0000;
|
|
||||||
break;
|
|
||||||
case 0x268:
|
|
||||||
regNum = MISCREG_MTRR_FIX_4K_C0000;
|
|
||||||
break;
|
|
||||||
case 0x269:
|
|
||||||
regNum = MISCREG_MTRR_FIX_4K_C8000;
|
|
||||||
break;
|
|
||||||
case 0x26A:
|
|
||||||
regNum = MISCREG_MTRR_FIX_4K_D0000;
|
|
||||||
break;
|
|
||||||
case 0x26B:
|
|
||||||
regNum = MISCREG_MTRR_FIX_4K_D8000;
|
|
||||||
break;
|
|
||||||
case 0x26C:
|
|
||||||
regNum = MISCREG_MTRR_FIX_4K_E0000;
|
|
||||||
break;
|
|
||||||
case 0x26D:
|
|
||||||
regNum = MISCREG_MTRR_FIX_4K_E8000;
|
|
||||||
break;
|
|
||||||
case 0x26E:
|
|
||||||
regNum = MISCREG_MTRR_FIX_4K_F0000;
|
|
||||||
break;
|
|
||||||
case 0x26F:
|
|
||||||
regNum = MISCREG_MTRR_FIX_4K_F8000;
|
|
||||||
break;
|
|
||||||
case 0x277:
|
|
||||||
regNum = MISCREG_PAT;
|
|
||||||
break;
|
|
||||||
case 0x2FF:
|
|
||||||
regNum = MISCREG_DEF_TYPE;
|
|
||||||
break;
|
|
||||||
case 0x400:
|
|
||||||
regNum = MISCREG_MC0_CTL;
|
|
||||||
break;
|
|
||||||
case 0x404:
|
|
||||||
regNum = MISCREG_MC1_CTL;
|
|
||||||
break;
|
|
||||||
case 0x408:
|
|
||||||
regNum = MISCREG_MC2_CTL;
|
|
||||||
break;
|
|
||||||
case 0x40C:
|
|
||||||
regNum = MISCREG_MC3_CTL;
|
|
||||||
break;
|
|
||||||
case 0x410:
|
|
||||||
regNum = MISCREG_MC4_CTL;
|
|
||||||
break;
|
|
||||||
case 0x414:
|
|
||||||
regNum = MISCREG_MC5_CTL;
|
|
||||||
break;
|
|
||||||
case 0x418:
|
|
||||||
regNum = MISCREG_MC6_CTL;
|
|
||||||
break;
|
|
||||||
case 0x41C:
|
|
||||||
regNum = MISCREG_MC7_CTL;
|
|
||||||
break;
|
|
||||||
case 0x401:
|
|
||||||
regNum = MISCREG_MC0_STATUS;
|
|
||||||
break;
|
|
||||||
case 0x405:
|
|
||||||
regNum = MISCREG_MC1_STATUS;
|
|
||||||
break;
|
|
||||||
case 0x409:
|
|
||||||
regNum = MISCREG_MC2_STATUS;
|
|
||||||
break;
|
|
||||||
case 0x40D:
|
|
||||||
regNum = MISCREG_MC3_STATUS;
|
|
||||||
break;
|
|
||||||
case 0x411:
|
|
||||||
regNum = MISCREG_MC4_STATUS;
|
|
||||||
break;
|
|
||||||
case 0x415:
|
|
||||||
regNum = MISCREG_MC5_STATUS;
|
|
||||||
break;
|
|
||||||
case 0x419:
|
|
||||||
regNum = MISCREG_MC6_STATUS;
|
|
||||||
break;
|
|
||||||
case 0x41D:
|
|
||||||
regNum = MISCREG_MC7_STATUS;
|
|
||||||
break;
|
|
||||||
case 0x402:
|
|
||||||
regNum = MISCREG_MC0_ADDR;
|
|
||||||
break;
|
|
||||||
case 0x406:
|
|
||||||
regNum = MISCREG_MC1_ADDR;
|
|
||||||
break;
|
|
||||||
case 0x40A:
|
|
||||||
regNum = MISCREG_MC2_ADDR;
|
|
||||||
break;
|
|
||||||
case 0x40E:
|
|
||||||
regNum = MISCREG_MC3_ADDR;
|
|
||||||
break;
|
|
||||||
case 0x412:
|
|
||||||
regNum = MISCREG_MC4_ADDR;
|
|
||||||
break;
|
|
||||||
case 0x416:
|
|
||||||
regNum = MISCREG_MC5_ADDR;
|
|
||||||
break;
|
|
||||||
case 0x41A:
|
|
||||||
regNum = MISCREG_MC6_ADDR;
|
|
||||||
break;
|
|
||||||
case 0x41E:
|
|
||||||
regNum = MISCREG_MC7_ADDR;
|
|
||||||
break;
|
|
||||||
case 0x403:
|
|
||||||
regNum = MISCREG_MC0_MISC;
|
|
||||||
break;
|
|
||||||
case 0x407:
|
|
||||||
regNum = MISCREG_MC1_MISC;
|
|
||||||
break;
|
|
||||||
case 0x40B:
|
|
||||||
regNum = MISCREG_MC2_MISC;
|
|
||||||
break;
|
|
||||||
case 0x40F:
|
|
||||||
regNum = MISCREG_MC3_MISC;
|
|
||||||
break;
|
|
||||||
case 0x413:
|
|
||||||
regNum = MISCREG_MC4_MISC;
|
|
||||||
break;
|
|
||||||
case 0x417:
|
|
||||||
regNum = MISCREG_MC5_MISC;
|
|
||||||
break;
|
|
||||||
case 0x41B:
|
|
||||||
regNum = MISCREG_MC6_MISC;
|
|
||||||
break;
|
|
||||||
case 0x41F:
|
|
||||||
regNum = MISCREG_MC7_MISC;
|
|
||||||
break;
|
|
||||||
case 0xC0000080:
|
|
||||||
regNum = MISCREG_EFER;
|
|
||||||
break;
|
|
||||||
case 0xC0000081:
|
|
||||||
regNum = MISCREG_STAR;
|
|
||||||
break;
|
|
||||||
case 0xC0000082:
|
|
||||||
regNum = MISCREG_LSTAR;
|
|
||||||
break;
|
|
||||||
case 0xC0000083:
|
|
||||||
regNum = MISCREG_CSTAR;
|
|
||||||
break;
|
|
||||||
case 0xC0000084:
|
|
||||||
regNum = MISCREG_SF_MASK;
|
|
||||||
break;
|
|
||||||
case 0xC0000100:
|
|
||||||
regNum = MISCREG_FS_BASE;
|
|
||||||
break;
|
|
||||||
case 0xC0000101:
|
|
||||||
regNum = MISCREG_GS_BASE;
|
|
||||||
break;
|
|
||||||
case 0xC0000102:
|
|
||||||
regNum = MISCREG_KERNEL_GS_BASE;
|
|
||||||
break;
|
|
||||||
case 0xC0000103:
|
|
||||||
regNum = MISCREG_TSC_AUX;
|
|
||||||
break;
|
|
||||||
case 0xC0010000:
|
|
||||||
regNum = MISCREG_PERF_EVT_SEL0;
|
|
||||||
break;
|
|
||||||
case 0xC0010001:
|
|
||||||
regNum = MISCREG_PERF_EVT_SEL1;
|
|
||||||
break;
|
|
||||||
case 0xC0010002:
|
|
||||||
regNum = MISCREG_PERF_EVT_SEL2;
|
|
||||||
break;
|
|
||||||
case 0xC0010003:
|
|
||||||
regNum = MISCREG_PERF_EVT_SEL3;
|
|
||||||
break;
|
|
||||||
case 0xC0010004:
|
|
||||||
regNum = MISCREG_PERF_EVT_CTR0;
|
|
||||||
break;
|
|
||||||
case 0xC0010005:
|
|
||||||
regNum = MISCREG_PERF_EVT_CTR1;
|
|
||||||
break;
|
|
||||||
case 0xC0010006:
|
|
||||||
regNum = MISCREG_PERF_EVT_CTR2;
|
|
||||||
break;
|
|
||||||
case 0xC0010007:
|
|
||||||
regNum = MISCREG_PERF_EVT_CTR3;
|
|
||||||
break;
|
|
||||||
case 0xC0010010:
|
|
||||||
regNum = MISCREG_SYSCFG;
|
|
||||||
break;
|
|
||||||
case 0xC0010016:
|
|
||||||
regNum = MISCREG_IORR_BASE0;
|
|
||||||
break;
|
|
||||||
case 0xC0010017:
|
|
||||||
regNum = MISCREG_IORR_BASE1;
|
|
||||||
break;
|
|
||||||
case 0xC0010018:
|
|
||||||
regNum = MISCREG_IORR_MASK0;
|
|
||||||
break;
|
|
||||||
case 0xC0010019:
|
|
||||||
regNum = MISCREG_IORR_MASK1;
|
|
||||||
break;
|
|
||||||
case 0xC001001A:
|
|
||||||
regNum = MISCREG_TOP_MEM;
|
|
||||||
break;
|
|
||||||
case 0xC001001D:
|
|
||||||
regNum = MISCREG_TOP_MEM2;
|
|
||||||
break;
|
|
||||||
case 0xC0010114:
|
|
||||||
regNum = MISCREG_VM_CR;
|
|
||||||
break;
|
|
||||||
case 0xC0010115:
|
|
||||||
regNum = MISCREG_IGNNE;
|
|
||||||
break;
|
|
||||||
case 0xC0010116:
|
|
||||||
regNum = MISCREG_SMM_CTL;
|
|
||||||
break;
|
|
||||||
case 0xC0010117:
|
|
||||||
regNum = MISCREG_VM_HSAVE_PA;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return new GeneralProtection(0);
|
|
||||||
}
|
|
||||||
//The index is multiplied by the size of a MiscReg so that
|
|
||||||
//any memory dependence calculations will not see these as
|
|
||||||
//overlapping.
|
|
||||||
req->setPaddr(regNum * sizeof(MiscReg));
|
|
||||||
return NoFault;
|
|
||||||
} else if (prefix == IntAddrPrefixIO) {
|
|
||||||
// TODO If CPL > IOPL or in virtual mode, check the I/O permission
|
|
||||||
// bitmap in the TSS.
|
|
||||||
|
|
||||||
Addr IOPort = vaddr & ~IntAddrPrefixMask;
|
|
||||||
// Make sure the address fits in the expected 16 bit IO address
|
|
||||||
// space.
|
|
||||||
assert(!(IOPort & ~0xFFFF));
|
|
||||||
if (IOPort == 0xCF8 && req->getSize() == 4) {
|
|
||||||
req->setMmapedIpr(true);
|
|
||||||
req->setPaddr(MISCREG_PCI_CONFIG_ADDRESS * sizeof(MiscReg));
|
|
||||||
} else if ((IOPort & ~mask(2)) == 0xCFC) {
|
|
||||||
Addr configAddress =
|
|
||||||
tc->readMiscRegNoEffect(MISCREG_PCI_CONFIG_ADDRESS);
|
|
||||||
if (bits(configAddress, 31, 31)) {
|
|
||||||
req->setPaddr(PhysAddrPrefixPciConfig |
|
|
||||||
mbits(configAddress, 30, 2) |
|
|
||||||
(IOPort & mask(2)));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
req->setPaddr(PhysAddrPrefixIO | IOPort);
|
|
||||||
}
|
|
||||||
return NoFault;
|
|
||||||
} else {
|
|
||||||
panic("Access to unrecognized internal address space %#x.\n",
|
|
||||||
prefix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get cr0. This will tell us how to do translation. We'll assume it was
|
|
||||||
// verified to be correct and consistent when set.
|
|
||||||
CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0);
|
|
||||||
|
|
||||||
// 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