summaryrefslogtreecommitdiff
path: root/ArmPkg
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2015-02-02 12:01:48 +0000
committerlersek <lersek@Edk2>2015-02-02 12:01:48 +0000
commit16b7aff06b4379eaac48dc6e78c7a3944c0bdbad (patch)
tree0c6767f26a508a95dc4afbe7fad751b74ab72c74 /ArmPkg
parentb36bc5af5854c3cd8b500e189366f1402ac30100 (diff)
downloadedk2-platforms-16b7aff06b4379eaac48dc6e78c7a3944c0bdbad.tar.xz
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')
-rw-r--r--ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c58
1 files changed, 38 insertions, 20 deletions
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
);