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