/** @file\r
ACPI Timer implements one instance of Timer Library.\r
\r
- Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>\r
\r
- This program and the accompanying materials are\r
- licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
- \r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
-**/ \r
+**/\r
\r
-#include <Base.h>\r
-#include <Library/TimerLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/PciLib.h>\r
#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <IndustryStandard/Acpi.h>\r
+\r
+#include "AcpiTimerLib.h"\r
\r
//\r
-// PIIX4 Power Management Base Address\r
+// The ACPI Time is a 24-bit counter\r
//\r
-UINT32 mPmba = 0x400;\r
-\r
-#define PCI_BAR_IO 0x1\r
-#define ACPI_TIMER_FREQUENCY 3579545\r
-#define ACPI_TIMER_COUNT_SIZE 0x01000000\r
-#define ACPI_TIMER_OFFSET 0x8\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
-AcpiTimerLibConstructor (\r
- VOID\r
- )\r
-{\r
- UINT8 Device;\r
-\r
- Device = 1;\r
- // Device = 7;\r
-\r
- if (PciRead8 (PCI_LIB_ADDRESS (0,Device,3,0x80)) & 1) {\r
- mPmba = PciRead32 (PCI_LIB_ADDRESS (0,Device,3,0x40));\r
- ASSERT (mPmba & PCI_BAR_IO);\r
- mPmba &= ~PCI_BAR_IO;\r
- } else {\r
- PciAndThenOr32 (PCI_LIB_ADDRESS (0,Device,3,0x40),\r
- (UINT32) ~0xfc0, mPmba);\r
- PciOr8 (PCI_LIB_ADDRESS (0,Device,3,0x04), 0x01);\r
- }\r
-\r
- //\r
- // ACPI Timer enable is in Bus 0, Device ?, Function 3\r
- //\r
- PciOr8 (PCI_LIB_ADDRESS (0,Device,3,0x80), 0x01);\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 (mPmba + ACPI_TIMER_OFFSET);\r
-}\r
+#define ACPI_TIMER_COUNT_SIZE BIT24\r
\r
/**\r
Stalls the CPU for at least the given number of ticks.\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
return ACPI_TIMER_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, ACPI_TIMER_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), ACPI_TIMER_FREQUENCY);\r
+\r
+ return NanoSeconds;\r
+}\r