/*
* 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
#include "base/trace.hh"
#include "mem/packet.hh"
+using namespace std;
+
// The one downside to bitsets is that static initializers can get ugly.
#define SET1(a1) (1 << (a1))
#define SET2(a1, a2) (SET1(a1) | SET1(a2))
{ SET3(IsWrite, NeedsExclusive, IsResponse),
InvalidCmd, "WriteInvalidateResp" },
/* UpgradeReq */
- { SET4(IsInvalidate, NeedsExclusive, IsRequest, NeedsResponse),
+ { SET5(IsInvalidate, NeedsExclusive, IsUpgrade, IsRequest, NeedsResponse),
UpgradeResp, "UpgradeReq" },
+ /* SCUpgradeReq: response could be UpgradeResp or UpgradeFailResp */
+ { SET6(IsInvalidate, NeedsExclusive, IsUpgrade, IsLlsc,
+ IsRequest, NeedsResponse),
+ UpgradeResp, "SCUpgradeReq" },
/* UpgradeResp */
- { SET2(NeedsExclusive, IsResponse),
+ { SET3(NeedsExclusive, IsUpgrade, IsResponse),
InvalidCmd, "UpgradeResp" },
+ /* SCUpgradeFailReq: generates UpgradeFailResp ASAP */
+ { SET5(IsInvalidate, NeedsExclusive, IsLlsc,
+ IsRequest, NeedsResponse),
+ UpgradeFailResp, "SCUpgradeFailReq" },
+ /* UpgradeFailResp */
+ { SET2(NeedsExclusive, IsResponse),
+ InvalidCmd, "UpgradeFailResp" },
/* ReadExReq */
{ SET5(IsRead, NeedsExclusive, IsInvalidate, IsRequest, NeedsResponse),
ReadExResp, "ReadExReq" },
/* ReadExResp */
{ SET4(IsRead, NeedsExclusive, IsResponse, HasData),
InvalidCmd, "ReadExResp" },
- /* LoadLockedReq */
- { SET4(IsRead, IsLocked, IsRequest, NeedsResponse),
- LoadLockedResp, "LoadLockedReq" },
- /* LoadLockedResp */
- { SET4(IsRead, IsLocked, IsResponse, HasData),
- InvalidCmd, "LoadLockedResp" },
+ /* LoadLockedReq: note that we use plain ReadResp as response, so that
+ * we can also use ReadRespWithInvalidate when needed */
+ { SET4(IsRead, IsLlsc, IsRequest, NeedsResponse),
+ ReadResp, "LoadLockedReq" },
/* StoreCondReq */
- { SET6(IsWrite, NeedsExclusive, IsLocked,
+ { SET6(IsWrite, NeedsExclusive, IsLlsc,
IsRequest, NeedsResponse, HasData),
StoreCondResp, "StoreCondReq" },
+ /* StoreCondFailReq: generates failing StoreCondResp ASAP */
+ { SET6(IsWrite, NeedsExclusive, IsLlsc,
+ IsRequest, NeedsResponse, HasData),
+ StoreCondResp, "StoreCondFailReq" },
/* StoreCondResp */
- { SET4(IsWrite, NeedsExclusive, IsLocked, IsResponse),
+ { SET4(IsWrite, NeedsExclusive, IsLlsc, IsResponse),
InvalidCmd, "StoreCondResp" },
/* SwapReq -- for Swap ldstub type operations */
{ SET6(IsRead, IsWrite, NeedsExclusive, IsRequest, HasData, NeedsResponse),
/* SwapResp -- for Swap ldstub type operations */
{ SET5(IsRead, IsWrite, NeedsExclusive, IsResponse, HasData),
InvalidCmd, "SwapResp" },
+ /* IntReq -- for interrupts */
+ { SET4(IsWrite, IsRequest, NeedsResponse, HasData),
+ MessageResp, "MessageReq" },
+ /* IntResp -- for interrupts */
+ { SET2(IsWrite, IsResponse), InvalidCmd, "MessageResp" },
/* NetworkNackError -- nacked at network layer (not by protocol) */
{ SET2(IsResponse, IsError), InvalidCmd, "NetworkNackError" },
/* InvalidDestError -- packet dest field invalid */
{ SET2(IsRequest, IsPrint), InvalidCmd, "PrintReq" }
};
-
-/** delete the data pointed to in the data pointer. Ok to call to matter how
- * data was allocted. */
-void
-Packet::deleteData()
-{
- assert(staticData || dynamicData);
- if (staticData)
- return;
-
- if (arrayData)
- delete [] data;
- else
- delete data;
-}
-
-/** If there isn't data in the packet, allocate some. */
-void
-Packet::allocate()
-{
- if (data)
- return;
- assert(!staticData);
- dynamicData = true;
- arrayData = true;
- data = new uint8_t[getSize()];
-}
-
-
bool
Packet::checkFunctional(Printable *obj, Addr addr, int size, uint8_t *data)
{
if (isRead()) {
if (func_start >= val_start && func_end <= val_end) {
allocate();
- std::memcpy(getPtr<uint8_t>(), data + offset, getSize());
- makeResponse();
+ memcpy(getPtr<uint8_t>(), data + offset, getSize());
return true;
} else {
// In this case the timing packet only partially satisfies
}
} else if (isWrite()) {
if (offset >= 0) {
- std::memcpy(data + offset, getPtr<uint8_t>(),
- (std::min(func_end, val_end) - func_start) + 1);
- } else { // val_start > func_start
- std::memcpy(data, getPtr<uint8_t>() - offset,
- (std::min(func_end, val_end) - val_start) + 1);
+ memcpy(data + offset, getPtr<uint8_t>(),
+ (min(func_end, val_end) - func_start) + 1);
+ } else {
+ // val_start > func_start
+ memcpy(data, getPtr<uint8_t>() - offset,
+ (min(func_end, val_end) - val_start) + 1);
}
} else {
panic("Don't know how to handle command %s\n", cmdString());
return false;
}
-
void
-Packet::print(std::ostream &o, const int verbosity,
- const std::string &prefix) const
+Packet::print(ostream &o, const int verbosity, const string &prefix) const
{
ccprintf(o, "%s[%x:%x] %s\n", prefix,
getAddr(), getAddr() + getSize() - 1, cmdString());
}
-
-Packet::PrintReqState::PrintReqState(std::ostream &_os, int _verbosity)
- : curPrefixPtr(new std::string("")), os(_os), verbosity(_verbosity)
+Packet::PrintReqState::PrintReqState(ostream &_os, int _verbosity)
+ : curPrefixPtr(new string("")), os(_os), verbosity(_verbosity)
{
labelStack.push_back(LabelStackEntry("", curPrefixPtr));
}
-
Packet::PrintReqState::~PrintReqState()
{
labelStack.pop_back();
delete curPrefixPtr;
}
-
Packet::PrintReqState::
-LabelStackEntry::LabelStackEntry(const std::string &_label,
- std::string *_prefix)
+LabelStackEntry::LabelStackEntry(const string &_label, string *_prefix)
: label(_label), prefix(_prefix), labelPrinted(false)
{
}
-
void
-Packet::PrintReqState::pushLabel(const std::string &lbl,
- const std::string &prefix)
+Packet::PrintReqState::pushLabel(const string &lbl, const string &prefix)
{
labelStack.push_back(LabelStackEntry(lbl, curPrefixPtr));
- curPrefixPtr = new std::string(*curPrefixPtr);
+ curPrefixPtr = new string(*curPrefixPtr);
*curPrefixPtr += prefix;
}