--- /dev/null
+/** @file\r
+ Timer Library functions built upon local APIC on IA32/x64.\r
+\r
+ Copyright (c) 2006 - 2008, Intel Corporation<BR>\r
+ All rights reserved. This program and the accompanying materials\r
+ are 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
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+\r
+//\r
+// The following array is used in calculating the frequency of local APIC\r
+// timer. Refer to IA-32 developers' manual for more details.\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED\r
+CONST UINT8 mTimerLibLocalApicDivisor[] = {\r
+ 0x02, 0x04, 0x08, 0x10,\r
+ 0x02, 0x04, 0x08, 0x10,\r
+ 0x20, 0x40, 0x80, 0x01,\r
+ 0x20, 0x40, 0x80, 0x01\r
+};\r
+\r
+/**\r
+ Internal function to retrieve the base address of local APIC.\r
+\r
+ Internal function to retrieve the base address of local APIC.\r
+\r
+ @return The base address of local APIC\r
+\r
+**/\r
+UINTN\r
+InternalX86GetApicBase (\r
+ VOID\r
+ )\r
+{\r
+ return (UINTN)AsmMsrBitFieldRead64 (27, 12, 35) << 12;\r
+}\r
+\r
+/**\r
+ Internal function to return the frequency of the local APIC timer.\r
+\r
+ Internal function to return the frequency of the local APIC timer.\r
+\r
+ @param ApicBase The base address of memory mapped registers of local APIC.\r
+\r
+ @return The frequency of the timer in Hz.\r
+\r
+**/\r
+UINT32\r
+InternalX86GetTimerFrequency (\r
+ IN UINTN ApicBase\r
+ )\r
+{\r
+ return\r
+ PcdGet32(PcdFSBClock) /\r
+ mTimerLibLocalApicDivisor[MmioBitFieldRead32 (ApicBase + 0x3e0, 0, 3)];\r
+}\r
+\r
+/**\r
+ Internal function to read the current tick counter of local APIC.\r
+\r
+ Internal function to read the current tick counter of local APIC.\r
+\r
+ @param ApicBase The base address of memory mapped registers of local APIC.\r
+\r
+ @return The tick counter read.\r
+\r
+**/\r
+INT32\r
+InternalX86GetTimerTick (\r
+ IN UINTN ApicBase\r
+ )\r
+{\r
+ return MmioRead32 (ApicBase + 0x390);\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 ApicBase The base address of memory mapped registers of local APIC.\r
+ @param Delay A period of time to delay in ticks.\r
+\r
+**/\r
+VOID\r
+InternalX86Delay (\r
+ IN UINTN ApicBase,\r
+ IN UINT32 Delay\r
+ )\r
+{\r
+ INT32 Ticks;\r
+\r
+ //\r
+ // The target timer count is calculated here\r
+ //\r
+ Ticks = InternalX86GetTimerTick (ApicBase) - Delay;\r
+\r
+ //\r
+ // Wait until time out\r
+ // Delay > 2^31 could not be handled by this function\r
+ // Timer wrap-arounds are handled correctly by this function\r
+ //\r
+ while (InternalX86GetTimerTick (ApicBase) - Ticks >= 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
+ UINTN ApicBase;\r
+\r
+ ApicBase = InternalX86GetApicBase ();\r
+ InternalX86Delay (\r
+ ApicBase,\r
+ (UINT32)DivU64x32 (\r
+ MultU64x64 (\r
+ InternalX86GetTimerFrequency (ApicBase),\r
+ MicroSeconds\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
+ UINTN ApicBase;\r
+\r
+ ApicBase = InternalX86GetApicBase ();\r
+ InternalX86Delay (\r
+ ApicBase,\r
+ (UINT32)DivU64x32 (\r
+ MultU64x64 (\r
+ InternalX86GetTimerFrequency (ApicBase),\r
+ NanoSeconds\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)(UINT32)InternalX86GetTimerTick (InternalX86GetApicBase ());\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
+ UINTN ApicBase;\r
+\r
+ ApicBase = InternalX86GetApicBase ();\r
+\r
+ if (StartValue != NULL) {\r
+ *StartValue = MmioRead32 (ApicBase + 0x380);\r
+ }\r
+\r
+ if (EndValue != NULL) {\r
+ *EndValue = 0;\r
+ }\r
+\r
+ return (UINT64) InternalX86GetTimerFrequency (ApicBase);;\r
+}\r
+++ /dev/null
-/** @file\r
- Timer Library functions built upon local APIC on IA32/x64.\r
-\r
- Copyright (c) 2006 - 2007, Intel Corporation<BR>\r
- All rights reserved. This program and the accompanying materials\r
- are 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
-\r
-**/\r
-\r
-#include <Base.h>\r
-#include <Library/TimerLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/PcdLib.h>\r
-\r
-\r
-//\r
-// The following array is used in calculating the frequency of local APIC\r
-// timer. Refer to IA-32 developers' manual for more details.\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED\r
-CONST UINT8 mTimerLibLocalApicDivisor[] = {\r
- 0x02, 0x04, 0x08, 0x10,\r
- 0x02, 0x04, 0x08, 0x10,\r
- 0x20, 0x40, 0x80, 0x01,\r
- 0x20, 0x40, 0x80, 0x01\r
-};\r
-\r
-/**\r
- Internal function to retrieve the base address of local APIC.\r
-\r
- Internal function to retrieve the base address of local APIC.\r
-\r
- @return The base address of local APIC\r
-\r
-**/\r
-STATIC\r
-UINTN\r
-InternalX86GetApicBase (\r
- VOID\r
- )\r
-{\r
- return (UINTN)AsmMsrBitFieldRead64 (27, 12, 35) << 12;\r
-}\r
-\r
-/**\r
- Internal function to return the frequency of the local APIC timer.\r
-\r
- Internal function to return the frequency of the local APIC timer.\r
-\r
- @param ApicBase The base address of memory mapped registers of local APIC.\r
-\r
- @return The frequency of the timer in Hz.\r
-\r
-**/\r
-STATIC\r
-UINT32\r
-InternalX86GetTimerFrequency (\r
- IN UINTN ApicBase\r
- )\r
-{\r
- return\r
- PcdGet32(PcdFSBClock) /\r
- mTimerLibLocalApicDivisor[MmioBitFieldRead32 (ApicBase + 0x3e0, 0, 3)];\r
-}\r
-\r
-/**\r
- Internal function to read the current tick counter of local APIC.\r
-\r
- Internal function to read the current tick counter of local APIC.\r
-\r
- @param ApicBase The base address of memory mapped registers of local APIC.\r
-\r
- @return The tick counter read.\r
-\r
-**/\r
-STATIC\r
-INT32\r
-InternalX86GetTimerTick (\r
- IN UINTN ApicBase\r
- )\r
-{\r
- return MmioRead32 (ApicBase + 0x390);\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 ApicBase The base address of memory mapped registers of local APIC.\r
- @param Delay A period of time to delay in ticks.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-InternalX86Delay (\r
- IN UINTN ApicBase,\r
- IN UINT32 Delay\r
- )\r
-{\r
- INT32 Ticks;\r
-\r
- //\r
- // The target timer count is calculated here\r
- //\r
- Ticks = InternalX86GetTimerTick (ApicBase) - Delay;\r
-\r
- //\r
- // Wait until time out\r
- // Delay > 2^31 could not be handled by this function\r
- // Timer wrap-arounds are handled correctly by this function\r
- //\r
- while (InternalX86GetTimerTick (ApicBase) - Ticks >= 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
- UINTN ApicBase;\r
-\r
- ApicBase = InternalX86GetApicBase ();\r
- InternalX86Delay (\r
- ApicBase,\r
- (UINT32)DivU64x32 (\r
- MultU64x64 (\r
- InternalX86GetTimerFrequency (ApicBase),\r
- MicroSeconds\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
- UINTN ApicBase;\r
-\r
- ApicBase = InternalX86GetApicBase ();\r
- InternalX86Delay (\r
- ApicBase,\r
- (UINT32)DivU64x32 (\r
- MultU64x64 (\r
- InternalX86GetTimerFrequency (ApicBase),\r
- NanoSeconds\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)(UINT32)InternalX86GetTimerTick (InternalX86GetApicBase ());\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
- UINTN ApicBase;\r
-\r
- ApicBase = InternalX86GetApicBase ();\r
-\r
- if (StartValue != NULL) {\r
- *StartValue = MmioRead32 (ApicBase + 0x380);\r
- }\r
-\r
- if (EndValue != NULL) {\r
- *EndValue = 0;\r
- }\r
-\r
- return (UINT64) InternalX86GetTimerFrequency (ApicBase);;\r
-}\r