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 <[email protected]> --- 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 bcddf1e..38c2517 100644 --- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c +++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c @@ -34,34 +34,35 @@ TimerConstructor ( // Check if the ARM Generic Timer Extension is implemented. // if (ArmIsArchTimerImplemented ()) { 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 extensions are 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 extensions are not implemented, set Timer Frequency + // here. + // + if ((ArmReadIdPfr1 () & ARM_PFR1_SEC) == 0x0) { + ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz)); + } +#endif } -#endif // // Architectural Timer Frequency must be set in the Secure privileged // mode (if secure extensions are supported). // If the reset value (0) is returned, just ASSERT. // @@ -89,20 +90,37 @@ EFIAPI MicroSecondDelay ( IN UINTN MicroSeconds ) { 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 ); // Read System Counter value SystemCounterVal = ArmGenericTimerGetSystemCount (); -- 1.8.3.1 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ _______________________________________________ edk2-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/edk2-devel
