OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
X86TimerLib.c
Go to the documentation of this file.
1
20#include <Base.h>
21#include <Library/TimerLib.h>
22#include <Library/BaseLib.h>
23#include <Library/DebugLib.h>
24#include <Library/HobLib.h>
26#include <Library/IoLib.h>
27#include <Library/PciLib.h>
28
30
38 VOID
39 )
40{
41 EFI_PEI_HOB_POINTERS GuidHob;
42
43 if (gAcpiDesc != NULL) {
44 return gAcpiDesc;
45 }
46
48 if (GuidHob.Raw != NULL) {
49 gAcpiDesc = GET_GUID_HOB_DATA (GuidHob.Guid);
50 DEBUG ((EFI_D_INFO, "ACPI Timer: PM_TMR_BLK.RegisterBitWidth = 0x%X\n", gAcpiDesc->PM_TMR_BLK.RegisterBitWidth));
51 DEBUG ((EFI_D_INFO, "ACPI Timer: PM_TMR_BLK.Address = 0x%X\n", gAcpiDesc->PM_TMR_BLK.Address));
52 return gAcpiDesc;
53 } else {
54 DEBUG ((EFI_D_ERROR, "Fail to get Acpi description table from hob\n"));
55 return NULL;
56 }
57}
58
65STATIC
66UINT32
68 VOID
69 )
70{
71 return IoRead32 ((UINTN)gAcpiDesc->PM_TMR_BLK.Address);
72}
73
83STATIC
84VOID
86 IN UINT32 Delay
87 )
88{
89 UINT32 Ticks;
90 UINT32 Times;
91
92 Times = Delay >> (gAcpiDesc->PM_TMR_BLK.RegisterBitWidth - 2);
93 Delay &= (1 << (gAcpiDesc->PM_TMR_BLK.RegisterBitWidth - 2)) - 1;
94 do {
95 //
96 // The target timer count is calculated here
97 //
98 Ticks = InternalAcpiGetTimerTick () + Delay;
99 Delay = 1 << (gAcpiDesc->PM_TMR_BLK.RegisterBitWidth - 2);
100 //
101 // Wait until time out
102 // Delay >= 2^23 (if ACPI provide 24-bit timer) or Delay >= 2^31 (if ACPI
103 // provide 32-bit timer) could not be handled by this function
104 // Timer wrap-arounds are handled correctly by this function
105 //
106 while (((Ticks - InternalAcpiGetTimerTick ()) & (1 << (gAcpiDesc->PM_TMR_BLK.RegisterBitWidth - 1))) == 0) {
107 CpuPause ();
108 }
109 } while (Times-- > 0);
110}
111
122UINTN
123EFIAPI
125 IN UINTN MicroSeconds
126 )
127{
128 if (InternalGetApciDescrptionTable () == NULL) {
129 return MicroSeconds;
130 }
131
133 (UINT32)DivU64x32 (
134 MultU64x32 (
135 MicroSeconds,
136 3579545
137 ),
138 1000000u
139 )
140 );
141 return MicroSeconds;
142}
143
154UINTN
155EFIAPI
157 IN UINTN NanoSeconds
158 )
159{
160 if (InternalGetApciDescrptionTable () == NULL) {
161 return NanoSeconds;
162 }
163
165 (UINT32)DivU64x32 (
166 MultU64x32 (
167 NanoSeconds,
168 3579545
169 ),
170 1000000000u
171 )
172 );
173 return NanoSeconds;
174}
175
188UINT64
189EFIAPI
191 VOID
192 )
193{
194 if (InternalGetApciDescrptionTable () == NULL) {
195 return 0;
196 }
197
198 return (UINT64)InternalAcpiGetTimerTick ();
199}
200
224UINT64
225EFIAPI
227 OUT UINT64 *StartValue, OPTIONAL
228 OUT UINT64 *EndValue OPTIONAL
229 )
230{
231 if (InternalGetApciDescrptionTable () == NULL) {
232 return 0;
233 }
234
235 if (StartValue != NULL) {
236 *StartValue = 0;
237 }
238
239 if (EndValue != NULL) {
240 *EndValue = (1 << gAcpiDesc->PM_TMR_BLK.RegisterBitWidth) - 1;
241 }
242
243 return 3579545;
244}
245
257UINT64
258EFIAPI
260 IN UINT64 Ticks
261 )
262{
263 UINT64 NanoSeconds;
264 UINT32 Remainder;
265
266 //
267 // Ticks
268 // Time = --------- x 1,000,000,000
269 // Frequency
270 //
271 NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, 3579545, &Remainder), 1000000000u);
272
273 //
274 // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
275 // will not overflow 64-bit.
276 //
277 NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), 3579545);
278
279 return NanoSeconds;
280}
EFI_GUID gEfiAcpiDescriptionGuid
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition UserMath.c:96
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
Definition UserMath.c:25
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition UserMisc.c:671
VOID EFIAPI CpuPause(VOID)
Definition UserMisc.c:22
UINT32 EFIAPI IoRead32(IN UINTN Port)
Definition UserMisc.c:318
UINT64 EFIAPI GetTimeInNanoSecond(IN UINT64 Ticks)
STATIC VOID InternalAcpiDelay(IN UINT32 Delay)
Definition X86TimerLib.c:85
EFI_ACPI_DESCRIPTION * InternalGetApciDescrptionTable(VOID)
Definition X86TimerLib.c:37
EFI_ACPI_DESCRIPTION * gAcpiDesc
Definition X86TimerLib.c:29
UINT64 EFIAPI GetPerformanceCounterProperties(OUT UINT64 *StartValue, OPTIONAL OUT UINT64 *EndValue OPTIONAL)
STATIC UINT32 InternalAcpiGetTimerTick(VOID)
Definition X86TimerLib.c:67
UINT64 EFIAPI GetPerformanceCounter(VOID)
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
UINTN EFIAPI NanoSecondDelay(IN UINTN NanoSeconds)
#define DivU64x32(x, y, z)
EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE PM_TMR_BLK