]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c
Update the copyright notice format
[mirror_edk2.git] / OvmfPkg / Library / AcpiTimerLib / AcpiTimerLib.c
CommitLineData
49ba9447 1/** @file\r
2 ACPI Timer implements one instance of Timer Library.\r
3\r
56d7640a
HT
4 Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials are\r
49ba9447 6 licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9 \r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/ \r
14\r
15#include <Base.h>\r
16#include <Library/TimerLib.h>\r
17#include <Library/BaseLib.h>\r
18#include <Library/IoLib.h>\r
19#include <Library/PciLib.h>\r
20\r
21#define ACPI_TIMER_FREQUENCY 3579545\r
22#define ACPI_TIMER_COUNT_SIZE 0x01000000\r
23\r
24/**\r
25 The constructor function enables ACPI IO space.\r
26\r
27 If ACPI I/O space not enabled, this function will enable it.\r
28 It will always return RETURN_SUCCESS.\r
29\r
30 @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.\r
31\r
32**/\r
33RETURN_STATUS\r
34EFIAPI\r
35AcpiTimerLibConstructor (\r
36 VOID\r
37 )\r
38{\r
39 UINT8 Device;\r
40\r
41 Device = 1;\r
42 // Device = 7;\r
43\r
44 //\r
45 // ACPI Timer enable is in Bus 0, Device ?, Function 3\r
46 //\r
47 PciOr8 (PCI_LIB_ADDRESS (0,Device,3,0x04), 0x01);\r
48 PciAndThenOr32 (PCI_LIB_ADDRESS (0,Device,3,0x40), (UINT32) ~0xfc0, 0x400);\r
49 PciOr8 (PCI_LIB_ADDRESS (0,Device,3,0x80), 0x01); return RETURN_SUCCESS;\r
50}\r
51\r
52/**\r
53 Internal function to read the current tick counter of ACPI.\r
54\r
55 Internal function to read the current tick counter of ACPI.\r
56\r
57 @return The tick counter read.\r
58\r
59**/\r
60STATIC\r
61UINT32\r
62InternalAcpiGetTimerTick (\r
63 VOID\r
64 )\r
65{\r
66 return IoRead32 (0x408);\r
67}\r
68\r
69/**\r
70 Stalls the CPU for at least the given number of ticks.\r
71\r
72 Stalls the CPU for at least the given number of ticks. It's invoked by\r
73 MicroSecondDelay() and NanoSecondDelay().\r
74\r
75 @param Delay A period of time to delay in ticks.\r
76\r
77**/\r
78STATIC\r
79VOID\r
80InternalAcpiDelay (\r
81 IN UINT32 Delay\r
82 )\r
83{\r
84 UINT32 Ticks;\r
85 UINT32 Times;\r
86\r
87 Times = Delay >> 22;\r
88 Delay &= BIT22 - 1;\r
89 do {\r
90 //\r
91 // The target timer count is calculated here\r
92 //\r
93 Ticks = InternalAcpiGetTimerTick () + Delay;\r
94 Delay = BIT22;\r
95 //\r
96 // Wait until time out\r
97 // Delay >= 2^23 could not be handled by this function\r
98 // Timer wrap-arounds are handled correctly by this function\r
99 //\r
100 while (((Ticks - InternalAcpiGetTimerTick ()) & BIT23) == 0) {\r
101 CpuPause ();\r
102 }\r
103 } while (Times-- > 0);\r
104}\r
105\r
106/**\r
107 Stalls the CPU for at least the given number of microseconds.\r
108\r
109 Stalls the CPU for the number of microseconds specified by MicroSeconds.\r
110\r
111 @param MicroSeconds The minimum number of microseconds to delay.\r
112\r
113 @return MicroSeconds\r
114\r
115**/\r
116UINTN\r
117EFIAPI\r
118MicroSecondDelay (\r
119 IN UINTN MicroSeconds\r
120 )\r
121{\r
122 InternalAcpiDelay (\r
123 (UINT32)DivU64x32 (\r
124 MultU64x32 (\r
125 MicroSeconds,\r
126 ACPI_TIMER_FREQUENCY\r
127 ),\r
128 1000000u\r
129 )\r
130 );\r
131 return MicroSeconds;\r
132}\r
133\r
134/**\r
135 Stalls the CPU for at least the given number of nanoseconds.\r
136\r
137 Stalls the CPU for the number of nanoseconds specified by NanoSeconds.\r
138\r
139 @param NanoSeconds The minimum number of nanoseconds to delay.\r
140\r
141 @return NanoSeconds\r
142\r
143**/\r
144UINTN\r
145EFIAPI\r
146NanoSecondDelay (\r
147 IN UINTN NanoSeconds\r
148 )\r
149{\r
150 InternalAcpiDelay (\r
151 (UINT32)DivU64x32 (\r
152 MultU64x32 (\r
153 NanoSeconds,\r
154 ACPI_TIMER_FREQUENCY\r
155 ),\r
156 1000000000u\r
157 )\r
158 );\r
159 return NanoSeconds;\r
160}\r
161\r
162/**\r
163 Retrieves the current value of a 64-bit free running performance counter.\r
164\r
165 Retrieves the current value of a 64-bit free running performance counter. The\r
166 counter can either count up by 1 or count down by 1. If the physical\r
167 performance counter counts by a larger increment, then the counter values\r
168 must be translated. The properties of the counter can be retrieved from\r
169 GetPerformanceCounterProperties().\r
170\r
171 @return The current value of the free running performance counter.\r
172\r
173**/\r
174UINT64\r
175EFIAPI\r
176GetPerformanceCounter (\r
177 VOID\r
178 )\r
179{\r
180 return (UINT64)InternalAcpiGetTimerTick ();\r
181}\r
182\r
183/**\r
184 Retrieves the 64-bit frequency in Hz and the range of performance counter\r
185 values.\r
186\r
187 If StartValue is not NULL, then the value that the performance counter starts\r
188 with immediately after is it rolls over is returned in StartValue. If\r
189 EndValue is not NULL, then the value that the performance counter end with\r
190 immediately before it rolls over is returned in EndValue. The 64-bit\r
191 frequency of the performance counter in Hz is always returned. If StartValue\r
192 is less than EndValue, then the performance counter counts up. If StartValue\r
193 is greater than EndValue, then the performance counter counts down. For\r
194 example, a 64-bit free running counter that counts up would have a StartValue\r
195 of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter\r
196 that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.\r
197\r
198 @param StartValue The value the performance counter starts with when it\r
199 rolls over.\r
200 @param EndValue The value that the performance counter ends with before\r
201 it rolls over.\r
202\r
203 @return The frequency in Hz.\r
204\r
205**/\r
206UINT64\r
207EFIAPI\r
208GetPerformanceCounterProperties (\r
209 OUT UINT64 *StartValue, OPTIONAL\r
210 OUT UINT64 *EndValue OPTIONAL\r
211 )\r
212{\r
213 if (StartValue != NULL) {\r
214 *StartValue = 0;\r
215 }\r
216\r
217 if (EndValue != NULL) {\r
218 *EndValue = ACPI_TIMER_COUNT_SIZE - 1;\r
219 }\r
220\r
221 return ACPI_TIMER_FREQUENCY;\r
222}\r