]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/GenericBdsLib/Performance.c
Clean up GenericBdsLib library Instance.
[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
19STATIC PERF_HEADER mPerfHeader;\r
20STATIC PERF_DATA mPerfData;\r
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
224 //\r
225 // Get DXE drivers performance\r
226 //\r
227 for (Index = 0; Index < NoHandles; Index++) {\r
228 Ticker = 0;\r
229 LogEntryKey = 0;\r
230 while ((LogEntryKey = GetPerformanceMeasurement (\r
231 LogEntryKey,\r
232 &Handle,\r
233 &Token,\r
234 &Module,\r
235 &StartTicker,\r
236 &EndTicker)) != 0) {\r
237 if ((Handle == Handles[Index]) && (EndTicker != 0)) {\r
238 Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
239 }\r
240 }\r
241\r
242 Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\r
243\r
244 if (Duration > 0) {\r
245\r
246 GetNameFromHandle (Handles[Index], GaugeString);\r
247\r
248 AsciiStrCpy (mPerfData.Token, GaugeString);\r
249 mPerfData.Duration = Duration;\r
250\r
251 CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
252 Ptr += sizeof (PERF_DATA);\r
253\r
254 mPerfHeader.Count++;\r
255 if (mPerfHeader.Count == LimitCount) {\r
256 goto Done;\r
257 }\r
258 }\r
259 }\r
260\r
261 FreePool (Handles);\r
262\r
263 //\r
264 // Get inserted performance data\r
265 //\r
266 LogEntryKey = 0;\r
267 while ((LogEntryKey = GetPerformanceMeasurement (\r
268 LogEntryKey,\r
269 &Handle,\r
270 &Token,\r
271 &Module,\r
272 &StartTicker,\r
273 &EndTicker)) != 0) {\r
274 if (Handle == NULL && EndTicker != 0) {\r
275\r
276 ZeroMem (&mPerfData, sizeof (PERF_DATA));\r
277\r
278 AsciiStrnCpy (mPerfData.Token, Token, PERF_TOKEN_LENGTH);\r
279 Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
280\r
281 mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\r
282\r
283 CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
284 Ptr += sizeof (PERF_DATA);\r
285\r
286 mPerfHeader.Count++;\r
287 if (mPerfHeader.Count == LimitCount) {\r
288 goto Done;\r
289 }\r
290 }\r
291 }\r
292\r
293Done:\r
294\r
295 mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;\r
296\r
297 //\r
298 // Put performance data to memory\r
299 //\r
300 CopyMem (\r
301 (UINTN *) (UINTN) AcpiLowMemoryBase,\r
302 &mPerfHeader,\r
303 sizeof (PERF_HEADER)\r
304 );\r
305\r
306 gRT->SetVariable (\r
307 L"PerfDataMemAddr",\r
308 &gEfiGenericPlatformVariableGuid,\r
309 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
310 sizeof (EFI_PHYSICAL_ADDRESS),\r
311 &AcpiLowMemoryBase\r
312 );\r
313\r
314 return ;\r
315}\r