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