blob: 50d5417a63bbfa0e0c0fd799b346ce6138a74520 [file] [log] [blame]
/*
* 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.
*
* Authors: Gabe Black
*/
#include "arch/arm/fastmodel/CortexA76x1/cortex_a76x1.hh"
#include "arch/arm/fastmodel/arm/cpu.hh"
#include "arch/arm/fastmodel/iris/cpu.hh"
#include "base/logging.hh"
#include "dev/arm/base_gic.hh"
#include "params/FastModelCortexA76x1.hh"
#include "sim/core.hh"
#include "systemc/tlm_bridge/gem5_to_tlm.hh"
namespace FastModel
{
void
CortexA76x1::clockChangeHandler()
{
clockRateControl->set_mul_div(SimClock::Int::s, clockPeriod.value);
}
CortexA76x1::CortexA76x1(const sc_core::sc_module_name &mod_name,
const FastModelCortexA76x1Params &p)
: scx_evs_CortexA76x1(mod_name),
amba(scx_evs_CortexA76x1::amba, p.name + ".amba", -1),
redistributor(scx_evs_CortexA76x1::redistributor,
p.name + ".redistributor", -1),
cnthpirq("cnthpirq"),
cnthvirq("cnthvirq"),
cntpsirq("cntpsirq"),
cntvirq("cntvirq"),
commirq("commirq"),
ctidbgirq("ctidbgirq"),
pmuirq("pmuirq"),
vcpumntirq("vcpumntirq"),
cntpnsirq("cntpnsirq"),
clockChanged(Iris::ClockEventName.c_str()),
clockPeriod(Iris::PeriodAttributeName.c_str()),
gem5Cpu(Iris::Gem5CpuAttributeName.c_str()),
sendFunctional(Iris::SendFunctionalAttributeName.c_str()),
params(p)
{
clockRateControl.bind(clock_rate_s);
set_parameter("core.BROADCASTATOMIC", params.BROADCASTATOMIC);
set_parameter("core.BROADCASTCACHEMAINT", params.BROADCASTCACHEMAINT);
set_parameter("core.BROADCASTOUTER", params.BROADCASTOUTER);
set_parameter("core.BROADCASTPERSIST", params.BROADCASTPERSIST);
set_parameter("core.CLUSTER_ID", params.CLUSTER_ID);
set_parameter("core.GICDISABLE", params.GICDISABLE);
set_parameter("core.cpi_div", params.cpi_div);
set_parameter("core.cpi_mul", params.cpi_mul);
set_parameter("core.dcache-hit_latency", params.dcache_hit_latency);
set_parameter("core.dcache-maintenance_latency",
params.dcache_maintenance_latency);
set_parameter("core.dcache-miss_latency", params.dcache_miss_latency);
set_parameter("core.dcache-prefetch_enabled",
params.dcache_prefetch_enabled);
set_parameter("core.dcache-read_access_latency",
params.dcache_read_access_latency);
set_parameter("core.dcache-read_latency", params.dcache_read_latency);
set_parameter("core.dcache-snoop_data_transfer_latency",
params.dcache_snoop_data_transfer_latency);
set_parameter("core.dcache-state_modelled", params.dcache_state_modelled);
set_parameter("core.dcache-write_access_latency",
params.dcache_write_access_latency);
set_parameter("core.dcache-write_latency", params.dcache_write_latency);
set_parameter("core.default_opmode", params.default_opmode);
set_parameter("core.diagnostics", params.diagnostics);
set_parameter("core.enable_simulation_performance_optimizations",
params.enable_simulation_performance_optimizations);
set_parameter("core.ext_abort_device_read_is_sync",
params.ext_abort_device_read_is_sync);
set_parameter("core.ext_abort_device_write_is_sync",
params.ext_abort_device_write_is_sync);
set_parameter("core.ext_abort_so_read_is_sync",
params.ext_abort_so_read_is_sync);
set_parameter("core.ext_abort_so_write_is_sync",
params.ext_abort_so_write_is_sync);
set_parameter("core.gicv3.cpuintf-mmap-access-level",
params.gicv3_cpuintf_mmap_access_level);
set_parameter("core.has_peripheral_port", params.has_peripheral_port);
set_parameter("core.has_statistical_profiling",
params.has_statistical_profiling);
set_parameter("core.icache-hit_latency", params.icache_hit_latency);
set_parameter("core.icache-maintenance_latency",
params.icache_maintenance_latency);
set_parameter("core.icache-miss_latency", params.icache_miss_latency);
set_parameter("core.icache-prefetch_enabled",
params.icache_prefetch_enabled);
set_parameter("core.icache-read_access_latency",
params.icache_read_access_latency);
set_parameter("core.icache-read_latency", params.icache_read_latency);
set_parameter("core.icache-state_modelled", params.icache_state_modelled);
set_parameter("core.l3cache-hit_latency", params.l3cache_hit_latency);
set_parameter("core.l3cache-maintenance_latency",
params.l3cache_maintenance_latency);
set_parameter("core.l3cache-miss_latency", params.l3cache_miss_latency);
set_parameter("core.l3cache-read_access_latency",
params.l3cache_read_access_latency);
set_parameter("core.l3cache-read_latency", params.l3cache_read_latency);
set_parameter("core.l3cache-size", params.l3cache_size);
set_parameter("core.l3cache-snoop_data_transfer_latency",
params.l3cache_snoop_data_transfer_latency);
set_parameter("core.l3cache-snoop_issue_latency",
params.l3cache_snoop_issue_latency);
set_parameter("core.l3cache-write_access_latency",
params.l3cache_write_access_latency);
set_parameter("core.l3cache-write_latency", params.l3cache_write_latency);
set_parameter("core.pchannel_treat_simreset_as_poreset",
params.pchannel_treat_simreset_as_poreset);
set_parameter("core.periph_address_end", params.periph_address_end);
set_parameter("core.periph_address_start", params.periph_address_start);
set_parameter("core.ptw_latency", params.ptw_latency);
set_parameter("core.tlb_latency", params.tlb_latency);
set_parameter("core.treat-dcache-cmos-to-pou-as-nop",
params.treat_dcache_cmos_to_pou_as_nop);
set_parameter("core.walk_cache_latency", params.walk_cache_latency);
set_parameter("core.cpu0.CFGEND", params.cpu0_CFGEND);
set_parameter("core.cpu0.CFGTE", params.cpu0_CFGTE);
set_parameter("core.cpu0.CRYPTODISABLE", params.cpu0_CRYPTODISABLE);
set_parameter("core.cpu0.RVBARADDR", params.cpu0_RVBARADDR);
set_parameter("core.cpu0.VINITHI", params.cpu0_VINITHI);
set_parameter("core.cpu0.enable_trace_special_hlt_imm16",
params.cpu0_enable_trace_special_hlt_imm16);
set_parameter("core.cpu0.l2cache-hit_latency",
params.cpu0_l2cache_hit_latency);
set_parameter("core.cpu0.l2cache-maintenance_latency",
params.cpu0_l2cache_maintenance_latency);
set_parameter("core.cpu0.l2cache-miss_latency",
params.cpu0_l2cache_miss_latency);
set_parameter("core.cpu0.l2cache-read_access_latency",
params.cpu0_l2cache_read_access_latency);
set_parameter("core.cpu0.l2cache-read_latency",
params.cpu0_l2cache_read_latency);
set_parameter("core.cpu0.l2cache-size", params.cpu0_l2cache_size);
set_parameter("core.cpu0.l2cache-snoop_data_transfer_latency",
params.cpu0_l2cache_snoop_data_transfer_latency);
set_parameter("core.cpu0.l2cache-snoop_issue_latency",
params.cpu0_l2cache_snoop_issue_latency);
set_parameter("core.cpu0.l2cache-write_access_latency",
params.cpu0_l2cache_write_access_latency);
set_parameter("core.cpu0.l2cache-write_latency",
params.cpu0_l2cache_write_latency);
set_parameter("core.cpu0.max_code_cache_mb",
params.cpu0_max_code_cache_mb);
set_parameter("core.cpu0.min_sync_level", params.cpu0_min_sync_level);
set_parameter("core.cpu0.semihosting-A32_HLT",
params.cpu0_semihosting_A32_HLT);
set_parameter("core.cpu0.semihosting-A64_HLT",
params.cpu0_semihosting_A64_HLT);
set_parameter("core.cpu0.semihosting-ARM_SVC",
params.cpu0_semihosting_ARM_SVC);
set_parameter("core.cpu0.semihosting-T32_HLT",
params.cpu0_semihosting_T32_HLT);
set_parameter("core.cpu0.semihosting-Thumb_SVC",
params.cpu0_semihosting_Thumb_SVC);
set_parameter("core.cpu0.semihosting-cmd_line",
params.cpu0_semihosting_cmd_line);
set_parameter("core.cpu0.semihosting-cwd", params.cpu0_semihosting_cwd);
set_parameter("core.cpu0.semihosting-enable",
params.cpu0_semihosting_enable);
set_parameter("core.cpu0.semihosting-heap_base",
params.cpu0_semihosting_heap_base);
set_parameter("core.cpu0.semihosting-heap_limit",
params.cpu0_semihosting_heap_limit);
set_parameter("core.cpu0.semihosting-stack_base",
params.cpu0_semihosting_stack_base);
set_parameter("core.cpu0.semihosting-stack_limit",
params.cpu0_semihosting_stack_limit);
set_parameter("core.cpu0.trace_special_hlt_imm16",
params.cpu0_trace_special_hlt_imm16);
set_parameter("core.cpu0.vfp-enable_at_reset",
params.cpu0_vfp_enable_at_reset);
add_attribute(gem5Cpu);
add_attribute(clockPeriod);
SC_METHOD(clockChangeHandler);
dont_initialize();
sensitive << clockChanged;
sendFunctional.value = [this](PacketPtr pkt) { sendFunc(pkt); };
add_attribute(sendFunctional);
scx_evs_CortexA76x1::cnthpirq.bind(cnthpirq.signal_in);
scx_evs_CortexA76x1::cnthvirq.bind(cnthvirq.signal_in);
scx_evs_CortexA76x1::cntpsirq.bind(cntpsirq.signal_in);
scx_evs_CortexA76x1::cntvirq.bind(cntvirq.signal_in);
scx_evs_CortexA76x1::commirq.bind(commirq.signal_in);
scx_evs_CortexA76x1::ctidbgirq.bind(ctidbgirq.signal_in);
scx_evs_CortexA76x1::pmuirq.bind(pmuirq.signal_in);
scx_evs_CortexA76x1::vcpumntirq.bind(vcpumntirq.signal_in);
scx_evs_CortexA76x1::cntpnsirq.bind(cntpnsirq.signal_in);
}
void
CortexA76x1::sendFunc(PacketPtr pkt)
{
auto *trans = sc_gem5::packet2payload(pkt);
panic_if(scx_evs_CortexA76x1::amba->transport_dbg(*trans) !=
trans->get_data_length(), "Didn't send entire functional packet!");
trans->release();
}
void
CortexA76x1::before_end_of_elaboration()
{
scx_evs_CortexA76x1::before_end_of_elaboration();
auto *gem5_cpu = gem5Cpu.value;
auto set_on_change = [gem5_cpu](SignalReceiver &recv,
ArmInterruptPinGen *gen,
int ctx_num)
{
auto *pin = gen->get(gem5_cpu->getContext(ctx_num));
auto handler = [pin](bool status)
{
status ? pin->raise() : pin->clear();
};
recv.onChange(handler);
};
set_on_change(cnthpirq, params.cnthpirq, 0);
set_on_change(cnthvirq, params.cnthvirq, 0);
set_on_change(cntpsirq, params.cntpsirq, 0);
set_on_change(cntvirq, params.cntvirq, 0);
set_on_change(commirq, params.commirq, 0);
set_on_change(ctidbgirq, params.ctidbgirq, 0);
set_on_change(pmuirq, params.pmuirq, 0);
set_on_change(vcpumntirq, params.vcpumntirq, 0);
set_on_change(cntpnsirq, params.cntpnsirq, 0);
}
Port &
CortexA76x1::gem5_getPort(const std::string &if_name, int idx)
{
if (if_name == "amba")
return amba;
else if (if_name == "redistributor")
return redistributor;
else
return scx_evs_CortexA76x1::gem5_getPort(if_name, idx);
}
} // namespace FastModel
FastModel::CortexA76x1 *
FastModelCortexA76x1Params::create()
{
return new FastModel::CortexA76x1(name.c_str(), *this);
}