From: Andreas Hansson Date: Mon, 15 Oct 2012 12:12:35 +0000 (-0400) Subject: Port: Add protocol-agnostic ports in the port hierarchy X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2a740aa09682c32eb8f1f8880f279c943d8c6ee1;p=gem5.git Port: Add protocol-agnostic ports in the port hierarchy This patch adds an additional level of ports in the inheritance hierarchy, separating out the protocol-specific and protocl-agnostic parts. All the functionality related to the binding of ports is now confined to use BaseMaster/BaseSlavePorts, and all the protocol-specific parts stay in the Master/SlavePort. In the future it will be possible to add other protocol-specific implementations. The functions used in the binding of ports, i.e. getMaster/SlavePort now use the base classes, and the index parameter is updated to use the PortID typedef with the symbolic InvalidPortID as the default. --- diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index dbd4211d5..5f4453935 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -110,8 +110,8 @@ TableWalker::resume() } } -MasterPort& -TableWalker::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort& +TableWalker::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "port") { return port; diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh index 509b24339..22c5d03b4 100644 --- a/src/arch/arm/table_walker.hh +++ b/src/arch/arm/table_walker.hh @@ -399,8 +399,8 @@ class TableWalker : public MemObject void completeDrain(); virtual unsigned int drain(Event *de); virtual void resume(); - virtual MasterPort& getMasterPort(const std::string &if_name, - int idx = -1); + virtual BaseMasterPort& getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode, TLB::Translation *_trans, bool timing, bool functional = false); diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index f9b2e6fe7..e7ac935e6 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -722,7 +722,7 @@ TLB::translateTiming(RequestPtr req, ThreadContext *tc, return fault; } -MasterPort* +BaseMasterPort* TLB::getMasterPort() { return &tableWalker->getMasterPort("port"); diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh index a20957f6a..968699764 100644 --- a/src/arch/arm/tlb.hh +++ b/src/arch/arm/tlb.hh @@ -224,7 +224,7 @@ class TLB : public BaseTLB * * @return A pointer to the walker master port */ - virtual MasterPort* getMasterPort(); + virtual BaseMasterPort* getMasterPort(); // Caching misc register values here. // Writing to misc registers needs to invalidate them. diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 06425fbda..06094f0b1 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -238,7 +238,8 @@ class Interrupts : public BasicPioDevice, IntDev AddrRangeList getAddrRanges() const; AddrRangeList getIntAddrRange() const; - MasterPort &getMasterPort(const std::string &if_name, int idx = -1) + BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID) { if (if_name == "int_master") { return intMasterPort; @@ -246,7 +247,8 @@ class Interrupts : public BasicPioDevice, IntDev return BasicPioDevice::getMasterPort(if_name, idx); } - SlavePort &getSlavePort(const std::string &if_name, int idx = -1) + BaseSlavePort &getSlavePort(const std::string &if_name, + PortID idx = InvalidPortID) { if (if_name == "int_slave") { return intSlavePort; diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index 46d608ace..1e42e5593 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -173,8 +173,8 @@ bool Walker::sendTiming(WalkerState* sendingState, PacketPtr pkt) return port.sendTimingReq(pkt); } -MasterPort & -Walker::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +Walker::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "port") return port; diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh index c59661619..07f476b00 100644 --- a/src/arch/x86/pagetable_walker.hh +++ b/src/arch/x86/pagetable_walker.hh @@ -169,7 +169,8 @@ namespace X86ISA RequestPtr req, BaseTLB::Mode mode); Fault startFunctional(ThreadContext * _tc, Addr &addr, unsigned &logBytes, BaseTLB::Mode mode); - MasterPort &getMasterPort(const std::string &if_name, int idx = -1); + BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); protected: // The TLB we're supposed to load. diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index df7a33ad2..fb7dac02e 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -435,7 +435,7 @@ TLB::unserialize(Checkpoint *cp, const std::string §ion) { } -MasterPort * +BaseMasterPort * TLB::getMasterPort() { return &walker->getMasterPort("port"); diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index 1d1204cfe..85bcead57 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -147,7 +147,7 @@ namespace X86ISA * * @return A pointer to the walker master port */ - virtual MasterPort *getMasterPort(); + virtual BaseMasterPort *getMasterPort(); }; } diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 1add92d1f..93c9f8629 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -296,8 +296,8 @@ BaseCPU::regStats() threadContexts[0]->regStats(name()); } -MasterPort & -BaseCPU::getMasterPort(const string &if_name, int idx) +BaseMasterPort & +BaseCPU::getMasterPort(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 @@ -380,17 +380,17 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) ThreadContext::compare(oldTC, newTC); */ - MasterPort *old_itb_port = oldTC->getITBPtr()->getMasterPort(); - MasterPort *old_dtb_port = oldTC->getDTBPtr()->getMasterPort(); - MasterPort *new_itb_port = newTC->getITBPtr()->getMasterPort(); - MasterPort *new_dtb_port = newTC->getDTBPtr()->getMasterPort(); + BaseMasterPort *old_itb_port = oldTC->getITBPtr()->getMasterPort(); + BaseMasterPort *old_dtb_port = oldTC->getDTBPtr()->getMasterPort(); + BaseMasterPort *new_itb_port = newTC->getITBPtr()->getMasterPort(); + BaseMasterPort *new_dtb_port = newTC->getDTBPtr()->getMasterPort(); // 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()); - SlavePort &slavePort = old_itb_port->getSlavePort(); + BaseSlavePort &slavePort = old_itb_port->getSlavePort(); old_itb_port->unbind(); new_itb_port->bind(slavePort); } @@ -398,7 +398,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) assert(!new_dtb_port->isConnected()); assert(old_dtb_port); assert(old_dtb_port->isConnected()); - SlavePort &slavePort = old_dtb_port->getSlavePort(); + BaseSlavePort &slavePort = old_dtb_port->getSlavePort(); old_dtb_port->unbind(); new_dtb_port->bind(slavePort); } @@ -408,13 +408,13 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) CheckerCPU *oldChecker = oldTC->getCheckerCpuPtr(); CheckerCPU *newChecker = newTC->getCheckerCpuPtr(); if (oldChecker && newChecker) { - MasterPort *old_checker_itb_port = + BaseMasterPort *old_checker_itb_port = oldChecker->getITBPtr()->getMasterPort(); - MasterPort *old_checker_dtb_port = + BaseMasterPort *old_checker_dtb_port = oldChecker->getDTBPtr()->getMasterPort(); - MasterPort *new_checker_itb_port = + BaseMasterPort *new_checker_itb_port = newChecker->getITBPtr()->getMasterPort(); - MasterPort *new_checker_dtb_port = + BaseMasterPort *new_checker_dtb_port = newChecker->getDTBPtr()->getMasterPort(); // Move over any table walker ports if they exist for checker @@ -422,7 +422,8 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) assert(!new_checker_itb_port->isConnected()); assert(old_checker_itb_port); assert(old_checker_itb_port->isConnected()); - SlavePort &slavePort = old_checker_itb_port->getSlavePort(); + BaseSlavePort &slavePort = + old_checker_itb_port->getSlavePort(); old_checker_itb_port->unbind(); new_checker_itb_port->bind(slavePort); } @@ -430,7 +431,8 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) assert(!new_checker_dtb_port->isConnected()); assert(old_checker_dtb_port); assert(old_checker_dtb_port->isConnected()); - SlavePort &slavePort = old_checker_dtb_port->getSlavePort(); + BaseSlavePort &slavePort = + old_checker_dtb_port->getSlavePort(); old_checker_dtb_port->unbind(); new_checker_dtb_port->bind(slavePort); } @@ -455,13 +457,13 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) // we are switching to. assert(!getInstPort().isConnected()); assert(oldCPU->getInstPort().isConnected()); - SlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort(); + BaseSlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort(); oldCPU->getInstPort().unbind(); getInstPort().bind(inst_peer_port); assert(!getDataPort().isConnected()); assert(oldCPU->getDataPort().isConnected()); - SlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort(); + BaseSlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort(); oldCPU->getDataPort().unbind(); getDataPort().bind(data_peer_port); } diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 0c1d19856..91cef24ed 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -171,7 +171,8 @@ class BaseCPU : public MemObject * * @return a reference to the port with the given name */ - MasterPort &getMasterPort(const std::string &if_name, int idx = -1); + BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); inline void workItemBegin() { numWorkItemsStarted++; } inline void workItemEnd() { numWorkItemsCompleted++; } diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.cc b/src/cpu/testers/directedtest/RubyDirectedTester.cc index 139798a72..70da23f03 100644 --- a/src/cpu/testers/directedtest/RubyDirectedTester.cc +++ b/src/cpu/testers/directedtest/RubyDirectedTester.cc @@ -74,8 +74,8 @@ RubyDirectedTester::init() generator->setDirectedTester(this); } -MasterPort & -RubyDirectedTester::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +RubyDirectedTester::getMasterPort(const std::string &if_name, PortID idx) { if (if_name != "cpuPort") { // pass it along to our super class diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.hh b/src/cpu/testers/directedtest/RubyDirectedTester.hh index 325c60447..cb58fa63f 100644 --- a/src/cpu/testers/directedtest/RubyDirectedTester.hh +++ b/src/cpu/testers/directedtest/RubyDirectedTester.hh @@ -68,8 +68,8 @@ class RubyDirectedTester : public MemObject RubyDirectedTester(const Params *p); ~RubyDirectedTester(); - virtual MasterPort &getMasterPort(const std::string &if_name, - int idx = -1); + virtual BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); MasterPort* getCpuPort(int idx); diff --git a/src/cpu/testers/memtest/memtest.cc b/src/cpu/testers/memtest/memtest.cc index 7ea6ad84b..ea3e5fd9b 100644 --- a/src/cpu/testers/memtest/memtest.cc +++ b/src/cpu/testers/memtest/memtest.cc @@ -131,8 +131,8 @@ MemTest::MemTest(const Params *p) dmaOutstanding = false; } -MasterPort & -MemTest::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +MemTest::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "functional") return funcPort; diff --git a/src/cpu/testers/memtest/memtest.hh b/src/cpu/testers/memtest/memtest.hh index 94617c876..cb5f8300f 100644 --- a/src/cpu/testers/memtest/memtest.hh +++ b/src/cpu/testers/memtest/memtest.hh @@ -59,8 +59,8 @@ class MemTest : public MemObject // main simulation loop (one cycle) void tick(); - virtual MasterPort &getMasterPort(const std::string &if_name, - int idx = -1); + virtual BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); /** * Print state of address in memory system via PrintReq (for diff --git a/src/cpu/testers/networktest/networktest.cc b/src/cpu/testers/networktest/networktest.cc index 3f61a87d3..8fff53aa7 100644 --- a/src/cpu/testers/networktest/networktest.cc +++ b/src/cpu/testers/networktest/networktest.cc @@ -97,8 +97,8 @@ NetworkTest::NetworkTest(const Params *p) name(), id); } -MasterPort & -NetworkTest::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +NetworkTest::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "test") return cachePort; diff --git a/src/cpu/testers/networktest/networktest.hh b/src/cpu/testers/networktest/networktest.hh index 76119e678..253b48233 100644 --- a/src/cpu/testers/networktest/networktest.hh +++ b/src/cpu/testers/networktest/networktest.hh @@ -54,8 +54,8 @@ class NetworkTest : public MemObject // main simulation loop (one cycle) void tick(); - virtual MasterPort &getMasterPort(const std::string &if_name, - int idx = -1); + virtual BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); /** * Print state of address in memory system via PrintReq (for diff --git a/src/cpu/testers/rubytest/RubyTester.cc b/src/cpu/testers/rubytest/RubyTester.cc index bdd6dacce..6ddab93e8 100644 --- a/src/cpu/testers/rubytest/RubyTester.cc +++ b/src/cpu/testers/rubytest/RubyTester.cc @@ -111,8 +111,8 @@ RubyTester::init() m_checkTable_ptr = new CheckTable(m_num_writers, m_num_readers, this); } -MasterPort & -RubyTester::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +RubyTester::getMasterPort(const std::string &if_name, PortID idx) { if (if_name != "cpuInstPort" && if_name != "cpuDataPort") { // pass it along to our super class @@ -134,7 +134,7 @@ RubyTester::getMasterPort(const std::string &if_name, int idx) // index // int read_idx = idx + m_num_inst_ports; - if (read_idx >= static_cast(readPorts.size())) { + if (read_idx >= static_cast(readPorts.size())) { panic("RubyTester::getMasterPort: unknown data port idx %d\n", idx); } diff --git a/src/cpu/testers/rubytest/RubyTester.hh b/src/cpu/testers/rubytest/RubyTester.hh index ad4b506ac..2fed84e2d 100644 --- a/src/cpu/testers/rubytest/RubyTester.hh +++ b/src/cpu/testers/rubytest/RubyTester.hh @@ -89,8 +89,8 @@ class RubyTester : public MemObject RubyTester(const Params *p); ~RubyTester(); - virtual MasterPort &getMasterPort(const std::string &if_name, - int idx = -1); + virtual BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); bool isInstReadableCpuPort(int idx); diff --git a/src/cpu/testers/traffic_gen/traffic_gen.cc b/src/cpu/testers/traffic_gen/traffic_gen.cc index 054900b20..af7ff89f4 100644 --- a/src/cpu/testers/traffic_gen/traffic_gen.cc +++ b/src/cpu/testers/traffic_gen/traffic_gen.cc @@ -66,8 +66,8 @@ TrafficGenParams::create() return new TrafficGen(this); } -MasterPort& -TrafficGen::getMasterPort(const string& if_name, int idx) +BaseMasterPort& +TrafficGen::getMasterPort(const string& if_name, PortID idx) { if (if_name == "port") { return port; diff --git a/src/cpu/testers/traffic_gen/traffic_gen.hh b/src/cpu/testers/traffic_gen/traffic_gen.hh index 19182fa15..5f59be82c 100644 --- a/src/cpu/testers/traffic_gen/traffic_gen.hh +++ b/src/cpu/testers/traffic_gen/traffic_gen.hh @@ -597,8 +597,8 @@ class TrafficGen : public MemObject ~TrafficGen() {} - virtual MasterPort& getMasterPort(const std::string &if_name, - int idx = InvalidPortID); + virtual BaseMasterPort& getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); void init(); diff --git a/src/dev/copy_engine.cc b/src/dev/copy_engine.cc index 77cc735a9..799e9f96a 100644 --- a/src/dev/copy_engine.cc +++ b/src/dev/copy_engine.cc @@ -110,8 +110,8 @@ CopyEngine::CopyEngineChannel::~CopyEngineChannel() delete [] copyBuffer; } -MasterPort & -CopyEngine::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +CopyEngine::getMasterPort(const std::string &if_name, PortID idx) { if (if_name != "dma") { // pass it along to our super class @@ -126,7 +126,7 @@ CopyEngine::getMasterPort(const std::string &if_name, int idx) } -MasterPort & +BaseMasterPort & CopyEngine::CopyEngineChannel::getMasterPort() { return cePort; diff --git a/src/dev/copy_engine.hh b/src/dev/copy_engine.hh index 28fc6315c..41b4a631e 100644 --- a/src/dev/copy_engine.hh +++ b/src/dev/copy_engine.hh @@ -94,7 +94,7 @@ class CopyEngine : public PciDev public: CopyEngineChannel(CopyEngine *_ce, int cid); virtual ~CopyEngineChannel(); - MasterPort &getMasterPort(); + BaseMasterPort &getMasterPort(); std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); } virtual Tick read(PacketPtr pkt) @@ -196,8 +196,8 @@ class CopyEngine : public PciDev void regStats(); - virtual MasterPort &getMasterPort(const std::string &if_name, - int idx = -1); + virtual BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); virtual Tick read(PacketPtr pkt); virtual Tick write(PacketPtr pkt); diff --git a/src/dev/dma_device.cc b/src/dev/dma_device.cc index c64694315..43d45146f 100644 --- a/src/dev/dma_device.cc +++ b/src/dev/dma_device.cc @@ -254,8 +254,8 @@ DmaPort::sendDma() panic("Unknown memory mode."); } -MasterPort & -DmaDevice::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +DmaDevice::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "dma") { return dmaPort; diff --git a/src/dev/dma_device.hh b/src/dev/dma_device.hh index 48c3f9c61..c46fbfd76 100644 --- a/src/dev/dma_device.hh +++ b/src/dev/dma_device.hh @@ -156,8 +156,8 @@ class DmaDevice : public PioDevice unsigned cacheBlockSize() const { return dmaPort.cacheBlockSize(); } - virtual MasterPort &getMasterPort(const std::string &if_name, - int idx = -1); + virtual BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); friend class DmaPort; }; diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 30779cfb4..0cc1324f5 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -79,8 +79,8 @@ PioDevice::init() pioPort.sendRangeChange(); } -SlavePort & -PioDevice::getSlavePort(const std::string &if_name, int idx) +BaseSlavePort & +PioDevice::getSlavePort(const std::string &if_name, PortID idx) { if (if_name == "pio") { return pioPort; diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index 260053169..bd6a26d14 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -127,7 +127,8 @@ class PioDevice : public MemObject virtual unsigned int drain(Event *de); - virtual SlavePort &getSlavePort(const std::string &if_name, int idx = -1); + virtual BaseSlavePort &getSlavePort(const std::string &if_name, + PortID idx = InvalidPortID); friend class PioPort; diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh index 51d2cc93e..9994d2a2d 100644 --- a/src/dev/pcidev.hh +++ b/src/dev/pcidev.hh @@ -218,7 +218,8 @@ class PciDev : public DmaDevice virtual unsigned int drain(Event *de); - virtual SlavePort &getSlavePort(const std::string &if_name, int idx = -1) + virtual BaseSlavePort &getSlavePort(const std::string &if_name, + PortID idx = InvalidPortID) { if (if_name == "config") { return configPort; diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh index 76a8f9c00..f5e292baa 100644 --- a/src/dev/x86/i82094aa.hh +++ b/src/dev/x86/i82094aa.hh @@ -120,7 +120,8 @@ class I82094AA : public PioDevice, public IntDev void writeReg(uint8_t offset, uint32_t value); uint32_t readReg(uint8_t offset); - MasterPort &getMasterPort(const std::string &if_name, int idx = -1) + BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID) { if (if_name == "int_master") return intMasterPort; diff --git a/src/mem/addr_mapper.cc b/src/mem/addr_mapper.cc index 28fc85245..b754cb7e6 100644 --- a/src/mem/addr_mapper.cc +++ b/src/mem/addr_mapper.cc @@ -59,8 +59,8 @@ AddrMapper::init() slavePort.peerBlockSize(), masterPort.peerBlockSize()); } -MasterPort& -AddrMapper::getMasterPort(const std::string& if_name, int idx) +BaseMasterPort& +AddrMapper::getMasterPort(const std::string& if_name, PortID idx) { if (if_name == "master") { return masterPort; @@ -69,8 +69,8 @@ AddrMapper::getMasterPort(const std::string& if_name, int idx) } } -SlavePort& -AddrMapper::getSlavePort(const std::string& if_name, int idx) +BaseSlavePort& +AddrMapper::getSlavePort(const std::string& if_name, PortID idx) { if (if_name == "slave") { return slavePort; @@ -192,7 +192,7 @@ AddrMapper::recvTimingSnoopResp(PacketPtr pkt) bool AddrMapper::isSnooping() const { - if (slavePort.getMasterPort().isSnooping()) + if (slavePort.isSnooping()) fatal("AddrMapper doesn't support remapping of snooping requests\n"); return false; } @@ -266,7 +266,7 @@ AddrRangeList RangeAddrMapper::getAddrRanges() const { AddrRangeList ranges; - AddrRangeList actualRanges = masterPort.getSlavePort().getAddrRanges(); + AddrRangeList actualRanges = masterPort.getAddrRanges(); for (AddrRangeIter r = actualRanges.begin(); r != actualRanges.end(); ++r) { AddrRange range = *r; diff --git a/src/mem/addr_mapper.hh b/src/mem/addr_mapper.hh index f469b26ba..887635999 100644 --- a/src/mem/addr_mapper.hh +++ b/src/mem/addr_mapper.hh @@ -62,11 +62,11 @@ class AddrMapper : public MemObject virtual ~AddrMapper() { } - virtual MasterPort& getMasterPort(const std::string& if_name, - int idx = -1); + virtual BaseMasterPort& getMasterPort(const std::string& if_name, + PortID idx = InvalidPortID); - virtual SlavePort& getSlavePort(const std::string& if_name, - int idx = -1); + virtual BaseSlavePort& getSlavePort(const std::string& if_name, + PortID idx = InvalidPortID); virtual void init(); diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index 8bc34e12e..bece5e6a1 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -83,8 +83,8 @@ Bridge::Bridge(Params *p) { } -MasterPort& -Bridge::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort& +Bridge::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "master") return masterPort; @@ -93,8 +93,8 @@ Bridge::getMasterPort(const std::string &if_name, int idx) return MemObject::getMasterPort(if_name, idx); } -SlavePort& -Bridge::getSlavePort(const std::string &if_name, int idx) +BaseSlavePort& +Bridge::getSlavePort(const std::string &if_name, PortID idx) { if (if_name == "slave") return slavePort; diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index eb0b2434f..6855d2722 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -338,9 +338,10 @@ class Bridge : public MemObject public: - virtual MasterPort& getMasterPort(const std::string& if_name, - int idx = -1); - virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1); + virtual BaseMasterPort& getMasterPort(const std::string& if_name, + PortID idx = InvalidPortID); + virtual BaseSlavePort& getSlavePort(const std::string& if_name, + PortID idx = InvalidPortID); virtual void init(); diff --git a/src/mem/bus.cc b/src/mem/bus.cc index badf145ac..274b8c258 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -105,8 +105,8 @@ BaseBus::init() warn_once("Block size is neither 16, 32, 64 or 128 bytes.\n"); } -MasterPort & -BaseBus::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +BaseBus::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "master" && idx < masterPorts.size()) { // the master port index translates directly to the vector position @@ -118,8 +118,8 @@ BaseBus::getMasterPort(const std::string &if_name, int idx) } } -SlavePort & -BaseBus::getSlavePort(const std::string &if_name, int idx) +BaseSlavePort & +BaseBus::getSlavePort(const std::string &if_name, PortID idx) { if (if_name == "slave" && idx < slavePorts.size()) { // the slave port index translates directly to the vector position diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 26729f7cc..f3cbc9d24 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -361,8 +361,10 @@ class BaseBus : public MemObject virtual void init(); /** A function used to return the port associated with this bus object. */ - virtual MasterPort& getMasterPort(const std::string& if_name, int idx = -1); - virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1); + BaseMasterPort& getMasterPort(const std::string& if_name, + PortID idx = InvalidPortID); + BaseSlavePort& getSlavePort(const std::string& if_name, + PortID idx = InvalidPortID); virtual unsigned int drain(Event *de) = 0; diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index c95999f3e..a88749627 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -118,8 +118,8 @@ BaseCache::init() cpuSidePort->sendRangeChange(); } -MasterPort & -BaseCache::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +BaseCache::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "mem_side") { return *memSidePort; @@ -128,8 +128,8 @@ BaseCache::getMasterPort(const std::string &if_name, int idx) } } -SlavePort & -BaseCache::getSlavePort(const std::string &if_name, int idx) +BaseSlavePort & +BaseCache::getSlavePort(const std::string &if_name, PortID idx) { if (if_name == "cpu_side") { return *cpuSidePort; diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh index 2e31836c0..42ade9b0b 100644 --- a/src/mem/cache/base.hh +++ b/src/mem/cache/base.hh @@ -430,8 +430,10 @@ class BaseCache : public MemObject virtual void init(); - virtual MasterPort &getMasterPort(const std::string &if_name, int idx = -1); - virtual SlavePort &getSlavePort(const std::string &if_name, int idx = -1); + virtual BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); + virtual BaseSlavePort &getSlavePort(const std::string &if_name, + PortID idx = InvalidPortID); /** * Query block size of a cache. diff --git a/src/mem/comm_monitor.cc b/src/mem/comm_monitor.cc index 1b030de5e..aea028692 100644 --- a/src/mem/comm_monitor.cc +++ b/src/mem/comm_monitor.cc @@ -74,8 +74,8 @@ CommMonitor::init() fatal("Communication monitor is not connected on both sides.\n"); } -MasterPort& -CommMonitor::getMasterPort(const std::string& if_name, int idx) +BaseMasterPort& +CommMonitor::getMasterPort(const std::string& if_name, PortID idx) { if (if_name == "master") { return masterPort; @@ -84,8 +84,8 @@ CommMonitor::getMasterPort(const std::string& if_name, int idx) } } -SlavePort& -CommMonitor::getSlavePort(const std::string& if_name, int idx) +BaseSlavePort& +CommMonitor::getSlavePort(const std::string& if_name, PortID idx) { if (if_name == "slave") { return slavePort; diff --git a/src/mem/comm_monitor.hh b/src/mem/comm_monitor.hh index 4b90306e1..e59b8c467 100644 --- a/src/mem/comm_monitor.hh +++ b/src/mem/comm_monitor.hh @@ -77,11 +77,11 @@ class CommMonitor : public MemObject /** Destructor */ ~CommMonitor() { } - virtual MasterPort& getMasterPort(const std::string& if_name, - int idx = -1); + virtual BaseMasterPort& getMasterPort(const std::string& if_name, + PortID idx = InvalidPortID); - virtual SlavePort& getSlavePort(const std::string& if_name, - int idx = -1); + virtual BaseSlavePort& getSlavePort(const std::string& if_name, + PortID idx = InvalidPortID); virtual void init(); diff --git a/src/mem/mem_object.cc b/src/mem/mem_object.cc index cc05b7fc2..766eceeb7 100644 --- a/src/mem/mem_object.cc +++ b/src/mem/mem_object.cc @@ -48,14 +48,14 @@ MemObject::MemObject(const Params *params) { } -MasterPort& -MemObject::getMasterPort(const std::string& if_name, int idx) +BaseMasterPort& +MemObject::getMasterPort(const std::string& if_name, PortID idx) { fatal("%s does not have any master port named %s\n", name(), if_name); } -SlavePort& -MemObject::getSlavePort(const std::string& if_name, int idx) +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 6cc0c4fd3..e12b30661 100644 --- a/src/mem/mem_object.hh +++ b/src/mem/mem_object.hh @@ -67,26 +67,30 @@ class MemObject : public ClockedObject MemObject(const Params *params); /** - * Get a master port with a given name and index. + * 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 MasterPort& getMasterPort(const std::string& if_name, - int idx = -1); + virtual BaseMasterPort& getMasterPort(const std::string& if_name, + PortID idx = InvalidPortID); /** - * Get a slave port with a given name and index. + * 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 SlavePort& getSlavePort(const std::string& if_name, - int idx = -1); + virtual BaseSlavePort& getSlavePort(const std::string& if_name, + PortID idx = InvalidPortID); }; #endif //__MEM_MEM_OBJECT_HH__ diff --git a/src/mem/port.cc b/src/mem/port.cc index 9b65da756..45045f40e 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -59,56 +59,100 @@ Port::~Port() { } -/** - * Master port - */ -MasterPort::MasterPort(const std::string& name, MemObject* owner, PortID _id) - : Port(name, *owner, _id), _slavePort(NULL) +BaseMasterPort::BaseMasterPort(const std::string& name, MemObject* owner, + PortID _id) + : Port(name, *owner, _id), _baseSlavePort(NULL) { } -MasterPort::~MasterPort() +BaseMasterPort::~BaseMasterPort() { } -SlavePort& -MasterPort::getSlavePort() const +BaseSlavePort& +BaseMasterPort::getSlavePort() const { - if(_slavePort == NULL) + if(_baseSlavePort == NULL) panic("Cannot getSlavePort on master port %s that is not connected\n", name()); - return *_slavePort; + return *_baseSlavePort; } -void -MasterPort::unbind() +bool +BaseMasterPort::isConnected() const { - if (_slavePort == NULL) - panic("Attempting to unbind master port %s that is not connected\n", - name()); - _slavePort->unbind(); - _slavePort = NULL; + return _baseSlavePort != NULL; } -void -MasterPort::bind(SlavePort& slave_port) +BaseSlavePort::BaseSlavePort(const std::string& name, MemObject* owner, + PortID _id) + : Port(name, *owner, _id), _baseMasterPort(NULL) { - if (_slavePort != NULL) - panic("Attempting to bind master port %s that is already connected\n", - name()); +} + +BaseSlavePort::~BaseSlavePort() +{ +} - // master port keeps track of the slave port - _slavePort = &slave_port; +BaseMasterPort& +BaseSlavePort::getMasterPort() const +{ + if(_baseMasterPort == NULL) + panic("Cannot getMasterPort on slave port %s that is not connected\n", + name()); - // slave port also keeps track of master port - _slavePort->bind(*this); + return *_baseMasterPort; } bool -MasterPort::isConnected() const +BaseSlavePort::isConnected() const +{ + return _baseMasterPort != NULL; +} + +/** + * Master port + */ +MasterPort::MasterPort(const std::string& name, MemObject* owner, PortID _id) + : BaseMasterPort(name, owner, _id), _slavePort(NULL) { - return _slavePort != NULL; +} + +MasterPort::~MasterPort() +{ +} + +void +MasterPort::bind(BaseSlavePort& slave_port) +{ + // bind on the level of the base ports + _baseSlavePort = &slave_port; + + // also attempt to base the slave to the appropriate type + SlavePort* cast_slave_port = dynamic_cast(&slave_port); + + // if this port is compatible, then proceed with the binding + if (cast_slave_port != NULL) { + // master port keeps track of the slave port + _slavePort = cast_slave_port; + // slave port also keeps track of master port + _slavePort->bind(*this); + } else { + fatal("Master port %s cannot bind to %s\n", name(), + slave_port.name()); + } +} + +void +MasterPort::unbind() +{ + if (_slavePort == NULL) + panic("Attempting to unbind master port %s that is not connected\n", + name()); + _slavePort->unbind(); + _slavePort = NULL; + _baseSlavePort = NULL; } unsigned @@ -172,7 +216,7 @@ MasterPort::printAddr(Addr a) * Slave port */ SlavePort::SlavePort(const std::string& name, MemObject* owner, PortID id) - : Port(name, *owner, id), _masterPort(NULL) + : BaseSlavePort(name, owner, id), _masterPort(NULL) { } @@ -183,37 +227,23 @@ SlavePort::~SlavePort() void SlavePort::unbind() { + _baseMasterPort = NULL; _masterPort = NULL; } void SlavePort::bind(MasterPort& master_port) { + _baseMasterPort = &master_port; _masterPort = &master_port; } -MasterPort& -SlavePort::getMasterPort() const -{ - if (_masterPort == NULL) - panic("Cannot getMasterPort on slave port %s that is not connected\n", - name()); - - return *_masterPort; -} - unsigned SlavePort::peerBlockSize() const { return _masterPort->deviceBlockSize(); } -bool -SlavePort::isConnected() const -{ - return _masterPort != NULL; -} - Tick SlavePort::sendAtomicSnoop(PacketPtr pkt) { diff --git a/src/mem/port.hh b/src/mem/port.hh index eaad9668a..53b82f66d 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -116,16 +116,68 @@ class Port }; +/** Forward declaration */ +class BaseSlavePort; + +/** + * A BaseMasterPort is a protocol-agnostic master port, responsible + * only for the structural connection to a slave port. The final + * master port that inherits from the base class must override the + * bind member function for the specific slave port class. + */ +class BaseMasterPort : public Port +{ + + protected: + + BaseSlavePort* _baseSlavePort; + + BaseMasterPort(const std::string& name, MemObject* owner, + PortID id = InvalidPortID); + virtual ~BaseMasterPort(); + + public: + + virtual void bind(BaseSlavePort& slave_port) = 0; + virtual void unbind() = 0; + BaseSlavePort& getSlavePort() const; + bool isConnected() const; + +}; + +/** + * A BaseSlavePort is a protocol-agnostic slave port, responsible + * only for the structural connection to a master port. + */ +class BaseSlavePort : public Port +{ + + protected: + + BaseMasterPort* _baseMasterPort; + + BaseSlavePort(const std::string& name, MemObject* owner, + PortID id = InvalidPortID); + virtual ~BaseSlavePort(); + + public: + + BaseMasterPort& getMasterPort() const; + bool isConnected() const; + +}; + /** Forward declaration */ class SlavePort; /** - * A MasterPort is a specialisation of a port. In addition to the - * basic functionality of sending packets to its slave peer, it also - * has functions specific to a master, e.g. to receive range changes - * or determine if the port is snooping or not. + * A MasterPort is a specialisation of a BaseMasterPort, which + * implements the default protocol for the three different level of + * transport functions. In addition to the basic functionality of + * sending packets, it also has functions to receive range changes or + * determine if the port is snooping or not. */ -class MasterPort : public Port +class MasterPort : public BaseMasterPort { friend class SlavePort; @@ -144,16 +196,13 @@ class MasterPort : public Port * Bind this master port to a slave port. This also does the * mirror action and binds the slave port to the master port. */ - void bind(SlavePort& slave_port); + void bind(BaseSlavePort& slave_port); /** * Unbind this master port and the associated slave port. */ void unbind(); - SlavePort& getSlavePort() const; - bool isConnected() const; - /** * Send an atomic request packet, where the data is moved and the * state is updated in zero time, without interleaving with other @@ -292,7 +341,7 @@ class MasterPort : public Port * has functions specific to a slave, e.g. to send range changes * and get the address ranges that the port responds to. */ -class SlavePort : public Port +class SlavePort : public BaseSlavePort { friend class MasterPort; @@ -307,9 +356,6 @@ class SlavePort : public Port PortID id = InvalidPortID); virtual ~SlavePort(); - MasterPort& getMasterPort() const; - bool isConnected() const; - /** * Send an atomic snoop request packet, where the data is moved * and the state is updated in zero time, without interleaving diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index dcedc7841..1259f0f15 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -78,8 +78,8 @@ RubyPort::init() m_mandatory_q_ptr = m_controller->getMandatoryQueue(); } -MasterPort & -RubyPort::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort & +RubyPort::getMasterPort(const std::string &if_name, PortID idx) { if (if_name == "pio_port") { return pio_port; @@ -91,7 +91,7 @@ RubyPort::getMasterPort(const std::string &if_name, int idx) // pass it along to our super class return MemObject::getMasterPort(if_name, idx); } else { - if (idx >= static_cast(master_ports.size())) { + if (idx >= static_cast(master_ports.size())) { panic("RubyPort::getMasterPort: unknown index %d\n", idx); } @@ -99,8 +99,8 @@ RubyPort::getMasterPort(const std::string &if_name, int idx) } } -SlavePort & -RubyPort::getSlavePort(const std::string &if_name, int idx) +BaseSlavePort & +RubyPort::getSlavePort(const std::string &if_name, PortID idx) { // used by the CPUs to connect the caches to the interconnect, and // for the x86 case also the interrupt master @@ -108,7 +108,7 @@ RubyPort::getSlavePort(const std::string &if_name, int idx) // pass it along to our super class return MemObject::getSlavePort(if_name, idx); } else { - if (idx >= static_cast(slave_ports.size())) { + if (idx >= static_cast(slave_ports.size())) { panic("RubyPort::getSlavePort: unknown index %d\n", idx); } diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index 7cce6bac3..ab09bd90a 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -126,8 +126,10 @@ class RubyPort : public MemObject void init(); - MasterPort &getMasterPort(const std::string &if_name, int idx); - SlavePort &getSlavePort(const std::string &if_name, int idx); + BaseMasterPort &getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); + BaseSlavePort &getSlavePort(const std::string &if_name, + PortID idx = InvalidPortID); virtual RequestStatus makeRequest(PacketPtr pkt) = 0; virtual int outstandingCount() const = 0; diff --git a/src/mem/simple_dram.cc b/src/mem/simple_dram.cc index 5ee8643e1..0f6e9511c 100644 --- a/src/mem/simple_dram.cc +++ b/src/mem/simple_dram.cc @@ -1186,8 +1186,8 @@ SimpleDRAM::recvFunctional(PacketPtr pkt) functionalAccess(pkt); } -SlavePort& -SimpleDRAM::getSlavePort(const string &if_name, int idx) +BaseSlavePort& +SimpleDRAM::getSlavePort(const string &if_name, PortID idx) { if (if_name != "port") { return MemObject::getSlavePort(if_name, idx); diff --git a/src/mem/simple_dram.hh b/src/mem/simple_dram.hh index c8e37ee18..74058afaa 100644 --- a/src/mem/simple_dram.hh +++ b/src/mem/simple_dram.hh @@ -461,8 +461,8 @@ class SimpleDRAM : public AbstractMemory unsigned int drain(Event* de); - virtual SlavePort& getSlavePort(const std::string& if_name, - int idx = InvalidPortID); + virtual BaseSlavePort& getSlavePort(const std::string& if_name, + PortID idx = InvalidPortID); virtual void init(); virtual void startup(); diff --git a/src/mem/simple_mem.cc b/src/mem/simple_mem.cc index a67b4825f..c54e8e5ea 100644 --- a/src/mem/simple_mem.cc +++ b/src/mem/simple_mem.cc @@ -165,8 +165,8 @@ SimpleMemory::release() } } -SlavePort & -SimpleMemory::getSlavePort(const std::string &if_name, int idx) +BaseSlavePort & +SimpleMemory::getSlavePort(const std::string &if_name, PortID idx) { if (if_name != "port") { return MemObject::getSlavePort(if_name, idx); diff --git a/src/mem/simple_mem.hh b/src/mem/simple_mem.hh index f201709c2..7fd64db47 100644 --- a/src/mem/simple_mem.hh +++ b/src/mem/simple_mem.hh @@ -125,7 +125,8 @@ class SimpleMemory : public AbstractMemory unsigned int drain(Event* de); - virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1); + virtual BaseSlavePort& getSlavePort(const std::string& if_name, + PortID idx = InvalidPortID); virtual void init(); protected: diff --git a/src/python/swig/pyobject.cc b/src/python/swig/pyobject.cc index 05698e794..fc4435781 100644 --- a/src/python/swig/pyobject.cc +++ b/src/python/swig/pyobject.cc @@ -102,8 +102,8 @@ connectPorts(SimObject *o1, const std::string &name1, int i1, } // generic master/slave port connection - MasterPort& masterPort = mo1->getMasterPort(name1, i1); - SlavePort& slavePort = mo2->getSlavePort(name2, i2); + BaseMasterPort& masterPort = mo1->getMasterPort(name1, i1); + BaseSlavePort& slavePort = mo2->getSlavePort(name2, i2); masterPort.bind(slavePort); diff --git a/src/sim/system.cc b/src/sim/system.cc index dae09b85a..5ec7f4b30 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -171,8 +171,8 @@ System::init() panic("System port on %s is not connected.\n", name()); } -MasterPort& -System::getMasterPort(const std::string &if_name, int idx) +BaseMasterPort& +System::getMasterPort(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 2393c83f2..645ef8af2 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -117,7 +117,8 @@ class System : public MemObject /** * Additional function to return the Port of a memory object. */ - MasterPort& getMasterPort(const std::string &if_name, int idx = -1); + BaseMasterPort& getMasterPort(const std::string &if_name, + PortID idx = InvalidPortID); static const char *MemoryModeStrings[3]; diff --git a/src/sim/tlb.hh b/src/sim/tlb.hh index 0b89c9bd0..aadf047bf 100644 --- a/src/sim/tlb.hh +++ b/src/sim/tlb.hh @@ -49,7 +49,7 @@ #include "sim/sim_object.hh" class ThreadContext; -class MasterPort; +class BaseMasterPort; class BaseTLB : public SimObject { @@ -73,7 +73,7 @@ class BaseTLB : public SimObject * * @return A pointer to the walker master port or NULL if not present */ - virtual MasterPort* getMasterPort() { return NULL; } + virtual BaseMasterPort* getMasterPort() { return NULL; } class Translation {