]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
ArmPkg: ArmArchTimerLib: conditionally rebase to actual timer frequency
[mirror_edk2.git] / ArmPkg / Library / ArmArchTimerLib / ArmArchTimerLib.c
index 51d7ce998fe66bf2d3ae76746017ee926227e85b..a0e4f5804b57e04e9bad55d9a5e81d728c7664a5 100644 (file)
@@ -37,28 +37,29 @@ TimerConstructor (
     UINTN TimerFreq;\r
 \r
     //\r
-    // Check if Architectural Timer frequency is valid (should not be 0).\r
+    // Check if Architectural Timer frequency is pre-determined by the platform\r
+    // (ie. nonzero).\r
     //\r
-    ASSERT (PcdGet32 (PcdArmArchTimerFreqInHz));\r
-\r
-    //\r
-    // Check if ticks/uS is not 0. The Architectural timer runs at constant\r
-    // frequency, irrespective of CPU frequency. According to General Timer\r
-    // Ref manual, lower bound of the frequency is in the range of 1-10MHz.\r
-    //\r
-    ASSERT (TICKS_PER_MICRO_SEC);\r
+    if (PcdGet32 (PcdArmArchTimerFreqInHz) != 0) {\r
+      //\r
+      // Check if ticks/uS is not 0. The Architectural timer runs at constant\r
+      // frequency, irrespective of CPU frequency. According to General Timer\r
+      // Ref manual, lower bound of the frequency is in the range of 1-10MHz.\r
+      //\r
+      ASSERT (TICKS_PER_MICRO_SEC);\r
 \r
 #ifdef MDE_CPU_ARM\r
-    //\r
-    // Only set the frequency for ARMv7. We expect the secure firmware to\r
-    // have already done it.\r
-    // If the security extension is not implemented, set Timer Frequency\r
-    // here.\r
-    //\r
-    if ((ArmReadIdPfr1 () & ARM_PFR1_SEC) == 0x0) {\r
-      ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));\r
-    }\r
+      //\r
+      // Only set the frequency for ARMv7. We expect the secure firmware to\r
+      // have already done it.\r
+      // If the security extension is not implemented, set Timer Frequency\r
+      // here.\r
+      //\r
+      if ((ArmReadIdPfr1 () & ARM_PFR1_SEC) == 0x0) {\r
+        ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));\r
+      }\r
 #endif\r
+    }\r
 \r
     //\r
     // Architectural Timer Frequency must be set in the Secure privileged\r
@@ -92,14 +93,31 @@ MicroSecondDelay (
 {\r
   UINT64 TimerTicks64;\r
   UINT64 SystemCounterVal;\r
+  UINT64 (EFIAPI\r
+          *MultU64xN) (\r
+            IN UINT64 Multiplicand,\r
+            IN UINTN  Multiplier\r
+            );\r
+  UINTN TimerFreq;\r
+\r
+#ifdef MDE_CPU_ARM\r
+  MultU64xN = MultU64x32;\r
+#else\r
+  MultU64xN = MultU64x64;\r
+#endif\r
+\r
+  TimerFreq = PcdGet32 (PcdArmArchTimerFreqInHz);\r
+  if (TimerFreq == 0) {\r
+    TimerFreq = ArmGenericTimerGetTimerFreq ();\r
+  }\r
 \r
   // Calculate counter ticks that can represent requested delay:\r
   //  = MicroSeconds x TICKS_PER_MICRO_SEC\r
   //  = MicroSeconds x Frequency.10^-6\r
   TimerTicks64 = DivU64x32 (\r
-                   MultU64x32 (\r
+                   MultU64xN (\r
                      MicroSeconds,\r
-                     PcdGet32 (PcdArmArchTimerFreqInHz)\r
+                     TimerFreq\r
                      ),\r
                    1000000U\r
                    );\r