]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c
1. Updated declaration of timer functions according to latest MWG.
[mirror_edk2.git] / MdePkg / Library / BaseTimerLibLocalApic / Ipf / IpfTimerLib.c
index 3814534607d924913f90021c0a3281223a804668..800b5258e38a1dee7867b91b2238a7ae5bff18ab 100644 (file)
 \r
 **/\r
 \r
-UINT64\r
-ReadItc (\r
-  VOID\r
-  );\r
-\r
 typedef struct {\r
   UINT64                            Status;\r
   UINT64                            r9;\r
@@ -30,6 +25,21 @@ typedef struct {
   UINT64                            r11;\r
 } PAL_PROC_RETURN;\r
 \r
+/**\r
+  Performs a PAL call using static calling convention.\r
+\r
+  An internal function to perform a PAL call using static calling convention.\r
+\r
+  @param  PalEntryPoint The entry point address of PAL. The address in ar.kr5\r
+                        would be used if this parameter were NULL on input.\r
+  @param  Arg1          The first argument of a PAL call.\r
+  @param  Arg1          The second argument of a PAL call.\r
+  @param  Arg1          The third argument of a PAL call.\r
+  @param  Arg1          The fourth argument of a PAL call.\r
+\r
+  @return The values returned in r8, r9, r10 and r11.\r
+\r
+**/\r
 PAL_PROC_RETURN\r
 PalCallStatic (\r
   IN      CONST VOID                *PalEntryPoint,\r
@@ -39,6 +49,50 @@ PalCallStatic (
   IN      UINT64                    Arg4\r
   );\r
 \r
+/**\r
+  Returns the current value of ar.itc.\r
+\r
+  An internal function to return the current value of ar.itc, which is the\r
+  timer tick on IPF.\r
+\r
+  @return The currect value of ar.itc\r
+\r
+**/\r
+INT64\r
+InternalIpfReadItc (\r
+  VOID\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 = InternalIpfReadItc () + 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 - InternalIpfReadItc () >= 0);\r
+}\r
+\r
 /**\r
   Stalls the CPU for at least the given number of microseconds.\r
 \r
@@ -46,7 +100,7 @@ PalCallStatic (
 \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
@@ -55,13 +109,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
@@ -71,7 +124,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
@@ -80,13 +133,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
@@ -107,7 +159,7 @@ GetPerformanceCounter (
   VOID\r
   )\r
 {\r
-  return ReadItc ();\r
+  return InternalIpfReadItc ();\r
 }\r
 \r
 /**\r
@@ -150,7 +202,13 @@ GetPerformanceCounterProperties (
   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