/*
 * Copyright 2019 Google, Inc.
 *
 * 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 "arch/arm/fastmodel/CortexA76/evs.hh"

#include "arch/arm/fastmodel/CortexA76/cortex_a76.hh"
#include "arch/arm/fastmodel/iris/cpu.hh"
#include "base/logging.hh"
#include "dev/arm/base_gic.hh"
#include "sim/core.hh"
#include "systemc/tlm_bridge/gem5_to_tlm.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(FastModel, fastmodel);
namespace fastmodel
{

template <class Types>
void
ScxEvsCortexA76<Types>::setClkPeriod(Tick clk_period)
{
    clockRateControl->set_mul_div(sim_clock::as_int::s, clk_period);
}

template <class Types>
void
ScxEvsCortexA76<Types>::setSysCounterFrq(uint64_t sys_counter_frq)
{
    periphClockRateControl->set_mul_div(sys_counter_frq, 1);
}

template <class Types>
void
ScxEvsCortexA76<Types>::setCluster(SimObject *cluster)
{
    gem5CpuCluster = dynamic_cast<CortexA76Cluster *>(cluster);
    panic_if(!gem5CpuCluster, "Cluster should be of type CortexA76Cluster");
}

template <class Types>
void
ScxEvsCortexA76<Types>::setResetAddr(int core, Addr addr, bool secure)
{
    this->rvbaraddr[core]->set_state(0, addr);
}

template <class Types>
ScxEvsCortexA76<Types>::ScxEvsCortexA76(
        const sc_core::sc_module_name &mod_name, const Params &p) :
    Base(mod_name), amba(Base::amba, p.name + ".amba", -1),
    params(p)
{
    for (int i = 0; i < CoreCount; i++) {
        redist.emplace_back(new TlmGicTarget(this->redistributor[i],
                    csprintf("%s.redistributor[%d]", name(), i), i));
        cnthpirq.emplace_back(new SignalReceiver(csprintf("cnthpirq[%d]", i)));
        cnthvirq.emplace_back(new SignalReceiver(csprintf("cnthvirq[%d]", i)));
        cntpsirq.emplace_back(new SignalReceiver(csprintf("cntpsirq[%d]", i)));
        cntvirq.emplace_back(new SignalReceiver(csprintf("cntvirq[%d]", i)));
        commirq.emplace_back(new SignalReceiver(csprintf("commirq[%d]", i)));
        ctidbgirq.emplace_back(
                new SignalReceiver(csprintf("ctidbgirq[%d]", i)));
        pmuirq.emplace_back(new SignalReceiver(csprintf("pmuirq[%d]", i)));
        vcpumntirq.emplace_back(
                new SignalReceiver(csprintf("vcpumntirq[%d]", i)));
        cntpnsirq.emplace_back(
                new SignalReceiver(csprintf("cntpnsirq[%d]", i)));
        rvbaraddr.emplace_back(new SignalInitiator<uint64_t>(
                    csprintf("rvbaraddr[%d]", i).c_str()));

        Base::cnthpirq[i].bind(cnthpirq[i]->signal_in);
        Base::cnthvirq[i].bind(cnthvirq[i]->signal_in);
        Base::cntpsirq[i].bind(cntpsirq[i]->signal_in);
        Base::cntvirq[i].bind(cntvirq[i]->signal_in);
        Base::commirq[i].bind(commirq[i]->signal_in);
        Base::ctidbgirq[i].bind(ctidbgirq[i]->signal_in);
        Base::pmuirq[i].bind(pmuirq[i]->signal_in);
        Base::vcpumntirq[i].bind(vcpumntirq[i]->signal_in);
        Base::cntpnsirq[i].bind(cntpnsirq[i]->signal_in);
        rvbaraddr[i]->bind(Base::rvbaraddr[i]);
    }

    clockRateControl.bind(this->clock_rate_s);
    periphClockRateControl.bind(this->periph_clock_rate_s);
}

template <class Types>
void
ScxEvsCortexA76<Types>::sendFunc(PacketPtr pkt)
{
    auto *trans = sc_gem5::packet2payload(pkt);
    panic_if(Base::amba->transport_dbg(*trans) != trans->get_data_length(),
            "Didn't send entire functional packet!");
    trans->release();
}

template <class Types>
void
ScxEvsCortexA76<Types>::before_end_of_elaboration()
{
    Base::before_end_of_elaboration();

    auto set_on_change = [this](
            SignalReceiver &recv, ArmInterruptPinGen *gen, int num)
    {
        auto *pin = gen->get(gem5CpuCluster->getCore(num)->getContext(0));
        auto handler = [pin](bool status)
        {
            status ? pin->raise() : pin->clear();
        };
        recv.onChange(handler);
    };

    for (int i = 0; i < CoreCount; i++) {
        set_on_change(*cnthpirq[i], gem5CpuCluster->params().cnthpirq, i);
        set_on_change(*cnthvirq[i], gem5CpuCluster->params().cnthvirq, i);
        set_on_change(*cntpsirq[i], gem5CpuCluster->params().cntpsirq, i);
        set_on_change(*cntvirq[i], gem5CpuCluster->params().cntvirq, i);
        set_on_change(*commirq[i], gem5CpuCluster->params().commirq, i);
        set_on_change(*ctidbgirq[i], gem5CpuCluster->params().ctidbgirq, i);
        set_on_change(*pmuirq[i], gem5CpuCluster->params().pmuirq, i);
        set_on_change(*vcpumntirq[i], gem5CpuCluster->params().vcpumntirq, i);
        set_on_change(*cntpnsirq[i], gem5CpuCluster->params().cntpnsirq, i);
    }
}

template <class Types>
Port &
ScxEvsCortexA76<Types>::gem5_getPort(const std::string &if_name, int idx)
{
    if (if_name == "redistributor")
        return *redist.at(idx);
    else if (if_name == "amba")
        return amba;
    else
        return Base::gem5_getPort(if_name, idx);
}

template class ScxEvsCortexA76<ScxEvsCortexA76x1Types>;
template class ScxEvsCortexA76<ScxEvsCortexA76x2Types>;
template class ScxEvsCortexA76<ScxEvsCortexA76x3Types>;
template class ScxEvsCortexA76<ScxEvsCortexA76x4Types>;

} // namespace fastmodel
} // namespace gem5
