]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/GenericBdsLib/Performance.c
Patch to remove STATIC modifier. This is on longer recommended by EFI Framework codin...
[mirror_edk2.git] / MdeModulePkg / Library / GenericBdsLib / Performance.c
CommitLineData
897f0eee 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
6Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
7All rights reserved. This program and the accompanying materials\r
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
fe1e36e5 19PERF_HEADER mPerfHeader;\r
20PERF_DATA mPerfData;\r
897f0eee 21\r
11ef23f9 22/**\r
23 Get the short verion of PDB file name to be\r
24 used in performance data logging.\r
25\r
26 @param PdbFileName The long PDB file name.\r
27 @param GaugeString The output string to be logged by performance logger.\r
28\r
29**/\r
897f0eee 30VOID\r
31GetShortPdbFileName (\r
11ef23f9 32 IN CONST CHAR8 *PdbFileName,\r
33 OUT CHAR8 *GaugeString\r
897f0eee 34 )\r
897f0eee 35{\r
36 UINTN Index;\r
37 UINTN Index1;\r
38 UINTN StartIndex;\r
39 UINTN EndIndex;\r
40\r
41 if (PdbFileName == NULL) {\r
42 AsciiStrCpy (GaugeString, " ");\r
43 } else {\r
44 StartIndex = 0;\r
45 for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)\r
46 ;\r
47\r
48 for (Index = 0; PdbFileName[Index] != 0; Index++) {\r
49 if (PdbFileName[Index] == '\\') {\r
50 StartIndex = Index + 1;\r
51 }\r
52\r
53 if (PdbFileName[Index] == '.') {\r
54 EndIndex = Index;\r
55 }\r
56 }\r
57\r
58 Index1 = 0;\r
59 for (Index = StartIndex; Index < EndIndex; Index++) {\r
60 GaugeString[Index1] = PdbFileName[Index];\r
61 Index1++;\r
62 if (Index1 == PERF_TOKEN_LENGTH - 1) {\r
63 break;\r
64 }\r
65 }\r
66\r
67 GaugeString[Index1] = 0;\r
68 }\r
69\r
70 return ;\r
71}\r
72\r
11ef23f9 73/**\r
74 Get the name from the Driver handle, which can be a handle with\r
75 EFI_LOADED_IMAGE_PROTOCOL or EFI_DRIVER_BINDING_PROTOCOL installed.\r
76 This name can be used in performance data logging.\r
77\r
78 @param Handle Driver handle.\r
79 @param GaugeString The output string to be logged by performance logger.\r
80\r
81**/\r
897f0eee 82VOID\r
83GetNameFromHandle (\r
84 IN EFI_HANDLE Handle,\r
85 OUT CHAR8 *GaugeString\r
86 )\r
87{\r
88 EFI_STATUS Status;\r
89 EFI_LOADED_IMAGE_PROTOCOL *Image;\r
90 CHAR8 *PdbFileName;\r
91 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
92\r
93 AsciiStrCpy (GaugeString, " ");\r
94\r
95 //\r
96 // Get handle name from image protocol\r
97 //\r
98 Status = gBS->HandleProtocol (\r
99 Handle,\r
100 &gEfiLoadedImageProtocolGuid,\r
101 (VOID **) &Image\r
102 );\r
103\r
104 if (EFI_ERROR (Status)) {\r
105 Status = gBS->OpenProtocol (\r
106 Handle,\r
107 &gEfiDriverBindingProtocolGuid,\r
108 (VOID **) &DriverBinding,\r
109 NULL,\r
110 NULL,\r
111 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
112 );\r
113 if (EFI_ERROR (Status)) {\r
114 return ;\r
115 }\r
116 //\r
117 // Get handle name from image protocol\r
118 //\r
119 Status = gBS->HandleProtocol (\r
120 DriverBinding->ImageHandle,\r
121 &gEfiLoadedImageProtocolGuid,\r
122 (VOID **) &Image\r
123 );\r
124 }\r
125\r
126 PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);\r
127\r
128 if (PdbFileName != NULL) {\r
129 GetShortPdbFileName (PdbFileName, GaugeString);\r
130 }\r
131\r
132 return ;\r
133}\r
134\r
11ef23f9 135/**\r
136\r
137 Allocates a block of memory and writes performance data of booting into it.\r
138 OS can processing these record.\r
139 \r
140**/\r
897f0eee 141VOID\r
142WriteBootToOsPerformanceData (\r
143 VOID\r
144 )\r
897f0eee 145{\r
146 EFI_STATUS Status;\r
147 EFI_PHYSICAL_ADDRESS AcpiLowMemoryBase;\r
148 UINT32 AcpiLowMemoryLength;\r
149 UINT32 LimitCount;\r
150 EFI_HANDLE *Handles;\r
151 UINTN NoHandles;\r
152 CHAR8 GaugeString[PERF_TOKEN_LENGTH];\r
153 UINT8 *Ptr;\r
154 UINT32 Index;\r
155 UINT64 Ticker;\r
156 UINT64 Freq;\r
157 UINT32 Duration;\r
158 UINTN LogEntryKey;\r
159 CONST VOID *Handle;\r
160 CONST CHAR8 *Token;\r
161 CONST CHAR8 *Module;\r
162 UINT64 StartTicker;\r
163 UINT64 EndTicker;\r
164 UINT64 StartValue;\r
165 UINT64 EndValue;\r
166 BOOLEAN CountUp;\r
167\r
168 //\r
169 // Retrive time stamp count as early as possilbe\r
170 //\r
171 Ticker = GetPerformanceCounter ();\r
172\r
173 Freq = GetPerformanceCounterProperties (&StartValue, &EndValue);\r
174 \r
175 Freq = DivU64x32 (Freq, 1000);\r
176\r
177 mPerfHeader.CpuFreq = Freq;\r
178\r
179 //\r
180 // Record BDS raw performance data\r
181 //\r
182 if (EndValue >= StartValue) {\r
183 mPerfHeader.BDSRaw = Ticker - StartValue;\r
184 CountUp = TRUE;\r
185 } else {\r
186 mPerfHeader.BDSRaw = StartValue - Ticker;\r
187 CountUp = FALSE;\r
188 }\r
189\r
190 AcpiLowMemoryLength = 0x2000;\r
191\r
192 //\r
193 // Allocate a block of memory that contain performance data to OS\r
194 //\r
195 Status = gBS->AllocatePages (\r
196 AllocateAnyPages,\r
197 EfiACPIReclaimMemory,\r
198 EFI_SIZE_TO_PAGES (AcpiLowMemoryLength),\r
199 &AcpiLowMemoryBase\r
200 );\r
201 if (EFI_ERROR (Status)) {\r
202 return ;\r
203 }\r
204\r
205\r
206 Ptr = (UINT8 *) ((UINT32) AcpiLowMemoryBase + sizeof (PERF_HEADER));\r
207 LimitCount = (AcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);\r
208\r
209 //\r
210 // Put Detailed performance data into memory\r
211 //\r
212 Handles = NULL;\r
213 Status = gBS->LocateHandleBuffer (\r
214 AllHandles,\r
215 NULL,\r
216 NULL,\r
217 &NoHandles,\r
218 &Handles\r
219 );\r
220 if (EFI_ERROR (Status)) {\r
221 gBS->FreePages (AcpiLowMemoryBase, 1);\r
222 return ;\r
223 }\r
ec8cd35c 224 \r
897f0eee 225 //\r
226 // Get DXE drivers performance\r
227 //\r
228 for (Index = 0; Index < NoHandles; Index++) {\r
229 Ticker = 0;\r
230 LogEntryKey = 0;\r
231 while ((LogEntryKey = GetPerformanceMeasurement (\r
232 LogEntryKey,\r
233 &Handle,\r
234 &Token,\r
235 &Module,\r
236 &StartTicker,\r
237 &EndTicker)) != 0) {\r
238 if ((Handle == Handles[Index]) && (EndTicker != 0)) {\r
239 Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
240 }\r
241 }\r
242\r
243 Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\r
244\r
245 if (Duration > 0) {\r
246\r
247 GetNameFromHandle (Handles[Index], GaugeString);\r
248\r
249 AsciiStrCpy (mPerfData.Token, GaugeString);\r
250 mPerfData.Duration = Duration;\r
251\r
252 CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
253 Ptr += sizeof (PERF_DATA);\r
254\r
255 mPerfHeader.Count++;\r
256 if (mPerfHeader.Count == LimitCount) {\r
257 goto Done;\r
258 }\r
259 }\r
260 }\r
261\r
262 FreePool (Handles);\r
263\r
264 //\r
265 // Get inserted performance data\r
266 //\r
267 LogEntryKey = 0;\r
268 while ((LogEntryKey = GetPerformanceMeasurement (\r
269 LogEntryKey,\r
270 &Handle,\r
271 &Token,\r
272 &Module,\r
273 &StartTicker,\r
274 &EndTicker)) != 0) {\r
275 if (Handle == NULL && EndTicker != 0) {\r
276\r
277 ZeroMem (&mPerfData, sizeof (PERF_DATA));\r
278\r
279 AsciiStrnCpy (mPerfData.Token, Token, PERF_TOKEN_LENGTH);\r
280 Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
281\r
282 mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\r
283\r
284 CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
285 Ptr += sizeof (PERF_DATA);\r
286\r
287 mPerfHeader.Count++;\r
288 if (mPerfHeader.Count == LimitCount) {\r
289 goto Done;\r
290 }\r
291 }\r
292 }\r
293\r
294Done:\r
295\r
296 mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;\r
297\r
298 //\r
ec8cd35c 299 // Put performance data to ACPI memory\r
897f0eee 300 //\r
301 CopyMem (\r
302 (UINTN *) (UINTN) AcpiLowMemoryBase,\r
303 &mPerfHeader,\r
304 sizeof (PERF_HEADER)\r
305 );\r
306\r
307 gRT->SetVariable (\r
308 L"PerfDataMemAddr",\r
309 &gEfiGenericPlatformVariableGuid,\r
310 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
311 sizeof (EFI_PHYSICAL_ADDRESS),\r
312 &AcpiLowMemoryBase\r
313 );\r
314\r
315 return ;\r
316}\r