- UINTN Ticks;\r
-\r
- Ticks = (UINTN)GetPerformanceCounter ();\r
- Ticks -= (UINTN)DivU64x32 (\r
- MultU64x64 (\r
- GetPerformanceCounterProperties (NULL, NULL),\r
- NDelay\r
- ),\r
- 1000000000u\r
- );\r
- while (Ticks >= GetPerformanceCounter ());\r
- return Ticks;\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
+ mTimerLibLocalApicFrequencies[AsmMsrBitFieldRead32 (44, 16, 18)] /\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