]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c
IntelFrameworkModulePkg/BdsDxe: Remove the useless Perf codes
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / GenericBdsLib / Performance.c
CommitLineData
5c08e117 1/** @file\r
2 This file include the file which can help to get the system\r
3 performance, all the function will only include if the performance\r
4 switch is set.\r
5\r
ed6d22e0 6Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
180a5a35 7This program and the accompanying materials\r
5c08e117 8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "InternalBdsLib.h"\r
18\r
19PERF_HEADER mPerfHeader;\r
20PERF_DATA mPerfData;\r
02c9c470 21EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase = 0x0FFFFFFFFULL;\r
5c08e117 22\r
23/**\r
24 Get the short verion of PDB file name to be\r
25 used in performance data logging.\r
26\r
27 @param PdbFileName The long PDB file name.\r
28 @param GaugeString The output string to be logged by performance logger.\r
29\r
30**/\r
31VOID\r
32GetShortPdbFileName (\r
33 IN CONST CHAR8 *PdbFileName,\r
34 OUT CHAR8 *GaugeString\r
35 )\r
36{\r
37 UINTN Index;\r
38 UINTN Index1;\r
39 UINTN StartIndex;\r
40 UINTN EndIndex;\r
41\r
42 if (PdbFileName == NULL) {\r
cce50970 43 AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " ");\r
5c08e117 44 } else {\r
45 StartIndex = 0;\r
46 for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)\r
47 ;\r
48\r
49 for (Index = 0; PdbFileName[Index] != 0; Index++) {\r
50 if (PdbFileName[Index] == '\\') {\r
51 StartIndex = Index + 1;\r
52 }\r
53\r
54 if (PdbFileName[Index] == '.') {\r
55 EndIndex = Index;\r
56 }\r
57 }\r
58\r
59 Index1 = 0;\r
60 for (Index = StartIndex; Index < EndIndex; Index++) {\r
61 GaugeString[Index1] = PdbFileName[Index];\r
62 Index1++;\r
cce50970 63 if (Index1 == PERF_TOKEN_LENGTH) {\r
5c08e117 64 break;\r
65 }\r
66 }\r
67\r
68 GaugeString[Index1] = 0;\r
69 }\r
70\r
71 return ;\r
72}\r
73\r
74/**\r
75 Get the name from the Driver handle, which can be a handle with\r
76 EFI_LOADED_IMAGE_PROTOCOL or EFI_DRIVER_BINDING_PROTOCOL installed.\r
77 This name can be used in performance data logging.\r
78\r
79 @param Handle Driver handle.\r
80 @param GaugeString The output string to be logged by performance logger.\r
81\r
82**/\r
83VOID\r
84GetNameFromHandle (\r
85 IN EFI_HANDLE Handle,\r
86 OUT CHAR8 *GaugeString\r
87 )\r
88{\r
89 EFI_STATUS Status;\r
90 EFI_LOADED_IMAGE_PROTOCOL *Image;\r
91 CHAR8 *PdbFileName;\r
92 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
93\r
cce50970 94 AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " ");\r
5c08e117 95\r
96 //\r
97 // Get handle name from image protocol\r
98 //\r
99 Status = gBS->HandleProtocol (\r
100 Handle,\r
101 &gEfiLoadedImageProtocolGuid,\r
102 (VOID **) &Image\r
103 );\r
104\r
105 if (EFI_ERROR (Status)) {\r
106 Status = gBS->OpenProtocol (\r
107 Handle,\r
108 &gEfiDriverBindingProtocolGuid,\r
109 (VOID **) &DriverBinding,\r
110 NULL,\r
111 NULL,\r
112 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
113 );\r
114 if (EFI_ERROR (Status)) {\r
115 return ;\r
116 }\r
117 //\r
118 // Get handle name from image protocol\r
119 //\r
120 Status = gBS->HandleProtocol (\r
121 DriverBinding->ImageHandle,\r
122 &gEfiLoadedImageProtocolGuid,\r
123 (VOID **) &Image\r
124 );\r
125 }\r
126\r
127 PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);\r
128\r
129 if (PdbFileName != NULL) {\r
130 GetShortPdbFileName (PdbFileName, GaugeString);\r
131 }\r
132\r
133 return ;\r
134}\r
135\r
26c0ba77
SZ
136/**\r
137\r
138 Writes performance data of booting into the allocated memory.\r
139 OS can process these records.\r
140\r
141 @param Event The triggered event.\r
142 @param Context Context for this event.\r
143\r
144**/\r
145VOID\r
146EFIAPI\r
147WriteBootToOsPerformanceData (\r
148 IN EFI_EVENT Event,\r
149 IN VOID *Context\r
150 )\r
5c08e117 151{\r
152 EFI_STATUS Status;\r
5c08e117 153 UINT32 LimitCount;\r
154 EFI_HANDLE *Handles;\r
155 UINTN NoHandles;\r
cce50970 156 CHAR8 GaugeString[PERF_TOKEN_SIZE];\r
5c08e117 157 UINT8 *Ptr;\r
158 UINT32 Index;\r
159 UINT64 Ticker;\r
160 UINT64 Freq;\r
161 UINT32 Duration;\r
162 UINTN LogEntryKey;\r
163 CONST VOID *Handle;\r
164 CONST CHAR8 *Token;\r
165 CONST CHAR8 *Module;\r
166 UINT64 StartTicker;\r
167 UINT64 EndTicker;\r
168 UINT64 StartValue;\r
169 UINT64 EndValue;\r
170 BOOLEAN CountUp;\r
f6c07313 171 UINTN VarSize;\r
201d2d21 172 BOOLEAN Found;\r
5c08e117 173\r
26c0ba77
SZ
174 //\r
175 // Record the performance data for End of BDS\r
176 //\r
177 PERF_END(NULL, "BDS", NULL, 0);\r
178\r
5c08e117 179 //\r
6055758f 180 // Retrieve time stamp count as early as possible\r
5c08e117 181 //\r
182 Ticker = GetPerformanceCounter ();\r
183\r
184 Freq = GetPerformanceCounterProperties (&StartValue, &EndValue);\r
185 \r
186 Freq = DivU64x32 (Freq, 1000);\r
187\r
188 mPerfHeader.CpuFreq = Freq;\r
189\r
190 //\r
191 // Record BDS raw performance data\r
192 //\r
193 if (EndValue >= StartValue) {\r
194 mPerfHeader.BDSRaw = Ticker - StartValue;\r
195 CountUp = TRUE;\r
196 } else {\r
197 mPerfHeader.BDSRaw = StartValue - Ticker;\r
198 CountUp = FALSE;\r
199 }\r
200\r
201d2d21
SZ
201 //\r
202 // Reset the entry count\r
203 //\r
204 mPerfHeader.Count = 0;\r
205\r
f6c07313
SZ
206 if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {\r
207 VarSize = sizeof (EFI_PHYSICAL_ADDRESS);\r
208 Status = gRT->GetVariable (\r
209 L"PerfDataMemAddr",\r
210 &gPerformanceProtocolGuid,\r
211 NULL,\r
212 &VarSize,\r
213 &mAcpiLowMemoryBase\r
214 );\r
215 if (EFI_ERROR (Status)) {\r
216 //\r
217 // Fail to get the variable, return.\r
218 //\r
219 return;\r
220 }\r
221 }\r
222\r
5c08e117 223 //\r
224 // Put Detailed performance data into memory\r
225 //\r
226 Handles = NULL;\r
227 Status = gBS->LocateHandleBuffer (\r
228 AllHandles,\r
229 NULL,\r
230 NULL,\r
231 &NoHandles,\r
232 &Handles\r
233 );\r
234 if (EFI_ERROR (Status)) {\r
5c08e117 235 return ;\r
236 }\r
02c9c470 237\r
02c9c470 238 Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));\r
f6c07313 239 LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);\r
02c9c470 240\r
5c08e117 241 //\r
201d2d21 242 // Get performance data\r
5c08e117 243 //\r
244 LogEntryKey = 0;\r
245 while ((LogEntryKey = GetPerformanceMeasurement (\r
246 LogEntryKey,\r
247 &Handle,\r
248 &Token,\r
249 &Module,\r
250 &StartTicker,\r
251 &EndTicker)) != 0) {\r
201d2d21 252 if (EndTicker != 0) {\r
07341a33 253 if (StartTicker == 1) {\r
254 StartTicker = StartValue;\r
255 }\r
256 if (EndTicker == 1) {\r
257 EndTicker = StartValue;\r
258 }\r
5c08e117 259 Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
260\r
201d2d21
SZ
261 Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\r
262 if (Duration == 0) {\r
263 continue;\r
264 }\r
265\r
266 ZeroMem (&mPerfData, sizeof (PERF_DATA));\r
267\r
268 mPerfData.Duration = Duration;\r
269\r
270 //\r
271 // See if the Handle is in the handle buffer\r
272 //\r
273 Found = FALSE;\r
274 for (Index = 0; Index < NoHandles; Index++) {\r
275 if (Handle == Handles[Index]) {\r
276 GetNameFromHandle (Handles[Index], GaugeString);\r
277 AsciiStrCpyS (mPerfData.Token, PERF_TOKEN_SIZE, GaugeString);\r
278 Found = TRUE;\r
279 break;\r
280 }\r
281 }\r
282\r
283 if (!Found) {\r
284 AsciiStrnCpyS (mPerfData.Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH);\r
285 }\r
5c08e117 286\r
287 CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
288 Ptr += sizeof (PERF_DATA);\r
289\r
290 mPerfHeader.Count++;\r
291 if (mPerfHeader.Count == LimitCount) {\r
292 goto Done;\r
293 }\r
294 }\r
295 }\r
296\r
297Done:\r
298\r
b5a144ec 299 FreePool (Handles);\r
b5a144ec 300\r
5c08e117 301 mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;\r
302\r
303 //\r
02c9c470 304 // Put performance data to Reserved memory\r
5c08e117 305 //\r
306 CopyMem (\r
02c9c470 307 (UINTN *) (UINTN) mAcpiLowMemoryBase,\r
5c08e117 308 &mPerfHeader,\r
309 sizeof (PERF_HEADER)\r
310 );\r
311\r
5c08e117 312 return ;\r
313}\r