update GetPerformanceCounterProperties() declare
[mirror_edk2.git] / MdePkg / Library / BaseTimerLibLocalApic / Ipf / IpfTimerLib.c
CommitLineData
878ddf1f 1/** @file\r
2 Timer Library functions built upon local APIC on IA32/x64.\r
3\r
4 @bug Should use PCD to retrieve all the constants including index of\r
5 the IA32_APIC_BASE MSR, the offsets of InitialCount, CorrentCount\r
6 and DivideConfiguration.\r
7\r
8 Copyright (c) 2006, Intel Corporation<BR>\r
9 All rights reserved. This program and the accompanying materials\r
10 are licensed and made available under the terms and conditions of the BSD License\r
11 which accompanies this distribution. The full text of the license may be found at\r
12 http://opensource.org/licenses/bsd-license.php\r
13\r
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17 Module Name: IpfTimerLib.c\r
18\r
19**/\r
20\r
878ddf1f 21typedef struct {\r
22 UINT64 Status;\r
23 UINT64 r9;\r
24 UINT64 r10;\r
25 UINT64 r11;\r
26} PAL_PROC_RETURN;\r
27\r
ed384ef3 28/**\r
29 Performs a PAL call using static calling convention.\r
30\r
31 An internal function to perform a PAL call using static calling convention.\r
32\r
33 @param PalEntryPoint The entry point address of PAL. The address in ar.kr5\r
34 would be used if this parameter were NULL on input.\r
35 @param Arg1 The first argument of a PAL call.\r
36 @param Arg1 The second argument of a PAL call.\r
37 @param Arg1 The third argument of a PAL call.\r
38 @param Arg1 The fourth argument of a PAL call.\r
39\r
40 @return The values returned in r8, r9, r10 and r11.\r
41\r
42**/\r
878ddf1f 43PAL_PROC_RETURN\r
e65e8d10 44PalCallStatic (\r
45 IN CONST VOID *PalEntryPoint,\r
878ddf1f 46 IN UINT64 Arg1,\r
47 IN UINT64 Arg2,\r
48 IN UINT64 Arg3,\r
49 IN UINT64 Arg4\r
50 );\r
51\r
ed384ef3 52/**\r
53 Returns the current value of ar.itc.\r
54\r
55 An internal function to return the current value of ar.itc, which is the\r
56 timer tick on IPF.\r
57\r
58 @return The currect value of ar.itc\r
59\r
60**/\r
61INT64\r
62InternalIpfReadItc (\r
63 VOID\r
64 );\r
65\r
66/**\r
67 Performs a delay measured as number of ticks.\r
68\r
69 An internal function to perform a delay measured as number of ticks. It's\r
70 invoked by MicroSecondDelay() and NanoSecondDelay().\r
71\r
72 @param Delay Number of ticks to delay.\r
73\r
74**/\r
75STATIC\r
76VOID\r
77InternalIpfDelay (\r
78 IN INT64 Delay\r
79 )\r
80{\r
81 INT64 Ticks;\r
82\r
83 //\r
84 // The target timer count is calculated here\r
85 //\r
86 Ticks = InternalIpfReadItc () + Delay;\r
87\r
88 //\r
89 // Wait until time out\r
90 // Delay > 2^63 could not be handled by this function\r
91 // Timer wrap-arounds are handled correctly by this function\r
92 //\r
93 while (Ticks - InternalIpfReadItc () >= 0);\r
94}\r
95\r
878ddf1f 96/**\r
97 Stalls the CPU for at least the given number of microseconds.\r
98\r
99 Stalls the CPU for the number of microseconds specified by MicroSeconds.\r
100\r
101 @param MicroSeconds The minimum number of microseconds to delay.\r
102\r
ed384ef3 103 @return MicroSeconds\r
878ddf1f 104\r
105**/\r
106UINTN\r
107EFIAPI\r
108MicroSecondDelay (\r
109 IN UINTN MicroSeconds\r
110 )\r
111{\r
ed384ef3 112 InternalIpfDelay (\r
113 GetPerformanceCounterProperties (NULL, NULL) *\r
114 MicroSeconds /\r
115 1000000\r
116 );\r
117 return MicroSeconds;\r
878ddf1f 118}\r
119\r
120/**\r
121 Stalls the CPU for at least the given number of nanoseconds.\r
122\r
123 Stalls the CPU for the number of nanoseconds specified by NanoSeconds.\r
124\r
125 @param NanoSeconds The minimum number of nanoseconds to delay.\r
126\r
ed384ef3 127 @return NanoSeconds\r
878ddf1f 128\r
129**/\r
130UINTN\r
131EFIAPI\r
132NanoSecondDelay (\r
133 IN UINTN NanoSeconds\r
134 )\r
135{\r
ed384ef3 136 InternalIpfDelay (\r
137 GetPerformanceCounterProperties (NULL, NULL) *\r
138 NanoSeconds /\r
139 1000000000\r
140 );\r
141 return NanoSeconds;\r
878ddf1f 142}\r
143\r
144/**\r
145 Retrieves the current value of a 64-bit free running performance counter.\r
146\r
147 Retrieves the current value of a 64-bit free running performance counter. The\r
148 counter can either count up by 1 or count down by 1. If the physical\r
149 performance counter counts by a larger increment, then the counter values\r
150 must be translated. The properties of the counter can be retrieved from\r
151 GetPerformanceCounterProperties().\r
152\r
153 @return The current value of the free running performance counter.\r
154\r
155**/\r
156UINT64\r
157EFIAPI\r
158GetPerformanceCounter (\r
159 VOID\r
160 )\r
161{\r
ed384ef3 162 return InternalIpfReadItc ();\r
878ddf1f 163}\r
164\r
165/**\r
166 Retrieves the 64-bit frequency in Hz and the range of performance counter\r
167 values.\r
168\r
169 If StartValue is not NULL, then the value that the performance counter starts\r
170 with immediately after is it rolls over is returned in StartValue. If\r
171 EndValue is not NULL, then the value that the performance counter end with\r
172 immediately before it rolls over is returned in EndValue. The 64-bit\r
173 frequency of the performance counter in Hz is always returned. If StartValue\r
174 is less than EndValue, then the performance counter counts up. If StartValue\r
175 is greater than EndValue, then the performance counter counts down. For\r
176 example, a 64-bit free running counter that counts up would have a StartValue\r
177 of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter\r
178 that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.\r
179\r
180 @param StartValue The value the performance counter starts with when it\r
181 rolls over.\r
182 @param EndValue The value that the performance counter ends with before\r
183 it rolls over.\r
184\r
185 @return The frequency in Hz.\r
186\r
187**/\r
188UINT64\r
189EFIAPI\r
190GetPerformanceCounterProperties (\r
5117b83b 191 OUT UINT64 *StartValue, OPTIONAL\r
192 OUT UINT64 *EndValue OPTIONAL\r
878ddf1f 193 )\r
194{\r
195 PAL_PROC_RETURN PalRet;\r
196 UINT64 BaseFrequence;\r
197\r
e65e8d10 198 PalRet = PalCallStatic (NULL, 13, 0, 0, 0);\r
878ddf1f 199 ASSERT (PalRet.Status == 0);\r
200 BaseFrequence = PalRet.r9;\r
201\r
e65e8d10 202 PalRet = PalCallStatic (NULL, 14, 0, 0, 0);\r
878ddf1f 203 ASSERT (PalRet.Status == 0);\r
204\r
ed384ef3 205 if (StartValue != NULL) {\r
206 *StartValue = 0;\r
207 }\r
208\r
209 if (EndValue != NULL) {\r
210 *EndValue = (UINT64)(-1);\r
211 }\r
212\r
878ddf1f 213 return BaseFrequence * (PalRet.r11 >> 32) / (UINT32)PalRet.r11;\r
214}\r