--- /dev/null
+/** @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