2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/platform/time.c
5 * PURPOSE: Boot Library Time Management Routines
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 /* DATA VARIABLES ************************************************************/
15 ULONGLONG BlpTimePerformanceFrequency
;
17 /* FUNCTIONS *****************************************************************/
20 BlpTimeMeasureTscFrequency (
24 #if defined(_M_IX86) || defined(_M_X64)
27 ULONGLONG TimeStamp1
, TimeStamp2
, Delta
;
29 /* Check if the ISVM bit it set, meaning we're in a hypervisor */
31 Count
= CpuInfo
[2] & 0x80000000 ? 10 : 1;
33 /* Loop trying to get an accurate TSC */
36 /* Stall for 1us and get count 1 */
38 TimeStamp1
= __rdtsc();
40 /* Stall for 1000us and get count 2*/
42 TimeStamp2
= __rdtsc();
44 /* Stall for 9000us and get the difference */
46 Delta
= __rdtsc() - TimeStamp2
;
48 /* Keep going as long as the TSC is fluctuating */
50 } while (((TimeStamp2
- TimeStamp1
) > Delta
) && (Count
));
52 /* Set the frequency based on the two measurements we took */
53 BlpTimePerformanceFrequency
= 125 * (Delta
- (TimeStamp2
- TimeStamp1
)) & 0x1FFFFFFFFFFFFFF;
54 return STATUS_SUCCESS
;
56 EfiPrintf(L
"BlpTimeMeasureTscFrequency not implemented for this platform.\r\n");
57 return STATUS_NOT_IMPLEMENTED
;
62 BlpTimeCalibratePerformanceCounter (
66 #if defined(_M_IX86) || defined(_M_X64)
69 /* Check if the ISVM bit it set, meaning we're in a hypervisor */
71 if (CpuInfo
[2] & 0x80000000)
73 /* Get the Hypervisor Identification Leaf */
74 __cpuid(CpuInfo
, 0x40000001);
76 /* Is this Hyper-V? */
77 if (CpuInfo
[0] == '1#vH')
79 /* Get the Hypervisor Feature Identification Leaf */
80 __cpuid(CpuInfo
, 0x40000003);
82 /* Check if HV_X64_MSR_REFERENCE_TSC is present */
83 if (CpuInfo
[3] & 0x100)
85 /* Read the TSC frequency from the MSR */
86 BlpTimePerformanceFrequency
= __readmsr(0x40000022);
87 return STATUS_SUCCESS
;
92 /* On other systems, compute it */
93 return BlpTimeMeasureTscFrequency();
95 EfiPrintf(L
"BlpTimeCalibratePerformanceCounter not implemented for this platform.\r\n");
96 return STATUS_NOT_IMPLEMENTED
;
101 BlTimeQueryPerformanceCounter (
102 _Out_opt_ PLARGE_INTEGER Frequency
105 #if defined(_M_IX86) || defined(_M_X64)
106 /* Check if caller wants frequency */
110 Frequency
->QuadPart
= BlpTimePerformanceFrequency
;
113 /* Return the TSC value */
116 EfiPrintf(L
"BlTimeQueryPerformanceCounter not implemented for this platform.\r\n");