config: Add fastmodel cluster in fs_bigLITTLE.py
authorChun-Chen TK Hsu <chunchenhsu@google.com>
Fri, 13 Sep 2019 04:43:00 +0000 (12:43 +0800)
committerChun-Chen TK Hsu <chunchenhsu@google.com>
Thu, 14 Nov 2019 00:03:55 +0000 (00:03 +0000)
One can create a system with ARM FastModels CPU and GICv3 with
--cpu-type fastmodel --machine-type VExpressFastmodel options.
Currently the FastmodelCluster only supports one CPU.

Change-Id: I2e985f08f9df01a703e21441c6f9bc1fbae4a222
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20901
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
configs/example/arm/devices.py
configs/example/arm/fs_bigLITTLE.py
src/arch/arm/fastmodel/GIC/FastModelGIC.py

index b73e7ae1f3323ef0bb6984711547ba362b6a8e54..16312eb729a1d24154b8d10a47e7e779c73dab27 100644 (file)
@@ -48,6 +48,7 @@ from common.Caches import *
 from common import ObjectList
 
 have_kvm = "ArmV8KvmCPU" in ObjectList.cpu_list.get_names()
+have_fastmodel = "FastModelCortexA76" in ObjectList.cpu_list.get_names()
 
 class L1I(L1_ICache):
     tag_latency = 1
@@ -185,6 +186,74 @@ class KvmCluster(CpuCluster):
     def addL1(self):
         pass
 
+class FastmodelCluster(SubSystem):
+    def __init__(self, system,  num_cpus, cpu_clock, cpu_voltage="1.0V"):
+        super(FastmodelCluster, self).__init__()
+
+        # Setup GIC
+        gic = system.realview.gic
+        gic.sc_gic.cpu_affinities = ','.join(
+            [ '0.0.%d.0' % i for i in range(num_cpus) ])
+
+        # Parse the base address of redistributor.
+        redist_base = gic.get_redist_bases()[0]
+        redist_frame_size = 0x40000 if gic.sc_gic.has_gicv4_1 else 0x20000
+        gic.sc_gic.reg_base_per_redistributor = ','.join([
+            '0.0.%d.0=%#x' % (i, redist_base + redist_frame_size * i)
+            for i in range(num_cpus)
+        ])
+
+        gic_a2t = AmbaToTlmBridge64(amba=gic.amba_m)
+        gic_t2g = TlmToGem5Bridge64(tlm=gic_a2t.tlm, gem5=system.iobus.slave)
+        gic_g2t = Gem5ToTlmBridge64(gem5=system.membus.master)
+        gic_g2t.addr_ranges = gic.get_addr_ranges()
+        gic_t2a = AmbaFromTlmBridge64(tlm=gic_g2t.tlm)
+        gic.amba_s = gic_t2a.amba
+
+        system.gic_hub = SubSystem()
+        system.gic_hub.gic_a2t = gic_a2t
+        system.gic_hub.gic_t2g = gic_t2g
+        system.gic_hub.gic_g2t = gic_g2t
+        system.gic_hub.gic_t2a = gic_t2a
+
+        self.voltage_domain = VoltageDomain(voltage=cpu_voltage)
+        self.clk_domain = SrcClockDomain(clock=cpu_clock,
+                                         voltage_domain=self.voltage_domain)
+
+        # Setup CPU
+        assert num_cpus <= 4
+        CpuClasses = [FastModelCortexA76x1, FastModelCortexA76x2,
+                      FastModelCortexA76x3, FastModelCortexA76x4]
+        CpuClass = CpuClasses[num_cpus - 1]
+
+        cpu = CpuClass(GICDISABLE=False)
+        for core in cpu.cores:
+            core.semihosting_enable = False
+            core.RVBARADDR = 0x10
+            core.redistributor = gic.redistributor
+        self.cpus = [ cpu ]
+
+        a2t = AmbaToTlmBridge64(amba=cpu.amba)
+        t2g = TlmToGem5Bridge64(tlm=a2t.tlm, gem5=system.membus.slave)
+        system.gic_hub.a2t = a2t
+        system.gic_hub.t2g = t2g
+
+        system.addCpuCluster(self, num_cpus)
+
+    def requireCaches(self):
+        return False
+
+    def memoryMode(self):
+        return 'atomic_noncaching'
+
+    def addL1(self):
+        pass
+
+    def addL2(self, clk_domain):
+        pass
+
+    def connectMemSide(self, bus):
+        pass
 
 def simpleSystem(BaseSystem, caches, mem_size, platform=None, **kwargs):
     """
index 378ac0d03941ba4c031203dd4e35db6f7a78ea95..94e28461fd6f22d75ff450ab5ff82ba143325cfe 100644 (file)
@@ -57,7 +57,7 @@ from common import ObjectList
 from common.cores.arm import ex5_big, ex5_LITTLE
 
 import devices
-from devices import AtomicCluster, KvmCluster
+from devices import AtomicCluster, KvmCluster, FastmodelCluster
 
 
 default_disk = 'aarch64-ubuntu-trusty-headless.img'
@@ -156,6 +156,9 @@ cpu_types = {
 if devices.have_kvm:
     cpu_types["kvm"] = (KvmCluster, KvmCluster)
 
+# Only add the FastModel CPU if it has been compiled into gem5
+if devices.have_fastmodel:
+    cpu_types["fastmodel"] = (FastmodelCluster, FastmodelCluster)
 
 def addOptions(parser):
     parser.add_argument("--restore-from", type=str, default=None,
@@ -284,6 +287,15 @@ def build(options):
     else:
         system.generateDtb(m5.options.outdir, 'system.dtb')
 
+    if devices.have_fastmodel and issubclass(big_model, FastmodelCluster):
+        from m5 import arm_fast_model as fm, systemc as sc
+        # setup FastModels for simulation
+        fm.setup_simulation("cortexa76")
+        # setup SystemC
+        root.systemc_kernel = m5.objects.SystemC_Kernel()
+        m5.tlm.tlm_global_quantum_instance().set(
+            sc.sc_time(10000.0 / 100000000.0, sc.sc_time.SC_SEC))
+
     return root
 
 def _build_kvm(system, cpus):
index 53b7e1a2da661b02321115ea95d7bd6ec4e427ac..72618b92d95354b9656a5cddd9b01aa8a49ac54d 100644 (file)
@@ -464,3 +464,38 @@ class FastModelGIC(BaseGic):
 
     redistributor = VectorGicv3CommsInitiatorSocket(
             'GIC communication initiator')
+
+    def get_redist_bases(self):
+        """
+        The format of reg_base_per_redistributor is
+        '0.0.0.0=0x2c010000,0.0.0.1=0x2c020000...'
+        Return an array of base addresses
+        """
+        redists = self.sc_gic.reg_base_per_redistributor.split(",")
+        # make sure we have at least one redistributor
+        assert len(redists) > 0 and "=" in redists[0]
+        return [ int(r.split('=')[1], 16) for r in redists ]
+
+    def get_addr_ranges(self):
+        """ Return address ranges that should be served by this GIC """
+        sc_gic = self.sc_gic
+        gic_frame_size = 0x10000
+        # Add range of distributor
+        ranges = [AddrRange(sc_gic.reg_base, size=gic_frame_size)]
+        # Add ranges of redistributors
+        redist_frame_size = gic_frame_size * (4 if sc_gic.has_gicv4_1 else 2)
+        ranges += [
+            AddrRange(redist_base, size=redist_frame_size)
+            for redist_base in self.get_redist_bases()
+        ]
+        # Add ranges of ITSs
+        its_bases = [
+            sc_gic.its0_base, sc_gic.its1_base, sc_gic.its2_base,
+            sc_gic.its3_base
+        ]
+        ranges += [
+            AddrRange(its_bases[i], size=2 * gic_frame_size)
+            for i in xrange(sc_gic.its_count)
+        ]
+
+        return ranges