From 49ba9447c92d6fca214476381107a180d08e59d1 Mon Sep 17 00:00:00 2001 From: jljusten Date: Wed, 27 May 2009 21:10:18 +0000 Subject: Add initial version of Open Virtual Machine Firmware (OVMF) platform. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8398 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c | 222 ++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100755 OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c (limited to 'OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c') diff --git a/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c b/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c new file mode 100755 index 0000000000..949a89d713 --- /dev/null +++ b/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c @@ -0,0 +1,222 @@ +/** @file + ACPI Timer implements one instance of Timer Library. + + Copyright (c) 2008, Intel Corporation
All rights + reserved. This program and the accompanying materials are + licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include + +#define ACPI_TIMER_FREQUENCY 3579545 +#define ACPI_TIMER_COUNT_SIZE 0x01000000 + +/** + The constructor function enables ACPI IO space. + + If ACPI I/O space not enabled, this function will enable it. + It will always return RETURN_SUCCESS. + + @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS. + +**/ +RETURN_STATUS +EFIAPI +AcpiTimerLibConstructor ( + VOID + ) +{ + UINT8 Device; + + Device = 1; + // Device = 7; + + // + // ACPI Timer enable is in Bus 0, Device ?, Function 3 + // + PciOr8 (PCI_LIB_ADDRESS (0,Device,3,0x04), 0x01); + PciAndThenOr32 (PCI_LIB_ADDRESS (0,Device,3,0x40), (UINT32) ~0xfc0, 0x400); + PciOr8 (PCI_LIB_ADDRESS (0,Device,3,0x80), 0x01); return RETURN_SUCCESS; +} + +/** + Internal function to read the current tick counter of ACPI. + + Internal function to read the current tick counter of ACPI. + + @return The tick counter read. + +**/ +STATIC +UINT32 +InternalAcpiGetTimerTick ( + VOID + ) +{ + return IoRead32 (0x408); +} + +/** + Stalls the CPU for at least the given number of ticks. + + Stalls the CPU for at least the given number of ticks. It's invoked by + MicroSecondDelay() and NanoSecondDelay(). + + @param Delay A period of time to delay in ticks. + +**/ +STATIC +VOID +InternalAcpiDelay ( + IN UINT32 Delay + ) +{ + UINT32 Ticks; + UINT32 Times; + + Times = Delay >> 22; + Delay &= BIT22 - 1; + do { + // + // The target timer count is calculated here + // + Ticks = InternalAcpiGetTimerTick () + Delay; + Delay = BIT22; + // + // Wait until time out + // Delay >= 2^23 could not be handled by this function + // Timer wrap-arounds are handled correctly by this function + // + while (((Ticks - InternalAcpiGetTimerTick ()) & BIT23) == 0) { + CpuPause (); + } + } while (Times-- > 0); +} + +/** + Stalls the CPU for at least the given number of microseconds. + + Stalls the CPU for the number of microseconds specified by MicroSeconds. + + @param MicroSeconds The minimum number of microseconds to delay. + + @return MicroSeconds + +**/ +UINTN +EFIAPI +MicroSecondDelay ( + IN UINTN MicroSeconds + ) +{ + InternalAcpiDelay ( + (UINT32)DivU64x32 ( + MultU64x32 ( + MicroSeconds, + ACPI_TIMER_FREQUENCY + ), + 1000000u + ) + ); + return MicroSeconds; +} + +/** + Stalls the CPU for at least the given number of nanoseconds. + + Stalls the CPU for the number of nanoseconds specified by NanoSeconds. + + @param NanoSeconds The minimum number of nanoseconds to delay. + + @return NanoSeconds + +**/ +UINTN +EFIAPI +NanoSecondDelay ( + IN UINTN NanoSeconds + ) +{ + InternalAcpiDelay ( + (UINT32)DivU64x32 ( + MultU64x32 ( + NanoSeconds, + ACPI_TIMER_FREQUENCY + ), + 1000000000u + ) + ); + return NanoSeconds; +} + +/** + Retrieves the current value of a 64-bit free running performance counter. + + Retrieves the current value of a 64-bit free running performance counter. The + counter can either count up by 1 or count down by 1. If the physical + performance counter counts by a larger increment, then the counter values + must be translated. The properties of the counter can be retrieved from + GetPerformanceCounterProperties(). + + @return The current value of the free running performance counter. + +**/ +UINT64 +EFIAPI +GetPerformanceCounter ( + VOID + ) +{ + return (UINT64)InternalAcpiGetTimerTick (); +} + +/** + Retrieves the 64-bit frequency in Hz and the range of performance counter + values. + + If StartValue is not NULL, then the value that the performance counter starts + with immediately after is it rolls over is returned in StartValue. If + EndValue is not NULL, then the value that the performance counter end with + immediately before it rolls over is returned in EndValue. The 64-bit + frequency of the performance counter in Hz is always returned. If StartValue + is less than EndValue, then the performance counter counts up. If StartValue + is greater than EndValue, then the performance counter counts down. For + example, a 64-bit free running counter that counts up would have a StartValue + of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter + that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0. + + @param StartValue The value the performance counter starts with when it + rolls over. + @param EndValue The value that the performance counter ends with before + it rolls over. + + @return The frequency in Hz. + +**/ +UINT64 +EFIAPI +GetPerformanceCounterProperties ( + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL + ) +{ + if (StartValue != NULL) { + *StartValue = 0; + } + + if (EndValue != NULL) { + *EndValue = ACPI_TIMER_COUNT_SIZE - 1; + } + + return ACPI_TIMER_FREQUENCY; +} -- cgit v1.2.3