OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcTimerLib.c
Go to the documentation of this file.
1
15#include <Uefi.h>
16
18#include <IndustryStandard/Pci.h>
20
21#include <Library/BaseLib.h>
22#include <Library/OcCpuLib.h>
23#include <Library/DebugLib.h>
24#include <Library/IoLib.h>
25#include <Library/PciLib.h>
26#include <Library/UefiBootServicesTableLib.h>
27#include <Library/TimerLib.h>
28
29STATIC UINT64 mTscFrequency = 0;
30
40STATIC
41VOID
43 IN UINT64 Delay
44 )
45{
46 UINT64 Ticks;
47
48 //
49 // The target timer count is calculated here
50 //
51 Ticks = AsmReadTsc () + Delay;
52
53 //
54 // Wait until time out
55 // Timer wrap-arounds are NOT handled correctly by this function.
56 // Thus, this function must be called within 10 years of reset since
57 // Intel guarantees a minimum of 10 years before the TSC wraps.
58 //
59 while (AsmReadTsc () <= Ticks) {
60 CpuPause ();
61 }
62}
63
74UINTN
75EFIAPI
77 IN UINTN MicroSeconds
78 )
79{
80 if (mTscFrequency > 0) {
82 DivU64x32 (
84 MicroSeconds,
86 ),
87 1000000u
88 )
89 );
90 }
91
92 return MicroSeconds;
93}
94
105UINTN
106EFIAPI
108 IN UINTN NanoSeconds
109 )
110{
111 if (mTscFrequency > 0) {
113 DivU64x32 (
114 MultU64x64 (
115 NanoSeconds,
117 ),
118 1000000000u
119 )
120 );
121 }
122
123 return NanoSeconds;
124}
125
137UINT64
138EFIAPI
140 VOID
141 )
142{
143 return AsmReadTsc ();
144}
145
169UINT64
170EFIAPI
172 OUT UINT64 *StartValue, OPTIONAL
173 OUT UINT64 *EndValue OPTIONAL
174 )
175{
176 if (StartValue != NULL) {
177 *StartValue = 0;
178 }
179
180 if (EndValue != NULL) {
181 *EndValue = 0xffffffffffffffffULL;
182 }
183
184 return mTscFrequency;
185}
186
198UINT64
199EFIAPI
201 IN UINT64 Ticks
202 )
203{
204 UINT64 Frequency;
205 UINT64 NanoSeconds;
206 UINT64 Remainder;
207 INTN Shift;
208
209 Frequency = GetPerformanceCounterProperties (NULL, NULL);
210
211 if (Frequency == 0) {
212 return 0;
213 }
214
215 //
216 // Ticks
217 // Time = --------- x 1,000,000,000
218 // Frequency
219 //
220 NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);
221
222 //
223 // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
224 // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,
225 // i.e. highest bit set in Remainder should <= 33.
226 //
227 Shift = MAX (0, HighBitSet64 (Remainder) - 33);
228 Remainder = RShiftU64 (Remainder, (UINTN)Shift);
229 Frequency = RShiftU64 (Frequency, (UINTN)Shift);
230 NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);
231
232 return NanoSeconds;
233}
234
241UINT64
242EFIAPI
244 VOID
245 )
246{
247 return mTscFrequency;
248}
249
256EFI_STATUS
257EFIAPI
259 VOID
260 )
261{
263
264 return EFI_SUCCESS;
265}
UINT64 OcGetTSCFrequency(VOID)
UINT64 EFIAPI GetTimeInNanoSecond(IN UINT64 Ticks)
Definition OcTimerLib.c:200
UINT64 EFIAPI GetPerformanceCounterProperties(OUT UINT64 *StartValue, OPTIONAL OUT UINT64 *EndValue OPTIONAL)
Definition OcTimerLib.c:171
EFI_STATUS EFIAPI OcTimerLibConstructor(VOID)
Definition OcTimerLib.c:258
STATIC VOID InternalCpuDelay(IN UINT64 Delay)
Definition OcTimerLib.c:42
UINT64 EFIAPI GetTscFrequency(VOID)
Definition OcTimerLib.c:243
UINT64 EFIAPI GetPerformanceCounter(VOID)
Definition OcTimerLib.c:139
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
Definition OcTimerLib.c:76
STATIC UINT64 mTscFrequency
Definition OcTimerLib.c:29
UINTN EFIAPI NanoSecondDelay(IN UINTN NanoSeconds)
Definition OcTimerLib.c:107
UINT64 EFIAPI MultU64x64(IN UINT64 Multiplicand, IN UINT64 Multiplier)
Definition UserMath.c:116
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition UserMath.c:86
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition UserMath.c:96
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
Definition UserMath.c:59
UINT64 EFIAPI AsmReadTsc(VOID)
Definition UserMisc.c:232
VOID EFIAPI CpuPause(VOID)
Definition UserMisc.c:22
#define MAX(a, b)
Definition coder.h:59
#define DivU64x32(x, y, z)