| /* |
| * 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 "systemc/tlm_bridge/gem5_to_tlm.hh" |
| |
| namespace gem5 |
| { |
| |
| GEM5_DEPRECATED_NAMESPACE(FastModel, fastmodel); |
| 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); |
| } |
| |
| void |
| CortexR52::setResetAddr(Addr addr, bool secure) |
| { |
| evs_base_cpu->setResetAddr(num, addr, secure); |
| } |
| |
| 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" || |
| if_name == "core_reset" || if_name == "poweron_reset" || |
| if_name == "halt") { |
| // 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 if (if_name == "ext_slave" || if_name == "top_reset") { |
| assert(idx == InvalidPortID); |
| return evs->gem5_getPort(if_name, idx); |
| } else { |
| return SimObject::getPort(if_name, idx); |
| } |
| } |
| |
| } // namespace fastmodel |
| } // namespace gem5 |