/*
 * Copyright (c) 2012-2013, 2015-2017 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) 2002-2005 The Regents of The University of Michigan
 * Copyright (c) 2010 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.
 *
 * Authors: Erik Hallnor
 *          Dave Greene
 *          Andreas Hansson
 */

/**
 * @file
 * Miss Status and Handling Register (WriteQueueEntry) definitions.
 */

#include "mem/cache/write_queue_entry.hh"

#include <algorithm>
#include <cassert>
#include <string>
#include <vector>

#include "base/logging.hh"
#include "base/types.hh"
#include "debug/Cache.hh"
#include "mem/cache/cache.hh"
#include "sim/core.hh"

using namespace std;

inline void
WriteQueueEntry::TargetList::add(PacketPtr pkt, Tick readyTime,
                                 Counter order)
{
    emplace_back(pkt, readyTime, order);
}

bool
WriteQueueEntry::TargetList::checkFunctional(PacketPtr pkt)
{
    for (auto& t : *this) {
        if (pkt->checkFunctional(t.pkt)) {
            return true;
        }
    }

    return false;
}

void
WriteQueueEntry::TargetList::print(std::ostream &os, int verbosity,
                                   const std::string &prefix) const
{
    for (auto& t : *this) {
        ccprintf(os, "%sFromCPU: ", prefix);
        t.pkt->print(os, verbosity, "");
    }
}

void
WriteQueueEntry::allocate(Addr blk_addr, unsigned blk_size, PacketPtr target,
                          Tick when_ready, Counter _order)
{
    blkAddr = blk_addr;
    blkSize = blk_size;
    isSecure = target->isSecure();
    readyTime = when_ready;
    order = _order;
    assert(target);
    _isUncacheable = target->req->isUncacheable();
    inService = false;

    // we should never have more than a single target for cacheable
    // writes (writebacks and clean evictions)
    panic_if(!_isUncacheable && !targets.empty(),
             "Write queue entry %#llx should never have more than one "
             "cacheable target", blkAddr);
    panic_if(!((target->isWrite() && _isUncacheable) ||
               (target->isEviction() && !_isUncacheable) ||
               target->cmd == MemCmd::WriteClean),
             "Write queue entry %#llx should be an uncacheable write or "
             "a cacheable eviction or a writeclean");

    targets.add(target, when_ready, _order);
}

void
WriteQueueEntry::deallocate()
{
    assert(targets.empty());
    inService = false;
}

bool
WriteQueueEntry::checkFunctional(PacketPtr pkt)
{
    // For printing, we treat the WriteQueueEntry as a whole as single
    // entity. For other requests, we iterate over the individual
    // targets since that's where the actual data lies.
    if (pkt->isPrint()) {
        pkt->checkFunctional(this, blkAddr, isSecure, blkSize, nullptr);
        return false;
    } else {
        return targets.checkFunctional(pkt);
    }
}

bool
WriteQueueEntry::sendPacket(Cache &cache)
{
    return cache.sendWriteQueuePacket(this);
}

void
WriteQueueEntry::print(std::ostream &os, int verbosity,
                       const std::string &prefix) const
{
    ccprintf(os, "%s[%#llx:%#llx](%s) %s %s %s state: %s %s %s %s %s\n",
             prefix, blkAddr, blkAddr + blkSize - 1,
             isSecure ? "s" : "ns",
             _isUncacheable ? "Unc" : "",
             inService ? "InSvc" : "");

    ccprintf(os, "%s  Targets:\n", prefix);
    targets.print(os, verbosity, prefix + "    ");
}

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