diff --git a/src/arch/arm/fastmodel/iris/thread_context.cc b/src/arch/arm/fastmodel/iris/thread_context.cc index 85171fcf8c..516565eb50 100644 --- a/src/arch/arm/fastmodel/iris/thread_context.cc +++ b/src/arch/arm/fastmodel/iris/thread_context.cc @@ -410,8 +410,7 @@ ThreadContext::initMemProxies(::ThreadContext *tc) virtProxy.reset(new FSTranslatingPortProxy(tc)); } else { assert(!virtProxy); - virtProxy.reset(new SETranslatingPortProxy( - _cpu->getSendFunctional(), getProcessPtr(), + virtProxy.reset(new SETranslatingPortProxy(this, SETranslatingPortProxy::NextPage)); } } diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc index 9cfa43127c..3d041eef57 100644 --- a/src/arch/arm/process.cc +++ b/src/arch/arm/process.cc @@ -404,16 +404,16 @@ ArmProcess::argsInit(int pageSize, IntRegIndex spIndex) //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 @@ -423,20 +423,20 @@ ArmProcess::argsInit(int pageSize, IntRegIndex spIndex) //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 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 diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index afeef8bd15..c388087589 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -159,24 +159,24 @@ MipsProcess::argsInit(int pageSize) 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 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]); diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index 3af8788ed4..6ebdd6f2ff 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -93,8 +93,8 @@ PowerProcess::argsInit(int intSize, int pageSize) 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. @@ -227,36 +227,36 @@ PowerProcess::argsInit(int intSize, int pageSize) //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 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]); diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc index 360ff11b67..5feff4353c 100644 --- a/src/arch/riscv/process.cc +++ b/src/arch/riscv/process.cc @@ -155,17 +155,17 @@ RiscvProcess::argsInit(int pageSize) 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 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()); } @@ -176,7 +176,7 @@ RiscvProcess::argsInit(int pageSize) vector 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()); @@ -195,7 +195,7 @@ RiscvProcess::argsInit(int pageSize) Addr sp = memState->getStackMin(); const auto pushOntoStack = [this, &sp](IntType data) { - initVirtMem.write(sp, data, GuestByteOrder); + initVirtMem->write(sp, data, GuestByteOrder); sp += sizeof(data); }; diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index f2d1de2e74..816df4f47e 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -351,29 +351,29 @@ SparcProcess::argsInit(int pageSize) // 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 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 @@ -404,9 +404,9 @@ Sparc64Process::argsInit(int intSize, int pageSize) SparcProcess::argsInit(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); } @@ -416,9 +416,9 @@ Sparc32Process::argsInit(int intSize, int pageSize) SparcProcess::argsInit(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); } diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 04c9db9b9c..f37a5186f8 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -195,7 +195,7 @@ X86_64Process::initState() 0x0f,0x05, // syscall 0xc3 // retq }; - initVirtMem.writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset, + initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset, vtimeBlob, sizeof(vtimeBlob)); uint8_t vgettimeofdayBlob[] = { @@ -203,7 +203,8 @@ X86_64Process::initState() 0x0f,0x05, // syscall 0xc3 // retq }; - initVirtMem.writeBlob(vsyscallPage.base + vsyscallPage.vgettimeofdayOffset, + initVirtMem->writeBlob( + vsyscallPage.base + vsyscallPage.vgettimeofdayOffset, vgettimeofdayBlob, sizeof(vgettimeofdayBlob)); if (kvmInSE) { @@ -635,7 +636,7 @@ I386Process::initState() 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. @@ -647,7 +648,7 @@ I386Process::initState() 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[] = { @@ -656,7 +657,7 @@ I386Process::initState() 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++) { @@ -976,10 +977,10 @@ X86Process::argsInit(int pageSize, // 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); @@ -993,22 +994,22 @@ X86Process::argsInit(int pageSize, // 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 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 diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index a1d5026b08..2210a7628a 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -115,9 +115,8 @@ ThreadState::initMemProxies(ThreadContext *tc) virtProxy = new FSTranslatingPortProxy(tc); } else { assert(virtProxy == NULL); - virtProxy = new SETranslatingPortProxy(baseCpu->getSendFunctional(), - process, - SETranslatingPortProxy::NextPage); + virtProxy = new SETranslatingPortProxy( + tc, SETranslatingPortProxy::NextPage); } } diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index b90015556a..df80cdc4a1 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -105,20 +105,7 @@ struct ThreadState : public Serializable { 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. diff --git a/src/mem/fs_translating_port_proxy.cc b/src/mem/fs_translating_port_proxy.cc index b33be4a555..99a4b8e48d 100644 --- a/src/mem/fs_translating_port_proxy.cc +++ b/src/mem/fs_translating_port_proxy.cc @@ -45,7 +45,6 @@ #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" @@ -58,21 +57,35 @@ FSTranslatingPortProxy::FSTranslatingPortProxy(ThreadContext *tc) : {} 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( 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()); @@ -86,19 +99,15 @@ bool 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( 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()); @@ -110,19 +119,15 @@ FSTranslatingPortProxy::tryWriteBlob( 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( 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()); diff --git a/src/mem/fs_translating_port_proxy.hh b/src/mem/fs_translating_port_proxy.hh index e536a38bce..c3f1bc6ebe 100644 --- a/src/mem/fs_translating_port_proxy.hh +++ b/src/mem/fs_translating_port_proxy.hh @@ -56,23 +56,33 @@ #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); diff --git a/src/mem/se_translating_port_proxy.cc b/src/mem/se_translating_port_proxy.cc index d31f0b448a..8bab243cb8 100644 --- a/src/mem/se_translating_port_proxy.cc +++ b/src/mem/se_translating_port_proxy.cc @@ -40,98 +40,28 @@ #include "mem/se_translating_port_proxy.hh" -#include - -#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) -{ } + ThreadContext *tc, AllocType alloc) + : FSTranslatingPortProxy(tc), allocating(alloc) +{} bool -SETranslatingPortProxy::tryReadBlob(Addr addr, void *p, int size) const +SETranslatingPortProxy::fixupAddr(Addr addr, BaseTLB::Mode mode) const { - int prevSize = 0; - auto *bytes = static_cast(p); + auto *process = _tc->getProcessPtr(); - 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(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); + 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::writeBlobPhys(paddr, 0, bytes + prevSize, gen.size()); - prevSize += gen.size(); } - - return true; -} - - -bool -SETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size) 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; - } - } - - PortProxy::memsetBlobPhys(paddr, 0, val, gen.size()); - } - - return true; + panic("Page table fault when accessing virtual address %#x " + "during functional write.", addr); } diff --git a/src/mem/se_translating_port_proxy.hh b/src/mem/se_translating_port_proxy.hh index ce55ed794c..96e17714cb 100644 --- a/src/mem/se_translating_port_proxy.hh +++ b/src/mem/se_translating_port_proxy.hh @@ -41,26 +41,9 @@ #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: @@ -71,21 +54,13 @@ class SETranslatingPortProxy : public PortProxy }; 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__ diff --git a/src/sim/process.cc b/src/sim/process.cc index 7099832274..ba2a1505aa 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -116,8 +116,6 @@ Process::Process(ProcessParams *params, EmulationPageTable *pTable, 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), @@ -189,9 +187,6 @@ Process::clone(ThreadContext *otc, ThreadContext *ntc, */ delete np->pTable; np->pTable = pTable; - auto &proxy = dynamic_cast( - ntc->getVirtProxy()); - proxy.setPageTable(np->pTable); np->memState = memState; } else { @@ -312,9 +307,12 @@ Process::initState() 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 diff --git a/src/sim/process.hh b/src/sim/process.hh index 35be983b00..7fd3571ec7 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -172,7 +173,8 @@ class Process : public SimObject EmulationPageTable *pTable; - SETranslatingPortProxy initVirtMem; // memory proxy for initial image load + // Memory proxy for initial image load. + std::unique_ptr initVirtMem; /** * Each instance of a Loader subclass will have a chance to try to load