arch, cpu, dev, gpu, mem, sim, python: start using getPort.

Replace the getMasterPort, getSlavePort, and getEthPort functions
with getPort, and remove extraneous mechanisms that are no longer
necessary.

Change-Id: Iab7e3c02d2f3a0cf33e7e824e18c28646b5bc318
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/17040
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 1a7b5d3..21257de 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -114,8 +114,8 @@
     fatal_if(!tlb, "Table walker must have a valid TLB\n");
 }
 
-BaseMasterPort&
-TableWalker::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+TableWalker::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "port") {
         if (!isStage2) {
@@ -124,7 +124,7 @@
             fatal("Cannot access table walker port through stage-two walker\n");
         }
     }
-    return MemObject::getMasterPort(if_name, idx);
+    return MemObject::getPort(if_name, idx);
 }
 
 TableWalker::WalkerState::WalkerState() :
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index 57e3aed..8176fc7 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -889,8 +889,8 @@
     DrainState drain() override;
     void drainResume() override;
 
-    BaseMasterPort& getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     void regStats() override;
 
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index ed7e680..dc3c35b 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -1243,8 +1243,8 @@
     return fault;
 }
 
-BaseMasterPort*
-TLB::getTableWalkerMasterPort()
+Port *
+TLB::getTableWalkerPort()
 {
     return &stage2Mmu->getPort();
 }
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index 8ca176a..fa1b040 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -392,7 +392,7 @@
     void regProbePoints() override;
 
     /**
-     * Get the table walker master port. This is used for migrating
+     * Get the table walker port. This is used for migrating
      * port connections during a CPU takeOverFrom() call. For
      * architectures that do not have a table walker, NULL is
      * returned, hence the use of a pointer rather than a
@@ -401,7 +401,7 @@
      *
      * @return A pointer to the walker master port
      */
-    BaseMasterPort* getTableWalkerMasterPort() override;
+    Port *getTableWalkerPort() override;
 
     // Caching misc register values here.
     // Writing to misc registers needs to invalidate them.
diff --git a/src/arch/generic/tlb.hh b/src/arch/generic/tlb.hh
index 7865d8a..ba07b10 100644
--- a/src/arch/generic/tlb.hh
+++ b/src/arch/generic/tlb.hh
@@ -131,15 +131,15 @@
     virtual void takeOverFrom(BaseTLB *otlb) = 0;
 
     /**
-     * Get the table walker master port if present. This is used for
+     * Get the table walker port if present. This is used for
      * migrating port connections during a CPU takeOverFrom()
      * call. For architectures that do not have a table walker, NULL
      * is returned, hence the use of a pointer rather than a
      * reference.
      *
-     * @return A pointer to the walker master port or NULL if not present
+     * @return A pointer to the walker port or NULL if not present
      */
-    virtual BaseMasterPort* getTableWalkerMasterPort() { return NULL; }
+    virtual Port* getTableWalkerPort() { return NULL; }
 
     void memInvalidate() { flushAll(); }
 };
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
index bfd1889..dfdff2b 100644
--- a/src/arch/x86/interrupts.hh
+++ b/src/arch/x86/interrupts.hh
@@ -215,22 +215,15 @@
 
     AddrRangeList getIntAddrRange() const override;
 
-    BaseMasterPort &getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override
     {
         if (if_name == "int_master") {
             return intMasterPort;
-        }
-        return BasicPioDevice::getMasterPort(if_name, idx);
-    }
-
-    BaseSlavePort &getSlavePort(const std::string &if_name,
-                                PortID idx = InvalidPortID) override
-    {
-        if (if_name == "int_slave") {
+        } else if (if_name == "int_slave") {
             return intSlavePort;
         }
-        return BasicPioDevice::getSlavePort(if_name, idx);
+        return BasicPioDevice::getPort(if_name, idx);
     }
 
     /*
diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc
index 4a405f2..0741dc2 100644
--- a/src/arch/x86/pagetable_walker.cc
+++ b/src/arch/x86/pagetable_walker.cc
@@ -167,13 +167,13 @@
 
 }
 
-BaseMasterPort &
-Walker::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+Walker::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "port")
         return port;
     else
-        return MemObject::getMasterPort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
 }
 
 void
diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh
index edca247..c1f4ed2 100644
--- a/src/arch/x86/pagetable_walker.hh
+++ b/src/arch/x86/pagetable_walker.hh
@@ -160,8 +160,8 @@
                 const RequestPtr &req, BaseTLB::Mode mode);
         Fault startFunctional(ThreadContext * _tc, Addr &addr,
                 unsigned &logBytes, BaseTLB::Mode mode);
-        BaseMasterPort &getMasterPort(const std::string &if_name,
-                                      PortID idx = InvalidPortID);
+        Port &getPort(const std::string &if_name,
+                      PortID idx=InvalidPortID) override;
 
       protected:
         // The TLB we're supposed to load.
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index 59fd3f0..33de058 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -511,10 +511,10 @@
     }
 }
 
-BaseMasterPort *
-TLB::getTableWalkerMasterPort()
+Port *
+TLB::getTableWalkerPort()
 {
-    return &walker->getMasterPort("port");
+    return &walker->getPort("port");
 }
 
 } // namespace X86ISA
diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh
index 8894a1e..b969bca 100644
--- a/src/arch/x86/tlb.hh
+++ b/src/arch/x86/tlb.hh
@@ -156,16 +156,16 @@
         void unserialize(CheckpointIn &cp) override;
 
         /**
-         * Get the table walker master port. This is used for
+         * Get the table walker port. This is used for
          * migrating port connections during a CPU takeOverFrom()
          * call. For architectures that do not have a table walker,
          * NULL is returned, hence the use of a pointer rather than a
          * reference. For X86 this method will always return a valid
          * port pointer.
          *
-         * @return A pointer to the walker master port
+         * @return A pointer to the walker port
          */
-        BaseMasterPort *getTableWalkerMasterPort() override;
+        Port *getTableWalkerPort() override;
     };
 }
 
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 09de646..8dfcf3c 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -449,19 +449,18 @@
         threadContexts[0]->regStats(name());
 }
 
-BaseMasterPort &
-BaseCPU::getMasterPort(const string &if_name, PortID idx)
+Port &
+BaseCPU::getPort(const string &if_name, PortID idx)
 {
     // Get the right port based on name. This applies to all the
     // subclasses of the base CPU and relies on their implementation
-    // of getDataPort and getInstPort. In all cases there methods
-    // return a MasterPort pointer.
+    // of getDataPort and getInstPort.
     if (if_name == "dcache_port")
         return getDataPort();
     else if (if_name == "icache_port")
         return getInstPort();
     else
-        return MemObject::getMasterPort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
 }
 
 void
@@ -621,21 +620,18 @@
             ThreadContext::compare(oldTC, newTC);
         */
 
-        BaseMasterPort *old_itb_port =
-            oldTC->getITBPtr()->getTableWalkerMasterPort();
-        BaseMasterPort *old_dtb_port =
-            oldTC->getDTBPtr()->getTableWalkerMasterPort();
-        BaseMasterPort *new_itb_port =
-            newTC->getITBPtr()->getTableWalkerMasterPort();
-        BaseMasterPort *new_dtb_port =
-            newTC->getDTBPtr()->getTableWalkerMasterPort();
+        Port *old_itb_port = oldTC->getITBPtr()->getTableWalkerPort();
+        Port *old_dtb_port = oldTC->getDTBPtr()->getTableWalkerPort();
+        Port *new_itb_port = newTC->getITBPtr()->getTableWalkerPort();
+        Port *new_dtb_port = newTC->getDTBPtr()->getTableWalkerPort();
 
         // Move over any table walker ports if they exist
         if (new_itb_port) {
             assert(!new_itb_port->isConnected());
             assert(old_itb_port);
             assert(old_itb_port->isConnected());
-            BaseSlavePort &slavePort = old_itb_port->getSlavePort();
+            auto &slavePort =
+                dynamic_cast<BaseMasterPort *>(old_itb_port)->getSlavePort();
             old_itb_port->unbind();
             new_itb_port->bind(slavePort);
         }
@@ -643,7 +639,8 @@
             assert(!new_dtb_port->isConnected());
             assert(old_dtb_port);
             assert(old_dtb_port->isConnected());
-            BaseSlavePort &slavePort = old_dtb_port->getSlavePort();
+            auto &slavePort =
+                dynamic_cast<BaseMasterPort *>(old_dtb_port)->getSlavePort();
             old_dtb_port->unbind();
             new_dtb_port->bind(slavePort);
         }
@@ -655,14 +652,14 @@
         CheckerCPU *oldChecker = oldTC->getCheckerCpuPtr();
         CheckerCPU *newChecker = newTC->getCheckerCpuPtr();
         if (oldChecker && newChecker) {
-            BaseMasterPort *old_checker_itb_port =
-                oldChecker->getITBPtr()->getTableWalkerMasterPort();
-            BaseMasterPort *old_checker_dtb_port =
-                oldChecker->getDTBPtr()->getTableWalkerMasterPort();
-            BaseMasterPort *new_checker_itb_port =
-                newChecker->getITBPtr()->getTableWalkerMasterPort();
-            BaseMasterPort *new_checker_dtb_port =
-                newChecker->getDTBPtr()->getTableWalkerMasterPort();
+            Port *old_checker_itb_port =
+                oldChecker->getITBPtr()->getTableWalkerPort();
+            Port *old_checker_dtb_port =
+                oldChecker->getDTBPtr()->getTableWalkerPort();
+            Port *new_checker_itb_port =
+                newChecker->getITBPtr()->getTableWalkerPort();
+            Port *new_checker_dtb_port =
+                newChecker->getDTBPtr()->getTableWalkerPort();
 
             newChecker->getITBPtr()->takeOverFrom(oldChecker->getITBPtr());
             newChecker->getDTBPtr()->takeOverFrom(oldChecker->getDTBPtr());
@@ -672,8 +669,9 @@
                 assert(!new_checker_itb_port->isConnected());
                 assert(old_checker_itb_port);
                 assert(old_checker_itb_port->isConnected());
-                BaseSlavePort &slavePort =
-                    old_checker_itb_port->getSlavePort();
+                auto &slavePort =
+                    dynamic_cast<BaseMasterPort *>(old_checker_itb_port)->
+                    getSlavePort();
                 old_checker_itb_port->unbind();
                 new_checker_itb_port->bind(slavePort);
             }
@@ -681,8 +679,9 @@
                 assert(!new_checker_dtb_port->isConnected());
                 assert(old_checker_dtb_port);
                 assert(old_checker_dtb_port->isConnected());
-                BaseSlavePort &slavePort =
-                    old_checker_dtb_port->getSlavePort();
+                auto &slavePort =
+                    dynamic_cast<BaseMasterPort *>(old_checker_dtb_port)->
+                    getSlavePort();
                 old_checker_dtb_port->unbind();
                 new_checker_dtb_port->bind(slavePort);
             }
@@ -709,13 +708,15 @@
     // we are switching to.
     assert(!getInstPort().isConnected());
     assert(oldCPU->getInstPort().isConnected());
-    BaseSlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort();
+    auto &inst_peer_port =
+        dynamic_cast<BaseMasterPort &>(oldCPU->getInstPort()).getSlavePort();
     oldCPU->getInstPort().unbind();
     getInstPort().bind(inst_peer_port);
 
     assert(!getDataPort().isConnected());
     assert(oldCPU->getDataPort().isConnected());
-    BaseSlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort();
+    auto &data_peer_port =
+        dynamic_cast<BaseMasterPort &>(oldCPU->getDataPort()).getSlavePort();
     oldCPU->getDataPort().unbind();
     getDataPort().bind(data_peer_port);
 }
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 8673d23..9075d4b 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -180,7 +180,7 @@
     MasterID instMasterId() { return _instMasterId; }
 
     /**
-     * Get a master port on this CPU. All CPUs have a data and
+     * Get a port on this CPU. All CPUs have a data and
      * instruction port, and this method uses getDataPort and
      * getInstPort of the subclasses to resolve the two ports.
      *
@@ -189,8 +189,8 @@
      *
      * @return a reference to the port with the given name
      */
-    BaseMasterPort &getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     /** Get cpu task id */
     uint32_t taskId() const { return _taskId; }
diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.cc b/src/cpu/testers/directedtest/RubyDirectedTester.cc
index be7f3c2..cd367b4 100644
--- a/src/cpu/testers/directedtest/RubyDirectedTester.cc
+++ b/src/cpu/testers/directedtest/RubyDirectedTester.cc
@@ -78,15 +78,15 @@
     generator->setDirectedTester(this);
 }
 
-BaseMasterPort &
-RubyDirectedTester::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+RubyDirectedTester::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name != "cpuPort") {
         // pass it along to our super class
-        return MemObject::getMasterPort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     } else {
         if (idx >= static_cast<int>(ports.size())) {
-            panic("RubyDirectedTester::getMasterPort: unknown index %d\n", idx);
+            panic("RubyDirectedTester::getPort: unknown index %d\n", idx);
         }
 
         return *ports[idx];
diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.hh b/src/cpu/testers/directedtest/RubyDirectedTester.hh
index 00278a6..0f51976 100644
--- a/src/cpu/testers/directedtest/RubyDirectedTester.hh
+++ b/src/cpu/testers/directedtest/RubyDirectedTester.hh
@@ -67,8 +67,8 @@
     RubyDirectedTester(const Params *p);
     ~RubyDirectedTester();
 
-    virtual BaseMasterPort &getMasterPort(const std::string &if_name,
-                                          PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     MasterPort* getCpuPort(int idx);
 
diff --git a/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc
index 0ced9df..1a07205 100644
--- a/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc
+++ b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc
@@ -110,13 +110,13 @@
             name(), id);
 }
 
-BaseMasterPort &
-GarnetSyntheticTraffic::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+GarnetSyntheticTraffic::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "test")
         return cachePort;
     else
-        return MemObject::getMasterPort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
 }
 
 void
diff --git a/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh
index 3da7e27..a18f5bb 100644
--- a/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh
+++ b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh
@@ -64,8 +64,8 @@
     // main simulation loop (one cycle)
     void tick();
 
-    virtual BaseMasterPort &getMasterPort(const std::string &if_name,
-                                          PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     /**
      * Print state of address in memory system via PrintReq (for
diff --git a/src/cpu/testers/memtest/memtest.cc b/src/cpu/testers/memtest/memtest.cc
index 09e7e88..346f882 100644
--- a/src/cpu/testers/memtest/memtest.cc
+++ b/src/cpu/testers/memtest/memtest.cc
@@ -124,13 +124,13 @@
     schedule(noResponseEvent, clockEdge(progressCheck));
 }
 
-BaseMasterPort &
-MemTest::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+MemTest::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "port")
         return port;
     else
-        return MemObject::getMasterPort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
 }
 
 void
diff --git a/src/cpu/testers/memtest/memtest.hh b/src/cpu/testers/memtest/memtest.hh
index 023b878..8e8f739 100644
--- a/src/cpu/testers/memtest/memtest.hh
+++ b/src/cpu/testers/memtest/memtest.hh
@@ -77,8 +77,8 @@
 
     virtual void regStats();
 
-    virtual BaseMasterPort &getMasterPort(const std::string &if_name,
-                                          PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
   protected:
 
diff --git a/src/cpu/testers/rubytest/RubyTester.cc b/src/cpu/testers/rubytest/RubyTester.cc
index 9375446..cb23688 100644
--- a/src/cpu/testers/rubytest/RubyTester.cc
+++ b/src/cpu/testers/rubytest/RubyTester.cc
@@ -128,17 +128,17 @@
     m_checkTable_ptr = new CheckTable(m_num_writers, m_num_readers, this);
 }
 
-BaseMasterPort &
-RubyTester::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+RubyTester::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name != "cpuInstPort" && if_name != "cpuInstDataPort" &&
         if_name != "cpuDataPort") {
         // pass it along to our super class
-        return MemObject::getMasterPort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     } else {
         if (if_name == "cpuInstPort") {
             if (idx > m_num_inst_only_ports) {
-                panic("RubyTester::getMasterPort: unknown inst port %d\n",
+                panic("RubyTester::getPort: unknown inst port %d\n",
                       idx);
             }
             //
@@ -147,7 +147,7 @@
             return *readPorts[idx];
         } else if (if_name == "cpuInstDataPort") {
             if (idx > m_num_inst_data_ports) {
-                panic("RubyTester::getMasterPort: unknown inst+data port %d\n",
+                panic("RubyTester::getPort: unknown inst+data port %d\n",
                       idx);
             }
             int read_idx = idx + m_num_inst_only_ports;
@@ -162,7 +162,7 @@
             //
             if (idx > (static_cast<int>(readPorts.size()) -
                        (m_num_inst_only_ports + m_num_inst_data_ports))) {
-                panic("RubyTester::getMasterPort: unknown data port %d\n",
+                panic("RubyTester::getPort: unknown data port %d\n",
                       idx);
             }
             int read_idx = idx + m_num_inst_only_ports + m_num_inst_data_ports;
diff --git a/src/cpu/testers/rubytest/RubyTester.hh b/src/cpu/testers/rubytest/RubyTester.hh
index 0070359..2509aa2 100644
--- a/src/cpu/testers/rubytest/RubyTester.hh
+++ b/src/cpu/testers/rubytest/RubyTester.hh
@@ -94,8 +94,8 @@
     RubyTester(const Params *p);
     ~RubyTester();
 
-    virtual BaseMasterPort &getMasterPort(const std::string &if_name,
-                                          PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     bool isInstOnlyCpuPort(int idx);
     bool isInstDataCpuPort(int idx);
diff --git a/src/cpu/testers/traffic_gen/base.cc b/src/cpu/testers/traffic_gen/base.cc
index ad4f67d..80fa8a9 100644
--- a/src/cpu/testers/traffic_gen/base.cc
+++ b/src/cpu/testers/traffic_gen/base.cc
@@ -88,13 +88,13 @@
 {
 }
 
-BaseMasterPort&
-BaseTrafficGen::getMasterPort(const string& if_name, PortID idx)
+Port &
+BaseTrafficGen::getPort(const string &if_name, PortID idx)
 {
     if (if_name == "port") {
         return port;
     } else {
-        return MemObject::getMasterPort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/cpu/testers/traffic_gen/base.hh b/src/cpu/testers/traffic_gen/base.hh
index 272dcb5..2443e62 100644
--- a/src/cpu/testers/traffic_gen/base.hh
+++ b/src/cpu/testers/traffic_gen/base.hh
@@ -182,8 +182,8 @@
 
     ~BaseTrafficGen();
 
-    BaseMasterPort& getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     void init() override;
 
diff --git a/src/cpu/trace/trace_cpu.cc b/src/cpu/trace/trace_cpu.cc
index 2b198e9..6e499db 100644
--- a/src/cpu/trace/trace_cpu.cc
+++ b/src/cpu/trace/trace_cpu.cc
@@ -108,13 +108,13 @@
     // Unbind the ports of the old CPU and bind the ports of the TraceCPU.
     assert(!getInstPort().isConnected());
     assert(oldCPU->getInstPort().isConnected());
-    BaseSlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort();
+    Port &inst_peer_port = oldCPU->getInstPort().getSlavePort();
     oldCPU->getInstPort().unbind();
     getInstPort().bind(inst_peer_port);
 
     assert(!getDataPort().isConnected());
     assert(oldCPU->getDataPort().isConnected());
-    BaseSlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort();
+    Port &data_peer_port = oldCPU->getDataPort().getSlavePort();
     oldCPU->getDataPort().unbind();
     getDataPort().bind(data_peer_port);
 }
diff --git a/src/dev/dma_device.cc b/src/dev/dma_device.cc
index c445fbc..047eef1 100644
--- a/src/dev/dma_device.cc
+++ b/src/dev/dma_device.cc
@@ -262,13 +262,13 @@
         panic("Unknown memory mode.");
 }
 
-BaseMasterPort &
-DmaDevice::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+DmaDevice::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "dma") {
         return dmaPort;
     }
-    return PioDevice::getMasterPort(if_name, idx);
+    return PioDevice::getPort(if_name, idx);
 }
 
 
diff --git a/src/dev/dma_device.hh b/src/dev/dma_device.hh
index 0dc79df..f556e14 100644
--- a/src/dev/dma_device.hh
+++ b/src/dev/dma_device.hh
@@ -179,8 +179,8 @@
 
     unsigned int cacheBlockSize() const { return sys->cacheLineSize(); }
 
-    BaseMasterPort &getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
 };
 
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index 28ea52a..1cec2bf 100644
--- a/src/dev/io_device.cc
+++ b/src/dev/io_device.cc
@@ -87,13 +87,13 @@
     pioPort.sendRangeChange();
 }
 
-BaseSlavePort &
-PioDevice::getSlavePort(const std::string &if_name, PortID idx)
+Port &
+PioDevice::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "pio") {
         return pioPort;
     }
-    return MemObject::getSlavePort(if_name, idx);
+    return MemObject::getPort(if_name, idx);
 }
 
 BasicPioDevice::BasicPioDevice(const Params *p, Addr size)
diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh
index 7e323b3..64d7aa5 100644
--- a/src/dev/io_device.hh
+++ b/src/dev/io_device.hh
@@ -125,8 +125,8 @@
 
     virtual void init();
 
-    virtual BaseSlavePort &getSlavePort(const std::string &if_name,
-                                        PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+            PortID idx=InvalidPortID) override;
 
     friend class PioPort;
 
diff --git a/src/dev/net/Ethernet.py b/src/dev/net/Ethernet.py
index 0cf37e2..7ef8374 100644
--- a/src/dev/net/Ethernet.py
+++ b/src/dev/net/Ethernet.py
@@ -47,7 +47,6 @@
 class EtherLink(SimObject):
     type = 'EtherLink'
     cxx_header = "dev/net/etherlink.hh"
-    cxx_extra_bases = [ "EtherObject" ]
     int0 = SlavePort("interface 0")
     int1 = SlavePort("interface 1")
     delay = Param.Latency('0us', "packet transmit delay")
@@ -58,7 +57,6 @@
 class DistEtherLink(SimObject):
     type = 'DistEtherLink'
     cxx_header = "dev/net/dist_etherlink.hh"
-    cxx_extra_bases = [ "EtherObject" ]
     int0 = SlavePort("interface 0")
     delay = Param.Latency('0us', "packet transmit delay")
     delay_var = Param.Latency('0ns', "packet transmit delay variability")
@@ -77,7 +75,6 @@
 class EtherBus(SimObject):
     type = 'EtherBus'
     cxx_header = "dev/net/etherbus.hh"
-    cxx_extra_bases = [ "EtherObject" ]
     loopback = Param.Bool(True, "send packet back to the sending interface")
     dump = Param.EtherDump(NULL, "dump object")
     speed = Param.NetworkBandwidth('100Mbps', "bus speed in bits per second")
@@ -85,7 +82,6 @@
 class EtherSwitch(SimObject):
     type = 'EtherSwitch'
     cxx_header = "dev/net/etherswitch.hh"
-    cxx_extra_bases = [ "EtherObject" ]
     dump = Param.EtherDump(NULL, "dump object")
     fabric_speed = Param.NetworkBandwidth('10Gbps', "switch fabric speed in bits "
                                           "per second")
@@ -99,7 +95,6 @@
     type = 'EtherTapBase'
     abstract = True
     cxx_header = "dev/net/ethertap.hh"
-    cxx_extra_bases = [ "EtherObject" ]
     bufsz = Param.Int(10000, "tap buffer size")
     dump = Param.EtherDump(NULL, "dump object")
     tap = SlavePort("Ethernet interface to connect to gem5's network")
@@ -127,7 +122,6 @@
     type = 'EtherDevice'
     abstract = True
     cxx_header = "dev/net/etherdevice.hh"
-    cxx_extra_bases = [ "EtherObject" ]
     interface = MasterPort("Ethernet Interface")
 
 class IGbE(EtherDevice):
diff --git a/src/dev/net/SConscript b/src/dev/net/SConscript
index 0bb6bbf..908dd44 100644
--- a/src/dev/net/SConscript
+++ b/src/dev/net/SConscript
@@ -45,7 +45,6 @@
 Import('*')
 
 SimObject('Ethernet.py')
-Source('python.cc', add_tags='python')
 
 # Basic Ethernet infrastructure
 Source('etherbus.cc')
diff --git a/src/dev/net/dist_etherlink.cc b/src/dev/net/dist_etherlink.cc
index 477ad61..0cefb90 100644
--- a/src/dev/net/dist_etherlink.cc
+++ b/src/dev/net/dist_etherlink.cc
@@ -61,7 +61,6 @@
 #include "dev/net/etherdump.hh"
 #include "dev/net/etherint.hh"
 #include "dev/net/etherlink.hh"
-#include "dev/net/etherobject.hh"
 #include "dev/net/etherpkt.hh"
 #include "dev/net/tcp_iface.hh"
 #include "params/EtherLink.hh"
@@ -109,15 +108,12 @@
     delete distIface;
 }
 
-EtherInt*
-DistEtherLink::getEthPort(const std::string &if_name, int idx)
+Port &
+DistEtherLink::getPort(const std::string &if_name, PortID idx)
 {
-    if (if_name != "int0") {
-        return nullptr;
-    } else {
-        panic_if(localIface->getPeer(), "interface already connected to");
-    }
-    return localIface;
+    if (if_name == "int0")
+        return *localIface;
+    return SimObject::getPort(if_name, idx);
 }
 
 void
diff --git a/src/dev/net/dist_etherlink.hh b/src/dev/net/dist_etherlink.hh
index 51852a5..7d00602 100644
--- a/src/dev/net/dist_etherlink.hh
+++ b/src/dev/net/dist_etherlink.hh
@@ -53,7 +53,6 @@
 #include <iostream>
 
 #include "dev/net/etherlink.hh"
-#include "dev/net/etherobject.hh"
 #include "params/DistEtherLink.hh"
 
 class DistIface;
@@ -62,7 +61,7 @@
 /**
  * Model for a fixed bandwidth full duplex ethernet link.
  */
-class DistEtherLink : public SimObject, public EtherObject
+class DistEtherLink : public SimObject
 {
   protected:
     class LocalIface;
@@ -224,7 +223,8 @@
         return dynamic_cast<const Params *>(_params);
     }
 
-    EtherInt *getEthPort(const std::string &if_name, int idx) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     virtual void init() override;
     virtual void startup() override;
diff --git a/src/dev/net/etherbus.cc b/src/dev/net/etherbus.cc
index dee772c..fa49b99 100644
--- a/src/dev/net/etherbus.cc
+++ b/src/dev/net/etherbus.cc
@@ -81,8 +81,8 @@
     packet = 0;
 }
 
-EtherInt*
-EtherBus::getEthPort(const std::string &if_name, int idx)
+Port &
+EtherBus::getPort(const std::string &if_name, PortID idx)
 {
     panic("Etherbus doesn't work\n");
 }
diff --git a/src/dev/net/etherbus.hh b/src/dev/net/etherbus.hh
index 8c1260f..24333b5 100644
--- a/src/dev/net/etherbus.hh
+++ b/src/dev/net/etherbus.hh
@@ -35,7 +35,6 @@
 #ifndef __DEV_NET_ETHERBUS_HH__
 #define __DEV_NET_ETHERBUS_HH__
 
-#include "dev/net/etherobject.hh"
 #include "dev/net/etherpkt.hh"
 #include "params/EtherBus.hh"
 #include "sim/eventq.hh"
@@ -43,7 +42,7 @@
 
 class EtherDump;
 class EtherInt;
-class EtherBus : public SimObject, public EtherObject
+class EtherBus : public SimObject
 {
   protected:
     typedef std::list<EtherInt *> devlist_t;
@@ -72,7 +71,8 @@
     void reg(EtherInt *dev);
     bool busy() const { return (bool)packet; }
     bool send(EtherInt *sender, EthPacketPtr &packet);
-    EtherInt *getEthPort(const std::string &if_name, int idx) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 };
 
 #endif // __DEV_NET_ETHERBUS_HH__
diff --git a/src/dev/net/etherdevice.hh b/src/dev/net/etherdevice.hh
index 7101ec8..7de4d82 100644
--- a/src/dev/net/etherdevice.hh
+++ b/src/dev/net/etherdevice.hh
@@ -37,7 +37,6 @@
 #define __DEV_NET_ETHERDEVICE_HH__
 
 #include "base/statistics.hh"
-#include "dev/net/etherobject.hh"
 #include "dev/pci/device.hh"
 #include "params/EtherDevBase.hh"
 #include "params/EtherDevice.hh"
@@ -45,7 +44,7 @@
 
 class EtherInt;
 
-class EtherDevice : public PciDevice, public EtherObject
+class EtherDevice : public PciDevice
 {
   public:
     typedef EtherDeviceParams Params;
diff --git a/src/dev/net/etherlink.cc b/src/dev/net/etherlink.cc
index b160e29..448bb88 100644
--- a/src/dev/net/etherlink.cc
+++ b/src/dev/net/etherlink.cc
@@ -88,20 +88,14 @@
     delete interface[1];
 }
 
-EtherInt*
-EtherLink::getEthPort(const std::string &if_name, int idx)
+Port &
+EtherLink::getPort(const std::string &if_name, PortID idx)
 {
-    Interface *i;
     if (if_name == "int0")
-        i = interface[0];
+        return *interface[0];
     else if (if_name == "int1")
-        i = interface[1];
-    else
-        return NULL;
-    if (i->getPeer())
-        panic("interface already connected to\n");
-
-    return i;
+        return *interface[1];
+    return SimObject::getPort(if_name, idx);
 }
 
 
diff --git a/src/dev/net/etherlink.hh b/src/dev/net/etherlink.hh
index 37fa168..9f12ca4 100644
--- a/src/dev/net/etherlink.hh
+++ b/src/dev/net/etherlink.hh
@@ -51,7 +51,6 @@
 
 #include "base/types.hh"
 #include "dev/net/etherint.hh"
-#include "dev/net/etherobject.hh"
 #include "dev/net/etherpkt.hh"
 #include "params/EtherLink.hh"
 #include "sim/eventq.hh"
@@ -62,7 +61,7 @@
 /*
  * Model for a fixed bandwidth full duplex ethernet link
  */
-class EtherLink : public EtherObject, public SimObject
+class EtherLink : public SimObject
 {
   protected:
     class Interface;
@@ -152,7 +151,8 @@
         return dynamic_cast<const Params *>(_params);
     }
 
-    EtherInt *getEthPort(const std::string &if_name, int idx) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     void serialize(CheckpointOut &cp) const override;
     void unserialize(CheckpointIn &cp) override;
diff --git a/src/dev/net/etherswitch.cc b/src/dev/net/etherswitch.cc
index c03b594..99e0621 100644
--- a/src/dev/net/etherswitch.cc
+++ b/src/dev/net/etherswitch.cc
@@ -62,16 +62,15 @@
     interfaces.clear();
 }
 
-EtherInt*
-EtherSwitch::getEthPort(const std::string &if_name, int idx)
+Port &
+EtherSwitch::getPort(const std::string &if_name, PortID idx)
 {
-    if (idx < 0 || idx >= interfaces.size())
-        return nullptr;
+    if (if_name == "interface") {
+        panic_if(idx < 0 || idx >= interfaces.size(), "index out of bounds");
+        return *interfaces.at(idx);
+    }
 
-    Interface *interface = interfaces.at(idx);
-    panic_if(interface->getPeer(), "interface already connected\n");
-
-    return interface;
+    return SimObject::getPort(if_name, idx);
 }
 
 bool
diff --git a/src/dev/net/etherswitch.hh b/src/dev/net/etherswitch.hh
index 36a0c68..9b60b85 100644
--- a/src/dev/net/etherswitch.hh
+++ b/src/dev/net/etherswitch.hh
@@ -42,14 +42,13 @@
 #include "base/inet.hh"
 #include "dev/net/etherint.hh"
 #include "dev/net/etherlink.hh"
-#include "dev/net/etherobject.hh"
 #include "dev/net/etherpkt.hh"
 #include "dev/net/pktfifo.hh"
 #include "params/EtherSwitch.hh"
 #include "sim/eventq.hh"
 #include "sim/sim_object.hh"
 
-class EtherSwitch : public SimObject, public EtherObject
+class EtherSwitch : public SimObject
 {
   public:
     typedef EtherSwitchParams Params;
@@ -62,7 +61,8 @@
         return dynamic_cast<const Params*>(_params);
     }
 
-    EtherInt *getEthPort(const std::string &if_name, int idx) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
   protected:
     /**
diff --git a/src/dev/net/ethertap.cc b/src/dev/net/ethertap.cc
index bf2dc68..552296d 100644
--- a/src/dev/net/ethertap.cc
+++ b/src/dev/net/ethertap.cc
@@ -159,15 +159,12 @@
 }
 
 
-EtherInt*
-EtherTapBase::getEthPort(const std::string &if_name, int idx)
+Port &
+EtherTapBase::getPort(const std::string &if_name, PortID idx)
 {
-    if (if_name == "tap") {
-        if (interface->getPeer())
-            panic("Interface already connected to\n");
-        return interface;
-    }
-    return NULL;
+    if (if_name == "tap")
+        return *interface;
+    return SimObject::getPort(if_name, idx);
 }
 
 bool
diff --git a/src/dev/net/ethertap.hh b/src/dev/net/ethertap.hh
index 7db73c5..5f59a39 100644
--- a/src/dev/net/ethertap.hh
+++ b/src/dev/net/ethertap.hh
@@ -41,7 +41,6 @@
 #include "base/pollevent.hh"
 #include "config/use_tuntap.hh"
 #include "dev/net/etherint.hh"
-#include "dev/net/etherobject.hh"
 #include "dev/net/etherpkt.hh"
 
 #if USE_TUNTAP
@@ -56,7 +55,7 @@
 class TapEvent;
 class EtherTapInt;
 
-class EtherTapBase : public SimObject, public EtherObject
+class EtherTapBase : public SimObject
 {
   public:
     typedef EtherTapBaseParams Params;
@@ -101,7 +100,8 @@
     EtherTapInt *interface;
 
   public:
-    EtherInt *getEthPort(const std::string &if_name, int idx) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     bool recvSimulated(EthPacketPtr packet);
     void sendSimulated(void *data, size_t len);
diff --git a/src/dev/net/i8254xGBe.cc b/src/dev/net/i8254xGBe.cc
index 2d55603..9d83519 100644
--- a/src/dev/net/i8254xGBe.cc
+++ b/src/dev/net/i8254xGBe.cc
@@ -139,16 +139,12 @@
     PciDevice::init();
 }
 
-EtherInt*
-IGbE::getEthPort(const std::string &if_name, int idx)
+Port &
+IGbE::getPort(const std::string &if_name, PortID idx)
 {
-
-    if (if_name == "interface") {
-        if (etherInt->getPeer())
-            panic("Port already connected to\n");
-        return etherInt;
-    }
-    return NULL;
+    if (if_name == "interface")
+        return *etherInt;
+    return EtherDevice::getPort(if_name, idx);
 }
 
 Tick
diff --git a/src/dev/net/i8254xGBe.hh b/src/dev/net/i8254xGBe.hh
index 402e61d..031cb4d 100644
--- a/src/dev/net/i8254xGBe.hh
+++ b/src/dev/net/i8254xGBe.hh
@@ -519,7 +519,8 @@
     ~IGbE();
     void init() override;
 
-    EtherInt *getEthPort(const std::string &if_name, int idx) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     Tick lastInterrupt;
 
diff --git a/src/dev/net/ns_gige.cc b/src/dev/net/ns_gige.cc
index 1a5adb2..29e8867 100644
--- a/src/dev/net/ns_gige.cc
+++ b/src/dev/net/ns_gige.cc
@@ -173,15 +173,12 @@
     return configDelay;
 }
 
-EtherInt*
-NSGigE::getEthPort(const std::string &if_name, int idx)
+Port &
+NSGigE::getPort(const std::string &if_name, PortID idx)
 {
-    if (if_name == "interface") {
-       if (interface->getPeer())
-           panic("interface already connected to\n");
-       return interface;
-    }
-    return NULL;
+    if (if_name == "interface")
+       return *interface;
+    return EtherDevBase::getPort(if_name, idx);
 }
 
 /**
diff --git a/src/dev/net/ns_gige.hh b/src/dev/net/ns_gige.hh
index f9be028..5745c30 100644
--- a/src/dev/net/ns_gige.hh
+++ b/src/dev/net/ns_gige.hh
@@ -341,7 +341,8 @@
     NSGigE(Params *params);
     ~NSGigE();
 
-    EtherInt *getEthPort(const std::string &if_name, int idx) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     Tick writeConfig(PacketPtr pkt) override;
 
diff --git a/src/dev/net/sinic.cc b/src/dev/net/sinic.cc
index ce9fbb6..8d73d15 100644
--- a/src/dev/net/sinic.cc
+++ b/src/dev/net/sinic.cc
@@ -142,16 +142,12 @@
     _maxVnicDistance = 0;
 }
 
-EtherInt*
-Device::getEthPort(const std::string &if_name, int idx)
+Port &
+Device::getPort(const std::string &if_name, PortID idx)
 {
-    if (if_name == "interface") {
-        if (interface->getPeer())
-            panic("interface already connected to\n");
-
-        return interface;
-    }
-    return NULL;
+    if (if_name == "interface")
+        return *interface;
+    return EtherDevBase::getPort(if_name, idx);
 }
 
 
diff --git a/src/dev/net/sinic.hh b/src/dev/net/sinic.hh
index 70d22f1..ab79a5f 100644
--- a/src/dev/net/sinic.hh
+++ b/src/dev/net/sinic.hh
@@ -230,7 +230,8 @@
   public:
     bool recvPacket(EthPacketPtr packet);
     void transferDone();
-    EtherInt *getEthPort(const std::string &if_name, int idx) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
 /**
  * DMA parameters
diff --git a/src/dev/pci/copy_engine.cc b/src/dev/pci/copy_engine.cc
index 7f8959a..2a74c5c 100644
--- a/src/dev/pci/copy_engine.cc
+++ b/src/dev/pci/copy_engine.cc
@@ -113,24 +113,24 @@
     delete [] copyBuffer;
 }
 
-BaseMasterPort &
-CopyEngine::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+CopyEngine::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name != "dma") {
         // pass it along to our super class
-        return PciDevice::getMasterPort(if_name, idx);
+        return PciDevice::getPort(if_name, idx);
     } else {
         if (idx >= static_cast<int>(chan.size())) {
-            panic("CopyEngine::getMasterPort: unknown index %d\n", idx);
+            panic("CopyEngine::getPort: unknown index %d\n", idx);
         }
 
-        return chan[idx]->getMasterPort();
+        return chan[idx]->getPort();
     }
 }
 
 
-BaseMasterPort &
-CopyEngine::CopyEngineChannel::getMasterPort()
+Port &
+CopyEngine::CopyEngineChannel::getPort()
 {
     return cePort;
 }
diff --git a/src/dev/pci/copy_engine.hh b/src/dev/pci/copy_engine.hh
index 1ec29f0..eb62fd3 100644
--- a/src/dev/pci/copy_engine.hh
+++ b/src/dev/pci/copy_engine.hh
@@ -95,7 +95,7 @@
       public:
         CopyEngineChannel(CopyEngine *_ce, int cid);
         virtual ~CopyEngineChannel();
-        BaseMasterPort &getMasterPort();
+        Port &getPort();
 
         std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); }
         virtual Tick read(PacketPtr pkt)
@@ -193,8 +193,8 @@
 
     void regStats() override;
 
-    BaseMasterPort &getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+            PortID idx = InvalidPortID) override;
 
     Tick read(PacketPtr pkt) override;
     Tick write(PacketPtr pkt) override;
diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc
index 2b09f14..fccc984 100644
--- a/src/dev/x86/i82094aa.cc
+++ b/src/dev/x86/i82094aa.cc
@@ -70,12 +70,12 @@
     IntDevice::init();
 }
 
-BaseMasterPort &
-X86ISA::I82094AA::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+X86ISA::I82094AA::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "int_master")
         return intMasterPort;
-    return BasicPioDevice::getMasterPort(if_name, idx);
+    return BasicPioDevice::getPort(if_name, idx);
 }
 
 AddrRangeList
diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh
index c9e2f1c..d5cb42f 100644
--- a/src/dev/x86/i82094aa.hh
+++ b/src/dev/x86/i82094aa.hh
@@ -102,8 +102,8 @@
     void writeReg(uint8_t offset, uint32_t value);
     uint32_t readReg(uint8_t offset);
 
-    BaseMasterPort &getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     Tick recvResponse(PacketPtr pkt) override;
 
diff --git a/src/gpu-compute/compute_unit.hh b/src/gpu-compute/compute_unit.hh
index c15e7e0..cfe25d7 100644
--- a/src/gpu-compute/compute_unit.hh
+++ b/src/gpu-compute/compute_unit.hh
@@ -691,8 +691,8 @@
     // port to the SQC TLB (there's a separate TLB for each I-cache)
     ITLBPort *sqcTLBPort;
 
-    virtual BaseMasterPort&
-    getMasterPort(const std::string &if_name, PortID idx)
+    Port &
+    getPort(const std::string &if_name, PortID idx) override
     {
         if (if_name == "memory_port") {
             memPort[idx] = new DataPort(csprintf("%s-port%d", name(), idx),
diff --git a/src/gpu-compute/dispatcher.cc b/src/gpu-compute/dispatcher.cc
index db250c2..211e399 100644
--- a/src/gpu-compute/dispatcher.cc
+++ b/src/gpu-compute/dispatcher.cc
@@ -251,14 +251,14 @@
 }
 
 
-BaseMasterPort&
-GpuDispatcher::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+GpuDispatcher::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "translation_port") {
         return *tlbPort;
     }
 
-    return DmaDevice::getMasterPort(if_name, idx);
+    return DmaDevice::getPort(if_name, idx);
 }
 
 void
diff --git a/src/gpu-compute/dispatcher.hh b/src/gpu-compute/dispatcher.hh
index 92956e2d..17dc5a5 100644
--- a/src/gpu-compute/dispatcher.hh
+++ b/src/gpu-compute/dispatcher.hh
@@ -140,8 +140,8 @@
 
         TLBPort *tlbPort;
 
-        virtual BaseMasterPort& getMasterPort(const std::string &if_name,
-                                              PortID idx);
+        Port &getPort(const std::string &if_name,
+                      PortID idx=InvalidPortID) override;
 
         AddrRangeList getAddrRanges() const;
         Tick read(PacketPtr pkt);
diff --git a/src/gpu-compute/gpu_tlb.cc b/src/gpu-compute/gpu_tlb.cc
index 9e07b05..c23b998 100644
--- a/src/gpu-compute/gpu_tlb.cc
+++ b/src/gpu-compute/gpu_tlb.cc
@@ -137,33 +137,25 @@
         assert(translationReturnEvent.empty());
     }
 
-    BaseSlavePort&
-    GpuTLB::getSlavePort(const std::string &if_name, PortID idx)
+    Port &
+    GpuTLB::getPort(const std::string &if_name, PortID idx)
     {
         if (if_name == "slave") {
             if (idx >= static_cast<PortID>(cpuSidePort.size())) {
-                panic("TLBCoalescer::getSlavePort: unknown index %d\n", idx);
+                panic("TLBCoalescer::getPort: unknown index %d\n", idx);
             }
 
             return *cpuSidePort[idx];
-        } else {
-            panic("TLBCoalescer::getSlavePort: unknown port %s\n", if_name);
-        }
-    }
-
-    BaseMasterPort&
-    GpuTLB::getMasterPort(const std::string &if_name, PortID idx)
-    {
-        if (if_name == "master") {
+        } else if (if_name == "master") {
             if (idx >= static_cast<PortID>(memSidePort.size())) {
-                panic("TLBCoalescer::getMasterPort: unknown index %d\n", idx);
+                panic("TLBCoalescer::getPort: unknown index %d\n", idx);
             }
 
             hasMemSidePort = true;
 
             return *memSidePort[idx];
         } else {
-            panic("TLBCoalescer::getMasterPort: unknown port %s\n", if_name);
+            panic("TLBCoalescer::getPort: unknown port %s\n", if_name);
         }
     }
 
diff --git a/src/gpu-compute/gpu_tlb.hh b/src/gpu-compute/gpu_tlb.hh
index 9ca478d..80510d7 100644
--- a/src/gpu-compute/gpu_tlb.hh
+++ b/src/gpu-compute/gpu_tlb.hh
@@ -308,11 +308,8 @@
         // TLB ports on the memory side
         std::vector<MemSidePort*> memSidePort;
 
-        BaseMasterPort &getMasterPort(const std::string &if_name,
-                                      PortID idx=InvalidPortID);
-
-        BaseSlavePort &getSlavePort(const std::string &if_name,
-                                    PortID idx=InvalidPortID);
+        Port &getPort(const std::string &if_name,
+                      PortID idx=InvalidPortID) override;
 
         /**
          * TLB TranslationState: this currently is a somewhat bastardization of
diff --git a/src/gpu-compute/lds_state.hh b/src/gpu-compute/lds_state.hh
index ccf758b..05bc11e 100644
--- a/src/gpu-compute/lds_state.hh
+++ b/src/gpu-compute/lds_state.hh
@@ -436,8 +436,8 @@
         return range;
     }
 
-    virtual BaseSlavePort &
-    getSlavePort(const std::string& if_name, PortID idx)
+    Port &
+    getPort(const std::string &if_name, PortID idx)
     {
         if (if_name == "cuPort") {
             // TODO need to set name dynamically at this point?
diff --git a/src/gpu-compute/tlb_coalescer.cc b/src/gpu-compute/tlb_coalescer.cc
index 193c44e..3b7631a 100644
--- a/src/gpu-compute/tlb_coalescer.cc
+++ b/src/gpu-compute/tlb_coalescer.cc
@@ -67,31 +67,23 @@
     }
 }
 
-BaseSlavePort&
-TLBCoalescer::getSlavePort(const std::string &if_name, PortID idx)
+Port &
+TLBCoalescer::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "slave") {
         if (idx >= static_cast<PortID>(cpuSidePort.size())) {
-            panic("TLBCoalescer::getSlavePort: unknown index %d\n", idx);
+            panic("TLBCoalescer::getPort: unknown index %d\n", idx);
         }
 
         return *cpuSidePort[idx];
-    } else {
-        panic("TLBCoalescer::getSlavePort: unknown port %s\n", if_name);
-    }
-}
-
-BaseMasterPort&
-TLBCoalescer::getMasterPort(const std::string &if_name, PortID idx)
-{
-    if (if_name == "master") {
+    } else  if (if_name == "master") {
         if (idx >= static_cast<PortID>(memSidePort.size())) {
-            panic("TLBCoalescer::getMasterPort: unknown index %d\n", idx);
+            panic("TLBCoalescer::getPort: unknown index %d\n", idx);
         }
 
         return *memSidePort[idx];
     } else {
-        panic("TLBCoalescer::getMasterPort: unknown port %s\n", if_name);
+        panic("TLBCoalescer::getPort: unknown port %s\n", if_name);
     }
 }
 
diff --git a/src/gpu-compute/tlb_coalescer.hh b/src/gpu-compute/tlb_coalescer.hh
index 0294e4f..2aff810 100644
--- a/src/gpu-compute/tlb_coalescer.hh
+++ b/src/gpu-compute/tlb_coalescer.hh
@@ -211,8 +211,8 @@
     // Coalescer master ports on the memory side
     std::vector<MemSidePort*> memSidePort;
 
-    BaseMasterPort& getMasterPort(const std::string &if_name, PortID idx);
-    BaseSlavePort& getSlavePort(const std::string &if_name, PortID idx);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     void processProbeTLBEvent();
     /// This event issues the TLB probes
diff --git a/src/learning_gem5/part2/simple_cache.cc b/src/learning_gem5/part2/simple_cache.cc
index 1ddb515..880dc39 100644
--- a/src/learning_gem5/part2/simple_cache.cc
+++ b/src/learning_gem5/part2/simple_cache.cc
@@ -51,30 +51,20 @@
     }
 }
 
-BaseMasterPort&
-SimpleCache::getMasterPort(const std::string& if_name, PortID idx)
+Port &
+SimpleCache::getPort(const std::string &if_name, PortID idx)
 {
     panic_if(idx != InvalidPortID, "This object doesn't support vector ports");
 
     // This is the name from the Python SimObject declaration in SimpleCache.py
     if (if_name == "mem_side") {
         return memPort;
-    } else {
-        // pass it along to our super class
-        return MemObject::getMasterPort(if_name, idx);
-    }
-}
-
-BaseSlavePort&
-SimpleCache::getSlavePort(const std::string& if_name, PortID idx)
-{
-    // This is the name from the Python SimObject declaration (SimpleMemobj.py)
-    if (if_name == "cpu_side" && idx < cpuPorts.size()) {
+    } else if (if_name == "cpu_side" && idx < cpuPorts.size()) {
         // We should have already created all of the ports in the constructor
         return cpuPorts[idx];
     } else {
         // pass it along to our super class
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/learning_gem5/part2/simple_cache.hh b/src/learning_gem5/part2/simple_cache.hh
index 7d53ffe..56859eb 100644
--- a/src/learning_gem5/part2/simple_cache.hh
+++ b/src/learning_gem5/part2/simple_cache.hh
@@ -304,30 +304,17 @@
     SimpleCache(SimpleCacheParams *params);
 
     /**
-     * Get a master port with a given name and index. This is used at
+     * Get a port with a given name and index. This is used at
      * binding time and returns a reference to a protocol-agnostic
-     * base master port.
+     * port.
      *
      * @param if_name Port name
      * @param idx Index in the case of a VectorPort
      *
      * @return A reference to the given port
      */
-    virtual BaseMasterPort& getMasterPort(const std::string& if_name,
-                                          PortID idx = InvalidPortID) override;
-
-    /**
-     * Get a slave port with a given name and index. This is used at
-     * binding time and returns a reference to a protocol-agnostic
-     * base master port.
-     *
-     * @param if_name Port name
-     * @param idx Index in the case of a VectorPort
-     *
-     * @return A reference to the given port
-     */
-    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
-                                        PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     /**
      * Register the stats
diff --git a/src/learning_gem5/part2/simple_memobj.cc b/src/learning_gem5/part2/simple_memobj.cc
index cb4d3d8..c9af346 100644
--- a/src/learning_gem5/part2/simple_memobj.cc
+++ b/src/learning_gem5/part2/simple_memobj.cc
@@ -41,33 +41,21 @@
 {
 }
 
-BaseMasterPort&
-SimpleMemobj::getMasterPort(const std::string& if_name, PortID idx)
+Port &
+SimpleMemobj::getPort(const std::string &if_name, PortID idx)
 {
     panic_if(idx != InvalidPortID, "This object doesn't support vector ports");
 
     // This is the name from the Python SimObject declaration (SimpleMemobj.py)
     if (if_name == "mem_side") {
         return memPort;
-    } else {
-        // pass it along to our super class
-        return MemObject::getMasterPort(if_name, idx);
-    }
-}
-
-BaseSlavePort&
-SimpleMemobj::getSlavePort(const std::string& if_name, PortID idx)
-{
-    panic_if(idx != InvalidPortID, "This object doesn't support vector ports");
-
-    // This is the name from the Python SimObject declaration in SimpleCache.py
-    if (if_name == "inst_port") {
+    } else if (if_name == "inst_port") {
         return instPort;
     } else if (if_name == "data_port") {
         return dataPort;
     } else {
         // pass it along to our super class
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/learning_gem5/part2/simple_memobj.hh b/src/learning_gem5/part2/simple_memobj.hh
index a44d433..7a9b447 100644
--- a/src/learning_gem5/part2/simple_memobj.hh
+++ b/src/learning_gem5/part2/simple_memobj.hh
@@ -235,30 +235,17 @@
     SimpleMemobj(SimpleMemobjParams *params);
 
     /**
-     * Get a master port with a given name and index. This is used at
+     * Get a port with a given name and index. This is used at
      * binding time and returns a reference to a protocol-agnostic
-     * base master port.
+     * port.
      *
      * @param if_name Port name
      * @param idx Index in the case of a VectorPort
      *
      * @return A reference to the given port
      */
-    BaseMasterPort& getMasterPort(const std::string& if_name,
-                                  PortID idx = InvalidPortID) override;
-
-    /**
-     * Get a slave port with a given name and index. This is used at
-     * binding time and returns a reference to a protocol-agnostic
-     * base master port.
-     *
-     * @param if_name Port name
-     * @param idx Index in the case of a VectorPort
-     *
-     * @return A reference to the given port
-     */
-    BaseSlavePort& getSlavePort(const std::string& if_name,
-                                PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 };
 
 
diff --git a/src/mem/addr_mapper.cc b/src/mem/addr_mapper.cc
index 546dd69..958a8ad 100644
--- a/src/mem/addr_mapper.cc
+++ b/src/mem/addr_mapper.cc
@@ -53,23 +53,15 @@
         fatal("Address mapper is not connected on both sides.\n");
 }
 
-BaseMasterPort&
-AddrMapper::getMasterPort(const std::string& if_name, PortID idx)
+Port &
+AddrMapper::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "master") {
         return masterPort;
-    } else {
-        return MemObject::getMasterPort(if_name, idx);
-    }
-}
-
-BaseSlavePort&
-AddrMapper::getSlavePort(const std::string& if_name, PortID idx)
-{
-    if (if_name == "slave") {
+    } else if (if_name == "slave") {
         return slavePort;
     } else {
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/mem/addr_mapper.hh b/src/mem/addr_mapper.hh
index 6765638..6b47cfc 100644
--- a/src/mem/addr_mapper.hh
+++ b/src/mem/addr_mapper.hh
@@ -62,11 +62,8 @@
 
     virtual ~AddrMapper() { }
 
-    virtual BaseMasterPort& getMasterPort(const std::string& if_name,
-                                          PortID idx = InvalidPortID);
-
-    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
-                                        PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     virtual void init();
 
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index 1066f47..7428e7f 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -85,24 +85,16 @@
 {
 }
 
-BaseMasterPort&
-Bridge::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+Bridge::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "master")
         return masterPort;
-    else
-        // pass it along to our super class
-        return MemObject::getMasterPort(if_name, idx);
-}
-
-BaseSlavePort&
-Bridge::getSlavePort(const std::string &if_name, PortID idx)
-{
-    if (if_name == "slave")
+    else if (if_name == "slave")
         return slavePort;
     else
         // pass it along to our super class
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
 }
 
 void
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index bb77277..9066403 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -316,10 +316,8 @@
 
   public:
 
-    virtual BaseMasterPort& getMasterPort(const std::string& if_name,
-                                          PortID idx = InvalidPortID);
-    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
-                                        PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     virtual void init();
 
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index 50622d7..19655a5 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -185,23 +185,15 @@
     forwardSnoops = cpuSidePort.isSnooping();
 }
 
-BaseMasterPort &
-BaseCache::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+BaseCache::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "mem_side") {
         return memSidePort;
-    }  else {
-        return MemObject::getMasterPort(if_name, idx);
-    }
-}
-
-BaseSlavePort &
-BaseCache::getSlavePort(const std::string &if_name, PortID idx)
-{
-    if (if_name == "cpu_side") {
+    } else if (if_name == "cpu_side") {
         return cpuSidePort;
-    } else {
-        return MemObject::getSlavePort(if_name, idx);
+    }  else {
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index a7b25ff..a45dcba 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -1028,10 +1028,8 @@
 
     void init() override;
 
-    BaseMasterPort &getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override;
-    BaseSlavePort &getSlavePort(const std::string &if_name,
-                                PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     /**
      * Query block size of a cache.
diff --git a/src/mem/comm_monitor.cc b/src/mem/comm_monitor.cc
index 223d1cc..f27027d 100644
--- a/src/mem/comm_monitor.cc
+++ b/src/mem/comm_monitor.cc
@@ -83,23 +83,15 @@
     ppPktResp.reset(new ProbePoints::Packet(getProbeManager(), "PktResponse"));
 }
 
-BaseMasterPort&
-CommMonitor::getMasterPort(const std::string& if_name, PortID idx)
+Port &
+CommMonitor::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "master") {
         return masterPort;
-    } else {
-        return MemObject::getMasterPort(if_name, idx);
-    }
-}
-
-BaseSlavePort&
-CommMonitor::getSlavePort(const std::string& if_name, PortID idx)
-{
-    if (if_name == "slave") {
+    } else if (if_name == "slave") {
         return slavePort;
     } else {
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/mem/comm_monitor.hh b/src/mem/comm_monitor.hh
index dac7118..1eea6a5 100644
--- a/src/mem/comm_monitor.hh
+++ b/src/mem/comm_monitor.hh
@@ -84,11 +84,8 @@
     void regProbePoints() override;
 
   public: // MemObject interfaces
-    BaseMasterPort& getMasterPort(const std::string& if_name,
-                                  PortID idx = InvalidPortID) override;
-
-    BaseSlavePort& getSlavePort(const std::string& if_name,
-                                PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
   private:
 
diff --git a/src/mem/dram_ctrl.cc b/src/mem/dram_ctrl.cc
index b6ec465..dd03cf1 100644
--- a/src/mem/dram_ctrl.cc
+++ b/src/mem/dram_ctrl.cc
@@ -2845,11 +2845,11 @@
     functionalAccess(pkt);
 }
 
-BaseSlavePort&
-DRAMCtrl::getSlavePort(const string &if_name, PortID idx)
+Port &
+DRAMCtrl::getPort(const string &if_name, PortID idx)
 {
     if (if_name != "port") {
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     } else {
         return port;
     }
diff --git a/src/mem/dram_ctrl.hh b/src/mem/dram_ctrl.hh
index a5f2fbe..d09223b 100644
--- a/src/mem/dram_ctrl.hh
+++ b/src/mem/dram_ctrl.hh
@@ -1176,8 +1176,8 @@
 
     DrainState drain() override;
 
-    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
-                                        PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     virtual void init() override;
     virtual void startup() override;
diff --git a/src/mem/dramsim2.cc b/src/mem/dramsim2.cc
index 6fe8543..f0c6121 100644
--- a/src/mem/dramsim2.cc
+++ b/src/mem/dramsim2.cc
@@ -336,11 +336,11 @@
         signalDrainDone();
 }
 
-BaseSlavePort&
-DRAMSim2::getSlavePort(const std::string &if_name, PortID idx)
+Port &
+DRAMSim2::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name != "port") {
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     } else {
         return port;
     }
diff --git a/src/mem/dramsim2.hh b/src/mem/dramsim2.hh
index 6444f75..2fd140b 100644
--- a/src/mem/dramsim2.hh
+++ b/src/mem/dramsim2.hh
@@ -191,8 +191,8 @@
 
     DrainState drain() override;
 
-    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
-                                        PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     void init() override;
     void startup() override;
diff --git a/src/mem/external_master.cc b/src/mem/external_master.cc
index 373aa84..799f850 100644
--- a/src/mem/external_master.cc
+++ b/src/mem/external_master.cc
@@ -60,9 +60,8 @@
     masterId(params->system->getMasterId(this))
 {}
 
-BaseMasterPort &
-ExternalMaster::getMasterPort(const std::string &if_name,
-    PortID idx)
+Port &
+ExternalMaster::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "port") {
         DPRINTF(ExternalPort, "Trying to bind external port: %s %s\n",
@@ -84,7 +83,7 @@
         }
         return *externalPort;
     } else {
-        return MemObject::getMasterPort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/mem/external_master.hh b/src/mem/external_master.hh
index d27cb4d..42ac67c 100644
--- a/src/mem/external_master.hh
+++ b/src/mem/external_master.hh
@@ -67,18 +67,18 @@
 {
   public:
     /** Derive from this class to create an external port interface */
-    class Port : public MasterPort
+    class ExternalPort : public MasterPort
     {
       protected:
         ExternalMaster &owner;
 
       public:
-        Port(const std::string &name_,
+        ExternalPort(const std::string &name_,
             ExternalMaster &owner_) :
             MasterPort(name_, &owner_), owner(owner_)
         { }
 
-        ~Port() { }
+        ~ExternalPort() { }
 
         /** Any or all of recv... can be overloaded to provide the port's
          *  functionality */
@@ -93,14 +93,14 @@
       public:
         /** Create or find an external port which can be bound.  Returns
          *  NULL on failure */
-        virtual Port *getExternalPort(
+        virtual ExternalPort *getExternalPort(
             const std::string &name, ExternalMaster &owner,
             const std::string &port_data) = 0;
     };
 
   protected:
     /** The peer port for the gem5 port "port" */
-    Port *externalPort;
+    ExternalPort *externalPort;
 
     /** Name of the bound port.  This will be name() + ".port" */
     std::string portName;
@@ -120,9 +120,9 @@
   public:
     ExternalMaster(ExternalMasterParams *params);
 
-    /** MasterPort interface.  Responds only to port "port" */
-    BaseMasterPort &getMasterPort(const std::string &if_name,
-        PortID idx = InvalidPortID);
+    /** Port interface.  Responds only to port "port" */
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     /** Register a handler which can provide ports with port_type ==
      *  handler_name */
diff --git a/src/mem/external_slave.cc b/src/mem/external_slave.cc
index ac93e66..6266f66 100644
--- a/src/mem/external_slave.cc
+++ b/src/mem/external_slave.cc
@@ -49,7 +49,7 @@
  *  a message.  The stub port can be used to configure and test a system
  *  where the external port is used for a peripheral before connecting
  *  the external port */
-class StubSlavePort : public ExternalSlave::Port
+class StubSlavePort : public ExternalSlave::ExternalPort
 {
   public:
     void processResponseEvent();
@@ -66,7 +66,7 @@
 
     StubSlavePort(const std::string &name_,
         ExternalSlave &owner_) :
-        ExternalSlave::Port(name_, owner_),
+        ExternalSlave::ExternalPort(name_, owner_),
         responseEvent([this]{ processResponseEvent(); }, name()),
         responsePacket(NULL), mustRetry(false)
     { }
@@ -83,7 +83,7 @@
     ExternalSlave::Handler
 {
   public:
-    ExternalSlave::Port *getExternalPort(
+    ExternalSlave::ExternalPort *getExternalPort(
         const std::string &name_,
         ExternalSlave &owner,
         const std::string &port_data)
@@ -175,7 +175,7 @@
     ExternalSlave::portHandlers;
 
 AddrRangeList
-ExternalSlave::Port::getAddrRanges() const
+ExternalSlave::ExternalPort::getAddrRanges() const
 {
     return owner.addrRanges;
 }
@@ -193,9 +193,8 @@
         registerHandler("stub", new StubSlavePortHandler);
 }
 
-BaseSlavePort &
-ExternalSlave::getSlavePort(const std::string &if_name,
-    PortID idx)
+Port &
+ExternalSlave::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "port") {
         DPRINTF(ExternalPort, "Trying to bind external port: %s %s\n",
@@ -217,7 +216,7 @@
         }
         return *externalPort;
     } else {
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/mem/external_slave.hh b/src/mem/external_slave.hh
index 2bb0be8..7290d63 100644
--- a/src/mem/external_slave.hh
+++ b/src/mem/external_slave.hh
@@ -67,18 +67,18 @@
 {
   public:
     /** Derive from this class to create an external port interface */
-    class Port : public SlavePort
+    class ExternalPort : public SlavePort
     {
       protected:
         ExternalSlave &owner;
 
       public:
-        Port(const std::string &name_,
+        ExternalPort(const std::string &name_,
             ExternalSlave &owner_) :
             SlavePort(name_, &owner_), owner(owner_)
         { }
 
-        ~Port() { }
+        ~ExternalPort() { }
 
         /** Any or all of recv... can be overloaded to provide the port's
          *  functionality */
@@ -95,14 +95,14 @@
       public:
         /** Create or find an external port which can be bound.  Returns
          *  NULL on failure */
-        virtual Port *getExternalPort(
+        virtual ExternalPort *getExternalPort(
             const std::string &name, ExternalSlave &owner,
             const std::string &port_data) = 0;
     };
 
   protected:
     /** The peer port for the gem5 port "port" */
-    Port *externalPort;
+    ExternalPort *externalPort;
 
     /** Name of the bound port.  This will be name() + ".port" */
     std::string portName;
@@ -126,9 +126,9 @@
   public:
     ExternalSlave(ExternalSlaveParams *params);
 
-    /** SlavePort interface.  Responds only to port "port" */
-    BaseSlavePort &getSlavePort(const std::string &if_name,
-        PortID idx = InvalidPortID);
+    /** Port interface.  Responds only to port "port" */
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     /** Register a handler which can provide ports with port_type ==
      *  handler_name */
diff --git a/src/mem/mem_checker_monitor.cc b/src/mem/mem_checker_monitor.cc
index 75c797c..8364b91 100644
--- a/src/mem/mem_checker_monitor.cc
+++ b/src/mem/mem_checker_monitor.cc
@@ -73,23 +73,15 @@
         fatal("Communication monitor is not connected on both sides.\n");
 }
 
-BaseMasterPort&
-MemCheckerMonitor::getMasterPort(const std::string& if_name, PortID idx)
+Port &
+MemCheckerMonitor::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "master" || if_name == "mem_side") {
         return masterPort;
-    } else {
-        return MemObject::getMasterPort(if_name, idx);
-    }
-}
-
-BaseSlavePort&
-MemCheckerMonitor::getSlavePort(const std::string& if_name, PortID idx)
-{
-    if (if_name == "slave" || if_name == "cpu_side") {
+    } else if (if_name == "slave" || if_name == "cpu_side") {
         return slavePort;
     } else {
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/mem/mem_checker_monitor.hh b/src/mem/mem_checker_monitor.hh
index e3a8832..0564a81 100644
--- a/src/mem/mem_checker_monitor.hh
+++ b/src/mem/mem_checker_monitor.hh
@@ -70,11 +70,8 @@
     /** Destructor */
     ~MemCheckerMonitor();
 
-    virtual BaseMasterPort& getMasterPort(const std::string& if_name,
-                                          PortID idx = InvalidPortID);
-
-    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
-                                        PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     virtual void init();
 
diff --git a/src/mem/mem_delay.cc b/src/mem/mem_delay.cc
index b3c89d2..67a9664 100644
--- a/src/mem/mem_delay.cc
+++ b/src/mem/mem_delay.cc
@@ -60,23 +60,15 @@
 }
 
 
-BaseMasterPort&
-MemDelay::getMasterPort(const std::string& if_name, PortID idx)
+Port &
+MemDelay::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "master") {
         return masterPort;
-    } else {
-        return MemObject::getMasterPort(if_name, idx);
-    }
-}
-
-BaseSlavePort&
-MemDelay::getSlavePort(const std::string& if_name, PortID idx)
-{
-    if (if_name == "slave") {
+    } else if (if_name == "slave") {
         return slavePort;
     } else {
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/mem/mem_delay.hh b/src/mem/mem_delay.hh
index 7ecb656..789d965 100644
--- a/src/mem/mem_delay.hh
+++ b/src/mem/mem_delay.hh
@@ -69,12 +69,9 @@
 
     void init() override;
 
-  protected: // Port interfaces
-    BaseMasterPort& getMasterPort(const std::string &if_name,
-                                          PortID idx = InvalidPortID) override;
-
-    BaseSlavePort& getSlavePort(const std::string &if_name,
-                                PortID idx = InvalidPortID) override;
+  protected: // Port interface
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     class MasterPort : public QueuedMasterPort
     {
diff --git a/src/mem/mem_object.cc b/src/mem/mem_object.cc
index 766ecee..c88905d 100644
--- a/src/mem/mem_object.cc
+++ b/src/mem/mem_object.cc
@@ -47,15 +47,3 @@
     : ClockedObject(params)
 {
 }
-
-BaseMasterPort&
-MemObject::getMasterPort(const std::string& if_name, PortID idx)
-{
-    fatal("%s does not have any master port named %s\n", name(), if_name);
-}
-
-BaseSlavePort&
-MemObject::getSlavePort(const std::string& if_name, PortID idx)
-{
-    fatal("%s does not have any slave port named %s\n", name(), if_name);
-}
diff --git a/src/mem/mem_object.hh b/src/mem/mem_object.hh
index e12b306..3ae9c4a 100644
--- a/src/mem/mem_object.hh
+++ b/src/mem/mem_object.hh
@@ -54,8 +54,7 @@
 #include "sim/clocked_object.hh"
 
 /**
- * The MemObject class extends the ClockedObject with accessor functions
- * to get its master and slave ports.
+ * The MemObject class extends the ClockedObject for historical reasons.
  */
 class MemObject : public ClockedObject
 {
@@ -65,32 +64,6 @@
     { return dynamic_cast<const Params *>(_params); }
 
     MemObject(const Params *params);
-
-    /**
-     * Get a master port with a given name and index. This is used at
-     * binding time and returns a reference to a protocol-agnostic
-     * base master port.
-     *
-     * @param if_name Port name
-     * @param idx Index in the case of a VectorPort
-     *
-     * @return A reference to the given port
-     */
-    virtual BaseMasterPort& getMasterPort(const std::string& if_name,
-                                          PortID idx = InvalidPortID);
-
-    /**
-     * Get a slave port with a given name and index. This is used at
-     * binding time and returns a reference to a protocol-agnostic
-     * base master port.
-     *
-     * @param if_name Port name
-     * @param idx Index in the case of a VectorPort
-     *
-     * @return A reference to the given port
-     */
-    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
-                                        PortID idx = InvalidPortID);
 };
 
 #endif //__MEM_MEM_OBJECT_HH__
diff --git a/src/mem/qos/mem_sink.cc b/src/mem/qos/mem_sink.cc
index 77cfbaf..3ff2339 100644
--- a/src/mem/qos/mem_sink.cc
+++ b/src/mem/qos/mem_sink.cc
@@ -106,11 +106,11 @@
     pkt->popLabel();
 }
 
-BaseSlavePort &
-MemSinkCtrl::getSlavePort(const std::string &interface, PortID idx)
+Port &
+MemSinkCtrl::getPort(const std::string &interface, PortID idx)
 {
     if (interface != "port") {
-        return MemObject::getSlavePort(interface, idx);
+        return MemObject::getPort(interface, idx);
     } else {
         return port;
     }
diff --git a/src/mem/qos/mem_sink.hh b/src/mem/qos/mem_sink.hh
index 84258e0..9a51269 100644
--- a/src/mem/qos/mem_sink.hh
+++ b/src/mem/qos/mem_sink.hh
@@ -133,12 +133,11 @@
     /**
      * Getter method to access this memory's slave port
      *
-     * @param interface interface name
+     * @param if_name interface name
      * @param idx port ID number
      * @return reference to this memory's slave port
      */
-    BaseSlavePort& getSlavePort(const std::string&,
-            PortID = InvalidPortID) override;
+    Port &getPort(const std::string &if_name, PortID=InvalidPortID) override;
 
     /**
      * Initializes this object
diff --git a/src/mem/ruby/network/MessageBuffer.hh b/src/mem/ruby/network/MessageBuffer.hh
index 69a0fb3..4e85ac4 100644
--- a/src/mem/ruby/network/MessageBuffer.hh
+++ b/src/mem/ruby/network/MessageBuffer.hh
@@ -43,10 +43,12 @@
 
 #include "base/trace.hh"
 #include "debug/RubyQueue.hh"
+#include "mem/packet.hh"
+#include "mem/port.hh"
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/common/Consumer.hh"
+#include "mem/ruby/network/dummy_port.hh"
 #include "mem/ruby/slicc_interface/Message.hh"
-#include "mem/packet.hh"
 #include "params/MessageBuffer.hh"
 #include "sim/sim_object.hh"
 
@@ -120,6 +122,12 @@
     void setIncomingLink(int link_id) { m_input_link_id = link_id; }
     void setVnet(int net) { m_vnet_id = net; }
 
+    Port &
+    getPort(const std::string &, PortID idx=InvalidPortID) override
+    {
+        return RubyDummyPort::instance();
+    }
+
     void regStats();
 
     // Function for figuring out if any of the messages in the buffer need
diff --git a/src/mem/ruby/network/Network.hh b/src/mem/ruby/network/Network.hh
index 7f5ed2a..4e97918 100644
--- a/src/mem/ruby/network/Network.hh
+++ b/src/mem/ruby/network/Network.hh
@@ -60,11 +60,13 @@
 #include "base/addr_range.hh"
 #include "base/types.hh"
 #include "mem/packet.hh"
+#include "mem/port.hh"
 #include "mem/protocol/LinkDirection.hh"
 #include "mem/protocol/MessageSizeType.hh"
 #include "mem/ruby/common/MachineID.hh"
 #include "mem/ruby/common/TypeDefines.hh"
 #include "mem/ruby/network/Topology.hh"
+#include "mem/ruby/network/dummy_port.hh"
 #include "params/RubyNetwork.hh"
 #include "sim/clocked_object.hh"
 
@@ -132,6 +134,12 @@
      */
     NodeID addressToNodeID(Addr addr, MachineType mtype);
 
+    Port &
+    getPort(const std::string &, PortID idx=InvalidPortID) override
+    {
+        return RubyDummyPort::instance();
+    }
+
   protected:
     // Private copy constructor and assignment operator
     Network(const Network& obj);
diff --git a/src/dev/net/etherobject.hh b/src/mem/ruby/network/dummy_port.hh
similarity index 66%
rename from src/dev/net/etherobject.hh
rename to src/mem/ruby/network/dummy_port.hh
index 638c506..ca1ef41 100644
--- a/src/dev/net/etherobject.hh
+++ b/src/mem/ruby/network/dummy_port.hh
@@ -1,7 +1,5 @@
 /*
- * Copyright (c) 2007 The Regents of The University of Michigan
  * Copyright 2019 Google, Inc.
- * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -26,29 +24,36 @@
  * (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
- *          Gabe Black
+ * Authors: Gabe Black
  */
 
-/**
- * @file
- * Base Ethernet Object declaration.
- */
+#ifndef __MEM_RUBY_NETWORK_DUMMY_PORT_HH__
+#define __MEM_RUBY_NETWORK_DUMMY_PORT_HH__
 
-#ifndef __DEV_NET_ETHEROBJECT_HH__
-#define __DEV_NET_ETHEROBJECT_HH__
+#include "mem/port.hh"
 
-#include <string>
-
-class EtherInt;
-
-/**
- * The base EtherObject interface.
- */
-class EtherObject
+class RubyDummyPort : public Port
 {
   public:
-    virtual EtherInt *getEthPort(const std::string &if_name, int idx=-1) = 0;
+    RubyDummyPort() : Port("DummyPort", -1) {}
+
+    void
+    bind(Port &peer) override
+    {
+        // No need to connect anything here currently. MessageBuffer
+        // port connections only serve to print the connections in
+        // the config output.
+        // TODO: Add real ports to MessageBuffers and use MemObject connect
+        // code below to bind MessageBuffer senders and receivers
+    }
+    void unbind() override {}
+
+    static RubyDummyPort &
+    instance()
+    {
+        static RubyDummyPort dummy;
+        return dummy;
+    }
 };
 
-#endif // __DEV_NET_ETHEROBJECT_HH__
+#endif //__MEM_RUBY_NETWORK_DUMMY_PORT_HH__
diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc
index 1327ecc..fa1c936 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.cc
+++ b/src/mem/ruby/slicc_interface/AbstractController.cc
@@ -229,9 +229,8 @@
     return (m_block_map.count(addr) > 0);
 }
 
-BaseMasterPort &
-AbstractController::getMasterPort(const std::string &if_name,
-                                  PortID idx)
+Port &
+AbstractController::getPort(const std::string &if_name, PortID idx)
 {
     return memoryPort;
 }
diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh
index 35cd3d2..5e39a28 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.hh
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh
@@ -126,8 +126,8 @@
     virtual void initNetQueues() = 0;
 
     /** A function used to return the port associated with this bus object. */
-    BaseMasterPort& getMasterPort(const std::string& if_name,
-                                  PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID);
 
     void queueMemoryRead(const MachineID &id, Addr addr, Cycles latency);
     void queueMemoryWrite(const MachineID &id, Addr addr, Cycles latency,
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index 84a70c0..795b473 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -87,53 +87,37 @@
     m_mandatory_q_ptr = m_controller->getMandatoryQueue();
 }
 
-BaseMasterPort &
-RubyPort::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+RubyPort::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "mem_master_port") {
         return memMasterPort;
-    }
-
-    if (if_name == "pio_master_port") {
+    } else if (if_name == "pio_master_port") {
         return pioMasterPort;
-    }
-
-    // used by the x86 CPUs to connect the interrupt PIO and interrupt slave
-    // port
-    if (if_name != "master") {
-        // pass it along to our super class
-        return MemObject::getMasterPort(if_name, idx);
-    } else {
+    } else if (if_name == "mem_slave_port") {
+        return memSlavePort;
+    } else if (if_name == "pio_slave_port") {
+        return pioSlavePort;
+    } else if (if_name == "master") {
+        // used by the x86 CPUs to connect the interrupt PIO and interrupt
+        // slave port
         if (idx >= static_cast<PortID>(master_ports.size())) {
-            panic("RubyPort::getMasterPort: unknown index %d\n", idx);
+            panic("RubyPort::getPort master: unknown index %d\n", idx);
         }
 
         return *master_ports[idx];
-    }
-}
-
-BaseSlavePort &
-RubyPort::getSlavePort(const std::string &if_name, PortID idx)
-{
-    if (if_name == "mem_slave_port") {
-        return memSlavePort;
-    }
-
-    if (if_name == "pio_slave_port")
-        return pioSlavePort;
-
-    // used by the CPUs to connect the caches to the interconnect, and
-    // for the x86 case also the interrupt master
-    if (if_name != "slave") {
-        // pass it along to our super class
-        return MemObject::getSlavePort(if_name, idx);
-    } else {
+    } else if (if_name == "slave") {
+        // used by the CPUs to connect the caches to the interconnect, and
+        // for the x86 case also the interrupt master
         if (idx >= static_cast<PortID>(slave_ports.size())) {
-            panic("RubyPort::getSlavePort: unknown index %d\n", idx);
+            panic("RubyPort::getPort slave: unknown index %d\n", idx);
         }
 
         return *slave_ports[idx];
     }
+
+    // pass it along to our super class
+    return MemObject::getPort(if_name, idx);
 }
 
 RubyPort::PioMasterPort::PioMasterPort(const std::string &_name,
diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh
index 1464432..922b3a9 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -148,10 +148,8 @@
 
     void init() override;
 
-    BaseMasterPort &getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override;
-    BaseSlavePort &getSlavePort(const std::string &if_name,
-                                PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     virtual RequestStatus makeRequest(PacketPtr pkt) = 0;
     virtual int outstandingCount() const = 0;
diff --git a/src/mem/serial_link.cc b/src/mem/serial_link.cc
index e1f3a00..438fb0e 100644
--- a/src/mem/serial_link.cc
+++ b/src/mem/serial_link.cc
@@ -93,24 +93,16 @@
 {
 }
 
-BaseMasterPort&
-SerialLink::getMasterPort(const std::string &if_name, PortID idx)
+Port&
+SerialLink::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "master")
         return masterPort;
-    else
-        // pass it along to our super class
-        return MemObject::getMasterPort(if_name, idx);
-}
-
-BaseSlavePort&
-SerialLink::getSlavePort(const std::string &if_name, PortID idx)
-{
-    if (if_name == "slave")
+    else if (if_name == "slave")
         return slavePort;
     else
         // pass it along to our super class
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
 }
 
 void
diff --git a/src/mem/serial_link.hh b/src/mem/serial_link.hh
index 6315f1b..0bb1692 100644
--- a/src/mem/serial_link.hh
+++ b/src/mem/serial_link.hh
@@ -315,10 +315,8 @@
 
   public:
 
-    virtual BaseMasterPort& getMasterPort(const std::string& if_name,
-                                          PortID idx = InvalidPortID);
-    virtual BaseSlavePort& getSlavePort(const std::string& if_name,
-                                        PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID);
 
     virtual void init();
 
diff --git a/src/mem/simple_mem.cc b/src/mem/simple_mem.cc
index 64d7d20..32fea1e 100644
--- a/src/mem/simple_mem.cc
+++ b/src/mem/simple_mem.cc
@@ -231,11 +231,11 @@
     dequeue();
 }
 
-BaseSlavePort &
-SimpleMemory::getSlavePort(const std::string &if_name, PortID idx)
+Port &
+SimpleMemory::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name != "port") {
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     } else {
         return port;
     }
diff --git a/src/mem/simple_mem.hh b/src/mem/simple_mem.hh
index 307981b..c8c3db5 100644
--- a/src/mem/simple_mem.hh
+++ b/src/mem/simple_mem.hh
@@ -187,8 +187,8 @@
 
     DrainState drain() override;
 
-    BaseSlavePort& getSlavePort(const std::string& if_name,
-                                PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
     void init() override;
 
   protected:
diff --git a/src/mem/xbar.cc b/src/mem/xbar.cc
index b139cdc..247024e 100644
--- a/src/mem/xbar.cc
+++ b/src/mem/xbar.cc
@@ -81,27 +81,19 @@
 {
 }
 
-BaseMasterPort &
-BaseXBar::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+BaseXBar::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "master" && idx < masterPorts.size()) {
         // the master port index translates directly to the vector position
         return *masterPorts[idx];
     } else  if (if_name == "default") {
         return *masterPorts[defaultPortID];
-    } else {
-        return MemObject::getMasterPort(if_name, idx);
-    }
-}
-
-BaseSlavePort &
-BaseXBar::getSlavePort(const std::string &if_name, PortID idx)
-{
-    if (if_name == "slave" && idx < slavePorts.size()) {
+    } else if (if_name == "slave" && idx < slavePorts.size()) {
         // the slave port index translates directly to the vector position
         return *slavePorts[idx];
     } else {
-        return MemObject::getSlavePort(if_name, idx);
+        return MemObject::getPort(if_name, idx);
     }
 }
 
diff --git a/src/mem/xbar.hh b/src/mem/xbar.hh
index abe2a10..0745ea5 100644
--- a/src/mem/xbar.hh
+++ b/src/mem/xbar.hh
@@ -413,10 +413,8 @@
     virtual void init();
 
     /** A function used to return the port associated with this object. */
-    BaseMasterPort& getMasterPort(const std::string& if_name,
-                                  PortID idx = InvalidPortID);
-    BaseSlavePort& getSlavePort(const std::string& if_name,
-                                PortID idx = InvalidPortID);
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     virtual void regStats();
 
diff --git a/src/python/SConscript b/src/python/SConscript
index 36e0d5b..fb1666c 100644
--- a/src/python/SConscript
+++ b/src/python/SConscript
@@ -70,5 +70,4 @@
 Source('pybind11/core.cc', add_tags='python')
 Source('pybind11/debug.cc', add_tags='python')
 Source('pybind11/event.cc', add_tags='python')
-Source('pybind11/pyobject.cc', add_tags='python')
 Source('pybind11/stats.cc', add_tags='python')
diff --git a/src/python/pybind11/pybind.hh b/src/python/pybind11/pybind.hh
index 9a0643c..e2e470a 100644
--- a/src/python/pybind11/pybind.hh
+++ b/src/python/pybind11/pybind.hh
@@ -46,7 +46,6 @@
 void pybind_init_debug(pybind11::module &m_native);
 
 void pybind_init_event(pybind11::module &m_native);
-void pybind_init_pyobject(pybind11::module &m_native);
 void pybind_init_stats(pybind11::module &m_native);
 
 #endif
diff --git a/src/python/pybind11/pyobject.cc b/src/python/pybind11/pyobject.cc
deleted file mode 100644
index bd363a1..0000000
--- a/src/python/pybind11/pyobject.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2017 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: Nathan Binkert
- */
-
-#include "pybind11/pybind11.h"
-
-#include <string>
-
-#include "config/the_isa.hh"
-
-#include "dev/net/etherdevice.hh"
-#include "dev/net/etherint.hh"
-#include "dev/net/etherobject.hh"
-#include "mem/mem_object.hh"
-#include "mem/ruby/network/Network.hh"
-#include "mem/ruby/slicc_interface/AbstractController.hh"
-#include "mem/ruby/system/Sequencer.hh"
-#include "sim/full_system.hh"
-
-namespace py = pybind11;
-
-/**
- * Connect the described MemObject ports.  Called from Python.
- * The indices i1 & i2 will be -1 for regular ports, >= 0 for vector ports.
- * SimObject1 is the master, and SimObject2 is the slave
- */
-static int
-connectPorts(SimObject *o1, const std::string &name1, int i1,
-             SimObject *o2, const std::string &name2, int i2)
-{
-    auto *eo1 = dynamic_cast<EtherObject*>(o1);
-    auto *eo2 = dynamic_cast<EtherObject*>(o2);
-
-    if (eo1 && eo2) {
-        EtherInt *p1 = eo1->getEthPort(name1, i1);
-        EtherInt *p2 = eo2->getEthPort(name2, i2);
-
-        if (p1 && p2) {
-            p1->setPeer(p2);
-            p2->setPeer(p1);
-
-            return 1;
-        }
-    }
-
-    // These could be MessageBuffers from the ruby memory system. If so, they
-    // need not be connected to anything currently.
-    MessageBuffer *mb1, *mb2;
-    mb1 = dynamic_cast<MessageBuffer*>(o1);
-    mb2 = dynamic_cast<MessageBuffer*>(o2);
-    Network *nw1, *nw2;
-    nw1 = dynamic_cast<Network*>(o1);
-    nw2 = dynamic_cast<Network*>(o2);
-
-    if ((mb1 || nw1) && (mb2 || nw2)) {
-        // No need to connect anything here currently. MessageBuffer
-        // connections in Python only serve to print the connections in
-        // the config output.
-        // TODO: Add real ports to MessageBuffers and use MemObject connect
-        // code below to bind MessageBuffer senders and receivers
-        return 1;
-    }
-
-    MemObject *mo1, *mo2;
-    mo1 = dynamic_cast<MemObject*>(o1);
-    mo2 = dynamic_cast<MemObject*>(o2);
-
-    if (mo1 == NULL || mo2 == NULL) {
-        panic ("Error casting SimObjects %s and %s to MemObject", o1->name(),
-               o2->name());
-    }
-
-    // generic master/slave port connection
-    BaseMasterPort& masterPort = mo1->getMasterPort(name1, i1);
-    BaseSlavePort& slavePort   = mo2->getSlavePort(name2, i2);
-
-    masterPort.bind(slavePort);
-
-    return 1;
-}
-
-void
-pybind_init_pyobject(py::module &m_native)
-{
-    py::module m = m_native.def_submodule("pyobject");
-
-    m.def("connectPorts", &connectPorts);
-}
diff --git a/src/sim/SConscript b/src/sim/SConscript
index a59b0ed..54e2512 100644
--- a/src/sim/SConscript
+++ b/src/sim/SConscript
@@ -55,6 +55,7 @@
 Source('init_signals.cc')
 Source('main.cc', tags='main')
 Source('port.cc')
+Source('python.cc', add_tags='python')
 Source('root.cc')
 Source('serialize.cc')
 Source('drain.cc')
diff --git a/src/sim/cxx_manager.cc b/src/sim/cxx_manager.cc
index 9157361..35d008d 100644
--- a/src/sim/cxx_manager.cc
+++ b/src/sim/cxx_manager.cc
@@ -471,9 +471,9 @@
      *  getCxxConfigDirectoryEntry for each object. */
 
     /* It would be nice to be able to catch the errors from these calls. */
-    BaseMasterPort &master_port = master_mem_object->getMasterPort(
+    Port &master_port = master_mem_object->getPort(
         master_port_name, master_port_index);
-    BaseSlavePort &slave_port = slave_mem_object->getSlavePort(
+    Port &slave_port = slave_mem_object->getPort(
         slave_port_name, slave_port_index);
 
     if (master_port.isConnected()) {
diff --git a/src/sim/init.cc b/src/sim/init.cc
index 5a49f36..1fb7e6e 100644
--- a/src/sim/init.cc
+++ b/src/sim/init.cc
@@ -207,7 +207,6 @@
     pybind_init_debug(m_m5);
 
     pybind_init_event(m_m5);
-    pybind_init_pyobject(m_m5);
     pybind_init_stats(m_m5);
 
     for (auto &kv : getMap()) {
diff --git a/src/dev/net/python.cc b/src/sim/python.cc
similarity index 82%
rename from src/dev/net/python.cc
rename to src/sim/python.cc
index a012074..159f32a 100644
--- a/src/dev/net/python.cc
+++ b/src/sim/python.cc
@@ -27,22 +27,22 @@
  * Authors: Gabe Black
  */
 
-#include "python/pybind11/pybind.hh"
-
-#include "dev/net/etherobject.hh"
+#include "pybind11/pybind11.h"
 #include "sim/init.hh"
+#include "sim/port.hh"
 
 namespace
 {
 
 void
-ethernet_pybind(pybind11::module &m_internal)
+sim_pybind(pybind11::module &m_internal)
 {
-    pybind11::module m = m_internal.def_submodule("ethernet");
+    pybind11::module m = m_internal.def_submodule("sim");
     pybind11::class_<
-        EtherObject, std::unique_ptr<EtherObject, pybind11::nodelete>>(
-                m, "EtherObject");
+        Port, std::unique_ptr<Port, pybind11::nodelete>>(m, "Port")
+        .def("bind", &Port::bind)
+        ;
 }
-EmbeddedPyBind embed_("ethernet", &ethernet_pybind);
+EmbeddedPyBind embed_("sim", &sim_pybind);
 
 } // anonymous namespace
diff --git a/src/sim/system.cc b/src/sim/system.cc
index ffa8eda..2113fc0 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -218,8 +218,8 @@
         panic("System port on %s is not connected.\n", name());
 }
 
-BaseMasterPort&
-System::getMasterPort(const std::string &if_name, PortID idx)
+Port &
+System::getPort(const std::string &if_name, PortID idx)
 {
     // no need to distinguish at the moment (besides checking)
     return _systemPort;
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 878c812..69448d3 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -128,8 +128,8 @@
     /**
      * Additional function to return the Port of a memory object.
      */
-    BaseMasterPort& getMasterPort(const std::string &if_name,
-                                  PortID idx = InvalidPortID) override;
+    Port &getPort(const std::string &if_name,
+                  PortID idx=InvalidPortID) override;
 
     /** @{ */
     /**