]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c
Make EDK Module Package pass Intel IPF compiler with /Ox switch.
[mirror_edk2.git] / MdePkg / Library / BaseTimerLibLocalApic / Ipf / IpfTimerLib.c
index 652cc7e6e49a4f1b22e8efb60821a27c6b693bcf..65b58bc54945ec96ff2187c5ad50020505ef2fcf 100644 (file)
 \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
@@ -45,7 +58,7 @@ CallPalProcStatic (
 \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
@@ -54,13 +67,12 @@ MicroSecondDelay (
   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
@@ -70,7 +82,7 @@ MicroSecondDelay (
 \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
@@ -79,13 +91,12 @@ NanoSecondDelay (
   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
@@ -106,7 +117,7 @@ GetPerformanceCounter (
   VOID\r
   )\r
 {\r
-  return ReadItc ();\r
+  return IpfReadItc ();\r
 }\r
 \r
 /**\r
@@ -135,21 +146,27 @@ GetPerformanceCounter (
 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