/*
- * Copyright (c) 2012-2018 ARM Limited
+ * Copyright (c) 2012-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#include <cassert>
#include <list>
+#include "base/addr_range.hh"
#include "base/cast.hh"
#include "base/compiler.hh"
#include "base/flags.hh"
#include "base/logging.hh"
#include "base/printable.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
#include "mem/request.hh"
#include "sim/core.hh"
WriteClean, // writes dirty data below without evicting
CleanEvict,
SoftPFReq,
+ SoftPFExReq,
HardPFReq,
SoftPFResp,
HardPFResp,
// Flags to transfer across when copying a packet
COPY_FLAGS = 0x0000003F,
+ // Flags that are used to create reponse packets
+ RESPONDER_FLAGS = 0x00000009,
+
// Does this packet have sharers (which means it should not be
// considered writable) or not. See setHasSharers below.
HAS_SHARERS = 0x00000001,
const PacketId id;
/// A pointer to the original request.
- const RequestPtr req;
+ RequestPtr req;
private:
/**
*/
std::vector<bool> bytesValid;
+ // Quality of Service priority value
+ uint8_t _qosValue;
+
public:
/**
bool isPrint() const { return cmd.isPrint(); }
bool isFlush() const { return cmd.isFlush(); }
+ bool isWholeLineWrite(unsigned blk_size)
+ {
+ return (cmd == MemCmd::WriteReq || cmd == MemCmd::WriteLineReq) &&
+ getOffset(blk_size) == 0 && getSize() == blk_size;
+ }
+
//@{
/// Snoop flags
/**
bool responderHadWritable() const
{ return flags.isSet(RESPONDER_HAD_WRITABLE); }
+ /**
+ * Copy the reponse flags from an input packet to this packet. The
+ * reponse flags determine whether a responder has been found and
+ * the state at which the block will be at the destination.
+ *
+ * @pkt The packet that we will copy flags from
+ */
+ void copyResponderFlags(const PacketPtr pkt);
+
/**
* A writeback/writeclean cmd gets propagated further downstream
* by the receiver when the flag is set.
bool isBlockCached() const { return flags.isSet(BLOCK_CACHED); }
void clearBlockCached() { flags.clear(BLOCK_CACHED); }
+ /**
+ * QoS Value getter
+ * Returns 0 if QoS value was never set (constructor default).
+ *
+ * @return QoS priority value of the packet
+ */
+ inline uint8_t qosValue() const { return _qosValue; }
+
+ /**
+ * QoS Value setter
+ * Interface for setting QoS priority value of the packet.
+ *
+ * @param qos_value QoS priority value
+ */
+ inline void qosValue(const uint8_t qos_value)
+ { _qosValue = qos_value; }
+
+ inline MasterID masterId() const { return req->masterId(); }
+
// Network error conditions... encapsulate them as methods since
// their encoding keeps changing (from result field to command
// field, etc.)
unsigned getSize() const { assert(flags.isSet(VALID_SIZE)); return size; }
+ /**
+ * Get address range to which this packet belongs.
+ *
+ * @return Address range of this packet.
+ */
+ AddrRange getAddrRange() const;
+
Addr getOffset(unsigned int blk_size) const
{
return getAddr() & Addr(blk_size - 1);
* first, but the Requests's physical address and size fields need
* not be valid. The command must be supplied.
*/
- Packet(const RequestPtr _req, MemCmd _cmd)
- : cmd(_cmd), id((PacketId)_req), req(_req), data(nullptr), addr(0),
- _isSecure(false), size(0), headerDelay(0), snoopDelay(0),
+ Packet(const RequestPtr &_req, MemCmd _cmd)
+ : cmd(_cmd), id((PacketId)_req.get()), req(_req),
+ data(nullptr), addr(0), _isSecure(false), size(0),
+ _qosValue(0), headerDelay(0), snoopDelay(0),
payloadDelay(0), senderState(NULL)
{
if (req->hasPaddr()) {
* a request that is for a whole block, not the address from the
* req. this allows for overriding the size/addr of the req.
*/
- Packet(const RequestPtr _req, MemCmd _cmd, int _blkSize, PacketId _id = 0)
- : cmd(_cmd), id(_id ? _id : (PacketId)_req), req(_req), data(nullptr),
- addr(0), _isSecure(false), headerDelay(0), snoopDelay(0),
- payloadDelay(0), senderState(NULL)
+ Packet(const RequestPtr &_req, MemCmd _cmd, int _blkSize, PacketId _id = 0)
+ : cmd(_cmd), id(_id ? _id : (PacketId)_req.get()), req(_req),
+ data(nullptr), addr(0), _isSecure(false),
+ _qosValue(0), headerDelay(0),
+ snoopDelay(0), payloadDelay(0), senderState(NULL)
{
if (req->hasPaddr()) {
addr = req->getPaddr() & ~(_blkSize - 1);
data(nullptr),
addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
bytesValid(pkt->bytesValid),
+ _qosValue(pkt->qosValue()),
headerDelay(pkt->headerDelay),
snoopDelay(0),
payloadDelay(pkt->payloadDelay),
* Generate the appropriate read MemCmd based on the Request flags.
*/
static MemCmd
- makeReadCmd(const RequestPtr req)
+ makeReadCmd(const RequestPtr &req)
{
if (req->isLLSC())
return MemCmd::LoadLockedReq;
+ else if (req->isPrefetchEx())
+ return MemCmd::SoftPFExReq;
else if (req->isPrefetch())
return MemCmd::SoftPFReq;
else
* Generate the appropriate write MemCmd based on the Request flags.
*/
static MemCmd
- makeWriteCmd(const RequestPtr req)
+ makeWriteCmd(const RequestPtr &req)
{
if (req->isLLSC())
return MemCmd::StoreCondReq;
- else if (req->isSwap())
+ else if (req->isSwap() || req->isAtomic())
return MemCmd::SwapReq;
else if (req->isCacheInvalidate()) {
return req->isCacheClean() ? MemCmd::CleanInvalidReq :
* Fine-tune the MemCmd type if it's not a vanilla read or write.
*/
static PacketPtr
- createRead(const RequestPtr req)
+ createRead(const RequestPtr &req)
{
return new Packet(req, makeReadCmd(req));
}
static PacketPtr
- createWrite(const RequestPtr req)
+ createWrite(const RequestPtr &req)
{
return new Packet(req, makeWriteCmd(req));
}
*/
~Packet()
{
- // Delete the request object if this is a request packet which
- // does not need a response, because the requester will not get
- // a chance. If the request packet needs a response then the
- // request will be deleted on receipt of the response
- // packet. We also make sure to never delete the request for
- // express snoops, even for cases when responses are not
- // needed (CleanEvict and Writeback), since the snoop packet
- // re-uses the same request.
- if (req && isRequest() && !needsResponse() &&
- !isExpressSnoop()) {
- delete req;
- }
deleteData();
}
flags.set(VALID_SIZE);
}
+ /**
+ * Check if packet corresponds to a given block-aligned address and
+ * address space.
+ *
+ * @param addr The address to compare against.
+ * @param is_secure Whether addr belongs to the secure address space.
+ * @param blk_size Block size in bytes.
+ * @return Whether packet matches description.
+ */
+ bool matchBlockAddr(const Addr addr, const bool is_secure,
+ const int blk_size) const;
+
+ /**
+ * Check if this packet refers to the same block-aligned address and
+ * address space as another packet.
+ *
+ * @param pkt The packet to compare against.
+ * @param blk_size Block size in bytes.
+ * @return Whether packet matches description.
+ */
+ bool matchBlockAddr(const PacketPtr pkt, const int blk_size) const;
+
+ /**
+ * Check if packet corresponds to a given address and address space.
+ *
+ * @param addr The address to compare against.
+ * @param is_secure Whether addr belongs to the secure address space.
+ * @return Whether packet matches description.
+ */
+ bool matchAddr(const Addr addr, const bool is_secure) const;
+
+ /**
+ * Check if this packet refers to the same address and address space as
+ * another packet.
+ *
+ * @param pkt The packet to compare against.
+ * @return Whether packet matches description.
+ */
+ bool matchAddr(const PacketPtr pkt) const;
public:
/**
template <typename T>
T get(ByteOrder endian) const;
+#if THE_ISA != NULL_ISA
/**
* Get the data in the packet byte swapped from guest to host
* endian.
*/
template <typename T>
- T get() const;
+ T get() const
+ M5_DEPRECATED_MSG("The memory system should be ISA independent.");
+#endif
/** Set the value in the data pointer to v as big endian. */
template <typename T>
template <typename T>
void set(T v, ByteOrder endian);
+#if THE_ISA != NULL_ISA
/** Set the value in the data pointer to v as guest endian. */
template <typename T>
- void set(T v);
-
+ void set(T v)
+ M5_DEPRECATED_MSG("The memory system should be ISA independent.");
+#endif
/**
* Get the data in the packet byte swapped from the specified
/** @} */
- private: // Private data accessor methods
/** Get the data in the packet without byte swapping. */
template <typename T>
T getRaw() const;
* accordingly.
*/
bool
- checkFunctional(PacketPtr other)
+ trySatisfyFunctional(PacketPtr other)
{
// all packets that are carrying a payload should have a valid
// data pointer
- return checkFunctional(other, other->getAddr(), other->isSecure(),
- other->getSize(),
- other->hasData() ?
- other->getPtr<uint8_t>() : NULL);
+ return trySatisfyFunctional(other, other->getAddr(), other->isSecure(),
+ other->getSize(),
+ other->hasData() ?
+ other->getPtr<uint8_t>() : NULL);
}
/**
* memory value.
*/
bool
- checkFunctional(Printable *obj, Addr base, bool is_secure, int size,
- uint8_t *_data);
+ trySatisfyFunctional(Printable *obj, Addr base, bool is_secure, int size,
+ uint8_t *_data);
/**
* Push label for PrintReq (safe to call unconditionally).