arch,cpu,mem: Replace the mmmapped IPR mechanism with local accesses.
The new local access mechanism installs a callback in the request which implements what the mmapped IPR was doing. That avoids having to have stubs in ISAs that don't have mmapped IPRs, avoids having to encode what to do to communicate from the TLB and the mmapped IPR functions, and gets rid of another global ISA interface function and header files. Jira Issue: https://gem5.atlassian.net/browse/GEM5-187 Change-Id: I772c2ae2ca3830a4486919ce9804560c0f2d596a Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23188 Reviewed-by: Matthew Poremba <matthew.poremba@amd.com> Maintainer: Gabe Black <gabeblack@google.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -56,6 +56,7 @@
|
||||
#include "mem/page_table.hh"
|
||||
#include "mem/request.hh"
|
||||
#include "sim/process.hh"
|
||||
#include "sim/pseudo_inst.hh"
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
@@ -273,8 +274,30 @@ namespace X86ISA
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
Cycles
|
||||
localMiscRegAccess(bool read, MiscRegIndex regNum,
|
||||
ThreadContext *tc, PacketPtr pkt)
|
||||
{
|
||||
if (read) {
|
||||
RegVal data = htole(tc->readMiscReg(regNum));
|
||||
// Make sure we don't trot off the end of data.
|
||||
pkt->setData((uint8_t *)&data);
|
||||
} else {
|
||||
RegVal data = htole(tc->readMiscRegNoEffect(regNum));
|
||||
tc->setMiscReg(regNum, letoh(data));
|
||||
}
|
||||
return Cycles(1);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
Fault
|
||||
GpuTLB::translateInt(const RequestPtr &req, ThreadContext *tc)
|
||||
GpuTLB::translateInt(bool read, const RequestPtr &req, ThreadContext *tc)
|
||||
{
|
||||
DPRINTF(GPUTLB, "Addresses references internal memory.\n");
|
||||
Addr vaddr = req->getVaddr();
|
||||
@@ -283,327 +306,19 @@ namespace X86ISA
|
||||
if (prefix == IntAddrPrefixCPUID) {
|
||||
panic("CPUID memory space not yet implemented!\n");
|
||||
} else if (prefix == IntAddrPrefixMSR) {
|
||||
vaddr = vaddr >> 3;
|
||||
req->setFlags(Request::MMAPPED_IPR);
|
||||
Addr regNum = 0;
|
||||
vaddr = (vaddr >> 3) & ~IntAddrPrefixMask;
|
||||
|
||||
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:
|
||||
MiscRegIndex regNum;
|
||||
if (!msrAddrToIndex(regNum, vaddr))
|
||||
return std::make_shared<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(RegVal));
|
||||
|
||||
req->setLocalAccessor(
|
||||
[read,regNum,vaddr](ThreadContext *tc, PacketPtr pkt)
|
||||
{
|
||||
return localMiscRegAccess(read, regNum, tc, pkt);
|
||||
}
|
||||
);
|
||||
|
||||
return NoFault;
|
||||
} else if (prefix == IntAddrPrefixIO) {
|
||||
// TODO If CPL > IOPL or in virtual mode, check the I/O permission
|
||||
@@ -613,25 +328,27 @@ namespace X86ISA
|
||||
// Make sure the address fits in the expected 16 bit IO address
|
||||
// space.
|
||||
assert(!(IOPort & ~0xFFFF));
|
||||
|
||||
if (IOPort == 0xCF8 && req->getSize() == 4) {
|
||||
req->setFlags(Request::MMAPPED_IPR);
|
||||
req->setPaddr(MISCREG_PCI_CONFIG_ADDRESS * sizeof(RegVal));
|
||||
req->setLocalAccessor(
|
||||
[read](ThreadContext *tc, PacketPtr pkt)
|
||||
{
|
||||
return localMiscRegAccess(
|
||||
read, MISCREG_PCI_CONFIG_ADDRESS, tc, pkt);
|
||||
}
|
||||
);
|
||||
} else if ((IOPort & ~mask(2)) == 0xCFC) {
|
||||
req->setFlags(Request::UNCACHEABLE);
|
||||
|
||||
req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER);
|
||||
Addr configAddress =
|
||||
tc->readMiscRegNoEffect(MISCREG_PCI_CONFIG_ADDRESS);
|
||||
|
||||
if (bits(configAddress, 31, 31)) {
|
||||
req->setPaddr(PhysAddrPrefixPciConfig |
|
||||
mbits(configAddress, 30, 2) |
|
||||
(IOPort & mask(2)));
|
||||
mbits(configAddress, 30, 2) |
|
||||
(IOPort & mask(2)));
|
||||
} else {
|
||||
req->setPaddr(PhysAddrPrefixIO | IOPort);
|
||||
}
|
||||
} else {
|
||||
req->setFlags(Request::UNCACHEABLE);
|
||||
req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER);
|
||||
req->setPaddr(PhysAddrPrefixIO | IOPort);
|
||||
}
|
||||
return NoFault;
|
||||
@@ -709,7 +426,7 @@ namespace X86ISA
|
||||
// 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);
|
||||
return translateInt(mode == Read, req, tc);
|
||||
}
|
||||
|
||||
delayedResponse = false;
|
||||
|
||||
Reference in New Issue
Block a user