arch-arm: Refactor code to check if gic is GicV2
authorChun-Chen TK Hsu <chunchenhsu@google.com>
Tue, 1 Oct 2019 13:22:27 +0000 (21:22 +0800)
committerChun-Chen TK Hsu <chunchenhsu@google.com>
Thu, 14 Nov 2019 00:04:20 +0000 (00:04 +0000)
Refactor code to use cpu_addr only when gic is GicV2 since cpu_addr is
only meanful to GicV2.

Test: Boot Android P successfully with the following command:
M5_PATH=$PWD/fs_files ./build/ARM/gem5.opt
./configs/example/arm/fs_bigLITTLE.py --dtb
$PWD/fs_files/binaries/armv8_gem5_v2_1cpu.dtb --kernel
$PWD/fs_files/binaries/vmlinux --disk $PWD/fs_files/disks/disk.img
--kernel-init "/init" --cpu-type fastmodel --machine-type
VExpressFastmodel --big-cpu-clock "2GHz" --big-cpus 1 --little-cpus 0
--mem-size 8GB --kernel-cmd "earlyprintk=pl011,0x1c090000
console=ttyAMA0 lpj=19988480 norandmaps rw loglevel=8 mem=8GB
root=/dev/vda1 init=/init androidboot.hardware=gem5 qemu=1 qemu.gles=2
android.bootanim=0 vmalloc=640MB android.early.fstab=/fstab.gem5
androidboot.selinux=permissive audit=0 cma=128M"

Change-Id: Iedd1388f292685c25f1effcd2e14b3db8899dff9
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21339
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>

src/arch/arm/fastmodel/GIC/gic.cc
src/arch/arm/fastmodel/GIC/gic.hh
src/arch/arm/system.cc
src/dev/arm/base_gic.hh
src/dev/arm/gic_v2.cc
src/dev/arm/gic_v2.hh
src/dev/arm/gic_v3.cc
src/dev/arm/gic_v3.hh

index cb7752892fa96e131b9db9bbbe7e021f33d8e7e5..8a7eb3b62d2f8c892b776309f2efcf3e89718856 100644 (file)
@@ -70,7 +70,8 @@ SCGIC::Terminator::sendTowardsCPU(uint8_t len, const uint8_t *data)
 }
 
 SCGIC::SCGIC(const SCFastModelGICParams &params,
-             sc_core::sc_module_name _name) : scx_evs_GIC(_name)
+             sc_core::sc_module_name _name)
+    : scx_evs_GIC(_name), _params(params)
 {
     signalInterrupt.bind(signal_interrupt);
 
@@ -349,6 +350,15 @@ GIC::clearPPInt(uint32_t num, uint32_t cpu)
     scGIC->signalInterrupt->ppi(cpu, num, false);
 }
 
+bool
+GIC::supportsVersion(GicVersion version)
+{
+    if (scGIC->params().gicv2_only)
+        return version == GicVersion::GIC_V2;
+    return (version == GicVersion::GIC_V3) ||
+           (version == GicVersion::GIC_V4 && scGIC->params().has_gicv4_1);
+}
+
 } // namespace FastModel
 
 FastModel::SCGIC *
index aadfa3aea9a0cac4da7baf39b33d0b20e0894fa5..f607d2b3c37a4acb9b4892711de7291a5c9d4ad4 100644 (file)
@@ -79,6 +79,7 @@ class SCGIC : public scx_evs_GIC
     };
 
     std::unique_ptr<Terminator> terminator;
+    const SCFastModelGICParams &_params;
 
   public:
     SCGIC(const SCFastModelGICParams &params, sc_core::sc_module_name _name);
@@ -94,6 +95,11 @@ class SCGIC : public scx_evs_GIC
         scx_evs_GIC::start_of_simulation();
     }
     void start_of_simulation() override {}
+    const SCFastModelGICParams &
+    params()
+    {
+        return _params;
+    }
 };
 
 // This class pairs with the one above to implement the receiving end of gem5's
@@ -125,6 +131,8 @@ class GIC : public BaseGic
     void sendPPInt(uint32_t num, uint32_t cpu) override;
     void clearPPInt(uint32_t num, uint32_t cpu) override;
 
+    bool supportsVersion(GicVersion version) override;
+
     AddrRangeList getAddrRanges() const override { return AddrRangeList(); }
     Tick read(PacketPtr pkt) override { return 0; }
     Tick write(PacketPtr pkt) override { return 0; }
index 6add9c065ca8c3dc58a91a1e29d2a5568ad84f14..c3c2b8d48b3ca3d4ff2767e0ea4bb350afbe2ace 100644 (file)
@@ -48,7 +48,7 @@
 #include "base/loader/object_file.hh"
 #include "base/loader/symtab.hh"
 #include "cpu/thread_context.hh"
-#include "dev/arm/gic_v3.hh"
+#include "dev/arm/gic_v2.hh"
 #include "mem/fs_translating_port_proxy.hh"
 #include "mem/physical.hh"
 #include "sim/full_system.hh"
@@ -142,7 +142,8 @@ ArmSystem::initState()
     const Params* p = params();
 
     if (bootldr) {
-        bool isGICv3System = dynamic_cast<Gicv3 *>(getGIC()) != nullptr;
+        bool is_gic_v2 =
+            getGIC()->supportsVersion(BaseGic::GicVersion::GIC_V2);
         bootldr->buildImage().write(physProxy);
 
         inform("Using bootloader at address %#x\n", bootldr->entryPoint());
@@ -153,14 +154,14 @@ ArmSystem::initState()
         if (!p->flags_addr)
            fatal("flags_addr must be set with bootloader\n");
 
-        if (!p->gic_cpu_addr && !isGICv3System)
+        if (!p->gic_cpu_addr && is_gic_v2)
             fatal("gic_cpu_addr must be set with bootloader\n");
 
         for (int i = 0; i < threadContexts.size(); i++) {
             if (!_highestELIs64)
                 threadContexts[i]->setIntReg(3, (kernelEntry & loadAddrMask) +
                         loadAddrOffset);
-            if (!isGICv3System)
+            if (is_gic_v2)
                 threadContexts[i]->setIntReg(4, params()->gic_cpu_addr);
             threadContexts[i]->setIntReg(5, params()->flags_addr);
         }
index 7c0cc0edc36d1d6ee33aa841f84e7fd6ae6bceae..3d7a57924c89b0102d9b48a38222a301cbd1601a 100644 (file)
@@ -65,6 +65,7 @@ class BaseGic :  public PioDevice
 {
   public:
     typedef BaseGicParams Params;
+    enum class GicVersion { GIC_V2, GIC_V3, GIC_V4 };
 
     BaseGic(const Params *p);
     virtual ~BaseGic();
@@ -107,6 +108,9 @@ class BaseGic :  public PioDevice
         return (ArmSystem *) sys;
     }
 
+    /** Check if version supported */
+    virtual bool supportsVersion(GicVersion version) = 0;
+
   protected:
     /** Platform this GIC belongs to. */
     Platform *platform;
index fa480a2224301eb2f619cd7ff82a65146052fc70..20bd015708f6de1fe7e47f5c034b618875264cb5 100644 (file)
@@ -950,6 +950,12 @@ GicV2::postFiq(uint32_t cpu, Tick when)
     }
 }
 
+bool
+GicV2::supportsVersion(GicVersion version)
+{
+    return version == GicVersion::GIC_V2;
+}
+
 void
 GicV2::postDelayedFiq(uint32_t cpu)
 {
index 410414075085203c25cd1d91cf11c7f678c51b98..15cb89e0aacfa3be10ae2126877df15f69ea1d42 100644 (file)
@@ -475,6 +475,8 @@ class GicV2 : public BaseGic, public BaseGicRegisters
     void sendPPInt(uint32_t num, uint32_t cpu) override;
     void clearPPInt(uint32_t num, uint32_t cpu) override;
 
+    bool supportsVersion(GicVersion version) override;
+
   protected:
     /** Handle a read to the distributor portion of the GIC
      * @param pkt packet to respond to
index ba0a8ee63f5f47327da320896afee8e1ee1869bb..e9c2fbcfebfe29da2ac29c238d1e8ec1c64b17e9 100644 (file)
@@ -209,6 +209,13 @@ Gicv3::postInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
     platform->intrctrl->post(cpu, int_type, 0);
 }
 
+bool
+Gicv3::supportsVersion(GicVersion version)
+{
+    return (version == GicVersion::GIC_V3) ||
+           (version == GicVersion::GIC_V4 && params()->gicv4);
+}
+
 void
 Gicv3::deassertInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
 {
index 89a8abec0c8dcb9f1c41fab482bde8ddc9c7c490..e0212ee614fceef8e12bf50523dbeed600fefd04 100644 (file)
@@ -125,6 +125,7 @@ class Gicv3 : public BaseGic
     void serialize(CheckpointOut & cp) const override;
     void unserialize(CheckpointIn & cp) override;
     Tick write(PacketPtr pkt) override;
+    bool supportsVersion(GicVersion version) override;
 
   public: