packet.cc revision 3335:71bef174e59f
19243SN/A/* 210206Sandreas.hansson@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 39243SN/A * All rights reserved. 49243SN/A * 59243SN/A * Redistribution and use in source and binary forms, with or without 69243SN/A * modification, are permitted provided that the following conditions are 79243SN/A * met: redistributions of source code must retain the above copyright 89243SN/A * notice, this list of conditions and the following disclaimer; 99243SN/A * redistributions in binary form must reproduce the above copyright 109243SN/A * notice, this list of conditions and the following disclaimer in the 119243SN/A * documentation and/or other materials provided with the distribution; 129243SN/A * neither the name of the copyright holders nor the names of its 139243SN/A * contributors may be used to endorse or promote products derived from 149831SN/A * this software without specific prior written permission. 159831SN/A * 169831SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179243SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189243SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199243SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209243SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219243SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229243SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239243SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249243SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259243SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269243SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279243SN/A * 289243SN/A * Authors: Ali Saidi 299243SN/A * Steve Reinhardt 309243SN/A */ 319243SN/A 329243SN/A/** 339243SN/A * @file 349243SN/A * Definition of the Packet Class, a packet is a transaction occuring 359243SN/A * between a single level of the memory heirarchy (ie L1->L2). 369243SN/A */ 379243SN/A 389243SN/A#include <iostream> 399243SN/A#include "base/misc.hh" 409243SN/A#include "mem/packet.hh" 419243SN/A#include "base/trace.hh" 429967SN/A 4310618SOmar.Naji@arm.comstatic const std::string ReadReqString("ReadReq"); 449243SN/Astatic const std::string WriteReqString("WriteReq"); 459243SN/Astatic const std::string WriteReqNoAckString("WriteReqNoAck|Writeback"); 4610146Sandreas.hansson@arm.comstatic const std::string ReadRespString("ReadResp"); 479356SN/Astatic const std::string WriteRespString("WriteResp"); 4810146Sandreas.hansson@arm.comstatic const std::string SoftPFReqString("SoftPFReq"); 4910247Sandreas.hansson@arm.comstatic const std::string SoftPFRespString("SoftPFResp"); 5010208Sandreas.hansson@arm.comstatic const std::string HardPFReqString("HardPFReq"); 519352SN/Astatic const std::string HardPFRespString("HardPFResp"); 5210146Sandreas.hansson@arm.comstatic const std::string InvalidateReqString("InvalidateReq"); 539814SN/Astatic const std::string WriteInvalidateReqString("WriteInvalidateReq"); 549243SN/Astatic const std::string WriteInvalidateRespString("WriteInvalidateResp"); 559243SN/Astatic const std::string UpgradeReqString("UpgradeReq"); 5610432SOmar.Naji@arm.comstatic const std::string ReadExReqString("ReadExReq"); 579243SN/Astatic const std::string ReadExRespString("ReadExResp"); 5810146Sandreas.hansson@arm.comstatic const std::string OtherCmdString("<other>"); 599243SN/A 6010619Sandreas.hansson@arm.comconst std::string & 619243SN/APacket::cmdString() const 6210211Sandreas.hansson@arm.com{ 6310618SOmar.Naji@arm.com switch (cmd) { 6410208Sandreas.hansson@arm.com case ReadReq: return ReadReqString; 6510489SOmar.Naji@arm.com case WriteReq: return WriteReqString; 669831SN/A case WriteReqNoAck: return WriteReqNoAckString; 679831SN/A case ReadResp: return ReadRespString; 689831SN/A case WriteResp: return WriteRespString; 699831SN/A case SoftPFReq: return SoftPFReqString; 709831SN/A case SoftPFResp: return SoftPFRespString; 7110140SN/A case HardPFReq: return HardPFReqString; 7210286Sandreas.hansson@arm.com case HardPFResp: return HardPFRespString; 739243SN/A case InvalidateReq: return InvalidateReqString; 7410394Swendy.elsasser@arm.com case WriteInvalidateReq:return WriteInvalidateReqString; 7510394Swendy.elsasser@arm.com case WriteInvalidateResp:return WriteInvalidateRespString; 769566SN/A case UpgradeReq: return UpgradeReqString; 779243SN/A case ReadExReq: return ReadExReqString; 789243SN/A case ReadExResp: return ReadExRespString; 7910140SN/A default: return OtherCmdString; 8010140SN/A } 8110147Sandreas.hansson@arm.com} 8210147Sandreas.hansson@arm.com 8310393Swendy.elsasser@arm.comconst std::string & 8410394Swendy.elsasser@arm.comPacket::cmdIdxToString(Packet::Command idx) 8510394Swendy.elsasser@arm.com{ 8610394Swendy.elsasser@arm.com switch (idx) { 879243SN/A case ReadReq: return ReadReqString; 889243SN/A case WriteReq: return WriteReqString; 8910141SN/A case WriteReqNoAck: return WriteReqNoAckString; 909726SN/A case ReadResp: return ReadRespString; 919726SN/A case WriteResp: return WriteRespString; 9210618SOmar.Naji@arm.com case SoftPFReq: return SoftPFReqString; 9310618SOmar.Naji@arm.com case SoftPFResp: return SoftPFRespString; 949243SN/A case HardPFReq: return HardPFReqString; 9510620Sandreas.hansson@arm.com case HardPFResp: return HardPFRespString; 9610620Sandreas.hansson@arm.com case InvalidateReq: return InvalidateReqString; 9710620Sandreas.hansson@arm.com case WriteInvalidateReq:return WriteInvalidateReqString; 9810620Sandreas.hansson@arm.com case WriteInvalidateResp:return WriteInvalidateRespString; 9910620Sandreas.hansson@arm.com case UpgradeReq: return UpgradeReqString; 10010618SOmar.Naji@arm.com case ReadExReq: return ReadExReqString; 10110618SOmar.Naji@arm.com case ReadExResp: return ReadExRespString; 10210618SOmar.Naji@arm.com default: return OtherCmdString; 10310432SOmar.Naji@arm.com } 10410618SOmar.Naji@arm.com} 10510618SOmar.Naji@arm.com 10610618SOmar.Naji@arm.com/** delete the data pointed to in the data pointer. Ok to call to matter how 10710432SOmar.Naji@arm.com * data was allocted. */ 10810246Sandreas.hansson@arm.comvoid 10910618SOmar.Naji@arm.comPacket::deleteData() 11010561SOmar.Naji@arm.com{ 11110561SOmar.Naji@arm.com assert(staticData || dynamicData); 11210561SOmar.Naji@arm.com if (staticData) 11310394Swendy.elsasser@arm.com return; 11410394Swendy.elsasser@arm.com 11510394Swendy.elsasser@arm.com if (arrayData) 11610394Swendy.elsasser@arm.com delete [] data; 11710394Swendy.elsasser@arm.com else 11810394Swendy.elsasser@arm.com delete data; 11910394Swendy.elsasser@arm.com} 12010394Swendy.elsasser@arm.com 12110618SOmar.Naji@arm.com/** If there isn't data in the packet, allocate some. */ 12210394Swendy.elsasser@arm.comvoid 12310394Swendy.elsasser@arm.comPacket::allocate() 12410618SOmar.Naji@arm.com{ 12510394Swendy.elsasser@arm.com if (data) 12610246Sandreas.hansson@arm.com return; 12710246Sandreas.hansson@arm.com assert(!staticData); 12810246Sandreas.hansson@arm.com dynamicData = true; 12910140SN/A arrayData = true; 13010140SN/A data = new uint8_t[getSize()]; 13110140SN/A} 13210140SN/A 13310140SN/A/** Do the packet modify the same addresses. */ 1349243SN/Abool 1359243SN/APacket::intersect(Packet *p) 1369567SN/A{ 1379243SN/A Addr s1 = getAddr(); 13810489SOmar.Naji@arm.com Addr e1 = getAddr() + getSize() - 1; 13910489SOmar.Naji@arm.com Addr s2 = p->getAddr(); 14010489SOmar.Naji@arm.com Addr e2 = p->getAddr() + p->getSize() - 1; 14110489SOmar.Naji@arm.com 14210489SOmar.Naji@arm.com return !(s1 > e2 || e1 < s2); 14310489SOmar.Naji@arm.com} 14410489SOmar.Naji@arm.com 14510489SOmar.Naji@arm.combool 14610489SOmar.Naji@arm.comfixPacket(Packet *func, Packet *timing) 14710489SOmar.Naji@arm.com{ 1489243SN/A Addr funcStart = func->getAddr(); 1499243SN/A Addr funcEnd = func->getAddr() + func->getSize() - 1; 1509831SN/A Addr timingStart = timing->getAddr(); 1519831SN/A Addr timingEnd = timing->getAddr() + timing->getSize() - 1; 1529831SN/A 1539831SN/A assert(!(funcStart > timingEnd || timingStart < funcEnd)); 1549831SN/A 1559243SN/A if (DTRACE(FunctionalAccess)) { 15610286Sandreas.hansson@arm.com DebugOut() << func; 1579566SN/A DebugOut() << timing; 1589566SN/A } 15910143SN/A 1609566SN/A // this packet can't solve our problem, continue on 1619566SN/A if (!timing->hasData()) 16210136SN/A return true; 1639831SN/A 16410286Sandreas.hansson@arm.com if (func->isRead()) { 16510136SN/A if (funcStart >= timingStart && funcEnd <= timingEnd) { 1669566SN/A func->allocate(); 16710286Sandreas.hansson@arm.com memcpy(func->getPtr<uint8_t>(), timing->getPtr<uint8_t>() + 16810286Sandreas.hansson@arm.com funcStart - timingStart, func->getSize()); 16910286Sandreas.hansson@arm.com func->result = Packet::Success; 17010286Sandreas.hansson@arm.com return false; 17110286Sandreas.hansson@arm.com } else { 17210286Sandreas.hansson@arm.com // In this case the timing packet only partially satisfies the 17310286Sandreas.hansson@arm.com // requset, so we would need more information to make this work. 17410286Sandreas.hansson@arm.com // Like bytes valid in the packet or something, so the request could 17510286Sandreas.hansson@arm.com // continue and get this bit of possibly newer data along with the 17610286Sandreas.hansson@arm.com // older data not written to yet. 17710286Sandreas.hansson@arm.com panic("Timing packet only partially satisfies the functional" 17810286Sandreas.hansson@arm.com "request. Now what?"); 17910286Sandreas.hansson@arm.com } 18010286Sandreas.hansson@arm.com } else if (func->isWrite()) { 18110286Sandreas.hansson@arm.com if (funcStart >= timingStart) { 18210286Sandreas.hansson@arm.com memcpy(timing->getPtr<uint8_t>() + (funcStart - timingStart), 1839669SN/A func->getPtr<uint8_t>(), 18410286Sandreas.hansson@arm.com funcStart - std::min(funcEnd, timingEnd)); 18510286Sandreas.hansson@arm.com } else { // timingStart > funcStart 18610286Sandreas.hansson@arm.com memcpy(timing->getPtr<uint8_t>(), 18710286Sandreas.hansson@arm.com func->getPtr<uint8_t>() + (timingStart - funcStart), 18810286Sandreas.hansson@arm.com timingStart - std::min(funcEnd, timingEnd)); 18910286Sandreas.hansson@arm.com } 19010286Sandreas.hansson@arm.com // we always want to keep going with a write 19110286Sandreas.hansson@arm.com return true; 1929566SN/A } else 1939566SN/A panic("Don't know how to handle command type %#x\n", 19410207Sandreas.hansson@arm.com func->cmdToIndex()); 19510207Sandreas.hansson@arm.com 19610207Sandreas.hansson@arm.com} 19710207Sandreas.hansson@arm.com 19810207Sandreas.hansson@arm.com 19910207Sandreas.hansson@arm.comstd::ostream & 20010394Swendy.elsasser@arm.comoperator<<(std::ostream &o, const Packet &p) 20110394Swendy.elsasser@arm.com{ 20210394Swendy.elsasser@arm.com 20310394Swendy.elsasser@arm.com o << "[0x"; 20410394Swendy.elsasser@arm.com o.setf(std::ios_base::hex, std::ios_base::showbase); 20510394Swendy.elsasser@arm.com o << p.getAddr(); 20610394Swendy.elsasser@arm.com o.unsetf(std::ios_base::hex| std::ios_base::showbase); 20710394Swendy.elsasser@arm.com o << ":"; 20810394Swendy.elsasser@arm.com o.setf(std::ios_base::hex, std::ios_base::showbase); 20910394Swendy.elsasser@arm.com o << p.getAddr() + p.getSize() - 1 << "] "; 21010394Swendy.elsasser@arm.com o.unsetf(std::ios_base::hex| std::ios_base::showbase); 21110394Swendy.elsasser@arm.com 21210394Swendy.elsasser@arm.com if (p.result == Packet::Success) 21310394Swendy.elsasser@arm.com o << "Successful "; 21410394Swendy.elsasser@arm.com if (p.result == Packet::BadAddress) 21510394Swendy.elsasser@arm.com o << "BadAddress "; 21610394Swendy.elsasser@arm.com if (p.result == Packet::Nacked) 21710394Swendy.elsasser@arm.com o << "Nacked "; 21810394Swendy.elsasser@arm.com if (p.result == Packet::Unknown) 21910394Swendy.elsasser@arm.com o << "Inflight "; 22010394Swendy.elsasser@arm.com 22110394Swendy.elsasser@arm.com if (p.isRead()) 22210561SOmar.Naji@arm.com o << "Read "; 22310561SOmar.Naji@arm.com if (p.isWrite()) 22410394Swendy.elsasser@arm.com o << "Read "; 22510394Swendy.elsasser@arm.com if (p.isInvalidate()) 22610394Swendy.elsasser@arm.com o << "Read "; 22710394Swendy.elsasser@arm.com if (p.isRequest()) 22810394Swendy.elsasser@arm.com o << "Request "; 22910394Swendy.elsasser@arm.com if (p.isResponse()) 2309243SN/A o << "Response "; 2319243SN/A if (p.hasData()) 2329243SN/A o << "w/Data "; 23310146Sandreas.hansson@arm.com 23410140SN/A o << std::endl; 23510466Sandreas.hansson@arm.com return o; 23610466Sandreas.hansson@arm.com} 23710466Sandreas.hansson@arm.com 23810146Sandreas.hansson@arm.com