Giacomo Travaglini has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/51010 )

Change subject: arch-arm: Define an ArmRelease class to handle ISA extensions
......................................................................

arch-arm: Define an ArmRelease class to handle ISA extensions

Signed-off-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
Change-Id: I3240853bd2123a6f24b2bb64c90ad457696f0d93
---
M src/arch/arm/ArmSystem.py
M src/arch/arm/mmu.cc
M configs/example/arm/baremetal.py
M src/dev/arm/gic_v3_distributor.cc
M src/arch/arm/isa.cc
M src/arch/arm/utility.cc
M src/dev/arm/generic_timer.cc
M src/arch/arm/table_walker.cc
M src/arch/arm/system.cc
M src/arch/arm/system.hh
M src/dev/arm/gic_v3_cpu_interface.cc
M src/dev/arm/RealView.py
12 files changed, 157 insertions(+), 184 deletions(-)



diff --git a/configs/example/arm/baremetal.py b/configs/example/arm/baremetal.py
index 9a56c11..9655bb1 100644
--- a/configs/example/arm/baremetal.py
+++ b/configs/example/arm/baremetal.py
@@ -143,8 +143,8 @@
     system.realview.gic.gicv4 = False

     system.highest_el_is_64 = True
-    system.have_virtualization = True
-    system.have_security = True
+    system.release.add(ArmExtension('SECURITY'))
+    system.release.add(ArmExtension('VIRTUALIZATION'))

     workload_class = workloads.workload_list.get(args.workload)
     system.workload = workload_class(
diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py
index 585df3b..6c42db0 100644
--- a/src/arch/arm/ArmSystem.py
+++ b/src/arch/arm/ArmSystem.py
@@ -43,20 +43,72 @@

 class SveVectorLength(UInt8): min = 1; max = 16

+class ArmExtension(ScopedEnum):
+    vals = [
+        # Armv8.1
+        'FEAT_VHE',
+        'FEAT_PAN',
+        'FEAT_LSE',
+
+        # Armv8.2
+        'FEAT_SVE',
+
+        # Armv8.4
+        'FEAT_SEL2',
+
+        # Others
+        'SECURITY',
+        'LPAE',
+        'VIRTUALIZATION',
+        'CRYPTO',
+        'TME'
+    ]
+
+class ArmRelease(SimObject):
+    type = 'ArmRelease'
+    cxx_header = "arch/arm/system.hh"
+    cxx_class = 'gem5::ArmRelease'
+
+    extensions = VectorParam.ArmExtension([], "ISA extensions")
+
+    def add(self, new_ext: ArmExtension) -> None:
+        """
+        Add the provided extension (ArmExtension) to the system
+        The method is discarding pre-existing values
+        """
+        if (new_ext.value not in
+            [ ext.value for ext in self.extensions ]):
+            self.extensions.append(new_ext)
+
+    def has(self, new_ext: ArmExtension) -> bool:
+        """
+        Is the system implementing the provided extension (ArmExtension) ?
+        """
+        if (new_ext.value not in
+            [ ext.value for ext in self.extensions ]):
+            return False
+        else:
+            return True
+
+class Armv8(ArmRelease):
+    extensions = [
+        'LPAE'
+    ]
+
+class ArmDefaultRelease(Armv8):
+    extensions = Armv8.extensions + [
+        'FEAT_SVE', 'FEAT_LSE', 'FEAT_PAN', 'FEAT_SEL2'
+    ]
+
 class ArmSystem(System):
     type = 'ArmSystem'
     cxx_header = "arch/arm/system.hh"
     cxx_class = 'gem5::ArmSystem'

+    release = Param.ArmRelease(ArmDefaultRelease(), "Arm Release")
+
     multi_proc = Param.Bool(True, "Multiprocessor system?")
     gic_cpu_addr = Param.Addr(0, "Addres of the GIC CPU interface")
-    have_security = Param.Bool(False,
-        "True if Security Extensions are implemented")
-    have_virtualization = Param.Bool(False,
-        "True if Virtualization Extensions are implemented")
-    have_crypto = Param.Bool(False,
-        "True if Crypto Extensions is implemented")
-    have_lpae = Param.Bool(True, "True if LPAE is implemented")
     reset_addr = Param.Addr(0x0,
         "Reset address (ARMv8)")
     auto_reset_addr = Param.Bool(True,
@@ -68,20 +120,8 @@
"Supported physical address range in bits when using AArch64 (ARMv8)")
     have_large_asid_64 = Param.Bool(False,
         "True if ASID is 16 bits in AArch64 (ARMv8)")
-    have_sve = Param.Bool(True,
-        "True if SVE is implemented (ARMv8)")
     sve_vl = Param.SveVectorLength(1,
         "SVE vector length in quadwords (128-bit)")
-    have_lse = Param.Bool(True,
-        "True if LSE is implemented (ARMv8.1)")
-    have_vhe = Param.Bool(False,
-        "True if FEAT_VHE (Virtualization Host Extensions) is implemented")
-    have_pan = Param.Bool(True,
-        "True if Priviledge Access Never is implemented (ARMv8.1)")
-    have_secel2 = Param.Bool(True,
-        "True if Secure EL2 is implemented (ARMv8)")
-    have_tme = Param.Bool(False,
-        "True if transactional memory extension (TME) is implemented")
     semihosting = Param.ArmSemihosting(NULL,
"Enable support for the Arm semihosting by settings this parameter")

diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 3b485ed..ee9c556 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -103,19 +103,19 @@
     // Cache system-level properties
     if (FullSystem && system) {
         highestELIs64 = system->highestELIs64();
-        haveSecurity = system->haveSecurity();
-        haveLPAE = system->haveLPAE();
-        haveCrypto = system->haveCrypto();
-        haveVirtualization = system->haveVirtualization();
+        haveSecurity = system->has(ArmExtension::SECURITY);
+        haveLPAE = system->has(ArmExtension::LPAE);
+        haveCrypto = system->has(ArmExtension::CRYPTO);
+        haveVirtualization = system->has(ArmExtension::VIRTUALIZATION);
         haveLargeAsid64 = system->haveLargeAsid64();
         physAddrRange = system->physAddrRange();
-        haveSVE = system->haveSVE();
-        haveVHE = system->haveVHE();
-        havePAN = system->havePAN();
-        haveSecEL2 = system->haveSecEL2();
+        haveSVE = system->has(ArmExtension::FEAT_SVE);
+        haveVHE = system->has(ArmExtension::FEAT_VHE);
+        havePAN = system->has(ArmExtension::FEAT_PAN);
+        haveSecEL2 = system->has(ArmExtension::FEAT_SEL2);
         sveVL = system->sveVL();
-        haveLSE = system->haveLSE();
-        haveTME = system->haveTME();
+        haveLSE = system->has(ArmExtension::FEAT_LSE);
+        haveTME = system->has(ArmExtension::TME);
     } else {
         highestELIs64 = true; // ArmSystem::highestELIs64 does the same
         haveSecurity = haveLPAE = haveVirtualization = false;
diff --git a/src/arch/arm/mmu.cc b/src/arch/arm/mmu.cc
index b739457..52606b0 100644
--- a/src/arch/arm/mmu.cc
+++ b/src/arch/arm/mmu.cc
@@ -72,8 +72,8 @@
     if (FullSystem) {
         ArmSystem *arm_sys = dynamic_cast<ArmSystem *>(p.sys);
         assert(arm_sys);
-        haveLPAE = arm_sys->haveLPAE();
-        haveVirtualization = arm_sys->haveVirtualization();
+        haveLPAE = arm_sys->has(ArmExtension::LPAE);
+        haveVirtualization = arm_sys->has(ArmExtension::VIRTUALIZATION);
         haveLargeAsid64 = arm_sys->haveLargeAsid64();
         physAddrRange = arm_sys->physAddrRange();
     } else {
diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc
index f19978e..4edc350 100644
--- a/src/arch/arm/system.cc
+++ b/src/arch/arm/system.cc
@@ -50,6 +50,7 @@
 #include "dev/arm/fvp_base_pwr_ctrl.hh"
 #include "dev/arm/gic_v2.hh"
 #include "mem/physical.hh"
+#include "params/ArmRelease.hh"

 namespace gem5
 {
@@ -57,26 +58,28 @@
 using namespace linux;
 using namespace ArmISA;

+ArmRelease::ArmRelease(const ArmReleaseParams &p)
+  : SimObject(p)
+{
+    for (auto ext : p.extensions) {
+        fatal_if(_extensions.find(ext) != _extensions.end(),
+            "Duplicated FEAT_\n");
+
+        _extensions[ext] = true;
+    }
+}
+
 ArmSystem::ArmSystem(const Params &p)
     : System(p),
-      _haveSecurity(p.have_security),
-      _haveLPAE(p.have_lpae),
-      _haveVirtualization(p.have_virtualization),
-      _haveCrypto(p.have_crypto),
       _genericTimer(nullptr),
       _gic(nullptr),
       _pwrCtrl(nullptr),
       _highestELIs64(p.highest_el_is_64),
       _physAddrRange64(p.phys_addr_range_64),
       _haveLargeAsid64(p.have_large_asid_64),
-      _haveTME(p.have_tme),
-      _haveSVE(p.have_sve),
       _sveVL(p.sve_vl),
-      _haveLSE(p.have_lse),
-      _haveVHE(p.have_vhe),
-      _havePAN(p.have_pan),
-      _haveSecEL2(p.have_secel2),
       semihosting(p.semihosting),
+      release(p.release),
       multiProc(p.multi_proc)
 {
     if (p.auto_reset_addr) {
@@ -105,21 +108,9 @@
 }

 bool
-ArmSystem::haveSecurity(ThreadContext *tc)
+ArmSystem::has(ArmExtension ext, ThreadContext *tc)
 {
-    return FullSystem? getArmSystem(tc)->haveSecurity() : false;
-}
-
-bool
-ArmSystem::haveLPAE(ThreadContext *tc)
-{
-    return FullSystem? getArmSystem(tc)->haveLPAE() : false;
-}
-
-bool
-ArmSystem::haveVirtualization(ThreadContext *tc)
-{
-    return FullSystem? getArmSystem(tc)->haveVirtualization() : false;
+    return FullSystem? getArmSystem(tc)->has(ext) : false;
 }

 bool
@@ -142,21 +133,15 @@
       case EL1:
         return true;
       case EL2:
-        return haveVirtualization(tc);
+        return has(ArmExtension::VIRTUALIZATION, tc);
       case EL3:
-        return haveSecurity(tc);
+        return has(ArmExtension::SECURITY, tc);
       default:
         warn("Unimplemented Exception Level\n");
         return false;
     }
 }

-bool
-ArmSystem::haveTME(ThreadContext *tc)
-{
-    return getArmSystem(tc)->haveTME();
-}
-
 Addr
 ArmSystem::resetAddr(ThreadContext *tc)
 {
diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh
index f2ec5c3..dac444b 100644
--- a/src/arch/arm/system.hh
+++ b/src/arch/arm/system.hh
@@ -43,6 +43,7 @@

 #include <memory>
 #include <string>
+#include <unordered_map>
 #include <vector>

 #include "kern/linux/events.hh"
@@ -50,6 +51,8 @@
 #include "sim/full_system.hh"
 #include "sim/sim_object.hh"
 #include "sim/system.hh"
+#include "enums/ArmExtension.hh"
+

 namespace gem5
 {
@@ -59,30 +62,35 @@
 class FVPBasePwrCtrl;
 class ThreadContext;

+struct ArmReleaseParams;
+
+class ArmRelease : public SimObject
+{
+  public:
+    PARAMS(ArmRelease);
+    ArmRelease(const Params &p);
+
+    bool
+    has(ArmExtension ext) const
+    {
+        try {
+            return _extensions.at(ext);
+        } catch (const std::out_of_range& oor) {
+            return false;
+        }
+    }
+
+  protected:
+    /**
+     * List of implemented extensions
+     */
+    std::unordered_map<ArmExtension, bool> _extensions;
+};
+
 class ArmSystem : public System
 {
   protected:
     /**
-     * True if this system implements the Security Extensions
-     */
-    const bool _haveSecurity;
-
-    /**
-     * True if this system implements the Large Physical Address Extension
-     */
-    const bool _haveLPAE;
-
-    /**
-     * True if this system implements the virtualization Extensions
-     */
-    const bool _haveVirtualization;
-
-    /**
-     * True if this system implements the Crypto Extension
-     */
-    const bool _haveCrypto;
-
-    /**
      * Pointer to the Generic Timer wrapper.
      */
     GenericTimer *_genericTimer;
@@ -115,38 +123,20 @@
      */
     const bool _haveLargeAsid64;

-    /**
-     * True if system implements the transactional memory extension (TME)
-     */
-    const bool _haveTME;
-
-    /**
-     * True if SVE is implemented (ARMv8)
-     */
-    const bool _haveSVE;
-
     /** SVE vector length at reset, in quadwords */
     const unsigned _sveVL;

     /**
-     * True if LSE is implemented (ARMv8.1)
-     */
-    const bool _haveLSE;
-
-    /** True if FEAT_VHE (Virtualization Host Extensions) is implemented */
-    const bool _haveVHE;
-
-    /** True if Priviledge Access Never is implemented */
-    const unsigned _havePAN;
-
-    /** True if Secure EL2 is implemented */
-    const unsigned _haveSecEL2;
-
-    /**
      * True if the Semihosting interface is enabled.
      */
     ArmSemihosting *const semihosting;

+    /**
+     * Arm Release object: contains a list of implemented
+     * features
+     */
+    const ArmRelease *release;
+
   public:
     static constexpr Addr PageBytes = ArmISA::PageBytes;
     static constexpr Addr PageShift = ArmISA::PageShift;
@@ -158,22 +148,9 @@
     /** true if this a multiprocessor system */
     bool multiProc;

-    /** Returns true if this system implements the Security Extensions */
-    bool haveSecurity() const { return _haveSecurity; }
+    const ArmRelease* releaseFS() const { return release; }

-    /** Returns true if this system implements the Large Physical Address
-     * Extension */
-    bool haveLPAE() const { return _haveLPAE; }
-
-    /** Returns true if this system implements the virtualization
-      * Extensions
-      */
-    bool haveVirtualization() const { return _haveVirtualization; }
-
-    /** Returns true if this system implements the Crypto
-      * Extension
-      */
-    bool haveCrypto() const { return _haveCrypto; }
+    bool has(ArmExtension ext) const { return release->has(ext); }

     /** Sets the pointer to the Generic Timer. */
     void
@@ -208,9 +185,9 @@
     ArmISA::ExceptionLevel
     highestEL() const
     {
-        if (_haveSecurity)
+        if (has(ArmExtension::SECURITY))
             return ArmISA::EL3;
-        if (_haveVirtualization)
+        if (has(ArmExtension::VIRTUALIZATION))
             return ArmISA::EL2;
         return ArmISA::EL1;
     }
@@ -223,29 +200,9 @@
     /** Returns true if ASID is 16 bits in AArch64 (ARMv8) */
     bool haveLargeAsid64() const { return _haveLargeAsid64; }

-    /** Returns true if this system implements the transactional
-      * memory extension (ARMv9)
-      */
-    bool haveTME() const { return _haveTME; }
-
-    /** Returns true if SVE is implemented (ARMv8) */
-    bool haveSVE() const { return _haveSVE; }
-
     /** Returns the SVE vector length at reset, in quadwords */
     unsigned sveVL() const { return _sveVL; }

-    /** Returns true if LSE is implemented (ARMv8.1) */
-    bool haveLSE() const { return _haveLSE; }
-
-    /** Returns true if Virtualization Host Extensions is implemented */
-    bool haveVHE() const { return _haveVHE; }
-
-    /** Returns true if Priviledge Access Never is implemented */
-    bool havePAN() const { return _havePAN; }
-
-    /** Returns true if Priviledge Access Never is implemented */
-    bool haveSecEL2() const { return _haveSecEL2; }
-
     /** Returns the supported physical address range in bits if the highest
      * implemented exception level is 64 bits (ARMv8) */
     uint8_t physAddrRange64() const { return _physAddrRange64; }
@@ -256,7 +213,7 @@
     {
         if (_highestELIs64)
             return _physAddrRange64;
-        if (_haveLPAE)
+        if (has(ArmExtension::LPAE))
             return 40;
         return 32;
     }
@@ -278,24 +235,8 @@
         return static_cast<ArmSystem *>(tc->getSystemPtr());
     }

- /** Returns true if the system of a specific thread context implements the
-     * Security Extensions
-     */
-    static bool haveSecurity(ThreadContext *tc);
+    static bool has(ArmExtension ext, ThreadContext *tc);

- /** Returns true if the system of a specific thread context implements the
-     * virtualization Extensions
-     */
-    static bool haveVirtualization(ThreadContext *tc);
-
- /** Returns true if the system of a specific thread context implements the
-     * Large Physical Address Extension
-     */
-    static bool haveLPAE(ThreadContext *tc);
-
- /** Returns true if the register width of the highest implemented exception
-     * level for the system of a specific thread context is 64 bits (ARMv8)
-     */
     static bool highestELIs64(ThreadContext *tc);

     /** Returns the highest implemented exception level for the system of a
@@ -306,11 +247,6 @@
     /** Return true if the system implements a specific exception level */
     static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el);

- /** Returns true if the system of a specific thread context implements the
-     * transactional memory extension (TME)
-     */
-    static bool haveTME(ThreadContext *tc);
-
/** Returns the reset address if the highest implemented exception level
      * for the system of a specific thread context is 64 bits (ARMv8)
      */
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 4cc0fff..8604d6f 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -82,13 +82,13 @@

     // Cache system-level properties
     if (FullSystem) {
-        ArmSystem *armSys = dynamic_cast<ArmSystem *>(p.sys);
-        assert(armSys);
-        haveSecurity = armSys->haveSecurity();
-        _haveLPAE = armSys->haveLPAE();
-        _haveVirtualization = armSys->haveVirtualization();
-        _physAddrRange = armSys->physAddrRange();
-        _haveLargeAsid64 = armSys->haveLargeAsid64();
+        ArmSystem *arm_sys = dynamic_cast<ArmSystem *>(p.sys);
+        assert(arm_sys);
+        haveSecurity = arm_sys->has(ArmExtension::SECURITY);
+        _haveLPAE = arm_sys->has(ArmExtension::LPAE);
+        _haveVirtualization = arm_sys->has(ArmExtension::VIRTUALIZATION);
+        _physAddrRange = arm_sys->physAddrRange();
+        _haveLargeAsid64 = arm_sys->haveLargeAsid64();
     } else {
         haveSecurity = _haveLPAE = _haveVirtualization = false;
         _haveLargeAsid64 = false;
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index 2baf9c0..520716e 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -128,7 +128,7 @@
 longDescFormatInUse(ThreadContext *tc)
 {
     TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR);
-    return ArmSystem::haveLPAE(tc) && ttbcr.eae;
+    return ArmSystem::has(ArmExtension::LPAE, tc) && ttbcr.eae;
 }

 RegVal
diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py
index 919ff63..0ba929b 100644
--- a/src/dev/arm/RealView.py
+++ b/src/dev/arm/RealView.py
@@ -40,6 +40,7 @@
 from m5.params import *
 from m5.proxy import *
 from m5.util.fdthelper import *
+from m5.objects.ArmSystem import ArmExtension
 from m5.objects.ClockDomain import ClockDomain, SrcClockDomain
 from m5.objects.VoltageDomain import VoltageDomain
 from m5.objects.Device import \
@@ -1308,7 +1309,7 @@
         system = self.system.unproxy(self)
         if system._have_psci:
             # PSCI functions exposed to the kernel
-            if not system.have_security:
+            if not system.release.has(ArmExtension('SECURITY')):
                 raise AssertionError("PSCI requires EL3 (have_security)")

             psci_node = FdtNode('psci')
diff --git a/src/dev/arm/generic_timer.cc b/src/dev/arm/generic_timer.cc
index 52f41fe..1c1d811 100644
--- a/src/dev/arm/generic_timer.cc
+++ b/src/dev/arm/generic_timer.cc
@@ -1285,7 +1285,7 @@
 bool
 GenericTimerMem::validateAccessPerm(ArmSystem &sys, bool is_sec)
 {
-    return !sys.haveSecurity() || is_sec;
+    return !sys.has(ArmExtension::SECURITY) || is_sec;
 }

 AddrRangeList
diff --git a/src/dev/arm/gic_v3_cpu_interface.cc b/src/dev/arm/gic_v3_cpu_interface.cc
index f4cdfc1..4ae6b9b 100644
--- a/src/dev/arm/gic_v3_cpu_interface.cc
+++ b/src/dev/arm/gic_v3_cpu_interface.cc
@@ -2333,7 +2333,7 @@
 bool
 Gicv3CPUInterface::inSecureState() const
 {
-    if (!gic->getSystem()->haveSecurity()) {
+    if (!gic->getSystem()->has(ArmExtension::SECURITY)) {
         return false;
     }

@@ -2376,10 +2376,10 @@
         return true;

       case EL2:
-        return gic->getSystem()->haveVirtualization();
+        return gic->getSystem()->has(ArmExtension::VIRTUALIZATION);

       case EL3:
-        return gic->getSystem()->haveSecurity();
+        return gic->getSystem()->has(ArmExtension::SECURITY);

       default:
         warn("Unimplemented Exception Level\n");
diff --git a/src/dev/arm/gic_v3_distributor.cc b/src/dev/arm/gic_v3_distributor.cc
index a4124ae..75c3df5 100644
--- a/src/dev/arm/gic_v3_distributor.cc
+++ b/src/dev/arm/gic_v3_distributor.cc
@@ -118,14 +118,15 @@
      * ITLinesNumber [4:0]   == N
      * (MaxSPIIntId = 32 (N + 1) - 1)
      */
+    bool have_security = gic->getSystem()->has(ArmExtension::SECURITY);
     int max_spi_int_id = itLines - 1;
     int it_lines_number = divCeil(max_spi_int_id + 1, 32) - 1;
     gicdTyper = (1 << 26) | (1 << 25) | (1 << 24) | (IDBITS << 19) |
         (1 << 17) | (1 << 16) |
-        ((gic->getSystem()->haveSecurity() ? 1 : 0) << 10) |
+        ((have_security ? 1 : 0) << 10) |
         (it_lines_number << 0);

-    if (gic->getSystem()->haveSecurity()) {
+    if (have_security) {
         DS = false;
     } else {
         DS = true;

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/51010
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I3240853bd2123a6f24b2bb64c90ad457696f0d93
Gerrit-Change-Number: 51010
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to