\r
**/\r
\r
-UINT64\r
-ReadItc (\r
- VOID\r
- );\r
-\r
-typedef struct {\r
- UINT64 Status;\r
- UINT64 r9;\r
- UINT64 r10;\r
- UINT64 r11;\r
-} PAL_PROC_RETURN;\r
-\r
-PAL_PROC_RETURN\r
-CallPalProcStatic (\r
- IN UINT64 Arg1,\r
- IN UINT64 Arg2,\r
- IN UINT64 Arg3,\r
- IN UINT64 Arg4\r
- );\r
+\r
+\r
+\r
+/**\r
+ Performs a delay measured as number of ticks.\r
+\r
+ An internal function to perform a delay measured as number of ticks. It's\r
+ invoked by MicroSecondDelay() and NanoSecondDelay().\r
+\r
+ @param Delay Number of ticks to delay.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+InternalIpfDelay (\r
+ IN INT64 Delay\r
+ )\r
+{\r
+ INT64 Ticks;\r
+\r
+ //\r
+ // The target timer count is calculated here\r
+ //\r
+ Ticks = IpfReadItc () + Delay;\r
+\r
+ //\r
+ // Wait until time out\r
+ // Delay > 2^63 could not be handled by this function\r
+ // Timer wrap-arounds are handled correctly by this function\r
+ //\r
+ while (Ticks - IpfReadItc () >= 0);\r
+}\r
\r
/**\r
Stalls the CPU for at least the given number of microseconds.\r
\r
@param MicroSeconds The minimum number of microseconds to delay.\r
\r
- @return The ticks delayed actually.\r
+ @return MicroSeconds\r
\r
**/\r
UINTN\r
IN UINTN MicroSeconds\r
)\r
{\r
- UINT64 Ticks;\r
- UINT64 Delay;\r
-\r
- Ticks = GetPerformanceCounter ();\r
- Delay = GetPerformanceCounterProperties (NULL, NULL) * MicroSeconds / 1000000;\r
- while (Ticks + Delay < GetPerformanceCounter ());\r
- return (UINTN)Delay;\r
+ InternalIpfDelay (\r
+ GetPerformanceCounterProperties (NULL, NULL) *\r
+ MicroSeconds /\r
+ 1000000\r
+ );\r
+ return MicroSeconds;\r
}\r
\r
/**\r
\r
@param NanoSeconds The minimum number of nanoseconds to delay.\r
\r
- @return The ticks delayed actually.\r
+ @return NanoSeconds\r
\r
**/\r
UINTN\r
IN UINTN NanoSeconds\r
)\r
{\r
- UINT64 Ticks;\r
- UINT64 Delay;\r
-\r
- Ticks = GetPerformanceCounter ();\r
- Delay = GetPerformanceCounterProperties (NULL, NULL) * NanoSeconds / 1000000000;\r
- while (Ticks + Delay < GetPerformanceCounter ());\r
- return (UINTN)Delay;\r
+ InternalIpfDelay (\r
+ GetPerformanceCounterProperties (NULL, NULL) *\r
+ NanoSeconds /\r
+ 1000000000\r
+ );\r
+ return NanoSeconds;\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- return ReadItc ();\r
+ return IpfReadItc ();\r
}\r
\r
/**\r
UINT64\r
EFIAPI\r
GetPerformanceCounterProperties (\r
- IN UINT64 *StartValue,\r
- IN UINT64 *EndValue\r
+ OUT UINT64 *StartValue, OPTIONAL\r
+ OUT UINT64 *EndValue OPTIONAL\r
)\r
{\r
PAL_PROC_RETURN PalRet;\r
UINT64 BaseFrequence;\r
\r
- PalRet = CallPalProcStatic (13, 0, 0, 0);\r
+ PalRet = PalCallStatic (NULL, 13, 0, 0, 0);\r
ASSERT (PalRet.Status == 0);\r
BaseFrequence = PalRet.r9;\r
\r
- PalRet = CallPalProcStatic (14, 0, 0, 0);\r
+ PalRet = PalCallStatic (NULL, 14, 0, 0, 0);\r
ASSERT (PalRet.Status == 0);\r
\r
- *StartValue = 0;\r
- *EndValue = (UINT64)(-1);\r
+ if (StartValue != NULL) {\r
+ *StartValue = 0;\r
+ }\r
+\r
+ if (EndValue != NULL) {\r
+ *EndValue = (UINT64)(-1);\r
+ }\r
+\r
return BaseFrequence * (PalRet.r11 >> 32) / (UINT32)PalRet.r11;\r
}\r