diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/miscregs.hh | 2 | ||||
-rw-r--r-- | src/arch/x86/mmaped_ipr.hh | 10 | ||||
-rw-r--r-- | src/arch/x86/tlb.cc | 22 | ||||
-rw-r--r-- | src/arch/x86/tlb.hh | 3 | ||||
-rw-r--r-- | src/arch/x86/x86_traits.hh | 3 |
5 files changed, 35 insertions, 5 deletions
diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 36b953526..2bf647150 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -339,6 +339,8 @@ namespace X86ISA //XXX Add "Model-Specific Registers" + MISCREG_PCI_CONFIG_ADDRESS, + NUM_MISCREGS }; diff --git a/src/arch/x86/mmaped_ipr.hh b/src/arch/x86/mmaped_ipr.hh index 9184ec4dc..36c0baaca 100644 --- a/src/arch/x86/mmaped_ipr.hh +++ b/src/arch/x86/mmaped_ipr.hh @@ -64,6 +64,7 @@ * ISA-specific helper functions for memory mapped IPR accesses. */ +#include "arch/x86/miscregs.hh" #include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" @@ -88,8 +89,13 @@ namespace X86ISA #if !FULL_SYSTEM panic("Shouldn't have a memory mapped register in SE\n"); #else - xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg), - gtoh(pkt->get<uint64_t>())); + MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg)); + if (index == MISCREG_PCI_CONFIG_ADDRESS) { + xc->setMiscReg(index, gtoh(pkt->get<uint32_t>())); + } else { + xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg), + gtoh(pkt->get<uint64_t>())); + } #endif return xc->getCpuPtr()->ticks(1); } diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 2e6ea4a22..acac3081a 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -76,7 +76,7 @@ namespace X86ISA { -TLB::TLB(const Params *p) : SimObject(p), size(p->size) +TLB::TLB(const Params *p) : SimObject(p), configAddress(0), size(p->size) { tlb = new TlbEntry[size]; std::memset(tlb, 0, sizeof(TlbEntry) * size); @@ -148,6 +148,12 @@ TLB::invalidateAll() } void +TLB::setConfigAddress(uint32_t addr) +{ + configAddress = addr; +} + +void TLB::invalidateNonGlobal() { DPRINTF(TLB, "Invalidating all non global entries.\n"); @@ -478,7 +484,19 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) // Make sure the address fits in the expected 16 bit IO address // space. assert(!(IOPort & ~0xFFFF)); - req->setPaddr(PhysAddrPrefixIO | IOPort); + 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 | + bits(configAddress, 30, 0)); + } + } else { + req->setPaddr(PhysAddrPrefixIO | IOPort); + } return NoFault; } else { panic("Access to unrecognized internal address space %#x.\n", diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index a361c2291..d08d6fa68 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -90,6 +90,7 @@ namespace X86ISA friend class FakeDTLBFault; bool _allowNX; + uint32_t configAddress; public: bool allowNX() const @@ -104,6 +105,8 @@ namespace X86ISA TlbEntry *lookup(Addr va, bool update_lru = true); + void setConfigAddress(uint32_t addr); + #if FULL_SYSTEM protected: diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index dc71de500..d605ce218 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -88,7 +88,8 @@ namespace X86ISA const Addr IntAddrPrefixMSR = ULL(0x200000000); const Addr IntAddrPrefixIO = ULL(0x300000000); - const Addr PhysAddrPrefixIO = ULL(0x1000000000000000); + const Addr PhysAddrPrefixIO = ULL(0x8000000000000000); + const Addr PhysAddrPrefixPciConfig = ULL(0xC000000000000000); } #endif //__ARCH_X86_X86TRAITS_HH__ |