/*
 * Copyright 2020 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/CortexR52/cortex_r52.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 FastModel
{

void
CortexR52::setCluster(CortexR52Cluster *_cluster, int _num)
{
    cluster = _cluster;
    num = _num;

    set_evs_param("CFGEND", params().CFGEND);
    set_evs_param("CFGTE", params().CFGTE);
    set_evs_param("RVBARADDR", params().RVBARADDR);
    set_evs_param("ase-present", params().ase_present);
    set_evs_param("dcache-size", params().dcache_size);
    set_evs_param("flash.enable", params().flash_enable);
    set_evs_param("icache-size", params().icache_size);
    set_evs_param("llpp.base", params().llpp_base);
    set_evs_param("llpp.size", params().llpp_size);
    set_evs_param("max_code_cache_mb", params().max_code_cache_mb);
    set_evs_param("min_sync_level", params().min_sync_level);
    set_evs_param("semihosting-A32_HLT", params().semihosting_A32_HLT);
    // Use uint32_t, since the model doesn't like setting these as uint8_t.
    set_evs_param<uint32_t>("semihosting-ARM_SVC",
            params().semihosting_ARM_SVC);
    set_evs_param<uint32_t>("semihosting-T32_HLT",
            params().semihosting_T32_HLT);
    set_evs_param<uint32_t>("semihosting-Thumb_SVC",
            params().semihosting_Thumb_SVC);
    set_evs_param("semihosting-cmd_line", params().semihosting_cmd_line);
    set_evs_param("semihosting-cwd", params().semihosting_cwd);
    set_evs_param("semihosting-enable", params().semihosting_enable);
    set_evs_param("semihosting-heap_base", params().semihosting_heap_base);
    set_evs_param("semihosting-heap_limit", params().semihosting_heap_limit);
    set_evs_param("semihosting-stack_base", params().semihosting_stack_base);
    set_evs_param("semihosting-stack_limit", params().semihosting_stack_limit);
    set_evs_param("tcm.a.enable", params().tcm_a_enable);
    set_evs_param("tcm.a.size", params().tcm_a_size);
    set_evs_param("tcm.b.size", params().tcm_b_size);
    set_evs_param("tcm.c.size", params().tcm_c_size);
    set_evs_param("vfp-dp-present", params().vfp_dp_present);
    set_evs_param("vfp-enable_at_reset", params().vfp_enable_at_reset);
}

Port &
CortexR52::getPort(const std::string &if_name, PortID idx)
{
    if (if_name == "ppi") {
        // Since PPIs are indexed both by core and by number, modify the name
        // to hold the core number.
        return evs->gem5_getPort(csprintf("%s_%d", if_name, num), idx);
    } else if (if_name == "amba" || if_name == "llpp" || if_name == "flash") {
        // Since these ports are scalar per core, use the core number as the
        // index. Also verify that that index is not being used.
        assert(idx == InvalidPortID);
        return evs->gem5_getPort(if_name, num);
    } else {
        return SimObject::getPort(if_name, idx);
    }
}

CortexR52Cluster::CortexR52Cluster(const Params &p) :
    SimObject(p), cores(p.cores), evs(p.evs)
{
    for (int i = 0; i < p.cores.size(); i++)
        p.cores[i]->setCluster(this, i);

    Iris::BaseCpuEvs *e = dynamic_cast<Iris::BaseCpuEvs *>(evs);
    panic_if(!e, "EVS should be of type Iris::BaseCpuEvs");
    e->setCluster(this);

    set_evs_param("core.CLUSTER_ID", params().CLUSTER_ID);
    set_evs_param("core.DBGROMADDR", params().DBGROMADDR);
    set_evs_param("core.DBGROMADDRV", params().DBGROMADDRV);
    set_evs_param("core.PERIPHBASE", params().PERIPHBASE);
    set_evs_param("core.cluster_utid", params().cluster_utid);
    set_evs_param("core.cpi_div", params().cpi_div);
    set_evs_param("core.cpi_mul", params().cpi_mul);
    set_evs_param("core.dcache-prefetch_enabled",
            params().dcache_prefetch_enabled);
    set_evs_param("core.dcache-read_access_latency",
            params().dcache_read_access_latency);
    set_evs_param("core.dcache-state_modelled",
            params().dcache_state_modelled);
    set_evs_param("core.dcache-write_access_latency",
            params().dcache_write_access_latency);
    set_evs_param("core.flash_protection_enable_at_reset",
            params().flash_protection_enable_at_reset);
    set_evs_param("core.has_flash_protection", params().has_flash_protection);
    set_evs_param("core.icache-prefetch_enabled",
            params().icache_prefetch_enabled);
    set_evs_param("core.icache-read_access_latency",
            params().icache_read_access_latency);
    set_evs_param("core.icache-state_modelled",
            params().icache_state_modelled);
    set_evs_param("core.memory.ext_slave_base",
            params().memory_ext_slave_base);
    set_evs_param("core.memory.flash_base", params().memory_flash_base);
    set_evs_param("core.memory.flash_size", params().memory_flash_size);
    // Use uint32_t, since the model doesn't like setting these as uint8_t.
    set_evs_param<uint32_t>("core.num_protection_regions_s1",
            params().num_protection_regions_s1);
    set_evs_param<uint32_t>("core.num_protection_regions_s2",
            params().num_protection_regions_s2);
    set_evs_param("core.num_spi", params().num_spi);
    set_evs_param("core.ram_protection_enable_at_reset",
            params().ram_protection_enable_at_reset);
    set_evs_param("core.has_export_m_port", params().has_export_m_port);
}

Port &
CortexR52Cluster::getPort(const std::string &if_name, PortID idx)
{
    if (if_name == "spi") {
        return evs->gem5_getPort(if_name, idx);
    } else {
        return SimObject::getPort(if_name, idx);
    }
}

} // namespace FastModel
