mem: Split the various protocols out of the gem5 master/slave ports.

This makes the protocols easier to see in their entirity, and makes it
easier to add a new type of port which only supports the functional
protocol.

Change-Id: If5d639bef45062f0a23af2ac46f50933e6a8f144
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20228
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Gabe Black
2019-08-15 16:41:51 -07:00
parent 34b22c298c
commit d97e4e1dd0
9 changed files with 868 additions and 275 deletions

View File

@@ -60,12 +60,14 @@ SimObject('MemDelay.py')
Source('abstract_mem.cc')
Source('addr_mapper.cc')
Source('atomic_protocol.cc')
Source('bridge.cc')
Source('coherent_xbar.cc')
Source('drampower.cc')
Source('dram_ctrl.cc')
Source('external_master.cc')
Source('external_slave.cc')
Source('functional_protocol.cc')
Source('mem_object.cc')
Source('mport.cc')
Source('noncoherent_xbar.cc')
@@ -75,6 +77,7 @@ Source('packet_queue.cc')
Source('port_proxy.cc')
Source('physical.cc')
Source('secure_port_proxy.cc')
Source('timing_protocol.cc')
Source('simple_mem.cc')
Source('snoop_filter.cc')
Source('stack_dist_calc.cc')

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2012,2015,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) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Andreas Hansson
* William Wang
*/
#include "mem/atomic_protocol.hh"
#include "base/trace.hh"
/* The request protocol. */
Tick
AtomicRequestProtocol::send(AtomicResponseProtocol *peer, PacketPtr pkt)
{
assert(pkt->isRequest());
return peer->recvAtomic(pkt);
}
Tick
AtomicRequestProtocol::sendBackdoor(AtomicResponseProtocol *peer,
PacketPtr pkt, MemBackdoorPtr &backdoor)
{
assert(pkt->isRequest());
return peer->recvAtomicBackdoor(pkt, backdoor);
}
/* The response protocol. */
Tick
AtomicResponseProtocol::sendSnoop(AtomicRequestProtocol *peer, PacketPtr pkt)
{
assert(pkt->isRequest());
return peer->recvAtomicSnoop(pkt);
}

120
src/mem/atomic_protocol.hh Normal file
View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2011-2012,2015,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) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ron Dreslinski
* Andreas Hansson
* William Wang
*/
#ifndef __MEM_ATOMIC_PROTOCOL_HH__
#define __MEM_ATOMIC_PROTOCOL_HH__
#include "mem/backdoor.hh"
#include "mem/packet.hh"
class AtomicResponseProtocol;
class AtomicRequestProtocol
{
friend class AtomicResponseProtocol;
protected:
/**
* Send an atomic request packet, where the data is moved and the
* state is updated in zero time, without interleaving with other
* memory accesses.
*
* @param peer Peer to send packet to.
* @param pkt Packet to send.
*
* @return Estimated latency of access.
*/
Tick send(AtomicResponseProtocol *peer, PacketPtr pkt);
/**
* Send an atomic request packet like above, but also request a backdoor
* to the data being accessed.
*
* @param peer Peer to send packet to.
* @param pkt Packet to send.
* @param backdoor Can be set to a back door pointer by the target to let
* caller have direct access to the requested data.
*
* @return Estimated latency of access.
*/
Tick sendBackdoor(AtomicResponseProtocol *peer, PacketPtr pkt,
MemBackdoorPtr &backdoor);
/**
* Receive an atomic snoop request packet from our peer.
*/
virtual Tick recvAtomicSnoop(PacketPtr pkt) = 0;
};
class AtomicResponseProtocol
{
friend class AtomicRequestProtocol;
protected:
/**
* Send an atomic snoop request packet, where the data is moved
* and the state is updated in zero time, without interleaving
* with other memory accesses.
*
* @param peer Peer to send packet to.
* @param pkt Snoop packet to send.
*
* @return Estimated latency of access.
*/
Tick sendSnoop(AtomicRequestProtocol *peer, PacketPtr pkt);
/**
* Receive an atomic request packet from the peer.
*/
virtual Tick recvAtomic(PacketPtr pkt) = 0;
/**
* Receive an atomic request packet from the peer, and optionally
* provide a backdoor to the data being accessed.
*/
virtual Tick recvAtomicBackdoor(
PacketPtr pkt, MemBackdoorPtr &backdoor) = 0;
};
#endif //__MEM_ATOMIC_PROTOCOL_HH__

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2012,2015,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) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Andreas Hansson
* William Wang
*/
#include "mem/functional_protocol.hh"
/* The request protocol. */
void
FunctionalRequestProtocol::send(
FunctionalResponseProtocol *peer, PacketPtr pkt) const
{
assert(pkt->isRequest());
return peer->recvFunctional(pkt);
}
/* The response protocol. */
void
FunctionalResponseProtocol::sendSnoop(
FunctionalRequestProtocol *peer, PacketPtr pkt) const
{
assert(pkt->isRequest());
return peer->recvFunctionalSnoop(pkt);
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2011-2012,2015,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) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ron Dreslinski
* Andreas Hansson
* William Wang
*/
#ifndef __MEM_FUNCTIONAL_PROTOCOL_HH__
#define __MEM_FUNCTIONAL_PROTOCOL_HH__
#include "mem/packet.hh"
class FunctionalResponseProtocol;
class FunctionalRequestProtocol
{
friend class FunctionalResponseProtocol;
protected:
/**
* Send a functional request packet, where the data is instantly
* updated everywhere in the memory system, without affecting the
* current state of any block or moving the block.
*
* @param pkt Packet to send.
*/
void send(FunctionalResponseProtocol *peer, PacketPtr pkt) const;
/**
* Receive a functional snoop request packet from the peer.
*/
virtual void recvFunctionalSnoop(PacketPtr pkt) = 0;
};
class FunctionalResponseProtocol
{
friend class FunctionalRequestProtocol;
protected:
/**
* Send a functional snoop request packet, where the data is
* instantly updated everywhere in the memory system, without
* affecting the current state of any block or moving the block.
*
* @param pkt Snoop packet to send.
*/
void sendSnoop(FunctionalRequestProtocol *peer, PacketPtr pkt) const;
/**
* Receive a functional request packet from the peer.
*/
virtual void recvFunctional(PacketPtr pkt) = 0;
};
#endif //__MEM_FUNCTIONAL_PROTOCOL_HH__

View File

@@ -137,54 +137,6 @@ MasterPort::getAddrRanges() const
return _slavePort->getAddrRanges();
}
Tick
MasterPort::sendAtomic(PacketPtr pkt)
{
assert(pkt->isRequest());
return _slavePort->recvAtomic(pkt);
}
Tick
MasterPort::sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor)
{
assert(pkt->isRequest());
return _slavePort->recvAtomicBackdoor(pkt, backdoor);
}
void
MasterPort::sendFunctional(PacketPtr pkt)
{
assert(pkt->isRequest());
return _slavePort->recvFunctional(pkt);
}
bool
MasterPort::sendTimingReq(PacketPtr pkt)
{
assert(pkt->isRequest());
return _slavePort->recvTimingReq(pkt);
}
bool
MasterPort::tryTiming(PacketPtr pkt) const
{
assert(pkt->isRequest());
return _slavePort->tryTiming(pkt);
}
bool
MasterPort::sendTimingSnoopResp(PacketPtr pkt)
{
assert(pkt->isResponse());
return _slavePort->recvTimingSnoopResp(pkt);
}
void
MasterPort::sendRetryResp()
{
_slavePort->recvRespRetry();
}
void
MasterPort::printAddr(Addr a)
{
@@ -236,43 +188,3 @@ SlavePort::recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor)
}
return recvAtomic(pkt);
}
Tick
SlavePort::sendAtomicSnoop(PacketPtr pkt)
{
assert(pkt->isRequest());
return _masterPort->recvAtomicSnoop(pkt);
}
void
SlavePort::sendFunctionalSnoop(PacketPtr pkt)
{
assert(pkt->isRequest());
return _masterPort->recvFunctionalSnoop(pkt);
}
bool
SlavePort::sendTimingResp(PacketPtr pkt)
{
assert(pkt->isResponse());
return _masterPort->recvTimingResp(pkt);
}
void
SlavePort::sendTimingSnoopReq(PacketPtr pkt)
{
assert(pkt->isRequest());
_masterPort->recvTimingSnoopReq(pkt);
}
void
SlavePort::sendRetryReq()
{
_masterPort->recvReqRetry();
}
void
SlavePort::sendRetrySnoopResp()
{
_masterPort->recvRetrySnoopResp();
}

View File

@@ -51,8 +51,10 @@
#define __MEM_PORT_HH__
#include "base/addr_range.hh"
#include "mem/backdoor.hh"
#include "mem/atomic_protocol.hh"
#include "mem/functional_protocol.hh"
#include "mem/packet.hh"
#include "mem/timing_protocol.hh"
#include "sim/port.hh"
class SimObject;
@@ -68,18 +70,14 @@ class BaseSlavePort;
*/
class BaseMasterPort : public Port
{
protected:
BaseSlavePort *_baseSlavePort;
BaseSlavePort* _baseSlavePort;
BaseMasterPort(const std::string& name, PortID id=InvalidPortID);
BaseMasterPort(const std::string &name, PortID id=InvalidPortID);
virtual ~BaseMasterPort();
public:
BaseSlavePort& getSlavePort() const;
};
/**
@@ -88,18 +86,14 @@ class BaseMasterPort : public Port
*/
class BaseSlavePort : public Port
{
protected:
BaseMasterPort *_baseMasterPort;
BaseMasterPort* _baseMasterPort;
BaseSlavePort(const std::string& name, PortID id=InvalidPortID);
BaseSlavePort(const std::string &name, PortID id=InvalidPortID);
virtual ~BaseSlavePort();
public:
BaseMasterPort& getMasterPort() const;
};
/** Forward declaration */
@@ -111,22 +105,22 @@ class SlavePort;
* 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.
*
* The three protocols are atomic, timing, and functional, each with its own
* header file.
*/
class MasterPort : public BaseMasterPort
class MasterPort : public BaseMasterPort, public AtomicRequestProtocol,
public TimingRequestProtocol, public FunctionalRequestProtocol
{
friend class SlavePort;
private:
SlavePort* _slavePort;
SlavePort *_slavePort;
protected:
SimObject& owner;
SimObject &owner;
public:
MasterPort(const std::string& name, SimObject* _owner,
PortID id=InvalidPortID);
virtual ~MasterPort();
@@ -142,6 +136,31 @@ class MasterPort : public BaseMasterPort
*/
void unbind() override;
/**
* Determine if this master port is snooping or not. The default
* implementation returns false and thus tells the neighbour we
* are not snooping. Any master port that wants to receive snoop
* requests (e.g. a cache connected to a bus) has to override this
* function.
*
* @return true if the port should be considered a snooper
*/
virtual bool isSnooping() const { return false; }
/**
* Get the address ranges of the connected slave port.
*/
AddrRangeList getAddrRanges() const;
/**
* Inject a PrintReq for the given address to print the state of
* that address throughout the memory system. For debugging.
*/
void printAddr(Addr a);
public:
/* The atomic protocol. */
/**
* Send an atomic request packet, where the data is moved and the
* state is updated in zero time, without interleaving with other
@@ -165,6 +184,9 @@ class MasterPort : public BaseMasterPort
*/
Tick sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor);
public:
/* The functional protocol. */
/**
* Send a functional request packet, where the data is instantly
* updated everywhere in the memory system, without affecting the
@@ -172,7 +194,10 @@ class MasterPort : public BaseMasterPort
*
* @param pkt Packet to send.
*/
void sendFunctional(PacketPtr pkt);
void sendFunctional(PacketPtr pkt) const;
public:
/* The timing protocol. */
/**
* Attempt to send a timing request to the slave port by calling
@@ -219,76 +244,7 @@ class MasterPort : public BaseMasterPort
*/
virtual void sendRetryResp();
/**
* Determine if this master port is snooping or not. The default
* implementation returns false and thus tells the neighbour we
* are not snooping. Any master port that wants to receive snoop
* requests (e.g. a cache connected to a bus) has to override this
* function.
*
* @return true if the port should be considered a snooper
*/
virtual bool isSnooping() const { return false; }
/**
* Get the address ranges of the connected slave port.
*/
AddrRangeList getAddrRanges() const;
/** Inject a PrintReq for the given address to print the state of
* that address throughout the memory system. For debugging.
*/
void printAddr(Addr a);
protected:
/**
* Receive an atomic snoop request packet from the slave port.
*/
virtual Tick recvAtomicSnoop(PacketPtr pkt)
{
panic("%s was not expecting an atomic snoop request\n", name());
return 0;
}
/**
* Receive a functional snoop request packet from the slave port.
*/
virtual void recvFunctionalSnoop(PacketPtr pkt)
{
panic("%s was not expecting a functional snoop request\n", name());
}
/**
* Receive a timing response from the slave port.
*/
virtual bool recvTimingResp(PacketPtr pkt) = 0;
/**
* Receive a timing snoop request from the slave port.
*/
virtual void recvTimingSnoopReq(PacketPtr pkt)
{
panic("%s was not expecting a timing snoop request\n", name());
}
/**
* Called by the slave port if sendTimingReq was called on this
* master port (causing recvTimingReq to be called on the slave
* port) and was unsuccesful.
*/
virtual void recvReqRetry() = 0;
/**
* Called by the slave port if sendTimingSnoopResp was called on this
* master port (causing recvTimingSnoopResp to be called on the slave
* port) and was unsuccesful.
*/
virtual void recvRetrySnoopResp()
{
panic("%s was not expecting a snoop retry\n", name());
}
/**
* Called to receive an address range change from the peer slave
* port. The default implementation ignores the change and does
@@ -297,6 +253,34 @@ class MasterPort : public BaseMasterPort
* interconnect component like a bus.
*/
virtual void recvRangeChange() { }
/**
* Default implementations.
*/
Tick
recvAtomicSnoop(PacketPtr pkt) override
{
panic("%s was not expecting an atomic snoop request\n", name());
return 0;
}
void
recvFunctionalSnoop(PacketPtr pkt) override
{
panic("%s was not expecting a functional snoop request\n", name());
}
void
recvTimingSnoopReq(PacketPtr pkt) override
{
panic("%s was not expecting a timing snoop request.\n", name());
}
void
recvRetrySnoopResp() override
{
panic("%s was not expecting a snoop retry.\n", name());
}
};
/**
@@ -304,81 +288,27 @@ class MasterPort : public BaseMasterPort
* basic functionality of sending packets to its master peer, it also
* has functions specific to a slave, e.g. to send range changes
* and get the address ranges that the port responds to.
*
* The three protocols are atomic, timing, and functional, each with its own
* header file.
*/
class SlavePort : public BaseSlavePort
class SlavePort : public BaseSlavePort, public AtomicResponseProtocol,
public TimingResponseProtocol, public FunctionalResponseProtocol
{
friend class MasterPort;
private:
MasterPort* _masterPort;
bool defaultBackdoorWarned;
protected:
SimObject& owner;
public:
SlavePort(const std::string& name, SimObject* _owner,
PortID id=InvalidPortID);
virtual ~SlavePort();
/**
* Send an atomic snoop request packet, where the data is moved
* and the state is updated in zero time, without interleaving
* with other memory accesses.
*
* @param pkt Snoop packet to send.
*
* @return Estimated latency of access.
*/
Tick sendAtomicSnoop(PacketPtr pkt);
/**
* Send a functional snoop request packet, where the data is
* instantly updated everywhere in the memory system, without
* affecting the current state of any block or moving the block.
*
* @param pkt Snoop packet to send.
*/
void sendFunctionalSnoop(PacketPtr pkt);
/**
* Attempt to send a timing response to the master port by calling
* its corresponding receive function. If the send does not
* succeed, as indicated by the return value, then the sender must
* wait for a recvRespRetry at which point it can re-issue a
* sendTimingResp.
*
* @param pkt Packet to send.
*
* @return If the send was succesful or not.
*/
bool sendTimingResp(PacketPtr pkt);
/**
* Attempt to send a timing snoop request packet to the master port
* by calling its corresponding receive function. Snoop requests
* always succeed and hence no return value is needed.
*
* @param pkt Packet to send.
*/
void sendTimingSnoopReq(PacketPtr pkt);
/**
* Send a retry to the master port that previously attempted a
* sendTimingReq to this slave port and failed.
*/
void sendRetryReq();
/**
* Send a retry to the master port that previously attempted a
* sendTimingSnoopResp to this slave port and failed.
*/
void sendRetrySnoopResp();
/**
* Find out if the peer master port is snooping or not.
*
@@ -389,9 +319,11 @@ class SlavePort : public BaseSlavePort
/**
* Called by the owner to send a range change
*/
void sendRangeChange() const {
if (!_masterPort)
fatal("%s cannot sendRangeChange() without master port", name());
void
sendRangeChange() const
{
fatal_if(!_masterPort,
"%s cannot sendRangeChange() without master port.", name());
_masterPort->recvRangeChange();
}
@@ -410,8 +342,94 @@ class SlavePort : public BaseSlavePort
void unbind() override {}
void bind(Port &peer) override {}
protected:
public:
/* The atomic protocol. */
/**
* Send an atomic snoop request packet, where the data is moved
* and the state is updated in zero time, without interleaving
* with other memory accesses.
*
* @param pkt Snoop packet to send.
*
* @return Estimated latency of access.
*/
Tick
sendAtomicSnoop(PacketPtr pkt)
{
return AtomicResponseProtocol::sendSnoop(_masterPort, pkt);
}
public:
/* The functional protocol. */
/**
* Send a functional snoop request packet, where the data is
* instantly updated everywhere in the memory system, without
* affecting the current state of any block or moving the block.
*
* @param pkt Snoop packet to send.
*/
void
sendFunctionalSnoop(PacketPtr pkt) const
{
FunctionalResponseProtocol::sendSnoop(_masterPort, pkt);
}
public:
/* The timing protocol. */
/**
* Attempt to send a timing response to the master port by calling
* its corresponding receive function. If the send does not
* succeed, as indicated by the return value, then the sender must
* wait for a recvRespRetry at which point it can re-issue a
* sendTimingResp.
*
* @param pkt Packet to send.
*
* @return If the send was succesful or not.
*/
bool
sendTimingResp(PacketPtr pkt)
{
return TimingResponseProtocol::sendResp(_masterPort, pkt);
}
/**
* Attempt to send a timing snoop request packet to the master port
* by calling its corresponding receive function. Snoop requests
* always succeed and hence no return value is needed.
*
* @param pkt Packet to send.
*/
void
sendTimingSnoopReq(PacketPtr pkt)
{
TimingResponseProtocol::sendSnoopReq(_masterPort, pkt);
}
/**
* Send a retry to the master port that previously attempted a
* sendTimingReq to this slave port and failed.
*/
void
sendRetryReq()
{
TimingResponseProtocol::sendRetryReq(_masterPort);
}
/**
* Send a retry to the master port that previously attempted a
* sendTimingSnoopResp to this slave port and failed.
*/
void
sendRetrySnoopResp()
{
TimingResponseProtocol::sendRetrySnoopResp(_masterPort);
}
protected:
/**
* Called by the master port to unbind. Should never be called
* directly.
@@ -425,48 +443,63 @@ class SlavePort : public BaseSlavePort
void slaveBind(MasterPort& master_port);
/**
* Receive an atomic request packet from the master port.
* Default implementations.
*/
virtual Tick recvAtomic(PacketPtr pkt) = 0;
Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override;
/**
* Receive an atomic request packet from the master port, and optionally
* provide a backdoor to the data being accessed.
*/
virtual Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor);
/**
* Receive a functional request packet from the master port.
*/
virtual void recvFunctional(PacketPtr pkt) = 0;
/**
* Receive a timing request from the master port.
*/
virtual bool recvTimingReq(PacketPtr pkt) = 0;
/**
* Availability request from the master port.
*/
virtual bool tryTiming(PacketPtr pkt) {
bool
tryTiming(PacketPtr pkt) override
{
panic("%s was not expecting a %s\n", name(), __func__);
}
/**
* Receive a timing snoop response from the master port.
*/
virtual bool recvTimingSnoopResp(PacketPtr pkt)
bool
recvTimingSnoopResp(PacketPtr pkt) override
{
panic("%s was not expecting a timing snoop response\n", name());
}
/**
* Called by the master port if sendTimingResp was called on this
* slave port (causing recvTimingResp to be called on the master
* port) and was unsuccesful.
*/
virtual void recvRespRetry() = 0;
};
inline Tick
MasterPort::sendAtomic(PacketPtr pkt)
{
return AtomicRequestProtocol::send(_slavePort, pkt);
}
inline Tick
MasterPort::sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor)
{
return AtomicRequestProtocol::sendBackdoor(_slavePort, pkt, backdoor);
}
inline void
MasterPort::sendFunctional(PacketPtr pkt) const
{
return FunctionalRequestProtocol::send(_slavePort, pkt);
}
inline bool
MasterPort::sendTimingReq(PacketPtr pkt)
{
return TimingRequestProtocol::sendReq(_slavePort, pkt);
}
inline bool
MasterPort::tryTiming(PacketPtr pkt) const
{
return TimingRequestProtocol::trySend(_slavePort, pkt);
}
inline bool
MasterPort::sendTimingSnoopResp(PacketPtr pkt)
{
return TimingRequestProtocol::sendSnoopResp(_slavePort, pkt);
}
inline void
MasterPort::sendRetryResp()
{
TimingRequestProtocol::sendRetryResp(_slavePort);
}
#endif //__MEM_PORT_HH__

105
src/mem/timing_protocol.cc Normal file
View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2012,2015,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) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Andreas Hansson
* William Wang
*/
#include "mem/timing_protocol.hh"
/* The request protocol. */
bool
TimingRequestProtocol::sendReq(TimingResponseProtocol *peer, PacketPtr pkt)
{
assert(pkt->isRequest());
return peer->recvTimingReq(pkt);
}
bool
TimingRequestProtocol::trySend(
TimingResponseProtocol *peer, PacketPtr pkt) const
{
assert(pkt->isRequest());
return peer->tryTiming(pkt);
}
bool
TimingRequestProtocol::sendSnoopResp(
TimingResponseProtocol *peer, PacketPtr pkt)
{
assert(pkt->isResponse());
return peer->recvTimingSnoopResp(pkt);
}
void
TimingRequestProtocol::sendRetryResp(TimingResponseProtocol *peer)
{
peer->recvRespRetry();
}
/* The response protocol. */
bool
TimingResponseProtocol::sendResp(TimingRequestProtocol *peer, PacketPtr pkt)
{
assert(pkt->isResponse());
return peer->recvTimingResp(pkt);
}
void
TimingResponseProtocol::sendSnoopReq(
TimingRequestProtocol *peer, PacketPtr pkt)
{
assert(pkt->isRequest());
peer->recvTimingSnoopReq(pkt);
}
void
TimingResponseProtocol::sendRetryReq(TimingRequestProtocol *peer)
{
peer->recvReqRetry();
}
void
TimingResponseProtocol::sendRetrySnoopResp(TimingRequestProtocol *peer)
{
peer->recvRetrySnoopResp();
}

190
src/mem/timing_protocol.hh Normal file
View File

@@ -0,0 +1,190 @@
/*
* Copyright (c) 2011-2012,2015,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) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ron Dreslinski
* Andreas Hansson
* William Wang
*/
#ifndef __MEM_TIMING_PROTOCOL_HH__
#define __MEM_TIMING_PROTOCOL_HH__
#include "mem/packet.hh"
class TimingResponseProtocol;
class TimingRequestProtocol
{
friend class TimingResponseProtocol;
protected:
/**
* Attempt to send a timing request to the peer by calling
* its corresponding receive function. If the send does not
* succeed, as indicated by the return value, then the sender must
* wait for a recvReqRetry at which point it can re-issue a
* sendTimingReq.
*
* @param peer Peer to send packet to.
* @param pkt Packet to send.
*
* @return If the send was succesful or not.
*/
bool sendReq(TimingResponseProtocol *peer, PacketPtr pkt);
/**
* Check if the peer can handle a timing request.
*
* If the send cannot be handled at the moment, as indicated by
* the return value, then the sender will receive a recvReqRetry
* at which point it can re-issue a sendTimingReq.
*
* @param peer Peer to send packet to.
* @param pkt Packet to send.
*
* @return If the send was succesful or not.
*/
bool trySend(TimingResponseProtocol *peer, PacketPtr pkt) const;
/**
* Attempt to send a timing snoop response packet to it's peer
* by calling its corresponding receive function. If the send
* does not succeed, as indicated by the return value, then the
* sender must wait for a recvRetrySnoop at which point it can
* re-issue a sendTimingSnoopResp.
*
* @param pkt Packet to send.
*/
bool sendSnoopResp(TimingResponseProtocol *peer, PacketPtr pkt);
/**
* Send a retry to the peer that previously attempted a
* sendTimingResp to this protocol and failed.
*/
void sendRetryResp(TimingResponseProtocol *peer);
/**
* Receive a timing response from the peer.
*/
virtual bool recvTimingResp(PacketPtr pkt) = 0;
/**
* Receive a timing snoop request from the peer.
*/
virtual void recvTimingSnoopReq(PacketPtr pkt) = 0;
/**
* Called by the peer if sendTimingReq was called on this peer (causing
* recvTimingReq to be called on the peer) and was unsuccessful.
*/
virtual void recvReqRetry() = 0;
/**
* Called by the peer if sendTimingSnoopResp was called on this
* protocol (causing recvTimingSnoopResp to be called on the peer)
* and was unsuccessful.
*/
virtual void recvRetrySnoopResp() = 0;
};
class TimingResponseProtocol
{
friend class TimingRequestProtocol;
protected:
/**
* Attempt to send a timing response to the peer by calling
* its corresponding receive function. If the send does not
* succeed, as indicated by the return value, then the sender must
* wait for a recvRespRetry at which point it can re-issue a
* sendTimingResp.
*
* @param peer Peer to send the packet to.
* @param pkt Packet to send.
*
* @return If the send was succesful or not.
*/
bool sendResp(TimingRequestProtocol *peer, PacketPtr pkt);
/**
* Attempt to send a timing snoop request packet to the peer
* by calling its corresponding receive function. Snoop requests
* always succeed and hence no return value is needed.
*
* @param peer Peer to send the packet to.
* @param pkt Packet to send.
*/
void sendSnoopReq(TimingRequestProtocol *peer, PacketPtr pkt);
/**
* Send a retry to the peer that previously attempted a
* sendTimingReq to this protocol and failed.
*/
void sendRetryReq(TimingRequestProtocol *peer);
/**
* Send a retry to the peer that previously attempted a
* sendTimingSnoopResp to this peer and failed.
*/
void sendRetrySnoopResp(TimingRequestProtocol *peer);
/**
* Receive a timing request from the peer.
*/
virtual bool recvTimingReq(PacketPtr pkt) = 0;
/**
* Availability request from the peer.
*/
virtual bool tryTiming(PacketPtr pkt) = 0;
/**
* Receive a timing snoop response from the peer.
*/
virtual bool recvTimingSnoopResp(PacketPtr pkt) = 0;
/**
* Called by the peer if sendTimingResp was called on this
* protocol (causing recvTimingResp to be called on the peer)
* and was unsuccessful.
*/
virtual void recvRespRetry() = 0;
};
#endif //__MEM_TIMING_PROTOCOL_HH__