-# Copyright (c) 2010 ARM Limited
+# Copyright (c) 2010-2012 ARM Limited
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
     self.console = binary('console')
     self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
 
+    self.system_port = self.membus.port
+
     return self
 
 def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
     self.hypervisor_desc_bin = binary('1up-hv.bin')
     self.partition_desc_bin = binary('1up-md.bin')
 
+    self.system_port = self.membus.port
+
     return self
 
 def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
     self.terminal = Terminal()
     self.vncserver = VncServer()
 
+    self.system_port = self.membus.port
+
     return self
 
 
     self.console = binary('mips/console')
     self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
 
+    self.system_port = self.membus.port
+
     return self
 
 def x86IOAddress(port):
     # connect the io bus
     x86_sys.pc.attachIO(x86_sys.iobus)
 
+    x86_sys.system_port = x86_sys.membus.port
+
 def connectX86RubySystem(x86_sys):
     # North Bridge
     x86_sys.piobus = Bus(bus_id=0)
 
+# Copyright (c) 2012 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) 2006-2008 The Regents of The University of Michigan
 # All rights reserved.
 #
     options.use_map = True
     Ruby.create_system(options, system)
     assert(options.num_cpus == len(system.ruby._cpu_ruby_ports))
+    system.system_port = system.ruby._sys_port_proxy.port
 else:
+    system.system_port = system.membus.port
     system.physmem.port = system.membus.port
     CacheConfig.config_cache(options, system)
 
 
+# Copyright (c) 2012 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) 2006-2007 The Regents of The University of Michigan
 # Copyright (c) 2009 Advanced Micro Devices, Inc.
 # All rights reserved.
         print "Error: could not create sytem for ruby protocol %s" % protocol
         raise
 
+    # Create a port proxy for connecting the system port. This is
+    # independent of the protocol and kept in the protocol-agnostic
+    # part (i.e. here).
+    sys_port_proxy = RubyPortProxy(version = 0,
+                                   physMemPort = system.physmem.port,
+                                   physmem = system.physmem,
+                                   ruby_system = ruby)
+    # Give the system port proxy a SimObject parent without creating a
+    # full-fledged controller
+    system.sys_port_proxy = sys_port_proxy
+
     #
     # Set the network classes based on the command line options
     #
     ruby.profiler = ruby_profiler
     ruby.mem_size = total_mem_size
     ruby._cpu_ruby_ports = cpu_sequencers
+    ruby._sys_port_proxy = sys_port_proxy
     ruby.random_seed    = options.random_seed
 
 #include "arch/vtophys.hh"
 #include "base/loader/symtab.hh"
 #include "cpu/thread_context.hh"
-#include "mem/physical.hh"
-#include "mem/port.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #include "sim/byteswap.hh"
 
 #define TIMER_FREQUENCY 1193180
     ppc_vaddr = (Addr)tc->readIntReg(17);
     timer_vaddr = (Addr)tc->readIntReg(18);
 
-    virtPort->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
-    virtPort->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
+    virtProxy->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
+    virtProxy->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
 }
 
 void
 
     strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
     strcpy(name->machine, "alpha");
 
-    name.copyOut(tc->getMemPort());
+    name.copyOut(tc->getMemProxy());
     return 0;
 }
 
           TypedBufferArg<uint64_t> fpcr(bufPtr);
           // I don't think this exactly matches the HW FPCR
           *fpcr = 0;
-          fpcr.copyOut(tc->getMemPort());
+          fpcr.copyOut(tc->getMemProxy());
           return 0;
       }
 
       case 14: { // SSI_IEEE_FP_CONTROL
           TypedBufferArg<uint64_t> fpcr(bufPtr);
           // I don't think this exactly matches the HW FPCR
-          fpcr.copyIn(tc->getMemPort());
+          fpcr.copyIn(tc->getMemProxy());
           DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
                    " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
           return 0;
 
 LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
     : AlphaSystem(p)
 {
+}
+
+void
+LinuxAlphaSystem::initState()
+{
+    // Moved from the constructor to here since it relies on the
+    // address map being resolved in the interconnect
+
+    // Call the initialisation of the super class
+    AlphaSystem::initState();
+
     Addr addr = 0;
 
     /**
      * 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(),
-                params()->boot_osflags.length()+1);
+    virtProxy->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
      * calculated it by using the PIT, RTC, etc.
      */
     if (kernelSymtab->findAddress("est_cycle_freq", addr))
-        virtPort->write(addr, (uint64_t)(SimClock::Frequency /
-                    p->boot_cpu_frequency));
+        virtProxy->write(addr, (uint64_t)(SimClock::Frequency /
+                                          params()->boot_cpu_frequency));
 
 
     /**
      * 255 ASNs.
      */
     if (kernelSymtab->findAddress("dp264_mv", addr))
-        virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
+        virtProxy->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
     else
         panic("could not find dp264_mv\n");
 
     if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
         Tick cpuFreq = tc->getCpuPtr()->frequency();
         Tick intrFreq = platform->intrFrequency();
-        VirtualPort *vp;
+        FSTranslatingPortProxy* vp;
 
-        vp = tc->getVirtPort();
+        vp = tc->getVirtProxy();
         vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
     }
 }
 
     LinuxAlphaSystem(Params *p);
     ~LinuxAlphaSystem();
 
+    /**
+     * Initialise the system
+     */
+    virtual void initState();
+
     void setDelayLoop(ThreadContext *tc);
 };
 
 
         if (!addr)
             addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
 
-        FunctionalPort *p = tc->getPhysPort();
+        PortProxy* p = tc->getPhysProxy();
         p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
 
         return sp & ~ULL(0x3fff);
 
 
         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;
 
 #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;
     : tc(_tc)
 {
     Addr addr = 0;
-    VirtualPort *vp = tc->getVirtPort();
+    FSTranslatingPortProxy* vp = tc->getVirtProxy();
     SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
 
     if (!symtab->findAddress("thread_info_size", addr))
 
     Addr tsk;
 
-    VirtualPort *vp;
+    FSTranslatingPortProxy* vp;
 
-    vp = tc->getVirtPort();
+    vp = tc->getVirtProxy();
     tsk = vp->readGtoH<Addr>(base + task_off);
 
     return tsk;
 
     uint16_t pd;
 
-    VirtualPort *vp;
+    FSTranslatingPortProxy* vp;
 
-    vp = tc->getVirtPort();
+    vp = tc->getVirtProxy();
     pd = vp->readGtoH<uint16_t>(task + pid_off);
 
     return pd;
 
 #include "base/loader/symtab.hh"
 #include "base/trace.hh"
 #include "debug/Loader.hh"
-#include "mem/physical.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #include "params/AlphaSystem.hh"
 #include "sim/byteswap.hh"
 
     pal = createObjectFile(params()->pal);
     if (pal == NULL)
         fatal("Could not load PALcode file %s", params()->pal);
+}
+
+AlphaSystem::~AlphaSystem()
+{
+    delete consoleSymtab;
+    delete console;
+    delete pal;
+#ifdef DEBUG
+    delete consolePanicEvent;
+#endif
+}
+
+void
+AlphaSystem::initState()
+{
+    // Moved from the constructor to here since it relies on the
+    // address map being resolved in the interconnect
 
+    // Call the initialisation of the super class
+    System::initState();
 
     // Load program sections into memory
-    pal->loadSections(functionalPort, loadAddrMask);
-    console->loadSections(functionalPort, loadAddrMask);
+    pal->loadSections(physProxy, loadAddrMask);
+    console->loadSections(physProxy, loadAddrMask);
 
     // load symbols
     if (!console->loadGlobalSymbols(consoleSymtab))
      * others do.)
      */
     if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
-        virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
-                strlen(params()->boot_osflags.c_str()));
+        virtProxy->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
+                             strlen(params()->boot_osflags.c_str()));
     }
 
     /**
     if (consoleSymtab->findAddress("m5_rpb", addr)) {
         uint64_t data;
         data = htog(params()->system_type);
-        virtPort->write(addr+0x50, data);
+        virtProxy->write(addr+0x50, data);
         data = htog(params()->system_rev);
-        virtPort->write(addr+0x58, data);
+        virtProxy->write(addr+0x58, data);
     } else
         panic("could not find hwrpb\n");
 }
 
-AlphaSystem::~AlphaSystem()
-{
-    delete consoleSymtab;
-    delete console;
-    delete pal;
-#ifdef DEBUG
-    delete consolePanicEvent;
-#endif
-}
-
 /**
  * This function fixes up addresses that are used to match PCs for
  * hooking simulator events on to target function executions.
     // lda  gp,Y(gp): opcode 8, Ra = 29, rb = 29
     const uint32_t gp_lda_pattern  = (8 << 26) | (29 << 21) | (29 << 16);
 
-    uint32_t i1 = virtPort->read<uint32_t>(addr);
-    uint32_t i2 = virtPort->read<uint32_t>(addr + sizeof(MachInst));
+    uint32_t i1 = virtProxy->read<uint32_t>(addr);
+    uint32_t i2 = virtProxy->read<uint32_t>(addr + sizeof(MachInst));
 
     if ((i1 & inst_mask) == gp_ldah_pattern &&
         (i2 & inst_mask) == gp_lda_pattern) {
 {
     Addr addr = 0;
     if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
-        virtPort->write(addr, htog(Phys2K0Seg(access)));
+        virtProxy->write(addr, htog(Phys2K0Seg(access)));
     } else {
         panic("could not find m5AlphaAccess\n");
     }
 
     ~AlphaSystem();
 
   public:
+
+    /**
+     * Initialise the state of the system.
+     */
+    virtual void initState();
+
     /**
      * Serialization stuff
      */
 
     strcpy(name->version, "732");
     strcpy(name->machine, "alpha");
 
-    name.copyOut(tc->getMemPort());
+    name.copyOut(tc->getMemProxy());
     return 0;
 }
 
       case AlphaTru64::GSI_MAX_CPU: {
           TypedBufferArg<uint32_t> max_cpu(bufPtr);
           *max_cpu = htog((uint32_t)process->numCpus());
-          max_cpu.copyOut(tc->getMemPort());
+          max_cpu.copyOut(tc->getMemProxy());
           return 1;
       }
 
       case AlphaTru64::GSI_CPUS_IN_BOX: {
           TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
           *cpus_in_box = htog((uint32_t)process->numCpus());
-          cpus_in_box.copyOut(tc->getMemPort());
+          cpus_in_box.copyOut(tc->getMemProxy());
           return 1;
       }
 
       case AlphaTru64::GSI_PHYSMEM: {
           TypedBufferArg<uint64_t> physmem(bufPtr);
           *physmem = htog((uint64_t)1024 * 1024);  // physical memory in KB
-          physmem.copyOut(tc->getMemPort());
+          physmem.copyOut(tc->getMemProxy());
           return 1;
       }
 
           infop->cpu_ex_binding = htog(0);
           infop->mhz = htog(667);
 
-          infop.copyOut(tc->getMemPort());
+          infop.copyOut(tc->getMemProxy());
           return 1;
       }
 
       case AlphaTru64::GSI_PROC_TYPE: {
           TypedBufferArg<uint64_t> proc_type(bufPtr);
           *proc_type = htog((uint64_t)11);
-          proc_type.copyOut(tc->getMemPort());
+          proc_type.copyOut(tc->getMemProxy());
           return 1;
       }
 
           strncpy((char *)bufArg.bufferPtr(),
                   "COMPAQ Professional Workstation XP1000",
                   nbytes);
-          bufArg.copyOut(tc->getMemPort());
+          bufArg.copyOut(tc->getMemProxy());
           return 1;
       }
 
       case AlphaTru64::GSI_CLK_TCK: {
           TypedBufferArg<uint64_t> clk_hz(bufPtr);
           *clk_hz = htog((uint64_t)1024);
-          clk_hz.copyOut(tc->getMemPort());
+          clk_hz.copyOut(tc->getMemProxy());
           return 1;
       }
 
           elp->si_phz = htog(clk_hz);
           elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
           elp->si_max_procs = htog(process->numCpus());
-          elp.copyOut(tc->getMemPort());
+          elp.copyOut(tc->getMemProxy());
           return 0;
       }
 
 
 #include "cpu/thread_context.hh"
 #include "kern/tru64/tru64_events.hh"
 #include "kern/system_events.hh"
-#include "mem/physical.hh"
-#include "mem/port.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 
 using namespace std;
 
 {
     Addr addr = 0;
     if (kernelSymtab->findAddress("enable_async_printf", addr)) {
-        virtPort->write(addr, (uint32_t)0);
+        virtProxy->write(addr, (uint32_t)0);
     }
 
 #ifdef DEBUG
 
 
 #if FULL_SYSTEM
 #include "arch/alpha/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #endif
 
 namespace AlphaISA {
             return tc->readIntReg(16 + number);
     } else {
         Addr sp = tc->readIntReg(StackPointerReg);
-        VirtualPort *vp = tc->getVirtPort();
+        FSTranslatingPortProxy* vp = tc->getVirtProxy();
         uint64_t arg = vp->read<uint64_t>(sp +
                            (number-NumArgumentRegs) * sizeof(uint64_t));
         return arg;
 
 #include "base/trace.hh"
 #include "cpu/thread_context.hh"
 #include "debug/VtoPhys.hh"
-#include "mem/vport.hh"
+#include "mem/port_proxy.hh"
 
 using namespace std;
 
 namespace AlphaISA {
 
 PageTableEntry
-kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr)
+kernel_pte_lookup(PortProxy* mem, Addr ptbr, VAddr vaddr)
 {
     Addr level1_pte = ptbr + vaddr.level1();
     PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
             paddr = vaddr;
         } else {
             PageTableEntry pte =
-                kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
+                kernel_pte_lookup(tc->getPhysProxy(), ptbr, vaddr);
             if (pte.valid())
                 paddr = pte.paddr() | vaddr.offset();
         }
 
 #include "arch/alpha/utility.hh"
 
 class ThreadContext;
-class FunctionalPort;
+class PortProxy;
 
 namespace AlphaISA {
 
-PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr,
+PageTableEntry kernel_pte_lookup(PortProxy* mem, Addr ptbr,
                                  VAddr vaddr);
 
 Addr vtophys(Addr vaddr);
 
     strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
     strcpy(name->machine, "armv7l");
 
-    name.copyOut(tc->getMemPort());
+    name.copyOut(tc->getMemProxy());
     return 0;
 }
 
     int index = 0;
     uint32_t tlsPtr = process->getSyscallArg(tc, index);
 
-    tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
+    tc->getMemProxy()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
                                 (uint8_t *)&tlsPtr, sizeof(tlsPtr));
     tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr);
     return 0;
 
     // Fill this page with swi -1 so we'll no if we land in it somewhere.
     for (Addr addr = 0; addr < PageBytes; addr += sizeof(swiNeg1)) {
-        tc->getMemPort()->writeBlob(commPage + addr,
+        tc->getMemProxy()->writeBlob(commPage + addr,
                                     swiNeg1, sizeof(swiNeg1));
     }
 
         0x5f, 0xf0, 0x7f, 0xf5, // dmb
         0x0e, 0xf0, 0xa0, 0xe1  // return
     };
-    tc->getMemPort()->writeBlob(commPage + 0x0fa0, memory_barrier,
+    tc->getMemProxy()->writeBlob(commPage + 0x0fa0, memory_barrier,
                                 sizeof(memory_barrier));
 
     uint8_t cmpxchg[] =
         0x5f, 0xf0, 0x7f, 0xf5,  // dmb
         0x0e, 0xf0, 0xa0, 0xe1   // return
     };
-    tc->getMemPort()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg));
+    tc->getMemProxy()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg));
 
     uint8_t get_tls[] =
     {
         0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3
         0x0e, 0xf0, 0xa0, 0xe1  // return
     };
-    tc->getMemPort()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls));
+    tc->getMemProxy()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls));
 }
 
 ArmISA::IntReg
 
 #include "cpu/thread_context.hh"
 #include "debug/Loader.hh"
 #include "kern/linux/events.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #include "mem/physical.hh"
 
 using namespace ArmISA;
 LinuxArmSystem::LinuxArmSystem(Params *p)
     : ArmSystem(p)
 {
+}
+
+bool
+LinuxArmSystem::adderBootUncacheable(Addr a)
+{
+    Addr block = a & ~ULL(0x7F);
+    if (block == secDataPtrAddr || block == secDataAddr ||
+            block == penReleaseAddr)
+        return true;
+    return false;
+}
+
+void
+LinuxArmSystem::initState()
+{
+    // Moved from the constructor to here since it relies on the
+    // address map being resolved in the interconnect
+
+    // Call the initialisation of the super class
+    ArmSystem::initState();
+
     // Load symbols at physical address, we might not want
     // to do this perminately, for but early bootup work
     // it is helpfulp.
     DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
     DDUMP(Loader, boot_data, size << 2);
 
-    functionalPort->writeBlob(ParamsList, boot_data, size << 2);
+    physProxy->writeBlob(ParamsList, boot_data, size << 2);
 
 #ifndef NDEBUG
     kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
     secDataPtrAddr &= ~ULL(0x7F);
     secDataAddr &= ~ULL(0x7F);
     penReleaseAddr &= ~ULL(0x7F);
-}
-
-bool
-LinuxArmSystem::adderBootUncacheable(Addr a)
-{
-    Addr block = a & ~ULL(0x7F);
-    if (block == secDataPtrAddr || block == secDataAddr ||
-            block == penReleaseAddr)
-        return true;
-    return false;
-}
-
-void
-LinuxArmSystem::initState()
-{
-    ArmSystem::initState();
 
     for (int i = 0; i < threadContexts.size(); i++) {
         threadContexts[i]->setIntReg(0, 0);
 
 #include "cpu/thread_context.hh"
 #include "debug/Stack.hh"
 #include "mem/page_table.hh"
-#include "mem/translating_port.hh"
 #include "sim/byteswap.hh"
 #include "sim/process_impl.hh"
 #include "sim/system.hh"
 
 #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;
     {
         Addr addr = 0;
 
-        VirtualPort *vp;
+        FSTranslatingPortProxy* vp;
 
-        vp = tc->getVirtPort();
+        vp = tc->getVirtProxy();
 
         if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
             panic("thread info not compiled into kernel\n");
 
 #include "base/loader/symtab.hh"
 #include "cpu/thread_context.hh"
 #include "mem/physical.hh"
+#include "mem/fs_translating_port_proxy.hh"
 
 using namespace std;
 using namespace Linux;
     : System(p), bootldr(NULL)
 {
     debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
+}
+
+void
+ArmSystem::initState()
+{
+    // Moved from the constructor to here since it relies on the
+    // address map being resolved in the interconnect
+
+    // Call the initialisation of the super class
+    System::initState();
+
+    const Params* p = params();
 
     if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
         fatal("If boot_loader is specifed, memory to load it must be also.\n");
         if (!bootldr)
             fatal("Could not read bootloader: %s\n", p->boot_loader);
 
-        Port *mem_port;
-        FunctionalPort fp(name() + "-fport");
-        mem_port = p->boot_loader_mem->getPort("functional");
-        fp.setPeer(mem_port);
-        mem_port->setPeer(&fp);
-
-        bootldr->loadSections(&fp);
+        bootldr->loadSections(physProxy);
         bootldr->loadGlobalSymbols(debugSymbolTable);
 
         uint8_t jump_to_bl[] =
         {
             0x07, 0xf0, 0xa0, 0xe1  // branch to r7
         };
-        functionalPort->writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
+        physProxy->writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
 
         inform("Using bootloader at address %#x\n", bootldr->entryPoint());
     }
-}
 
-void
-ArmSystem::initState()
-{
-    System::initState();
     if (bootldr) {
         // Put the address of the boot loader into r7 so we know
         // where to branch to after the reset fault
             threadContexts[i]->setIntReg(5, params()->flags_addr);
             threadContexts[i]->setIntReg(7, bootldr->entryPoint());
         }
-        if (!params()->gic_cpu_addr || !params()->flags_addr)
+        if (!p->gic_cpu_addr || !p->flags_addr)
             fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
     } else {
         // Set the initial PC to be at start of the kernel code
         threadContexts[0]->pcState(kernelEntry & loadAddrMask);
     }
     for (int i = 0; i < threadContexts.size(); i++) {
-        if (params()->midr_regval) {
+        if (p->midr_regval) {
             threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
-                    params()->midr_regval);
+                                          p->midr_regval);
         }
     }
 
 
     ArmSystem(Params *p);
     ~ArmSystem();
 
-    void initState();
+    /**
+     * Initialise the system
+     */
+    virtual void initState();
 
     /** Check if an address should be uncacheable until all caches are enabled.
      * This exits because coherence on some addresses at boot is maintained via
 
 
 #if FULL_SYSTEM
 #include "arch/arm/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #endif
 
 #include "arch/arm/tlb.hh"
         }
     } else {
         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
 
 #include "base/chunk_generator.hh"
 #include "base/trace.hh"
 #include "cpu/thread_context.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 
 using namespace std;
 using namespace ArmISA;
         N = 0;
     }
 
-    FunctionalPort *port = tc->getPhysPort();
+    PortProxy* port = tc->getPhysProxy();
     Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2);
 
     TableWalker::L1Descriptor l1desc;
 
     strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
     strcpy(name->machine, "mips");
 
-    name.copyOut(tc->getMemPort());
+    name.copyOut(tc->getMemProxy());
     return 0;
 }
 
             TypedBufferArg<uint64_t> fpcr(bufPtr);
             // I don't think this exactly matches the HW FPCR
             *fpcr = 0;
-            fpcr.copyOut(tc->getMemPort());
+            fpcr.copyOut(tc->getMemProxy());
             return 0;
         }
       default:
             // SSI_IEEE_FP_CONTROL
             TypedBufferArg<uint64_t> fpcr(bufPtr);
             // I don't think this exactly matches the HW FPCR
-            fpcr.copyIn(tc->getMemPort());
+            fpcr.copyIn(tc->getMemProxy());
             DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
                    " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
             return 0;
 
     if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
         Tick cpuFreq = tc->getCpuPtr()->frequency();
         Tick intrFreq = platform->intrFrequency();
-        VirtualPort *vp;
+        FSTranslatingPortProxy* vp;
 
-        vp = tc->getVirtPort();
+        vp = tc->getVirtProxy();
         vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
     }
 }
 
         if (!addr)
             addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/);
 
-        FunctionalPort *p = tc->getPhysPort();
+        PortProxy* p = tc->getPhysProxy();
         p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
 
         return sp & ~ULL(0x3fff);
 
 
     Addr tsk;
 
-    VirtualPort *vp;
+    FSTranslatingPortProxy* vp;
 
-    vp = tc->getVirtPort();
+    vp = tc->getVirtProxy();
     tsk = vp->readGtoH<Addr>(base + task_off);
 
     return tsk;
 
     uint16_t pd;
 
-    VirtualPort *vp;
+    FSTranslatingPortProxy* vp;
 
-    vp = tc->getVirtPort();
+    vp = tc->getVirtProxy();
     pd = vp->readGtoH<uint16_t>(task + pid_off);
 
     return pd;
 
 #if FULL_SYSTEM
 #include "arch/mips/registers.hh"
 #include "arch/mips/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #endif
 
 
             return tc->readIntReg(FirstArgumentReg + number);
     } else {
         Addr sp = tc->readIntReg(StackPointerReg);
-        VirtualPort *vp = tc->getVirtPort();
+        FSTranslatingPortProxy* vp = tc->getVirtProxy();
         uint64_t arg = vp->read<uint64_t>(sp +
                 (number - 4) * sizeof(uint64_t));
         return arg;
 
     strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
     strcpy(name->machine, "power");
 
-    name.copyOut(tc->getMemPort());
+    name.copyOut(tc->getMemProxy());
     return 0;
 }
 
 
 #include "cpu/thread_context.hh"
 #include "debug/Stack.hh"
 #include "mem/page_table.hh"
-#include "mem/translating_port.hh"
 #include "sim/process_impl.hh"
 #include "sim/system.hh"
 
 
     strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
     strcpy(name->machine, "sparc");
 
-    name.copyOut(tc->getMemPort());
+    name.copyOut(tc->getMemProxy());
 
     return 0;
 }
     if (ruid) {
         BufferArg ruidBuff(ruid, sizeof(IntReg));
         memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
-        ruidBuff.copyOut(tc->getMemPort());
+        ruidBuff.copyOut(tc->getMemProxy());
     }
     // Set the euid
     if (euid) {
         BufferArg euidBuff(euid, sizeof(IntReg));
         memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
-        euidBuff.copyOut(tc->getMemPort());
+        euidBuff.copyOut(tc->getMemProxy());
     }
     // Set the suid
     if (suid) {
         BufferArg suidBuff(suid, sizeof(IntReg));
         memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
-        suidBuff.copyOut(tc->getMemPort());
+        suidBuff.copyOut(tc->getMemProxy());
     }
     return 0;
 }
 
 #include "cpu/thread_context.hh"
 #include "debug/Stack.hh"
 #include "mem/page_table.hh"
-#include "mem/translating_port.hh"
 #include "sim/process_impl.hh"
 #include "sim/system.hh"
 
             for (int index = 16; index < 32; index++) {
                 uint32_t regVal = tc->readIntReg(index);
                 regVal = htog(regVal);
-                if (!tc->getMemPort()->tryWriteBlob(
+                if (!tc->getMemProxy()->tryWriteBlob(
                         sp + (index - 16) * 4, (uint8_t *)®Val, 4)) {
                     warn("Failed to save register to the stack when "
                             "flushing windows.\n");
             for (int index = 16; index < 32; index++) {
                 IntReg regVal = tc->readIntReg(index);
                 regVal = htog(regVal);
-                if (!tc->getMemPort()->tryWriteBlob(
+                if (!tc->getMemProxy()->tryWriteBlob(
                         sp + 2047 + (index - 16) * 8, (uint8_t *)®Val, 8)) {
                     warn("Failed to save register to the stack when "
                             "flushing windows.\n");
 
     strcpy(name->version, "Generic_118558-21");
     strcpy(name->machine, "sun4u");
 
-    name.copyOut(tc->getMemPort());
+    name.copyOut(tc->getMemProxy());
 
     return 0;
 }
 
 using namespace BigEndianGuest;
 
 SparcSystem::SparcSystem(Params *p)
-    : System(p), sysTick(0),funcRomPort(p->name + "-fromport"),
-    funcNvramPort(p->name + "-fnvramport"),
-    funcHypDescPort(p->name + "-fhypdescport"),
-    funcPartDescPort(p->name + "-fpartdescport")
+    : System(p), sysTick(0)
 {
     resetSymtab = new SymbolTable;
     hypervisorSymtab = new SymbolTable;
     nvramSymtab = new SymbolTable;
     hypervisorDescSymtab = new SymbolTable;
     partitionDescSymtab = new SymbolTable;
+}
 
-    Port *rom_port;
-    rom_port = params()->rom->getPort("functional");
-    funcRomPort.setPeer(rom_port);
-    rom_port->setPeer(&funcRomPort);
-
-    rom_port = params()->nvram->getPort("functional");
-    funcNvramPort.setPeer(rom_port);
-    rom_port->setPeer(&funcNvramPort);
-
-    rom_port = params()->hypervisor_desc->getPort("functional");
-    funcHypDescPort.setPeer(rom_port);
-    rom_port->setPeer(&funcHypDescPort);
-
-    rom_port = params()->partition_desc->getPort("functional");
-    funcPartDescPort.setPeer(rom_port);
-    rom_port->setPeer(&funcPartDescPort);
+void
+SparcSystem::initState()
+{
+    // Call the initialisation of the super class
+    System::initState();
 
     /**
      * Load the boot code, and hypervisor into memory.
 
     // Load reset binary into memory
     reset->setTextBase(params()->reset_addr);
-    reset->loadSections(&funcRomPort);
+    reset->loadSections(physProxy);
     // Load the openboot binary
     openboot->setTextBase(params()->openboot_addr);
-    openboot->loadSections(&funcRomPort);
+    openboot->loadSections(physProxy);
     // Load the hypervisor binary
     hypervisor->setTextBase(params()->hypervisor_addr);
-    hypervisor->loadSections(&funcRomPort);
+    hypervisor->loadSections(physProxy);
     // Load the nvram image
     nvram->setTextBase(params()->nvram_addr);
-    nvram->loadSections(&funcNvramPort);
+    nvram->loadSections(physProxy);
     // Load the hypervisor description image
     hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
-    hypervisor_desc->loadSections(&funcHypDescPort);
+    hypervisor_desc->loadSections(physProxy);
     // Load the partition description image
     partition_desc->setTextBase(params()->partition_desc_addr);
-    partition_desc->loadSections(&funcPartDescPort);
+    partition_desc->loadSections(physProxy);
 
     // load symbols
     if (!reset->loadGlobalSymbols(resetSymtab))
 
     SparcSystem(Params *p);
     ~SparcSystem();
 
+    virtual void initState();
+
 /**
  * Serialization stuff
  */
     /** System Tick for syncronized tick across all cpus. */
     Tick sysTick;
 
-    /** functional port to ROM */
-    FunctionalPort funcRomPort;
-
-    /** functional port to nvram */
-    FunctionalPort funcNvramPort;
-
-    /** functional port to hypervisor description */
-    FunctionalPort funcHypDescPort;
-
-    /** functional port to partition description */
-    FunctionalPort funcPartDescPort;
-
   protected:
     const Params *params() const { return (const Params *)_params; }
 
 
 #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 {
         return tc->readIntReg(8 + number);
     } else {
         Addr sp = tc->readIntReg(StackPointerReg);
-        VirtualPort *vp = tc->getVirtPort();
+        FSTranslatingPortProxy* vp = tc->getVirtProxy();
         uint64_t arg = vp->read<uint64_t>(sp + 92 +
                             (number-NumArgumentRegs) * sizeof(uint64_t));
         return arg;
 
 #include "base/trace.hh"
 #include "cpu/thread_context.hh"
 #include "debug/VtoPhys.hh"
-#include "mem/vport.hh"
+#include "mem/port_proxy.hh"
 
 using namespace std;
 
     int pri_context = bits(tlbdata,47,32);
     // int sec_context = bits(tlbdata,63,48);
 
-    FunctionalPort *mem = tc->getPhysPort();
+    PortProxy* mem = tc->getPhysProxy();
     TLB* itb = tc->getITBPtr();
     TLB* dtb = tc->getDTBPtr();
     TlbEntry* tbe;
 
 #include "arch/x86/isa_traits.hh"
 #include "base/misc.hh"
 #include "base/types.hh"
-#include "mem/port.hh"
+#include "mem/port_proxy.hh"
 #include "sim/byteswap.hh"
 
 // Config entry types
 
 template<class T>
 uint8_t
-writeOutField(FunctionalPort * port, Addr addr, T val)
+writeOutField(PortProxy* proxy, Addr addr, T val)
 {
     T guestVal = X86ISA::htog(val);
-    port->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T));
+    proxy->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T));
 
     uint8_t checkSum = 0;
     while(guestVal) {
 }
 
 uint8_t
-writeOutString(FunctionalPort * port, Addr addr, string str, int length)
+writeOutString(PortProxy* proxy, Addr addr, string str, int length)
 {
     char cleanedString[length + 1];
     cleanedString[length] = 0;
         memcpy(cleanedString, str.c_str(), str.length());
         memset(cleanedString + str.length(), 0, length - str.length());
     }
-    port->writeBlob(addr, (uint8_t *)(&cleanedString), length);
+    proxy->writeBlob(addr, (uint8_t *)(&cleanedString), length);
 
     uint8_t checkSum = 0;
     for (int i = 0; i < length; i++)
 }
 
 Addr
-X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr)
+X86ISA::IntelMP::FloatingPointer::writeOut(PortProxy* proxy, Addr addr)
 {
     // Make sure that either a config table is present or a default
     // configuration was found but not both.
 
     uint8_t checkSum = 0;
 
-    port->writeBlob(addr, (uint8_t *)signature, 4);
+    proxy->writeBlob(addr, (uint8_t *)signature, 4);
     for (int i = 0; i < 4; i++)
         checkSum += signature[i];
 
-    checkSum += writeOutField(port, addr + 4, tableAddr);
+    checkSum += writeOutField(proxy, addr + 4, tableAddr);
 
     // The length of the structure in paragraphs, aka 16 byte chunks.
     uint8_t length = 1;
-    port->writeBlob(addr + 8, &length, 1);
+    proxy->writeBlob(addr + 8, &length, 1);
     checkSum += length;
 
-    port->writeBlob(addr + 9, &specRev, 1);
+    proxy->writeBlob(addr + 9, &specRev, 1);
     checkSum += specRev;
 
-    port->writeBlob(addr + 11, &defaultConfig, 1);
+    proxy->writeBlob(addr + 11, &defaultConfig, 1);
     checkSum += defaultConfig;
 
     uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
-    checkSum += writeOutField(port, addr + 12, features2_5);
+    checkSum += writeOutField(proxy, addr + 12, features2_5);
 
     checkSum = -checkSum;
-    port->writeBlob(addr + 10, &checkSum, 1);
+    proxy->writeBlob(addr + 10, &checkSum, 1);
 
     return 16;
 }
 }
 
 Addr
-X86ISA::IntelMP::BaseConfigEntry::writeOut(FunctionalPort * port,
+X86ISA::IntelMP::BaseConfigEntry::writeOut(PortProxy* proxy,
         Addr addr, uint8_t &checkSum)
 {
-    port->writeBlob(addr, &type, 1);
+    proxy->writeBlob(addr, &type, 1);
     checkSum += type;
     return 1;
 }
 {}
 
 Addr
-X86ISA::IntelMP::ExtConfigEntry::writeOut(FunctionalPort * port,
+X86ISA::IntelMP::ExtConfigEntry::writeOut(PortProxy* proxy,
         Addr addr, uint8_t &checkSum)
 {
-    port->writeBlob(addr, &type, 1);
+    proxy->writeBlob(addr, &type, 1);
     checkSum += type;
-    port->writeBlob(addr + 1, &length, 1);
+    proxy->writeBlob(addr + 1, &length, 1);
     checkSum += length;
     return 1;
 }
 const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
 
 Addr
-X86ISA::IntelMP::ConfigTable::writeOut(FunctionalPort * port, Addr addr)
+X86ISA::IntelMP::ConfigTable::writeOut(PortProxy* proxy, Addr addr)
 {
     uint8_t checkSum = 0;
 
-    port->writeBlob(addr, (uint8_t *)signature, 4);
+    proxy->writeBlob(addr, (uint8_t *)signature, 4);
     for (int i = 0; i < 4; i++)
         checkSum += signature[i];
 
     // Base table length goes here but will be calculated later.
 
-    port->writeBlob(addr + 6, (uint8_t *)(&specRev), 1);
+    proxy->writeBlob(addr + 6, (uint8_t *)(&specRev), 1);
     checkSum += specRev;
 
     // The checksum goes here but is still being calculated.
 
-    checkSum += writeOutString(port, addr + 8, oemID, 8);
-    checkSum += writeOutString(port, addr + 16, productID, 12);
+    checkSum += writeOutString(proxy, addr + 8, oemID, 8);
+    checkSum += writeOutString(proxy, addr + 16, productID, 12);
 
-    checkSum += writeOutField(port, addr + 28, oemTableAddr);
-    checkSum += writeOutField(port, addr + 32, oemTableSize);
-    checkSum += writeOutField(port, addr + 34, (uint16_t)baseEntries.size());
-    checkSum += writeOutField(port, addr + 36, localApic);
+    checkSum += writeOutField(proxy, addr + 28, oemTableAddr);
+    checkSum += writeOutField(proxy, addr + 32, oemTableSize);
+    checkSum += writeOutField(proxy, addr + 34, (uint16_t)baseEntries.size());
+    checkSum += writeOutField(proxy, addr + 36, localApic);
 
     uint8_t reserved = 0;
-    port->writeBlob(addr + 43, &reserved, 1);
+    proxy->writeBlob(addr + 43, &reserved, 1);
     checkSum += reserved;
 
     vector<BaseConfigEntry *>::iterator baseEnt;
     uint16_t offset = 44;
     for (baseEnt = baseEntries.begin();
             baseEnt != baseEntries.end(); baseEnt++) {
-        offset += (*baseEnt)->writeOut(port, addr + offset, checkSum);
+        offset += (*baseEnt)->writeOut(proxy, addr + offset, checkSum);
     }
 
     // We've found the end of the base table this point.
-    checkSum += writeOutField(port, addr + 4, offset);
+    checkSum += writeOutField(proxy, addr + 4, offset);
 
     vector<ExtConfigEntry *>::iterator extEnt;
     uint16_t extOffset = 0;
     uint8_t extCheckSum = 0;
     for (extEnt = extEntries.begin();
             extEnt != extEntries.end(); extEnt++) {
-        extOffset += (*extEnt)->writeOut(port,
+        extOffset += (*extEnt)->writeOut(proxy,
                 addr + offset + extOffset, extCheckSum);
     }
 
-    checkSum += writeOutField(port, addr + 40, extOffset);
+    checkSum += writeOutField(proxy, addr + 40, extOffset);
     extCheckSum = -extCheckSum;
-    checkSum += writeOutField(port, addr + 42, extCheckSum);
+    checkSum += writeOutField(proxy, addr + 42, extCheckSum);
 
     // And now, we finally have the whole check sum completed.
     checkSum = -checkSum;
-    writeOutField(port, addr + 7, checkSum);
+    writeOutField(proxy, addr + 7, checkSum);
 
     return offset + extOffset;
 };
 
 Addr
 X86ISA::IntelMP::Processor::writeOut(
-        FunctionalPort * port, Addr addr, uint8_t &checkSum)
+        PortProxy* proxy, Addr addr, uint8_t &checkSum)
 {
-    BaseConfigEntry::writeOut(port, addr, checkSum);
-    checkSum += writeOutField(port, addr + 1, localApicID);
-    checkSum += writeOutField(port, addr + 2, localApicVersion);
-    checkSum += writeOutField(port, addr + 3, cpuFlags);
-    checkSum += writeOutField(port, addr + 4, cpuSignature);
-    checkSum += writeOutField(port, addr + 8, featureFlags);
+    BaseConfigEntry::writeOut(proxy, addr, checkSum);
+    checkSum += writeOutField(proxy, addr + 1, localApicID);
+    checkSum += writeOutField(proxy, addr + 2, localApicVersion);
+    checkSum += writeOutField(proxy, addr + 3, cpuFlags);
+    checkSum += writeOutField(proxy, addr + 4, cpuSignature);
+    checkSum += writeOutField(proxy, addr + 8, featureFlags);
 
     uint32_t reserved = 0;
-    port->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
-    port->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
+    proxy->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
+    proxy->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
     return 20;
 }
 
 
 Addr
 X86ISA::IntelMP::Bus::writeOut(
-        FunctionalPort * port, Addr addr, uint8_t &checkSum)
+        PortProxy* proxy, Addr addr, uint8_t &checkSum)
 {
-    BaseConfigEntry::writeOut(port, addr, checkSum);
-    checkSum += writeOutField(port, addr + 1, busID);
-    checkSum += writeOutString(port, addr + 2, busType, 6);
+    BaseConfigEntry::writeOut(proxy, addr, checkSum);
+    checkSum += writeOutField(proxy, addr + 1, busID);
+    checkSum += writeOutString(proxy, addr + 2, busType, 6);
     return 8;
 }
 
 
 Addr
 X86ISA::IntelMP::IOAPIC::writeOut(
-        FunctionalPort * port, Addr addr, uint8_t &checkSum)
+        PortProxy* proxy, Addr addr, uint8_t &checkSum)
 {
-    BaseConfigEntry::writeOut(port, addr, checkSum);
-    checkSum += writeOutField(port, addr + 1, id);
-    checkSum += writeOutField(port, addr + 2, version);
-    checkSum += writeOutField(port, addr + 3, flags);
-    checkSum += writeOutField(port, addr + 4, address);
+    BaseConfigEntry::writeOut(proxy, addr, checkSum);
+    checkSum += writeOutField(proxy, addr + 1, id);
+    checkSum += writeOutField(proxy, addr + 2, version);
+    checkSum += writeOutField(proxy, addr + 3, flags);
+    checkSum += writeOutField(proxy, addr + 4, address);
     return 8;
 }
 
 
 Addr
 X86ISA::IntelMP::IntAssignment::writeOut(
-        FunctionalPort * port, Addr addr, uint8_t &checkSum)
+        PortProxy* proxy, Addr addr, uint8_t &checkSum)
 {
-    BaseConfigEntry::writeOut(port, addr, checkSum);
-    checkSum += writeOutField(port, addr + 1, interruptType);
-    checkSum += writeOutField(port, addr + 2, flags);
-    checkSum += writeOutField(port, addr + 4, sourceBusID);
-    checkSum += writeOutField(port, addr + 5, sourceBusIRQ);
-    checkSum += writeOutField(port, addr + 6, destApicID);
-    checkSum += writeOutField(port, addr + 7, destApicIntIn);
+    BaseConfigEntry::writeOut(proxy, addr, checkSum);
+    checkSum += writeOutField(proxy, addr + 1, interruptType);
+    checkSum += writeOutField(proxy, addr + 2, flags);
+    checkSum += writeOutField(proxy, addr + 4, sourceBusID);
+    checkSum += writeOutField(proxy, addr + 5, sourceBusIRQ);
+    checkSum += writeOutField(proxy, addr + 6, destApicID);
+    checkSum += writeOutField(proxy, addr + 7, destApicIntIn);
     return 8;
 }
 
 
 Addr
 X86ISA::IntelMP::AddrSpaceMapping::writeOut(
-        FunctionalPort * port, Addr addr, uint8_t &checkSum)
+        PortProxy* proxy, Addr addr, uint8_t &checkSum)
 {
-    ExtConfigEntry::writeOut(port, addr, checkSum);
-    checkSum += writeOutField(port, addr + 2, busID);
-    checkSum += writeOutField(port, addr + 3, addrType);
-    checkSum += writeOutField(port, addr + 4, addr);
-    checkSum += writeOutField(port, addr + 12, addrLength);
+    ExtConfigEntry::writeOut(proxy, addr, checkSum);
+    checkSum += writeOutField(proxy, addr + 2, busID);
+    checkSum += writeOutField(proxy, addr + 3, addrType);
+    checkSum += writeOutField(proxy, addr + 4, addr);
+    checkSum += writeOutField(proxy, addr + 12, addrLength);
     return length;
 }
 
 
 Addr
 X86ISA::IntelMP::BusHierarchy::writeOut(
-        FunctionalPort * port, Addr addr, uint8_t &checkSum)
+        PortProxy* proxy, Addr addr, uint8_t &checkSum)
 {
-    ExtConfigEntry::writeOut(port, addr, checkSum);
-    checkSum += writeOutField(port, addr + 2, busID);
-    checkSum += writeOutField(port, addr + 3, info);
-    checkSum += writeOutField(port, addr + 4, parentBus);
+    ExtConfigEntry::writeOut(proxy, addr, checkSum);
+    checkSum += writeOutField(proxy, addr + 2, busID);
+    checkSum += writeOutField(proxy, addr + 3, info);
+    checkSum += writeOutField(proxy, addr + 4, parentBus);
 
     uint32_t reserved = 0;
-    port->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
+    proxy->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
 
     return length;
 }
 
 Addr
 X86ISA::IntelMP::CompatAddrSpaceMod::writeOut(
-        FunctionalPort * port, Addr addr, uint8_t &checkSum)
+        PortProxy* proxy, Addr addr, uint8_t &checkSum)
 {
-    ExtConfigEntry::writeOut(port, addr, checkSum);
-    checkSum += writeOutField(port, addr + 2, busID);
-    checkSum += writeOutField(port, addr + 3, mod);
-    checkSum += writeOutField(port, addr + 4, rangeList);
+    ExtConfigEntry::writeOut(proxy, addr, checkSum);
+    checkSum += writeOutField(proxy, addr + 2, busID);
+    checkSum += writeOutField(proxy, addr + 3, mod);
+    checkSum += writeOutField(proxy, addr + 4, rangeList);
     return length;
 }
 
 
 #include "enums/X86IntelMPTriggerMode.hh"
 #include "sim/sim_object.hh"
 
-class FunctionalPort;
+class PortProxy;
 
 // Config entry types
 class X86IntelMPBaseConfigEntryParams;
 
   public:
 
-    Addr writeOut(FunctionalPort * port, Addr addr);
+    Addr writeOut(PortProxy* proxy, Addr addr);
 
     Addr getTableAddr()
     {
 
   public:
 
-    virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+    virtual Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
 
     BaseConfigEntry(Params * p, uint8_t _type);
 };
 
   public:
 
-    virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+    virtual Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
 
     ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length);
 };
     std::vector<ExtConfigEntry *> extEntries;
 
   public:
-    Addr writeOut(FunctionalPort * port, Addr addr);
+    Addr writeOut(PortProxy* proxy, Addr addr);
 
     ConfigTable(Params * p);
 };
     uint32_t featureFlags;
 
   public:
-    Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+    Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
 
     Processor(Params * p);
 };
     std::string busType;
 
   public:
-    Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+    Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
 
     Bus(Params * p);
 };
     uint32_t address;
 
   public:
-    Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+    Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
 
     IOAPIC(Params * p);
 };
     uint8_t destApicIntIn;
 
   public:
-    Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+    Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
 
     IntAssignment(X86IntelMPBaseConfigEntryParams * p,
             Enums::X86IntelMPInterruptType _interruptType,
     uint64_t addrLength;
 
   public:
-    Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+    Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
 
     AddrSpaceMapping(Params * p);
 };
     uint8_t parentBus;
 
   public:
-    Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+    Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
 
     BusHierarchy(Params * p);
 };
     uint32_t rangeList;
 
   public:
-    Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+    Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
 
     CompatAddrSpaceMod(Params * p);
 };
 
 #include "arch/x86/bios/smbios.hh"
 #include "arch/x86/isa_traits.hh"
 #include "base/types.hh"
-#include "mem/port.hh"
+#include "mem/port_proxy.hh"
 #include "params/X86SMBiosBiosInformation.hh"
 #include "params/X86SMBiosSMBiosStructure.hh"
 #include "params/X86SMBiosSMBiosTable.hh"
 }
 
 uint16_t
-X86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr)
+X86ISA::SMBios::SMBiosStructure::writeOut(PortProxy* proxy, Addr addr)
 {
-    port->writeBlob(addr, (uint8_t *)(&type), 1);
+    proxy->writeBlob(addr, (uint8_t *)(&type), 1);
 
     uint8_t length = getLength();
-    port->writeBlob(addr + 1, (uint8_t *)(&length), 1);
+    proxy->writeBlob(addr + 1, (uint8_t *)(&length), 1);
 
     uint16_t handleGuest = X86ISA::htog(handle);
-    port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
+    proxy->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
 
     return length + getStringLength();
 }
 
 void
 X86ISA::SMBios::SMBiosStructure::writeOutStrings(
-        FunctionalPort * port, Addr addr)
+        PortProxy* proxy, Addr addr)
 {
     std::vector<std::string>::iterator it;
     Addr offset = 0;
     // If there are string fields but none of them are used, that's a
     // special case which is handled by this if.
     if (strings.size() == 0 && stringFields) {
-        port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
+        proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
         offset++;
     } else {
         for (it = strings.begin(); it != strings.end(); it++) {
-            port->writeBlob(addr + offset,
+            proxy->writeBlob(addr + offset,
                     (uint8_t *)it->c_str(), it->length() + 1);
             offset += it->length() + 1;
         }
     }
-    port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
+    proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
 }
 
 int
     }
 
 uint16_t
-X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr)
+X86ISA::SMBios::BiosInformation::writeOut(PortProxy* proxy, Addr addr)
 {
-    uint8_t size = SMBiosStructure::writeOut(port, addr);
+    uint8_t size = SMBiosStructure::writeOut(proxy, addr);
 
-    port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
-    port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
+    proxy->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
+    proxy->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
 
     uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment);
-    port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
+    proxy->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
 
-    port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
-    port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
+    proxy->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
+    proxy->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
 
     uint64_t characteristicsGuest = X86ISA::htog(characteristics);
-    port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
+    proxy->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
 
     uint16_t characteristicExtBytesGuest =
         X86ISA::htog(characteristicExtBytes);
-    port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
+    proxy->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
 
-    port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
-    port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
-    port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
-    port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
+    proxy->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
+    proxy->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
+    proxy->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
+    proxy->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
 
-    writeOutStrings(port, addr + getLength());
+    writeOutStrings(proxy, addr + getLength());
 
     return size;
 }
 }
 
 void
-X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
+X86ISA::SMBios::SMBiosTable::writeOut(PortProxy* proxy, Addr addr,
         Addr &headerSize, Addr &structSize)
 {
     headerSize = 0x1F;
      */
     uint8_t mainChecksum = 0;
 
-    port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
+    proxy->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
     for (int i = 0; i < 4; i++)
         mainChecksum += smbiosHeader.anchorString[i];
 
     // The checksum goes here, but we're figuring it out as we go.
 
-    port->writeBlob(addr + 0x5,
+    proxy->writeBlob(addr + 0x5,
             (uint8_t *)(&smbiosHeader.entryPointLength), 1);
     mainChecksum += smbiosHeader.entryPointLength;
-    port->writeBlob(addr + 0x6,
+    proxy->writeBlob(addr + 0x6,
             (uint8_t *)(&smbiosHeader.majorVersion), 1);
     mainChecksum += smbiosHeader.majorVersion;
-    port->writeBlob(addr + 0x7,
+    proxy->writeBlob(addr + 0x7,
             (uint8_t *)(&smbiosHeader.minorVersion), 1);
     mainChecksum += smbiosHeader.minorVersion;
     // Maximum structure size goes here, but we'll figure it out later.
-    port->writeBlob(addr + 0xA,
+    proxy->writeBlob(addr + 0xA,
             (uint8_t *)(&smbiosHeader.entryPointRevision), 1);
     mainChecksum += smbiosHeader.entryPointRevision;
-    port->writeBlob(addr + 0xB,
+    proxy->writeBlob(addr + 0xB,
             (uint8_t *)(&smbiosHeader.formattedArea), 5);
     for (int i = 0; i < 5; i++)
         mainChecksum += smbiosHeader.formattedArea[i];
      */
     uint8_t intChecksum = 0;
 
-    port->writeBlob(addr + 0x10,
+    proxy->writeBlob(addr + 0x10,
             (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
     for (int i = 0; i < 5; i++)
         intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
 
     uint32_t tableAddrGuest =
         X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr);
-    port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
+    proxy->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
     for (int i = 0; i < 4; i++) {
         intChecksum += tableAddrGuest;
         tableAddrGuest >>= 8;
     }
 
     uint16_t numStructs = X86ISA::gtoh(structures.size());
-    port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
+    proxy->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
     for (int i = 0; i < 2; i++) {
         intChecksum += numStructs;
         numStructs >>= 8;
     }
 
-    port->writeBlob(addr + 0x1E,
+    proxy->writeBlob(addr + 0x1E,
             (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
             1);
     intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
     uint16_t maxSize = 0;
     std::vector<SMBiosStructure *>::iterator it;
     for (it = structures.begin(); it != structures.end(); it++) {
-        uint16_t size = (*it)->writeOut(port, base + offset);
+        uint16_t size = (*it)->writeOut(proxy, base + offset);
         if (size > maxSize)
             maxSize = size;
         offset += size;
      */
 
     maxSize = X86ISA::htog(maxSize);
-    port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
+    proxy->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
     for (int i = 0; i < 2; i++) {
         mainChecksum += maxSize;
         maxSize >>= 8;
 
     // Set the checksum
     mainChecksum = -mainChecksum;
-    port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
+    proxy->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
 
     /*
      * Intermediate header
 
     uint16_t tableSize = offset;
     tableSize = X86ISA::htog(tableSize);
-    port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
+    proxy->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
     for (int i = 0; i < 2; i++) {
         intChecksum += tableSize;
         tableSize >>= 8;
     }
 
     intChecksum = -intChecksum;
-    port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
+    proxy->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
 }
 
 X86ISA::SMBios::BiosInformation *
 
 #include "enums/ExtCharacteristic.hh"
 #include "sim/sim_object.hh"
 
-class FunctionalPort;
+class PortProxy;
 class X86SMBiosBiosInformationParams;
 class X86SMBiosSMBiosStructureParams;
 class X86SMBiosSMBiosTableParams;
         return 4;
     }
 
-    virtual uint16_t writeOut(FunctionalPort * port, Addr addr);
+    virtual uint16_t writeOut(PortProxy* proxy, Addr addr);
 
   protected:
     bool stringFields;
 
     std::vector<std::string> strings;
 
-    void writeOutStrings(FunctionalPort * port, Addr addr);
+    void writeOutStrings(PortProxy* proxy, Addr addr);
 
     int getStringLength();
 
     BiosInformation(Params * p);
 
     uint8_t getLength() { return 0x18; }
-    uint16_t writeOut(FunctionalPort * port, Addr addr);
+    uint16_t writeOut(PortProxy* proxy, Addr addr);
 };
 
 class SMBiosTable : public SimObject
         smbiosHeader.intermediateHeader.tableAddr = addr;
     }
 
-    void writeOut(FunctionalPort * port, Addr addr,
+    void writeOut(PortProxy* proxy, Addr addr,
             Addr &headerSize, Addr &structSize);
 };
 
 
     strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
     strcpy(name->machine, "x86_64");
 
-    name.copyOut(tc->getMemPort());
+    name.copyOut(tc->getMemProxy());
 
     return 0;
 }
     int code = process->getSyscallArg(tc, index);
     uint64_t addr = process->getSyscallArg(tc, index);
     uint64_t fsBase, gsBase;
-    TranslatingPort *p = tc->getMemPort();
+    SETranslatingPortProxy* p = tc->getMemProxy();
     switch(code)
     {
       //Each of these valid options should actually check addr.
         gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
                 numTLSEntries * sizeof(uint64_t));
 
-    if (!userDesc.copyIn(tc->getMemPort()))
+    if (!userDesc.copyIn(tc->getMemProxy()))
         return -EFAULT;
 
-    if (!gdt.copyIn(tc->getMemPort()))
+    if (!gdt.copyIn(tc->getMemProxy()))
         panic("Failed to copy in GDT for %s.\n", desc->name);
 
     if (userDesc->entry_number == (uint32_t)(-1)) {
 
     gdt[index] = (uint64_t)segDesc;
 
-    if (!userDesc.copyOut(tc->getMemPort()))
+    if (!userDesc.copyOut(tc->getMemProxy()))
         return -EFAULT;
-    if (!gdt.copyOut(tc->getMemPort()))
+    if (!gdt.copyOut(tc->getMemProxy()))
         panic("Failed to copy out GDT for %s.\n", desc->name);
 
     return 0;
 
 #include "arch/vtophys.hh"
 #include "base/trace.hh"
 #include "cpu/thread_context.hh"
-#include "mem/physical.hh"
+#include "mem/port_proxy.hh"
 #include "params/LinuxX86System.hh"
 #include "sim/byteswap.hh"
 
     // The location of the real mode data structure.
     const Addr realModeData = 0x90200;
 
-    // A port to write to memory.
-    FunctionalPort * physPort = threadContexts[0]->getPhysPort();
+    // A port proxy to write to memory.
+    PortProxy* physProxy = threadContexts[0]->getPhysProxy();
 
     /*
      * Deal with the command line stuff.
     if (commandLine.length() + 1 > realModeData - commandLineBuff)
         panic("Command line \"%s\" is longer than %d characters.\n",
                 commandLine, realModeData - commandLineBuff - 1);
-    physPort->writeBlob(commandLineBuff,
+    physProxy->writeBlob(commandLineBuff,
             (uint8_t *)commandLine.c_str(), commandLine.length() + 1);
 
     // Generate a pointer of the right size and endianness to put into
     // commandLinePointer.
     uint32_t guestCommandLineBuff =
         X86ISA::htog((uint32_t)commandLineBuff);
-    physPort->writeBlob(commandLinePointer,
+    physProxy->writeBlob(commandLinePointer,
             (uint8_t *)&guestCommandLineBuff, sizeof(guestCommandLineBuff));
 
     /*
     // A pointer to the buffer for E820 entries.
     const Addr e820MapPointer = realModeData + 0x2d0;
 
-    e820Table->writeTo(physPort, e820MapNrPointer, e820MapPointer);
+    e820Table->writeTo(getSystemPort(), e820MapNrPointer, e820MapPointer);
 
     /*
      * Pass the location of the real mode data structure to the kernel
 
 #include "cpu/thread_context.hh"
 #include "debug/Stack.hh"
 #include "mem/page_table.hh"
-#include "mem/translating_port.hh"
 #include "sim/process_impl.hh"
 #include "sim/syscall_emul.hh"
 #include "sim/system.hh"
 
 #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;
     {
         Addr addr = 0;
 
-        VirtualPort *vp;
+        FSTranslatingPortProxy* vp;
 
-        vp = tc->getVirtPort();
+        vp = tc->getVirtProxy();
 
         if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
             panic("thread info not compiled into kernel\n");
 
         Addr tsk;
 
-        VirtualPort *vp;
+        FSTranslatingPortProxy* vp;
 
-        vp = tc->getVirtPort();
+        vp = tc->getVirtProxy();
         tsk = vp->readGtoH<Addr>(base + task_off);
 
         return tsk;
 
         uint16_t pd;
 
-        VirtualPort *vp;
+        FSTranslatingPortProxy* vp;
 
-        vp = tc->getVirtPort();
+        vp = tc->getVirtProxy();
         pd = vp->readGtoH<uint16_t>(task + pid_off);
 
         return pd;
 
 #include "base/intmath.hh"
 #include "base/trace.hh"
 #include "cpu/thread_context.hh"
-#include "mem/physical.hh"
+#include "mem/port_proxy.hh"
 #include "params/X86System.hh"
 #include "sim/byteswap.hh"
 
     mpConfigTable(p->intel_mp_table),
     rsdp(p->acpi_description_table_pointer)
 {
-    if (kernel->getArch() == ObjectFile::I386)
-        fatal("Loading a 32 bit x86 kernel is not supported.\n");
 }
 
 static void
 {
     System::initState();
 
+    if (kernel->getArch() == ObjectFile::I386)
+        fatal("Loading a 32 bit x86 kernel is not supported.\n");
+
     ThreadContext *tc = threadContexts[0];
     // This is the boot strap processor (BSP). Initialize it to look like
     // the boot loader has just turned control over to the 64 bit OS. We
     const int PDPTBits = 9;
     const int PDTBits = 9;
 
-    // Get a port to write the page tables and descriptor tables.
-    FunctionalPort * physPort = tc->getPhysPort();
+    // Get a port proxy to write the page tables and descriptor tables.
+    PortProxy* physProxy = tc->getPhysProxy();
 
     /*
      * Set up the gdt.
     uint8_t numGDTEntries = 0;
     // Place holder at selector 0
     uint64_t nullDescriptor = 0;
-    physPort->writeBlob(GDTBase + numGDTEntries * 8,
+    physProxy->writeBlob(GDTBase + numGDTEntries * 8,
             (uint8_t *)(&nullDescriptor), 8);
     numGDTEntries++;
 
     //it's beginning in memory and it's actual data, we'll use an
     //intermediary.
     uint64_t csDescVal = csDesc;
-    physPort->writeBlob(GDTBase + numGDTEntries * 8,
+    physProxy->writeBlob(GDTBase + numGDTEntries * 8,
             (uint8_t *)(&csDescVal), 8);
 
     numGDTEntries++;
     dsDesc.limitHigh = 0xF;
     dsDesc.limitLow = 0xFF;
     uint64_t dsDescVal = dsDesc;
-    physPort->writeBlob(GDTBase + numGDTEntries * 8,
+    physProxy->writeBlob(GDTBase + numGDTEntries * 8,
             (uint8_t *)(&dsDescVal), 8);
 
     numGDTEntries++;
     tssDesc.limitHigh = 0xF;
     tssDesc.limitLow = 0xFF;
     uint64_t tssDescVal = tssDesc;
-    physPort->writeBlob(GDTBase + numGDTEntries * 8,
+    physProxy->writeBlob(GDTBase + numGDTEntries * 8,
             (uint8_t *)(&tssDescVal), 8);
 
     numGDTEntries++;
     // read/write, user, not present
     uint64_t pml4e = X86ISA::htog(0x6);
     for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) {
-        physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8);
+        physProxy->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8);
     }
     // Point to the only PDPT
     pml4e = X86ISA::htog(0x7 | PageDirPtrTable);
-    physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
+    physProxy->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
 
     // Page Directory Pointer Table
 
     // read/write, user, not present
     uint64_t pdpe = X86ISA::htog(0x6);
     for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) {
-        physPort->writeBlob(PageDirPtrTable + offset,
+        physProxy->writeBlob(PageDirPtrTable + offset,
                 (uint8_t *)(&pdpe), 8);
     }
     // Point to the PDTs
     for (int table = 0; table < NumPDTs; table++) {
         pdpe = X86ISA::htog(0x7 | PageDirTable[table]);
-        physPort->writeBlob(PageDirPtrTable + table * 8,
+        physProxy->writeBlob(PageDirPtrTable + table * 8,
                 (uint8_t *)(&pdpe), 8);
     }
 
         for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) {
             // read/write, user, present, 4MB
             uint64_t pdte = X86ISA::htog(0x87 | base);
-            physPort->writeBlob(PageDirTable[table] + offset,
+            physProxy->writeBlob(PageDirTable[table] + offset,
                     (uint8_t *)(&pdte), 8);
             base += pageSize;
         }
 X86System::writeOutSMBiosTable(Addr header,
         Addr &headerSize, Addr &structSize, Addr table)
 {
-    // Get a port to write the table and header to memory.
-    FunctionalPort * physPort = threadContexts[0]->getPhysPort();
+    // Get a port proxy to write the table and header to memory.
+    PortProxy* physProxy = threadContexts[0]->getPhysProxy();
 
     // If the table location isn't specified, just put it after the header.
     // The header size as of the 2.5 SMBios specification is 0x1F bytes
         table = header + 0x1F;
     smbiosTable->setTableAddr(table);
 
-    smbiosTable->writeOut(physPort, header, headerSize, structSize);
+    smbiosTable->writeOut(physProxy, header, headerSize, structSize);
 
     // Do some bounds checking to make sure we at least didn't step on
     // ourselves.
 X86System::writeOutMPTable(Addr fp,
         Addr &fpSize, Addr &tableSize, Addr table)
 {
-    // Get a port to write the table and header to memory.
-    FunctionalPort * physPort = threadContexts[0]->getPhysPort();
+    // Get a port proxy to write the table and header to memory.
+    PortProxy* physProxy = threadContexts[0]->getPhysProxy();
 
     // If the table location isn't specified and it exists, just put
     // it after the floating pointer. The fp size as of the 1.4 Intel MP
         mpFloatingPointer->setTableAddr(table);
     }
 
-    fpSize = mpFloatingPointer->writeOut(physPort, fp);
+    fpSize = mpFloatingPointer->writeOut(physProxy, fp);
     if (mpConfigTable)
-        tableSize = mpConfigTable->writeOut(physPort, table);
+        tableSize = mpConfigTable->writeOut(physProxy, table);
     else
         tableSize = 0;
 
 
 }
 
 bool
-ElfObject::loadSections(Port *memPort, Addr addrMask)
+ElfObject::loadSections(PortProxy* memProxy, Addr addrMask)
 {
-    if (!ObjectFile::loadSections(memPort, addrMask))
+    if (!ObjectFile::loadSections(memProxy, addrMask))
         return false;
 
     vector<Segment>::iterator extraIt;
     for (extraIt = extraSegments.begin();
             extraIt != extraSegments.end(); extraIt++) {
-        if (!loadSection(&(*extraIt), memPort, addrMask)) {
+        if (!loadSection(&(*extraIt), memProxy, addrMask)) {
             return false;
         }
     }
 
   public:
     virtual ~ElfObject() {}
 
-    bool loadSections(Port *memPort,
+    bool loadSections(PortProxy *memProxy,
             Addr addrMask = std::numeric_limits<Addr>::max());
     virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
             std::numeric_limits<Addr>::max());
 
 #include "base/loader/hex_file.hh"
 #include "base/loader/symtab.hh"
 #include "base/cprintf.hh"
-#include "mem/translating_port.hh"
+#include "mem/port_proxy.hh"
 
 using namespace std;
 /*
 }
 
 bool
-HexFile::loadSections(Port *memPort)
+HexFile::loadSections(PortProxy* memProxy)
 {
     char Line[64];
     Addr MemAddr;
         parseLine(Line, &MemAddr, &Data);
         if (MemAddr != 0) {
             // Now, write to memory
-            memPort->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
+            memProxy->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
         }
     }
     return true;
 
 
 #include "base/types.hh"
 
-class Port;
+class PortProxy;
 
 class HexFile
 {
     virtual ~HexFile();
 
     void close();
-    bool loadSections(Port *memPort);
+    bool loadSections(PortProxy* memProxy);
 };
 
 #endif // __BASE_LOADER_HEX_FILE_HH__
 
 #include "base/loader/raw_object.hh"
 #include "base/loader/symtab.hh"
 #include "base/cprintf.hh"
-#include "mem/translating_port.hh"
+#include "mem/port_proxy.hh"
 
 using namespace std;
 
 
 
 bool
-ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
+ObjectFile::loadSection(Section *sec, PortProxy* memProxy, Addr addrMask)
 {
     if (sec->size != 0) {
         Addr addr = sec->baseAddr & addrMask;
         if (sec->fileImage) {
-            memPort->writeBlob(addr, sec->fileImage, sec->size);
+            memProxy->writeBlob(addr, sec->fileImage, sec->size);
         }
         else {
             // no image: must be bss
-            memPort->memsetBlob(addr, 0, sec->size);
+            memProxy->memsetBlob(addr, 0, sec->size);
         }
     }
     return true;
 
 
 bool
-ObjectFile::loadSections(Port *memPort, Addr addrMask)
+ObjectFile::loadSections(PortProxy* memProxy, Addr addrMask)
 {
-    return (loadSection(&text, memPort, addrMask)
-            && loadSection(&data, memPort, addrMask)
-            && loadSection(&bss, memPort, addrMask));
+    return (loadSection(&text, memProxy, addrMask)
+            && loadSection(&data, memProxy, addrMask)
+            && loadSection(&bss, memProxy, addrMask));
 }
 
 
 
 
 #include "base/types.hh"
 
-class Port;
+class PortProxy;
 class SymbolTable;
 
 class ObjectFile
 
     void close();
 
-    virtual bool loadSections(Port *memPort, Addr addrMask =
+    virtual bool loadSections(PortProxy *memProxy, Addr addrMask =
             std::numeric_limits<Addr>::max());
     virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
             std::numeric_limits<Addr>::max()) = 0;
     Section data;
     Section bss;
 
-    bool loadSection(Section *sec, Port *memPort, Addr addrMask);
+    bool loadSection(Section *sec, PortProxy* memProxy, Addr addrMask);
     void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
 
   public:
 
 
 #if FULL_SYSTEM
 #include "arch/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #endif
 
 #include "base/intmath.hh"
 #include "cpu/thread_context.hh"
 #include "debug/GDBAll.hh"
 #include "mem/port.hh"
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
 #include "sim/system.hh"
 
 using namespace std;
     DPRINTF(GDBRead, "read:  addr=%#x, size=%d", vaddr, size);
 
 #if FULL_SYSTEM
-    VirtualPort *port = context->getVirtPort();
+    FSTranslatingPortProxy *port = context->getVirtProxy();
 #else
-    TranslatingPort *port = context->getMemPort();
+    SETranslatingPortProxy *port = context->getMemProxy();
 #endif
     port->readBlob(vaddr, (uint8_t*)data, size);
 
             DPRINTFNR("\n");
     }
 #if FULL_SYSTEM
-    VirtualPort *port = context->getVirtPort();
+    FSTranslatingPortProxy *port = context->getVirtProxy();
 #else
-    TranslatingPort *port = context->getMemPort();
+    SETranslatingPortProxy *port = context->getMemProxy();
 #endif
     port->writeBlob(vaddr, (uint8_t*)data, size);
 #if !FULL_SYSTEM
 
     TheISA::Kernel::Statistics *getKernelStats()
     { return actualTC->getKernelStats(); }
 
-    FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
+    PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
 
-    VirtualPort *getVirtPort()
-    { return actualTC->getVirtPort(); }
+    FSTranslatingPortProxy* getVirtProxy()
+    { return actualTC->getVirtProxy(); }
 #else
-    TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
+    SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
 
     Process *getProcessPtr() { return actualTC->getProcessPtr(); }
 #endif
 
 #include "debug/RefCount.hh"
 #include "debug/SkedCache.hh"
 #include "debug/Quiesce.hh"
-#include "mem/translating_port.hh"
 #include "params/InOrderCPU.hh"
 #include "sim/process.hh"
 #include "sim/stat_control.hh"
     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
 
     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
 
     /** Halts the CPU. */
     void halt() { panic("Halt not implemented!\n"); }
 
-    /** Update the Virt and Phys ports of all ThreadContexts to
-     * reflect change in memory connections. */
-    void updateMemPorts();
-
     /** Check if this address is a valid instruction address. */
     bool validInstAddr(Addr addr) { return true; }
 
 
 
 }
 
-void
-CacheUnit::CachePort::setPeer(Port *port)
-{
-    Port::setPeer(port);
-
-#if FULL_SYSTEM
-    // Update the ThreadContext's memory ports (Functional/Virtual
-    // Ports)
-    if (cachePortUnit->resName == "dcache_port") {
-        cachePortUnit->cpu->updateMemPorts();
-    }
-
-#endif
-}
-
 Port *
 CacheUnit::getPort(const string &if_name, int idx)
 {
 
 
         bool snoopRangeSent;
 
-        void setPeer(Port *port);
-
       protected:
         /** Atomic version of receive.  Panics. */
         Tick recvAtomic(PacketPtr pkt);
 
 
 #if FULL_SYSTEM
 
-VirtualPort *
-InOrderThreadContext::getVirtPort()
+FSTranslatingPortProxy*
+InOrderThreadContext::getVirtProxy()
 {
-    return thread->getVirtPort();
+    return thread->getVirtProxy();
 }
 
 
 
     TheISA::Kernel::Statistics *getKernelStats()
     { return thread->kernelStats; }
 
-    FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+    PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
 
-    VirtualPort *getVirtPort();
+    FSTranslatingPortProxy* getVirtProxy();
 
-    void connectMemPorts(ThreadContext *tc)
-    { thread->connectMemPorts(tc); }
+    void initMemProxies(ThreadContext *tc)
+    { thread->initMemProxies(tc); }
 
     /** Dumps the function profiling information.
      * @todo: Implement.
         return this->thread->quiesceEvent;
     }
 #else
-    TranslatingPort *getMemPort() { return thread->getMemPort(); }
+    SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
 
     /** Returns a pointer to this thread's process. */
     Process *getProcessPtr() { return thread->getProcessPtr(); }
 
     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
 
     this->trap(interrupt, 0, NULL);
 }
 
-template <class Impl>
-void
-FullO3CPU<Impl>::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 <class Impl>
 
     /** Halts the CPU. */
     void halt() { panic("Halt not implemented!\n"); }
 
-    /** Update the Virt and Phys ports of all ThreadContexts to
-     * reflect change in memory connections. */
-    void updateMemPorts();
-
     /** Check if this address is a valid instruction address. */
     bool validInstAddr(Addr addr) { return true; }
 
 
 
         bool snoopRangeSent;
 
-        virtual void setPeer(Port *port);
-
       protected:
         /** Atomic version of receive.  Panics. */
         virtual Tick recvAtomic(PacketPtr pkt);
     /** D-cache port. */
     DcachePort dcachePort;
 
-#if FULL_SYSTEM
-    /** Tell the CPU to update the Phys and Virt ports. */
-    void updateMemPorts() { cpu->updateMemPorts(); }
-#endif
-
   protected:
     /** The LSQ policy for SMT mode. */
     LSQPolicy lsqPolicy;
 
 
 using namespace std;
 
-template<class Impl>
-void
-LSQ<Impl>::DcachePort::setPeer(Port *port)
-{
-    Port::setPeer(port);
-
-#if FULL_SYSTEM
-    // Update the ThreadContext's memory ports (Functional/Virtual
-    // Ports)
-    lsq->updateMemPorts();
-#endif
-}
-
 template <class Impl>
 Tick
 LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
 
     virtual TheISA::Kernel::Statistics *getKernelStats()
     { return thread->kernelStats; }
 
-    virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+    virtual PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
 
-    virtual VirtualPort *getVirtPort();
+    virtual FSTranslatingPortProxy* getVirtProxy();
 
-    virtual void connectMemPorts(ThreadContext *tc) { thread->connectMemPorts(tc); }
+    virtual void initMemProxies(ThreadContext *tc)
+    { thread->initMemProxies(tc); }
 #else
-    virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
+    virtual SETranslatingPortProxy* getMemProxy()
+    { return thread->getMemProxy(); }
 
     /** Returns a pointer to this thread's process. */
     virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
 
 
 #if FULL_SYSTEM
 template <class Impl>
-VirtualPort *
-O3ThreadContext<Impl>::getVirtPort()
+FSTranslatingPortProxy*
+O3ThreadContext<Impl>::getVirtProxy()
 {
-    return thread->getVirtPort();
+    return thread->getVirtProxy();
 }
 
 template <class Impl>
 
         TheISA::Kernel::Statistics *getKernelStats()
         { return thread->getKernelStats(); }
 
-        FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+        PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
 
-        VirtualPort *getVirtPort()
-        { return thread->getVirtPort(); }
+        FSTranslatingPortProxy* getVirtProxy()
+        { return thread->getVirtProxy(); }
 #else
-        TranslatingPort *getMemPort() { return thread->getMemPort(); }
+        SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
 
         Process *getProcessPtr() { return thread->getProcessPtr(); }
 #endif
 
     backEnd->renameTable.copyFrom(thread.renameTable);
 
 #if FULL_SYSTEM
-    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);
+    thread.connectMemPorts(tc);
 #endif
 
     DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
 
         // initialize CPU, including PC
         TheISA::initCPU(tc, tc->contextId());
     }
+
+    // Initialise the ThreadContext's memory proxies
+    tcBase()->initMemProxies(tcBase());
 #endif
     if (hasPhysMemPort) {
         bool snoop = false;
     panic("AtomicSimpleCPU doesn't expect recvRetry callback!");
 }
 
-void
-AtomicSimpleCPU::DcachePort::setPeer(Port *port)
-{
-    Port::setPeer(port);
-
-#if FULL_SYSTEM
-    // Update the ThreadContext's memory ports (Functional/Virtual
-    // Ports)
-    cpu->tcBase()->connectMemPorts(cpu->tcBase());
-#endif
-}
-
 AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
     : BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false),
       simulate_data_stalls(p->simulate_data_stalls),
 
     };
     CpuPort icachePort;
 
-    class DcachePort : public CpuPort
-    {
-      public:
-        DcachePort(const std::string &_name, AtomicSimpleCPU *_cpu)
-            : CpuPort(_name, _cpu)
-        { }
-
-        virtual void setPeer(Port *port);
-    };
-    DcachePort dcachePort;
+    CpuPort dcachePort;
 
     CpuPort physmemPort;
     bool hasPhysMemPort;
 
         // initialize CPU, including PC
         TheISA::initCPU(tc, _cpuId);
     }
+
+    // Initialise the ThreadContext's memory proxies
+    tcBase()->initMemProxies(tcBase());
 #endif
 }
 
     drainEvent->process();
 }
 
-void
-TimingSimpleCPU::DcachePort::setPeer(Port *port)
-{
-    Port::setPeer(port);
-
-#if FULL_SYSTEM
-    // Update the ThreadContext's memory ports (Functional/Virtual
-    // Ports)
-    cpu->tcBase()->connectMemPorts(cpu->tcBase());
-#endif
-}
-
 bool
 TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
 {
 
             : CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu)
         { }
 
-        virtual void setPeer(Port *port);
-
       protected:
 
         virtual bool recvTiming(PacketPtr pkt);
 
 #include "base/trace.hh"
 #include "cpu/profile.hh"
 #include "cpu/quiesce_event.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #include "sim/serialize.hh"
 #include "sim/sim_exit.hh"
 #else
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
 #include "sim/process.hh"
 #include "sim/system.hh"
 #endif
 
 SimpleThread::~SimpleThread()
 {
-#if FULL_SYSTEM
-    delete physPort;
-    delete virtPort;
-#endif
     delete tc;
 }
 
 
     System *getSystemPtr() { return system; }
 
 #if FULL_SYSTEM
-    FunctionalPort *getPhysPort() { return physPort; }
+    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; }
 
 class Checkpoint;
 class Decoder;
 class EndQuiesceEvent;
-class TranslatingPort;
-class FunctionalPort;
-class VirtualPort;
+class SETranslatingPortProxy;
+class FSTranslatingPortProxy;
+class PortProxy;
 class Process;
 class System;
 namespace TheISA {
 #if FULL_SYSTEM
     virtual TheISA::Kernel::Statistics *getKernelStats() = 0;
 
-    virtual FunctionalPort *getPhysPort() = 0;
+    virtual PortProxy* getPhysProxy() = 0;
 
-    virtual VirtualPort *getVirtPort() = 0;
+    virtual FSTranslatingPortProxy* getVirtProxy() = 0;
 
-    virtual void connectMemPorts(ThreadContext *tc) = 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 TranslatingPort *getMemPort() = 0;
+    virtual SETranslatingPortProxy *getMemProxy() = 0;
 
     virtual Process *getProcessPtr() = 0;
 #endif
     TheISA::Kernel::Statistics *getKernelStats()
     { return actualTC->getKernelStats(); }
 
-    FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
+    PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
 
-    VirtualPort *getVirtPort() { return actualTC->getVirtPort(); }
+    FSTranslatingPortProxy* getVirtProxy() { return actualTC->getVirtProxy(); }
 
-    void connectMemPorts(ThreadContext *tc) { actualTC->connectMemPorts(tc); }
+    void initMemProxies(ThreadContext *tc) { actualTC->initMemProxies(tc); }
 #else
-    TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
+    SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
 
     Process *getProcessPtr() { return actualTC->getProcessPtr(); }
 #endif
 
 #include "cpu/base.hh"
 #include "cpu/profile.hh"
 #include "cpu/thread_state.hh"
-#include "mem/port.hh"
-#include "mem/translating_port.hh"
+#include "mem/port_proxy.hh"
+#include "mem/se_translating_port_proxy.hh"
 #include "sim/serialize.hh"
+#include "sim/system.hh"
 
 #if FULL_SYSTEM
 #include "arch/kernel_stats.hh"
 #include "cpu/quiesce_event.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #endif
 
 #if FULL_SYSTEM
       baseCpu(cpu), _threadId(_tid), lastActivate(0), lastSuspend(0),
 #if FULL_SYSTEM
       profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
-      kernelStats(NULL), physPort(NULL), virtPort(NULL),
+      kernelStats(NULL), physProxy(NULL), virtProxy(NULL),
 #else
-      port(NULL), process(_process),
+      proxy(NULL), process(_process),
 #endif
       funcExeInst(0), storeCondFailures(0)
 {
 
 ThreadState::~ThreadState()
 {
-#if !FULL_SYSTEM
-    if (port) {
-        delete port->getPeer();
-        delete port;
+#if FULL_SYSTEM
+    if (physProxy != NULL) {
+        delete physProxy;
+    }
+    if (virtProxy != NULL) {
+        delete virtProxy;
+    }
+#else
+    if (proxy != NULL) {
+        delete proxy;
     }
 #endif
 }
 
 #if FULL_SYSTEM
 void
-ThreadState::connectMemPorts(ThreadContext *tc)
+ThreadState::initMemProxies(ThreadContext *tc)
 {
-    connectPhysPort();
-    connectVirtPort(tc);
-}
-
-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);
+    // 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
 }
 
 #else
-TranslatingPort *
-ThreadState::getMemPort()
+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);
+    if (proxy != NULL)
+        return proxy;
 
-    connectToMemFunc(port);
+    /* Use this port proxy to for syscall emulation writes to memory. */
+    proxy = new SETranslatingPortProxy(*process->system->getSystemPort(),
+                                       process,
+                                       SETranslatingPortProxy::NextPage);
 
-    return port;
+    return proxy;
 }
 #endif
-
-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);
-
-    func_mem_port = mem_object->getPort("functional");
-    assert(func_mem_port != NULL);
-
-    func_mem_port->setPeer(port);
-    port->setPeer(func_mem_port);
-}
 
 #endif
 
 class Checkpoint;
-class Port;
-class TranslatingPort;
+class PortProxy;
+class SETranslatingPort;
+class FSTranslatingPort;
 
 /**
  *  Struct for holding general thread state that is needed across CPU
     Tick readLastSuspend() { return lastSuspend; }
 
 #if FULL_SYSTEM
-    void connectMemPorts(ThreadContext *tc);
-
-    void connectPhysPort();
-
-    void connectVirtPort(ThreadContext *tc);
+    /**
+     * 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();
 
 
     TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
 
-    FunctionalPort *getPhysPort() { return physPort; }
+    PortProxy* getPhysProxy() { return physProxy; }
 
-    void setPhysPort(FunctionalPort *port) { physPort = port; }
-
-    VirtualPort *getVirtPort() { return virtPort; }
+    FSTranslatingPortProxy* getVirtProxy() { return virtProxy; }
 #else
     Process *getProcessPtr() { return process; }
 
-    TranslatingPort *getMemPort();
-
-    void setMemPort(TranslatingPort *_port) { port = _port; }
+    SETranslatingPortProxy* getMemProxy();
 #endif
 
     /** Reads the number of instructions functionally executed and
     void setStatus(Status new_status) { _status = new_status; }
 
   public:
-    /** Connects port to the functional port of the memory object
-     * below the CPU. */
-    void connectToMemFunc(Port *port);
 
     /** Number of instructions committed. */
     Counter numInst;
 
     TheISA::Kernel::Statistics *kernelStats;
   protected:
-    /** 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 functional port, outgoing only, for functional accesse to virtual
-     * addresses. */
-    VirtualPort *virtPort;
+    /** A translating port proxy, outgoing only, for functional
+     * accesse to virtual addresses. */
+    FSTranslatingPortProxy* virtProxy;
 #else
-    TranslatingPort *port;
+    SETranslatingPortProxy* proxy;
 
     Process *process;
 #endif
 
 #include "debug/SimpleDiskData.hh"
 #include "dev/disk_image.hh"
 #include "dev/simple_disk.hh"
-#include "mem/port.hh"
+#include "mem/port_proxy.hh"
 #include "sim/system.hh"
 
 using namespace std;
     for (int i = 0, j = 0; i < count; i += SectorSize, j++)
         image->read(data + i, block + j);
 
-    system->functionalPort->writeBlob(addr, data, count);
+    system->physProxy->writeBlob(addr, data, count);
 
     DPRINTF(SimpleDisk, "read  block=%#x len=%d\n", (uint64_t)block, count);
     DDUMP(SimpleDiskData, data, count);
 
 typedef struct statfs global_statfs;
 typedef struct dirent global_dirent;
 
-class TranslatingPort;
+class SETranslatingPortProxy;
 
 ///
 /// This class encapsulates the types, structures, constants,
     /// memory space.  Used by statfs() and fstatfs().
     template <class T>
     static void
-    copyOutStatfsBuf(TranslatingPort *mem, Addr addr, global_statfs *host)
+    copyOutStatfsBuf(SETranslatingPortProxy *mem, Addr addr,
+                     global_statfs *host)
     {
         using namespace TheISA;
 
 
         // just pass basep through uninterpreted.
         TypedBufferArg<int64_t> basep(tgt_basep);
-        basep.copyIn(tc->getMemPort());
+        basep.copyIn(tc->getMemProxy());
         long host_basep = (off_t)htog((int64_t)*basep);
         int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
 
             tgt_dp->d_reclen = tgt_bufsize;
             tgt_dp->d_namlen = namelen;
             strcpy(tgt_dp->d_name, host_dp->d_name);
-            tgt_dp.copyOut(tc->getMemPort());
+            tgt_dp.copyOut(tc->getMemProxy());
 
             tgt_buf_ptr += tgt_bufsize;
             host_buf_ptr += host_dp->d_reclen;
         delete [] host_buf;
 
         *basep = htog((int64_t)host_basep);
-        basep.copyOut(tc->getMemPort());
+        basep.copyOut(tc->getMemProxy());
 
         return tgt_buf_ptr - tgt_buf;
 #endif
         int index = 0;
         TypedBufferArg<Tru64::sigcontext> sc(process->getSyscallArg(tc, index));
 
-        sc.copyIn(tc->getMemPort());
+        sc.copyIn(tc->getMemProxy());
 
         // Restore state from sigcontext structure.
         // Note that we'll advance PC <- NPC before the end of the cycle,
         int index = 0;
         TypedBufferArg<Tru64::vm_stack> argp(process->getSyscallArg(tc, index));
 
-        argp.copyIn(tc->getMemPort());
+        argp.copyIn(tc->getMemProxy());
 
         int stack_size =
             gtoh(argp->rsize) + gtoh(argp->ysize) + gtoh(argp->gsize);
         process->allocateMem(rounded_stack_base, rounded_stack_size);
 
         argp->address = gtoh(rounded_stack_base);
-        argp.copyOut(tc->getMemPort());
+        argp.copyOut(tc->getMemProxy());
 
         return 0;
     }
             attrp(process->getSyscallArg(tc, index));
         TypedBufferArg<Addr> configptr_ptr(process->getSyscallArg(tc, index));
 
-        attrp.copyIn(tc->getMemPort());
+        attrp.copyIn(tc->getMemProxy());
 
         if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) {
             cerr << "nxm_task_init: thread library version mismatch! "
         int size = cur_addr - base_addr;
         process->allocateMem(base_addr, roundUp(size, VMPageSize));
 
-        config.copyOut(tc->getMemPort());
-        slot_state.copyOut(tc->getMemPort());
-        rad_state.copyOut(tc->getMemPort());
-        configptr_ptr.copyOut(tc->getMemPort());
+        config.copyOut(tc->getMemProxy());
+        slot_state.copyOut(tc->getMemProxy());
+        rad_state.copyOut(tc->getMemProxy());
+        configptr_ptr.copyOut(tc->getMemProxy());
 
         return 0;
     }
         int thread_index = process->getSyscallArg(tc, index);
 
         // get attribute args
-        attrp.copyIn(tc->getMemPort());
+        attrp.copyIn(tc->getMemProxy());
 
         if (gtoh(attrp->version) != NXM_LIB_VERSION) {
             cerr << "nxm_thread_create: thread library version mismatch! "
 
         TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
                                                     rad_state_size);
-        rad_state.copyIn(tc->getMemPort());
+        rad_state.copyIn(tc->getMemProxy());
 
         uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset);
 
 
             // This is supposed to be a port number.  Make something up.
             *kidp = htog(99);
-            kidp.copyOut(tc->getMemPort());
+            kidp.copyOut(tc->getMemProxy());
 
             return 0;
         } else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) {
             ssp->nxm_u.pth_id = attrp->pthid;
             ssp->nxm_u.nxm_active = htog(uniq_val | 1);
 
-            rad_state.copyOut(tc->getMemPort());
+            rad_state.copyOut(tc->getMemProxy());
 
             Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info);
             int slot_state_size =
                 slot_state(slot_state_addr,
                            slot_state_size);
 
-            slot_state.copyIn(tc->getMemPort());
+            slot_state.copyIn(tc->getMemProxy());
 
             if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
                 cerr << "nxm_thread_createFunc: requested VP slot "
             // doesn't work anyway
             slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
 
-            slot_state.copyOut(tc->getMemPort());
+            slot_state.copyOut(tc->getMemProxy());
 
             // Find a free simulator thread context.
             ThreadContext *tc = process->findFreeContext();
                 // and get away with just sticking the thread index
                 // here.
                 *kidp = htog(thread_index);
-                kidp.copyOut(tc->getMemPort());
+                kidp.copyOut(tc->getMemProxy());
 
                 return 0;
             }
 
         TypedBufferArg<uint64_t> lockp(uaddr);
 
-        lockp.copyIn(tc->getMemPort());
+        lockp.copyIn(tc->getMemProxy());
 
         if (gtoh(*lockp) == 0) {
             // lock is free: grab it
             *lockp = htog(1);
-            lockp.copyOut(tc->getMemPort());
+            lockp.copyOut(tc->getMemProxy());
         } else {
             // lock is busy: disable until free
             process->waitList.push_back(Process::WaitRec(uaddr, tc));
     {
         TypedBufferArg<uint64_t> lockp(uaddr);
 
-        lockp.copyIn(tc->getMemPort());
+        lockp.copyIn(tc->getMemProxy());
         assert(*lockp != 0);
 
         // Check for a process waiting on the lock.
         // clear lock field if no waiting context is taking over the lock
         if (num_waiting == 0) {
             *lockp = 0;
-            lockp.copyOut(tc->getMemPort());
+            lockp.copyOut(tc->getMemProxy());
         }
     }
 
         Addr uaddr = process->getSyscallArg(tc, index);
         TypedBufferArg<uint64_t> lockp(uaddr);
 
-        lockp.copyIn(tc->getMemPort());
+        lockp.copyIn(tc->getMemProxy());
 
         if (gtoh(*lockp) == 0) {
             // lock is free: grab it
             *lockp = htog(1);
-            lockp.copyOut(tc->getMemPort());
+            lockp.copyOut(tc->getMemProxy());
             return 0;
         } else {
             return 1;
         TypedBufferArg<uint64_t> lockp(lock_addr);
 
         // user is supposed to acquire lock before entering
-        lockp.copyIn(tc->getMemPort());
+        lockp.copyIn(tc->getMemProxy());
         assert(gtoh(*lockp) != 0);
 
         m5_unlock_mutex(lock_addr, process, tc);
 
     typedef F64_stat tgt_stat;
 /*
-    static void copyOutStatBuf(TranslatingPort *mem, Addr addr,
+    static void copyOutStatBuf(SETranslatingPortProxy *mem, Addr addr,
                                global_stat *host)
     {
         Tru64::copyOutStatBuf<Tru64::F64_stat>(mem, addr, host);
     }*/
 
-    static void copyOutStatfsBuf(TranslatingPort *mem, Addr addr,
+    static void copyOutStatfsBuf(SETranslatingPortProxy *mem, Addr addr,
                                  global_statfs *host)
     {
         Tru64::copyOutStatfsBuf<Tru64::F64_statfs>(mem, addr, host);
 
     typedef pre_F64_stat tgt_stat;
 /*
-    static void copyOutStatBuf(TranslatingPort *mem, Addr addr,
+    static void copyOutStatBuf(SETranslatingPortProxy *mem, Addr addr,
                                global_stat *host)
     {
         Tru64::copyOutStatBuf<Tru64::pre_F64_stat>(mem, addr, host);
     }*/
 
-    static void copyOutStatfsBuf(TranslatingPort *mem, Addr addr,
+    static void copyOutStatfsBuf(SETranslatingPortProxy *mem, Addr addr,
                                  global_statfs *host)
     {
         Tru64::copyOutStatfsBuf<Tru64::pre_F64_statfs>(mem, addr, host);
 
     AddrRangeIter iter;
     bool found = false;
 
-    tc->getPhysPort()->getPeerAddressRanges(resp, snoop);
+    Port* dataPort = tc->getCpuPtr()->getPort("dcache_port");
+
+    dataPort->getPeerAddressRanges(resp, snoop);
     for (iter = resp.begin(); iter != resp.end(); iter++) {
         if (*iter == (K0Seg2Phys(a0) & PAddrImplMask))
             found = true;
 
     Source('physical.cc')
 
 if env['FULL_SYSTEM']:
-    Source('vport.cc')
+    Source('fs_translating_port_proxy.cc')
 elif env['TARGET_ISA'] != 'no':
     Source('page_table.cc')
-    Source('translating_port.cc')
+    Source('se_translating_port_proxy.cc')
 
 DebugFlag('Bus')
 DebugFlag('BusAddrRanges')
 
--- /dev/null
+/*
+ * 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) 2006 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: Ali Saidi
+ *          Andreas Hansson
+ */
+
+/**
+ * @file
+ * Port object definitions.
+ */
+
+#include "base/chunk_generator.hh"
+#include "cpu/base.hh"
+#include "cpu/thread_context.hh"
+#include "mem/fs_translating_port_proxy.hh"
+
+using namespace TheISA;
+
+FSTranslatingPortProxy::FSTranslatingPortProxy(ThreadContext *tc)
+    : PortProxy(*(tc->getCpuPtr()->getPort("dcache_port"))), _tc(tc)
+{
+}
+
+FSTranslatingPortProxy::FSTranslatingPortProxy(Port &port)
+    : PortProxy(port), _tc(NULL)
+{
+}
+
+FSTranslatingPortProxy::~FSTranslatingPortProxy()
+{
+}
+
+void
+FSTranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
+{
+    Addr paddr;
+    for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
+         gen.next())
+    {
+        if (_tc)
+            paddr = TheISA::vtophys(_tc,gen.addr());
+        else
+            paddr = TheISA::vtophys(gen.addr());
+
+        PortProxy::readBlob(paddr, p, gen.size());
+        p += gen.size();
+    }
+}
+
+void
+FSTranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
+{
+    Addr paddr;
+    for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
+         gen.next())
+    {
+        if (_tc)
+            paddr = TheISA::vtophys(_tc,gen.addr());
+        else
+            paddr = TheISA::vtophys(gen.addr());
+
+        PortProxy::writeBlob(paddr, p, gen.size());
+        p += gen.size();
+    }
+}
+
+void
+FSTranslatingPortProxy::memsetBlob(Addr address, uint8_t v, int size)
+{
+    Addr paddr;
+    for (ChunkGenerator gen(address, size, TheISA::PageBytes); !gen.done();
+         gen.next())
+    {
+        if (_tc)
+            paddr = TheISA::vtophys(_tc,gen.addr());
+        else
+            paddr = TheISA::vtophys(gen.addr());
+
+        PortProxy::memsetBlob(paddr, v, gen.size());
+    }
+}
+
+void
+CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
+{
+    uint8_t *dst = (uint8_t *)dest;
+    FSTranslatingPortProxy* vp = tc->getVirtProxy();
+
+    vp->readBlob(src, dst, cplen);
+}
+
+void
+CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
+{
+    uint8_t *src = (uint8_t *)source;
+    FSTranslatingPortProxy* vp = tc->getVirtProxy();
+
+    vp->writeBlob(dest, src, cplen);
+}
+
+void
+CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
+{
+    int len = 0;
+    char *start = dst;
+    FSTranslatingPortProxy* vp = tc->getVirtProxy();
+
+    do {
+        vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
+    } while (len < maxlen && start[len++] != 0 );
+
+    dst[len] = 0;
+}
+
+void
+CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
+{
+    FSTranslatingPortProxy* vp = tc->getVirtProxy();
+    for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
+            gen.next())
+    {
+        vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
+        src += gen.size();
+    }
+}
 
--- /dev/null
+/*
+ * 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) 2006 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: Ali Saidi
+ *          Andreas Hansson
+ */
+
+/**
+ * @file
+ * TranslatingPortProxy Object Declaration for FS.
+ *
+ * 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.
+ */
+
+#ifndef __MEM_FS_PORT_PROXY_HH__
+#define __MEM_FS_PORT_PROXY_HH__
+
+#include "arch/vtophys.hh"
+#include "mem/port_proxy.hh"
+
+/**
+ * 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).
+ */
+class FSTranslatingPortProxy : public PortProxy
+{
+  private:
+    ThreadContext* _tc;
+
+  public:
+
+    FSTranslatingPortProxy(ThreadContext* tc);
+
+    FSTranslatingPortProxy(Port &port);
+
+    virtual ~FSTranslatingPortProxy();
+
+    /** Version of readblob that translates virt->phys and deals
+      * with page boundries. */
+    virtual void readBlob(Addr addr, uint8_t *p, int size);
+
+    /** Version of writeBlob that translates virt->phys and deals
+      * with page boundries. */
+    virtual void writeBlob(Addr addr, uint8_t *p, int size);
+
+    /**
+     * Fill size bytes starting at addr with byte value val.
+     */
+    virtual void memsetBlob(Addr address, uint8_t  v, int size);
+};
+
+void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen);
+void CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen);
+void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
+void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
+
+#endif //__MEM_FS_PORT_PROXY_HH__
 
     void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd);
 };
 
-/** A simple functional port that is only meant for one way communication to
- * physical memory. It is only meant to be used to load data into memory before
- * the simulation begins.
- */
-
-class FunctionalPort : public Port
-{
-  public:
-    FunctionalPort(const std::string &_name, MemObject *_owner = NULL)
-        : Port(_name, _owner)
-    {}
-
-  protected:
-    virtual bool recvTiming(PacketPtr pkt) { panic("FuncPort is UniDir");
-        M5_DUMMY_RETURN }
-    virtual Tick recvAtomic(PacketPtr pkt) { panic("FuncPort is UniDir");
-        M5_DUMMY_RETURN }
-    virtual void recvFunctional(PacketPtr pkt) { panic("FuncPort is UniDir"); }
-    virtual void recvStatusChange(Status status) {}
-
-  public:
-    /** a write function that also does an endian conversion. */
-    template <typename T>
-    inline void writeHtoG(Addr addr, T d);
-
-    /** a read function that also does an endian conversion. */
-    template <typename T>
-    inline T readGtoH(Addr addr);
-
-    template <typename T>
-    inline void write(Addr addr, T d)
-    {
-        writeBlob(addr, (uint8_t*)&d, sizeof(T));
-    }
-
-    template <typename T>
-    inline T read(Addr addr)
-    {
-        T d;
-        readBlob(addr, (uint8_t*)&d, sizeof(T));
-        return d;
-    }
-};
-
 #endif //__MEM_PORT_HH__
 
+++ /dev/null
-/*
- * Copyright (c) 2006 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: Ali Saidi
- */
-
-#include "arch/isa_traits.hh"
-#include "config/the_isa.hh"
-#include "mem/port.hh"
-#include "sim/byteswap.hh"
-
-template <typename T>
-void
-FunctionalPort::writeHtoG(Addr addr, T d)
-{
-    d = TheISA::htog(d);
-    writeBlob(addr, (uint8_t*)&d, sizeof(T));
-}
-
-
-template <typename T>
-T
-FunctionalPort::readGtoH(Addr addr)
-{
-    T d;
-    readBlob(addr, (uint8_t*)&d, sizeof(T));
-    return TheISA::gtoh(d);
-}
-
 
--- /dev/null
+/*
+ * 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.
+ *
+ * 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: Andreas Hansson
+ */
+
+/**
+ * @file
+ * PortProxy Object Declaration.
+ *
+ * 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.
+ */
+
+#ifndef __MEM_PORT_PROXY_HH__
+#define __MEM_PORT_PROXY_HH__
+
+#include "config/the_isa.hh"
+#if THE_ISA != NO_ISA
+    #include "arch/isa_traits.hh"
+#endif
+
+#include "base/types.hh"
+#include "mem/port.hh"
+#include "sim/byteswap.hh"
+
+/**
+ * This object is a proxy for a structural port,
+ * to be used for debug accesses.
+ *
+ * This proxy object is used when non structural entities
+ * (e.g. thread contexts, object file loaders) need access to the
+ * memory system. It calls the corresponding functions on the underlying
+ * structural port, and provides templatized convenience access functions.
+ *
+ * The addresses are interpreted as physical addresses.
+ *
+ * @sa SETranslatingProxy
+ * @sa FSTranslatingProxy
+ */
+class PortProxy
+{
+  protected:
+    Port &_port;
+
+  public:
+    PortProxy(Port &port) : _port(port) { }
+    virtual ~PortProxy() { }
+
+  public:
+    /**
+     * Read size bytes memory at address and store in p.
+     */
+    virtual void readBlob(Addr address, uint8_t* p, int size)
+    { _port.readBlob(address, p, size); }
+
+    /**
+     * Write size bytes from p to address.
+     */
+    virtual void writeBlob(Addr address, uint8_t* p, int size)
+    { _port.writeBlob(address, p, size); }
+
+    /**
+     * Fill size bytes starting at addr with byte value val.
+     */
+    virtual void memsetBlob(Addr address, uint8_t  v, int size)
+    { _port.memsetBlob(address, v, size); }
+
+    /**
+     * Read sizeof(T) bytes from address and return as object T.
+     */
+    template <typename T>
+    T read(Addr address);
+
+    /**
+     * Write object T to address. Writes sizeof(T) bytes.
+     */
+    template <typename T>
+    void write(Addr address, T data);
+
+#if THE_ISA != NO_ISA
+    /**
+     * Read sizeof(T) bytes from address and return as object T.
+     * Performs Guest to Host endianness transform.
+     */
+    template <typename T>
+    T readGtoH(Addr address);
+
+    /**
+     * Write object T to address. Writes sizeof(T) bytes.
+     * Performs Host to Guest endianness transform.
+     */
+    template <typename T>
+    void writeHtoG(Addr address, T data);
+#endif
+};
+
+
+template <typename T>
+T
+PortProxy::read(Addr address)
+{
+    T data;
+    readBlob(address, (uint8_t*)&data, sizeof(T));
+    return data;
+}
+
+template <typename T>
+void
+PortProxy::write(Addr address, T data)
+{
+    writeBlob(address, (uint8_t*)&data, sizeof(T));
+}
+
+#if THE_ISA != NO_ISA
+template <typename T>
+T
+PortProxy::readGtoH(Addr address)
+{
+    T data;
+    readBlob(address, (uint8_t*)&data, sizeof(T));
+    return TheISA::gtoh(data);
+}
+
+template <typename T>
+void
+PortProxy::writeHtoG(Addr address, T data)
+{
+    data = TheISA::htog(data);
+    writeBlob(address, (uint8_t*)&data, sizeof(T));
+}
+#endif
+
+#endif // __MEM_PORT_PROXY_HH__
 
     // turn packet around to go back to requester if response expected
     if (needsResponse) {
         pkt->setFunctionalResponseStatus(accessSucceeded);
-        DPRINTF(RubyPort, "Sending packet back over port\n");
-        sendFunctional(pkt);
+
+        // @todo There should not be a reverse call since the response is
+        // communicated through the packet pointer
+        // DPRINTF(RubyPort, "Sending packet back over port\n");
+        // sendFunctional(pkt);
     }
     DPRINTF(RubyPort, "Functional access %s!\n",
             accessSucceeded ? "successful":"failed");
 
--- /dev/null
+/*
+ * 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.
+ *
+ * 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: Andreas Hansson
+ */
+
+#include "mem/ruby/system/RubyPortProxy.hh"
+
+RubyPortProxy::RubyPortProxy(const RubyPortProxyParams* p) :
+    RubyPort(p) {
+}
+
+RubyPortProxy::~RubyPortProxy()
+{
+}
+
+void
+RubyPortProxy::init()
+{
+    // Merely override to not care about the m_controller being NULL
+}
+
+RequestStatus
+RubyPortProxy::makeRequest(PacketPtr pkt)
+{
+    // This sequencer should only be used through the functional
+    // accesses made by the system port and so simply fail if this
+    // happens.
+    panic("RubyPortProxy::makeRequest should not be called");
+    return RequestStatus_NULL;
+}
+
+RubyPortProxy*
+RubyPortProxyParams::create()
+{
+    return new RubyPortProxy(this);
+}
 
--- /dev/null
+/*
+ * 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.
+ *
+ * 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: Andreas Hansson
+ */
+
+/**
+ * @file
+ * RobyPortProxy for connecting system port to Ruby
+ *
+ * A trivial wrapper that allows the system port to connect to Ruby
+ * and use nothing but functional accesses.
+ */
+
+#ifndef __MEM_RUBY_SYSTEM_RUBYPORTPROXY_HH__
+#define __MEM_RUBY_SYSTEM_RUBYPORTPROXY_HH__
+
+#include "mem/ruby/system/RubyPort.hh"
+#include "params/RubyPortProxy.hh"
+
+class RubyPortProxy : public RubyPort
+{
+
+  public:
+
+    /**
+     * Create a new RubyPortProxy.
+     *
+     * @param p Parameters inherited from the RubyPort
+     */
+    RubyPortProxy(const RubyPortProxyParams* p);
+
+    /**
+     * Destruct a RubyPortProxy.
+     */
+    virtual ~RubyPortProxy();
+
+    /**
+     * Initialise a RubyPortProxy by doing nothing and avoid
+     * involving the super class.
+     */
+    void init();
+
+    /**
+     * Pure virtual member in the super class that we are forced to
+     * implement even if it is never used (since there are only
+     * functional accesses).
+     *
+     * @param pkt The packet to serve to Ruby
+     * @returns always a NULL status
+     */
+    RequestStatus makeRequest(PacketPtr pkt);
+
+    /**
+     * Pure virtual member in the super class that we are forced to
+     * implement even if it is never used (since there are only
+     * functional accesses).
+     *
+     * @returns always 0
+     */
+    int outstandingCount() const { return 0; }
+
+    /**
+     * Pure virtual member in the super class that we are forced to
+     * implement even if it is never used (since there are only
+     * functional accesses).
+     *
+     * @returns always false
+     */
+    bool isDeadlockEventScheduled() const { return false; }
+
+    /**
+     * Pure virtual member in the super class that we are forced to
+     * implement even if it is never used (since there are only
+     * functional accesses).
+     */
+    void descheduleDeadlockEvent() { }
+
+};
+
+#endif // __MEM_RUBY_SYSTEM_RUBYPORTPROXY_HH__
 
 Source('MemoryNode.cc')
 Source('PersistentTable.cc')
 Source('RubyPort.cc')
+Source('RubyPortProxy.cc')
 Source('Sequencer.cc')
 Source('System.cc')
 Source('TimerTable.cc')
 
     access_phys_mem = Param.Bool(True,
         "should the rubyport atomically update phys_mem")
     ruby_system = Param.RubySystem("")
+
+class RubyPortProxy(RubyPort):
+    type = 'RubyPortProxy'
     
 class RubySequencer(RubyPort):
     type = 'RubySequencer'
 
--- /dev/null
+/*
+ * 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 <string>
+
+#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()) {
+
+        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()) {
+
+        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()) {
+
+        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;
+
+    do {
+        c = *str++;
+        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;
+
+    do {
+        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);
+}
+
 
--- /dev/null
+/*
+ * 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
+ *          Ali Saidi
+ *          Andreas Hansson
+ */
+
+#ifndef __MEM_SE_TRANSLATING_PORT_PROXY_HH__
+#define __MEM_SE_TRANSLATING_PORT_PROXY_HH__
+
+#include "mem/page_table.hh"
+#include "mem/port_proxy.hh"
+#include "sim/process.hh"
+
+/**
+ * @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
+{
+
+  public:
+    enum AllocType {
+        Always,
+        Never,
+        NextPage
+    };
+
+  private:
+    PageTable *pTable;
+    Process *process;
+    AllocType allocating;
+
+  public:
+    SETranslatingPortProxy(Port& port, Process* p, AllocType alloc);
+    virtual ~SETranslatingPortProxy();
+
+    bool tryReadBlob(Addr addr, uint8_t *p, int size);
+    bool tryWriteBlob(Addr addr, uint8_t *p, int size);
+    bool tryMemsetBlob(Addr addr, uint8_t val, int size);
+    bool tryWriteString(Addr addr, const char *str);
+    bool tryReadString(std::string &str, Addr addr);
+
+    virtual void readBlob(Addr addr, uint8_t *p, int size);
+    virtual void writeBlob(Addr addr, uint8_t *p, int size);
+    virtual void memsetBlob(Addr addr, uint8_t val, int size);
+
+    void writeString(Addr addr, const char *str);
+    void readString(std::string &str, Addr addr);
+};
+
+#endif // __MEM_SE_TRANSLATING_PORT_PROXY_HH__
 
+++ /dev/null
-/*
- * 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
- */
-
-#include <string>
-
-#include "base/chunk_generator.hh"
-#include "config/the_isa.hh"
-#include "mem/page_table.hh"
-#include "mem/port.hh"
-#include "mem/translating_port.hh"
-#include "sim/process.hh"
-
-using namespace TheISA;
-
-TranslatingPort::TranslatingPort(const std::string &_name,
-                                 Process *p, AllocType alloc)
-    : FunctionalPort(_name), pTable(p->pTable), process(p),
-      allocating(alloc)
-{ }
-
-TranslatingPort::~TranslatingPort()
-{ }
-
-bool
-TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
-{
-    Addr paddr;
-    int prevSize = 0;
-
-    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
-
-        if (!pTable->translate(gen.addr(),paddr))
-            return false;
-
-        Port::readBlob(paddr, p + prevSize, gen.size());
-        prevSize += gen.size();
-    }
-
-    return true;
-}
-
-void
-TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
-{
-    if (!tryReadBlob(addr, p, size))
-        fatal("readBlob(0x%x, ...) failed", addr);
-}
-
-
-bool
-TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
-{
-
-    Addr paddr;
-    int prevSize = 0;
-
-    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
-
-        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);
-        }
-
-        Port::writeBlob(paddr, p + prevSize, gen.size());
-        prevSize += gen.size();
-    }
-
-    return true;
-}
-
-
-void
-TranslatingPort::writeBlob(Addr addr, uint8_t *p, int size)
-{
-    if (!tryWriteBlob(addr, p, size))
-        fatal("writeBlob(0x%x, ...) failed", addr);
-}
-
-bool
-TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
-{
-    Addr paddr;
-
-    for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
-
-        if (!pTable->translate(gen.addr(), paddr)) {
-            if (allocating == Always) {
-                process->allocateMem(roundDown(gen.addr(), VMPageSize),
-                                     VMPageSize);
-                pTable->translate(gen.addr(), paddr);
-            } else {
-                return false;
-            }
-        }
-
-        Port::memsetBlob(paddr, val, gen.size());
-    }
-
-    return true;
-}
-
-void
-TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size)
-{
-    if (!tryMemsetBlob(addr, val, size))
-        fatal("memsetBlob(0x%x, ...) failed", addr);
-}
-
-
-bool
-TranslatingPort::tryWriteString(Addr addr, const char *str)
-{
-    Addr paddr,vaddr;
-    uint8_t c;
-
-    vaddr = addr;
-
-    do {
-        c = *str++;
-        if (!pTable->translate(vaddr++,paddr))
-            return false;
-
-        Port::writeBlob(paddr, &c, 1);
-    } while (c);
-
-    return true;
-}
-
-void
-TranslatingPort::writeString(Addr addr, const char *str)
-{
-    if (!tryWriteString(addr, str))
-        fatal("writeString(0x%x, ...) failed", addr);
-}
-
-bool
-TranslatingPort::tryReadString(std::string &str, Addr addr)
-{
-    Addr paddr,vaddr;
-    uint8_t c;
-
-    vaddr = addr;
-
-    do {
-        if (!pTable->translate(vaddr++,paddr))
-            return false;
-
-        Port::readBlob(paddr, &c, 1);
-        str += c;
-    } while (c);
-
-    return true;
-}
-
-void
-TranslatingPort::readString(std::string &str, Addr addr)
-{
-    if (!tryReadString(str, addr))
-        fatal("readString(0x%x, ...) failed", addr);
-}
-
 
+++ /dev/null
-/*
- * 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
- *          Ali Saidi
- */
-
-#ifndef __MEM_TRANSLATING_PROT_HH__
-#define __MEM_TRANSLATING_PROT_HH__
-
-#include "mem/port.hh"
-
-class PageTable;
-class Process;
-
-class TranslatingPort : public FunctionalPort
-{
-  public:
-    enum AllocType {
-        Always,
-        Never,
-        NextPage
-    };
-
-  private:
-    PageTable *pTable;
-    Process *process;
-    AllocType allocating;
-
-  public:
-    TranslatingPort(const std::string &_name,
-                    Process *p, AllocType alloc);
-    virtual ~TranslatingPort();
-
-    bool tryReadBlob(Addr addr, uint8_t *p, int size);
-    bool tryWriteBlob(Addr addr, uint8_t *p, int size);
-    bool tryMemsetBlob(Addr addr, uint8_t val, int size);
-    bool tryWriteString(Addr addr, const char *str);
-    bool tryReadString(std::string &str, Addr addr);
-
-    virtual void readBlob(Addr addr, uint8_t *p, int size);
-    virtual void writeBlob(Addr addr, uint8_t *p, int size);
-    virtual void memsetBlob(Addr addr, uint8_t val, int size);
-
-    void writeString(Addr addr, const char *str);
-    void readString(std::string &str, Addr addr);
-};
-
-#endif
 
+++ /dev/null
-/*
- * Copyright (c) 2006 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: Ali Saidi
- */
-
-/**
- * @file
- * Port object definitions.
- */
-
-#include "base/chunk_generator.hh"
-#include "config/the_isa.hh"
-#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
-
-void
-VirtualPort::readBlob(Addr addr, uint8_t *p, int size)
-{
-    Addr paddr;
-    for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
-            gen.next())
-    {
-        if (tc)
-            paddr = TheISA::vtophys(tc,gen.addr());
-        else
-            paddr = TheISA::vtophys(gen.addr());
-
-        FunctionalPort::readBlob(paddr, p, gen.size());
-        p += gen.size();
-    }
-}
-
-void
-VirtualPort::writeBlob(Addr addr, uint8_t *p, int size)
-{
-    Addr paddr;
-    for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
-            gen.next())
-    {
-        if (tc)
-            paddr = TheISA::vtophys(tc,gen.addr());
-        else
-            paddr = TheISA::vtophys(gen.addr());
-
-        FunctionalPort::writeBlob(paddr, p, gen.size());
-        p += gen.size();
-    }
-}
-
-void
-CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
-{
-    uint8_t *dst = (uint8_t *)dest;
-    VirtualPort *vp = tc->getVirtPort();
-
-    vp->readBlob(src, dst, cplen);
-}
-
-void
-CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
-{
-    uint8_t *src = (uint8_t *)source;
-    VirtualPort *vp = tc->getVirtPort();
-
-    vp->writeBlob(dest, src, cplen);
-}
-
-void
-CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
-{
-    int len = 0;
-    char *start = dst;
-    VirtualPort *vp = tc->getVirtPort();
-
-    do {
-        vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
-    } while (len < maxlen && start[len++] != 0 );
-
-    dst[len] = 0;
-}
-
-void
-CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
-{
-    VirtualPort *vp = tc->getVirtPort();
-    for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
-            gen.next())
-    {
-        vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
-        src += gen.size();
-    }
-}
 
+++ /dev/null
-/*
- * Copyright (c) 2006 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: Ali Saidi
- */
-
-/**
- * @file
- * Virtual Port Object Declaration. These ports incorporate some translation
- * into their access methods. Thus you can use one to read and write data
- * to/from virtual addresses.
- */
-
-#ifndef __MEM_VPORT_HH__
-#define __MEM_VPORT_HH__
-
-#include "arch/vtophys.hh"
-#include "config/full_system.hh"
-#include "mem/port_impl.hh"
-
-/** A class that translates a virtual address to a physical address and then
- * calls the above read/write functions. 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).
- */
-
-
-class VirtualPort  : public FunctionalPort
-{
-  private:
-    ThreadContext *tc;
-
-  public:
-    VirtualPort(const std::string &_name, ThreadContext *_tc = NULL)
-        : FunctionalPort(_name), tc(_tc)
-    {}
-
-    /** Return true if we have an thread context. This is used to
-     * prevent someone from accidently deleting the cpus statically
-     * allocated vport.
-     * @return true if a thread context isn't valid
-     */
-    bool nullThreadContext() { return tc != NULL; }
-
-    /** Version of readblob that translates virt->phys and deals
-      * with page boundries. */
-    virtual void readBlob(Addr addr, uint8_t *p, int size);
-
-    /** Version of writeBlob that translates virt->phys and deals
-      * with page boundries. */
-    virtual void writeBlob(Addr addr, uint8_t *p, int size);
-};
-
-
-void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen);
-void CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen);
-void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
-void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
-
-#endif //__MEM_VPORT_HH__
-
 
 #include "arch/vtophys.hh"
 #include "base/refcnt.hh"
 #include "base/types.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 
 class ThreadContext;
 
 
 #include "cpu/thread_context.hh"
 #include "mem/page_table.hh"
 #include "mem/physical.hh"
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
 #include "params/LiveProcess.hh"
 #include "params/Process.hh"
 #include "sim/debug.hh"
     // mark this context as active so it will start ticking.
     tc->activate(0);
 
-    Port *mem_port;
-    mem_port = system->physmem->getPort("functional");
-    initVirtMem = new TranslatingPort("process init port", this,
-            TranslatingPort::Always);
-    mem_port->setPeer(initVirtMem);
-    initVirtMem->setPeer(mem_port);
+    initVirtMem = new SETranslatingPortProxy(*system->getSystemPort(), this,
+                                             SETranslatingPortProxy::Always);
 }
 
 // map simulator fd sim_fd to target fd tgt_fd
 
 class SyscallDesc;
 class System;
 class ThreadContext;
-class TranslatingPort;
+class SETranslatingPortProxy;
 
 template<class IntType>
 struct AuxVector
 
   protected:
     /// Memory object for initialization (image loading)
-    TranslatingPort *initVirtMem;
+    SETranslatingPortProxy *initVirtMem;
 
   public:
     PageTable *pTable;
 
 #include <string>
 #include <vector>
 
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
 #include "sim/byteswap.hh"
 
 //This needs to be templated for cases where 32 bit pointers are needed.
 void
 copyStringArray(std::vector<std::string> &strings,
         AddrType array_ptr, AddrType data_ptr,
-        TranslatingPort* memPort)
+        SETranslatingPortProxy* memProxy)
 {
     AddrType data_ptr_swap;
     for (std::vector<std::string>::size_type i = 0; i < strings.size(); ++i) {
         data_ptr_swap = htog(data_ptr);
-        memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap,
+        memProxy->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap,
                 sizeof(AddrType));
-        memPort->writeString(data_ptr, strings[i].c_str());
+        memProxy->writeString(data_ptr, strings[i].c_str());
         array_ptr += sizeof(AddrType);
         data_ptr += strings[i].size() + 1;
     }
     // add NULL terminator
     data_ptr = 0;
 
-    memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
+    memProxy->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
 }
 
 
 
             // if the address is already there, zero it out
             else {
                 uint8_t zero  = 0;
-                TranslatingPort *tp = tc->getMemPort();
+                SETranslatingPortProxy *tp = tc->getMemProxy();
 
                 // split non-page aligned accesses
                 Addr next_page = roundUp(gen.addr(), VMPageSize);
     int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
 
     if (bytes_read != -1)
-        bufArg.copyOut(tc->getMemPort());
+        bufArg.copyOut(tc->getMemProxy());
 
     return bytes_read;
 }
     int nbytes = p->getSyscallArg(tc, index);
     BufferArg bufArg(bufPtr, nbytes);
 
-    bufArg.copyIn(tc->getMemPort());
+    bufArg.copyIn(tc->getMemProxy());
 
     int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
 
         // target platform
         BufferArg result_buf(result_ptr, sizeof(result));
         memcpy(result_buf.bufferPtr(), &result, sizeof(result));
-        result_buf.copyOut(tc->getMemPort());
+        result_buf.copyOut(tc->getMemProxy());
         return 0;
     }
 
 
     strncpy((char *)name.bufferPtr(), hostname, name_len);
 
-    name.copyOut(tc->getMemPort());
+    name.copyOut(tc->getMemProxy());
 
     return 0;
 }
         }
     }
 
-    buf.copyOut(tc->getMemPort());
+    buf.copyOut(tc->getMemProxy());
 
     return (result == -1) ? -errno : result;
 }
     string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+    if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
         return (TheISA::IntReg)-EFAULT;
 
     // Adjust path for current working directory
 
     int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
 
-    buf.copyOut(tc->getMemPort());
+    buf.copyOut(tc->getMemProxy());
 
     return (result == -1) ? -errno : result;
 }
     string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+    if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
         return (TheISA::IntReg)-EFAULT;
 
     // Adjust path for current working directory
     string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+    if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
         return (TheISA::IntReg)-EFAULT;
 
     // Adjust path for current working directory
     string old_name;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, index)))
+    if (!tc->getMemProxy()->tryReadString(old_name, p->getSyscallArg(tc, index)))
         return -EFAULT;
 
     string new_name;
 
-    if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, index)))
+    if (!tc->getMemProxy()->tryReadString(new_name, p->getSyscallArg(tc, index)))
         return -EFAULT;
 
     // Adjust path for current working directory
     string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+    if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
         return -EFAULT;
 
     off_t length = p->getSyscallArg(tc, index);
     int index = 0;
     string path;
 
-    if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, index)))
+    if (!tc->getMemProxy()->tryReadString(path, process->getSyscallArg(tc, index)))
        return -EFAULT;
 
     int64_t length = process->getSyscallArg(tc, index, 64);
     string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+    if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
         return -EFAULT;
 
     /* XXX endianess */
 
 #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/system.hh"
     //
     // copy data into simulator space (read from target memory)
     //
-    virtual bool copyIn(TranslatingPort *memport)
+    virtual bool copyIn(SETranslatingPortProxy* memproxy)
     {
-        memport->readBlob(addr, bufPtr, size);
+        memproxy->readBlob(addr, bufPtr, size);
         return true;    // no EFAULT detection for now
     }
 
     //
     // copy data out of simulator space (write to target memory)
     //
-    virtual bool copyOut(TranslatingPort *memport)
+    virtual bool copyOut(SETranslatingPortProxy* memproxy)
     {
-        memport->writeBlob(addr, bufPtr, size);
+        memproxy->writeBlob(addr, bufPtr, size);
         return true;    // no EFAULT detection for now
     }
 
 //Here are a couple convenience functions
 template<class OS>
 static void
-copyOutStatBuf(TranslatingPort * mem, Addr addr,
+copyOutStatBuf(SETranslatingPortProxy* mem, Addr addr,
         hst_stat *host, bool fakeTTY = false)
 {
     typedef TypedBufferArg<typename OS::tgt_stat> tgt_stat_buf;
 
 template<class OS>
 static void
-copyOutStat64Buf(TranslatingPort * mem, Addr addr,
+copyOutStat64Buf(SETranslatingPortProxy* mem, Addr addr,
         hst_stat64 *host, bool fakeTTY = false)
 {
     typedef TypedBufferArg<typename OS::tgt_stat64> tgt_stat_buf;
     std::string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path,
+    if (!tc->getMemProxy()->tryReadString(path,
                 process->getSyscallArg(tc, index)))
         return -EFAULT;
 
     sysinfo->uptime=seconds_since_epoch;
     sysinfo->totalram=process->system->memSize();
 
-    sysinfo.copyOut(tc->getMemPort());
+    sysinfo.copyOut(tc->getMemProxy());
 
     return 0;
 }
     std::string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path,
+    if (!tc->getMemProxy()->tryReadString(path,
                 process->getSyscallArg(tc, index))) {
         return -EFAULT;
     }
     std::string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path,
+    if (!tc->getMemProxy()->tryReadString(path,
                 process->getSyscallArg(tc, index))) {
         return -EFAULT;
     }
     if (result < 0)
         return -errno;
 
-    copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+    copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
 
     return 0;
 }
     std::string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path,
+    if (!tc->getMemProxy()->tryReadString(path,
                 process->getSyscallArg(tc, index)))
         return -EFAULT;
     Addr bufPtr = process->getSyscallArg(tc, index);
     if (result < 0)
         return -errno;
 
-    copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+    copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
 
     return 0;
 }
     if (result < 0)
         return -errno;
 
-    copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
+    copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (fd == 1));
 
     return 0;
 }
     std::string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path,
+    if (!tc->getMemProxy()->tryReadString(path,
                 process->getSyscallArg(tc, index))) {
         return -EFAULT;
     }
     if (result < 0)
         return -errno;
 
-    copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+    copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
 
     return 0;
 }
     std::string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path,
+    if (!tc->getMemProxy()->tryReadString(path,
                 process->getSyscallArg(tc, index))) {
         return -EFAULT;
     }
     if (result < 0)
         return -errno;
 
-    copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+    copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
 
     return 0;
 }
     if (result < 0)
         return -errno;
 
-    copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
+    copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (fd == 1));
 
     return 0;
 }
     std::string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path,
+    if (!tc->getMemProxy()->tryReadString(path,
                 process->getSyscallArg(tc, index))) {
         return -EFAULT;
     }
     if (result < 0)
         return -errno;
 
-    OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
+    OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
 
     return 0;
 }
     if (result < 0)
         return -errno;
 
-    OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
+    OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
 
     return 0;
 }
         return -EBADF;
     }
 
-    TranslatingPort *p = tc->getMemPort();
+    SETranslatingPortProxy *p = tc->getMemProxy();
     uint64_t tiov_base = process->getSyscallArg(tc, index);
     size_t count = process->getSyscallArg(tc, index);
     struct iovec hiov[count];
             break;
     }
 
-    rlp.copyOut(tc->getMemPort());
+    rlp.copyOut(tc->getMemProxy());
     return 0;
 }
 
     tp->tv_sec = TheISA::htog(tp->tv_sec);
     tp->tv_usec = TheISA::htog(tp->tv_usec);
 
-    tp.copyOut(tc->getMemPort());
+    tp.copyOut(tc->getMemProxy());
 
     return 0;
 }
     std::string path;
 
     int index = 0;
-    if (!tc->getMemPort()->tryReadString(path,
+    if (!tc->getMemProxy()->tryReadString(path,
                 process->getSyscallArg(tc, index))) {
         return -EFAULT;
     }
 
     TypedBufferArg<typename OS::timeval [2]>
         tp(process->getSyscallArg(tc, index));
-    tp.copyIn(tc->getMemPort());
+    tp.copyIn(tc->getMemProxy());
 
     struct timeval hostTimeval[2];
     for (int i = 0; i < 2; ++i)
              who);
     }
 
-    rup.copyOut(tc->getMemPort());
+    rup.copyOut(tc->getMemProxy());
 
     return 0;
 }
     bufp->tms_utime = htog(bufp->tms_utime);
 
     // Write back
-    bufp.copyOut(tc->getMemPort());
+    bufp.copyOut(tc->getMemProxy());
 
     // Return clock ticks since system boot
     return clocks;
     if(taddr != 0) {
         typename OS::time_t t = sec;
         t = htog(t);
-        TranslatingPort *p = tc->getMemPort();
+        SETranslatingPortProxy *p = tc->getMemProxy();
         p->writeBlob(taddr, (uint8_t*)&t, (int)sizeof(typename OS::time_t));
     }
     return sec;
 
 #if FULL_SYSTEM
 #include "arch/vtophys.hh"
 #include "kern/kernel_stats.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 #else
 #include "params/System.hh"
 #endif
     if (!debugSymbolTable)
         debugSymbolTable = new SymbolTable;
 
-
     /**
-     * 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");
-    }
-#endif // FULL_SYSTEM
-
-    // increment the number of running systms
-    numSystemsRunning++;
-
-    activeCpus.clear();
+    physProxy = new PortProxy(*getSystemPort());
+    virtProxy = new FSTranslatingPortProxy(*getSystemPort());
+#endif
 }
 
 System::~System()
         delete workItemStats[j];
 }
 
+void
+System::init()
+{
+    // check that the system port is connected
+    if (!_systemPort.isConnected())
+        panic("System port on %s is not connected.\n", name());
+}
+
 Port*
 System::getPort(const std::string &if_name, int idx)
 {
 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");
+    }
+#endif // FULL_SYSTEM
+
+    // increment the number of running systms
+    numSystemsRunning++;
+
+    activeCpus.clear();
+
 #if FULL_SYSTEM
     int i;
     for (i = 0; i < threadContexts.size(); i++)
 
 
 #if FULL_SYSTEM
 class Platform;
-class FunctionalPort;
-class VirtualPort;
+class PortProxy;
+class FSTranslatingPortProxy;
 #endif
 class GDBListener;
 class BaseRemoteGDB;
 
   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
 
     /** Port to physical memory used for writing object files into ram at
      * boot.*/
-    FunctionalPort *functionalPort;
-    VirtualPort *virtPort;
+    PortProxy* physProxy;
+    FSTranslatingPortProxy* virtProxy;
 
     /** kernel symbol table */
     SymbolTable *kernelSymtab;
 
 
 #include "arch/isa_traits.hh"
 #include "arch/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
 
 class ThreadContext;
 
         if (!ptr)
             return;
 
-        VirtualPort *port = tc->getVirtPort();
-        port->readBlob(ptr, buffer, sizeof(T));
+        FSTranslatingPortProxy* proxy = tc->getVirtProxy();
+        proxy->readBlob(ptr, buffer, sizeof(T));
     }
 
     bool
 
 system = System(cpu = cpu,
                 physmem = PhysicalMemory(),
                 membus = Bus())
+system.system_port = system.membus.port
 system.physmem.port = system.membus.port
 cpu.connectAllPorts(system.membus)
 
 
      #
      ruby_port.access_phys_mem = False
 
+
+# Connect the system port for loading of binaries etc
+system.system_port = system.ruby._sys_port_proxy.port
+
 # -----------------------
 # run simulation
 # -----------------------
 
     cpu.l1c.mem_side = system.toL2Bus.port
     system.funcmem.port = cpu.functional
 
+system.system_port = system.membus.port
+
 # connect memory to membus
 system.physmem.port = system.membus.port
 
 
 # connect memory to membus
 system.physmem.port = system.membus.port
 
+# connect system port to membus
+system.system_port = system.membus.port
 
 # -----------------------
 # run simulation
 
 system = System(cpu = cpu,
                 physmem = PhysicalMemory(),
                 membus = Bus())
+system.system_port = system.membus.port
 system.physmem.port = system.membus.port
 cpu.connectAllPorts(system.membus)
 
 
     #
     ruby_port.access_phys_mem = False
 
+# Connect the system port for loading of binaries etc
+system.system_port = system.ruby._sys_port_proxy.port
+
 # -----------------------
 # run simulation
 # -----------------------
 
 # connect memory to membus
 system.physmem.port = system.membus.port
 
+# connect system port to membus
+system.system_port = system.membus.port
 
 # -----------------------
 # run simulation
 
 system = System(cpu = AtomicSimpleCPU(cpu_id=0),
                 physmem = PhysicalMemory(),
                 membus = Bus())
+system.system_port = system.membus.port
 system.physmem.port = system.membus.port
 system.cpu.connectAllPorts(system.membus)
 system.cpu.clock = '2GHz'
 
     cpu.icache_port = system.ruby._cpu_ruby_ports[i].port
     cpu.dcache_port = system.ruby._cpu_ruby_ports[i].port
 
+# Connect the system port for loading of binaries etc
+system.system_port = system.ruby._sys_port_proxy.port
+
 # -----------------------
 # run simulation
 # -----------------------
 
     cpu.connectAllPorts(system.toL2Bus, system.membus)
     cpu.clock = '2GHz'
 
+system.system_port = system.membus.port
+
 # connect memory to membus
 system.physmem.port = system.membus.port
 
 
 cpu.icache_port = system.ruby._cpu_ruby_ports[0].port
 cpu.dcache_port = system.ruby._cpu_ruby_ports[0].port
 
+# Connect the system port for loading of binaries etc
+system.system_port = system.ruby._sys_port_proxy.port
+
 # -----------------------
 # run simulation
 # -----------------------
 
 system = System(cpu = cpu,
                 physmem = PhysicalMemory(),
                 membus = Bus())
+system.system_port = system.membus.port
 system.physmem.port = system.membus.port
 cpu.connectAllPorts(system.membus)
 cpu.clock = '2GHz'