From: Gabe Black Date: Sat, 28 Jan 2012 15:24:01 +0000 (-0800) Subject: Merge with the main repo. X-Git-Tag: stable_2012_06_28~274 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c3d41a2def15cdaf2ac3984315f452dacc6a0884;p=gem5.git Merge with the main repo. --HG-- rename : src/mem/vport.hh => src/mem/fs_translating_port_proxy.hh rename : src/mem/translating_port.cc => src/mem/se_translating_port_proxy.cc rename : src/mem/translating_port.hh => src/mem/se_translating_port_proxy.hh --- c3d41a2def15cdaf2ac3984315f452dacc6a0884 diff --cc src/arch/alpha/linux/system.cc index e662ef9ce,19a2a6ac3..6f3cf6b32 --- a/src/arch/alpha/linux/system.cc +++ b/src/arch/alpha/linux/system.cc @@@ -163,10 -176,10 +175,10 @@@ LinuxAlphaSystem::setDelayLoop(ThreadCo Addr addr = 0; if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { Tick cpuFreq = tc->getCpuPtr()->frequency(); - Tick intrFreq = platform->intrFrequency(); + assert(intrFreq); - VirtualPort *vp; + FSTranslatingPortProxy* vp; - vp = tc->getVirtPort(); + vp = tc->getVirtProxy(); vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988)); } } diff --cc src/arch/alpha/linux/system.hh index 3e4de7b2a,e2fda39a8..5436a27b2 --- a/src/arch/alpha/linux/system.hh +++ b/src/arch/alpha/linux/system.hh @@@ -128,7 -128,12 +128,14 @@@ class LinuxAlphaSystem : public AlphaSy LinuxAlphaSystem(Params *p); ~LinuxAlphaSystem(); + /** + * Initialise the system + */ + virtual void initState(); + void setDelayLoop(ThreadContext *tc); ++ ++ const Params *params() const { return (const Params *)_params; } }; #endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__ diff --cc src/arch/alpha/remote_gdb.cc index 4b285e7ec,cd9c8910d..aaf9ecb3c --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@@ -156,51 -158,51 +156,51 @@@ RemoteGDB::RemoteGDB(System *_system, T bool RemoteGDB::acc(Addr va, size_t len) { -#if !FULL_SYSTEM - panic("acc function needs to be rewritten for SE mode\n"); -#else - Addr last_va; - - va = TruncPage(va); - last_va = RoundPage(va + len); - - do { - if (IsK0Seg(va)) { - if (va < (K0SegBase + pmem->size())) { - DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " - "%#x < K0SEG + size\n", va); + if (FullSystem) { + Addr last_va; + + va = TruncPage(va); + last_va = RoundPage(va + len); + + do { + if (IsK0Seg(va)) { + if (va < (K0SegBase + pmem->size())) { + DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " + "%#x < K0SEG + size\n", va); + return true; + } else { + DPRINTF(GDBAcc, "acc: Mapping invalid %#x " + "> K0SEG + size\n", va); + return false; + } + } + + /** + * This code says that all accesses to palcode (instruction + * and data) are valid since there isn't a va->pa mapping + * because palcode is accessed physically. At some point this + * should probably be cleaned up but there is no easy way to + * do it. + */ + + if (PcPAL(va) || va < 0x10000) return true; - } else { - DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n", - va); + + Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20); + PageTableEntry pte = - kernel_pte_lookup(context->getPhysPort(), ptbr, va); ++ kernel_pte_lookup(context->getPhysProxy(), ptbr, va); + if (!pte.valid()) { + DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); return false; } - } - - /** - * This code says that all accesses to palcode (instruction - * and data) are valid since there isn't a va->pa mapping - * because palcode is accessed physically. At some point this - * should probably be cleaned up but there is no easy way to - * do it. - */ - - if (PcPAL(va) || va < 0x10000) - return true; - - Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20); - PageTableEntry pte = - kernel_pte_lookup(context->getPhysProxy(), ptbr, va); - if (!pte.valid()) { - DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); - return false; - } - va += PageBytes; - } while (va < last_va); + va += PageBytes; + } while (va < last_va); - DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); - return true; -#endif + DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); + return true; + } else { + panic("acc function needs to be rewritten for SE mode\n"); + } } /* diff --cc src/arch/alpha/utility.cc index 0048e43e9,4de77ffd4..efafec4bc --- a/src/arch/alpha/utility.cc +++ b/src/arch/alpha/utility.cc @@@ -30,33 -30,35 +30,33 @@@ */ #include "arch/alpha/utility.hh" - -#if FULL_SYSTEM #include "arch/alpha/vtophys.hh" - #include "mem/vport.hh" + #include "mem/fs_translating_port_proxy.hh" -#endif +#include "sim/full_system.hh" namespace AlphaISA { uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) { -#if FULL_SYSTEM - const int NumArgumentRegs = 6; - if (number < NumArgumentRegs) { - if (fp) - return tc->readFloatRegBits(16 + number); - else - return tc->readIntReg(16 + number); + if (FullSystem) { + const int NumArgumentRegs = 6; + if (number < NumArgumentRegs) { + if (fp) + return tc->readFloatRegBits(16 + number); + else + return tc->readIntReg(16 + number); + } else { + Addr sp = tc->readIntReg(StackPointerReg); - VirtualPort *vp = tc->getVirtPort(); ++ FSTranslatingPortProxy* vp = tc->getVirtProxy(); + uint64_t arg = vp->read(sp + + (number-NumArgumentRegs) * sizeof(uint64_t)); + return arg; + } } else { - Addr sp = tc->readIntReg(StackPointerReg); - FSTranslatingPortProxy* vp = tc->getVirtProxy(); - uint64_t arg = vp->read(sp + - (number-NumArgumentRegs) * sizeof(uint64_t)); - return arg; + panic("getArgument() is Full system only\n"); + M5_DUMMY_RETURN; } -#else - panic("getArgument() is Full system only\n"); - M5_DUMMY_RETURN; -#endif } void diff --cc src/arch/arm/utility.cc index 6c2997a27,98195ab04..42b5be181 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@@ -40,12 -40,15 +40,12 @@@ #include "arch/arm/faults.hh" #include "arch/arm/isa_traits.hh" +#include "arch/arm/tlb.hh" #include "arch/arm/utility.hh" -#include "cpu/thread_context.hh" - -#if FULL_SYSTEM #include "arch/arm/vtophys.hh" +#include "cpu/thread_context.hh" - #include "mem/vport.hh" + #include "mem/fs_translating_port_proxy.hh" -#endif - -#include "arch/arm/tlb.hh" +#include "sim/full_system.hh" namespace ArmISA { @@@ -63,49 -66,49 +63,49 @@@ initCPU(ThreadContext *tc, int cpuId uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) { -#if FULL_SYSTEM - if (size == (uint16_t)(-1)) - size = ArmISA::MachineBytes; - if (fp) - panic("getArgument(): Floating point arguments not implemented\n"); + if (FullSystem) { + if (size == (uint16_t)(-1)) + size = ArmISA::MachineBytes; + if (fp) + panic("getArgument(): Floating point arguments not implemented\n"); - if (number < NumArgumentRegs) { - // If the argument is 64 bits, it must be in an even regiser number - // Increment the number here if it isn't even - if (size == sizeof(uint64_t)) { - if ((number % 2) != 0) - number++; - // Read the two halves of the data - // number is inc here to get the second half of the 64 bit reg - uint64_t tmp; - tmp = tc->readIntReg(number++); - tmp |= tc->readIntReg(number) << 32; - return tmp; + if (number < NumArgumentRegs) { + // If the argument is 64 bits, it must be in an even regiser + // number. Increment the number here if it isn't even. + if (size == sizeof(uint64_t)) { + if ((number % 2) != 0) + number++; + // Read the two halves of the data. Number is inc here to + // get the second half of the 64 bit reg. + uint64_t tmp; + tmp = tc->readIntReg(number++); + tmp |= tc->readIntReg(number) << 32; + return tmp; + } else { + return tc->readIntReg(number); + } } else { - return tc->readIntReg(number); - } - } else { - Addr sp = tc->readIntReg(StackPointerReg); - FSTranslatingPortProxy* vp = tc->getVirtProxy(); - uint64_t arg; - if (size == sizeof(uint64_t)) { - // If the argument is even it must be aligned - if ((number % 2) != 0) + Addr sp = tc->readIntReg(StackPointerReg); - VirtualPort *vp = tc->getVirtPort(); ++ FSTranslatingPortProxy* vp = tc->getVirtProxy(); + uint64_t arg; + if (size == sizeof(uint64_t)) { + // If the argument is even it must be aligned + if ((number % 2) != 0) + number++; + arg = vp->read(sp + + (number-NumArgumentRegs) * sizeof(uint32_t)); + // since two 32 bit args == 1 64 bit arg, increment number number++; - arg = vp->read(sp + - (number-NumArgumentRegs) * sizeof(uint32_t)); - // since two 32 bit args == 1 64 bit arg, increment number - number++; - } else { - arg = vp->read(sp + - (number-NumArgumentRegs) * sizeof(uint32_t)); + } else { + arg = vp->read(sp + + (number-NumArgumentRegs) * sizeof(uint32_t)); + } + return arg; } - return arg; + } else { + panic("getArgument() only implemented for full system mode.\n"); + M5_DUMMY_RETURN } -#else - panic("getArgument() only implemented for FULL_SYSTEM\n"); - M5_DUMMY_RETURN -#endif } void diff --cc src/arch/mips/linux/system.cc index 30e0f95e9,7cfa043e2..f97426f85 --- a/src/arch/mips/linux/system.cc +++ b/src/arch/mips/linux/system.cc @@@ -63,91 -62,91 +63,10 @@@ using namespace Linux LinuxMipsSystem::LinuxMipsSystem(Params *p) : MipsSystem(p) { -- Addr addr = 0; -- -- /** -- * The symbol swapper_pg_dir marks the beginning of the kernel and -- * the location of bootloader passed arguments -- */ -- if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) { -- panic("Could not determine start location of kernel"); -- } -- -- /** -- * Since we aren't using a bootloader, we have to copy the -- * kernel arguments directly into the kernel's memory. -- */ - virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(), - virtPort.writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(), -- params()->boot_osflags.length()+1); -- -- /** -- * find the address of the est_cycle_freq variable and insert it -- * so we don't through the lengthly process of trying to -- * calculated it by using the PIT, RTC, etc. -- */ -- if (kernelSymtab->findAddress("est_cycle_freq", addr)) - virtPort->write(addr, (uint64_t)(SimClock::Frequency / - virtPort.write(addr, (uint64_t)(SimClock::Frequency / -- p->boot_cpu_frequency)); -- -- /** -- * EV5 only supports 127 ASNs so we are going to tell the kernel that the -- * paritiuclar EV6 we have only supports 127 asns. -- * @todo At some point we should change ev5.hh and the palcode to support -- * 255 ASNs. -- */ -- if (kernelSymtab->findAddress("dp264_mv", addr)) - virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127)); - virtPort.write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127)); -- else -- panic("could not find dp264_mv\n"); -- --#ifndef NDEBUG -- kernelPanicEvent = addKernelFuncEvent("panic"); -- if (!kernelPanicEvent) -- panic("could not find kernel symbol \'panic\'"); -- --#endif -- -- /** -- * Any time ide_delay_50ms, calibarte_delay or -- * determine_cpu_caches is called just skip the -- * function. Currently determine_cpu_caches only is used put -- * information in proc, however if that changes in the future we -- * will have to fill in the cache size variables appropriately. -- */ -- -- skipIdeDelay50msEvent = -- addKernelFuncEvent("ide_delay_50ms"); -- skipDelayLoopEvent = -- addKernelFuncEvent("calibrate_delay"); -- skipCacheProbeEvent = -- addKernelFuncEvent("determine_cpu_caches"); -- debugPrintkEvent = addKernelFuncEvent("dprintk"); -- idleStartEvent = addKernelFuncEvent("cpu_idle"); -- -- // Disable for now as it runs into panic() calls in VPTr methods -- // (see sim/vptr.hh). Once those bugs are fixed, we can -- // re-enable, but we should find a better way to turn it on than -- // using DTRACE(Thread), since looking at a trace flag at tick 0 -- // leads to non-intuitive behavior with --trace-start. -- if (false && kernelSymtab->findAddress("mips_switch_to", addr)) { -- printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo", -- addr + sizeof(MachInst) * 6); -- } else { -- printThreadEvent = NULL; -- } } LinuxMipsSystem::~LinuxMipsSystem() { --#ifndef NDEBUG -- delete kernelPanicEvent; --#endif -- delete skipIdeDelay50msEvent; -- delete skipDelayLoopEvent; -- delete skipCacheProbeEvent; -- delete debugPrintkEvent; -- delete idleStartEvent; -- delete printThreadEvent; } diff --cc src/arch/mips/stacktrace.cc index 50f6e1fb0,ced60b88e..d4548b4bb --- a/src/arch/mips/stacktrace.cc +++ b/src/arch/mips/stacktrace.cc @@@ -37,7 -37,6 +37,7 @@@ #include "base/trace.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" - #include "mem/vport.hh" ++#include "mem/fs_translating_port_proxy.hh" #include "sim/system.hh" using namespace std; diff --cc src/arch/mips/system.cc index d367acd64,c1735b740..f0d4c250e --- a/src/arch/mips/system.cc +++ b/src/arch/mips/system.cc @@@ -46,67 -45,70 +45,6 @@@ using namespace LittleEndianGuest MipsSystem::MipsSystem(Params *p) : System(p) { - -#if FULL_SYSTEM -- if (p->bare_iron == true) { -- hexFile = new HexFile(params()->hex_file_name); -- if (!hexFile->loadSections(functionalPort)) -- panic("Could not load hex file\n"); -- } -- -- Addr addr = 0; -- -- consoleSymtab = new SymbolTable; -- -- -- /** -- * Load the console code into memory -- */ -- // Load Console Code -- console = createObjectFile(params()->console); -- -- warn("console code is located at: %s\n", params()->console); -- -- if (console == NULL) -- fatal("Could not load console file %s", params()->console); -- //Load program sections into memory -- console->loadSections(functionalPort, loadAddrMask); -- -- //load symbols -- if (!console->loadGlobalSymbols(consoleSymtab)) -- panic("could not load console symbols\n"); -- -- if (!console->loadGlobalSymbols(debugSymbolTable)) -- panic("could not load console symbols\n"); -- -- --#ifndef NDEBUG -- consolePanicEvent = addConsoleFuncEvent("panic"); --#endif -- -- /** -- * Copy the osflags (kernel arguments) into the consoles -- * memory. (Presently Linux does not use the console service -- * routine to get these command line arguments, but Tru64 and -- * others do.) -- */ -- if (consoleSymtab->findAddress("env_booted_osflags", addr)) { -- warn("writing addr starting from %#x", addr); -- virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(), -- strlen(params()->boot_osflags.c_str())); -- } -- -- /** -- * Set the hardware reset parameter block system type and revision -- * information to Tsunami. -- */ -- if (consoleSymtab->findAddress("m5_rpb", addr)) { -- uint64_t data; -- data = htog(params()->system_type); -- virtPort->write(addr + 0x50, data); -- data = htog(params()->system_rev); -- virtPort->write(addr + 0x58, data); -- } else { -- panic("could not find hwrpb\n"); -- } -#endif } MipsSystem::~MipsSystem() diff --cc src/arch/mips/utility.cc index 1f3b19c7b,fc6e9e2f9..65432b4ea --- a/src/arch/mips/utility.cc +++ b/src/arch/mips/utility.cc @@@ -31,17 -31,20 +31,16 @@@ #include #include "arch/mips/isa_traits.hh" ++#include "arch/mips/registers.hh" #include "arch/mips/utility.hh" ++#include "arch/mips/vtophys.hh" #include "base/bitfield.hh" #include "base/misc.hh" -#include "config/full_system.hh" #include "cpu/static_inst.hh" #include "cpu/thread_context.hh" -#include "sim/serialize.hh" - -#if FULL_SYSTEM -#include "arch/mips/registers.hh" -#include "arch/mips/vtophys.hh" + #include "mem/fs_translating_port_proxy.hh" -#endif +#include "sim/serialize.hh" - #include "arch/mips/registers.hh" - #include "arch/mips/vtophys.hh" - #include "mem/vport.hh" - using namespace MipsISA; using namespace std; diff --cc src/arch/mips/vtophys.cc index c6a317df8,08e1a1e1c..60d9bc1ba --- a/src/arch/mips/vtophys.cc +++ b/src/arch/mips/vtophys.cc @@@ -37,8 -37,7 +37,7 @@@ #include "base/chunk_generator.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" -#include "mem/vport.hh" +#include "debug/VtoPhys.hh" - #include "mem/vport.hh" using namespace std; using namespace MipsISA; diff --cc src/arch/sparc/utility.cc index 63b8e7960,1c9cf552d..74b1b2794 --- a/src/arch/sparc/utility.cc +++ b/src/arch/sparc/utility.cc @@@ -31,8 -31,10 +31,8 @@@ #include "arch/sparc/faults.hh" #include "arch/sparc/utility.hh" -#if FULL_SYSTEM #include "arch/sparc/vtophys.hh" - #include "mem/vport.hh" + #include "mem/fs_translating_port_proxy.hh" -#endif namespace SparcISA { @@@ -46,21 -48,21 +46,21 @@@ uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) { -#if FULL_SYSTEM - const int NumArgumentRegs = 6; - if (number < NumArgumentRegs) { - return tc->readIntReg(8 + number); + if (FullSystem) { + const int NumArgumentRegs = 6; + if (number < NumArgumentRegs) { + return tc->readIntReg(8 + number); + } else { + Addr sp = tc->readIntReg(StackPointerReg); - VirtualPort *vp = tc->getVirtPort(); ++ FSTranslatingPortProxy* vp = tc->getVirtProxy(); + uint64_t arg = vp->read(sp + 92 + + (number-NumArgumentRegs) * sizeof(uint64_t)); + return arg; + } } else { - Addr sp = tc->readIntReg(StackPointerReg); - FSTranslatingPortProxy* vp = tc->getVirtProxy(); - uint64_t arg = vp->read(sp + 92 + - (number-NumArgumentRegs) * sizeof(uint64_t)); - return arg; + panic("getArgument() only implemented for full system\n"); + M5_DUMMY_RETURN } -#else - panic("getArgument() only implemented for FULL_SYSTEM\n"); - M5_DUMMY_RETURN -#endif } void diff --cc src/base/remote_gdb.cc index 021ef3684,1d8256b42..7b38753e2 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@@ -132,9 -138,7 +132,9 @@@ #include "cpu/thread_context.hh" #include "debug/GDBAll.hh" #include "mem/port.hh" - #include "mem/translating_port.hh" - #include "mem/vport.hh" ++#include "mem/fs_translating_port_proxy.hh" + #include "mem/se_translating_port_proxy.hh" +#include "sim/full_system.hh" #include "sim/system.hh" using namespace std; @@@ -460,13 -464,12 +460,13 @@@ BaseRemoteGDB::read(Addr vaddr, size_t DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size); -#if FULL_SYSTEM - FSTranslatingPortProxy *port = context->getVirtProxy(); -#else - SETranslatingPortProxy *port = context->getMemProxy(); -#endif - port->readBlob(vaddr, (uint8_t*)data, size); + if (FullSystem) { - VirtualPort *port = context->getVirtPort(); ++ FSTranslatingPortProxy *port = context->getVirtProxy(); + port->readBlob(vaddr, (uint8_t*)data, size); + } else { - TranslatingPort *port = context->getMemPort(); ++ SETranslatingPortProxy *port = context->getMemProxy(); + port->readBlob(vaddr, (uint8_t*)data, size); + } #if TRACING_ON if (DTRACE(GDBRead)) { @@@ -503,14 -506,15 +503,14 @@@ BaseRemoteGDB::write(Addr vaddr, size_ } else DPRINTFNR("\n"); } -#if FULL_SYSTEM - FSTranslatingPortProxy *port = context->getVirtProxy(); -#else - SETranslatingPortProxy *port = context->getMemProxy(); -#endif - port->writeBlob(vaddr, (uint8_t*)data, size); -#if !FULL_SYSTEM - delete port; -#endif + if (FullSystem) { - VirtualPort *port = context->getVirtPort(); ++ FSTranslatingPortProxy *port = context->getVirtProxy(); + port->writeBlob(vaddr, (uint8_t*)data, size); + } else { - TranslatingPort *port = context->getMemPort(); ++ SETranslatingPortProxy *port = context->getMemProxy(); + port->writeBlob(vaddr, (uint8_t*)data, size); + delete port; + } return true; } diff --cc src/cpu/BaseCPU.py index 50a8501e2,6800b4c91..19464acbc --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@@ -138,12 -152,15 +138,15 @@@ class BaseCPU(MemObject) tracer = Param.InstTracer(default_tracer, "Instruction tracer") - _cached_ports = [] + icache_port = Port("Instruction Port") + dcache_port = Port("Data Port") + _cached_ports = ['icache_port', 'dcache_port'] + - if buildEnv['TARGET_ISA'] in ['x86', 'arm'] and buildEnv['FULL_SYSTEM']: + if buildEnv['TARGET_ISA'] in ['x86', 'arm']: - _cached_ports = ["itb.walker.port", "dtb.walker.port"] + _cached_ports += ["itb.walker.port", "dtb.walker.port"] _uncached_ports = [] - if buildEnv['TARGET_ISA'] == 'x86' and buildEnv['FULL_SYSTEM']: + if buildEnv['TARGET_ISA'] == 'x86': _uncached_ports = ["interrupts.pio", "interrupts.int_port"] def connectCachedPorts(self, bus): diff --cc src/cpu/checker/thread_context.hh index 6c3c50a9c,4eb3eabfd..178ded80e --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@@ -96,14 -97,15 +96,14 @@@ class CheckerThreadContext : public Thr TheISA::Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); } + Process *getProcessPtr() { return actualTC->getProcessPtr(); } + - TranslatingPort *getMemPort() { return actualTC->getMemPort(); } + PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); } - VirtualPort *getVirtPort() - { return actualTC->getVirtPort(); } + FSTranslatingPortProxy* getVirtProxy() + { return actualTC->getVirtProxy(); } -#else - SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); } - FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); } - Process *getProcessPtr() { return actualTC->getProcessPtr(); } -#endif ++ SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); } Status status() const { return actualTC->status(); } diff --cc src/cpu/inorder/cpu.cc index 010bdb512,9614a5df2..5a14e92a7 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@@ -54,12 -53,14 +54,11 @@@ #include "debug/RefCount.hh" #include "debug/SkedCache.hh" #include "debug/Quiesce.hh" - #include "mem/translating_port.hh" #include "params/InOrderCPU.hh" +#include "sim/full_system.hh" #include "sim/process.hh" #include "sim/stat_control.hh" - -#if FULL_SYSTEM -#include "cpu/quiesce_event.hh" #include "sim/system.hh" -#endif #if THE_ISA == ALPHA_ISA #include "arch/alpha/osfpal.hh" @@@ -754,12 -761,14 +753,14 @@@ InOrderCPU::init( for (ThreadID tid = 0; tid < numThreads; ++tid) thread[tid]->inSyscall = true; -#if FULL_SYSTEM - for (ThreadID tid = 0; tid < numThreads; tid++) { - ThreadContext *src_tc = threadContexts[tid]; - TheISA::initCPU(src_tc, src_tc->contextId()); - // Initialise the ThreadContext's memory proxies - thread[tid]->initMemProxies(thread[tid]->getTC()); + if (FullSystem) { + for (ThreadID tid = 0; tid < numThreads; tid++) { + ThreadContext *src_tc = threadContexts[tid]; + TheISA::initCPU(src_tc, src_tc->contextId()); ++ // Initialise the ThreadContext's memory proxies ++ thread[tid]->initMemProxies(thread[tid]->getTC()); + } } -#endif // Clear inSyscall. for (ThreadID tid = 0; tid < numThreads; ++tid) @@@ -860,7 -870,7 +861,6 @@@ InOrderCPU::getInterrupts( return interrupts->getInterrupt(threadContexts[0]); } -- void InOrderCPU::processInterrupts(Fault interrupt) { @@@ -879,16 -889,8 +879,6 @@@ trap(interrupt, threadContexts[0]->contextId(), dummyBufferInst); } - void - InOrderCPU::updateMemPorts() - { - // Update all ThreadContext's memory ports (Functional/Virtual - // Ports) - ThreadID size = thread.size(); - for (ThreadID i = 0; i < size; ++i) - thread[i]->connectMemPorts(thread[i]->getTC()); - } -#endif -- void InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay) { diff --cc src/cpu/inorder/thread_context.cc index 5f141a1b3,82e681f04..acfcf0939 --- a/src/cpu/inorder/thread_context.cc +++ b/src/cpu/inorder/thread_context.cc @@@ -38,12 -37,15 +38,12 @@@ using namespace TheISA; - VirtualPort * - InOrderThreadContext::getVirtPort() -#if FULL_SYSTEM - + FSTranslatingPortProxy* + InOrderThreadContext::getVirtProxy() { - return thread->getVirtPort(); + return thread->getVirtProxy(); } - void InOrderThreadContext::dumpFuncProfile() { diff --cc src/cpu/inorder/thread_context.hh index 84d62137e,5b67d7e8b..7fe0fb5ef --- a/src/cpu/inorder/thread_context.hh +++ b/src/cpu/inorder/thread_context.hh @@@ -141,15 -146,13 +145,12 @@@ class InOrderThreadContext : public Thr { return this->thread->quiesceEvent; } -#else + + SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); } + /** Returns a pointer to this thread's process. */ Process *getProcessPtr() { return thread->getProcessPtr(); } -#endif - TranslatingPort *getMemPort() { return thread->getMemPort(); } - - VirtualPort *getVirtPort(); - FunctionalPort *getPhysPort() { return thread->getPhysPort(); } - /** Returns this thread's status. */ Status status() const { return thread->status(); } diff --cc src/cpu/o3/cpu.cc index 5d3af6c70,7e0b4cee7..ef08c96f4 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@@ -215,7 -269,10 +266,8 @@@ FullO3CPU::FullO3CPU(DerivO3CPUPa if (params->checker) { BaseCPU *temp_checker = params->checker; checker = dynamic_cast *>(temp_checker); + checker->setIcachePort(&icachePort); -#if FULL_SYSTEM checker->setSystem(params->system); -#endif } else { checker = NULL; } @@@ -600,12 -658,21 +652,21 @@@ FullO3CPU::init( for (ThreadID tid = 0; tid < numThreads; ++tid) thread[tid]->inSyscall = true; + // this CPU could still be unconnected if we are restoring from a + // checkpoint and this CPU is to be switched in, thus we can only + // do this here if the instruction port is actually connected, if + // not we have to do it as part of takeOverFrom + if (icachePort.isConnected()) + fetch.setIcache(); + -#if FULL_SYSTEM - for (ThreadID tid = 0; tid < numThreads; tid++) { - ThreadContext *src_tc = threadContexts[tid]; - TheISA::initCPU(src_tc, src_tc->contextId()); - // Initialise the ThreadContext's memory proxies - thread[tid]->initMemProxies(thread[tid]->getTC()); + if (FullSystem) { + for (ThreadID tid = 0; tid < numThreads; tid++) { + ThreadContext *src_tc = threadContexts[tid]; + TheISA::initCPU(src_tc, src_tc->contextId()); ++ // Initialise the ThreadContext's memory proxies ++ thread[tid]->initMemProxies(thread[tid]->getTC()); + } } -#endif // Clear inSyscall. for (int tid = 0; tid < numThreads; ++tid) @@@ -967,17 -1035,8 +1028,6 @@@ FullO3CPU::processInterrupts(Faul this->trap(interrupt, 0, NULL); } - template - void - FullO3CPU::updateMemPorts() - { - // Update all ThreadContext's memory ports (Functional/Virtual - // Ports) - ThreadID size = thread.size(); - for (ThreadID i = 0; i < size; ++i) - thread[i]->connectMemPorts(thread[i]->getTC()); - } -#endif -- template void FullO3CPU::trap(Fault fault, ThreadID tid, StaticInstPtr inst) diff --cc src/cpu/o3/thread_context.hh index 815c9cb64,6ac745770..ff6ca0093 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@@ -96,18 -97,19 +96,19 @@@ class O3ThreadContext : public ThreadCo virtual TheISA::Kernel::Statistics *getKernelStats() { return thread->kernelStats; } - virtual void connectMemPorts(ThreadContext *tc) - { thread->connectMemPorts(tc); } - + /** Returns a pointer to this thread's process. */ + virtual Process *getProcessPtr() { return thread->getProcessPtr(); } + - virtual TranslatingPort *getMemPort() { return thread->getMemPort(); } + virtual PortProxy* getPhysProxy() { return thread->getPhysProxy(); } + + virtual FSTranslatingPortProxy* getVirtProxy(); - virtual VirtualPort *getVirtPort(); + virtual void initMemProxies(ThreadContext *tc) + { thread->initMemProxies(tc); } -#else + - virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); } + virtual SETranslatingPortProxy* getMemProxy() + { return thread->getMemProxy(); } - /** Returns a pointer to this thread's process. */ - virtual Process *getProcessPtr() { return thread->getProcessPtr(); } -#endif /** Returns this thread's status. */ virtual Status status() const { return thread->status(); } diff --cc src/cpu/o3/thread_context_impl.hh index 15fc397dc,4c2fee22d..5ba454458 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@@ -48,11 -47,12 +48,11 @@@ #include "cpu/quiesce_event.hh" #include "debug/O3CPU.hh" -#if FULL_SYSTEM template - VirtualPort * - O3ThreadContext::getVirtPort() + FSTranslatingPortProxy* + O3ThreadContext::getVirtProxy() { - return thread->getVirtPort(); + return thread->getVirtProxy(); } template diff --cc src/cpu/ozone/cpu.hh index 36df58ab5,541fea44c..ff43ad6cb --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@@ -112,14 -124,15 +112,14 @@@ class OzoneCPU : public BaseCP TheISA::Kernel::Statistics *getKernelStats() { return thread->getKernelStats(); } + Process *getProcessPtr() { return thread->getProcessPtr(); } + - TranslatingPort *getMemPort() { return thread->getMemPort(); } + PortProxy* getPhysProxy() { return thread->getPhysProxy(); } - VirtualPort *getVirtPort() - { return thread->getVirtPort(); } + FSTranslatingPortProxy* getVirtProxy() + { return thread->getVirtProxy(); } -#else - SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); } - FunctionalPort *getPhysPort() { return thread->getPhysPort(); } - Process *getProcessPtr() { return thread->getProcessPtr(); } -#endif ++ SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); } Status status() const { return thread->status(); } diff --cc src/cpu/ozone/cpu_impl.hh index e2f5dc10c,273d46bdc..f532078fe --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@@ -186,25 -194,9 +186,7 @@@ OzoneCPU::OzoneCPU(Params *p frontEnd->renameTable.copyFrom(thread.renameTable); backEnd->renameTable.copyFrom(thread.renameTable); - if (FullSystem) { - Port *mem_port; - FunctionalPort *phys_port; - VirtualPort *virt_port; - phys_port = new FunctionalPort(csprintf("%s-%d-funcport", - name(), 0)); - mem_port = system->physmem->getPort("functional"); - mem_port->setPeer(phys_port); - phys_port->setPeer(mem_port); - - virt_port = new VirtualPort(csprintf("%s-%d-vport", - name(), 0)); - mem_port = system->physmem->getPort("functional"); - mem_port->setPeer(virt_port); - virt_port->setPeer(mem_port); - - thread.setPhysPort(phys_port); - thread.setVirtPort(virt_port); - } -#if FULL_SYSTEM + thread.connectMemPorts(tc); -#endif DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n"); } diff --cc src/cpu/simple/atomic.cc index fed94ffd8,425c8b1f1..2c12b244b --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@@ -84,18 -83,20 +84,20 @@@ voi AtomicSimpleCPU::init() { BaseCPU::init(); -#if FULL_SYSTEM - ThreadID size = threadContexts.size(); - for (ThreadID i = 0; i < size; ++i) { - ThreadContext *tc = threadContexts[i]; - - // initialize CPU, including PC - TheISA::initCPU(tc, tc->contextId()); + if (FullSystem) { + ThreadID size = threadContexts.size(); + for (ThreadID i = 0; i < size; ++i) { + ThreadContext *tc = threadContexts[i]; + // initialize CPU, including PC + TheISA::initCPU(tc, tc->contextId()); + } } + + // Initialise the ThreadContext's memory proxies + tcBase()->initMemProxies(tcBase()); -#endif ++ if (hasPhysMemPort) { - bool snoop = false; - AddrRangeList pmAddrList; - physmemPort.getPeerAddressRanges(pmAddrList, snoop); + AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges(); physMemAddr = *pmAddrList.begin(); } // Atomic doesn't do MT right now, so contextId == threadId diff --cc src/cpu/simple/timing.cc index 983672c27,f8d13efd9..fd02e8300 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@@ -75,27 -74,17 +75,16 @@@ voi TimingSimpleCPU::init() { BaseCPU::init(); -#if FULL_SYSTEM - for (int i = 0; i < threadContexts.size(); ++i) { - ThreadContext *tc = threadContexts[i]; - - // initialize CPU, including PC - TheISA::initCPU(tc, _cpuId); + if (FullSystem) { + for (int i = 0; i < threadContexts.size(); ++i) { + ThreadContext *tc = threadContexts[i]; + // initialize CPU, including PC + TheISA::initCPU(tc, _cpuId); + } } - } - - Tick - TimingSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt) - { - panic("TimingSimpleCPU doesn't expect recvAtomic callback!"); - return curTick(); - } - void - TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt) - { - //No internal storage to update, jusst return - return; + // Initialise the ThreadContext's memory proxies + tcBase()->initMemProxies(tcBase()); -#endif } void diff --cc src/cpu/simple_thread.cc index edde884e7,2541bdee1..a12ab8e8a --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@@ -41,20 -48,16 +41,21 @@@ #include "base/cprintf.hh" #include "base/output.hh" #include "base/trace.hh" +#include "config/the_isa.hh" +#include "cpu/base.hh" #include "cpu/profile.hh" #include "cpu/quiesce_event.hh" +#include "cpu/simple_thread.hh" +#include "cpu/thread_context.hh" - #include "mem/translating_port.hh" - #include "mem/vport.hh" +#include "params/BaseCPU.hh" + #include "mem/fs_translating_port_proxy.hh" ++#include "mem/se_translating_port_proxy.hh" +#include "sim/full_system.hh" +#include "sim/process.hh" #include "sim/serialize.hh" #include "sim/sim_exit.hh" -#else -#include "mem/se_translating_port_proxy.hh" + #include "sim/process.hh" #include "sim/system.hh" -#endif using namespace std; diff --cc src/cpu/simple_thread.hh index ffa89a967,ebc23276a..f2132dc36 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@@ -57,9 -55,11 +57,8 @@@ class BaseCPU class FunctionProfile; class ProfileNode; --class FunctionalPort; class PhysicalPort; +class TranslatingPort; namespace TheISA { namespace Kernel { @@@ -195,13 -207,15 +194,13 @@@ class SimpleThread : public ThreadStat System *getSystemPtr() { return system; } - FunctionalPort *getPhysPort() { return physPort; } -#if FULL_SYSTEM + PortProxy* getPhysProxy() { return physProxy; } /** Return a virtual port. This port cannot be cached locally in an object. * After a CPU switch it may point to the wrong memory object which could * mean stale data. */ - VirtualPort *getVirtPort() { return virtPort; } + FSTranslatingPortProxy* getVirtProxy() { return virtProxy; } -#endif Status status() const { return _status; } diff --cc src/cpu/thread_context.hh index f7879ea60,d80d26e3d..261ace7cf --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@@ -124,17 -125,25 +124,23 @@@ class ThreadContex virtual System *getSystemPtr() = 0; -#if FULL_SYSTEM virtual TheISA::Kernel::Statistics *getKernelStats() = 0; - virtual void connectMemPorts(ThreadContext *tc) = 0; + virtual PortProxy* getPhysProxy() = 0; - virtual Process *getProcessPtr() = 0; + virtual FSTranslatingPortProxy* getVirtProxy() = 0; - virtual TranslatingPort *getMemPort() = 0; + /** + * Initialise the physical and virtual port proxies and tie them to + * the data port of the CPU. + * + * tc ThreadContext for the virtual-to-physical translation + */ + virtual void initMemProxies(ThreadContext *tc) = 0; -#else + - virtual VirtualPort *getVirtPort() = 0; + virtual SETranslatingPortProxy *getMemProxy() = 0; - virtual FunctionalPort *getPhysPort() = 0; + virtual Process *getProcessPtr() = 0; -#endif virtual Status status() const = 0; @@@ -288,15 -303,17 +294,15 @@@ class ProxyThreadContext : public Threa TheISA::Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); } - void connectMemPorts(ThreadContext *tc) { actualTC->connectMemPorts(tc); } + PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); } - Process *getProcessPtr() { return actualTC->getProcessPtr(); } + FSTranslatingPortProxy* getVirtProxy() { return actualTC->getVirtProxy(); } - TranslatingPort *getMemPort() { return actualTC->getMemPort(); } + void initMemProxies(ThreadContext *tc) { actualTC->initMemProxies(tc); } -#else + - VirtualPort *getVirtPort() { return actualTC->getVirtPort(); } + SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); } - FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); } + Process *getProcessPtr() { return actualTC->getProcessPtr(); } -#endif Status status() const { return actualTC->status(); } diff --cc src/cpu/thread_state.cc index ef81271a8,6c9bb99ea..574be7b6d --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@@ -32,29 -31,49 +32,33 @@@ #include "base/output.hh" #include "cpu/base.hh" #include "cpu/profile.hh" +#include "cpu/quiesce_event.hh" #include "cpu/thread_state.hh" ++#include "mem/fs_translating_port_proxy.hh" +#include "mem/port.hh" - #include "mem/translating_port.hh" - #include "mem/vport.hh" + #include "mem/port_proxy.hh" + #include "mem/se_translating_port_proxy.hh" +#include "sim/full_system.hh" #include "sim/serialize.hh" + #include "sim/system.hh" -#if FULL_SYSTEM -#include "arch/kernel_stats.hh" -#include "cpu/quiesce_event.hh" -#include "mem/fs_translating_port_proxy.hh" -#endif - -#if FULL_SYSTEM -ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid) -#else ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid, Process *_process) -#endif : numInst(0), numLoad(0), _status(ThreadContext::Halted), baseCpu(cpu), _threadId(_tid), lastActivate(0), lastSuspend(0), -#if FULL_SYSTEM profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL), - kernelStats(NULL), process(_process), port(NULL), virtPort(NULL), - physPort(NULL), funcExeInst(0), storeCondFailures(0) - kernelStats(NULL), physProxy(NULL), virtProxy(NULL), -#else - proxy(NULL), process(_process), -#endif - funcExeInst(0), storeCondFailures(0) ++ kernelStats(NULL), process(_process), physProxy(NULL), virtProxy(NULL), ++ proxy(NULL), funcExeInst(0), storeCondFailures(0) { } ThreadState::~ThreadState() { - if (port) { - delete port->getPeer(); - delete port; - } -#if FULL_SYSTEM - if (physProxy != NULL) { ++ if (physProxy != NULL) + delete physProxy; - } - if (virtProxy != NULL) { ++ if (virtProxy != NULL) + delete virtProxy; - } -#else - if (proxy != NULL) { ++ if (proxy != NULL) + delete proxy; - } -#endif } void @@@ -82,49 -101,28 +86,27 @@@ ThreadState::unserialize(Checkpoint *cp // thread_num and cpu_id are deterministic from the config UNSERIALIZE_SCALAR(funcExeInst); -#if FULL_SYSTEM - Tick quiesceEndTick; - UNSERIALIZE_SCALAR(quiesceEndTick); - if (quiesceEndTick) - baseCpu->schedule(quiesceEvent, quiesceEndTick); - if (kernelStats) - kernelStats->unserialize(cp, section); -#endif + if (FullSystem) { + Tick quiesceEndTick; + UNSERIALIZE_SCALAR(quiesceEndTick); + if (quiesceEndTick) + baseCpu->schedule(quiesceEvent, quiesceEndTick); + if (kernelStats) + kernelStats->unserialize(cp, section); + } } -#if FULL_SYSTEM void - ThreadState::connectPhysPort() - { - // @todo: For now this disregards any older port that may have - // already existed. Fix this memory leak once the bus port IDs - // for functional ports is resolved. - if (physPort) - physPort->removeConn(); - else - physPort = new FunctionalPort(csprintf("%s-%d-funcport", - baseCpu->name(), _threadId)); - connectToMemFunc(physPort); - } - - void - ThreadState::connectVirtPort(ThreadContext *tc) - { - // @todo: For now this disregards any older port that may have - // already existed. Fix this memory leak once the bus port IDs - // for functional ports is resolved. - if (virtPort) - virtPort->removeConn(); - else - virtPort = new VirtualPort(csprintf("%s-%d-vport", - baseCpu->name(), _threadId), tc); - connectToMemFunc(virtPort); - } - - void - ThreadState::connectMemPorts(ThreadContext *tc) + ThreadState::initMemProxies(ThreadContext *tc) { - connectPhysPort(); - connectVirtPort(tc); + // Note that this only refers to the port on the CPU side and can + // safely be done at init() time even if the CPU is not connected + // (i.e. due to restoring from a checkpoint and later switching + // in. + if (physProxy == NULL) + physProxy = new PortProxy(*baseCpu->getPort("dcache_port")); + if (virtProxy == NULL) + virtProxy = new FSTranslatingPortProxy(tc); } void @@@ -141,35 -139,18 +123,16 @@@ ThreadState::profileSample( profile->sample(profileNode, profilePC); } - TranslatingPort * - ThreadState::getMemPort() -#else + SETranslatingPortProxy * + ThreadState::getMemProxy() { - if (port != NULL) - return port; - - /* Use this port to for syscall emulation writes to memory. */ - port = new TranslatingPort(csprintf("%s-%d-funcport", baseCpu->name(), - _threadId), process, TranslatingPort::NextPage); - - connectToMemFunc(port); - - return port; - } - - void - ThreadState::connectToMemFunc(Port *port) - { - Port *dcache_port, *func_mem_port; - - dcache_port = baseCpu->getPort("dcache_port"); - assert(dcache_port != NULL); - - MemObject *mem_object = dcache_port->getPeer()->getOwner(); - assert(mem_object != NULL); + if (proxy != NULL) + return proxy; - func_mem_port = mem_object->getPort("functional"); - assert(func_mem_port != NULL); + /* Use this port proxy to for syscall emulation writes to memory. */ + proxy = new SETranslatingPortProxy(*process->system->getSystemPort(), + process, + SETranslatingPortProxy::NextPage); - func_mem_port->setPeer(port); - port->setPeer(func_mem_port); + return proxy; } -#endif diff --cc src/cpu/thread_state.hh index 972ca895d,a007567c1..30bb64ed7 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@@ -47,10 -51,12 +47,11 @@@ namespace TheISA class Statistics; }; }; -#endif class Checkpoint; - class Port; - class TranslatingPort; + class PortProxy; + class SETranslatingPort; + class FSTranslatingPort; /** * Struct for holding general thread state that is needed across CPU @@@ -83,11 -93,14 +84,13 @@@ struct ThreadState Tick readLastSuspend() { return lastSuspend; } - void connectPhysPort(); - - void connectVirtPort(ThreadContext *tc); - - void connectMemPorts(ThreadContext *tc); -#if FULL_SYSTEM + /** + * Initialise the physical and virtual port proxies and tie them to + * the data port of the CPU. + * + * tc ThreadContext for the virtual-to-physical translation + */ + void initMemProxies(ThreadContext *tc); void dumpFuncProfile(); @@@ -99,17 -112,14 +102,13 @@@ TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; } - Process *getProcessPtr() { return process; } - - TranslatingPort *getMemPort(); + PortProxy* getPhysProxy() { return physProxy; } - void setMemPort(TranslatingPort *_port) { port = _port; } + FSTranslatingPortProxy* getVirtProxy() { return virtProxy; } -#else + - VirtualPort *getVirtPort() { return virtPort; } - - FunctionalPort *getPhysPort() { return physPort; } + Process *getProcessPtr() { return process; } - void setPhysPort(FunctionalPort *port) { physPort = port; } + SETranslatingPortProxy* getMemProxy(); -#endif /** Reads the number of instructions functionally executed and * committed. @@@ -173,20 -181,20 +169,19 @@@ EndQuiesceEvent *quiesceEvent; TheISA::Kernel::Statistics *kernelStats; + protected: + Process *process; + - TranslatingPort *port; - - /** A functional port, outgoing only, for functional accesse to virtual - * addresses. */ - VirtualPort *virtPort; - - /** A functional port outgoing only for functional accesses to physical + /** A port proxy outgoing only for functional accesses to physical * addresses.*/ - FunctionalPort *physPort; + PortProxy *physProxy; + + /** A translating port proxy, outgoing only, for functional + * accesse to virtual addresses. */ + FSTranslatingPortProxy* virtProxy; -#else + SETranslatingPortProxy* proxy; - Process *process; -#endif - public: /* * number of executed instructions, for matching with syscall trace diff --cc src/dev/Pci.py index 2f9f93a59,9c2f27142..95cb3916f --- a/src/dev/Pci.py +++ b/src/dev/Pci.py @@@ -42,8 -41,7 +42,8 @@@ class PciConfigAll(PioDevice) class PciDevice(DmaDevice): type = 'PciDevice' abstract = True + platform = Param.Platform(Parent.any, "Platform this device is part of.") - config = Port(Self.pio.peerObj.port, "PCI configuration space port") + config = Port("PCI configuration space port") pci_bus = Param.Int("PCI bus") pci_dev = Param.Int("PCI device number") pci_func = Param.Int("PCI function code") diff --cc src/mem/SConscript index 8418a4f51,dafc8c4a2..09cc93c77 --- a/src/mem/SConscript +++ b/src/mem/SConscript @@@ -41,14 -40,18 +41,14 @@@ Source('mport.cc' Source('packet.cc') Source('port.cc') Source('tport.cc') - Source('vport.cc') -Source('mport.cc') ++Source('fs_translating_port_proxy.cc') ++Source('se_translating_port_proxy.cc') if env['TARGET_ISA'] != 'no': SimObject('PhysicalMemory.py') Source('dram.cc') - Source('physical.cc') - -if env['FULL_SYSTEM']: - Source('fs_translating_port_proxy.cc') -elif env['TARGET_ISA'] != 'no': Source('page_table.cc') - Source('se_translating_port_proxy.cc') + Source('physical.cc') - Source('translating_port.cc') DebugFlag('Bus') DebugFlag('BusAddrRanges') diff --cc src/mem/se_translating_port_proxy.cc index 000000000,027930287..0f7ecb491 mode 000000,100644..100644 --- a/src/mem/se_translating_port_proxy.cc +++ b/src/mem/se_translating_port_proxy.cc @@@ -1,0 -1,211 +1,212 @@@ + /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ron Dreslinski + * Steve Reinhardt + * Andreas Hansson + */ + + #include + ++#include "arch/isa_traits.hh" + #include "base/chunk_generator.hh" + #include "config/the_isa.hh" + #include "mem/page_table.hh" + #include "mem/se_translating_port_proxy.hh" + #include "sim/process.hh" + + using namespace TheISA; + + SETranslatingPortProxy::SETranslatingPortProxy(Port& port, Process *p, + AllocType alloc) + : PortProxy(port), pTable(p->pTable), process(p), + allocating(alloc) + { } + + SETranslatingPortProxy::~SETranslatingPortProxy() + { } + + bool + SETranslatingPortProxy::tryReadBlob(Addr addr, uint8_t *p, int size) + { - Addr paddr; + int prevSize = 0; + + for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) { ++ Addr paddr; + + if (!pTable->translate(gen.addr(),paddr)) + return false; + + PortProxy::readBlob(paddr, p + prevSize, gen.size()); + prevSize += gen.size(); + } + + return true; + } + + void + SETranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size) + { + if (!tryReadBlob(addr, p, size)) + fatal("readBlob(0x%x, ...) failed", addr); + } + + + bool + SETranslatingPortProxy::tryWriteBlob(Addr addr, uint8_t *p, int size) + { - - Addr paddr; + int prevSize = 0; + + for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) { ++ Addr paddr; + + if (!pTable->translate(gen.addr(), paddr)) { + if (allocating == Always) { + process->allocateMem(roundDown(gen.addr(), VMPageSize), + VMPageSize); + } 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::writeBlob(paddr, p + prevSize, gen.size()); + prevSize += gen.size(); + } + + return true; + } + + + void + SETranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size) + { + if (!tryWriteBlob(addr, p, size)) + fatal("writeBlob(0x%x, ...) failed", addr); + } + + bool + SETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size) + { - Addr paddr; - + for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) { ++ Addr paddr; + + if (!pTable->translate(gen.addr(), paddr)) { + if (allocating == Always) { + process->allocateMem(roundDown(gen.addr(), VMPageSize), + VMPageSize); + pTable->translate(gen.addr(), paddr); + } else { + return false; + } + } + + PortProxy::memsetBlob(paddr, val, gen.size()); + } + + return true; + } + + void + SETranslatingPortProxy::memsetBlob(Addr addr, uint8_t val, int size) + { + if (!tryMemsetBlob(addr, val, size)) + fatal("memsetBlob(0x%x, ...) failed", addr); + } + + + bool + SETranslatingPortProxy::tryWriteString(Addr addr, const char *str) + { - Addr paddr,vaddr; + uint8_t c; + - vaddr = addr; ++ Addr vaddr = addr; + + do { + c = *str++; - if (!pTable->translate(vaddr++,paddr)) ++ Addr paddr; ++ ++ if (!pTable->translate(vaddr++, paddr)) + return false; + + PortProxy::writeBlob(paddr, &c, 1); + } while (c); + + return true; + } + + void + SETranslatingPortProxy::writeString(Addr addr, const char *str) + { + if (!tryWriteString(addr, str)) + fatal("writeString(0x%x, ...) failed", addr); + } + + bool + SETranslatingPortProxy::tryReadString(std::string &str, Addr addr) + { - Addr paddr,vaddr; + uint8_t c; + - vaddr = addr; ++ Addr vaddr = addr; + + do { - if (!pTable->translate(vaddr++,paddr)) ++ Addr paddr; ++ ++ if (!pTable->translate(vaddr++, paddr)) + return false; + + PortProxy::readBlob(paddr, &c, 1); + str += c; + } while (c); + + return true; + } + + void + SETranslatingPortProxy::readString(std::string &str, Addr addr) + { + if (!tryReadString(str, addr)) + fatal("readString(0x%x, ...) failed", addr); + } + diff --cc src/sim/process_impl.hh index 944c55ec0,b1b14d0f3..401e16f52 --- a/src/sim/process_impl.hh +++ b/src/sim/process_impl.hh @@@ -57,7 -66,10 +57,7 @@@ copyStringArray(std::vectorwriteBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType)); + memProxy->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType)); } - -#endif // !FULL_SYSTEM - #endif diff --cc src/sim/syscall_emul.hh index 5c480272d,7ea383b29..45c87f0ab --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@@ -62,10 -62,9 +62,10 @@@ #include "cpu/thread_context.hh" #include "debug/SyscallVerbose.hh" #include "mem/page_table.hh" - #include "mem/translating_port.hh" + #include "mem/se_translating_port_proxy.hh" #include "sim/byteswap.hh" #include "sim/process.hh" +#include "sim/syscallreturn.hh" #include "sim/system.hh" /// diff --cc src/sim/system.cc index d3bee1ad1,35e6da109..14c44d063 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@@ -56,16 -56,20 +56,16 @@@ #include "cpu/thread_context.hh" #include "debug/Loader.hh" #include "debug/WorkItems.hh" +#include "kern/kernel_stats.hh" ++#include "mem/fs_translating_port_proxy.hh" #include "mem/mem_object.hh" #include "mem/physical.hh" - #include "mem/vport.hh" +#include "params/System.hh" #include "sim/byteswap.hh" #include "sim/debug.hh" +#include "sim/full_system.hh" #include "sim/system.hh" -#if FULL_SYSTEM -#include "arch/vtophys.hh" -#include "kern/kernel_stats.hh" -#include "mem/fs_translating_port_proxy.hh" -#else -#include "params/System.hh" -#endif - using namespace std; using namespace TheISA; @@@ -74,10 -78,16 +74,12 @@@ vector System::systemList int System::numSystemsRunning = 0; System::System(Params *p) - : SimObject(p), physmem(p->physmem), _numContexts(0), pagePtr(0), + : MemObject(p), _systemPort("system_port", this), + physmem(p->physmem), + _numContexts(0), -#if FULL_SYSTEM init_param(p->init_param), loadAddrMask(p->load_addr_mask), -#else - pagePtr(0), nextPID(0), -#endif memoryMode(p->mem_mode), workItemsBegin(0), workItemsEnd(0), @@@ -99,73 -109,17 +101,17 @@@ p->memories[x]->size())); } -#if FULL_SYSTEM - kernelSymtab = new SymbolTable; - if (!debugSymbolTable) - debugSymbolTable = new SymbolTable; + if (FullSystem) { + kernelSymtab = new SymbolTable; + if (!debugSymbolTable) + debugSymbolTable = new SymbolTable; - - /** - * Get a port proxy to memory - */ - physProxy = new PortProxy(*getSystemPort()); - virtProxy = new FSTranslatingPortProxy(*getSystemPort()); -#endif + /** - * Get a functional port to memory - */ - Port *mem_port; - functionalPort = new FunctionalPort(name() + "-fport"); - mem_port = physmem->getPort("functional"); - functionalPort->setPeer(mem_port); - mem_port->setPeer(functionalPort); - - virtPort = new VirtualPort(name() + "-fport"); - mem_port = physmem->getPort("functional"); - virtPort->setPeer(mem_port); - mem_port->setPeer(virtPort); - - - /** - * Load the kernel code into memory ++ * Get a port proxy to memory + */ - if (params()->kernel == "") { - inform("No kernel set for full system simulation. " - "Assuming you know what you're doing...\n"); - } else { - // Load kernel code - kernel = createObjectFile(params()->kernel); - inform("kernel located at: %s", params()->kernel); - - if (kernel == NULL) - fatal("Could not load kernel file %s", params()->kernel); - - // Load program sections into memory - kernel->loadSections(functionalPort, loadAddrMask); - - // setup entry points - kernelStart = kernel->textBase(); - kernelEnd = kernel->bssBase() + kernel->bssSize(); - kernelEntry = kernel->entryPoint(); - - // load symbols - if (!kernel->loadGlobalSymbols(kernelSymtab)) - fatal("could not load kernel symbols\n"); - - if (!kernel->loadLocalSymbols(kernelSymtab)) - fatal("could not load kernel local symbols\n"); - - if (!kernel->loadGlobalSymbols(debugSymbolTable)) - fatal("could not load kernel symbols\n"); - - if (!kernel->loadLocalSymbols(debugSymbolTable)) - fatal("could not load kernel local symbols\n"); - - DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); - DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); - DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); - DPRINTF(Loader, "Kernel loaded...\n"); - } ++ physProxy = new PortProxy(*getSystemPort()); ++ virtProxy = new FSTranslatingPortProxy(*getSystemPort()); + } - - // increment the number of running systms - numSystemsRunning++; - - activeCpus.clear(); } System::~System() @@@ -257,11 -231,61 +218,64 @@@ System::numRunningContexts( void System::initState() { - // Moved from the constructor to here since it relies on the - // address map being resolved in the interconnect -#if FULL_SYSTEM - /** - * Load the kernel code into memory - */ - if (params()->kernel == "") { - inform("No kernel set for full system simulation. Assuming you know what" - " you're doing...\n"); - } else { - // Load kernel code - kernel = createObjectFile(params()->kernel); - inform("kernel located at: %s", params()->kernel); - - if (kernel == NULL) - fatal("Could not load kernel file %s", params()->kernel); - - // Load program sections into memory - kernel->loadSections(physProxy, loadAddrMask); - - // setup entry points - kernelStart = kernel->textBase(); - kernelEnd = kernel->bssBase() + kernel->bssSize(); - kernelEntry = kernel->entryPoint(); - - // load symbols - if (!kernel->loadGlobalSymbols(kernelSymtab)) - fatal("could not load kernel symbols\n"); - - if (!kernel->loadLocalSymbols(kernelSymtab)) - fatal("could not load kernel local symbols\n"); - - if (!kernel->loadGlobalSymbols(debugSymbolTable)) - fatal("could not load kernel symbols\n"); - - if (!kernel->loadLocalSymbols(debugSymbolTable)) - fatal("could not load kernel local symbols\n"); - - DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); - DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); - DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); - DPRINTF(Loader, "Kernel loaded...\n"); ++ if (FullSystem) { ++ int i; ++ for (i = 0; i < threadContexts.size(); i++) ++ TheISA::startupCPU(threadContexts[i], i); ++ // Moved from the constructor to here since it relies on the ++ // address map being resolved in the interconnect ++ /** ++ * Load the kernel code into memory ++ */ ++ if (params()->kernel == "") { ++ inform("No kernel set for full system simulation. " ++ "Assuming you know what you're doing...\n"); ++ } else { ++ // Load kernel code ++ kernel = createObjectFile(params()->kernel); ++ inform("kernel located at: %s", params()->kernel); ++ ++ if (kernel == NULL) ++ fatal("Could not load kernel file %s", params()->kernel); ++ ++ // Load program sections into memory ++ kernel->loadSections(physProxy, loadAddrMask); ++ ++ // setup entry points ++ kernelStart = kernel->textBase(); ++ kernelEnd = kernel->bssBase() + kernel->bssSize(); ++ kernelEntry = kernel->entryPoint(); ++ ++ // load symbols ++ if (!kernel->loadGlobalSymbols(kernelSymtab)) ++ fatal("could not load kernel symbols\n"); ++ ++ if (!kernel->loadLocalSymbols(kernelSymtab)) ++ fatal("could not load kernel local symbols\n"); ++ ++ if (!kernel->loadGlobalSymbols(debugSymbolTable)) ++ fatal("could not load kernel symbols\n"); ++ ++ if (!kernel->loadLocalSymbols(debugSymbolTable)) ++ fatal("could not load kernel local symbols\n"); ++ ++ DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); ++ DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); ++ DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); ++ DPRINTF(Loader, "Kernel loaded...\n"); ++ } + } -#endif // FULL_SYSTEM + + // increment the number of running systms + numSystemsRunning++; + + activeCpus.clear(); + -#if FULL_SYSTEM - int i; - for (i = 0; i < threadContexts.size(); i++) - TheISA::startupCPU(threadContexts[i], i); -#endif + if (FullSystem) { + int i; + for (i = 0; i < threadContexts.size(); i++) + TheISA::startupCPU(threadContexts[i], i); + } } void diff --cc src/sim/system.hh index d675eb727,53f1762c7..eb192fb99 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@@ -41,27 -53,90 +53,84 @@@ #include "base/loader/symtab.hh" #include "base/misc.hh" #include "base/statistics.hh" -#include "config/full_system.hh" #include "cpu/pc_event.hh" #include "enums/MemoryMode.hh" +#include "kern/system_events.hh" + #include "mem/mem_object.hh" #include "mem/port.hh" #include "params/System.hh" - #include "sim/sim_object.hh" -#if FULL_SYSTEM -#include "kern/system_events.hh" -#endif - class BaseCPU; -class ThreadContext; +class BaseRemoteGDB; - class FunctionalPort; ++class FSTranslatingPortProxy; +class GDBListener; class ObjectFile; class PhysicalMemory; - -#if FULL_SYSTEM class Platform; + class PortProxy; -class FSTranslatingPortProxy; -#endif -class GDBListener; -class BaseRemoteGDB; +class ThreadContext; +class VirtualPort; - class System : public SimObject + class System : public MemObject { + private: + + /** + * Private class for the system port which is only used as a + * master for debug access and for non-structural entities that do + * not have a port of their own. + */ + class SystemPort : public Port + { + public: + + /** + * Create a system port with a name and an owner. + */ + SystemPort(const std::string &_name, MemObject *_owner) + : Port(_name, _owner) + { } + bool recvTiming(PacketPtr pkt) + { panic("SystemPort does not receive timing!\n"); return false; } + Tick recvAtomic(PacketPtr pkt) + { panic("SystemPort does not receive atomic!\n"); return 0; } + void recvFunctional(PacketPtr pkt) + { panic("SystemPort does not receive functional!\n"); } + + /** + * The system port is a master port connected to a single + * slave and thus do not care about what ranges the slave + * covers (as there is nothing to choose from). + */ + void recvRangeChange() { } + + }; + + SystemPort _systemPort; + public: + /** + * After all objects have been created and all ports are + * connected, check that the system port is connected. + */ + virtual void init(); + + /** + * Get a pointer to the system port that can be used by + * non-structural simulation objects like processes or threads, or + * external entities like loaders and debuggers, etc, to access + * the memory system. + * + * @return a pointer to the system port we own + */ + Port* getSystemPort() { return &_systemPort; } + + /** + * Additional function to return the Port of a memory object. + */ + Port *getPort(const std::string &if_name, int idx = -1); + static const char *MemoryModeStrings[3]; Enums::MemoryMode diff --cc tests/configs/simple-timing-ruby.py index d03b86068,359421a49..319dd3b55 --- a/tests/configs/simple-timing-ruby.py +++ b/tests/configs/simple-timing-ruby.py @@@ -82,8 -82,12 +82,11 @@@ assert(len(system.ruby._cpu_ruby_ports # Tie the cpu cache ports to the ruby cpu ports and # physmem, respectively # -cpu.icache_port = system.ruby._cpu_ruby_ports[0].port -cpu.dcache_port = system.ruby._cpu_ruby_ports[0].port +cpu.connectAllPorts(system.ruby._cpu_ruby_ports[0]) + # Connect the system port for loading of binaries etc + system.system_port = system.ruby._sys_port_proxy.port + # ----------------------- # run simulation # -----------------------