mem: Add HTM fields to the Packet object
JIRA: https://gem5.atlassian.net/browse/GEM5-587 Change-Id: I39268825327f2387ca7e622093fdb42c24a6c82c Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/30318 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Giacomo Travaglini
parent
03ec22b990
commit
1c61dae99b
@@ -114,6 +114,7 @@ DebugFlag('DRAM')
|
||||
DebugFlag('DRAMPower')
|
||||
DebugFlag('DRAMState')
|
||||
DebugFlag('ExternalPort')
|
||||
DebugFlag('HtmMem', 'Hardware Transactional Memory (Mem side)')
|
||||
DebugFlag('LLSC')
|
||||
DebugFlag('MMU')
|
||||
DebugFlag('MemoryAccess')
|
||||
|
||||
@@ -230,7 +230,11 @@ MemCmd::commandInfo[] =
|
||||
InvalidateResp, "InvalidateReq" },
|
||||
/* Invalidation Response */
|
||||
{ SET2(IsInvalidate, IsResponse),
|
||||
InvalidCmd, "InvalidateResp" }
|
||||
InvalidCmd, "InvalidateResp" },
|
||||
// hardware transactional memory
|
||||
{ SET3(IsRead, IsRequest, NeedsResponse), HTMReqResp, "HTMReq" },
|
||||
{ SET2(IsRead, IsResponse), InvalidCmd, "HTMReqResp" },
|
||||
{ SET2(IsRead, IsRequest), InvalidCmd, "HTMAbort" },
|
||||
};
|
||||
|
||||
AddrRange
|
||||
@@ -489,3 +493,62 @@ Packet::PrintReqState::printObj(Printable *obj)
|
||||
printLabels();
|
||||
obj->print(os, verbosity, curPrefix());
|
||||
}
|
||||
|
||||
void
|
||||
Packet::makeHtmTransactionalReqResponse(
|
||||
const HtmCacheFailure htm_return_code)
|
||||
{
|
||||
assert(needsResponse());
|
||||
assert(isRequest());
|
||||
|
||||
cmd = cmd.responseCommand();
|
||||
|
||||
setHtmTransactionFailedInCache(htm_return_code);
|
||||
|
||||
// responses are never express, even if the snoop that
|
||||
// triggered them was
|
||||
flags.clear(EXPRESS_SNOOP);
|
||||
}
|
||||
|
||||
void
|
||||
Packet::setHtmTransactionFailedInCache(
|
||||
const HtmCacheFailure htm_return_code)
|
||||
{
|
||||
if (htm_return_code != HtmCacheFailure::NO_FAIL)
|
||||
flags.set(FAILS_TRANSACTION);
|
||||
|
||||
htmReturnReason = htm_return_code;
|
||||
}
|
||||
|
||||
bool
|
||||
Packet::htmTransactionFailedInCache() const
|
||||
{
|
||||
return flags.isSet(FAILS_TRANSACTION);
|
||||
}
|
||||
|
||||
HtmCacheFailure
|
||||
Packet::getHtmTransactionFailedInCacheRC() const
|
||||
{
|
||||
assert(htmTransactionFailedInCache());
|
||||
return htmReturnReason;
|
||||
}
|
||||
|
||||
void
|
||||
Packet::setHtmTransactional(uint64_t htm_uid)
|
||||
{
|
||||
flags.set(FROM_TRANSACTION);
|
||||
htmTransactionUid = htm_uid;
|
||||
}
|
||||
|
||||
bool
|
||||
Packet::isHtmTransactional() const
|
||||
{
|
||||
return flags.isSet(FROM_TRANSACTION);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
Packet::getHtmTransactionUid() const
|
||||
{
|
||||
assert(flags.isSet(FROM_TRANSACTION));
|
||||
return htmTransactionUid;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "base/logging.hh"
|
||||
#include "base/printable.hh"
|
||||
#include "base/types.hh"
|
||||
#include "mem/htm.hh"
|
||||
#include "mem/request.hh"
|
||||
#include "sim/core.hh"
|
||||
|
||||
@@ -131,6 +132,10 @@ class MemCmd
|
||||
FlushReq, //request for a cache flush
|
||||
InvalidateReq, // request for address to be invalidated
|
||||
InvalidateResp,
|
||||
// hardware transactional memory
|
||||
HTMReq,
|
||||
HTMReqResp,
|
||||
HTMAbort,
|
||||
NUM_MEM_CMDS
|
||||
};
|
||||
|
||||
@@ -259,7 +264,7 @@ class Packet : public Printable
|
||||
|
||||
enum : FlagsType {
|
||||
// Flags to transfer across when copying a packet
|
||||
COPY_FLAGS = 0x0000003F,
|
||||
COPY_FLAGS = 0x000000FF,
|
||||
|
||||
// Flags that are used to create reponse packets
|
||||
RESPONDER_FLAGS = 0x00000009,
|
||||
@@ -289,6 +294,17 @@ class Packet : public Printable
|
||||
// operations
|
||||
SATISFIED = 0x00000020,
|
||||
|
||||
// hardware transactional memory
|
||||
|
||||
// Indicates that this packet/request has returned from the
|
||||
// cache hierarchy in a failed transaction. The core is
|
||||
// notified like this.
|
||||
FAILS_TRANSACTION = 0x00000040,
|
||||
|
||||
// Indicates that this packet/request originates in the CPU executing
|
||||
// in transactional mode, i.e. in a transaction.
|
||||
FROM_TRANSACTION = 0x00000080,
|
||||
|
||||
/// Are the 'addr' and 'size' fields valid?
|
||||
VALID_ADDR = 0x00000100,
|
||||
VALID_SIZE = 0x00000200,
|
||||
@@ -351,6 +367,21 @@ class Packet : public Printable
|
||||
// Quality of Service priority value
|
||||
uint8_t _qosValue;
|
||||
|
||||
// hardware transactional memory
|
||||
|
||||
/**
|
||||
* Holds the return status of the transaction.
|
||||
* The default case will be NO_FAIL, otherwise this will specify the
|
||||
* reason for the transaction's failure in the memory subsystem.
|
||||
*/
|
||||
HtmCacheFailure htmReturnReason;
|
||||
|
||||
/**
|
||||
* A global unique identifier of the transaction.
|
||||
* This is used for correctness/debugging only.
|
||||
*/
|
||||
uint64_t htmTransactionUid;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -793,14 +824,33 @@ class Packet : public Printable
|
||||
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),
|
||||
_qosValue(0),
|
||||
htmReturnReason(HtmCacheFailure::NO_FAIL),
|
||||
htmTransactionUid(0),
|
||||
headerDelay(0), snoopDelay(0),
|
||||
payloadDelay(0), senderState(NULL)
|
||||
{
|
||||
flags.clear();
|
||||
if (req->hasPaddr()) {
|
||||
addr = req->getPaddr();
|
||||
flags.set(VALID_ADDR);
|
||||
_isSecure = req->isSecure();
|
||||
}
|
||||
|
||||
/**
|
||||
* hardware transactional memory
|
||||
*
|
||||
* This is a bit of a hack!
|
||||
* Technically the address of a HTM command is set to zero
|
||||
* but is not valid. The reason that we pretend it's valid is
|
||||
* to void the getAddr() function from failing. It would be
|
||||
* cumbersome to add control flow in many places to check if the
|
||||
* packet represents a HTM command before calling getAddr().
|
||||
*/
|
||||
if (req->isHTMCmd()) {
|
||||
flags.set(VALID_ADDR);
|
||||
assert(addr == 0x0);
|
||||
}
|
||||
if (req->hasSize()) {
|
||||
size = req->getSize();
|
||||
flags.set(VALID_SIZE);
|
||||
@@ -815,9 +865,13 @@ class Packet : public Printable
|
||||
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),
|
||||
_qosValue(0),
|
||||
htmReturnReason(HtmCacheFailure::NO_FAIL),
|
||||
htmTransactionUid(0),
|
||||
headerDelay(0),
|
||||
snoopDelay(0), payloadDelay(0), senderState(NULL)
|
||||
{
|
||||
flags.clear();
|
||||
if (req->hasPaddr()) {
|
||||
addr = req->getPaddr() & ~(_blkSize - 1);
|
||||
flags.set(VALID_ADDR);
|
||||
@@ -840,6 +894,8 @@ class Packet : public Printable
|
||||
addr(pkt->addr), _isSecure(pkt->_isSecure), size(pkt->size),
|
||||
bytesValid(pkt->bytesValid),
|
||||
_qosValue(pkt->qosValue()),
|
||||
htmReturnReason(HtmCacheFailure::NO_FAIL),
|
||||
htmTransactionUid(0),
|
||||
headerDelay(pkt->headerDelay),
|
||||
snoopDelay(0),
|
||||
payloadDelay(pkt->payloadDelay),
|
||||
@@ -850,6 +906,15 @@ class Packet : public Printable
|
||||
|
||||
flags.set(pkt->flags & (VALID_ADDR|VALID_SIZE));
|
||||
|
||||
if (pkt->isHtmTransactional())
|
||||
setHtmTransactional(pkt->getHtmTransactionUid());
|
||||
|
||||
if (pkt->htmTransactionFailedInCache()) {
|
||||
setHtmTransactionFailedInCache(
|
||||
pkt->getHtmTransactionFailedInCacheRC()
|
||||
);
|
||||
}
|
||||
|
||||
// should we allocate space for data, or not, the express
|
||||
// snoops do not need to carry any data as they only serve to
|
||||
// co-ordinate state changes
|
||||
@@ -873,7 +938,12 @@ class Packet : public Printable
|
||||
static MemCmd
|
||||
makeReadCmd(const RequestPtr &req)
|
||||
{
|
||||
if (req->isLLSC())
|
||||
if (req->isHTMCmd()) {
|
||||
if (req->isHTMAbort())
|
||||
return MemCmd::HTMAbort;
|
||||
else
|
||||
return MemCmd::HTMReq;
|
||||
} else if (req->isLLSC())
|
||||
return MemCmd::LoadLockedReq;
|
||||
else if (req->isPrefetchEx())
|
||||
return MemCmd::SoftPFExReq;
|
||||
@@ -1346,6 +1416,58 @@ class Packet : public Printable
|
||||
* @return string with the request's type and start<->end addresses
|
||||
*/
|
||||
std::string print() const;
|
||||
|
||||
// hardware transactional memory
|
||||
|
||||
/**
|
||||
* Communicates to the core that a packet was processed by the memory
|
||||
* subsystem while running in transactional mode.
|
||||
* It may happen that the transaction has failed at the memory subsystem
|
||||
* and this needs to be communicated to the core somehow.
|
||||
* This function decorates the response packet with flags to indicate
|
||||
* such a situation has occurred.
|
||||
*/
|
||||
void makeHtmTransactionalReqResponse(const HtmCacheFailure ret_code);
|
||||
|
||||
/**
|
||||
* Stipulates that this packet/request originates in the CPU executing
|
||||
* in transactional mode, i.e. within a transaction.
|
||||
*/
|
||||
void setHtmTransactional(uint64_t val);
|
||||
|
||||
/**
|
||||
* Returns whether or not this packet/request originates in the CPU
|
||||
* executing in transactional mode, i.e. within a transaction.
|
||||
*/
|
||||
bool isHtmTransactional() const;
|
||||
|
||||
/**
|
||||
* If a packet/request originates in a CPU executing in transactional
|
||||
* mode, i.e. within a transaction, this function returns the unique ID
|
||||
* of the transaction. This is used for verifying correctness
|
||||
* and debugging.
|
||||
*/
|
||||
uint64_t getHtmTransactionUid() const;
|
||||
|
||||
/**
|
||||
* Stipulates that this packet/request has returned from the
|
||||
* cache hierarchy in a failed transaction. The core is
|
||||
* notified like this.
|
||||
*/
|
||||
void setHtmTransactionFailedInCache(const HtmCacheFailure ret_code);
|
||||
|
||||
/**
|
||||
* Returns whether or not this packet/request has returned from the
|
||||
* cache hierarchy in a failed transaction. The core is
|
||||
* notified liked this.
|
||||
*/
|
||||
bool htmTransactionFailedInCache() const;
|
||||
|
||||
/**
|
||||
* If a packet/request has returned from the cache hierarchy in a
|
||||
* failed transaction, this function returns the failure reason.
|
||||
*/
|
||||
HtmCacheFailure getHtmTransactionFailedInCacheRC() const;
|
||||
};
|
||||
|
||||
#endif //__MEM_PACKET_HH
|
||||
|
||||
Reference in New Issue
Block a user