diff --git a/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c b/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c index 201ef48d2d..c6441281b4 100644 --- a/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c +++ b/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c @@ -1,7 +1,7 @@ /** @file ACPI Timer implements one instance of Timer Library. - Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
Copyright (c) 2011, Andrei Warkentin This program and the accompanying materials are @@ -22,15 +22,42 @@ #include #include #include +#include // -// PIIX4 Power Management Base Address +// PCI Location of PIIX4 Power Management PCI Configuration Registers // -STATIC UINT32 mPmba; +#define PIIX4_POWER_MANAGEMENT_BUS 0x00 +#define PIIX4_POWER_MANAGEMENT_DEVICE 0x01 +#define PIIX4_POWER_MANAGEMENT_FUNCTION 0x03 -#define PCI_BAR_IO 0x1 -#define ACPI_TIMER_FREQUENCY 3579545 -#define ACPI_TIMER_COUNT_SIZE 0x01000000 +// +// Macro to access PIIX4 Power Management PCI Configuration Registers +// +#define PIIX4_PCI_POWER_MANAGEMENT_REGISTER(Register) \ + PCI_LIB_ADDRESS ( \ + PIIX4_POWER_MANAGEMENT_BUS, \ + PIIX4_POWER_MANAGEMENT_DEVICE, \ + PIIX4_POWER_MANAGEMENT_FUNCTION, \ + Register \ + ) + +// +// PIIX4 Power Management PCI Configuration Registers +// +#define PMBA PIIX4_PCI_POWER_MANAGEMENT_REGISTER (0x40) +#define PMBA_RTE BIT0 +#define PMREGMISC PIIX4_PCI_POWER_MANAGEMENT_REGISTER (0x80) +#define PMIOSE BIT0 + +// +// The ACPI Time in the PIIX4 is a 24-bit counter +// +#define ACPI_TIMER_COUNT_SIZE BIT24 + +// +// Offset in the PIIX4 Power Management Base Address to the ACPI Timer +// #define ACPI_TIMER_OFFSET 0x8 /** @@ -48,30 +75,22 @@ AcpiTimerLibConstructor ( VOID ) { - UINT8 Device; + // + // Check to see if the PIIX4 Power Management Base Address is already enabled + // + if ((PciRead8 (PMREGMISC) & PMIOSE) == 0) { + // + // If the PIIX4 Power Management Base Address is not programmed, + // then program the PIIX4 Power Management Base Address from a PCD. + // + PciAndThenOr32 (PMBA, (UINT32)(~0x0000FFC0), PcdGet16 (PcdAcpiPmBaseAddress)); - Device = 1; - // Device = 7; - - if (PciRead8 (PCI_LIB_ADDRESS (0,Device,3,0x80)) & 1) { - mPmba = PciRead32 (PCI_LIB_ADDRESS (0,Device,3,0x40)); - ASSERT (mPmba & PCI_BAR_IO); - mPmba &= ~PCI_BAR_IO; - } else { - mPmba = PcdGet16 (PcdAcpiPmBaseAddress); - - PciAndThenOr32 (PCI_LIB_ADDRESS (0,Device,3,0x40), - (UINT32) ~0xFFC0, mPmba); - PciOr8 ( - PCI_LIB_ADDRESS (0, Device, 3, PCI_COMMAND_OFFSET), - EFI_PCI_COMMAND_IO_SPACE - ); + // + // Enable PMBA I/O port decodes in PMREGMISC + // + PciOr8 (PMREGMISC, PMIOSE); } - - // - // ACPI Timer enable is in Bus 0, Device ?, Function 3 - // - PciOr8 (PCI_LIB_ADDRESS (0,Device,3,0x80), 0x01); + return RETURN_SUCCESS; } @@ -83,13 +102,15 @@ AcpiTimerLibConstructor ( @return The tick counter read. **/ -STATIC UINT32 InternalAcpiGetTimerTick ( VOID ) { - return IoRead32 (mPmba + ACPI_TIMER_OFFSET); + // + // Read PMBA to read and return the current ACPI timer value. + // + return IoRead32 ((PciRead32 (PMBA) & ~PMBA_RTE) + ACPI_TIMER_OFFSET); } /** @@ -101,7 +122,6 @@ InternalAcpiGetTimerTick ( @param Delay A period of time to delay in ticks. **/ -STATIC VOID InternalAcpiDelay ( IN UINT32 Delay