/*
 * Copyright (c) 2011-2019 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * Copyright (c) 2010,2015 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 * Definition of the Packet Class, a packet is a transaction occuring
 * between a single level of the memory heirarchy (ie L1->L2).
 */

#include "mem/packet.hh"

#include <algorithm>
#include <cstring>
#include <iostream>
#include <sstream>
#include <string>

#include "base/cprintf.hh"
#include "base/logging.hh"
#include "base/trace.hh"
#include "mem/packet_access.hh"

namespace gem5
{

const MemCmd::CommandInfo
MemCmd::commandInfo[] =
{
    /* InvalidCmd */
    { {}, InvalidCmd, "InvalidCmd" },
    /* ReadReq - Read issued by a non-caching agent such as a CPU or
     * device, with no restrictions on alignment. */
    { {IsRead, IsRequest, NeedsResponse}, ReadResp, "ReadReq" },
    /* ReadResp */
    { {IsRead, IsResponse, HasData}, InvalidCmd, "ReadResp" },
    /* ReadRespWithInvalidate */
    { {IsRead, IsResponse, HasData, IsInvalidate},
            InvalidCmd, "ReadRespWithInvalidate" },
    /* WriteReq */
    { {IsWrite, NeedsWritable, IsRequest, NeedsResponse, HasData},
            WriteResp, "WriteReq" },
    /* WriteResp */
    { {IsWrite, IsResponse}, InvalidCmd, "WriteResp" },
    /* WriteCompleteResp - The WriteCompleteResp command is needed
     * because in the GPU memory model we use a WriteResp to indicate
     * that a write has reached the cache controller so we can free
     * resources at the coalescer. Later, when the write succesfully
     * completes we send a WriteCompleteResp to the CU so its wait
     * counters can be updated. Wait counters in the CU is how memory
     * dependences are handled in the GPU ISA. */
    { {IsWrite, IsResponse}, InvalidCmd, "WriteCompleteResp" },
    /* WritebackDirty */
    { {IsWrite, IsRequest, IsEviction, HasData, FromCache},
            InvalidCmd, "WritebackDirty" },
    /* WritebackClean - This allows the upstream cache to writeback a
     * line to the downstream cache without it being considered
     * dirty. */
    { {IsWrite, IsRequest, IsEviction, HasData, FromCache},
            InvalidCmd, "WritebackClean" },
    /* WriteClean - This allows a cache to write a dirty block to a memory
       below without evicting its copy. */
    { {IsWrite, IsRequest, HasData, FromCache}, InvalidCmd, "WriteClean" },
    /* CleanEvict */
    { {IsRequest, IsEviction, FromCache}, InvalidCmd, "CleanEvict" },
    /* SoftPFReq */
    { {IsRead, IsRequest, IsSWPrefetch, NeedsResponse},
            SoftPFResp, "SoftPFReq" },
    /* SoftPFExReq */
    { {IsRead, NeedsWritable, IsInvalidate, IsRequest,
           IsSWPrefetch, NeedsResponse}, SoftPFResp, "SoftPFExReq" },
    /* HardPFReq */
    { {IsRead, IsRequest, IsHWPrefetch, NeedsResponse, FromCache},
            HardPFResp, "HardPFReq" },
    /* SoftPFResp */
    { {IsRead, IsResponse, IsSWPrefetch, HasData}, InvalidCmd, "SoftPFResp" },
    /* HardPFResp */
    { {IsRead, IsResponse, IsHWPrefetch, HasData}, InvalidCmd, "HardPFResp" },
    /* WriteLineReq */
    { {IsWrite, NeedsWritable, IsRequest, NeedsResponse, HasData},
            WriteResp, "WriteLineReq" },
    /* UpgradeReq */
    { {IsInvalidate, NeedsWritable, IsUpgrade, IsRequest, NeedsResponse,
            FromCache}, UpgradeResp, "UpgradeReq" },
    /* SCUpgradeReq: response could be UpgradeResp or UpgradeFailResp */
    { {IsInvalidate, NeedsWritable, IsUpgrade, IsLlsc,
           IsRequest, NeedsResponse, FromCache},
            UpgradeResp, "SCUpgradeReq" },
    /* UpgradeResp */
    { {IsUpgrade, IsResponse}, InvalidCmd, "UpgradeResp" },
    /* SCUpgradeFailReq: generates UpgradeFailResp but still gets the data */
    { {IsRead, NeedsWritable, IsInvalidate,
           IsLlsc, IsRequest, NeedsResponse, FromCache},
            UpgradeFailResp, "SCUpgradeFailReq" },
    /* UpgradeFailResp - Behaves like a ReadExReq, but notifies an SC
     * that it has failed, acquires line as Dirty*/
    { {IsRead, IsResponse, HasData}, InvalidCmd, "UpgradeFailResp" },
    /* ReadExReq - Read issues by a cache, always cache-line aligned,
     * and the response is guaranteed to be writeable (exclusive or
     * even modified} */
    { {IsRead, NeedsWritable, IsInvalidate, IsRequest, NeedsResponse,
          FromCache}, ReadExResp, "ReadExReq" },
    /* ReadExResp - Response matching a read exclusive, as we check
     * the need for exclusive also on responses */
    { {IsRead, IsResponse, HasData}, InvalidCmd, "ReadExResp" },
    /* ReadCleanReq - Read issued by a cache, always cache-line
     * aligned, and the response is guaranteed to not contain dirty data
     * (exclusive or shared}.*/
    { {IsRead, IsRequest, NeedsResponse, FromCache},
            ReadResp, "ReadCleanReq" },
    /* ReadSharedReq - Read issued by a cache, always cache-line
     * aligned, response is shared, possibly exclusive, owned or even
     * modified. */
    { {IsRead, IsRequest, NeedsResponse, FromCache},
            ReadResp, "ReadSharedReq" },
    /* LoadLockedReq: note that we use plain ReadResp as response, so that
     *                we can also use ReadRespWithInvalidate when needed */
    { {IsRead, IsLlsc, IsRequest, NeedsResponse},
            ReadResp, "LoadLockedReq" },
    /* StoreCondReq */
    { {IsWrite, NeedsWritable, IsLlsc,
           IsRequest, NeedsResponse, HasData},
            StoreCondResp, "StoreCondReq" },
    /* StoreCondFailReq: generates failing StoreCondResp */
    { {IsWrite, NeedsWritable, IsLlsc, IsRequest, NeedsResponse, HasData},
            StoreCondResp, "StoreCondFailReq" },
    /* StoreCondResp */
    { {IsWrite, IsLlsc, IsResponse},
            InvalidCmd, "StoreCondResp" },
    /* LockedRMWReadReq */
    { {IsRead, IsLockedRMW, NeedsWritable, IsRequest, NeedsResponse},
            LockedRMWReadResp, "LockedRMWReadReq" },
    /* LockedRMWReadResp */
    { {IsRead, IsLockedRMW, NeedsWritable, IsResponse, HasData},
            InvalidCmd, "LockedRMWReadResp" },
    /* LockedRMWWriteReq */
    { {IsWrite, IsLockedRMW, NeedsWritable, IsRequest, NeedsResponse,
           HasData}, LockedRMWWriteResp, "LockedRMWWriteReq" },
    /* LockedRMWWriteResp */
    { {IsWrite, IsLockedRMW, NeedsWritable, IsResponse},
            InvalidCmd, "LockedRMWWriteResp" },
    /* SwapReq -- for Swap ldstub type operations */
    { {IsRead, IsWrite, NeedsWritable, IsRequest, HasData, NeedsResponse},
        SwapResp, "SwapReq" },
    /* SwapResp -- for Swap ldstub type operations */
    { {IsRead, IsWrite, IsResponse, HasData}, InvalidCmd, "SwapResp" },
    { {}, InvalidCmd, "Deprecated_MessageReq" },
    { {}, InvalidCmd, "Deprecated_MessageResp" },
    /* MemFenceReq -- for synchronization requests */
    {{IsRequest, NeedsResponse}, MemFenceResp, "MemFenceReq"},
    /* MemSyncReq */
    {{IsRequest, NeedsResponse}, MemSyncResp, "MemSyncReq"},
    /* MemSyncResp */
    {{IsResponse}, InvalidCmd, "MemSyncResp"},
    /* MemFenceResp -- for synchronization responses */
    {{IsResponse}, InvalidCmd, "MemFenceResp"},
    /* Cache Clean Request -- Update with the latest data all existing
       copies of the block down to the point indicated by the
       request */
    { {IsRequest, IsClean, NeedsResponse, FromCache},
      CleanSharedResp, "CleanSharedReq" },
    /* Cache Clean Response - Indicates that all caches up to the
       specified point of reference have a up-to-date copy of the
       cache block or no copy at all */
    { {IsResponse, IsClean}, InvalidCmd, "CleanSharedResp" },
    /* Cache Clean and Invalidate Request -- Invalidate all existing
       copies down to the point indicated by the request */
    { {IsRequest, IsInvalidate, IsClean, NeedsResponse, FromCache},
      CleanInvalidResp, "CleanInvalidReq" },
     /* Cache Clean and Invalidate Respose -- Indicates that no cache
        above the specified point holds the block and that the block
        was written to a memory below the specified point. */
    { {IsResponse, IsInvalidate, IsClean},
      InvalidCmd, "CleanInvalidResp" },
    /* InvalidDestError  -- packet dest field invalid */
    { {IsResponse, IsError}, InvalidCmd, "InvalidDestError" },
    /* BadAddressError   -- memory address invalid */
    { {IsResponse, IsError}, InvalidCmd, "BadAddressError" },
    /* FunctionalReadError */
    { {IsRead, IsResponse, IsError}, InvalidCmd, "FunctionalReadError" },
    /* FunctionalWriteError */
    { {IsWrite, IsResponse, IsError}, InvalidCmd, "FunctionalWriteError" },
    /* PrintReq */
    { {IsRequest, IsPrint}, InvalidCmd, "PrintReq" },
    /* Flush Request */
    { {IsRequest, IsFlush, NeedsWritable}, InvalidCmd, "FlushReq" },
    /* Invalidation Request */
    { {IsInvalidate, IsRequest, NeedsWritable, NeedsResponse, FromCache},
      InvalidateResp, "InvalidateReq" },
    /* Invalidation Response */
    { {IsInvalidate, IsResponse},
      InvalidCmd, "InvalidateResp" },
      // hardware transactional memory
    { {IsRead, IsRequest, NeedsResponse}, HTMReqResp, "HTMReq" },
    { {IsRead, IsResponse}, InvalidCmd, "HTMReqResp" },
    { {IsRead, IsRequest}, InvalidCmd, "HTMAbort" },
};

AddrRange
Packet::getAddrRange() const
{
    return RangeSize(getAddr(), getSize());
}

bool
Packet::trySatisfyFunctional(Printable *obj, Addr addr, bool is_secure, int size,
                        uint8_t *_data)
{
    const Addr func_start = getAddr();
    const Addr func_end   = getAddr() + getSize() - 1;
    const Addr val_start  = addr;
    const Addr val_end    = val_start + size - 1;

    if (is_secure != _isSecure || func_start > val_end ||
        val_start > func_end) {
        // no intersection
        return false;
    }

    // check print first since it doesn't require data
    if (isPrint()) {
        assert(!_data);
        safe_cast<PrintReqState*>(senderState)->printObj(obj);
        return false;
    }

    // we allow the caller to pass NULL to signify the other packet
    // has no data
    if (!_data) {
        return false;
    }

    const Addr val_offset = func_start > val_start ?
        func_start - val_start : 0;
    const Addr func_offset = func_start < val_start ?
        val_start - func_start : 0;
    const Addr overlap_size = std::min(val_end, func_end)+1 -
        std::max(val_start, func_start);

    if (isRead()) {
        std::memcpy(getPtr<uint8_t>() + func_offset,
               _data + val_offset,
               overlap_size);

        // initialise the tracking of valid bytes if we have not
        // used it already
        if (bytesValid.empty())
            bytesValid.resize(getSize(), false);

        // track if we are done filling the functional access
        bool all_bytes_valid = true;

        int i = 0;

        // check up to func_offset
        for (; all_bytes_valid && i < func_offset; ++i)
            all_bytes_valid &= bytesValid[i];

        // update the valid bytes
        for (i = func_offset; i < func_offset + overlap_size; ++i)
            bytesValid[i] = true;

        // check the bit after the update we just made
        for (; all_bytes_valid && i < getSize(); ++i)
            all_bytes_valid &= bytesValid[i];

        return all_bytes_valid;
    } else if (isWrite()) {
        std::memcpy(_data + val_offset,
               getConstPtr<uint8_t>() + func_offset,
               overlap_size);
    } else {
        panic("Don't know how to handle command %s\n", cmdString());
    }

    // keep going with request by default
    return false;
}

void
Packet::copyResponderFlags(const PacketPtr pkt)
{
    assert(isRequest());
    // If we have already found a responder, no other cache should
    // commit to responding
    assert(!pkt->cacheResponding() || !cacheResponding());
    flags.set(pkt->flags & RESPONDER_FLAGS);
}

void
Packet::pushSenderState(Packet::SenderState *sender_state)
{
    assert(sender_state != NULL);
    sender_state->predecessor = senderState;
    senderState = sender_state;
}

Packet::SenderState *
Packet::popSenderState()
{
    assert(senderState != NULL);
    SenderState *sender_state = senderState;
    senderState = sender_state->predecessor;
    sender_state->predecessor = NULL;
    return sender_state;
}

uint64_t
Packet::getUintX(ByteOrder endian) const
{
    switch(getSize()) {
      case 1:
        return (uint64_t)get<uint8_t>(endian);
      case 2:
        return (uint64_t)get<uint16_t>(endian);
      case 4:
        return (uint64_t)get<uint32_t>(endian);
      case 8:
        return (uint64_t)get<uint64_t>(endian);
      default:
        panic("%i isn't a supported word size.\n", getSize());
    }
}

void
Packet::setUintX(uint64_t w, ByteOrder endian)
{
    switch(getSize()) {
      case 1:
        set<uint8_t>((uint8_t)w, endian);
        break;
      case 2:
        set<uint16_t>((uint16_t)w, endian);
        break;
      case 4:
        set<uint32_t>((uint32_t)w, endian);
        break;
      case 8:
        set<uint64_t>((uint64_t)w, endian);
        break;
      default:
        panic("%i isn't a supported word size.\n", getSize());
    }

}

void
Packet::print(std::ostream &o, const int verbosity,
              const std::string &prefix) const
{
    ccprintf(o, "%s%s [%x:%x]%s%s%s%s%s%s", prefix, cmdString(),
             getAddr(), getAddr() + getSize() - 1,
             req->isSecure() ? " (s)" : "",
             req->isInstFetch() ? " IF" : "",
             req->isUncacheable() ? " UC" : "",
             isExpressSnoop() ? " ES" : "",
             req->isToPOC() ? " PoC" : "",
             req->isToPOU() ? " PoU" : "");
}

std::string
Packet::print() const {
    std::ostringstream str;
    print(str);
    return str.str();
}

bool
Packet::matchBlockAddr(const Addr addr, const bool is_secure,
                       const int blk_size) const
{
    return (getBlockAddr(blk_size) == addr) && (isSecure() == is_secure);
}

bool
Packet::matchBlockAddr(const PacketPtr pkt, const int blk_size) const
{
    return matchBlockAddr(pkt->getBlockAddr(blk_size), pkt->isSecure(),
                          blk_size);
}

bool
Packet::matchAddr(const Addr addr, const bool is_secure) const
{
    return (getAddr() == addr) && (isSecure() == is_secure);
}

bool
Packet::matchAddr(const PacketPtr pkt) const
{
    return matchAddr(pkt->getAddr(), pkt->isSecure());
}

Packet::PrintReqState::PrintReqState(std::ostream &_os, int _verbosity)
    : curPrefixPtr(new std::string("")), os(_os), verbosity(_verbosity)
{
    labelStack.push_back(LabelStackEntry("", curPrefixPtr));
}

Packet::PrintReqState::~PrintReqState()
{
    labelStack.pop_back();
    assert(labelStack.empty());
    delete curPrefixPtr;
}

Packet::PrintReqState::
LabelStackEntry::LabelStackEntry(const std::string &_label,
                                 std::string *_prefix)
    : label(_label), prefix(_prefix), labelPrinted(false)
{
}

void
Packet::PrintReqState::pushLabel(const std::string &lbl,
                                 const std::string &prefix)
{
    labelStack.push_back(LabelStackEntry(lbl, curPrefixPtr));
    curPrefixPtr = new std::string(*curPrefixPtr);
    *curPrefixPtr += prefix;
}

void
Packet::PrintReqState::popLabel()
{
    delete curPrefixPtr;
    curPrefixPtr = labelStack.back().prefix;
    labelStack.pop_back();
    assert(!labelStack.empty());
}

void
Packet::PrintReqState::printLabels()
{
    if (!labelStack.back().labelPrinted) {
        LabelStack::iterator i = labelStack.begin();
        LabelStack::iterator end = labelStack.end();
        while (i != end) {
            if (!i->labelPrinted) {
                ccprintf(os, "%s%s\n", *(i->prefix), i->label);
                i->labelPrinted = true;
            }
            i++;
        }
    }
}


void
Packet::PrintReqState::printObj(Printable *obj)
{
    printLabels();
    obj->print(os, verbosity, curPrefix());
}

void
Packet::makeHtmTransactionalReqResponse(
    const HtmCacheFailure htm_return_code)
{
    assert(needsResponse());
    assert(isRequest());

    cmd = cmd.responseCommand();

    setHtmTransactionFailedInCache(htm_return_code);

    // responses are never express, even if the snoop that
    // triggered them was
    flags.clear(EXPRESS_SNOOP);
}

void
Packet::setHtmTransactionFailedInCache(
    const HtmCacheFailure htm_return_code)
{
    if (htm_return_code != HtmCacheFailure::NO_FAIL)
        flags.set(FAILS_TRANSACTION);

    htmReturnReason = htm_return_code;
}

bool
Packet::htmTransactionFailedInCache() const
{
    return flags.isSet(FAILS_TRANSACTION);
}

HtmCacheFailure
Packet::getHtmTransactionFailedInCacheRC() const
{
    assert(htmTransactionFailedInCache());
    return htmReturnReason;
}

void
Packet::setHtmTransactional(uint64_t htm_uid)
{
    flags.set(FROM_TRANSACTION);
    htmTransactionUid = htm_uid;
}

bool
Packet::isHtmTransactional() const
{
    return flags.isSet(FROM_TRANSACTION);
}

uint64_t
Packet::getHtmTransactionUid() const
{
    assert(flags.isSet(FROM_TRANSACTION));
    return htmTransactionUid;
}

} // namespace gem5
