From 16b7aff06b4379eaac48dc6e78c7a3944c0bdbad Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Mon, 2 Feb 2015 12:01:48 +0000 Subject: ArmPkg: ArmArchTimerLib: conditionally rebase to actual timer frequency Allow a platform to set PcdArmArchTimerFreqInHz to zero, and consider it a request to use the actual timer frequency. No global variable is introduced, so that the library can be used in PEIMs that execute from flash. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Reviewed-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16691 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c | 58 ++++++++++++++++-------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c index 51d7ce9..a0e4f58 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 ); -- cgit v1.1