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
20// Select appropriate multiply function for platform architecture.
21#ifdef MDE_CPU_ARM
22#define MULT_U64_X_N MultU64x32
23#else
24#define MULT_U64_X_N MultU64x64
25#endif
26
36EFIAPI
38 )
39{
40 UINTN TimerFreq;
41
42 TimerFreq = ArmGenericTimerGetTimerFreq ();
43
44 ASSERT (TimerFreq != 0);
45
46 return TimerFreq;
47}
48
58EFIAPI
60 IN UINTN MicroSeconds
61 )
62{
63 UINT64 TimerTicks64;
64 UINT64 SystemCounterVal;
65 UINT64 PreviousSystemCounterVal;
66 UINT64 DeltaCounterVal;
67
68 // Calculate counter ticks that represent requested delay:
69 // = MicroSeconds x TICKS_PER_MICRO_SEC
70 // = MicroSeconds x Frequency.10^-6
71 TimerTicks64 = DivU64x32 (
72 MULT_U64_X_N (
73 MicroSeconds,
75 ),
76 1000000U
77 );
78
79 // Read System Counter value
80 PreviousSystemCounterVal = ArmGenericTimerGetSystemCount ();
81
82 // Wait until delay count expires.
83 while (TimerTicks64 > 0) {
84 SystemCounterVal = ArmGenericTimerGetSystemCount ();
85 // Get how much we advanced this tick. Wrap around still has delta correct
86 DeltaCounterVal = (SystemCounterVal - PreviousSystemCounterVal)
87 & (MAX_UINT64 >> 8); // Account for a lesser (minimum) size
88 // Never wrap back around below zero by choosing the min and thus stop at 0
89 TimerTicks64 -= MIN (TimerTicks64, DeltaCounterVal);
90 PreviousSystemCounterVal = SystemCounterVal;
91 }
92
93 return MicroSeconds;
94}
95
109UINTN
110EFIAPI
112 IN UINTN NanoSeconds
113 )
114{
115 UINTN MicroSeconds;
116
117 // Round up to 1us Tick Number
118 MicroSeconds = NanoSeconds / 1000;
119 MicroSeconds += ((NanoSeconds % 1000) == 0) ? 0 : 1;
120
121 MicroSecondDelay (MicroSeconds);
122
123 return NanoSeconds;
124}
125
137UINT64
138EFIAPI
140 VOID
141 )
142{
143 // Just return the value of system count
144 return ArmGenericTimerGetSystemCount ();
145}
146
170UINT64
171EFIAPI
173 OUT UINT64 *StartValue OPTIONAL,
174 OUT UINT64 *EndValue OPTIONAL
175 )
176{
177 if (StartValue != NULL) {
178 // Timer starts at 0
179 *StartValue = (UINT64)0ULL;
180 }
181
182 if (EndValue != NULL) {
183 // Timer counts up.
184 *EndValue = 0xFFFFFFFFFFFFFFFFUL;
185 }
186
187 return (UINT64)ArmGenericTimerGetTimerFreq ();
188}
189
201UINT64
202EFIAPI
204 IN UINT64 Ticks
205 )
206{
207 UINT64 NanoSeconds;
208 UINT32 Remainder;
209 UINT32 TimerFreq;
210
211 TimerFreq = GetPlatformTimerFreq ();
212 //
213 // Ticks
214 // Time = --------- x 1,000,000,000
215 // Frequency
216 //
217 NanoSeconds = MULT_U64_X_N (
219 Ticks,
220 TimerFreq,
221 &Remainder
222 ),
223 1000000000U
224 );
225
226 //
227 // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
228 // will not overflow 64-bit.
229 //
230 NanoSeconds += DivU64x32 (
231 MULT_U64_X_N (
232 (UINT64)Remainder,
233 1000000000U
234 ),
235 TimerFreq
236 );
237
238 return NanoSeconds;
239}
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 DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define MIN(a, b)
Definition: Base.h:1007
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284