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