TianoCore EDK2 master
Loading...
Searching...
No Matches
ArmArchTimerLib.c
Go to the documentation of this file.
1
10#include <Base.h>
11#include <Library/ArmLib.h>
12#include <Library/BaseLib.h>
13#include <Library/TimerLib.h>
14#include <Library/DebugLib.h>
15#include <Library/PcdLib.h>
17
18#define TICKS_PER_MICRO_SEC (ArmGenericTimerGetTimerFreq ()/1000000U)
19
29EFIAPI
31 )
32{
33 UINTN TimerFreq;
34
35 TimerFreq = ArmGenericTimerGetTimerFreq ();
36
37 ASSERT (TimerFreq != 0);
38
39 return TimerFreq;
40}
41
51EFIAPI
53 IN UINTN MicroSeconds
54 )
55{
56 UINT64 TimerTicks64;
57 UINT64 SystemCounterVal;
58 UINT64 PreviousSystemCounterVal;
59 UINT64 DeltaCounterVal;
60
61 // Calculate counter ticks that represent requested delay:
62 // = MicroSeconds x TICKS_PER_MICRO_SEC
63 // = MicroSeconds x Frequency.10^-6
64 TimerTicks64 = DivU64x32 (
66 MicroSeconds,
68 ),
69 1000000U
70 );
71
72 // Read System Counter value
73 PreviousSystemCounterVal = ArmGenericTimerGetSystemCount ();
74
75 // Wait until delay count expires.
76 while (TimerTicks64 > 0) {
77 SystemCounterVal = ArmGenericTimerGetSystemCount ();
78 // Get how much we advanced this tick. Wrap around still has delta correct
79 DeltaCounterVal = (SystemCounterVal - PreviousSystemCounterVal)
80 & (MAX_UINT64 >> 8); // Account for a lesser (minimum) size
81 // Never wrap back around below zero by choosing the min and thus stop at 0
82 TimerTicks64 -= MIN (TimerTicks64, DeltaCounterVal);
83 PreviousSystemCounterVal = SystemCounterVal;
84 }
85
86 return MicroSeconds;
87}
88
102UINTN
103EFIAPI
105 IN UINTN NanoSeconds
106 )
107{
108 UINTN MicroSeconds;
109
110 // Round up to 1us Tick Number
111 MicroSeconds = NanoSeconds / 1000;
112 MicroSeconds += ((NanoSeconds % 1000) == 0) ? 0 : 1;
113
114 MicroSecondDelay (MicroSeconds);
115
116 return NanoSeconds;
117}
118
130UINT64
131EFIAPI
133 VOID
134 )
135{
136 // Just return the value of system count
137 return ArmGenericTimerGetSystemCount ();
138}
139
163UINT64
164EFIAPI
166 OUT UINT64 *StartValue OPTIONAL,
167 OUT UINT64 *EndValue OPTIONAL
168 )
169{
170 if (StartValue != NULL) {
171 // Timer starts at 0
172 *StartValue = (UINT64)0ULL;
173 }
174
175 if (EndValue != NULL) {
176 // Timer counts up.
177 *EndValue = 0xFFFFFFFFFFFFFFFFUL;
178 }
179
180 return (UINT64)ArmGenericTimerGetTimerFreq ();
181}
182
194UINT64
195EFIAPI
197 IN UINT64 Ticks
198 )
199{
200 UINT64 NanoSeconds;
201 UINT64 Remainder;
202 UINT64 TimerFreq;
203
204 TimerFreq = GetPlatformTimerFreq ();
205 //
206 // Ticks
207 // Time = --------- x 1,000,000,000
208 // Frequency
209 //
210 NanoSeconds = MultU64x64 (
212 Ticks,
213 TimerFreq,
214 &Remainder
215 ),
216 1000000000U
217 );
218
219 //
220 // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
221 // will not overflow 64-bit.
222 //
223 NanoSeconds += DivU64x64Remainder (
224 MultU64x64 (
225 Remainder,
226 1000000000U
227 ),
228 TimerFreq,
229 NULL
230 );
231
232 return NanoSeconds;
233}
UINT64 UINTN
UINT64 EFIAPI GetPerformanceCounterProperties(OUT UINT64 *StartValue OPTIONAL, OUT UINT64 *EndValue OPTIONAL)
UINT64 EFIAPI GetTimeInNanoSecond(IN UINT64 Ticks)
STATIC UINTN EFIAPI GetPlatformTimerFreq()
UINT64 EFIAPI GetPerformanceCounter(VOID)
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
UINTN EFIAPI NanoSecondDelay(IN UINTN NanoSeconds)
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
UINT64 EFIAPI MultU64x64(IN UINT64 Multiplicand, IN UINT64 Multiplier)
Definition: MultU64x64.c:27
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define MIN(a, b)
Definition: Base.h:1007
#define VOID
Definition: Base.h:269
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284