aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/edk2/OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c')
-rw-r--r--roms/edk2/OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/roms/edk2/OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c b/roms/edk2/OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
new file mode 100644
index 000000000..7c593e8be
--- /dev/null
+++ b/roms/edk2/OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
@@ -0,0 +1,103 @@
+/** @file
+ Provide constructor and GetTick for Base instance of ACPI Timer Library
+
+ Copyright (C) 2014, Gabriel L. Somlo <somlo@cmu.edu>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <OvmfPlatforms.h>
+
+//
+// Cached ACPI Timer IO Address
+//
+STATIC UINT32 mAcpiTimerIoAddr;
+
+/**
+ The constructor function caches the ACPI tick counter address, and,
+ if necessary, enables ACPI IO space.
+
+ @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.
+
+**/
+RETURN_STATUS
+EFIAPI
+AcpiTimerLibConstructor (
+ VOID
+ )
+{
+ UINT16 HostBridgeDevId;
+ UINTN Pmba;
+ UINT32 PmbaAndVal;
+ UINT32 PmbaOrVal;
+ UINTN AcpiCtlReg;
+ UINT8 AcpiEnBit;
+
+ //
+ // Query Host Bridge DID to determine platform type
+ //
+ HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
+ switch (HostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+ PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
+ PmbaOrVal = PIIX4_PMBA_VALUE;
+ AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
+ AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;
+ break;
+ case INTEL_Q35_MCH_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
+ PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;
+ PmbaOrVal = ICH9_PMBASE_VALUE;
+ AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
+ AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN;
+ break;
+ default:
+ DEBUG ((DEBUG_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+ __FUNCTION__, HostBridgeDevId));
+ ASSERT (FALSE);
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // Check to see if the Power Management Base Address is already enabled
+ //
+ if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
+ //
+ // If the Power Management Base Address is not programmed,
+ // then program it now.
+ //
+ PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);
+
+ //
+ // Enable PMBA I/O port decodes
+ //
+ PciOr8 (AcpiCtlReg, AcpiEnBit);
+ }
+
+ mAcpiTimerIoAddr = (PciRead32 (Pmba) & ~PMBA_RTE) + ACPI_TIMER_OFFSET;
+ return RETURN_SUCCESS;
+}
+
+/**
+ Internal function to read the current tick counter of ACPI.
+
+ Read the current ACPI tick counter using the counter address cached
+ by this instance's constructor.
+
+ @return The tick counter read.
+
+**/
+UINT32
+InternalAcpiGetTimerTick (
+ VOID
+ )
+{
+ //
+ // Return the current ACPI timer value.
+ //
+ return IoRead32 (mAcpiTimerIoAddr);
+}