]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.c
Vlv2TbltDevicePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / IntelPchAcpiTimerLib / IntelPchAcpiTimerLib.c
1 /** @file
2 ICH9 ACPI Timer implements one instance of Timer Library.
3
4 Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8
9
10 **/
11
12 #include "CommonHeader.h"
13
14 /**
15 The constructor function enables ACPI IO space.
16
17 If ACPI I/O space not enabled, this function will enable it.
18 It will always return RETURN_SUCCESS.
19
20 @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.
21
22 **/
23 RETURN_STATUS
24 EFIAPI
25 IntelPchAcpiTimerLibConstructor (
26 VOID
27 )
28 {
29 if ((PchLpcPciCfg8(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_EN) == 0) {
30 //
31 // If ACPI I/O space is not enabled, program ACPI I/O base address and enable it.
32 //
33 MmioWrite16 (
34 MmPciAddress (
35 0,
36 DEFAULT_PCI_BUS_NUMBER_PCH,
37 PCI_DEVICE_NUMBER_PCH_LPC,
38 PCI_FUNCTION_NUMBER_PCH_LPC,
39 R_PCH_LPC_ACPI_BASE
40 ),
41 ((PcdGet16 (PcdPchAcpiIoPortBaseAddress) & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN)
42 );
43 }
44 return RETURN_SUCCESS;
45 }
46
47 /**
48 Internal function to read the current tick counter of ACPI.
49
50 Internal function to read the current tick counter of ACPI.
51
52 @return The tick counter read.
53
54 **/
55 STATIC
56 UINT32
57 InternalAcpiGetTimerTick (
58 VOID
59 )
60 {
61 return IoRead32 (PcdGet16 (PcdPchAcpiIoPortBaseAddress) + R_PCH_ACPI_PM1_TMR);
62 }
63
64 /**
65 Stalls the CPU for at least the given number of ticks.
66
67 Stalls the CPU for at least the given number of ticks. It's invoked by
68 MicroSecondDelay() and NanoSecondDelay().
69
70 @param Delay A period of time to delay in ticks.
71
72 **/
73 STATIC
74 VOID
75 InternalAcpiDelay (
76 IN UINT32 Delay
77 )
78 {
79 UINT32 Ticks;
80 UINT32 Times;
81
82 Times = Delay >> 22;
83 Delay &= BIT22 - 1;
84 do {
85 //
86 // The target timer count is calculated here
87 //
88 Ticks = InternalAcpiGetTimerTick () + Delay;
89 Delay = BIT22;
90 //
91 // Wait until time out
92 // Delay >= 2^23 could not be handled by this function
93 // Timer wrap-arounds are handled correctly by this function
94 //
95 while (((Ticks - InternalAcpiGetTimerTick ()) & BIT23) == 0) {
96 CpuPause ();
97 }
98 } while (Times-- > 0);
99 }
100
101 /**
102 Stalls the CPU for at least the given number of microseconds.
103
104 Stalls the CPU for the number of microseconds specified by MicroSeconds.
105
106 @param MicroSeconds The minimum number of microseconds to delay.
107
108 @return MicroSeconds
109
110 **/
111 UINTN
112 EFIAPI
113 MicroSecondDelay (
114 IN UINTN MicroSeconds
115 )
116 {
117 InternalAcpiDelay (
118 (UINT32)DivU64x32 (
119 MultU64x32 (
120 MicroSeconds,
121 V_PCH_ACPI_PM1_TMR_FREQUENCY
122 ),
123 1000000u
124 )
125 );
126 return MicroSeconds;
127 }
128
129 /**
130 Stalls the CPU for at least the given number of nanoseconds.
131
132 Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
133
134 @param NanoSeconds The minimum number of nanoseconds to delay.
135
136 @return NanoSeconds
137
138 **/
139 UINTN
140 EFIAPI
141 NanoSecondDelay (
142 IN UINTN NanoSeconds
143 )
144 {
145 InternalAcpiDelay (
146 (UINT32)DivU64x32 (
147 MultU64x32 (
148 NanoSeconds,
149 V_PCH_ACPI_PM1_TMR_FREQUENCY
150 ),
151 1000000000u
152 )
153 );
154 return NanoSeconds;
155 }
156
157 /**
158 Retrieves the current value of a 64-bit free running performance counter.
159
160 Retrieves the current value of a 64-bit free running performance counter. The
161 counter can either count up by 1 or count down by 1. If the physical
162 performance counter counts by a larger increment, then the counter values
163 must be translated. The properties of the counter can be retrieved from
164 GetPerformanceCounterProperties().
165
166 @return The current value of the free running performance counter.
167
168 **/
169 UINT64
170 EFIAPI
171 GetPerformanceCounter (
172 VOID
173 )
174 {
175 return (UINT64)InternalAcpiGetTimerTick ();
176 }
177
178 /**
179 Retrieves the 64-bit frequency in Hz and the range of performance counter
180 values.
181
182 If StartValue is not NULL, then the value that the performance counter starts
183 with immediately after is it rolls over is returned in StartValue. If
184 EndValue is not NULL, then the value that the performance counter end with
185 immediately before it rolls over is returned in EndValue. The 64-bit
186 frequency of the performance counter in Hz is always returned. If StartValue
187 is less than EndValue, then the performance counter counts up. If StartValue
188 is greater than EndValue, then the performance counter counts down. For
189 example, a 64-bit free running counter that counts up would have a StartValue
190 of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
191 that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
192
193 @param StartValue The value the performance counter starts with when it
194 rolls over.
195 @param EndValue The value that the performance counter ends with before
196 it rolls over.
197
198 @return The frequency in Hz.
199
200 **/
201 UINT64
202 EFIAPI
203 GetPerformanceCounterProperties (
204 OUT UINT64 *StartValue, OPTIONAL
205 OUT UINT64 *EndValue OPTIONAL
206 )
207 {
208 if (StartValue != NULL) {
209 *StartValue = 0;
210 }
211
212 if (EndValue != NULL) {
213 *EndValue = V_PCH_ACPI_PM1_TMR_MAX_VAL - 1;
214 }
215
216 return V_PCH_ACPI_PM1_TMR_FREQUENCY;
217 }
218
219 /**
220 Converts elapsed ticks of performance counter to time in nanoseconds.
221
222 This function converts the elapsed ticks of running performance counter to
223 time value in unit of nanoseconds.
224
225 @param Ticks The number of elapsed ticks of running performance counter.
226
227 @return The elapsed time in nanoseconds.
228
229 **/
230 UINT64
231 EFIAPI
232 GetTimeInNanoSecond (
233 IN UINT64 Ticks
234 )
235 {
236 UINT64 NanoSeconds;
237 UINT32 Remainder;
238
239 //
240 // Ticks
241 // Time = --------- x 1,000,000,000
242 // Frequency
243 //
244 NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, V_PCH_ACPI_PM1_TMR_FREQUENCY, &Remainder), 1000000000u);
245
246 //
247 // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
248 // will not overflow 64-bit.
249 //
250 NanoSeconds += DivU64x32 (MultU64x32 ((UINT64) Remainder, 1000000000u), V_PCH_ACPI_PM1_TMR_FREQUENCY);
251
252 return NanoSeconds;
253 }
254
255