From 14e4ca25c6199fa29bda7066f31d919197840664 Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Fri, 30 Oct 2015 17:53:31 +0000 Subject: [PATCH] UefiCpuPkg: LocalApicLib: Add API to set SoftwareEnable bit The LocalApicLib does not provide a function to manage the state of the Local APIC SoftwareEnable bit in the Spurious Vector register. There are cases where this bit needs to be managed without side effects to. other Local APIC registers. One use case is in the DebugAgent in the SourceLevelDebugPkg. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney Reviewed-by: Hao Wu Reviewed-by: Jeff Fan git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18711 6f19259b-4bc3-4df7-8a09-765794883524 --- UefiCpuPkg/Include/Library/LocalApicLib.h | 16 +++++++- .../Library/BaseXApicLib/BaseXApicLib.c | 38 +++++++++++++++++-- .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 38 +++++++++++++++++-- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/UefiCpuPkg/Include/Library/LocalApicLib.h b/UefiCpuPkg/Include/Library/LocalApicLib.h index b92b99e115..cd4e613ef5 100644 --- a/UefiCpuPkg/Include/Library/LocalApicLib.h +++ b/UefiCpuPkg/Include/Library/LocalApicLib.h @@ -4,7 +4,7 @@ Local APIC library assumes local APIC is enabled. It does not handles cases where local APIC is disabled. - Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -227,6 +227,20 @@ SendInitSipiSipiAllExcludingSelf ( IN UINT32 StartupRoutine ); +/** + Initialize the state of the SoftwareEnable bit in the Local APIC + Spurious Interrupt Vector register. + + @param Enable If TRUE, then set SoftwareEnable to 1 + If FALSE, then set SoftwareEnable to 0. + +**/ +VOID +EFIAPI +InitializeLocalApicSoftwareEnable ( + IN BOOLEAN Enable + ); + /** Programming Virtual Wire Mode. diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c index 6cf36cb8f4..1fca66ef1b 100644 --- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c @@ -563,6 +563,39 @@ SendInitSipiSipiAllExcludingSelf ( SendIpi (IcrLow.Uint32, 0); } +/** + Initialize the state of the SoftwareEnable bit in the Local APIC + Spurious Interrupt Vector register. + + @param Enable If TRUE, then set SoftwareEnable to 1 + If FALSE, then set SoftwareEnable to 0. + +**/ +VOID +EFIAPI +InitializeLocalApicSoftwareEnable ( + IN BOOLEAN Enable + ) +{ + LOCAL_APIC_SVR Svr; + + // + // Set local APIC software-enabled bit. + // + Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); + if (Enable) { + if (Svr.Bits.SoftwareEnable == 0) { + Svr.Bits.SoftwareEnable = 1; + WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + } + } else { + if (Svr.Bits.SoftwareEnable == 1) { + Svr.Bits.SoftwareEnable = 0; + WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + } + } +} + /** Programming Virtual Wire Mode. @@ -679,7 +712,6 @@ InitializeApicTimer ( IN UINT8 Vector ) { - LOCAL_APIC_SVR Svr; LOCAL_APIC_DCR Dcr; LOCAL_APIC_LVT_TIMER LvtTimer; UINT32 Divisor; @@ -687,9 +719,7 @@ InitializeApicTimer ( // // Ensure local APIC is in software-enabled state. // - Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); - Svr.Bits.SoftwareEnable = 1; - WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + InitializeLocalApicSoftwareEnable (TRUE); // // Program init-count register. diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c index 05039427b1..38f5370cc3 100644 --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c @@ -658,6 +658,39 @@ SendInitSipiSipiAllExcludingSelf ( SendIpi (IcrLow.Uint32, 0); } +/** + Initialize the state of the SoftwareEnable bit in the Local APIC + Spurious Interrupt Vector register. + + @param Enable If TRUE, then set SoftwareEnable to 1 + If FALSE, then set SoftwareEnable to 0. + +**/ +VOID +EFIAPI +InitializeLocalApicSoftwareEnable ( + IN BOOLEAN Enable + ) +{ + LOCAL_APIC_SVR Svr; + + // + // Set local APIC software-enabled bit. + // + Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); + if (Enable) { + if (Svr.Bits.SoftwareEnable == 0) { + Svr.Bits.SoftwareEnable = 1; + WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + } + } else { + if (Svr.Bits.SoftwareEnable == 1) { + Svr.Bits.SoftwareEnable = 0; + WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + } + } +} + /** Programming Virtual Wire Mode. @@ -774,7 +807,6 @@ InitializeApicTimer ( IN UINT8 Vector ) { - LOCAL_APIC_SVR Svr; LOCAL_APIC_DCR Dcr; LOCAL_APIC_LVT_TIMER LvtTimer; UINT32 Divisor; @@ -782,9 +814,7 @@ InitializeApicTimer ( // // Ensure local APIC is in software-enabled state. // - Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); - Svr.Bits.SoftwareEnable = 1; - WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32); + InitializeLocalApicSoftwareEnable (TRUE); // // Program init-count register. -- 2.39.2