*/
#include <cstring>
+#include <memory>
+#include "arch/generic/mmapped_ipr.hh"
#include "arch/x86/insts/microldstop.hh"
#include "arch/x86/regs/misc.hh"
#include "arch/x86/regs/msr.hh"
MiscRegIndex regNum;
if (!msrAddrToIndex(regNum, vaddr))
- return new GeneralProtection(0);
+ 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
{
Addr paddr = req->getPaddr();
- // Check for an access to the local APIC
- if (FullSystem) {
+ AddrRange m5opRange(0xFFFF0000, 0xFFFFFFFF);
+
+ if (m5opRange.contains(paddr)) {
+ if (m5opRange.contains(paddr)) {
+ req->setFlags(Request::MMAPPED_IPR | Request::GENERIC_IPR);
+ req->setPaddr(GenericISA::iprAddressPseudoInst(
+ (paddr >> 8) & 0xFF,
+ paddr & 0xFF));
+ }
+ } else if (FullSystem) {
+ // Check for an access to the local APIC
LocalApicBase localApicBase =
tc->readMiscRegNoEffect(MISCREG_APIC_BASE);
AddrRange apicRange(localApicBase.base * PageBytes,
if (!(seg == SEGMENT_REG_TSG || seg == SYS_SEGMENT_REG_IDTR ||
seg == SEGMENT_REG_HS || seg == SEGMENT_REG_LS)
&& !tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg)))
- return new GeneralProtection(0);
+ return std::make_shared<GeneralProtection>(0);
bool expandDown = false;
SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg));
if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) {
if (!attr.writable && (mode == Write || storeCheck))
- return new GeneralProtection(0);
+ return std::make_shared<GeneralProtection>(0);
if (!attr.readable && mode == Read)
- return new GeneralProtection(0);
+ return std::make_shared<GeneralProtection>(0);
expandDown = attr.expandDown;
}
DPRINTF(TLB, "Checking an expand down segment.\n");
warn_once("Expand down segments are untested.\n");
if (offset <= limit || endOffset <= limit)
- return new GeneralProtection(0);
+ return std::make_shared<GeneralProtection>(0);
} else {
if (offset > limit || endOffset > limit)
- return new GeneralProtection(0);
+ return std::make_shared<GeneralProtection>(0);
}
}
if (m5Reg.submode != SixtyFourBitMode ||
}
}
if (!success) {
- return new PageFault(vaddr, true, mode, true, false);
+ return std::make_shared<PageFault>(vaddr, true, mode,
+ true, false);
} else {
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
// The page must have been present to get into the TLB in
// the first place. We'll assume the reserved bits are
// fine even though we're not checking them.
- return new PageFault(vaddr, true, mode, inUser, false);
+ return std::make_shared<PageFault>(vaddr, true, mode, inUser,
+ false);
}
if (storeCheck && badWrite) {
// This would fault if this were a write, so return a page
// fault that reflects that happening.
- return new PageFault(vaddr, true, Write, inUser, false);
+ return std::make_shared<PageFault>(vaddr, true, Write, inUser,
+ false);
}
Addr paddr = entry->paddr | (vaddr & mask(entry->logBytes));
void
TLB::serialize(std::ostream &os)
{
+ // Only store the entries in use.
+ uint32_t _size = size - freeList.size();
+ SERIALIZE_SCALAR(_size);
+ SERIALIZE_SCALAR(lruSeq);
+
+ uint32_t _count = 0;
+
+ for (uint32_t x = 0; x < size; x++) {
+ if (tlb[x].trieHandle != NULL) {
+ os << "\n[" << csprintf("%s.Entry%d", name(), _count) << "]\n";
+ tlb[x].serialize(os);
+ _count++;
+ }
+ }
}
void
TLB::unserialize(Checkpoint *cp, const std::string §ion)
{
+ // Do not allow to restore with a smaller tlb.
+ uint32_t _size;
+ UNSERIALIZE_SCALAR(_size);
+ if (_size > size) {
+ fatal("TLB size less than the one in checkpoint!");
+ }
+
+ UNSERIALIZE_SCALAR(lruSeq);
+
+ for (uint32_t x = 0; x < _size; x++) {
+ TlbEntry *newEntry = freeList.front();
+ freeList.pop_front();
+
+ newEntry->unserialize(cp, csprintf("%s.Entry%d", name(), x));
+ newEntry->trieHandle = trie.insert(newEntry->vaddr,
+ TlbEntryTrie::MaxBits - newEntry->logBytes, newEntry);
+ }
}
BaseMasterPort *