]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Library / AcpiTimerLib / AcpiTimerLib.c
1 /** @file
2 ACPI Timer implements one instance of Timer Library.
3
4 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <Library/DebugLib.h>
12 #include <Library/BaseLib.h>
13 #include <IndustryStandard/Acpi.h>
14
15 #include "AcpiTimerLib.h"
16
17 //
18 // The ACPI Time is a 24-bit counter
19 //
20 #define ACPI_TIMER_COUNT_SIZE BIT24
21
22 /**
23 Stalls the CPU for at least the given number of ticks.
24
25 Stalls the CPU for at least the given number of ticks. It's invoked by
26 MicroSecondDelay() and NanoSecondDelay().
27
28 @param Delay A period of time to delay in ticks.
29
30 **/
31 VOID
32 InternalAcpiDelay (
33 IN UINT32 Delay
34 )
35 {
36 UINT32 Ticks;
37 UINT32 Times;
38
39 Times = Delay >> 22;
40 Delay &= BIT22 - 1;
41 do {
42 //
43 // The target timer count is calculated here
44 //
45 Ticks = InternalAcpiGetTimerTick () + Delay;
46 Delay = BIT22;
47 //
48 // Wait until time out
49 // Delay >= 2^23 could not be handled by this function
50 // Timer wrap-arounds are handled correctly by this function
51 //
52 while (((Ticks - InternalAcpiGetTimerTick ()) & BIT23) == 0) {
53 CpuPause ();
54 }
55 } while (Times-- > 0);
56 }
57
58 /**
59 Stalls the CPU for at least the given number of microseconds.
60
61 Stalls the CPU for the number of microseconds specified by MicroSeconds.
62
63 @param MicroSeconds The minimum number of microseconds to delay.
64
65 @return MicroSeconds
66
67 **/
68 UINTN
69 EFIAPI
70 MicroSecondDelay (
71 IN UINTN MicroSeconds
72 )
73 {
74 InternalAcpiDelay (
75 (UINT32)DivU64x32 (
76 MultU64x32 (
77 MicroSeconds,
78 ACPI_TIMER_FREQUENCY
79 ),
80 1000000u
81 )
82 );
83 return MicroSeconds;
84 }
85
86 /**
87 Stalls the CPU for at least the given number of nanoseconds.
88
89 Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
90
91 @param NanoSeconds The minimum number of nanoseconds to delay.
92
93 @return NanoSeconds
94
95 **/
96 UINTN
97 EFIAPI
98 NanoSecondDelay (
99 IN UINTN NanoSeconds
100 )
101 {
102 InternalAcpiDelay (
103 (UINT32)DivU64x32 (
104 MultU64x32 (
105 NanoSeconds,
106 ACPI_TIMER_FREQUENCY
107 ),
108 1000000000u
109 )
110 );
111 return NanoSeconds;
112 }
113
114 /**
115 Retrieves the current value of a 64-bit free running performance counter.
116
117 Retrieves the current value of a 64-bit free running performance counter. The
118 counter can either count up by 1 or count down by 1. If the physical
119 performance counter counts by a larger increment, then the counter values
120 must be translated. The properties of the counter can be retrieved from
121 GetPerformanceCounterProperties().
122
123 @return The current value of the free running performance counter.
124
125 **/
126 UINT64
127 EFIAPI
128 GetPerformanceCounter (
129 VOID
130 )
131 {
132 return (UINT64)InternalAcpiGetTimerTick ();
133 }
134
135 /**
136 Retrieves the 64-bit frequency in Hz and the range of performance counter
137 values.
138
139 If StartValue is not NULL, then the value that the performance counter starts
140 with immediately after is it rolls over is returned in StartValue. If
141 EndValue is not NULL, then the value that the performance counter end with
142 immediately before it rolls over is returned in EndValue. The 64-bit
143 frequency of the performance counter in Hz is always returned. If StartValue
144 is less than EndValue, then the performance counter counts up. If StartValue
145 is greater than EndValue, then the performance counter counts down. For
146 example, a 64-bit free running counter that counts up would have a StartValue
147 of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
148 that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
149
150 @param StartValue The value the performance counter starts with when it
151 rolls over.
152 @param EndValue The value that the performance counter ends with before
153 it rolls over.
154
155 @return The frequency in Hz.
156
157 **/
158 UINT64
159 EFIAPI
160 GetPerformanceCounterProperties (
161 OUT UINT64 *StartValue OPTIONAL,
162 OUT UINT64 *EndValue OPTIONAL
163 )
164 {
165 if (StartValue != NULL) {
166 *StartValue = 0;
167 }
168
169 if (EndValue != NULL) {
170 *EndValue = ACPI_TIMER_COUNT_SIZE - 1;
171 }
172
173 return ACPI_TIMER_FREQUENCY;
174 }
175
176 /**
177 Converts elapsed ticks of performance counter to time in nanoseconds.
178
179 This function converts the elapsed ticks of running performance counter to
180 time value in unit of nanoseconds.
181
182 @param Ticks The number of elapsed ticks of running performance counter.
183
184 @return The elapsed time in nanoseconds.
185
186 **/
187 UINT64
188 EFIAPI
189 GetTimeInNanoSecond (
190 IN UINT64 Ticks
191 )
192 {
193 UINT64 NanoSeconds;
194 UINT32 Remainder;
195
196 //
197 // Ticks
198 // Time = --------- x 1,000,000,000
199 // Frequency
200 //
201 NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, ACPI_TIMER_FREQUENCY, &Remainder), 1000000000u);
202
203 //
204 // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
205 // will not overflow 64-bit.
206 //
207 NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), ACPI_TIMER_FREQUENCY);
208
209 return NanoSeconds;
210 }