diff options
author | Laszlo Ersek <lersek@redhat.com> | 2015-02-02 12:01:48 +0000 |
---|---|---|
committer | lersek <lersek@Edk2> | 2015-02-02 12:01:48 +0000 |
commit | 16b7aff06b4379eaac48dc6e78c7a3944c0bdbad (patch) | |
tree | 0c6767f26a508a95dc4afbe7fad751b74ab72c74 /ArmPkg/Library | |
parent | b36bc5af5854c3cd8b500e189366f1402ac30100 (diff) | |
download | edk2-16b7aff06b4379eaac48dc6e78c7a3944c0bdbad.zip edk2-16b7aff06b4379eaac48dc6e78c7a3944c0bdbad.tar.gz edk2-16b7aff06b4379eaac48dc6e78c7a3944c0bdbad.tar.bz2 |
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 <lersek@redhat.com>
Reviewed-by: Olivier Martin <Olivier.martin@arm.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16691 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPkg/Library')
-rw-r--r-- | ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c | 58 |
1 files 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
);
|