virtProxy.reset(new FSTranslatingPortProxy(tc));
} else {
assert(!virtProxy);
- virtProxy.reset(new SETranslatingPortProxy(
- _cpu->getSendFunctional(), getProcessPtr(),
+ virtProxy.reset(new SETranslatingPortProxy(this,
SETranslatingPortProxy::NextPage));
}
}
//Write out the sentry void *
IntType sentry_NULL = 0;
- initVirtMem.writeBlob(sentry_base, &sentry_NULL, sentry_size);
+ initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size);
//Fix up the aux vectors which point to other data
for (int i = auxv.size() - 1; i >= 0; i--) {
if (auxv[i].type == M5_AT_PLATFORM) {
auxv[i].val = platform_base;
- initVirtMem.writeString(platform_base, platform.c_str());
+ initVirtMem->writeString(platform_base, platform.c_str());
} else if (auxv[i].type == M5_AT_EXECFN) {
auxv[i].val = aux_data_base;
- initVirtMem.writeString(aux_data_base, filename.c_str());
+ initVirtMem->writeString(aux_data_base, filename.c_str());
} else if (auxv[i].type == M5_AT_RANDOM) {
auxv[i].val = aux_random_base;
// Just leave the value 0, we don't want randomness
//Copy the aux stuff
Addr auxv_array_end = auxv_array_base;
for (const auto &aux: auxv) {
- initVirtMem.write(auxv_array_end, aux, GuestByteOrder);
+ initVirtMem->write(auxv_array_end, aux, GuestByteOrder);
auxv_array_end += sizeof(aux);
}
//Write out the terminating zeroed auxillary vector
const AuxVector<IntType> zero(0, 0);
- initVirtMem.write(auxv_array_end, zero);
+ initVirtMem->write(auxv_array_end, zero);
auxv_array_end += sizeof(zero);
copyStringArray(envp, envp_array_base, env_data_base,
- LittleEndianByteOrder, initVirtMem);
+ LittleEndianByteOrder, *initVirtMem);
copyStringArray(argv, argv_array_base, arg_data_base,
- LittleEndianByteOrder, initVirtMem);
+ LittleEndianByteOrder, *initVirtMem);
- initVirtMem.writeBlob(argc_base, &guestArgc, intSize);
+ initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set the stack pointer register
argc = htole((IntType)argc);
- initVirtMem.writeBlob(memState->getStackMin(), &argc, intSize);
+ initVirtMem->writeBlob(memState->getStackMin(), &argc, intSize);
copyStringArray(argv, argv_array_base, arg_data_base,
- LittleEndianByteOrder, initVirtMem);
+ LittleEndianByteOrder, *initVirtMem);
copyStringArray(envp, envp_array_base, env_data_base,
- LittleEndianByteOrder, initVirtMem);
+ LittleEndianByteOrder, *initVirtMem);
// Copy the aux vector
Addr auxv_array_end = auxv_array_base;
for (const auto &aux: auxv) {
- initVirtMem.write(auxv_array_end, aux, GuestByteOrder);
+ initVirtMem->write(auxv_array_end, aux, GuestByteOrder);
auxv_array_end += sizeof(aux);
}
// Write out the terminating zeroed auxilliary vector
const AuxVector<IntType> zero(0, 0);
- initVirtMem.write(auxv_array_end, zero);
+ initVirtMem->write(auxv_array_end, zero);
auxv_array_end += sizeof(zero);
ThreadContext *tc = system->getThreadContext(contextIds[0]);
uint64_t align = 16;
// load object file into target memory
- image.write(initVirtMem);
- interpImage.write(initVirtMem);
+ image.write(*initVirtMem);
+ interpImage.write(*initVirtMem);
//Setup the auxilliary vectors. These will already have endian conversion.
//Auxilliary vectors are loaded only for elf formatted executables.
//Write out the sentry void *
uint32_t sentry_NULL = 0;
- initVirtMem.writeBlob(sentry_base, &sentry_NULL, sentry_size);
+ initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size);
//Fix up the aux vectors which point to other data
for (int i = auxv.size() - 1; i >= 0; i--) {
if (auxv[i].type == M5_AT_PLATFORM) {
auxv[i].val = platform_base;
- initVirtMem.writeString(platform_base, platform.c_str());
+ initVirtMem->writeString(platform_base, platform.c_str());
} else if (auxv[i].type == M5_AT_EXECFN) {
auxv[i].val = aux_data_base;
- initVirtMem.writeString(aux_data_base, filename.c_str());
+ initVirtMem->writeString(aux_data_base, filename.c_str());
}
}
//Copy the aux stuff
Addr auxv_array_end = auxv_array_base;
for (const auto &aux: auxv) {
- initVirtMem.write(auxv_array_end, aux, GuestByteOrder);
+ initVirtMem->write(auxv_array_end, aux, GuestByteOrder);
auxv_array_end += sizeof(aux);
}
//Write out the terminating zeroed auxilliary vector
const AuxVector<uint64_t> zero(0, 0);
- initVirtMem.write(auxv_array_end, zero);
+ initVirtMem->write(auxv_array_end, zero);
auxv_array_end += sizeof(zero);
copyStringArray(envp, envp_array_base, env_data_base,
- BigEndianByteOrder, initVirtMem);
+ BigEndianByteOrder, *initVirtMem);
copyStringArray(argv, argv_array_base, arg_data_base,
- BigEndianByteOrder, initVirtMem);
+ BigEndianByteOrder, *initVirtMem);
- initVirtMem.writeBlob(argc_base, &guestArgc, intSize);
+ initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
ThreadContext *tc = system->getThreadContext(contextIds[0]);
uint8_t at_random[RandomBytes];
generate(begin(at_random), end(at_random),
[&]{ return random_mt.random(0, 0xFF); });
- initVirtMem.writeBlob(memState->getStackMin(), at_random, RandomBytes);
+ initVirtMem->writeBlob(memState->getStackMin(), at_random, RandomBytes);
// Copy argv to stack
vector<Addr> argPointers;
for (const string& arg: argv) {
memState->setStackMin(memState->getStackMin() - (arg.size() + 1));
- initVirtMem.writeString(memState->getStackMin(), arg.c_str());
+ initVirtMem->writeString(memState->getStackMin(), arg.c_str());
argPointers.push_back(memState->getStackMin());
if (DTRACE(Stack)) {
string wrote;
- initVirtMem.readString(wrote, argPointers.back());
+ initVirtMem->readString(wrote, argPointers.back());
DPRINTFN("Wrote arg \"%s\" to address %p\n",
wrote, (void*)memState->getStackMin());
}
vector<Addr> envPointers;
for (const string& env: envp) {
memState->setStackMin(memState->getStackMin() - (env.size() + 1));
- initVirtMem.writeString(memState->getStackMin(), env.c_str());
+ initVirtMem->writeString(memState->getStackMin(), env.c_str());
envPointers.push_back(memState->getStackMin());
DPRINTF(Stack, "Wrote env \"%s\" to address %p\n",
env, (void*)memState->getStackMin());
Addr sp = memState->getStackMin();
const auto pushOntoStack =
[this, &sp](IntType data) {
- initVirtMem.write(sp, data, GuestByteOrder);
+ initVirtMem->write(sp, data, GuestByteOrder);
sp += sizeof(data);
};
// Write out the sentry void *
uint64_t sentry_NULL = 0;
- initVirtMem.writeBlob(sentry_base, &sentry_NULL, sentry_size);
+ initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size);
// Write the file name
- initVirtMem.writeString(file_name_base, filename.c_str());
+ initVirtMem->writeString(file_name_base, filename.c_str());
// Copy the aux stuff
Addr auxv_array_end = auxv_array_base;
for (const auto &aux: auxv) {
- initVirtMem.write(auxv_array_end, aux, GuestByteOrder);
+ initVirtMem->write(auxv_array_end, aux, GuestByteOrder);
auxv_array_end += sizeof(aux);
}
// Write out the terminating zeroed auxilliary vector
const AuxVector<IntType> zero(0, 0);
- initVirtMem.write(auxv_array_end, zero);
+ initVirtMem->write(auxv_array_end, zero);
auxv_array_end += sizeof(zero);
copyStringArray(envp, envp_array_base, env_data_base,
- BigEndianByteOrder, initVirtMem);
+ BigEndianByteOrder, *initVirtMem);
copyStringArray(argv, argv_array_base, arg_data_base,
- BigEndianByteOrder, initVirtMem);
+ BigEndianByteOrder, *initVirtMem);
- initVirtMem.writeBlob(argc_base, &guestArgc, intSize);
+ initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
// Set up space for the trap handlers into the processes address space.
// Since the stack grows down and there is reserved address space abov
SparcProcess::argsInit<uint64_t>(pageSize);
// Stuff the trap handlers into the process address space
- initVirtMem.writeBlob(fillStart,
+ initVirtMem->writeBlob(fillStart,
fillHandler64, sizeof(MachInst) * numFillInsts);
- initVirtMem.writeBlob(spillStart,
+ initVirtMem->writeBlob(spillStart,
spillHandler64, sizeof(MachInst) * numSpillInsts);
}
SparcProcess::argsInit<uint32_t>(pageSize);
// Stuff the trap handlers into the process address space
- initVirtMem.writeBlob(fillStart,
+ initVirtMem->writeBlob(fillStart,
fillHandler32, sizeof(MachInst) * numFillInsts);
- initVirtMem.writeBlob(spillStart,
+ initVirtMem->writeBlob(spillStart,
spillHandler32, sizeof(MachInst) * numSpillInsts);
}
0x0f,0x05, // syscall
0xc3 // retq
};
- initVirtMem.writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset,
+ initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset,
vtimeBlob, sizeof(vtimeBlob));
uint8_t vgettimeofdayBlob[] = {
0x0f,0x05, // syscall
0xc3 // retq
};
- initVirtMem.writeBlob(vsyscallPage.base + vsyscallPage.vgettimeofdayOffset,
+ initVirtMem->writeBlob(
+ vsyscallPage.base + vsyscallPage.vgettimeofdayOffset,
vgettimeofdayBlob, sizeof(vgettimeofdayBlob));
if (kvmInSE) {
assert(_gdtSize % sizeof(zero) == 0);
for (Addr gdtCurrent = _gdtStart;
gdtCurrent < _gdtStart + _gdtSize; gdtCurrent += sizeof(zero)) {
- initVirtMem.write(gdtCurrent, zero);
+ initVirtMem->write(gdtCurrent, zero);
}
// Set up the vsyscall page for this process.
0x89, 0xe5, // mov %esp, %ebp
0x0f, 0x34 // sysenter
};
- initVirtMem.writeBlob(vsyscallPage.base + vsyscallPage.vsyscallOffset,
+ initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vsyscallOffset,
vsyscallBlob, sizeof(vsyscallBlob));
uint8_t vsysexitBlob[] = {
0x59, // pop %ecx
0xc3 // ret
};
- initVirtMem.writeBlob(vsyscallPage.base + vsyscallPage.vsysexitOffset,
+ initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vsysexitOffset,
vsysexitBlob, sizeof(vsysexitBlob));
for (int i = 0; i < contextIds.size(); i++) {
// Write out the sentry void *
IntType sentry_NULL = 0;
- initVirtMem.writeBlob(sentry_base, &sentry_NULL, sentry_size);
+ initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size);
// Write the file name
- initVirtMem.writeString(file_name_base, filename.c_str());
+ initVirtMem->writeString(file_name_base, filename.c_str());
// Fix up the aux vectors which point to data
assert(auxv[auxv.size() - 3].type == M5_AT_RANDOM);
// Copy the aux stuff
Addr auxv_array_end = auxv_array_base;
for (const auto &aux: auxv) {
- initVirtMem.write(auxv_array_end, aux, GuestByteOrder);
+ initVirtMem->write(auxv_array_end, aux, GuestByteOrder);
auxv_array_end += sizeof(aux);
}
// Write out the terminating zeroed auxiliary vector
const AuxVector<uint64_t> zero(0, 0);
- initVirtMem.write(auxv_array_end, zero);
+ initVirtMem->write(auxv_array_end, zero);
auxv_array_end += sizeof(zero);
- initVirtMem.writeString(aux_data_base, platform.c_str());
+ initVirtMem->writeString(aux_data_base, platform.c_str());
copyStringArray(envp, envp_array_base, env_data_base,
- LittleEndianByteOrder, initVirtMem);
+ LittleEndianByteOrder, *initVirtMem);
copyStringArray(argv, argv_array_base, arg_data_base,
- LittleEndianByteOrder, initVirtMem);
+ LittleEndianByteOrder, *initVirtMem);
- initVirtMem.writeBlob(argc_base, &guestArgc, intSize);
+ initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
ThreadContext *tc = system->getThreadContext(contextIds[0]);
// Set the stack pointer register
virtProxy = new FSTranslatingPortProxy(tc);
} else {
assert(virtProxy == NULL);
- virtProxy = new SETranslatingPortProxy(baseCpu->getSendFunctional(),
- process,
- SETranslatingPortProxy::NextPage);
+ virtProxy = new SETranslatingPortProxy(
+ tc, SETranslatingPortProxy::NextPage);
}
}
Process *getProcessPtr() { return process; }
- void setProcessPtr(Process *p)
- {
- process = p;
- /**
- * When the process pointer changes while operating in SE Mode,
- * the se translating port proxy needs to be reinitialized since it
- * holds a pointer to the process class.
- */
- if (virtProxy) {
- delete virtProxy;
- virtProxy = NULL;
- initMemProxies(NULL);
- }
- }
+ void setProcessPtr(Process *p) { process = p; }
/** Reads the number of instructions functionally executed and
* committed.
#include "mem/fs_translating_port_proxy.hh"
-#include "arch/generic/tlb.hh"
#include "base/chunk_generator.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
{}
bool
-FSTranslatingPortProxy::tryReadBlob(Addr addr, void *p, int size) const
+FSTranslatingPortProxy::tryTLBsOnce(RequestPtr req, BaseTLB::Mode mode) const
{
BaseTLB *dtb = _tc->getDTBPtr();
BaseTLB *itb = _tc->getDTBPtr();
+ return dtb->translateFunctional(req, _tc, mode) == NoFault ||
+ itb->translateFunctional(req, _tc, BaseTLB::Read) == NoFault;
+}
+bool
+FSTranslatingPortProxy::tryTLBs(RequestPtr req, BaseTLB::Mode mode) const
+{
+ // If at first this doesn't succeed, try to fixup and translate again. If
+ // it still fails, report failure.
+ return tryTLBsOnce(req, mode) ||
+ (fixupAddr(req->getVaddr(), mode) && tryTLBsOnce(req, mode));
+}
+
+bool
+FSTranslatingPortProxy::tryReadBlob(Addr addr, void *p, int size) const
+{
for (ChunkGenerator gen(addr, size, pageBytes); !gen.done();
gen.next())
{
auto req = std::make_shared<Request>(
gen.addr(), gen.size(), 0, Request::funcMasterId, 0,
_tc->contextId());
- if (dtb->translateFunctional(req, _tc, BaseTLB::Read) != NoFault &&
- itb->translateFunctional(req, _tc, BaseTLB::Read) != NoFault) {
+
+ if (!tryTLBs(req, BaseTLB::Read))
return false;
- }
PortProxy::readBlobPhys(
req->getPaddr(), req->getFlags(), p, gen.size());
FSTranslatingPortProxy::tryWriteBlob(
Addr addr, const void *p, int size) const
{
- BaseTLB *dtb = _tc->getDTBPtr();
- BaseTLB *itb = _tc->getDTBPtr();
-
for (ChunkGenerator gen(addr, size, pageBytes); !gen.done();
gen.next())
{
auto req = std::make_shared<Request>(
gen.addr(), gen.size(), 0, Request::funcMasterId, 0,
_tc->contextId());
- if (dtb->translateFunctional(req, _tc, BaseTLB::Write) != NoFault &&
- itb->translateFunctional(req, _tc, BaseTLB::Write) != NoFault) {
+
+ if (!tryTLBs(req, BaseTLB::Write))
return false;
- }
PortProxy::writeBlobPhys(
req->getPaddr(), req->getFlags(), p, gen.size());
bool
FSTranslatingPortProxy::tryMemsetBlob(Addr address, uint8_t v, int size) const
{
- BaseTLB *dtb = _tc->getDTBPtr();
- BaseTLB *itb = _tc->getDTBPtr();
-
for (ChunkGenerator gen(address, size, pageBytes); !gen.done();
gen.next())
{
auto req = std::make_shared<Request>(
gen.addr(), gen.size(), 0, Request::funcMasterId, 0,
_tc->contextId());
- if (dtb->translateFunctional(req, _tc, BaseTLB::Write) != NoFault &&
- itb->translateFunctional(req, _tc, BaseTLB::Write) != NoFault) {
+
+ if (!tryTLBs(req, BaseTLB::Write))
return false;
- }
PortProxy::memsetBlobPhys(
req->getPaddr(), req->getFlags(), v, gen.size());
#ifndef __MEM_FS_TRANSLATING_PORT_PROXY_HH__
#define __MEM_FS_TRANSLATING_PORT_PROXY_HH__
+#include "arch/generic/tlb.hh"
#include "mem/port_proxy.hh"
class ThreadContext;
/**
- * A TranslatingPortProxy in FS mode translates a virtual address to a
- * physical address and then calls the read/write functions of the
- * port. If a thread context is provided the address can alway be
- * translated, If not it can only be translated if it is a simple
- * address masking operation (such as alpha super page accesses).
+ * This proxy attempts to translate virtual addresses using the TLBs. If it
+ * fails, subclasses can override the fixupAddr virtual method to try to
+ * recover, and then attempt the translation again. If it still fails then the
+ * access as a whole fails.
*/
class FSTranslatingPortProxy : public PortProxy
{
private:
+ bool tryTLBsOnce(RequestPtr req, BaseTLB::Mode) const;
+ bool tryTLBs(RequestPtr req, BaseTLB::Mode) const;
+
+ protected:
ThreadContext* _tc;
const Addr pageBytes;
+ virtual bool
+ fixupAddr(Addr addr, BaseTLB::Mode mode) const
+ {
+ return false;
+ }
+
public:
FSTranslatingPortProxy(ThreadContext* tc);
#include "mem/se_translating_port_proxy.hh"
-#include <string>
-
-#include "arch/isa_traits.hh"
-#include "base/chunk_generator.hh"
-#include "config/the_isa.hh"
-#include "mem/page_table.hh"
#include "sim/process.hh"
#include "sim/system.hh"
-using namespace TheISA;
-
SETranslatingPortProxy::SETranslatingPortProxy(
- SendFunctionalFunc func, Process *p, AllocType alloc)
- : PortProxy(func, p->system->cacheLineSize()), pTable(p->pTable),
- process(p), allocating(alloc)
-{ }
-SETranslatingPortProxy::SETranslatingPortProxy(MasterPort &port,
- Process *p, AllocType alloc)
- : PortProxy(port, p->system->cacheLineSize()), pTable(p->pTable),
- process(p), allocating(alloc)
-{ }
-
-bool
-SETranslatingPortProxy::tryReadBlob(Addr addr, void *p, int size) const
-{
- int prevSize = 0;
- auto *bytes = static_cast<uint8_t *>(p);
-
- for (ChunkGenerator gen(addr, size, PageBytes); !gen.done(); gen.next()) {
- Addr paddr;
-
- if (!pTable->translate(gen.addr(),paddr))
- return false;
-
- PortProxy::readBlobPhys(paddr, 0, bytes + prevSize, gen.size());
- prevSize += gen.size();
- }
-
- return true;
-}
-
-
-bool
-SETranslatingPortProxy::tryWriteBlob(Addr addr, const void *p, int size) const
-{
- int prevSize = 0;
- auto *bytes = static_cast<const uint8_t *>(p);
-
- for (ChunkGenerator gen(addr, size, PageBytes); !gen.done(); gen.next()) {
- Addr paddr;
-
- if (!pTable->translate(gen.addr(), paddr)) {
- if (allocating == Always) {
- process->allocateMem(roundDown(gen.addr(), PageBytes),
- PageBytes);
- } else if (allocating == NextPage) {
- // check if we've accessed the next page on the stack
- if (!process->fixupStackFault(gen.addr()))
- panic("Page table fault when accessing virtual address %#x "
- "during functional write\n", gen.addr());
- } else {
- return false;
- }
- pTable->translate(gen.addr(), paddr);
- }
-
- PortProxy::writeBlobPhys(paddr, 0, bytes + prevSize, gen.size());
- prevSize += gen.size();
- }
-
- return true;
-}
-
+ ThreadContext *tc, AllocType alloc)
+ : FSTranslatingPortProxy(tc), allocating(alloc)
+{}
bool
-SETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size) const
+SETranslatingPortProxy::fixupAddr(Addr addr, BaseTLB::Mode mode) const
{
- for (ChunkGenerator gen(addr, size, PageBytes); !gen.done(); gen.next()) {
- Addr paddr;
-
- if (!pTable->translate(gen.addr(), paddr)) {
- if (allocating == Always) {
- process->allocateMem(roundDown(gen.addr(), PageBytes),
- PageBytes);
- pTable->translate(gen.addr(), paddr);
- } else {
- return false;
- }
+ auto *process = _tc->getProcessPtr();
+
+ if (mode == BaseTLB::Write) {
+ if (allocating == Always) {
+ process->allocateMem(roundDown(addr, pageBytes), pageBytes);
+ return true;
+ } else if (allocating == NextPage && process->fixupStackFault(addr)) {
+ // We've accessed the next page on the stack.
+ return true;
}
-
- PortProxy::memsetBlobPhys(paddr, 0, val, gen.size());
}
-
- return true;
+ panic("Page table fault when accessing virtual address %#x "
+ "during functional write.", addr);
}
#ifndef __MEM_SE_TRANSLATING_PORT_PROXY_HH__
#define __MEM_SE_TRANSLATING_PORT_PROXY_HH__
-#include "mem/port_proxy.hh"
+#include "mem/fs_translating_port_proxy.hh"
-class EmulationPageTable;
-class Process;
-
-/**
- * @file
- * TranslatingPortProxy Object Declaration for SE.
- *
- * Port proxies are used when non structural entities need access to
- * the memory system. Proxy objects replace the previous
- * FunctionalPort, TranslatingPort and VirtualPort objects, which
- * provided the same functionality as the proxies, but were instances
- * of ports not corresponding to real structural ports of the
- * simulated system. Via the port proxies all the accesses go through
- * an actual port and thus are transparent to a potentially
- * distributed memory and automatically adhere to the memory map of
- * the system.
- */
-class SETranslatingPortProxy : public PortProxy
+class SETranslatingPortProxy : public FSTranslatingPortProxy
{
public:
};
private:
- EmulationPageTable *pTable;
- Process *process;
AllocType allocating;
- public:
- SETranslatingPortProxy(SendFunctionalFunc func,
- Process* p, AllocType alloc);
- SETranslatingPortProxy(MasterPort &port, Process* p, AllocType alloc);
- ~SETranslatingPortProxy() {}
+ protected:
+ bool fixupAddr(Addr addr, BaseTLB::Mode mode) const override;
- void setPageTable(EmulationPageTable *p) { pTable = p; }
- void setProcess(Process *p) { process = p; }
- bool tryReadBlob(Addr addr, void *p, int size) const override;
- bool tryWriteBlob(Addr addr, const void *p, int size) const override;
- bool tryMemsetBlob(Addr addr, uint8_t val, int size) const override;
+ public:
+ SETranslatingPortProxy(ThreadContext *tc, AllocType alloc);
};
#endif // __MEM_SE_TRANSLATING_PORT_PROXY_HH__
kvmInSE(params->kvmInSE),
useForClone(false),
pTable(pTable),
- initVirtMem(system->getSystemPort(), this,
- SETranslatingPortProxy::Always),
objFile(obj_file),
argv(params->cmd), envp(params->env),
executable(params->executable),
*/
delete np->pTable;
np->pTable = pTable;
- auto &proxy = dynamic_cast<SETranslatingPortProxy &>(
- ntc->getVirtProxy());
- proxy.setPageTable(np->pTable);
np->memState = memState;
} else {
pTable->initState();
+ initVirtMem.reset(new SETranslatingPortProxy(
+ tc, SETranslatingPortProxy::Always));
+
// load object file into target memory
- image.write(initVirtMem);
- interpImage.write(initVirtMem);
+ image.write(*initVirtMem);
+ interpImage.write(*initVirtMem);
}
DrainState
#include <inttypes.h>
#include <map>
+#include <memory>
#include <string>
#include <vector>
EmulationPageTable *pTable;
- SETranslatingPortProxy initVirtMem; // memory proxy for initial image load
+ // Memory proxy for initial image load.
+ std::unique_ptr<SETranslatingPortProxy> initVirtMem;
/**
* Each instance of a Loader subclass will have a chance to try to load