fastmodel: Add a wrapper for the CortexR52.
authorGabe Black <gabeblack@google.com>
Tue, 4 Aug 2020 07:46:52 +0000 (00:46 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 13 Oct 2020 12:53:42 +0000 (12:53 +0000)
There has been some testing of this wrapper, but some components are
missing. It's not currently possible to read or set Misc registers,
64 bit integer registers, flattened integer registers, or vector
registers. In some cases that's because no mapping from gem5 indexes
to IRIS resource names has been set up, but in some cases, since R52
is 32 bit, no mapping *can* be set up, and we need to figure out what
to do with requests for 64 bit only state.

Change-Id: I2d650a7c1765b39f25058727502c96e6de5aa26b
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35635
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
16 files changed:
src/arch/arm/fastmodel/CortexR52/FastModelCortexR52.py [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/SConscript [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/cortex_r52.cc [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/cortex_r52.hh [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/evs.cc [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/evs.hh [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/thread_context.cc [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/thread_context.hh [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/x1/x1.lisa [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/x1/x1.sgproj [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/x2/x2.lisa [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/x2/x2.sgproj [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/x3/x3.lisa [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/x3/x3.sgproj [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/x4/x4.lisa [new file with mode: 0644]
src/arch/arm/fastmodel/CortexR52/x4/x4.sgproj [new file with mode: 0644]

diff --git a/src/arch/arm/fastmodel/CortexR52/FastModelCortexR52.py b/src/arch/arm/fastmodel/CortexR52/FastModelCortexR52.py
new file mode 100644 (file)
index 0000000..39b7d44
--- /dev/null
@@ -0,0 +1,220 @@
+# 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.
+
+from m5.params import *
+from m5.proxy import *
+from m5.SimObject import SimObject
+
+from m5.objects.ArmInterrupts import ArmInterrupts
+from m5.objects.ArmISA import ArmISA
+from m5.objects.FastModel import AmbaInitiatorSocket
+from m5.objects.IntPin import VectorIntSinkPin
+from m5.objects.Iris import IrisBaseCPU
+from m5.objects.SystemC import SystemC_ScModule
+
+class FastModelCortexR52(IrisBaseCPU):
+    type = 'FastModelCortexR52'
+    cxx_class = 'FastModel::CortexR52'
+    cxx_header = 'arch/arm/fastmodel/CortexR52/cortex_r52.hh'
+
+    evs = Parent.evs
+
+    ppi = VectorIntSinkPin('PPI inputs (0-8)')
+
+    llpp = AmbaInitiatorSocket(64, 'Low Latency Peripheral Port')
+    flash = AmbaInitiatorSocket(64, 'Flash')
+    amba = AmbaInitiatorSocket(64, 'AMBA initiator socket')
+
+    CFGEND = Param.Bool(False, "Endianness configuration at reset.  0, " \
+            "little endian. 1, big endian.")
+    CFGTE = Param.Bool(False, "Equivalent to CFGTHUMBEXCEPTIONS")
+    RVBARADDR = Param.UInt32(0, "Equivalent to CFGVECTABLE")
+    ase_present = Param.Bool(True, "Set whether the model has been built " \
+            "with NEON support")
+    dcache_size = Param.UInt16(0x8000, "L1 D-Cache size in bytes")
+    flash_enable = Param.Bool(False, "Equivalent to CFGFLASHEN")
+    icache_size = Param.UInt16(0x8000, "L1 I-Cache size in bytes")
+    llpp_base = Param.UInt32(0, "Equivalent to CFGLLPPBASEADDR")
+    llpp_size = Param.UInt32(0x1000, "Equivalent to CFGLLPPSIZE")
+    max_code_cache_mb = Param.UInt64(0x100, "Maximum size of the " \
+            "simulation code cache (MiB). For platforms with more than 2 " \
+            "cores this limit will be scaled down. (e.g 1/8 for 16 or more " \
+            "cores).")
+    min_sync_level = Param.UInt8(0, "Force minimum syncLevel " \
+            "(0=off=default,1=syncState,2=postInsnIO,3=postInsnAll)")
+    semihosting_A32_HLT = Param.UInt16(0xf000, "A32 HLT number for " \
+            "semihosting calls.")
+    semihosting_ARM_SVC = Param.UInt32(0x123456, "A32 SVC number for " \
+            "semihosting calls.")
+    semihosting_T32_HLT = Param.UInt8(60, "T32 HLT number for semihosting " \
+            "calls.")
+    semihosting_Thumb_SVC = Param.UInt8(171, "T32 SVC number for " \
+            "semihosting calls.")
+    semihosting_cmd_line = Param.String("", "Command line available to " \
+            "semihosting calls.")
+    semihosting_cwd = Param.String("", "Base directory for semihosting " \
+            "file access.")
+    semihosting_enable = Param.Bool(True, "Enable semihosting SVC/HLT traps.")
+    semihosting_heap_base = Param.UInt32(0, "Virtual address of heap base.")
+    semihosting_heap_limit = Param.UInt32(0xf000000, "Virtual address of " \
+            "top of heap.")
+    semihosting_stack_base = Param.UInt32(0x10000000, "Virtual address of " \
+            "base of descending stack.")
+    semihosting_stack_limit = Param.UInt32(0xf000000, "Virtual address of " \
+            "stack limit.")
+    tcm_a_enable = Param.Bool(False, "Equivalent to CFGTCMBOOT")
+    tcm_a_size = Param.UInt32(0x4000, "Sets the size of the ATCM(in bytes)")
+    tcm_b_size = Param.UInt32(0x4000, "Sets the size of the BTCM(in bytes)")
+    tcm_c_size = Param.UInt32(0x2000, "Sets the size of the CTCM(in bytes)")
+    vfp_dp_present = Param.Bool(True, "Whether double-precision floating " \
+            "point feature is implemented")
+    vfp_enable_at_reset = Param.Bool(False, "Enable VFP in CPACR, CPPWR, " \
+            "NSACR at reset. Warning: Arm recommends going through the "
+            "implementation's suggested VFP power-up sequence!")
+
+class FastModelCortexR52Cluster(SimObject):
+    type = 'FastModelCortexR52Cluster'
+    cxx_class = 'FastModel::CortexR52Cluster'
+    cxx_header = 'arch/arm/fastmodel/CortexR52/cortex_r52.hh'
+
+    cores = VectorParam.FastModelCortexR52(
+            'Core in a given cluster of CortexR52s')
+
+    evs = Param.SystemC_ScModule(
+            "Fast mo0del exported virtual subsystem holding cores")
+
+    spi = VectorIntSinkPin('SPI inputs (0-959)')
+
+    CLUSTER_ID = Param.UInt16(0, "CLUSTER_ID[15:8] equivalent to " \
+            "CFGMPIDRAFF2, CLUSTER_ID[7:0] equivalent to CFGMPIDRAFF1")
+    DBGROMADDR = Param.UInt32(0, "Equivalent to CFGDBGROMADDR")
+    DBGROMADDRV = Param.Bool(False, "If true, set bits[1:0] of the CP15 " \
+            "DBGDRAR to indicate that the address is valid")
+    PERIPHBASE = Param.UInt32(0x13080000, "Equivalent to CFGPERIPHBASE")
+    cluster_utid = Param.UInt8(0, "Equivalent to CFGCLUSTERUTID")
+    cpi_div = Param.UInt32(1, "Divider for calculating CPI " \
+            "(Cycles Per Instruction)")
+    cpi_mul = Param.UInt32(1, "Multiplier for calculating CPI " \
+            "(Cycles Per Instruction)")
+    dcache_prefetch_enabled = Param.Bool(False, "Enable simulation of data " \
+            "cache prefetching.  This is only used when " \
+            "dcache-state_modelled=true")
+    dcache_read_access_latency = Param.UInt64(0, "L1 D-Cache timing " \
+            "annotation latency for read accesses given in ticks per access " \
+            "(of size dcache-read_bus_width_in_bytes).  If this parameter " \
+            "is non-zero, per-access latencies will be used instead of " \
+            "per-byte even if dcache-read_latency is set. This is in " \
+            "addition to the hit or miss latency, and intended to " \
+            "correspond to the time taken to transfer across the cache " \
+            "upstream bus, this is only used when dcache-state_modelled=true.")
+    dcache_state_modelled = Param.Bool(False, "Set whether D-cache has " \
+            "stateful implementation")
+    dcache_write_access_latency = Param.UInt64(0, "L1 D-Cache timing " \
+            "annotation latency for write accesses given in ticks per " \
+            "access (of size dcache-write_bus_width_in_bytes). If this " \
+            "parameter is non-zero, per-access latencies will be used " \
+            "instead of per-byte even if dcache-write_latency is set. This " \
+            "is only used when dcache-state_modelled=true.")
+    flash_protection_enable_at_reset = Param.Bool(False, "Equivalent to " \
+            "CFGFLASHPROTEN")
+    has_flash_protection = Param.Bool(True, "Equivalent to CFGFLASHPROTIMP")
+    icache_prefetch_enabled = Param.Bool(False, "Enable simulation of " \
+            "instruction cache prefetching. This is only used when " \
+            "icache-state_modelled=true.")
+    icache_read_access_latency = Param.UInt64(0, "L1 I-Cache timing " \
+            "annotation latency for read accesses given in ticks per access " \
+            "(of size icache-read_bus_width_in_bytes).  If this parameter " \
+            "is non-zero, per-access latencies will be used instead of " \
+            "per-byte even if icache-read_latency is set. This is in " \
+            "addition to the hit or miss latency, and intended to " \
+            "correspond to the time taken to transfer across the cache " \
+            "upstream bus, this is only used when icache-state_modelled=true.")
+    icache_state_modelled = Param.Bool(False, "Set whether I-cache has " \
+            "stateful implementation")
+    memory_ext_slave_base = Param.UInt32(0, "Equivalent to CFGAXISTCMBASEADDR")
+    memory_flash_base = Param.UInt32(0, "Equivalent to CFGFLASHBASEADDR")
+    memory_flash_size = Param.UInt32(0x4000000, "Equivalent to CFGFLASHIMP. " \
+            "memory.flash_size = 0 => CFGFLASHIMP = false")
+    num_protection_regions_s1 = Param.UInt8(16, "Number of v8-R stage1 " \
+            "protection regions")
+    num_protection_regions_s2 = Param.UInt8(16, "Number of v8-R hyp " \
+            "protection regions")
+    num_spi = Param.UInt16(960, "Number of interrupts (SPI) into the " \
+            "internal GIC controller")
+    ram_protection_enable_at_reset = Param.Bool(False, "Equivalent to " \
+            "CFGRAMPROTEN")
+    has_export_m_port = Param.Bool(True, "The interrupt distributor has an " \
+            "optional interrupt export port for routing interrupts to an " \
+            "external device")
+
+class FastModelScxEvsCortexR52x1(SystemC_ScModule):
+    type = 'FastModelScxEvsCortexR52x1'
+    cxx_class = 'FastModel::ScxEvsCortexR52<FastModel::ScxEvsCortexR52x1Types>'
+    cxx_template_params = [ 'class Types' ]
+    cxx_header = 'arch/arm/fastmodel/CortexR52/evs.hh'
+
+class FastModelCortexR52x1(FastModelCortexR52Cluster):
+    cores = [ FastModelCortexR52(thread_paths=[ 'core.cpu0' ]) ]
+
+    evs = FastModelScxEvsCortexR52x1()
+
+class FastModelScxEvsCortexR52x2(SystemC_ScModule):
+    type = 'FastModelScxEvsCortexR52x2'
+    cxx_class = 'FastModel::ScxEvsCortexR52<FastModel::ScxEvsCortexR52x2Types>'
+    cxx_template_params = [ 'class Types' ]
+    cxx_header = 'arch/arm/fastmodel/CortexR52/evs.hh'
+
+class FastModelCortexR52x2(FastModelCortexR52Cluster):
+    cores = [ FastModelCortexR52(thread_paths=[ 'core.cpu0' ]),
+              FastModelCortexR52(thread_paths=[ 'core.cpu1' ]) ]
+
+    evs = FastModelScxEvsCortexR52x2()
+
+class FastModelScxEvsCortexR52x3(SystemC_ScModule):
+    type = 'FastModelScxEvsCortexR52x3'
+    cxx_class = 'FastModel::ScxEvsCortexR52<FastModel::ScxEvsCortexR52x3Types>'
+    cxx_template_params = [ 'class Types' ]
+    cxx_header = 'arch/arm/fastmodel/CortexR52/evs.hh'
+
+class FastModelCortexR52x3(FastModelCortexR52Cluster):
+    cores = [ FastModelCortexR52(thread_paths=[ 'core.cpu0' ]),
+              FastModelCortexR52(thread_paths=[ 'core.cpu1' ]),
+              FastModelCortexR52(thread_paths=[ 'core.cpu2' ]) ]
+
+    evs = FastModelScxEvsCortexR52x3()
+
+class FastModelScxEvsCortexR52x4(SystemC_ScModule):
+    type = 'FastModelScxEvsCortexR52x4'
+    cxx_class = 'FastModel::ScxEvsCortexR52<FastModel::ScxEvsCortexR52x4Types>'
+    cxx_template_params = [ 'class Types' ]
+    cxx_header = 'arch/arm/fastmodel/CortexR52/evs.hh'
+
+class FastModelCortexR52x4(FastModelCortexR52Cluster):
+    cores = [ FastModelCortexR52(thread_paths=[ 'core.cpu0' ]),
+              FastModelCortexR52(thread_paths=[ 'core.cpu1' ]),
+              FastModelCortexR52(thread_paths=[ 'core.cpu2' ]),
+              FastModelCortexR52(thread_paths=[ 'core.cpu3' ]) ]
+
+    evs = FastModelScxEvsCortexR52x4()
diff --git a/src/arch/arm/fastmodel/CortexR52/SConscript b/src/arch/arm/fastmodel/CortexR52/SConscript
new file mode 100644 (file)
index 0000000..3f7a2c8
--- /dev/null
@@ -0,0 +1,44 @@
+# 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.
+
+Import('*')
+
+if not env['USE_ARM_FASTMODEL'] or env['TARGET_ISA'] != 'arm':
+    Return()
+
+protocol_dir = Dir('..').Dir('protocol')
+
+for name in ('x1', 'x2', 'x3', 'x4'):
+    ArmFastModelComponent(Dir(name).File(name + '.sgproj'),
+                          Dir(name).File(name + '.lisa'),
+                          protocol_dir.File(
+                              'ExportedClockRateControlProtocol.lisa'),
+                          protocol_dir.File('SignalInterruptProtocol.lisa')
+                          ).prepare_env(env)
+
+SimObject('FastModelCortexR52.py')
+Source('cortex_r52.cc')
+Source('evs.cc')
+Source('thread_context.cc')
diff --git a/src/arch/arm/fastmodel/CortexR52/cortex_r52.cc b/src/arch/arm/fastmodel/CortexR52/cortex_r52.cc
new file mode 100644 (file)
index 0000000..c246435
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * 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(Params &p) :
+    SimObject(&p), _params(p), cores(p.cores), evs(p.evs)
+{
+    for (int i = 0; i < p.cores.size(); i++)
+        p.cores[i]->setCluster(this, i);
+
+    sc_core::sc_attr_base *base;
+
+    base = evs->get_attribute(Iris::Gem5CpuClusterAttributeName);
+    auto *gem5_cluster_attr =
+        dynamic_cast<sc_core::sc_attribute<CortexR52Cluster *> *>(base);
+    panic_if(base && !gem5_cluster_attr,
+             "The EVS gem5 CPU cluster attribute was not of type "
+             "sc_attribute<FastModel::CortexR52Cluster *>.");
+    if (gem5_cluster_attr)
+        gem5_cluster_attr->value = 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
+
+FastModel::CortexR52 *
+FastModelCortexR52Params::create()
+{
+    return new FastModel::CortexR52(*this);
+}
+
+FastModel::CortexR52Cluster *
+FastModelCortexR52ClusterParams::create()
+{
+    return new FastModel::CortexR52Cluster(*this);
+}
diff --git a/src/arch/arm/fastmodel/CortexR52/cortex_r52.hh b/src/arch/arm/fastmodel/CortexR52/cortex_r52.hh
new file mode 100644 (file)
index 0000000..2e1700d
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_FASTMODEL_CORTEXR52_CORETEX_R52_HH__
+#define __ARCH_ARM_FASTMODEL_CORTEXR52_CORETEX_R52_HH__
+
+#include "arch/arm/fastmodel/CortexR52/thread_context.hh"
+#include "arch/arm/fastmodel/amba_ports.hh"
+#include "arch/arm/fastmodel/iris/cpu.hh"
+#include "params/FastModelCortexR52.hh"
+#include "params/FastModelCortexR52Cluster.hh"
+#include "scx/scx.h"
+#include "sim/port.hh"
+#include "systemc/ext/core/sc_module.hh"
+
+class BaseCPU;
+
+namespace FastModel
+{
+
+// The fast model exports a class called scx_evs_CortexR52x1 which represents
+// the subsystem described in LISA+. This class specializes it to export gem5
+// ports and interface with its peer gem5 CPU. The gem5 CPU inherits from the
+// gem5 BaseCPU class and implements its API, while this class actually does
+// the work.
+class CortexR52Cluster;
+
+class CortexR52 : public Iris::CPU<CortexR52TC>
+{
+  protected:
+    typedef FastModelCortexR52Params Params;
+    typedef Iris::CPU<CortexR52TC> Base;
+    const Params &_params;
+
+    CortexR52Cluster *cluster = nullptr;
+    int num = 0;
+
+    const Params &params() { return _params; }
+
+  public:
+    CortexR52(Params &p) : Base(&p, scx::scx_get_iris_connection_interface()),
+        _params(p)
+    {}
+
+    template <class T>
+    void set_evs_param(const std::string &n, T val);
+
+    void setCluster(CortexR52Cluster *_cluster, int _num);
+
+    Port &getPort(const std::string &if_name,
+            PortID idx=InvalidPortID) override;
+};
+
+class CortexR52Cluster : public SimObject
+{
+  private:
+    typedef FastModelCortexR52ClusterParams Params;
+    const Params &_params;
+
+    std::vector<CortexR52 *> cores;
+    sc_core::sc_module *evs;
+
+  public:
+    template <class T>
+    void
+    set_evs_param(const std::string &n, T val)
+    {
+        scx::scx_set_parameter(evs->name() + std::string(".") + n, val);
+    }
+
+    CortexR52 *getCore(int num) const { return cores.at(num); }
+    sc_core::sc_module *getEvs() const { return evs; }
+
+    CortexR52Cluster(Params &p);
+    const Params &params() { return _params; }
+
+    Port &getPort(const std::string &if_name,
+            PortID idx=InvalidPortID) override;
+};
+
+template <class T>
+inline void
+CortexR52::set_evs_param(const std::string &n, T val)
+{
+    for (auto &path: params().thread_paths)
+        cluster->set_evs_param(path + "." + n, val);
+}
+
+} // namespace FastModel
+
+#endif // __ARCH_ARM_FASTMODEL_CORTEXR52_CORETEX_R52_HH__
diff --git a/src/arch/arm/fastmodel/CortexR52/evs.cc b/src/arch/arm/fastmodel/CortexR52/evs.cc
new file mode 100644 (file)
index 0000000..88812ee
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * 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/evs.hh"
+
+#include "arch/arm/fastmodel/iris/cpu.hh"
+#include "base/logging.hh"
+#include "sim/core.hh"
+#include "systemc/tlm_bridge/gem5_to_tlm.hh"
+
+namespace FastModel
+{
+
+template <class Types>
+void
+ScxEvsCortexR52<Types>::clockChangeHandler()
+{
+    clockRateControl->set_mul_div(SimClock::Int::s, clockPeriod.value);
+}
+
+template <class Types>
+ScxEvsCortexR52<Types>::CorePins::CorePins(Evs *_evs, int _cpu) :
+        name(csprintf("%s.cpu%s", _evs->name(), _cpu)),
+    evs(_evs), cpu(_cpu),
+    llpp(evs->llpp[cpu], name + ".llpp", -1),
+    flash(evs->flash[cpu], name + ".flash", -1),
+    amba(evs->amba[cpu], name + ".amba", -1)
+{
+    for (int i = 0; i < Evs::PpiCount; i++) {
+        ppis.emplace_back(
+                new CoreInt(csprintf("%s.ppi[%d]", name, i), i, this));
+    }
+}
+
+
+template <class Types>
+ScxEvsCortexR52<Types>::ScxEvsCortexR52(
+        const sc_core::sc_module_name &mod_name, const Params &p) :
+    Base(mod_name),
+    clockChanged(Iris::ClockEventName.c_str()),
+    clockPeriod(Iris::PeriodAttributeName.c_str()),
+    gem5CpuCluster(Iris::Gem5CpuClusterAttributeName.c_str()),
+    sendFunctional(Iris::SendFunctionalAttributeName.c_str()),
+    params(p)
+{
+    for (int i = 0; i < CoreCount; i++)
+        corePins.emplace_back(new CorePins(this, i));
+
+    for (int i = 0; i < SpiCount; i++) {
+        spis.emplace_back(
+                new ClstrInt(csprintf("%s.spi[%d]", name(), i), i, this));
+    }
+
+    clockRateControl.bind(this->clock_rate_s);
+    signalInterrupt.bind(this->signal_interrupt);
+
+    this->add_attribute(gem5CpuCluster);
+    this->add_attribute(clockPeriod);
+    SC_METHOD(clockChangeHandler);
+    this->dont_initialize();
+    this->sensitive << clockChanged;
+
+    sendFunctional.value = [this](PacketPtr pkt) { sendFunc(pkt); };
+    this->add_attribute(sendFunctional);
+}
+
+template <class Types>
+void
+ScxEvsCortexR52<Types>::sendFunc(PacketPtr pkt)
+{
+    auto *trans = sc_gem5::packet2payload(pkt);
+    panic_if(Base::amba[0]->transport_dbg(*trans) != trans->get_data_length(),
+            "Didn't send entire functional packet!");
+    trans->release();
+}
+
+template <class Types>
+Port &
+ScxEvsCortexR52<Types>::gem5_getPort(const std::string &if_name, int idx)
+{
+    if (if_name == "llpp") {
+        return this->corePins.at(idx)->llpp;
+    } else if (if_name == "flash") {
+        return this->corePins.at(idx)->flash;
+    } else if (if_name == "amba") {
+        return this->corePins.at(idx)->amba;
+    } else if (if_name == "spi") {
+        return *this->spis.at(idx);
+    } else if (if_name.substr(0, 3) == "ppi") {
+        int cpu;
+        try {
+            cpu = std::stoi(if_name.substr(4));
+        } catch (const std::invalid_argument &a) {
+            panic("Couldn't find CPU number in %s.", if_name);
+        }
+        return *this->corePins.at(cpu)->ppis.at(idx);
+    } else {
+        return Base::gem5_getPort(if_name, idx);
+    }
+}
+
+template class ScxEvsCortexR52<ScxEvsCortexR52x1Types>;
+template class ScxEvsCortexR52<ScxEvsCortexR52x2Types>;
+template class ScxEvsCortexR52<ScxEvsCortexR52x3Types>;
+template class ScxEvsCortexR52<ScxEvsCortexR52x4Types>;
+
+} // namespace FastModel
+
+FastModel::ScxEvsCortexR52x1 *
+FastModelScxEvsCortexR52x1Params::create()
+{
+    return new FastModel::ScxEvsCortexR52x1(name.c_str(), *this);
+}
+
+FastModel::ScxEvsCortexR52x2 *
+FastModelScxEvsCortexR52x2Params::create()
+{
+    return new FastModel::ScxEvsCortexR52x2(name.c_str(), *this);
+}
+
+FastModel::ScxEvsCortexR52x3 *
+FastModelScxEvsCortexR52x3Params::create()
+{
+    return new FastModel::ScxEvsCortexR52x3(name.c_str(), *this);
+}
+
+FastModel::ScxEvsCortexR52x4 *
+FastModelScxEvsCortexR52x4Params::create()
+{
+    return new FastModel::ScxEvsCortexR52x4(name.c_str(), *this);
+}
diff --git a/src/arch/arm/fastmodel/CortexR52/evs.hh b/src/arch/arm/fastmodel/CortexR52/evs.hh
new file mode 100644 (file)
index 0000000..c49a9ad
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_FASTMODEL_CORTEXR52_EVS_HH__
+#define __ARCH_ARM_FASTMODEL_CORTEXR52_EVS_HH__
+
+#include <memory>
+
+#include "arch/arm/fastmodel/amba_ports.hh"
+#include "arch/arm/fastmodel/common/signal_receiver.hh"
+#include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh"
+#include "arch/arm/fastmodel/protocol/signal_interrupt.hh"
+#include "dev/intpin.hh"
+#include "mem/port_proxy.hh"
+#include "params/FastModelScxEvsCortexR52x1.hh"
+#include "params/FastModelScxEvsCortexR52x2.hh"
+#include "params/FastModelScxEvsCortexR52x3.hh"
+#include "params/FastModelScxEvsCortexR52x4.hh"
+#include "scx_evs_CortexR52x1.h"
+#include "scx_evs_CortexR52x2.h"
+#include "scx_evs_CortexR52x3.h"
+#include "scx_evs_CortexR52x4.h"
+#include "systemc/ext/core/sc_event.hh"
+#include "systemc/ext/core/sc_module.hh"
+#include "systemc/tlm_port_wrapper.hh"
+
+namespace FastModel
+{
+
+class CortexR52Cluster;
+
+template <class Types>
+class ScxEvsCortexR52 : public Types::Base
+{
+  private:
+    static const int CoreCount = Types::CoreCount;
+    static const int PpiCount = 9;
+    static const int SpiCount = 960;
+    using Base = typename Types::Base;
+    using Params = typename Types::Params;
+    using Evs = ScxEvsCortexR52<Types>;
+
+    SC_HAS_PROCESS(ScxEvsCortexR52);
+
+    ClockRateControlInitiatorSocket clockRateControl;
+    SignalInterruptInitiatorSocket signalInterrupt;
+
+    // A structure to collect per-core connections, and also plumb up PPIs.
+    struct CorePins
+    {
+        using CoreInt = IntSinkPin<CorePins>;
+
+        std::string name;
+        Evs *evs;
+        int cpu;
+
+        CorePins(Evs *_evs, int _cpu);
+
+        void
+        raiseInterruptPin(int num)
+        {
+            evs->signalInterrupt->ppi(cpu, num, true);
+        }
+
+        void
+        lowerInterruptPin(int num)
+        {
+            evs->signalInterrupt->ppi(cpu, num, false);
+        }
+
+        std::vector<std::unique_ptr<CoreInt>> ppis;
+
+        AmbaInitiator llpp;
+        AmbaInitiator flash;
+        AmbaInitiator amba;
+    };
+
+    std::vector<std::unique_ptr<CorePins>> corePins;
+
+    using ClstrInt = IntSinkPin<ScxEvsCortexR52>;
+
+    std::vector<std::unique_ptr<ClstrInt>> spis;
+
+    sc_core::sc_event clockChanged;
+    sc_core::sc_attribute<Tick> clockPeriod;
+    sc_core::sc_attribute<CortexR52Cluster *> gem5CpuCluster;
+    sc_core::sc_attribute<PortProxy::SendFunctionalFunc> sendFunctional;
+
+    void sendFunc(PacketPtr pkt);
+
+    void clockChangeHandler();
+
+    const Params &params;
+
+  public:
+    ScxEvsCortexR52(const sc_core::sc_module_name &mod_name, const Params &p);
+
+    void
+    raiseInterruptPin(int num)
+    {
+        this->signalInterrupt->spi(num, true);
+    }
+
+    void
+    lowerInterruptPin(int num)
+    {
+        this->signalInterrupt->spi(num, false);
+    }
+
+    Port &gem5_getPort(const std::string &if_name, int idx) override;
+
+    void
+    end_of_elaboration() override
+    {
+        Base::end_of_elaboration();
+        Base::start_of_simulation();
+    }
+    void start_of_simulation() override {}
+};
+
+struct ScxEvsCortexR52x1Types
+{
+    using Base = scx_evs_CortexR52x1;
+    using Params = FastModelScxEvsCortexR52x1Params;
+    static const int CoreCount = 1;
+};
+using ScxEvsCortexR52x1 = ScxEvsCortexR52<ScxEvsCortexR52x1Types>;
+extern template class ScxEvsCortexR52<ScxEvsCortexR52x1Types>;
+
+struct ScxEvsCortexR52x2Types
+{
+    using Base = scx_evs_CortexR52x2;
+    using Params = FastModelScxEvsCortexR52x2Params;
+    static const int CoreCount = 2;
+};
+using ScxEvsCortexR52x2 = ScxEvsCortexR52<ScxEvsCortexR52x2Types>;
+extern template class ScxEvsCortexR52<ScxEvsCortexR52x2Types>;
+
+struct ScxEvsCortexR52x3Types
+{
+    using Base = scx_evs_CortexR52x3;
+    using Params = FastModelScxEvsCortexR52x3Params;
+    static const int CoreCount = 3;
+};
+using ScxEvsCortexR52x3 = ScxEvsCortexR52<ScxEvsCortexR52x3Types>;
+extern template class ScxEvsCortexR52<ScxEvsCortexR52x3Types>;
+
+struct ScxEvsCortexR52x4Types
+{
+    using Base = scx_evs_CortexR52x4;
+    using Params = FastModelScxEvsCortexR52x4Params;
+    static const int CoreCount = 4;
+};
+using ScxEvsCortexR52x4 = ScxEvsCortexR52<ScxEvsCortexR52x4Types>;
+extern template class ScxEvsCortexR52<ScxEvsCortexR52x4Types>;
+
+} // namespace FastModel
+
+#endif // __ARCH_ARM_FASTMODEL_CORTEXR52_EVS_HH__
diff --git a/src/arch/arm/fastmodel/CortexR52/thread_context.cc b/src/arch/arm/fastmodel/CortexR52/thread_context.cc
new file mode 100644 (file)
index 0000000..648a39a
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * 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/thread_context.hh"
+
+#include "arch/arm/fastmodel/iris/memory_spaces.hh"
+#include "arch/arm/utility.hh"
+#include "iris/detail/IrisCppAdapter.h"
+#include "iris/detail/IrisObjects.h"
+
+namespace FastModel
+{
+
+CortexR52TC::CortexR52TC(
+        ::BaseCPU *cpu, int id, System *system, ::BaseTLB *dtb, ::BaseTLB *itb,
+        ::BaseISA *isa, iris::IrisConnectionInterface *iris_if,
+        const std::string &iris_path) :
+    ThreadContext(cpu, id, system, dtb, itb, isa, iris_if, iris_path)
+{}
+
+bool
+CortexR52TC::translateAddress(Addr &paddr, Addr vaddr)
+{
+    // Determine what memory spaces are currently active.
+    Iris::CanonicalMsn in_msn;
+    switch (ArmISA::currEL(this)) {
+      case ArmISA::EL3:
+        in_msn = Iris::SecureMonitorMsn;
+        break;
+      case ArmISA::EL2:
+        in_msn = Iris::NsHypMsn;
+        break;
+      default:
+        in_msn = Iris::GuestMsn;
+        break;
+    }
+
+    Iris::CanonicalMsn out_msn = ArmISA::isSecure(this) ?
+        Iris::PhysicalMemorySecureMsn : Iris::PhysicalMemoryNonSecureMsn;
+
+    // Figure out what memory spaces match the canonical numbers we need.
+    iris::MemorySpaceId in = iris::IRIS_UINT64_MAX;
+    iris::MemorySpaceId out = iris::IRIS_UINT64_MAX;
+
+    for (auto &space: memorySpaces) {
+        if (space.canonicalMsn == in_msn)
+            in = space.spaceId;
+        else if (space.canonicalMsn == out_msn)
+            out = space.spaceId;
+    }
+
+    panic_if(in == iris::IRIS_UINT64_MAX || out == iris::IRIS_UINT64_MAX,
+            "Canonical IRIS memory space numbers not found.");
+
+    return ThreadContext::translateAddress(paddr, out, vaddr, in);
+}
+
+void
+CortexR52TC::initFromIrisInstance(const ResourceMap &resources)
+{
+    pcRscId = extractResourceId(resources, "R15");
+
+    extractResourceMap(intReg32Ids, resources, intReg32IdxNameMap);
+    extractResourceMap(ccRegIds, resources, ccRegIdxNameMap);
+}
+
+RegVal
+CortexR52TC::readIntReg(RegIndex reg_idx) const
+{
+    iris::ResourceReadResult result;
+    call().resource_read(_instId, result, intReg32Ids.at(reg_idx));
+    return result.data.at(0);
+}
+
+void
+CortexR52TC::setIntReg(RegIndex reg_idx, RegVal val)
+{
+    iris::ResourceWriteResult result;
+    call().resource_write(_instId, result, intReg32Ids.at(reg_idx), val);
+}
+
+RegVal
+CortexR52TC::readCCRegFlat(RegIndex idx) const
+{
+    RegVal result = Iris::ThreadContext::readCCRegFlat(idx);
+    switch (idx) {
+      case ArmISA::CCREG_NZ:
+        result = ((ArmISA::CPSR)result).nz;
+        break;
+      case ArmISA::CCREG_FP:
+        result = bits(result, 31, 28);
+        break;
+      default:
+        break;
+    }
+    return result;
+}
+
+void
+CortexR52TC::setCCRegFlat(RegIndex idx, RegVal val)
+{
+    switch (idx) {
+      case ArmISA::CCREG_NZ:
+        {
+            ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
+            cpsr.nz = val;
+            val = cpsr;
+        }
+        break;
+      case ArmISA::CCREG_FP:
+        {
+            ArmISA::FPSCR fpscr = readMiscRegNoEffect(ArmISA::MISCREG_FPSCR);
+            val = insertBits(fpscr, 31, 28, val);
+        }
+        break;
+      default:
+        break;
+    }
+    Iris::ThreadContext::setCCRegFlat(idx, val);
+}
+
+const std::vector<iris::MemorySpaceId> &
+CortexR52TC::getBpSpaceIds() const
+{
+    if (bpSpaceIds.empty()) {
+        for (auto &space: memorySpaces) {
+            auto cmsn = space.canonicalMsn;
+            if (cmsn == Iris::SecureMonitorMsn ||
+                    cmsn == Iris::GuestMsn ||
+                    cmsn == Iris::NsHypMsn ||
+                    cmsn == Iris::HypAppMsn) {
+                bpSpaceIds.push_back(space.spaceId);
+            }
+        }
+        panic_if(bpSpaceIds.empty(),
+                "Unable to find address space(s) for breakpoints.");
+    }
+    return bpSpaceIds;
+}
+
+Iris::ThreadContext::IdxNameMap CortexR52TC::intReg32IdxNameMap({
+        { ArmISA::INTREG_R0, "R0" },
+        { ArmISA::INTREG_R1, "R1" },
+        { ArmISA::INTREG_R2, "R2" },
+        { ArmISA::INTREG_R3, "R3" },
+        { ArmISA::INTREG_R4, "R4" },
+        { ArmISA::INTREG_R5, "R5" },
+        { ArmISA::INTREG_R6, "R6" },
+        { ArmISA::INTREG_R7, "R7" },
+        { ArmISA::INTREG_R8, "R8" },
+        { ArmISA::INTREG_R9, "R9" },
+        { ArmISA::INTREG_R10, "R10" },
+        { ArmISA::INTREG_R11, "R11" },
+        { ArmISA::INTREG_R12, "R12" },
+        { ArmISA::INTREG_R13, "R13" },
+        { ArmISA::INTREG_R14, "R14" },
+        { ArmISA::INTREG_R15, "R15" }
+});
+
+Iris::ThreadContext::IdxNameMap CortexR52TC::ccRegIdxNameMap({
+        { ArmISA::CCREG_NZ, "CPSR" },
+        { ArmISA::CCREG_C, "CPSR.C" },
+        { ArmISA::CCREG_V, "CPSR.V" },
+        { ArmISA::CCREG_GE, "CPSR.GE" },
+        { ArmISA::CCREG_FP, "FPSCR" },
+});
+
+std::vector<iris::MemorySpaceId> CortexR52TC::bpSpaceIds;
+
+} // namespace FastModel
diff --git a/src/arch/arm/fastmodel/CortexR52/thread_context.hh b/src/arch/arm/fastmodel/CortexR52/thread_context.hh
new file mode 100644 (file)
index 0000000..74ac1a0
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_FASTMODEL_CORTEXR52_THREAD_CONTEXT_HH__
+#define __ARCH_ARM_FASTMODEL_CORTEXR52_THREAD_CONTEXT_HH__
+
+#include "arch/arm/fastmodel/iris/thread_context.hh"
+
+namespace FastModel
+{
+
+// This ThreadContext class translates accesses to state using gem5's native
+// to the Iris API. This includes extracting and translating register indices.
+class CortexR52TC : public Iris::ThreadContext
+{
+  protected:
+    static IdxNameMap intReg32IdxNameMap;
+    static IdxNameMap ccRegIdxNameMap;
+    static std::vector<iris::MemorySpaceId> bpSpaceIds;
+
+  public:
+    CortexR52TC(::BaseCPU *cpu, int id, System *system,
+                ::BaseTLB *dtb, ::BaseTLB *itb, ::BaseISA *isa,
+                iris::IrisConnectionInterface *iris_if,
+                const std::string &iris_path);
+
+    bool translateAddress(Addr &paddr, Addr vaddr) override;
+
+    void initFromIrisInstance(const ResourceMap &resources) override;
+
+    // Since this CPU doesn't support aarch64, we override these two methods
+    // and always assume we're 32 bit. More than likely we could be more
+    // general than that, but that would require letting the default
+    // implementation read the CPSR, and that's not currently implemented.
+    RegVal readIntReg(RegIndex reg_idx) const override;
+    void setIntReg(RegIndex reg_idx, RegVal val) override;
+
+    RegVal readCCRegFlat(RegIndex idx) const override;
+    void setCCRegFlat(RegIndex idx, RegVal val) override;
+
+    const std::vector<iris::MemorySpaceId> &getBpSpaceIds() const override;
+
+    // The map from gem5 indexes to IRIS resource names is not currently set
+    // up. It will be a little more complicated for R52, since it won't have
+    // many of the registers since it doesn't support aarch64. We may need to
+    // just return dummy values on reads and throw away writes, throw an
+    // error, or some combination of the two.
+    RegVal
+    readMiscRegNoEffect(RegIndex) const override
+    {
+        panic("%s not implemented.", __FUNCTION__);
+    }
+
+    void
+    setMiscRegNoEffect(RegIndex, const RegVal) override
+    {
+        panic("%s not implemented.", __FUNCTION__);
+    }
+
+    // Like the Misc regs, not currently supported and a little complicated.
+    RegVal
+    readIntRegFlat(RegIndex idx) const override
+    {
+        panic("%s not implemented.", __FUNCTION__);
+    }
+
+    void
+    setIntRegFlat(RegIndex idx, RegVal val) override
+    {
+        panic("%s not implemented.", __FUNCTION__);
+    }
+
+    // Not supported by the CPU. There isn't anything to set up here as far
+    // as mapping, but the question still remains what to do about registers
+    // that don't exist in the CPU.
+    const ArmISA::VecRegContainer &
+    readVecReg(const RegId &) const override
+    {
+        panic("%s not implemented.", __FUNCTION__);
+    }
+};
+
+} // namespace FastModel
+
+#endif // __ARCH_ARM_FASTMODEL_CORTEXR52_THREAD_CONTEXT_HH__
diff --git a/src/arch/arm/fastmodel/CortexR52/x1/x1.lisa b/src/arch/arm/fastmodel/CortexR52/x1/x1.lisa
new file mode 100644 (file)
index 0000000..9ed73a6
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+component CortexR52x1
+{
+
+    composition
+    {
+        core : ARMCortexR52x1CT();
+
+        // Clocks.
+        clock1Hz : MasterClock();
+        clockDiv : ClockDivider();
+        clockDivPeriph : ClockDivider(mul=0x01800000);
+    }
+
+    connection
+    {
+        // Memory interfaces.
+        core.llpp_m => self.llpp;
+        core.flash_m => self.flash;
+        core.pvbus_core_m => self.amba;
+
+        // Clocks.
+        clock1Hz.clk_out => clockDiv.clk_in;
+        clock1Hz.clk_out => clockDivPeriph.clk_in;
+        clockDiv.clk_out => core.clk_in;
+
+        // Internal ports for PPI and SPI programmatic access.
+        self.ppi_0 => core.extppi_in_0;
+
+        self.spi => core.spi_in;
+    }
+
+    properties
+    {
+        component_type = "System";
+    }
+
+    master port<PVBus> llpp[1];
+    master port<PVBus> flash[1];
+    master port<PVBus> amba[1];
+
+    slave port<ExportedClockRateControl> clock_rate_s
+    {
+        behavior set_mul_div(uint64_t mul, uint64_t div)
+        {
+            clockDiv.rate.set64(mul, div);
+        }
+    }
+
+    slave port<SignalInterrupt> signal_interrupt
+    {
+        behavior ppi(uint8_t cpu, uint32_t num, bool state_val)
+        {
+            sg::Signal::State state =
+                state_val ? sg::Signal::Set : sg::Signal::Clear;
+
+            sc_assert(cpu < 1);
+            switch (cpu) {
+              case 0:
+                ppi_0[num].setValue(state);
+                break;
+              default:
+                sc_assert(false);
+            }
+        }
+
+        behavior spi(uint32_t num, bool state_val)
+        {
+            sg::Signal::State state =
+                state_val ? sg::Signal::Set : sg::Signal::Clear;
+            spi[num].setValue(state);
+        }
+    }
+
+    internal slave port<Signal> spi[960];
+
+    internal slave port<Signal> ppi_0[9];
+}
diff --git a/src/arch/arm/fastmodel/CortexR52/x1/x1.sgproj b/src/arch/arm/fastmodel/CortexR52/x1/x1.sgproj
new file mode 100644 (file)
index 0000000..4e8d35f
--- /dev/null
@@ -0,0 +1,30 @@
+sgproject "x1.sgproj"
+{
+TOP_LEVEL_COMPONENT = "CortexR52x1";
+ACTIVE_CONFIG_LINUX  = "gcc";
+ACTIVE_CONFIG_WINDOWS  = "Win64-Release-VC2015";
+config "gcc"
+{
+    ADDITIONAL_COMPILER_SETTINGS = "-O3 -Wall -std=c++14 -Wno-deprecated -Wno-unused-function";
+    ADDITIONAL_LINKER_SETTINGS = "-Wl,--no-undefined";
+    BUILD_DIR = "./gcc";
+    COMPILER = "gcc-6.4";
+    CONFIG_DESCRIPTION = "";
+    CONFIG_NAME = "gcc";
+    PLATFORM = "Linux64";
+    PREPROCESSOR_DEFINES = "NDEBUG";
+    SIMGEN_COMMAND_LINE = "--num-comps-file 50";
+    TARGET_MAXVIEW = "0";
+    TARGET_SYSTEMC = "1";
+    TARGET_SYSTEMC_AUTO = "1";
+
+    INCLUDE_DIRS="../../../../../";
+}
+files
+{
+    path = "x1.lisa";
+    path = "${PVLIB_HOME}/etc/sglib.sgrepo";
+    path = "../../protocol/ExportedClockRateControlProtocol.lisa";
+    path = "../../protocol/SignalInterruptProtocol.lisa";
+}
+}
diff --git a/src/arch/arm/fastmodel/CortexR52/x2/x2.lisa b/src/arch/arm/fastmodel/CortexR52/x2/x2.lisa
new file mode 100644 (file)
index 0000000..147d2e9
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+component CortexR52x2
+{
+
+    composition
+    {
+        core : ARMCortexR52x2CT();
+
+        // Clocks.
+        clock1Hz : MasterClock();
+        clockDiv : ClockDivider();
+        clockDivPeriph : ClockDivider(mul=0x01800000);
+    }
+
+    connection
+    {
+        // Memory interfaces.
+        core.llpp_m => self.llpp;
+        core.flash_m => self.flash;
+        core.pvbus_core_m => self.amba;
+
+        // Clocks.
+        clock1Hz.clk_out => clockDiv.clk_in;
+        clock1Hz.clk_out => clockDivPeriph.clk_in;
+        clockDiv.clk_out => core.clk_in;
+
+        // Internal ports for PPI and SPI programmatic access.
+        self.ppi_0 => core.extppi_in_0;
+        self.ppi_1 => core.extppi_in_1;
+
+        self.spi => core.spi_in;
+    }
+
+    properties
+    {
+        component_type = "System";
+    }
+
+    master port<PVBus> llpp[2];
+    master port<PVBus> flash[2];
+    master port<PVBus> amba[2];
+
+    slave port<ExportedClockRateControl> clock_rate_s
+    {
+        behavior set_mul_div(uint64_t mul, uint64_t div)
+        {
+            clockDiv.rate.set64(mul, div);
+        }
+    }
+
+    slave port<SignalInterrupt> signal_interrupt
+    {
+        behavior ppi(uint8_t cpu, uint32_t num, bool state_val)
+        {
+            sg::Signal::State state =
+                state_val ? sg::Signal::Set : sg::Signal::Clear;
+
+            sc_assert(cpu < 2);
+            switch (cpu) {
+              case 0:
+                ppi_0[num].setValue(state);
+                break;
+              case 1:
+                ppi_1[num].setValue(state);
+                break;
+              default:
+                sc_assert(false);
+            }
+        }
+
+        behavior spi(uint32_t num, bool state_val)
+        {
+            sg::Signal::State state =
+                state_val ? sg::Signal::Set : sg::Signal::Clear;
+            spi[num].setValue(state);
+        }
+    }
+
+    internal slave port<Signal> spi[960];
+
+    internal slave port<Signal> ppi_0[9];
+    internal slave port<Signal> ppi_1[9];
+}
diff --git a/src/arch/arm/fastmodel/CortexR52/x2/x2.sgproj b/src/arch/arm/fastmodel/CortexR52/x2/x2.sgproj
new file mode 100644 (file)
index 0000000..ad3d40a
--- /dev/null
@@ -0,0 +1,30 @@
+sgproject "x2.sgproj"
+{
+TOP_LEVEL_COMPONENT = "CortexR52x2";
+ACTIVE_CONFIG_LINUX  = "gcc";
+ACTIVE_CONFIG_WINDOWS  = "Win64-Release-VC2015";
+config "gcc"
+{
+    ADDITIONAL_COMPILER_SETTINGS = "-march=core2 -O3 -Wall -std=c++14 -Wno-deprecated -Wno-unused-function";
+    ADDITIONAL_LINKER_SETTINGS = "-Wl,--no-undefined";
+    BUILD_DIR = "./gcc";
+    COMPILER = "gcc-6.4";
+    CONFIG_DESCRIPTION = "";
+    CONFIG_NAME = "gcc";
+    PLATFORM = "Linux64";
+    PREPROCESSOR_DEFINES = "NDEBUG";
+    SIMGEN_COMMAND_LINE = "--num-comps-file 50";
+    TARGET_MAXVIEW = "0";
+    TARGET_SYSTEMC = "1";
+    TARGET_SYSTEMC_AUTO = "1";
+
+    INCLUDE_DIRS="../../../../../";
+}
+files
+{
+    path = "x2.lisa";
+    path = "${PVLIB_HOME}/etc/sglib.sgrepo";
+    path = "../../protocol/ExportedClockRateControlProtocol.lisa";
+    path = "../../protocol/SignalInterruptProtocol.lisa";
+}
+}
diff --git a/src/arch/arm/fastmodel/CortexR52/x3/x3.lisa b/src/arch/arm/fastmodel/CortexR52/x3/x3.lisa
new file mode 100644 (file)
index 0000000..505c5e3
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+component CortexR52x3
+{
+
+    composition
+    {
+        core : ARMCortexR52x3CT();
+
+        // Clocks.
+        clock1Hz : MasterClock();
+        clockDiv : ClockDivider();
+        clockDivPeriph : ClockDivider(mul=0x01800000);
+    }
+
+    connection
+    {
+        // Memory interfaces.
+        core.llpp_m => self.llpp;
+        core.flash_m => self.flash;
+        core.pvbus_core_m => self.amba;
+
+        // Clocks.
+        clock1Hz.clk_out => clockDiv.clk_in;
+        clock1Hz.clk_out => clockDivPeriph.clk_in;
+        clockDiv.clk_out => core.clk_in;
+
+        // Internal ports for PPI and SPI programmatic access.
+        self.ppi_0 => core.extppi_in_0;
+        self.ppi_1 => core.extppi_in_1;
+        self.ppi_2 => core.extppi_in_2;
+
+        self.spi => core.spi_in;
+    }
+
+    properties
+    {
+        component_type = "System";
+    }
+
+    master port<PVBus> llpp[3];
+    master port<PVBus> flash[3];
+    master port<PVBus> amba[3];
+
+    slave port<ExportedClockRateControl> clock_rate_s
+    {
+        behavior set_mul_div(uint64_t mul, uint64_t div)
+        {
+            clockDiv.rate.set64(mul, div);
+        }
+    }
+
+    slave port<SignalInterrupt> signal_interrupt
+    {
+        behavior ppi(uint8_t cpu, uint32_t num, bool state_val)
+        {
+            sg::Signal::State state =
+                state_val ? sg::Signal::Set : sg::Signal::Clear;
+
+            sc_assert(cpu < 3);
+            switch (cpu) {
+              case 0:
+                ppi_0[num].setValue(state);
+                break;
+              case 1:
+                ppi_1[num].setValue(state);
+                break;
+              case 2:
+                ppi_2[num].setValue(state);
+                break;
+              default:
+                sc_assert(false);
+            }
+        }
+
+        behavior spi(uint32_t num, bool state_val)
+        {
+            sg::Signal::State state =
+                state_val ? sg::Signal::Set : sg::Signal::Clear;
+            spi[num].setValue(state);
+        }
+    }
+
+    internal slave port<Signal> spi[960];
+
+    internal slave port<Signal> ppi_0[9];
+    internal slave port<Signal> ppi_1[9];
+    internal slave port<Signal> ppi_2[9];
+}
diff --git a/src/arch/arm/fastmodel/CortexR52/x3/x3.sgproj b/src/arch/arm/fastmodel/CortexR52/x3/x3.sgproj
new file mode 100644 (file)
index 0000000..a5d269e
--- /dev/null
@@ -0,0 +1,30 @@
+sgproject "x3.sgproj"
+{
+TOP_LEVEL_COMPONENT = "CortexR52x3";
+ACTIVE_CONFIG_LINUX  = "gcc";
+ACTIVE_CONFIG_WINDOWS  = "Win64-Release-VC2015";
+config "gcc"
+{
+    ADDITIONAL_COMPILER_SETTINGS = "-march=core2 -O3 -Wall -std=c++14 -Wno-deprecated -Wno-unused-function";
+    ADDITIONAL_LINKER_SETTINGS = "-Wl,--no-undefined";
+    BUILD_DIR = "./gcc";
+    COMPILER = "gcc-6.4";
+    CONFIG_DESCRIPTION = "";
+    CONFIG_NAME = "gcc";
+    PLATFORM = "Linux64";
+    PREPROCESSOR_DEFINES = "NDEBUG";
+    SIMGEN_COMMAND_LINE = "--num-comps-file 50";
+    TARGET_MAXVIEW = "0";
+    TARGET_SYSTEMC = "1";
+    TARGET_SYSTEMC_AUTO = "1";
+
+    INCLUDE_DIRS="../../../../../";
+}
+files
+{
+    path = "x3.lisa";
+    path = "${PVLIB_HOME}/etc/sglib.sgrepo";
+    path = "../../protocol/ExportedClockRateControlProtocol.lisa";
+    path = "../../protocol/SignalInterruptProtocol.lisa";
+}
+}
diff --git a/src/arch/arm/fastmodel/CortexR52/x4/x4.lisa b/src/arch/arm/fastmodel/CortexR52/x4/x4.lisa
new file mode 100644 (file)
index 0000000..00e6522
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+component CortexR52x4
+{
+
+    composition
+    {
+        core : ARMCortexR52x4CT();
+
+        // Clocks.
+        clock1Hz : MasterClock();
+        clockDiv : ClockDivider();
+        clockDivPeriph : ClockDivider(mul=0x01800000);
+    }
+
+    connection
+    {
+        // Memory interfaces.
+        core.llpp_m => self.llpp;
+        core.flash_m => self.flash;
+        core.pvbus_core_m => self.amba;
+
+        // Clocks.
+        clock1Hz.clk_out => clockDiv.clk_in;
+        clock1Hz.clk_out => clockDivPeriph.clk_in;
+        clockDiv.clk_out => core.clk_in;
+
+        // Internal ports for PPI and SPI programmatic access.
+        self.ppi_0 => core.extppi_in_0;
+        self.ppi_1 => core.extppi_in_1;
+        self.ppi_2 => core.extppi_in_2;
+        self.ppi_3 => core.extppi_in_3;
+
+        self.spi => core.spi_in;
+    }
+
+    properties
+    {
+        component_type = "System";
+    }
+
+    master port<PVBus> llpp[4];
+    master port<PVBus> flash[4];
+    master port<PVBus> amba[4];
+
+    slave port<ExportedClockRateControl> clock_rate_s
+    {
+        behavior set_mul_div(uint64_t mul, uint64_t div)
+        {
+            clockDiv.rate.set64(mul, div);
+        }
+    }
+
+    slave port<SignalInterrupt> signal_interrupt
+    {
+        behavior ppi(uint8_t cpu, uint32_t num, bool state_val)
+        {
+            sg::Signal::State state =
+                state_val ? sg::Signal::Set : sg::Signal::Clear;
+
+            sc_assert(cpu < 4);
+            switch (cpu) {
+              case 0:
+                ppi_0[num].setValue(state);
+                break;
+              case 1:
+                ppi_1[num].setValue(state);
+                break;
+              case 2:
+                ppi_2[num].setValue(state);
+                break;
+              case 3:
+                ppi_3[num].setValue(state);
+                break;
+              default:
+                sc_assert(false);
+            }
+        }
+
+        behavior spi(uint32_t num, bool state_val)
+        {
+            sg::Signal::State state =
+                state_val ? sg::Signal::Set : sg::Signal::Clear;
+            spi[num].setValue(state);
+        }
+    }
+
+    internal slave port<Signal> spi[960];
+
+    internal slave port<Signal> ppi_0[9];
+    internal slave port<Signal> ppi_1[9];
+    internal slave port<Signal> ppi_2[9];
+    internal slave port<Signal> ppi_3[9];
+}
diff --git a/src/arch/arm/fastmodel/CortexR52/x4/x4.sgproj b/src/arch/arm/fastmodel/CortexR52/x4/x4.sgproj
new file mode 100644 (file)
index 0000000..d33f850
--- /dev/null
@@ -0,0 +1,30 @@
+sgproject "x4.sgproj"
+{
+TOP_LEVEL_COMPONENT = "CortexR52x4";
+ACTIVE_CONFIG_LINUX  = "gcc";
+ACTIVE_CONFIG_WINDOWS  = "Win64-Release-VC2015";
+config "gcc"
+{
+    ADDITIONAL_COMPILER_SETTINGS = "-march=core2 -O3 -Wall -std=c++14 -Wno-deprecated -Wno-unused-function";
+    ADDITIONAL_LINKER_SETTINGS = "-Wl,--no-undefined";
+    BUILD_DIR = "./gcc";
+    COMPILER = "gcc-6.4";
+    CONFIG_DESCRIPTION = "";
+    CONFIG_NAME = "gcc";
+    PLATFORM = "Linux64";
+    PREPROCESSOR_DEFINES = "NDEBUG";
+    SIMGEN_COMMAND_LINE = "--num-comps-file 50";
+    TARGET_MAXVIEW = "0";
+    TARGET_SYSTEMC = "1";
+    TARGET_SYSTEMC_AUTO = "1";
+
+    INCLUDE_DIRS="../../../../../";
+}
+files
+{
+    path = "x4.lisa";
+    path = "${PVLIB_HOME}/etc/sglib.sgrepo";
+    path = "../../protocol/ExportedClockRateControlProtocol.lisa";
+    path = "../../protocol/SignalInterruptProtocol.lisa";
+}
+}