]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
OvmfPkg: AcpiTimerLib: Split into multiple phase-specific instances
[mirror_edk2.git] / OvmfPkg / Library / AcpiTimerLib / BaseAcpiTimerLib.c
diff --git a/OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c b/OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
new file mode 100644 (file)
index 0000000..05b0257
--- /dev/null
@@ -0,0 +1,98 @@
+/** @file\r
+  Provide constructor and GetTick for Base instance of ACPI Timer Library\r
+\r
+  Copyright (C) 2014, Gabriel L. Somlo <somlo@cmu.edu>\r
+\r
+  This program and the accompanying materials are licensed and made\r
+  available under the terms and conditions of the BSD License which\r
+  accompanies this distribution.   The full text of the license may\r
+  be found at http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/PciLib.h>\r
+#include <OvmfPlatforms.h>\r
+\r
+//\r
+// Power Management PCI Configuration Register fields\r
+//\r
+#define PMBA_RTE  BIT0\r
+\r
+//\r
+// Offset in the Power Management Base Address to the ACPI Timer\r
+//\r
+#define ACPI_TIMER_OFFSET  0x8\r
+\r
+//\r
+// Cached ACPI Timer IO Address\r
+//\r
+STATIC UINT32 mAcpiTimerIoAddr;\r
+\r
+/**\r
+  The constructor function caches the ACPI tick counter address\r
+\r
+  At the time this constructor runs (DXE_CORE or later), ACPI IO space\r
+  has already been enabled by either PlatformPei or by the "Base"\r
+  instance of this library.\r
+  In order to avoid querying the underlying platform type during each\r
+  tick counter read operation, we cache the counter address during\r
+  initialization of this instance of the Timer Library.\r
+\r
+  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AcpiTimerLibConstructor (\r
+  VOID\r
+  )\r
+{\r
+  UINT16 HostBridgeDevId;\r
+  UINTN Pmba;\r
+\r
+  //\r
+  // Query Host Bridge DID to determine platform type\r
+  //\r
+  HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);\r
+  switch (HostBridgeDevId) {\r
+    case INTEL_82441_DEVICE_ID:\r
+      Pmba = POWER_MGMT_REGISTER_PIIX4 (0x40);\r
+      break;\r
+    case INTEL_Q35_MCH_DEVICE_ID:\r
+      Pmba = POWER_MGMT_REGISTER_Q35 (0x40);\r
+      break;\r
+    default:\r
+      DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
+        __FUNCTION__, HostBridgeDevId));\r
+      ASSERT (FALSE);\r
+      return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  mAcpiTimerIoAddr = (PciRead32 (Pmba) & ~PMBA_RTE) + ACPI_TIMER_OFFSET;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Internal function to read the current tick counter of ACPI.\r
+\r
+  Read the current ACPI tick counter using the counter address cached\r
+  by this instance's constructor.\r
+\r
+  @return The tick counter read.\r
+\r
+**/\r
+UINT32\r
+InternalAcpiGetTimerTick (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  //   Return the current ACPI timer value.\r
+  //\r
+  return IoRead32 (mAcpiTimerIoAddr);\r
+}\r