/*
* Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2010 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
WriteInvalidateReq,
WriteInvalidateResp,
UpgradeReq,
+ SCUpgradeReq, // Special "weak" upgrade for StoreCond
UpgradeResp,
+ SCUpgradeFailReq, // Failed SCUpgradeReq in MSHR (never sent)
+ UpgradeFailResp, // Valid for SCUpgradeReq only
ReadExReq,
ReadExResp,
LoadLockedReq,
StoreCondReq,
+ StoreCondFailReq, // Failed StoreCondReq in MSHR (never sent)
StoreCondResp,
SwapReq,
SwapResp,
BadAddressError, // memory address invalid
// Fake simulator-only commands
PrintReq, // Print state matching address
+ FlushReq, //request for a cache flush
NUM_MEM_CMDS
};
{
IsRead, //!< Data flows from responder to requester
IsWrite, //!< Data flows from requester to responder
+ IsUpgrade,
IsPrefetch, //!< Not a demand access
IsInvalidate,
NeedsExclusive, //!< Requires exclusive copy to complete in-cache
HasData, //!< There is an associated payload
IsError, //!< Error response
IsPrint, //!< Print state matching address (for debugging)
+ IsFlush, //!< Flush the address from caches
NUM_COMMAND_ATTRIBUTES
};
public:
bool isRead() const { return testCmdAttrib(IsRead); }
- bool isWrite() const { return testCmdAttrib(IsWrite); }
+ bool isWrite() const { return testCmdAttrib(IsWrite); }
+ bool isUpgrade() const { return testCmdAttrib(IsUpgrade); }
bool isRequest() const { return testCmdAttrib(IsRequest); }
bool isResponse() const { return testCmdAttrib(IsResponse); }
bool needsExclusive() const { return testCmdAttrib(NeedsExclusive); }
bool isLLSC() const { return testCmdAttrib(IsLlsc); }
bool isError() const { return testCmdAttrib(IsError); }
bool isPrint() const { return testCmdAttrib(IsPrint); }
+ bool isFlush() const { return testCmdAttrib(IsFlush); }
const Command
responseCommand() const
inline int cmdToIndex() const { return cmd.toInt(); }
bool isRead() const { return cmd.isRead(); }
- bool isWrite() const { return cmd.isWrite(); }
+ bool isWrite() const { return cmd.isWrite(); }
+ bool isUpgrade() const { return cmd.isUpgrade(); }
bool isRequest() const { return cmd.isRequest(); }
bool isResponse() const { return cmd.isResponse(); }
bool needsExclusive() const { return cmd.needsExclusive(); }
bool isLLSC() const { return cmd.isLLSC(); }
bool isError() const { return cmd.isError(); }
bool isPrint() const { return cmd.isPrint(); }
+ bool isFlush() const { return cmd.isFlush(); }
// Snoop flags
void assertMemInhibit() { flags.set(MEM_INHIBIT); }
void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
bool isExpressSnoop() { return flags.isSet(EXPRESS_SNOOP); }
void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); }
+ void clearSupplyExclusive() { flags.clear(SUPPLY_EXCLUSIVE); }
bool isSupplyExclusive() { return flags.isSet(SUPPLY_EXCLUSIVE); }
// Network error conditions... encapsulate them as methods since
bool hadBadAddress() const { return cmd == MemCmd::BadAddressError; }
void copyError(Packet *pkt) { assert(pkt->isError()); cmd = pkt->cmd; }
+ bool isSrcValid() { return flags.isSet(VALID_SRC); }
/// Accessor function to get the source index of the packet.
NodeID getSrc() const { assert(flags.isSet(VALID_SRC)); return src; }
/// Accessor function to set the source index of the packet.
/// Reset source field, e.g. to retransmit packet on different bus.
void clearSrc() { flags.clear(VALID_SRC); }
+ bool isDestValid() { return flags.isSet(VALID_DST); }
/// Accessor function for the destination index of the packet.
NodeID getDest() const { assert(flags.isSet(VALID_DST)); return dest; }
/// Accessor function to set the destination index of the packet.
unsigned getSize() const { assert(flags.isSet(VALID_SIZE)); return size; }
Addr getOffset(int blkSize) const { return getAddr() & (Addr)(blkSize - 1); }
+ /**
+ * It has been determined that the SC packet should successfully update
+ * memory. Therefore, convert this SC packet to a normal write.
+ */
+ void
+ convertScToWrite()
+ {
+ assert(isLLSC());
+ assert(isWrite());
+ cmd = MemCmd::WriteReq;
+ }
+
+ /**
+ * When ruby is in use, Ruby will monitor the cache line and thus M5
+ * phys memory should treat LL ops as normal reads.
+ */
+ void
+ convertLlToRead()
+ {
+ assert(isLLSC());
+ assert(isRead());
+ cmd = MemCmd::ReadReq;
+ }
+
/**
* Constructor. Note that a Request object must be constructed
* first, but the Requests's physical address and size fields need
*/
Packet(Request *_req, MemCmd _cmd, NodeID _dest)
: flags(VALID_DST), cmd(_cmd), req(_req), data(NULL),
- dest(_dest), time(curTick), senderState(NULL)
+ dest(_dest), time(curTick()), senderState(NULL)
{
if (req->hasPaddr()) {
addr = req->getPaddr();
*/
Packet(Request *_req, MemCmd _cmd, NodeID _dest, int _blkSize)
: flags(VALID_DST), cmd(_cmd), req(_req), data(NULL),
- dest(_dest), time(curTick), senderState(NULL)
+ dest(_dest), time(curTick()), senderState(NULL)
{
if (req->hasPaddr()) {
addr = req->getPaddr() & ~(_blkSize - 1);
: cmd(pkt->cmd), req(pkt->req),
data(pkt->flags.isSet(STATIC_DATA) ? pkt->data : NULL),
addr(pkt->addr), size(pkt->size), src(pkt->src), dest(pkt->dest),
- time(curTick), senderState(pkt->senderState)
+ time(curTick()), senderState(pkt->senderState)
{
if (!clearFlags)
flags.set(pkt->flags & COPY_FLAGS);
origCmd = cmd;
cmd = cmd.responseCommand();
+ // responses are never express, even if the snoop that
+ // triggered them was
+ flags.clear(EXPRESS_SNOOP);
+
dest = src;
flags.set(VALID_DST, flags.isSet(VALID_SRC));
flags.clear(VALID_SRC);
setDest(Broadcast);
}
+ void
+ setSize(unsigned size)
+ {
+ assert(!flags.isSet(VALID_SIZE));
+
+ this->size = size;
+ flags.set(VALID_SIZE);
+ }
+
/**
* Set the data pointer to the following value that should not be
*/
template <typename T>
T*
- getPtr()
+ getPtr(bool null_ok = false)
{
- assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
+ assert(null_ok || flags.isSet(STATIC_DATA|DYNAMIC_DATA));
return (T*)data;
}
void
setData(uint8_t *p)
{
- std::memcpy(getPtr<uint8_t>(), p, getSize());
+ if (p != getPtr<uint8_t>())
+ std::memcpy(getPtr<uint8_t>(), p, getSize());
}
/**
data = new uint8_t[getSize()];
}
-
/**
* Check a functional request against a memory value represented
* by a base/size pair and an associated data array. If the