From eadbec01094cddc4052e73ea06743d5c6761e9f7 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 9 Jun 2015 09:28:06 +0000 Subject: [PATCH] ArmPkg: reduce sysreg access count in GIC revision probe 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 Reviewed-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17596 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c | 10 ++++++++-- ArmPkg/Drivers/ArmGic/Arm/ArmGicArchLib.c | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c b/ArmPkg/Drivers/ArmGic/AArch64/ArmGicArchLib.c index 9da69b2131..88fa4621e6 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 f360a40583..9ef56efeaa 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; } } -- 2.39.2