4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ACPI Timer implements one instance of Timer Library.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials are
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Base.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/TimerLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/BaseLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/IoLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/PciLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/DebugLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// PIIX4 Power Management Base Address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32 mPmba = 0x400;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define PCI_BAR_IO 0x1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define ACPI_TIMER_FREQUENCY 3579545
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define ACPI_TIMER_COUNT_SIZE 0x01000000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define ACPI_TIMER_OFFSET 0x8
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The constructor function enables ACPI IO space.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If ACPI I/O space not enabled, this function will enable it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync It will always return RETURN_SUCCESS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRETURN_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAcpiTimerLibConstructor (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Device;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Device = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Device = 7;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PciRead8 (PCI_LIB_ADDRESS (0,Device,3,0x80)) & 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mPmba = PciRead32 (PCI_LIB_ADDRESS (0,Device,3,0x40));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (mPmba & PCI_BAR_IO);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mPmba &= ~PCI_BAR_IO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciAndThenOr32 (PCI_LIB_ADDRESS (0,Device,3,0x40),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT32) ~0xfc0, mPmba);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciOr8 (PCI_LIB_ADDRESS (0,Device,3,0x04), 0x01);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ACPI Timer enable is in Bus 0, Device ?, Function 3
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PciOr8 (PCI_LIB_ADDRESS (0,Device,3,0x80), 0x01);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return RETURN_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Internal function to read the current tick counter of ACPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Internal function to read the current tick counter of ACPI.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The tick counter read.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSTATIC
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInternalAcpiGetTimerTick (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return IoRead32 (mPmba + ACPI_TIMER_OFFSET);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stalls the CPU for at least the given number of ticks.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stalls the CPU for at least the given number of ticks. It's invoked by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MicroSecondDelay() and NanoSecondDelay().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Delay A period of time to delay in ticks.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSTATIC
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInternalAcpiDelay (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Delay
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Ticks;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Times;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Times = Delay >> 22;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay &= BIT22 - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The target timer count is calculated here
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ticks = InternalAcpiGetTimerTick () + Delay;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delay = BIT22;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Wait until time out
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Delay >= 2^23 could not be handled by this function
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Timer wrap-arounds are handled correctly by this function
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (((Ticks - InternalAcpiGetTimerTick ()) & BIT23) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuPause ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Times-- > 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stalls the CPU for at least the given number of microseconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stalls the CPU for the number of microseconds specified by MicroSeconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MicroSeconds The minimum number of microseconds to delay.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return MicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINTN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMicroSecondDelay (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN MicroSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InternalAcpiDelay (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT32)DivU64x32 (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32 (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MicroSeconds,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ACPI_TIMER_FREQUENCY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1000000u
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return MicroSeconds;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stalls the CPU for at least the given number of nanoseconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param NanoSeconds The minimum number of nanoseconds to delay.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return NanoSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINTN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncNanoSecondDelay (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN NanoSeconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InternalAcpiDelay (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT32)DivU64x32 (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MultU64x32 (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NanoSeconds,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ACPI_TIMER_FREQUENCY
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1000000000u
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NanoSeconds;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Retrieves the current value of a 64-bit free running performance counter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Retrieves the current value of a 64-bit free running performance counter. The
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync counter can either count up by 1 or count down by 1. If the physical
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync performance counter counts by a larger increment, then the counter values
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync must be translated. The properties of the counter can be retrieved from
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GetPerformanceCounterProperties().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The current value of the free running performance counter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT64
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGetPerformanceCounter (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (UINT64)InternalAcpiGetTimerTick ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Retrieves the 64-bit frequency in Hz and the range of performance counter
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync values.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If StartValue is not NULL, then the value that the performance counter starts
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync with immediately after is it rolls over is returned in StartValue. If
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EndValue is not NULL, then the value that the performance counter end with
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync immediately before it rolls over is returned in EndValue. The 64-bit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync frequency of the performance counter in Hz is always returned. If StartValue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is less than EndValue, then the performance counter counts up. If StartValue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is greater than EndValue, then the performance counter counts down. For
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync example, a 64-bit free running counter that counts up would have a StartValue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param StartValue The value the performance counter starts with when it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rolls over.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param EndValue The value that the performance counter ends with before
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync it rolls over.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The frequency in Hz.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT64
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGetPerformanceCounterProperties (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *StartValue, OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *EndValue OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StartValue != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *StartValue = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EndValue != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *EndValue = ACPI_TIMER_COUNT_SIZE - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ACPI_TIMER_FREQUENCY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Converts elapsed ticks of performance counter to time in nanoseconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function converts the elapsed ticks of running performance counter to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync time value in unit of nanoseconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Ticks The number of elapsed ticks of running performance counter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The elapsed time in nanoseconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT64
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGetTimeInNanoSecond (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Ticks
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 NanoSeconds;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Remainder;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Ticks
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Time = --------- x 1,000,000,000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Frequency
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, ACPI_TIMER_FREQUENCY, &Remainder), 1000000000u);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // will not overflow 64-bit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NanoSeconds += DivU64x32 (MultU64x32 ((UINT64) Remainder, 1000000000u), ACPI_TIMER_FREQUENCY);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NanoSeconds;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}