packet.cc revision 3348
17735SN/A/* 27735SN/A * Copyright (c) 2006 The Regents of The University of Michigan 37735SN/A * All rights reserved. 49988Snilay@cs.wisc.edu * 58835SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 69988Snilay@cs.wisc.edu * modification, are permitted provided that the following conditions are 77935SN/A * met: redistributions of source code must retain the above copyright 87935SN/A * notice, this list of conditions and the following disclaimer; 97935SN/A * redistributions in binary form must reproduce the above copyright 107735SN/A * notice, this list of conditions and the following disclaimer in the 117735SN/A * documentation and/or other materials provided with the distribution; 127735SN/A * neither the name of the copyright holders nor the names of its 1310315Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from 1410513SAli.Saidi@ARM.com * this software without specific prior written permission. 1511570SCurtis.Dunham@arm.com * 1610513SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179885Sstever@gmail.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189885Sstever@gmail.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911570SCurtis.Dunham@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011570SCurtis.Dunham@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219055Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229481Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239988Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411312Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510513SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610513SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710038SAli.Saidi@ARM.com * 2811515Sandreas.sandberg@arm.com * Authors: Ali Saidi 2910038SAli.Saidi@ARM.com * Steve Reinhardt 3010038SAli.Saidi@ARM.com */ 3110038SAli.Saidi@ARM.com 327735SN/A/** 3311570SCurtis.Dunham@arm.com * @file 3410315Snilay@cs.wisc.edu * Definition of the Packet Class, a packet is a transaction occuring 357735SN/A * between a single level of the memory heirarchy (ie L1->L2). 3610513SAli.Saidi@ARM.com */ 3710513SAli.Saidi@ARM.com 387735SN/A#include <iostream> 3910513SAli.Saidi@ARM.com 4010636Snilay@cs.wisc.edu#include "base/misc.hh" 4110736Snilay@cs.wisc.edu#include "base/trace.hh" 429079SAli.Saidi@ARM.com#include "mem/packet.hh" 4311219Snilay@cs.wisc.edu 448721SN/Astatic const std::string ReadReqString("ReadReq"); 4511570SCurtis.Dunham@arm.comstatic const std::string WriteReqString("WriteReq"); 4611570SCurtis.Dunham@arm.comstatic const std::string WriteReqNoAckString("WriteReqNoAck|Writeback"); 4711570SCurtis.Dunham@arm.comstatic const std::string ReadRespString("ReadResp"); 489885Sstever@gmail.comstatic const std::string WriteRespString("WriteResp"); 499885Sstever@gmail.comstatic const std::string SoftPFReqString("SoftPFReq"); 5010038SAli.Saidi@ARM.comstatic const std::string SoftPFRespString("SoftPFResp"); 5111570SCurtis.Dunham@arm.comstatic const std::string HardPFReqString("HardPFReq"); 5211570SCurtis.Dunham@arm.comstatic const std::string HardPFRespString("HardPFResp"); 5310038SAli.Saidi@ARM.comstatic const std::string InvalidateReqString("InvalidateReq"); 547735SN/Astatic const std::string WriteInvalidateReqString("WriteInvalidateReq"); 5511440SCurtis.Dunham@arm.comstatic const std::string WriteInvalidateRespString("WriteInvalidateResp"); 5611440SCurtis.Dunham@arm.comstatic const std::string UpgradeReqString("UpgradeReq"); 577935SN/Astatic const std::string ReadExReqString("ReadExReq"); 587935SN/Astatic const std::string ReadExRespString("ReadExResp"); 597935SN/Astatic const std::string OtherCmdString("<other>"); 607935SN/A 617935SN/Aconst std::string & 627935SN/APacket::cmdString() const 637935SN/A{ 6410513SAli.Saidi@ARM.com switch (cmd) { 657735SN/A case ReadReq: return ReadReqString; 667735SN/A case WriteReq: return WriteReqString; 677735SN/A case WriteReqNoAck: return WriteReqNoAckString; 689885Sstever@gmail.com case ReadResp: return ReadRespString; 6911570SCurtis.Dunham@arm.com case WriteResp: return WriteRespString; 707735SN/A case SoftPFReq: return SoftPFReqString; 719988Snilay@cs.wisc.edu case SoftPFResp: return SoftPFRespString; 7211570SCurtis.Dunham@arm.com case HardPFReq: return HardPFReqString; 7311570SCurtis.Dunham@arm.com case HardPFResp: return HardPFRespString; 7411570SCurtis.Dunham@arm.com case InvalidateReq: return InvalidateReqString; 7511570SCurtis.Dunham@arm.com case WriteInvalidateReq:return WriteInvalidateReqString; 7610513SAli.Saidi@ARM.com case WriteInvalidateResp:return WriteInvalidateRespString; 778721SN/A case UpgradeReq: return UpgradeReqString; 788721SN/A case ReadExReq: return ReadExReqString; 798891SAli.Saidi@ARM.com case ReadExResp: return ReadExRespString; 808891SAli.Saidi@ARM.com default: return OtherCmdString; 817735SN/A } 828528SN/A} 838528SN/A 848528SN/Aconst std::string & 858528SN/APacket::cmdIdxToString(Packet::Command idx) 868528SN/A{ 879988Snilay@cs.wisc.edu switch (idx) { 888528SN/A case ReadReq: return ReadReqString; 898528SN/A case WriteReq: return WriteReqString; 908528SN/A case WriteReqNoAck: return WriteReqNoAckString; 918528SN/A case ReadResp: return ReadRespString; 928528SN/A case WriteResp: return WriteRespString; 938528SN/A case SoftPFReq: return SoftPFReqString; 949988Snilay@cs.wisc.edu case SoftPFResp: return SoftPFRespString; 958528SN/A case HardPFReq: return HardPFReqString; 968528SN/A case HardPFResp: return HardPFRespString; 978528SN/A case InvalidateReq: return InvalidateReqString; 988528SN/A case WriteInvalidateReq:return WriteInvalidateReqString; 998528SN/A case WriteInvalidateResp:return WriteInvalidateRespString; 1008528SN/A case UpgradeReq: return UpgradeReqString; 1019988Snilay@cs.wisc.edu case ReadExReq: return ReadExReqString; 10211570SCurtis.Dunham@arm.com case ReadExResp: return ReadExRespString; 1038528SN/A default: return OtherCmdString; 1048528SN/A } 1059885Sstever@gmail.com} 1069885Sstever@gmail.com 1079885Sstever@gmail.com/** delete the data pointed to in the data pointer. Ok to call to matter how 10810315Snilay@cs.wisc.edu * data was allocted. */ 1099988Snilay@cs.wisc.eduvoid 11010315Snilay@cs.wisc.eduPacket::deleteData() 1119885Sstever@gmail.com{ 1129885Sstever@gmail.com assert(staticData || dynamicData); 1137735SN/A if (staticData) 1147735SN/A return; 11510038SAli.Saidi@ARM.com 11610315Snilay@cs.wisc.edu if (arrayData) 1177735SN/A delete [] data; 1189885Sstever@gmail.com else 1197735SN/A delete data; 12011570SCurtis.Dunham@arm.com} 1217735SN/A 1227735SN/A/** If there isn't data in the packet, allocate some. */ 1237735SN/Avoid 12410038SAli.Saidi@ARM.comPacket::allocate() 1257735SN/A{ 1269988Snilay@cs.wisc.edu if (data) 1278983Snate@binkert.org return; 1287735SN/A assert(!staticData); 1297735SN/A dynamicData = true; 1307735SN/A arrayData = true; 1319481Snilay@cs.wisc.edu data = new uint8_t[getSize()]; 13210038SAli.Saidi@ARM.com} 1337735SN/A 1347735SN/A/** Do the packet modify the same addresses. */ 1357735SN/Abool 1367735SN/APacket::intersect(Packet *p) 1377735SN/A{ 1387735SN/A Addr s1 = getAddr(); 13911570SCurtis.Dunham@arm.com Addr e1 = getAddr() + getSize() - 1; 14011570SCurtis.Dunham@arm.com Addr s2 = p->getAddr(); 14111570SCurtis.Dunham@arm.com Addr e2 = p->getAddr() + p->getSize() - 1; 14211570SCurtis.Dunham@arm.com 1437735SN/A return !(s1 > e2 || e1 < s2); 1447735SN/A} 1459885Sstever@gmail.com 1467735SN/Abool 1477735SN/AfixPacket(Packet *func, Packet *timing) 14810315Snilay@cs.wisc.edu{ 1499481Snilay@cs.wisc.edu Addr funcStart = func->getAddr(); 1507735SN/A Addr funcEnd = func->getAddr() + func->getSize() - 1; 1517735SN/A Addr timingStart = timing->getAddr(); 1527735SN/A Addr timingEnd = timing->getAddr() + timing->getSize() - 1; 1538835SAli.Saidi@ARM.com 1547735SN/A assert(!(funcStart > timingEnd || timingStart < funcEnd)); 1557735SN/A 1567735SN/A if (DTRACE(FunctionalAccess)) { 1577735SN/A DebugOut() << func; 15811103Snilay@cs.wisc.edu DebugOut() << timing; 1599885Sstever@gmail.com } 1608891SAli.Saidi@ARM.com 1617735SN/A // this packet can't solve our problem, continue on 1629885Sstever@gmail.com if (!timing->hasData()) 16311219Snilay@cs.wisc.edu return true; 16411570SCurtis.Dunham@arm.com 16510636Snilay@cs.wisc.edu if (func->isRead()) { 1669988Snilay@cs.wisc.edu if (funcStart >= timingStart && funcEnd <= timingEnd) { 1679481Snilay@cs.wisc.edu func->allocate(); 16811014Sandreas.sandberg@arm.com memcpy(func->getPtr<uint8_t>(), timing->getPtr<uint8_t>() + 1697735SN/A funcStart - timingStart, func->getSize()); 1707735SN/A func->result = Packet::Success; 17111570SCurtis.Dunham@arm.com return false; 17211570SCurtis.Dunham@arm.com } else { 17311570SCurtis.Dunham@arm.com // In this case the timing packet only partially satisfies the 17411570SCurtis.Dunham@arm.com // requset, so we would need more information to make this work. 1757735SN/A // Like bytes valid in the packet or something, so the request could 1768835SAli.Saidi@ARM.com // continue and get this bit of possibly newer data along with the 1779481Snilay@cs.wisc.edu // older data not written to yet. 17810036SAli.Saidi@ARM.com panic("Timing packet only partially satisfies the functional" 1797735SN/A "request. Now what?"); 1808835SAli.Saidi@ARM.com } 1819885Sstever@gmail.com } else if (func->isWrite()) { 1829481Snilay@cs.wisc.edu if (funcStart >= timingStart) { 1837735SN/A memcpy(timing->getPtr<uint8_t>() + (funcStart - timingStart), 18411219Snilay@cs.wisc.edu func->getPtr<uint8_t>(), 1857735SN/A funcStart - std::min(funcEnd, timingEnd)); 1869481Snilay@cs.wisc.edu } else { // timingStart > funcStart 1877735SN/A memcpy(timing->getPtr<uint8_t>(), 1889885Sstever@gmail.com func->getPtr<uint8_t>() + (timingStart - funcStart), 1899885Sstever@gmail.com timingStart - std::min(funcEnd, timingEnd)); 1909885Sstever@gmail.com } 1919885Sstever@gmail.com // we always want to keep going with a write 1929885Sstever@gmail.com return true; 19311570SCurtis.Dunham@arm.com } else 1949988Snilay@cs.wisc.edu panic("Don't know how to handle command type %#x\n", 1959885Sstever@gmail.com func->cmdToIndex()); 19611570SCurtis.Dunham@arm.com 19711570SCurtis.Dunham@arm.com} 19811570SCurtis.Dunham@arm.com 19911570SCurtis.Dunham@arm.com 20010036SAli.Saidi@ARM.comstd::ostream & 2019885Sstever@gmail.comoperator<<(std::ostream &o, const Packet &p) 2029885Sstever@gmail.com{ 20310038SAli.Saidi@ARM.com 20410038SAli.Saidi@ARM.com o << "[0x"; 20510038SAli.Saidi@ARM.com o.setf(std::ios_base::hex, std::ios_base::showbase); 20610038SAli.Saidi@ARM.com o << p.getAddr(); 20710038SAli.Saidi@ARM.com o.unsetf(std::ios_base::hex| std::ios_base::showbase); 20810736Snilay@cs.wisc.edu o << ":"; 20910038SAli.Saidi@ARM.com o.setf(std::ios_base::hex, std::ios_base::showbase); 21010038SAli.Saidi@ARM.com o << p.getAddr() + p.getSize() - 1 << "] "; 21110038SAli.Saidi@ARM.com o.unsetf(std::ios_base::hex| std::ios_base::showbase); 21210038SAli.Saidi@ARM.com 21310038SAli.Saidi@ARM.com if (p.result == Packet::Success) 21410038SAli.Saidi@ARM.com o << "Successful "; 21510038SAli.Saidi@ARM.com if (p.result == Packet::BadAddress) 21610038SAli.Saidi@ARM.com o << "BadAddress "; 21710038SAli.Saidi@ARM.com if (p.result == Packet::Nacked) 21810038SAli.Saidi@ARM.com o << "Nacked "; 21910038SAli.Saidi@ARM.com if (p.result == Packet::Unknown) 22010038SAli.Saidi@ARM.com o << "Inflight "; 22110038SAli.Saidi@ARM.com 22211570SCurtis.Dunham@arm.com if (p.isRead()) 22310038SAli.Saidi@ARM.com o << "Read "; 22410038SAli.Saidi@ARM.com if (p.isWrite()) 22510038SAli.Saidi@ARM.com o << "Read "; 22611570SCurtis.Dunham@arm.com if (p.isInvalidate()) 22711570SCurtis.Dunham@arm.com o << "Read "; 22811570SCurtis.Dunham@arm.com if (p.isRequest()) 22911570SCurtis.Dunham@arm.com o << "Request "; 23010038SAli.Saidi@ARM.com if (p.isResponse()) 23110038SAli.Saidi@ARM.com o << "Response "; 2327735SN/A if (p.hasData()) 2337735SN/A o << "w/Data "; 2347735SN/A 2359988Snilay@cs.wisc.edu o << std::endl; 23610038SAli.Saidi@ARM.com return o; 2377735SN/A} 2387735SN/A 2397735SN/A