+++ /dev/null
-/** @file\r
- ICH9 ACPI Timer implements one instance of Timer Library.\r
-\r
-Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
- \r\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
- \r\r
-\r
-**/\r
-\r
-#include "CommonHeader.h"\r
-\r
-/**\r
- The constructor function enables ACPI IO space.\r
-\r
- If ACPI I/O space not enabled, this function will enable it.\r
- It will always return RETURN_SUCCESS.\r
-\r
- @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.\r
-\r
-**/\r
-RETURN_STATUS\r
-EFIAPI\r
-IntelPchAcpiTimerLibConstructor (\r
- VOID\r
- )\r
-{\r
- if ((PchLpcPciCfg8(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_EN) == 0) {\r
- //\r
- // If ACPI I/O space is not enabled, program ACPI I/O base address and enable it.\r
- //\r
- MmioWrite16 (\r
- MmPciAddress (\r
- 0,\r
- DEFAULT_PCI_BUS_NUMBER_PCH,\r
- PCI_DEVICE_NUMBER_PCH_LPC,\r
- PCI_FUNCTION_NUMBER_PCH_LPC,\r
- R_PCH_LPC_ACPI_BASE\r
- ),\r
- ((PcdGet16 (PcdPchAcpiIoPortBaseAddress) & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN)\r
- );\r
- }\r
- return RETURN_SUCCESS;\r
-}\r
-\r
-/**\r
- Internal function to read the current tick counter of ACPI.\r
-\r
- Internal function to read the current tick counter of ACPI.\r
-\r
- @return The tick counter read.\r
-\r
-**/\r
-STATIC\r
-UINT32\r
-InternalAcpiGetTimerTick (\r
- VOID\r
- )\r
-{\r
- return IoRead32 (PcdGet16 (PcdPchAcpiIoPortBaseAddress) + R_PCH_ACPI_PM1_TMR);\r
-}\r
-\r
-/**\r
- Stalls the CPU for at least the given number of ticks.\r
-\r
- Stalls the CPU for at least the given number of ticks. It's invoked by\r
- MicroSecondDelay() and NanoSecondDelay().\r
-\r
- @param Delay A period of time to delay in ticks.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-InternalAcpiDelay (\r
- IN UINT32 Delay\r
- )\r
-{\r
- UINT32 Ticks;\r
- UINT32 Times;\r
-\r
- Times = Delay >> 22;\r
- Delay &= BIT22 - 1;\r
- do {\r
- //\r
- // The target timer count is calculated here\r
- //\r
- Ticks = InternalAcpiGetTimerTick () + Delay;\r
- Delay = BIT22;\r
- //\r
- // Wait until time out\r
- // Delay >= 2^23 could not be handled by this function\r
- // Timer wrap-arounds are handled correctly by this function\r
- //\r
- while (((Ticks - InternalAcpiGetTimerTick ()) & BIT23) == 0) {\r
- CpuPause ();\r
- }\r
- } while (Times-- > 0);\r
-}\r
-\r
-/**\r
- Stalls the CPU for at least the given number of microseconds.\r
-\r
- Stalls the CPU for the number of microseconds specified by MicroSeconds.\r
-\r
- @param MicroSeconds The minimum number of microseconds to delay.\r
-\r
- @return MicroSeconds\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-MicroSecondDelay (\r
- IN UINTN MicroSeconds\r
- )\r
-{\r
- InternalAcpiDelay (\r
- (UINT32)DivU64x32 (\r
- MultU64x32 (\r
- MicroSeconds,\r
- V_PCH_ACPI_PM1_TMR_FREQUENCY\r
- ),\r
- 1000000u\r
- )\r
- );\r
- return MicroSeconds;\r
-}\r
-\r
-/**\r
- Stalls the CPU for at least the given number of nanoseconds.\r
-\r
- Stalls the CPU for the number of nanoseconds specified by NanoSeconds.\r
-\r
- @param NanoSeconds The minimum number of nanoseconds to delay.\r
-\r
- @return NanoSeconds\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-NanoSecondDelay (\r
- IN UINTN NanoSeconds\r
- )\r
-{\r
- InternalAcpiDelay (\r
- (UINT32)DivU64x32 (\r
- MultU64x32 (\r
- NanoSeconds,\r
- V_PCH_ACPI_PM1_TMR_FREQUENCY\r
- ),\r
- 1000000000u\r
- )\r
- );\r
- return NanoSeconds;\r
-}\r
-\r
-/**\r
- Retrieves the current value of a 64-bit free running performance counter.\r
-\r
- Retrieves the current value of a 64-bit free running performance counter. The\r
- counter can either count up by 1 or count down by 1. If the physical\r
- performance counter counts by a larger increment, then the counter values\r
- must be translated. The properties of the counter can be retrieved from\r
- GetPerformanceCounterProperties().\r
-\r
- @return The current value of the free running performance counter.\r
-\r
-**/\r
-UINT64\r
-EFIAPI\r
-GetPerformanceCounter (\r
- VOID\r
- )\r
-{\r
- return (UINT64)InternalAcpiGetTimerTick ();\r
-}\r
-\r
-/**\r
- Retrieves the 64-bit frequency in Hz and the range of performance counter\r
- values.\r
-\r
- If StartValue is not NULL, then the value that the performance counter starts\r
- with immediately after is it rolls over is returned in StartValue. If\r
- EndValue is not NULL, then the value that the performance counter end with\r
- immediately before it rolls over is returned in EndValue. The 64-bit\r
- frequency of the performance counter in Hz is always returned. If StartValue\r
- is less than EndValue, then the performance counter counts up. If StartValue\r
- is greater than EndValue, then the performance counter counts down. For\r
- example, a 64-bit free running counter that counts up would have a StartValue\r
- of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter\r
- that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.\r
-\r
- @param StartValue The value the performance counter starts with when it\r
- rolls over.\r
- @param EndValue The value that the performance counter ends with before\r
- it rolls over.\r
-\r
- @return The frequency in Hz.\r
-\r
-**/\r
-UINT64\r
-EFIAPI\r
-GetPerformanceCounterProperties (\r
- OUT UINT64 *StartValue, OPTIONAL\r
- OUT UINT64 *EndValue OPTIONAL\r
- )\r
-{\r
- if (StartValue != NULL) {\r
- *StartValue = 0;\r
- }\r
-\r
- if (EndValue != NULL) {\r
- *EndValue = V_PCH_ACPI_PM1_TMR_MAX_VAL - 1;\r
- }\r
-\r
- return V_PCH_ACPI_PM1_TMR_FREQUENCY;\r
-}\r
-\r
-/**\r
- Converts elapsed ticks of performance counter to time in nanoseconds.\r
-\r
- This function converts the elapsed ticks of running performance counter to\r
- time value in unit of nanoseconds.\r
-\r
- @param Ticks The number of elapsed ticks of running performance counter.\r
-\r
- @return The elapsed time in nanoseconds.\r
-\r
-**/\r
-UINT64\r
-EFIAPI\r
-GetTimeInNanoSecond (\r
- IN UINT64 Ticks\r
- )\r
-{\r
- UINT64 NanoSeconds;\r
- UINT32 Remainder;\r
-\r
- //\r
- // Ticks\r
- // Time = --------- x 1,000,000,000\r
- // Frequency\r
- //\r
- NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, V_PCH_ACPI_PM1_TMR_FREQUENCY, &Remainder), 1000000000u);\r
-\r
- //\r
- // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)\r
- // will not overflow 64-bit.\r
- //\r
- NanoSeconds += DivU64x32 (MultU64x32 ((UINT64) Remainder, 1000000000u), V_PCH_ACPI_PM1_TMR_FREQUENCY);\r
-\r
- return NanoSeconds;\r
-}\r
-\r
-\r