packet.cc revision 8436
12497SN/A/* 210405Sandreas.hansson@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 38711SN/A * Copyright (c) 2010 Advanced Micro Devices, Inc. 48711SN/A * All rights reserved. 58711SN/A * 68711SN/A * Redistribution and use in source and binary forms, with or without 78711SN/A * modification, are permitted provided that the following conditions are 88711SN/A * met: redistributions of source code must retain the above copyright 98711SN/A * notice, this list of conditions and the following disclaimer; 108711SN/A * redistributions in binary form must reproduce the above copyright 118711SN/A * notice, this list of conditions and the following disclaimer in the 128711SN/A * documentation and/or other materials provided with the distribution; 138711SN/A * neither the name of the copyright holders nor the names of its 142497SN/A * contributors may be used to endorse or promote products derived from 152497SN/A * this software without specific prior written permission. 162497SN/A * 172497SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182497SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192497SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202497SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212497SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222497SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232497SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242497SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252497SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262497SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272497SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282497SN/A * 292497SN/A * Authors: Ali Saidi 302497SN/A * Steve Reinhardt 312497SN/A */ 322497SN/A 332497SN/A/** 342497SN/A * @file 352497SN/A * Definition of the Packet Class, a packet is a transaction occuring 362497SN/A * between a single level of the memory heirarchy (ie L1->L2). 372497SN/A */ 382497SN/A 392665SN/A#include <cstring> 402665SN/A#include <iostream> 418715SN/A 428922SN/A#include "base/cprintf.hh" 432497SN/A#include "base/misc.hh" 442497SN/A#include "base/trace.hh" 452497SN/A#include "mem/packet.hh" 462982SN/A 4710405Sandreas.hansson@arm.comusing namespace std; 482497SN/A 492497SN/A// The one downside to bitsets is that static initializers can get ugly. 502846SN/A#define SET1(a1) (1 << (a1)) 512548SN/A#define SET2(a1, a2) (SET1(a1) | SET1(a2)) 5210405Sandreas.hansson@arm.com#define SET3(a1, a2, a3) (SET2(a1, a2) | SET1(a3)) 5310405Sandreas.hansson@arm.com#define SET4(a1, a2, a3, a4) (SET3(a1, a2, a3) | SET1(a4)) 5410405Sandreas.hansson@arm.com#define SET5(a1, a2, a3, a4, a5) (SET4(a1, a2, a3, a4) | SET1(a5)) 559524SN/A#define SET6(a1, a2, a3, a4, a5, a6) (SET5(a1, a2, a3, a4, a5) | SET1(a6)) 562497SN/A 5710405Sandreas.hansson@arm.comconst MemCmd::CommandInfo 5810405Sandreas.hansson@arm.comMemCmd::commandInfo[] = 597523SN/A{ 608851SN/A /* InvalidCmd */ 618948SN/A { 0, InvalidCmd, "InvalidCmd" }, 628948SN/A /* ReadReq */ 638851SN/A { SET3(IsRead, IsRequest, NeedsResponse), ReadResp, "ReadReq" }, 649095SN/A /* ReadResp */ 6510405Sandreas.hansson@arm.com { SET3(IsRead, IsResponse, HasData), InvalidCmd, "ReadResp" }, 668922SN/A /* ReadRespWithInvalidate */ 679715SN/A { SET4(IsRead, IsResponse, HasData, IsInvalidate), 689715SN/A InvalidCmd, "ReadRespWithInvalidate" }, 699715SN/A /* WriteReq */ 709715SN/A { SET5(IsWrite, NeedsExclusive, IsRequest, NeedsResponse, HasData), 718851SN/A WriteResp, "WriteReq" }, 728851SN/A /* WriteResp */ 738948SN/A { SET3(IsWrite, NeedsExclusive, IsResponse), InvalidCmd, "WriteResp" }, 748948SN/A /* Writeback */ 758915SN/A { SET4(IsWrite, NeedsExclusive, IsRequest, HasData), 769031SN/A InvalidCmd, "Writeback" }, 779095SN/A /* SoftPFReq */ 7810405Sandreas.hansson@arm.com { SET4(IsRead, IsRequest, IsSWPrefetch, NeedsResponse), 799036SN/A SoftPFResp, "SoftPFReq" }, 808922SN/A /* HardPFReq */ 819715SN/A { SET4(IsRead, IsRequest, IsHWPrefetch, NeedsResponse), 829715SN/A HardPFResp, "HardPFReq" }, 839715SN/A /* SoftPFResp */ 849715SN/A { SET4(IsRead, IsResponse, IsSWPrefetch, HasData), 859715SN/A InvalidCmd, "SoftPFResp" }, 868915SN/A /* HardPFResp */ 878915SN/A { SET4(IsRead, IsResponse, IsHWPrefetch, HasData), 888948SN/A InvalidCmd, "HardPFResp" }, 898851SN/A /* WriteInvalidateReq */ 909095SN/A { SET6(IsWrite, NeedsExclusive, IsInvalidate, 9110405Sandreas.hansson@arm.com IsRequest, HasData, NeedsResponse), 928922SN/A WriteInvalidateResp, "WriteInvalidateReq" }, 939715SN/A /* WriteInvalidateResp */ 949715SN/A { SET3(IsWrite, NeedsExclusive, IsResponse), 959716SN/A InvalidCmd, "WriteInvalidateResp" }, 968851SN/A /* UpgradeReq */ 978851SN/A { SET5(IsInvalidate, NeedsExclusive, IsUpgrade, IsRequest, NeedsResponse), 9810402SN/A UpgradeResp, "UpgradeReq" }, 9910402SN/A /* SCUpgradeReq: response could be UpgradeResp or UpgradeFailResp */ 10010402SN/A { SET6(IsInvalidate, NeedsExclusive, IsUpgrade, IsLlsc, 1017523SN/A IsRequest, NeedsResponse), 1027523SN/A UpgradeResp, "SCUpgradeReq" }, 1037523SN/A /* UpgradeResp */ 10410405Sandreas.hansson@arm.com { SET3(NeedsExclusive, IsUpgrade, IsResponse), 1059715SN/A InvalidCmd, "UpgradeResp" }, 10610405Sandreas.hansson@arm.com /* SCUpgradeFailReq: generates UpgradeFailResp ASAP */ 10710405Sandreas.hansson@arm.com { SET5(IsInvalidate, NeedsExclusive, IsLlsc, 10810405Sandreas.hansson@arm.com IsRequest, NeedsResponse), 10910405Sandreas.hansson@arm.com UpgradeFailResp, "SCUpgradeFailReq" }, 11010405Sandreas.hansson@arm.com /* UpgradeFailResp */ 11110405Sandreas.hansson@arm.com { SET2(NeedsExclusive, IsResponse), 11210405Sandreas.hansson@arm.com InvalidCmd, "UpgradeFailResp" }, 11310405Sandreas.hansson@arm.com /* ReadExReq */ 1149715SN/A { SET5(IsRead, NeedsExclusive, IsInvalidate, IsRequest, NeedsResponse), 1159715SN/A ReadExResp, "ReadExReq" }, 1162568SN/A /* ReadExResp */ 11710405Sandreas.hansson@arm.com { SET4(IsRead, NeedsExclusive, IsResponse, HasData), 1182568SN/A InvalidCmd, "ReadExResp" }, 1199278SN/A /* LoadLockedReq: note that we use plain ReadResp as response, so that 12010405Sandreas.hansson@arm.com * we can also use ReadRespWithInvalidate when needed */ 1219278SN/A { SET4(IsRead, IsLlsc, IsRequest, NeedsResponse), 1228948SN/A ReadResp, "LoadLockedReq" }, 1238948SN/A /* StoreCondReq */ 12410405Sandreas.hansson@arm.com { SET6(IsWrite, NeedsExclusive, IsLlsc, 1259088SN/A IsRequest, NeedsResponse, HasData), 12610405Sandreas.hansson@arm.com StoreCondResp, "StoreCondReq" }, 12710405Sandreas.hansson@arm.com /* StoreCondFailReq: generates failing StoreCondResp ASAP */ 12810405Sandreas.hansson@arm.com { SET6(IsWrite, NeedsExclusive, IsLlsc, 12910405Sandreas.hansson@arm.com IsRequest, NeedsResponse, HasData), 1308711SN/A StoreCondResp, "StoreCondFailReq" }, 1318711SN/A /* StoreCondResp */ 1322568SN/A { SET4(IsWrite, NeedsExclusive, IsLlsc, IsResponse), 1339036SN/A InvalidCmd, "StoreCondResp" }, 13410405Sandreas.hansson@arm.com /* SwapReq -- for Swap ldstub type operations */ 1353244SN/A { SET6(IsRead, IsWrite, NeedsExclusive, IsRequest, HasData, NeedsResponse), 1363244SN/A SwapResp, "SwapReq" }, 1378948SN/A /* SwapResp -- for Swap ldstub type operations */ 13810405Sandreas.hansson@arm.com { SET5(IsRead, IsWrite, NeedsExclusive, IsResponse, HasData), 1393244SN/A InvalidCmd, "SwapResp" }, 1408975SN/A /* IntReq -- for interrupts */ 1419032SN/A { SET4(IsWrite, IsRequest, NeedsResponse, HasData), 1423244SN/A MessageResp, "MessageReq" }, 1439091SN/A /* IntResp -- for interrupts */ 1449091SN/A { SET2(IsWrite, IsResponse), InvalidCmd, "MessageResp" }, 1459091SN/A /* NetworkNackError -- nacked at network layer (not by protocol) */ 1469612SN/A { SET2(IsResponse, IsError), InvalidCmd, "NetworkNackError" }, 1479712SN/A /* InvalidDestError -- packet dest field invalid */ 1489612SN/A { SET2(IsResponse, IsError), InvalidCmd, "InvalidDestError" }, 14910405Sandreas.hansson@arm.com /* BadAddressError -- memory address invalid */ 1509033SN/A { SET2(IsResponse, IsError), InvalidCmd, "BadAddressError" }, 1519715SN/A /* FunctionalReadError */ 15210405Sandreas.hansson@arm.com { SET3(IsRead, IsResponse, IsError), InvalidCmd, "FunctionalReadError" }, 1538949SN/A /* FunctionalWriteError */ 1543244SN/A { SET3(IsWrite, IsResponse, IsError), InvalidCmd, "FunctionalWriteError" }, 1553244SN/A /* PrintReq */ 1563244SN/A { SET2(IsRequest, IsPrint), InvalidCmd, "PrintReq" }, 15710405Sandreas.hansson@arm.com /* Flush Request */ 1589091SN/A { SET3(IsRequest, IsFlush, NeedsExclusive), InvalidCmd, "FlushReq" }, 1599091SN/A}; 1605197SN/A 1619712SN/Abool 1629712SN/APacket::checkFunctional(Printable *obj, Addr addr, int size, uint8_t *data) 1639712SN/A{ 1649712SN/A Addr func_start = getAddr(); 1659712SN/A Addr func_end = getAddr() + getSize() - 1; 1669032SN/A Addr val_start = addr; 1679032SN/A Addr val_end = val_start + size - 1; 1689032SN/A 1699547SN/A if (func_start > val_end || val_start > func_end) { 17010405Sandreas.hansson@arm.com // no intersection 1714912SN/A return false; 1728979SN/A } 1739524SN/A 1748979SN/A // check print first since it doesn't require data 1758979SN/A if (isPrint()) { 17610402SN/A dynamic_cast<PrintReqState*>(senderState)->printObj(obj); 17710402SN/A return false; 17810402SN/A } 17910402SN/A 18010405Sandreas.hansson@arm.com // if there's no data, there's no need to look further 18110402SN/A if (!data) { 18210402SN/A return false; 18310402SN/A } 18410402SN/A 18510402SN/A // offset of functional request into supplied value (could be 18610402SN/A // negative if partial overlap) 18710402SN/A int offset = func_start - val_start; 1888979SN/A 1898948SN/A if (isRead()) { 1908975SN/A if (func_start >= val_start && func_end <= val_end) { 1918975SN/A allocate(); 1928975SN/A memcpy(getPtr<uint8_t>(), data + offset, getSize()); 1938975SN/A return true; 1949091SN/A } else { 1958948SN/A // In this case the timing packet only partially satisfies 1968975SN/A // the request, so we would need more information to make 1978975SN/A // this work. Like bytes valid in the packet or 1988975SN/A // something, so the request could continue and get this 1998975SN/A // bit of possibly newer data along with the older data 2008975SN/A // not written to yet. 2018975SN/A panic("Memory value only partially satisfies the functional " 2028975SN/A "request. Now what?"); 2038975SN/A } 2048975SN/A } else if (isWrite()) { 2058915SN/A if (offset >= 0) { 20610402SN/A memcpy(data + offset, getPtr<uint8_t>(), 20710402SN/A (min(func_end, val_end) - func_start) + 1); 20810402SN/A } else { 2099612SN/A // val_start > func_start 2109712SN/A memcpy(data, getPtr<uint8_t>() - offset, 2118948SN/A (min(func_end, val_end) - val_start) + 1); 21210402SN/A } 21310402SN/A } else { 21410402SN/A panic("Don't know how to handle command %s\n", cmdString()); 21510402SN/A } 21610402SN/A 21710402SN/A // keep going with request by default 21810402SN/A return false; 21910402SN/A} 22010402SN/A 22110402SN/Avoid 22210402SN/APacket::print(ostream &o, const int verbosity, const string &prefix) const 22310402SN/A{ 22410402SN/A ccprintf(o, "%s[%x:%x] %s\n", prefix, 22510402SN/A getAddr(), getAddr() + getSize() - 1, cmdString()); 22610402SN/A} 2279091SN/A 2289091SN/APacket::PrintReqState::PrintReqState(ostream &_os, int _verbosity) 2299091SN/A : curPrefixPtr(new string("")), os(_os), verbosity(_verbosity) 23010405Sandreas.hansson@arm.com{ 2319091SN/A labelStack.push_back(LabelStackEntry("", curPrefixPtr)); 2329091SN/A} 2339091SN/A 2349091SN/APacket::PrintReqState::~PrintReqState() 2359091SN/A{ 2368948SN/A labelStack.pop_back(); 2379091SN/A assert(labelStack.empty()); 2389091SN/A delete curPrefixPtr; 2399091SN/A} 2409091SN/A 2418948SN/APacket::PrintReqState:: 2429549SN/ALabelStackEntry::LabelStackEntry(const string &_label, string *_prefix) 24310405Sandreas.hansson@arm.com : label(_label), prefix(_prefix), labelPrinted(false) 2449549SN/A{ 24510405Sandreas.hansson@arm.com} 2469091SN/A 2478948SN/Avoid 24810405Sandreas.hansson@arm.comPacket::PrintReqState::pushLabel(const string &lbl, const string &prefix) 2499715SN/A{ 2509715SN/A labelStack.push_back(LabelStackEntry(lbl, curPrefixPtr)); 2519091SN/A curPrefixPtr = new string(*curPrefixPtr); 25210405Sandreas.hansson@arm.com *curPrefixPtr += prefix; 2539715SN/A} 2549091SN/A 2558975SN/Avoid 2568975SN/APacket::PrintReqState::popLabel() 2579712SN/A{ 2589712SN/A delete curPrefixPtr; 2599712SN/A curPrefixPtr = labelStack.back().prefix; 26010405Sandreas.hansson@arm.com labelStack.pop_back(); 2619712SN/A assert(!labelStack.empty()); 2629712SN/A} 2639712SN/A 2649091SN/Avoid 2658975SN/APacket::PrintReqState::printLabels() 2668975SN/A{ 2678975SN/A if (!labelStack.back().labelPrinted) { 26810405Sandreas.hansson@arm.com LabelStack::iterator i = labelStack.begin(); 2698975SN/A LabelStack::iterator end = labelStack.end(); 2708975SN/A while (i != end) { 2719032SN/A if (!i->labelPrinted) { 2728975SN/A ccprintf(os, "%s%s\n", *(i->prefix), i->label); 2739713SN/A i->labelPrinted = true; 2749713SN/A } 27510572Sandreas.hansson@arm.com i++; 27610572Sandreas.hansson@arm.com } 2779713SN/A } 27810405Sandreas.hansson@arm.com} 27910405Sandreas.hansson@arm.com 2809715SN/A 28110405Sandreas.hansson@arm.comvoid 2828975SN/APacket::PrintReqState::printObj(Printable *obj) 2838975SN/A{ 2848975SN/A printLabels(); 2858975SN/A obj->print(os, verbosity, curPrefix()); 28610405Sandreas.hansson@arm.com} 2878975SN/A