/*
 * Copyright (c) 2012-2014 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: Vasileios Spiliopoulos
 *          Akash Bagdia
 *          Stephan Diestelhorst
 */

#include "dev/arm/energy_ctrl.hh"

#include "debug/EnergyCtrl.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "params/EnergyCtrl.hh"
#include "sim/dvfs_handler.hh"

EnergyCtrl::EnergyCtrl(const Params *p)
    : BasicPioDevice(p, PIO_NUM_FIELDS * 4),        // each field is 32 bit
      dvfsHandler(p->dvfs_handler),
      domainID(0),
      domainIDIndexToRead(0),
      perfLevelAck(0),
      perfLevelToRead(0),
      updateAckEvent(this)
{
    fatal_if(!p->dvfs_handler, "EnergyCtrl: Needs a DVFSHandler for a "
             "functioning system.\n");
}

Tick
EnergyCtrl::read(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    assert(pkt->getSize() == 4);

    Addr daddr = pkt->getAddr() - pioAddr;
    assert((daddr & 3) == 0);
    Registers reg = Registers(daddr / 4);

    if (!dvfsHandler->isEnabled()) {
        // NB: Zero is a good response if the handler is disabled
        pkt->set<uint32_t>(0);
        warn_once("EnergyCtrl: Disabled handler, ignoring read from reg %i\n",
                  reg);
        DPRINTF(EnergyCtrl, "dvfs handler disabled, return 0 for read from "\
                "reg %i\n", reg);
        pkt->makeAtomicResponse();
        return pioDelay;
    }

    uint32_t result = 0;
    Tick period;
    double voltage;

    switch(reg) {
      case DVFS_HANDLER_STATUS:
        result = 1;
        DPRINTF(EnergyCtrl, "dvfs handler enabled\n");
        break;
      case DVFS_NUM_DOMAINS:
        result = dvfsHandler->numDomains();
        DPRINTF(EnergyCtrl, "reading number of domains %d\n", result);
        break;
      case DVFS_DOMAINID_AT_INDEX:
        result = dvfsHandler->domainID(domainIDIndexToRead);
        DPRINTF(EnergyCtrl, "reading domain id at index %d as %d\n",
                domainIDIndexToRead, result);
        break;
      case DVFS_HANDLER_TRANS_LATENCY:
        // Return transition latency in nanoseconds
        result = dvfsHandler->transLatency() / SimClock::Int::ns;
        DPRINTF(EnergyCtrl, "reading dvfs handler trans latency %d ns\n",
                result);
        break;
      case DOMAIN_ID:
        result = domainID;
        DPRINTF(EnergyCtrl, "reading domain id:%d\n", result);
        break;
      case PERF_LEVEL:
        result = dvfsHandler->perfLevel(domainID);
        DPRINTF(EnergyCtrl, "reading domain %d perf level: %d\n",
                domainID, result);
        break;
      case PERF_LEVEL_ACK:
        result = perfLevelAck;
        DPRINTF(EnergyCtrl, "reading ack:%d\n", result);
        // Signal is set for a single read only
        if (result == 1)
            perfLevelAck = 0;
        break;
      case NUM_OF_PERF_LEVELS:
        result = dvfsHandler->numPerfLevels(domainID);
        DPRINTF(EnergyCtrl, "reading num of perf level:%d\n", result);
        break;
      case FREQ_AT_PERF_LEVEL:
        period = dvfsHandler->clkPeriodAtPerfLevel(domainID, perfLevelToRead);
        result = ticksTokHz(period);
        DPRINTF(EnergyCtrl, "reading freq %d KHz at perf level: %d\n",
                result, perfLevelToRead);
        break;
      case VOLT_AT_PERF_LEVEL:
        voltage = dvfsHandler->voltageAtPerfLevel(domainID, perfLevelToRead);
        result = toMicroVolt(voltage);
        DPRINTF(EnergyCtrl, "reading voltage %d u-volt at perf level: %d\n",
                result, perfLevelToRead);
        break;
      default:
        panic("Tried to read EnergyCtrl at offset %#x / reg %i\n", daddr,
              reg);
    }
    pkt->set<uint32_t>(result);
    pkt->makeAtomicResponse();
    return pioDelay;
}

Tick
EnergyCtrl::write(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    assert(pkt->getSize() == 4);

    uint32_t data;
    data = pkt->get<uint32_t>();

    Addr daddr = pkt->getAddr() - pioAddr;
    assert((daddr & 3) == 0);
    Registers reg = Registers(daddr / 4);

    if (!dvfsHandler->isEnabled()) {
        // Ignore writes to a disabled controller
        warn_once("EnergyCtrl: Disabled handler, ignoring write %u to "\
                  "reg %i\n", data, reg);
        DPRINTF(EnergyCtrl, "dvfs handler disabled, ignoring write %u to "\
                "reg %i\n", data, reg);
        pkt->makeAtomicResponse();
        return pioDelay;
    }

    switch(reg) {
      case DVFS_DOMAINID_AT_INDEX:
        domainIDIndexToRead = data;
        DPRINTF(EnergyCtrl, "writing domain id index:%d\n",
                domainIDIndexToRead);
        break;
      case DOMAIN_ID:
        // Extra check to ensure that a valid domain ID is being queried
        if (dvfsHandler->validDomainID(data)) {
            domainID = data;
            DPRINTF(EnergyCtrl, "writing domain id:%d\n", domainID);
        } else {
           DPRINTF(EnergyCtrl, "invalid domain id:%d\n", domainID);
        }
        break;
      case PERF_LEVEL:
        if (dvfsHandler->perfLevel(domainID, data)) {
            if (updateAckEvent.scheduled()) {
                // The OS driver is trying to change the perf level while
                // another change is in flight.  This is fine, but only a
                // single acknowledgment will be sent.
                DPRINTF(EnergyCtrl, "descheduling previous pending ack "\
                        "event\n");
                deschedule(updateAckEvent);
            }
            schedule(updateAckEvent, curTick() + dvfsHandler->transLatency());
            DPRINTF(EnergyCtrl, "writing domain %d perf level: %d\n",
                    domainID, data);
        } else {
            DPRINTF(EnergyCtrl, "invalid / ineffective perf level:%d for "\
                    "domain:%d\n", data, domainID);
        }
        break;
      case PERF_LEVEL_TO_READ:
        perfLevelToRead = data;
        DPRINTF(EnergyCtrl, "writing perf level to read opp at: %d\n",
                data);
        break;
      default:
        panic("Tried to write EnergyCtrl at offset %#x\n", daddr);
        break;
    }

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
EnergyCtrl::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(domainID);
    SERIALIZE_SCALAR(domainIDIndexToRead);
    SERIALIZE_SCALAR(perfLevelToRead);
    SERIALIZE_SCALAR(perfLevelAck);

    Tick next_event = updateAckEvent.scheduled() ? updateAckEvent.when() : 0;
    SERIALIZE_SCALAR(next_event);
}

void
EnergyCtrl::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(domainID);
    UNSERIALIZE_SCALAR(domainIDIndexToRead);
    UNSERIALIZE_SCALAR(perfLevelToRead);
    UNSERIALIZE_SCALAR(perfLevelAck);
    Tick next_event = 0;
    UNSERIALIZE_SCALAR(next_event);

    // restore scheduled events
    if (next_event != 0) {
        schedule(updateAckEvent, next_event);
    }
}

EnergyCtrl * EnergyCtrlParams::create()
{
    return new EnergyCtrl(this);
}

void
EnergyCtrl::startup()
{
    if (!dvfsHandler->isEnabled()) {
        warn("Existing EnergyCtrl, but no enabled DVFSHandler found.\n");
    }
}

void
EnergyCtrl::init()
{
    BasicPioDevice::init();
}
