diff mbox

[edk2,1/7] ArmPkg: reduce sysreg access count in GIC revision probe

Message ID 1432902820-18721-2-git-send-email-ard.biesheuvel@linaro.org
State New
Headers show

Commit Message

Ard Biesheuvel May 29, 2015, 12:33 p.m. UTC
Accesses to system registers are disproportionately heavy-weight
when executed under virtualization, since each one involves two
world switches (from guest to host and back again).

So change the sequence that enables the GIC SRE interface so that
it performs only a single sysreg read to test whether the SRE
interface is enabled already, and only performs a write and an
additional read if that turns out not to be the case.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c | 10 ++++++++--
 ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c     | 10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c b/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c
index 9da69b2131e3..88fa4621e613 100644
--- a/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c
+++ b/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c
@@ -23,6 +23,8 @@  ArmGicGetSupportedArchRevision (
   VOID
   )
 {
+  UINT32    IccSre;
+
   // Ideally we would like to use the GICC IIDR Architecture version here, but
   // this does not seem to be very reliable as the implementation could easily
   // get it wrong. It is more reliable to check if the GICv3 System Register
@@ -37,8 +39,12 @@  ArmGicGetSupportedArchRevision (
     // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
     // at the same exception level.
     // It is the OS responsibility to set this bit.
-    ArmGicV3SetControlSystemRegisterEnable (ArmGicV3GetControlSystemRegisterEnable () | ICC_SRE_EL2_SRE);
-    if (ArmGicV3GetControlSystemRegisterEnable () & ICC_SRE_EL2_SRE) {
+    IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+    if (!(IccSre & ICC_SRE_EL2_SRE)) {
+      ArmGicV3SetControlSystemRegisterEnable (IccSre | ICC_SRE_EL2_SRE);
+      IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+    }
+    if (IccSre & ICC_SRE_EL2_SRE) {
       return ARM_GIC_ARCH_REVISION_3;
     }
   }
diff --git a/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c b/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c
index f360a405833d..9ef56efeaa7b 100644
--- a/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c
+++ b/ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c
@@ -23,6 +23,8 @@  ArmGicGetSupportedArchRevision (
   VOID
   )
 {
+  UINT32    IccSre;
+
   // Ideally we would like to use the GICC IIDR Architecture version here, but
   // this does not seem to be very reliable as the implementation could easily
   // get it wrong. It is more reliable to check if the GICv3 System Register
@@ -37,8 +39,12 @@  ArmGicGetSupportedArchRevision (
     // Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
     // at the same exception level.
     // It is the OS responsibility to set this bit.
-    ArmGicV3SetControlSystemRegisterEnable (ArmGicV3GetControlSystemRegisterEnable () | ICC_SRE_EL2_SRE);
-    if (ArmGicV3GetControlSystemRegisterEnable () & ICC_SRE_EL2_SRE) {
+    IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+    if (!(IccSre & ICC_SRE_EL2_SRE)) {
+      ArmGicV3SetControlSystemRegisterEnable (IccSre| ICC_SRE_EL2_SRE);
+      IccSre = ArmGicV3GetControlSystemRegisterEnable ();
+    }
+    if (IccSre & ICC_SRE_EL2_SRE) {
       return ARM_GIC_ARCH_REVISION_3;
     }
   }