X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=PerformancePkg%2FLibrary%2FTscTimerLib%2FTscTimerLibShare.c;fp=PerformancePkg%2FLibrary%2FTscTimerLib%2FTscTimerLibShare.c;h=0000000000000000000000000000000000000000;hp=161af002374291d2596f973906ee32b42e6171f0;hb=922c1e94e4bb75e805d76acebbb54d0275fdbab7;hpb=02f6fd1d5f2e21dafc080721e7258bc2a2dc603c diff --git a/PerformancePkg/Library/TscTimerLib/TscTimerLibShare.c b/PerformancePkg/Library/TscTimerLib/TscTimerLibShare.c deleted file mode 100644 index 161af00237..0000000000 --- a/PerformancePkg/Library/TscTimerLib/TscTimerLibShare.c +++ /dev/null @@ -1,275 +0,0 @@ -/** @file - The Timer Library implementation which uses the Time Stamp Counter in the processor. - - For Pentium 4 processors, Intel Xeon processors (family [0FH], models [03H and higher]); - for Intel Core Solo and Intel Core Duo processors (family [06H], model [0EH]); - for the Intel Xeon processor 5100 series and Intel Core 2 Duo processors (family [06H], model [0FH]); - for Intel Core 2 and Intel Xeon processors (family [06H], display_model [17H]); - for Intel Atom processors (family [06H], display_model [1CH]): - the time-stamp counter increments at a constant rate. - That rate may be set by the maximum core-clock to bus-clock ratio of the processor or may be set by - the maximum resolved frequency at which the processor is booted. The maximum resolved frequency may - differ from the maximum qualified frequency of the processor. - - The specific processor configuration determines the behavior. Constant TSC behavior ensures that the - duration of each clock tick is uniform and supports the use of the TSC as a wall clock timer even if - the processor core changes frequency. This is the architectural behavior moving forward. - - A Processor's support for invariant TSC is indicated by CPUID.0x80000007.EDX[8]. - - Copyright (c) 2009 - 2011, 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 "TscTimerLibInternal.h" - -/** Calculate TSC frequency. - - The TSC counting frequency is determined by comparing how far it counts - during a 1ms period as determined by the ACPI timer. The ACPI timer is - used because it counts at a known frequency. - If ACPI I/O space not enabled, this function will enable it. Then the - TSC is sampled, followed by waiting for 3579 clocks of the ACPI timer, or 1ms. - The TSC is then sampled again. The difference multiplied by 1000 is the TSC - frequency. There will be a small error because of the overhead of reading - the ACPI timer. An attempt is made to determine and compensate for this error. - - @return The number of TSC counts per second. - -**/ -UINT64 -InternalCalculateTscFrequency ( - VOID - ) -{ - UINT64 StartTSC; - UINT64 EndTSC; - UINT32 TimerAddr; - UINT32 Ticks; - UINT64 TscFrequency; - - // - // If ACPI I/O space is not enabled yet, program ACPI I/O base address and enable it. - // - if ((PciRead8 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_CNT)) & B_ICH_LPC_ACPI_CNT_ACPI_EN) == 0) { - PciWrite16 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_BASE), PcdGet16 (PcdPerfPkgAcpiIoPortBaseAddress)); - PciOr8 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_CNT), B_ICH_LPC_ACPI_CNT_ACPI_EN); - } - - // - // ACPI I/O space should be enabled now, locate the ACPI Timer. - // ACPI I/O base address maybe have be initialized by other driver with different value, - // So get it from PCI space directly. - // - TimerAddr = ((PciRead16 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_BASE))) & B_ICH_LPC_ACPI_BASE_BAR) + R_ACPI_PM1_TMR; - Ticks = IoRead32 (TimerAddr) + (3579); // Set Ticks to 1ms in the future - StartTSC = AsmReadTsc(); // Get base value for the TSC - // - // Wait until the ACPI timer has counted 1ms. - // Timer wrap-arounds are handled correctly by this function. - // When the current ACPI timer value is greater than 'Ticks', the while loop will exit. - // - while (((Ticks - IoRead32 (TimerAddr)) & BIT23) == 0) { - CpuPause(); - } - EndTSC = AsmReadTsc(); // TSC value 1ms later - - TscFrequency = MultU64x32 ( - (EndTSC - StartTSC), // Number of TSC counts in 1ms - 1000 // Number of ms in a second - ); - - return TscFrequency; -} - -/** 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[in] Delay A period of time to delay in ticks. - -**/ -VOID -InternalX86Delay ( - IN UINT64 Delay - ) -{ - UINT64 Ticks; - - // - // The target timer count is calculated here - // - Ticks = AsmReadTsc() + Delay; - - // - // Wait until time out - // Timer wrap-arounds are NOT handled correctly by this function. - // Thus, this function must be called within 10 years of reset since - // Intel guarantees a minimum of 10 years before the TSC wraps. - // - while (AsmReadTsc() <= Ticks) CpuPause(); -} - -/** Stalls the CPU for at least the specified number of MicroSeconds. - - @param[in] MicroSeconds The minimum number of microseconds to delay. - - @return The value of MicroSeconds input. - -**/ -UINTN -EFIAPI -MicroSecondDelay ( - IN UINTN MicroSeconds - ) -{ - InternalX86Delay ( - DivU64x32 ( - MultU64x64 ( - InternalGetTscFrequency (), - MicroSeconds - ), - 1000000u - ) - ); - return MicroSeconds; -} - -/** Stalls the CPU for at least the specified number of NanoSeconds. - - @param[in] NanoSeconds The minimum number of nanoseconds to delay. - - @return The value of NanoSeconds input. - -**/ -UINTN -EFIAPI -NanoSecondDelay ( - IN UINTN NanoSeconds - ) -{ - InternalX86Delay ( - DivU64x32 ( - MultU64x32 ( - InternalGetTscFrequency (), - (UINT32)NanoSeconds - ), - 1000000000u - ) - ); - return NanoSeconds; -} - -/** Retrieves the current value of the 64-bit free running Time-Stamp counter. - - The time-stamp counter (as implemented in the P6 family, Pentium, Pentium M, - Pentium 4, Intel Xeon, Intel Core Solo and Intel Core Duo processors and - later processors) is a 64-bit counter that is set to 0 following a RESET of - the processor. Following a RESET, the counter increments even when the - processor is halted by the HLT instruction or the external STPCLK# pin. Note - that the assertion of the external DPSLP# pin may cause the time-stamp - counter to stop. - - The properties of the counter can be retrieved by the - GetPerformanceCounterProperties() function. - - @return The current value of the free running performance counter. - -**/ -UINT64 -EFIAPI -GetPerformanceCounter ( - VOID - ) -{ - return AsmReadTsc(); -} - -/** 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, 0x0, is returned in StartValue. If EndValue is not NULL, then the value - that the performance counter end with, 0xFFFFFFFFFFFFFFFF, is returned in - EndValue. - - The 64-bit frequency of the performance counter, in Hz, is always returned. - To determine average processor clock frequency, Intel recommends the use of - EMON logic to count processor core clocks over the period of time for which - the average is required. - - - @param[out] StartValue Pointer to where the performance counter's starting value is saved, or NULL. - @param[out] EndValue Pointer to where the performance counter's ending value is saved, or NULL. - - @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 = 0xFFFFFFFFFFFFFFFFull; - } - - return InternalGetTscFrequency (); -} - -/** - Converts elapsed ticks of performance counter to time in nanoseconds. - - This function converts the elapsed ticks of running performance counter to - time value in unit of nanoseconds. - - @param Ticks The number of elapsed ticks of running performance counter. - - @return The elapsed time in nanoseconds. - -**/ -UINT64 -EFIAPI -GetTimeInNanoSecond ( - IN UINT64 Ticks - ) -{ - UINT64 Frequency; - UINT64 NanoSeconds; - UINT64 Remainder; - INTN Shift; - - Frequency = GetPerformanceCounterProperties (NULL, NULL); - - // - // Ticks - // Time = --------- x 1,000,000,000 - // Frequency - // - NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u); - - // - // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. - // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34, - // i.e. highest bit set in Remainder should <= 33. - // - Shift = MAX (0, HighBitSet64 (Remainder) - 33); - Remainder = RShiftU64 (Remainder, (UINTN) Shift); - Frequency = RShiftU64 (Frequency, (UINTN) Shift); - NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL); - - return NanoSeconds; -}