/*
 * Copyright (c) 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.
 *
 * 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: Matteo Andreozzi
 */

#include "mem_ctrl.hh"

#include "turnaround_policy.hh"

namespace QoS {

MemCtrl::MemCtrl(const QoSMemCtrlParams * p)
  : AbstractMemory(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)
{
    // 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::init()
{
    AbstractMemory::init();
}

void
MemCtrl::logRequest(BusState dir, MasterID m_id, uint8_t qos,
                    Addr addr, uint64_t entries)
{
    // If needed, initialize all counters and statistics
    // for this master
    addMaster(m_id);

    DPRINTF(QOS,
            "QoSMemCtrl::logRequest MASTER %s [id %d] address %d"
            " prio %d this master q packets %d"
            " - queue size %d - requested entries %d\n",
            masters[m_id], m_id, addr, qos, packetPriorities[m_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[m_id][qos] += entries;
    for (auto j = 0; j < entries; ++j) {
        requestTimes[m_id][addr].push_back(curTick());
    }

    // Record statistics
    avgPriority[m_id].sample(qos);

    // Compute avg priority distance

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

        if (distance > 0) {
            avgPriorityDistance[m_id].sample(distance);
            DPRINTF(QOS,
                    "QoSMemCtrl::logRequest MASTER %s [id %d]"
                    " registering priority distance %d for priority %d"
                    " (packets %d)\n",
                    masters[m_id], m_id, distance, i,
                    packetPriorities[m_id][i]);
        }
    }

    DPRINTF(QOS,
            "QoSMemCtrl::logRequest MASTER %s [id %d] prio %d "
            "this master q packets %d - new queue size %d\n",
            masters[m_id], m_id, qos, packetPriorities[m_id][qos],
            (dir == READ) ? readQueueSizes[qos]: writeQueueSizes[qos]);

}

void
MemCtrl::logResponse(BusState dir, MasterID m_id, uint8_t qos,
                     Addr addr, uint64_t entries, double delay)
{
    panic_if(!hasMaster(m_id),
        "Logging response with invalid master\n");

    DPRINTF(QOS,
            "QoSMemCtrl::logResponse MASTER %s [id %d] address %d prio"
            " %d this master q packets %d"
            " - queue size %d - requested entries %d\n",
            masters[m_id], m_id, addr, qos, packetPriorities[m_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[m_id][qos] == 0,
             "QoSMemCtrl::logResponse master %s negative packets for priority"
             " %d", masters[m_id], qos);

    packetPriorities[m_id][qos] -= entries;

    for (auto j = 0; j < entries; ++j) {
        auto it = requestTimes[m_id].find(addr);
        panic_if(it == requestTimes[m_id].end(),
                 "QoSMemCtrl::logResponse master %s unmatched response for"
                 " address %d received", masters[m_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[m_id].erase(it);
        }
        // Compute latency
        double latency = (double) (curTick() + delay - requestTime)
                / SimClock::Float::s;

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

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

    DPRINTF(QOS,
            "QoSMemCtrl::logResponse MASTER %s [id %d] prio %d "
            "this master q packets %d - new queue size %d\n",
            masters[m_id], m_id, qos, packetPriorities[m_id][qos],
            (dir == READ) ? readQueueSizes[qos]: writeQueueSizes[qos]);
}

uint8_t
MemCtrl::schedule(MasterID m_id, uint64_t data)
{
    if (policy) {
        return policy->schedule(m_id, data);
    } else {
        DPRINTF(QOS,
                "QoSScheduler::schedule master ID [%d] "
                "data received [%d], but QoS scheduler not initialized\n",
                m_id,data);
        return 0;
    }
}

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

    if (policy) {
        return schedule(pkt->req->masterId(), pkt->getSize());
    } else {
        DPRINTF(QOS, "QoSScheduler::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,
                "QoSMemoryTurnaround::selectBusState running policy %s\n",
                turnPolicy->name());

        bus_state = turnPolicy->selectBusState();
    } else {
        DPRINTF(QOS,
                "QoSMemoryTurnaround::selectBusState 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::addMaster(MasterID m_id)
{
    if (!hasMaster(m_id)) {
        masters.emplace(m_id, _system->getMasterName(m_id));
        packetPriorities[m_id].resize(numPriorities(), 0);

        DPRINTF(QOS,
                "QoSMemCtrl::addMaster registering"
                " Master %s [id %d]\n",
                masters[m_id], m_id);
    }
}

void
MemCtrl::regStats()
{
    AbstractMemory::regStats();

    using namespace Stats;

    // Initializes per master statistics
    avgPriority.init(_system->maxMasters()).name(name() + ".avgPriority")
        .desc("Average QoS priority value for accepted requests")
        .flags(nozero | nonan).precision(2);

    avgPriorityDistance.init(_system->maxMasters())
        .name(name() + ".avgPriorityDistance")
        .desc("Average QoS priority distance between assigned and "
        "queued values").flags(nozero | nonan);

    priorityMinLatency.init(numPriorities())
        .name(name() + ".priorityMinLatency")
        .desc("per QoS priority minimum request to response latency (s)")
        .precision(12);

    priorityMaxLatency.init(numPriorities())
        .name(name() + ".priorityMaxLatency")
        .desc("per QoS priority maximum request to response latency (s)")
        .precision(12);

    numReadWriteTurnArounds.name(name() + ".numReadWriteTurnArounds")
        .desc("Number of turnarounds from READ to WRITE");

    numWriteReadTurnArounds.name(name() + ".numWriteReadTurnArounds")
        .desc("Number of turnarounds from WRITE to READ");

    numStayReadState.name(name() + ".numStayReadState")
        .desc("Number of times bus staying in READ state");

    numStayWriteState.name(name() + ".numStayWriteState")
        .desc("Number of times bus staying in WRITE state");

    for (int i = 0; i < _system->maxMasters(); i++) {
        const std::string master = _system->getMasterName(i);
        avgPriority.subname(i, master);
        avgPriorityDistance.subname(i, master);
    }

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

    if (policy)
        policy->regStats();
}

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

} // namespace QoS
