/*
 * Copyright (c) 2017-2020 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.
 *
 * 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.
 */

#include "mem/qos/mem_ctrl.hh"

#include "mem/qos/policy.hh"
#include "mem/qos/q_policy.hh"
#include "mem/qos/turnaround_policy.hh"
#include "sim/core.hh"

GEM5_DEPRECATED_NAMESPACE(QoS, qos);
namespace qos
{

MemCtrl::MemCtrl(const QoSMemCtrlParams &p)
  : ClockedObject(p),
    policy(p.qos_policy),
    turnPolicy(p.qos_turnaround_policy),
    queuePolicy(QueuePolicy::create(p)),
    _numPriorities(p.qos_priorities),
    qosPriorityEscalation(p.qos_priority_escalation),
    qosSyncroScheduler(p.qos_syncro_scheduler),
    totalReadQueueSize(0), totalWriteQueueSize(0),
    busState(READ), busStateNext(READ),
    stats(*this),
    _system(p.system)
{
    // Set the priority policy
    if (policy) {
        policy->setMemCtrl(this);
    }

    // Set the queue priority policy
    if (queuePolicy) {
        queuePolicy->setMemCtrl(this);
    }

    // Set the bus turnaround policy
    if (turnPolicy) {
        turnPolicy->setMemCtrl(this);
    }

    readQueueSizes.resize(_numPriorities);
    writeQueueSizes.resize(_numPriorities);
    serviceTick.resize(_numPriorities);
}

MemCtrl::~MemCtrl()
{}

void
MemCtrl::logRequest(BusState dir, RequestorID id, uint8_t _qos,
                    Addr addr, uint64_t entries)
{
    // If needed, initialize all counters and statistics
    // for this requestor
    addRequestor(id);

    DPRINTF(QOS,
            "qos::MemCtrl::logRequest REQUESTOR %s [id %d] address %d"
            " prio %d this requestor q packets %d"
            " - queue size %d - requested entries %d\n",
            requestors[id], id, addr, _qos, packetPriorities[id][_qos],
            (dir == READ) ? readQueueSizes[_qos]: writeQueueSizes[_qos],
            entries);

    if (dir == READ) {
        readQueueSizes[_qos] += entries;
        totalReadQueueSize += entries;
    } else if (dir == WRITE) {
        writeQueueSizes[_qos] += entries;
        totalWriteQueueSize += entries;
    }

    packetPriorities[id][_qos] += entries;
    for (auto j = 0; j < entries; ++j) {
        requestTimes[id][addr].push_back(curTick());
    }

    // Record statistics
    stats.avgPriority[id].sample(_qos);

    // Compute avg priority distance

    for (uint8_t i = 0; i < packetPriorities[id].size(); ++i) {
        uint8_t distance =
            (abs(int(_qos) - int(i))) * packetPriorities[id][i];

        if (distance > 0) {
            stats.avgPriorityDistance[id].sample(distance);
            DPRINTF(QOS,
                    "qos::MemCtrl::logRequest REQUESTOR %s [id %d]"
                    " registering priority distance %d for priority %d"
                    " (packets %d)\n",
                    requestors[id], id, distance, i,
                    packetPriorities[id][i]);
        }
    }

    DPRINTF(QOS,
            "qos::MemCtrl::logRequest REQUESTOR %s [id %d] prio %d "
            "this requestor q packets %d - new queue size %d\n",
            requestors[id], id, _qos, packetPriorities[id][_qos],
            (dir == READ) ? readQueueSizes[_qos]: writeQueueSizes[_qos]);

}

void
MemCtrl::logResponse(BusState dir, RequestorID id, uint8_t _qos,
                     Addr addr, uint64_t entries, double delay)
{
    panic_if(!hasRequestor(id),
        "Logging response with invalid requestor\n");

    DPRINTF(QOS,
            "qos::MemCtrl::logResponse REQUESTOR %s [id %d] address %d prio"
            " %d this requestor q packets %d"
            " - queue size %d - requested entries %d\n",
            requestors[id], id, addr, _qos, packetPriorities[id][_qos],
            (dir == READ) ? readQueueSizes[_qos]: writeQueueSizes[_qos],
            entries);

    if (dir == READ) {
        readQueueSizes[_qos] -= entries;
        totalReadQueueSize -= entries;
    } else if (dir == WRITE) {
        writeQueueSizes[_qos] -= entries;
        totalWriteQueueSize -= entries;
    }

    panic_if(packetPriorities[id][_qos] == 0,
             "qos::MemCtrl::logResponse requestor %s negative packets "
             "for priority %d", requestors[id], _qos);

    packetPriorities[id][_qos] -= entries;

    for (auto j = 0; j < entries; ++j) {
        auto it = requestTimes[id].find(addr);
        panic_if(it == requestTimes[id].end(),
                 "qos::MemCtrl::logResponse requestor %s unmatched response "
                 "for address %d received", requestors[id], addr);

        // Load request time
        uint64_t requestTime = it->second.front();

        // Remove request entry
        it->second.pop_front();

        // Remove whole address entry if last one
        if (it->second.empty()) {
            requestTimes[id].erase(it);
        }
        // Compute latency
        double latency = (double) (curTick() + delay - requestTime)
                / sim_clock::as_float::s;

        if (latency > 0) {
            // Record per-priority latency stats
            if (stats.priorityMaxLatency[_qos].value() < latency) {
                stats.priorityMaxLatency[_qos] = latency;
            }

            if (stats.priorityMinLatency[_qos].value() > latency
                    || stats.priorityMinLatency[_qos].value() == 0) {
                stats.priorityMinLatency[_qos] = latency;
            }
        }
    }

    DPRINTF(QOS,
            "qos::MemCtrl::logResponse REQUESTOR %s [id %d] prio %d "
            "this requestor q packets %d - new queue size %d\n",
            requestors[id], id, _qos, packetPriorities[id][_qos],
            (dir == READ) ? readQueueSizes[_qos]: writeQueueSizes[_qos]);
}

uint8_t
MemCtrl::schedule(RequestorID id, uint64_t data)
{
    if (policy) {
        return policy->schedule(id, data);
    } else {
        DPRINTF(QOS,
                "qos::MemCtrl::schedule requestor id [%d] "
                "data received [%d], but QoS scheduler not initialized\n",
                id,data);
        return 0;
    }
}

uint8_t
MemCtrl::schedule(const PacketPtr pkt)
{
    assert(pkt->req);

    if (policy) {
        return schedule(pkt->req->requestorId(), pkt->getSize());
    } else {
        DPRINTF(QOS, "qos::MemCtrl::schedule Packet received [Qv %d], "
                "but QoS scheduler not initialized\n",
                pkt->qosValue());
        return pkt->qosValue();
    }
}

MemCtrl::BusState
MemCtrl::selectNextBusState()
{
    auto bus_state = getBusState();

    if (turnPolicy) {
        DPRINTF(QOS,
                "qos::MemCtrl::selectNextBusState running policy %s\n",
                turnPolicy->name());

        bus_state = turnPolicy->selectBusState();
    } else {
        DPRINTF(QOS,
                "qos::MemCtrl::selectNextBusState running "
                "default bus direction selection policy\n");

        if ((!getTotalReadQueueSize() && bus_state == MemCtrl::READ) ||
            (!getTotalWriteQueueSize() && bus_state == MemCtrl::WRITE)) {
            // READ/WRITE turnaround
            bus_state = (bus_state == MemCtrl::READ) ? MemCtrl::WRITE :
                                                       MemCtrl::READ;

        }
    }

    return bus_state;
}

void
MemCtrl::addRequestor(RequestorID id)
{
    if (!hasRequestor(id)) {
        requestors.emplace(id, _system->getRequestorName(id));
        packetPriorities[id].resize(numPriorities(), 0);

        DPRINTF(QOS,
                "qos::MemCtrl::addRequestor registering"
                " Requestor %s [id %d]\n",
                requestors[id], id);
    }
}

MemCtrl::MemCtrlStats::MemCtrlStats(MemCtrl &mc)
    : statistics::Group(&mc),
    memCtrl(mc),

    ADD_STAT(avgPriority, statistics::units::Count::get(),
             "Average QoS priority value for accepted requests"),
    ADD_STAT(avgPriorityDistance, statistics::units::Count::get(),
             "Average QoS priority distance between assigned and queued "
             "values"),

    ADD_STAT(priorityMinLatency, statistics::units::Second::get(),
             "per QoS priority minimum request to response latency"),
    ADD_STAT(priorityMaxLatency, statistics::units::Second::get(),
             "per QoS priority maximum request to response latency"),
    ADD_STAT(numReadWriteTurnArounds, statistics::units::Count::get(),
             "Number of turnarounds from READ to WRITE"),
    ADD_STAT(numWriteReadTurnArounds, statistics::units::Count::get(),
             "Number of turnarounds from WRITE to READ"),
    ADD_STAT(numStayReadState, statistics::units::Count::get(),
             "Number of times bus staying in READ state"),
    ADD_STAT(numStayWriteState, statistics::units::Count::get(),
             "Number of times bus staying in WRITE state")
{
}

void
MemCtrl::MemCtrlStats::regStats()
{
    statistics::Group::regStats();

    using namespace statistics;

    System *system = memCtrl._system;
    const auto max_requestors = system->maxRequestors();
    const auto num_priorities = memCtrl.numPriorities();

    // Initializes per requestor statistics
    avgPriority
        .init(max_requestors)
        .flags(nozero | nonan)
        .precision(2)
        ;

    avgPriorityDistance
        .init(max_requestors)
        .flags(nozero | nonan)
        ;

    priorityMinLatency
        .init(num_priorities)
        .precision(12)
        ;

    priorityMaxLatency
        .init(num_priorities)
        .precision(12)
        ;

    for (int i = 0; i < max_requestors; i++) {
        const std::string name = system->getRequestorName(i);
        avgPriority.subname(i, name);
        avgPriorityDistance.subname(i, name);
    }

    for (int j = 0; j < num_priorities; ++j) {
        priorityMinLatency.subname(j, std::to_string(j));
        priorityMaxLatency.subname(j, std::to_string(j));
    }
}

void
MemCtrl::recordTurnaroundStats()
{
    if (busStateNext != busState) {
        if (busState == READ) {
            stats.numWriteReadTurnArounds++;
        } else if (busState == WRITE) {
            stats.numReadWriteTurnArounds++;
        }
    } else {
        if (busState == READ) {
            stats.numStayReadState++;
        } else if (busState == WRITE) {
            stats.numStayWriteState++;
        }
    }
}

} // namespace qos
