/*
 * Copyright (c) 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 "dev/arm/fvp_base_pwr_ctrl.hh"

#include "arch/arm/faults.hh"
#include "arch/arm/system.hh"
#include "arch/arm/utility.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/FVPBasePwrCtrl.hh"
#include "mem/packet_access.hh"
#include "params/FVPBasePwrCtrl.hh"
#include "sim/system.hh"

FVPBasePwrCtrl::FVPBasePwrCtrl(FVPBasePwrCtrlParams *const params)
    : BasicPioDevice(params, 0x1000),
      regs(),
      system(*static_cast<ArmSystem *>(sys))
{
    warn_if(sys->multiThread,
            "Base Power Controller does not support multi-threaded systems\n");
    system.setPowerController(this);
}

void
FVPBasePwrCtrl::init()
{
    // All cores are ON by default (PwrStatus.{l0,l1} = 0b1)
    corePwrStatus.resize(sys->numContexts(), 0x60000000);
    for (const auto &tc : sys->threadContexts)
        poweredCoresPerCluster[tc->socketId()] += 1;
    BasicPioDevice::init();
}

void
FVPBasePwrCtrl::setStandByWfi(ThreadContext *const tc)
{
    PwrStatus *pwrs = getCorePwrStatus(tc);

    if (!pwrs->pwfi)
        DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::setStandByWfi: STANDBYWFI "
                "asserted for core %d\n", tc->contextId());
    pwrs->pwfi = 1;
    if (pwrs->l0 && (pwrs->pp || pwrs->pc))
        powerCoreOff(tc, pwrs);
}

void
FVPBasePwrCtrl::clearStandByWfi(ThreadContext *const tc)
{
    PwrStatus *pwrs = getCorePwrStatus(tc);

    if (pwrs->pwfi)
        DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::clearStandByWfi: STANDBYWFI "
                "deasserted for core %d\n", tc->contextId());
    pwrs->pwfi = 0;
}

bool
FVPBasePwrCtrl::setWakeRequest(ThreadContext *const tc)
{
    PwrStatus *pwrs = getCorePwrStatus(tc);

    if (!pwrs->pwk)
        DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::setWakeRequest: WakeRequest "
                "asserted for core %d\n", tc->contextId());
    pwrs->pwk = 1;
    if (!pwrs->l0 && pwrs->wen) {
        pwrs->wk = WK_GICWR;
        powerCoreOn(tc, pwrs);
        return true;
    }
    return false;
}

void
FVPBasePwrCtrl::clearWakeRequest(ThreadContext *const tc)
{
    PwrStatus *pwrs = getCorePwrStatus(tc);

    if (pwrs->pwk)
        DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::clearWakeRequest: "
                "WakeRequest deasserted for core %d\n", tc->contextId());
    pwrs->pwk = 0;
}

Tick
FVPBasePwrCtrl::read(PacketPtr pkt)
{
    const Addr addr = pkt->getAddr() - pioAddr;
    const size_t size = pkt->getSize();
    panic_if(size != 4, "FVPBasePwrCtrl::read: Invalid size %i\n", size);

    uint64_t resp = 0;
    switch (addr) {
      case PPOFFR:
        resp = regs.ppoffr;
        break;
      case PPONR:
        resp = regs.pponr;
        break;
      case PCOFFR:
        resp = regs.pcoffr;
        break;
      case PWKUPR:
        resp = regs.pwkupr;
        break;
      case PSYSR:
        resp = regs.psysr;
        break;
      default:
        warn("FVPBasePwrCtrl::read: Unexpected address (0x%x:%i), "
             "assuming RAZ\n", addr, size);
    }

    DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::read: 0x%x<-0x%x(%i)\n", resp,
            addr, size);

    pkt->setUintX(resp, LittleEndianByteOrder);
    pkt->makeResponse();
    return pioDelay;
}

Tick
FVPBasePwrCtrl::write(PacketPtr pkt)
{
    const Addr addr = pkt->getAddr() - pioAddr;
    const size_t size = pkt->getSize();
    panic_if(size != 4, "FVPBasePwrCtrl::write: Invalid size %i\n", size);

    uint64_t data = pkt->getUintX(LittleEndianByteOrder);

    // Software may use the power controller to check for core presence
    // If core is not present, return an invalid MPID as notification
    ThreadContext *tc = getThreadContextByMPID(data & MPID_MSK);
    PwrStatus *pwrs = tc ? getCorePwrStatus(tc) : nullptr;
    switch (addr) {
      case PPOFFR:
        if (!tc) {
            regs.ppoffr = ~0;
        } else if (pwrs->l0) {
            // Set pending power off
            pwrs->pp = 1;
            regs.ppoffr = data & MPID_MSK;
        } else {
            regs.ppoffr = ~0 & MPID_MSK;
        }
        break;
      case PPONR:
        if (!tc) {
            regs.pponr = ~0;
        } else {
            if (!pwrs->l0) {
                pwrs->wk = WK_PPONR;
                powerCoreOn(tc, pwrs);
                startCoreUp(tc);
                regs.pponr = data & MPID_MSK;
            } else {
                regs.pponr = ~0 & MPID_MSK;
            }
        }
        break;
      case PCOFFR:
        if (!tc) {
            regs.pcoffr = ~0;
        } else if (pwrs->l0) {
            // Power off all cores in the cluster
            for (const auto &tco : sys->threadContexts) {
                if (tc->socketId() == tco->socketId()) {
                    PwrStatus *npwrs = getCorePwrStatus(tco);
                    // Set pending cluster power off
                    npwrs->pc = 1;
                    if (npwrs->l0 && npwrs->pwfi)
                        powerCoreOff(tco, npwrs);
                }
            }
        } else {
            regs.pcoffr = ~0 & MPID_MSK;
        }
        break;
      case PWKUPR:
        if (!tc) {
            regs.pwkupr = ~0;
        } else {
            // Update WEN value
            pwrs->wen = bits(data, 31);
            // Power-on if there is any pending Wakeup Requests
            if (!pwrs->l0 && pwrs->wen && pwrs->pwk) {
                pwrs->wk = WK_GICWR;
                powerCoreOn(tc, pwrs);
                startCoreUp(tc);
            }
            regs.pwkupr = data & (MPID_MSK | (1 << 31));
        }
        break;
      case PSYSR:
        if (!tc)
            regs.psysr = ~0;
        else
            regs.psysr = (data & MPID_MSK) | (((uint32_t) *pwrs) & ~MPID_MSK);
        break;
      default:
        warn("FVPBasePwrCtrl::write: Unexpected address (0x%x:%i), "
             "assuming WI\n", addr, size);
    }

    DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::write: 0x%x->0x%x(%i)\n", data,
            addr, size);

    pkt->makeResponse();
    return pioDelay;
}

FVPBasePwrCtrl::PwrStatus *
FVPBasePwrCtrl::getCorePwrStatus(ThreadContext *const tc)
{
    PwrStatus *pwrs = &corePwrStatus[tc->contextId()];
    pwrs->l1 = poweredCoresPerCluster[tc->socketId()] > 0;
    return pwrs;
}

ThreadContext *
FVPBasePwrCtrl::getThreadContextByMPID(uint32_t mpid) const
{
    for (auto &tc : sys->threadContexts) {
        if (mpid == ArmISA::getAffinity(&system, tc))
            return tc;
    }
    return nullptr;
}

void
FVPBasePwrCtrl::powerCoreOn(ThreadContext *const tc, PwrStatus *const pwrs)
{
    DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::powerCoreOn: Powering ON "
            "core %d\n", tc->contextId());
    pwrs->l0 = 1;
    poweredCoresPerCluster[tc->socketId()]++;
    // Clear pending power-offs to the core
    pwrs->pp = 0;
    // Clear pending power-offs to the core's cluster
    for (const auto &tco : sys->threadContexts) {
        if (tc->socketId() == tco->socketId()) {
            PwrStatus *npwrs = getCorePwrStatus(tco);
            npwrs->pc = 0;
        }
    }
    tc->getCpuPtr()->powerState->set(Enums::PwrState::ON);
}

void
FVPBasePwrCtrl::powerCoreOff(ThreadContext *const tc, PwrStatus *const pwrs)
{
    DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::powerCoreOff: Powering OFF "
            "core %d\n", tc->contextId());
    pwrs->l0 = 0;
    poweredCoresPerCluster[tc->socketId()]--;
    // Clear pending power-offs to the core
    pwrs->pp = 0;
    pwrs->pc = 0;
    // Clear power-on reason
    pwrs->wk = 0;
    tc->getCpuPtr()->powerState->set(Enums::PwrState::OFF);
}

void
FVPBasePwrCtrl::startCoreUp(ThreadContext *const tc)
{
    DPRINTF(FVPBasePwrCtrl, "FVPBasePwrCtrl::startCoreUp: Starting core %d "
            "from the power controller\n", tc->contextId());
    clearStandByWfi(tc);
    clearWakeRequest(tc);

    // InitCPU
    Reset().invoke(tc);
    tc->activate();
}

FVPBasePwrCtrl *
FVPBasePwrCtrlParams::create()
{
    return new FVPBasePwrCtrl(this);
}
