UefiCpuPkg: LocalApicLib: Add API to set SoftwareEnable bit
authorMichael Kinney <michael.d.kinney@intel.com>
Fri, 30 Oct 2015 17:53:31 +0000 (17:53 +0000)
committermdkinney <mdkinney@Edk2>
Fri, 30 Oct 2015 17:53:31 +0000 (17:53 +0000)
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 <michael.d.kinney@intel.com>
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18711 6f19259b-4bc3-4df7-8a09-765794883524

UefiCpuPkg/Include/Library/LocalApicLib.h
UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c

index b92b99e11519638a7feb77eccfd57a5740ad24d6..cd4e613ef5f82eadd34ae27c8fdff64d59e771e7 100644 (file)
@@ -4,7 +4,7 @@
   Local APIC library assumes local APIC is enabled. It does not\r
   handles cases where local APIC is disabled.\r
 \r
-  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -227,6 +227,20 @@ SendInitSipiSipiAllExcludingSelf (
   IN UINT32          StartupRoutine\r
   );\r
 \r
+/**\r
+  Initialize the state of the SoftwareEnable bit in the Local APIC\r
+  Spurious Interrupt Vector register.\r
+\r
+  @param  Enable  If TRUE, then set SoftwareEnable to 1\r
+                  If FALSE, then set SoftwareEnable to 0.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeLocalApicSoftwareEnable (\r
+  IN BOOLEAN  Enable\r
+  );\r
+\r
 /**\r
   Programming Virtual Wire Mode.\r
 \r
index 6cf36cb8f4afd6f4ecfb0ec2edd6a8380eca7a0c..1fca66ef1b293b76483aa818d5e757c094e5d01c 100644 (file)
@@ -563,6 +563,39 @@ SendInitSipiSipiAllExcludingSelf (
   SendIpi (IcrLow.Uint32, 0);\r
 }\r
 \r
+/**\r
+  Initialize the state of the SoftwareEnable bit in the Local APIC\r
+  Spurious Interrupt Vector register.\r
+\r
+  @param  Enable  If TRUE, then set SoftwareEnable to 1\r
+                  If FALSE, then set SoftwareEnable to 0.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeLocalApicSoftwareEnable (\r
+  IN BOOLEAN  Enable\r
+  )\r
+{\r
+  LOCAL_APIC_SVR  Svr;\r
+\r
+  //\r
+  // Set local APIC software-enabled bit.\r
+  //\r
+  Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);\r
+  if (Enable) {\r
+    if (Svr.Bits.SoftwareEnable == 0) {\r
+      Svr.Bits.SoftwareEnable = 1;\r
+      WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);\r
+    }\r
+  } else {\r
+    if (Svr.Bits.SoftwareEnable == 1) {\r
+      Svr.Bits.SoftwareEnable = 0;\r
+      WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   Programming Virtual Wire Mode.\r
 \r
@@ -679,7 +712,6 @@ InitializeApicTimer (
   IN UINT8   Vector\r
   )\r
 {\r
-  LOCAL_APIC_SVR       Svr;\r
   LOCAL_APIC_DCR       Dcr;\r
   LOCAL_APIC_LVT_TIMER LvtTimer;\r
   UINT32               Divisor;\r
@@ -687,9 +719,7 @@ InitializeApicTimer (
   //\r
   // Ensure local APIC is in software-enabled state.\r
   //\r
-  Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);\r
-  Svr.Bits.SoftwareEnable = 1;\r
-  WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);\r
+  InitializeLocalApicSoftwareEnable (TRUE);\r
 \r
   //\r
   // Program init-count register.\r
index 05039427b1ff3480a641d85b4410767c979ac9aa..38f5370cc3dfd5b6e8e01b67e4cba8f2f5b0afe9 100644 (file)
@@ -658,6 +658,39 @@ SendInitSipiSipiAllExcludingSelf (
   SendIpi (IcrLow.Uint32, 0);\r
 }\r
 \r
+/**\r
+  Initialize the state of the SoftwareEnable bit in the Local APIC\r
+  Spurious Interrupt Vector register.\r
+\r
+  @param  Enable  If TRUE, then set SoftwareEnable to 1\r
+                  If FALSE, then set SoftwareEnable to 0.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeLocalApicSoftwareEnable (\r
+  IN BOOLEAN  Enable\r
+  )\r
+{\r
+  LOCAL_APIC_SVR  Svr;\r
+\r
+  //\r
+  // Set local APIC software-enabled bit.\r
+  //\r
+  Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);\r
+  if (Enable) {\r
+    if (Svr.Bits.SoftwareEnable == 0) {\r
+      Svr.Bits.SoftwareEnable = 1;\r
+      WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);\r
+    }\r
+  } else {\r
+    if (Svr.Bits.SoftwareEnable == 1) {\r
+      Svr.Bits.SoftwareEnable = 0;\r
+      WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   Programming Virtual Wire Mode.\r
 \r
@@ -774,7 +807,6 @@ InitializeApicTimer (
   IN UINT8   Vector\r
   )\r
 {\r
-  LOCAL_APIC_SVR       Svr;\r
   LOCAL_APIC_DCR       Dcr;\r
   LOCAL_APIC_LVT_TIMER LvtTimer;\r
   UINT32               Divisor;\r
@@ -782,9 +814,7 @@ InitializeApicTimer (
   //\r
   // Ensure local APIC is in software-enabled state.\r
   //\r
-  Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);\r
-  Svr.Bits.SoftwareEnable = 1;\r
-  WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);\r
+  InitializeLocalApicSoftwareEnable (TRUE);\r
 \r
   //\r
   // Program init-count register.\r