x86, mem: Don't try to force physical addresses on the system.
Use the system object to allocate physical memory instead of manually placing certain structures and then forcing the system to start other allocations after them in physical memory. Change-Id: Ie18c81645c3b648c64a6d7a649a0e50f7028f344 Reviewed-on: https://gem5-review.googlesource.com/7346 Maintainer: Gabe Black <gabeblack@google.com> Reviewed-by: Brandon Potter <Brandon.Potter@amd.com>
This commit is contained in:
@@ -103,8 +103,7 @@ X86Process::X86Process(ProcessParams *params, ObjectFile *objFile,
|
||||
new ArchPageTable(
|
||||
params->name, params->pid,
|
||||
params->system, PageBytes,
|
||||
PageTableLayout,
|
||||
pageTablePhysAddr >> PageShift)) :
|
||||
PageTableLayout)) :
|
||||
new EmulationPageTable(params->name, params->pid,
|
||||
PageBytes),
|
||||
objFile),
|
||||
@@ -214,12 +213,19 @@ X86_64Process::initState()
|
||||
if (kvmInSE) {
|
||||
PortProxy physProxy = system->physProxy;
|
||||
|
||||
Addr syscallCodePhysAddr = system->allocPhysPages(1);
|
||||
Addr gdtPhysAddr = system->allocPhysPages(1);
|
||||
Addr idtPhysAddr = system->allocPhysPages(1);
|
||||
Addr istPhysAddr = system->allocPhysPages(1);
|
||||
Addr tssPhysAddr = system->allocPhysPages(1);
|
||||
Addr pfHandlerPhysAddr = system->allocPhysPages(1);
|
||||
|
||||
/*
|
||||
* Set up the gdt.
|
||||
*/
|
||||
uint8_t numGDTEntries = 0;
|
||||
uint64_t nullDescriptor = 0;
|
||||
physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
|
||||
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
|
||||
(uint8_t *)(&nullDescriptor), 8);
|
||||
numGDTEntries++;
|
||||
|
||||
@@ -243,7 +249,7 @@ X86_64Process::initState()
|
||||
csLowPLDesc.type.codeOrData = 1;
|
||||
csLowPLDesc.dpl = 0;
|
||||
uint64_t csLowPLDescVal = csLowPLDesc;
|
||||
physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
|
||||
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
|
||||
(uint8_t *)(&csLowPLDescVal), 8);
|
||||
|
||||
numGDTEntries++;
|
||||
@@ -257,7 +263,7 @@ X86_64Process::initState()
|
||||
dsLowPLDesc.type.codeOrData = 0;
|
||||
dsLowPLDesc.dpl = 0;
|
||||
uint64_t dsLowPLDescVal = dsLowPLDesc;
|
||||
physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
|
||||
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
|
||||
(uint8_t *)(&dsLowPLDescVal), 8);
|
||||
|
||||
numGDTEntries++;
|
||||
@@ -271,7 +277,7 @@ X86_64Process::initState()
|
||||
dsDesc.type.codeOrData = 0;
|
||||
dsDesc.dpl = 3;
|
||||
uint64_t dsDescVal = dsDesc;
|
||||
physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
|
||||
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
|
||||
(uint8_t *)(&dsDescVal), 8);
|
||||
|
||||
numGDTEntries++;
|
||||
@@ -285,7 +291,7 @@ X86_64Process::initState()
|
||||
csDesc.type.codeOrData = 1;
|
||||
csDesc.dpl = 3;
|
||||
uint64_t csDescVal = csDesc;
|
||||
physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
|
||||
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
|
||||
(uint8_t *)(&csDescVal), 8);
|
||||
|
||||
numGDTEntries++;
|
||||
@@ -321,7 +327,7 @@ X86_64Process::initState()
|
||||
uint64_t high;
|
||||
} tssDescVal = {TSSDescLow, TSSDescHigh};
|
||||
|
||||
physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
|
||||
physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
|
||||
(uint8_t *)(&tssDescVal), sizeof(tssDescVal));
|
||||
|
||||
numGDTEntries++;
|
||||
@@ -405,7 +411,7 @@ X86_64Process::initState()
|
||||
CR0 cr2 = 0;
|
||||
tc->setMiscReg(MISCREG_CR2, cr2);
|
||||
|
||||
CR3 cr3 = pageTablePhysAddr;
|
||||
CR3 cr3 = dynamic_cast<ArchPageTable *>(pTable)->basePtr();
|
||||
tc->setMiscReg(MISCREG_CR3, cr3);
|
||||
|
||||
CR4 cr4 = 0;
|
||||
@@ -428,10 +434,6 @@ X86_64Process::initState()
|
||||
CR4 cr8 = 0;
|
||||
tc->setMiscReg(MISCREG_CR8, cr8);
|
||||
|
||||
const Addr PageMapLevel4 = pageTablePhysAddr;
|
||||
//Point to the page tables.
|
||||
tc->setMiscReg(MISCREG_CR3, PageMapLevel4);
|
||||
|
||||
tc->setMiscReg(MISCREG_MXCSR, 0x1f80);
|
||||
|
||||
tc->setMiscReg(MISCREG_APIC_BASE, 0xfee00900);
|
||||
@@ -493,7 +495,7 @@ X86_64Process::initState()
|
||||
tss.RSP1_high = tss.IST1_high;
|
||||
tss.RSP2_low = tss.IST1_low;
|
||||
tss.RSP2_high = tss.IST1_high;
|
||||
physProxy.writeBlob(TSSPhysAddr, (uint8_t *)(&tss), sizeof(tss));
|
||||
physProxy.writeBlob(tssPhysAddr, (uint8_t *)(&tss), sizeof(tss));
|
||||
|
||||
/* Setting IDT gates */
|
||||
GateDescriptorLow PFGateLow = 0;
|
||||
@@ -513,7 +515,7 @@ X86_64Process::initState()
|
||||
uint64_t high;
|
||||
} PFGate = {PFGateLow, PFGateHigh};
|
||||
|
||||
physProxy.writeBlob(IDTPhysAddr + 0xE0,
|
||||
physProxy.writeBlob(idtPhysAddr + 0xE0,
|
||||
(uint8_t *)(&PFGate), sizeof(PFGate));
|
||||
|
||||
/* System call handler */
|
||||
@@ -539,7 +541,7 @@ X86_64Process::initState()
|
||||
0x48, 0xcf
|
||||
};
|
||||
|
||||
physProxy.writeBlob(PFHandlerPhysAddr, faultBlob, sizeof(faultBlob));
|
||||
physProxy.writeBlob(pfHandlerPhysAddr, faultBlob, sizeof(faultBlob));
|
||||
|
||||
MultiLevelPageTable<PageTableOps> *pt =
|
||||
dynamic_cast<MultiLevelPageTable<PageTableOps> *>(pTable);
|
||||
@@ -547,15 +549,15 @@ X86_64Process::initState()
|
||||
/* Syscall handler */
|
||||
pt->map(syscallCodeVirtAddr, syscallCodePhysAddr, PageBytes, false);
|
||||
/* GDT */
|
||||
pt->map(GDTVirtAddr, GDTPhysAddr, PageBytes, false);
|
||||
pt->map(GDTVirtAddr, gdtPhysAddr, PageBytes, false);
|
||||
/* IDT */
|
||||
pt->map(IDTVirtAddr, IDTPhysAddr, PageBytes, false);
|
||||
pt->map(IDTVirtAddr, idtPhysAddr, PageBytes, false);
|
||||
/* TSS */
|
||||
pt->map(TSSVirtAddr, TSSPhysAddr, PageBytes, false);
|
||||
pt->map(TSSVirtAddr, tssPhysAddr, PageBytes, false);
|
||||
/* IST */
|
||||
pt->map(ISTVirtAddr, ISTPhysAddr, PageBytes, false);
|
||||
pt->map(ISTVirtAddr, istPhysAddr, PageBytes, false);
|
||||
/* PF handler */
|
||||
pt->map(PFHandlerVirtAddr, PFHandlerPhysAddr, PageBytes, false);
|
||||
pt->map(PFHandlerVirtAddr, pfHandlerPhysAddr, PageBytes, false);
|
||||
/* MMIO region for m5ops */
|
||||
pt->map(MMIORegionVirtAddr, MMIORegionPhysAddr, 16*PageBytes, false);
|
||||
} else {
|
||||
|
||||
@@ -64,21 +64,14 @@ namespace X86ISA
|
||||
|
||||
/* memory mappings for KVMCpu in SE mode */
|
||||
const uint64_t syscallCodeVirtAddr = 0xffff800000000000;
|
||||
const uint64_t syscallCodePhysAddr = 0x60000;
|
||||
const uint64_t GDTVirtAddr = 0xffff800000001000;
|
||||
const uint64_t GDTPhysAddr = 0x61000;
|
||||
const uint64_t IDTVirtAddr = 0xffff800000002000;
|
||||
const uint64_t IDTPhysAddr = 0x62000;
|
||||
const uint64_t TSSVirtAddr = 0xffff800000003000;
|
||||
const uint64_t TSSPhysAddr = 0x63000;
|
||||
const uint64_t ISTVirtAddr = 0xffff800000004000;
|
||||
const uint64_t ISTPhysAddr = 0x64000;
|
||||
const uint64_t PFHandlerVirtAddr = 0xffff800000005000;
|
||||
const uint64_t PFHandlerPhysAddr = 0x65000;
|
||||
const uint64_t MMIORegionVirtAddr = 0xffffc90000000000;
|
||||
const uint64_t MMIORegionPhysAddr = 0xffff0000;
|
||||
|
||||
const uint64_t pageTablePhysAddr = 0x70000;
|
||||
}
|
||||
|
||||
class X86System : public System
|
||||
|
||||
@@ -115,7 +115,7 @@ class MultiLevelPageTable : public EmulationPageTable
|
||||
/**
|
||||
* Physical address to the last level of the page table
|
||||
*/
|
||||
Addr basePtr;
|
||||
Addr _basePtr;
|
||||
|
||||
/**
|
||||
* Vector with sizes of all levels in base 2 logarithmic
|
||||
@@ -140,12 +140,13 @@ class MultiLevelPageTable : public EmulationPageTable
|
||||
public:
|
||||
MultiLevelPageTable(const std::string &__name, uint64_t _pid,
|
||||
System *_sys, Addr pageSize,
|
||||
const std::vector<uint8_t> &layout,
|
||||
Addr _basePtr);
|
||||
const std::vector<uint8_t> &layout);
|
||||
~MultiLevelPageTable();
|
||||
|
||||
void initState(ThreadContext* tc) override;
|
||||
|
||||
Addr basePtr() { return _basePtr; }
|
||||
|
||||
void map(Addr vaddr, Addr paddr, int64_t size,
|
||||
uint64_t flags = 0) override;
|
||||
void remap(Addr vaddr, int64_t size, Addr new_vaddr) override;
|
||||
|
||||
@@ -47,9 +47,9 @@ using namespace TheISA;
|
||||
template <class ISAOps>
|
||||
MultiLevelPageTable<ISAOps>::MultiLevelPageTable(
|
||||
const std::string &__name, uint64_t _pid, System *_sys,
|
||||
Addr pageSize, const std::vector<uint8_t> &layout, Addr _basePtr)
|
||||
Addr pageSize, const std::vector<uint8_t> &layout)
|
||||
: EmulationPageTable(__name, _pid, pageSize), system(_sys),
|
||||
basePtr(_basePtr), logLevelSize(layout), numLevels(logLevelSize.size())
|
||||
logLevelSize(layout), numLevels(logLevelSize.size())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,18 +62,16 @@ template <class ISAOps>
|
||||
void
|
||||
MultiLevelPageTable<ISAOps>::initState(ThreadContext* tc)
|
||||
{
|
||||
system->pagePtr = basePtr;
|
||||
|
||||
/* setting first level of the page table */
|
||||
uint64_t log_req_size = floorLog2(sizeof(PageTableEntry)) +
|
||||
logLevelSize[numLevels-1];
|
||||
logLevelSize[numLevels - 1];
|
||||
assert(log_req_size >= PageShift);
|
||||
uint64_t npages = 1 << (log_req_size - PageShift);
|
||||
|
||||
Addr paddr = system->allocPhysPages(npages);
|
||||
Addr _basePtr = system->allocPhysPages(npages);
|
||||
|
||||
PortProxy &p = system->physProxy;
|
||||
p.memsetBlob(paddr, 0, npages << PageShift);
|
||||
p.memsetBlob(_basePtr, 0, npages << PageShift);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +81,7 @@ MultiLevelPageTable<ISAOps>::walk(Addr vaddr, bool allocate, Addr &PTE_addr)
|
||||
{
|
||||
std::vector<uint64_t> offsets = pTableISAOps.getOffsets(vaddr);
|
||||
|
||||
Addr level_base = basePtr;
|
||||
Addr level_base = _basePtr;
|
||||
for (int i = numLevels - 1; i > 0; i--) {
|
||||
|
||||
Addr entry_addr = (level_base<<PageShift) +
|
||||
@@ -221,7 +219,7 @@ MultiLevelPageTable<ISAOps>::serialize(CheckpointOut &cp) const
|
||||
* which is serialized separately, we will serialize
|
||||
* just the base pointer
|
||||
*/
|
||||
paramOut(cp, "ptable.pointer", basePtr);
|
||||
paramOut(cp, "ptable.pointer", _basePtr);
|
||||
}
|
||||
|
||||
template <class ISAOps>
|
||||
@@ -229,5 +227,5 @@ void
|
||||
MultiLevelPageTable<ISAOps>::unserialize(CheckpointIn &cp)
|
||||
{
|
||||
EmulationPageTable::unserialize(cp);
|
||||
paramIn(cp, "ptable.pointer", basePtr);
|
||||
paramIn(cp, "ptable.pointer", _basePtr);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user