Import Usb/UsbBusDxe and Usb/UsbMassStorageDxe into MdeModulePkg.
[mirror_edk2.git] / EdkNt32Pkg / Library / EdkGenericBdsLib / Performance.c
CommitLineData
878ddf1f 1/*++\r
2\r
fa332de7 3Copyright (c) 2006 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
878ddf1f 11\r
12Module Name:\r
13\r
14 Performance.c\r
15\r
16Abstract:\r
17\r
18 This file include the file which can help to get the system\r
19 performance, all the function will only include if the performance\r
20 switch is set.\r
21\r
22--*/\r
23\r
24#include "Performance.h"\r
25\r
878ddf1f 26\r
27STATIC\r
28VOID\r
29GetShortPdbFileName (\r
30 CHAR8 *PdbFileName,\r
31 CHAR8 *GaugeString\r
32 )\r
33/*++\r
34\r
35Routine Description:\r
fa332de7 36\r
878ddf1f 37Arguments:\r
38\r
39Returns:\r
40\r
41--*/\r
42{\r
43 UINTN Index;\r
44 UINTN Index1;\r
45 UINTN StartIndex;\r
46 UINTN EndIndex;\r
47\r
48 if (PdbFileName == NULL) {\r
49 AsciiStrCpy (GaugeString, " ");\r
50 } else {\r
51 StartIndex = 0;\r
52 for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)\r
53 ;\r
54\r
55 for (Index = 0; PdbFileName[Index] != 0; Index++) {\r
56 if (PdbFileName[Index] == '\\') {\r
57 StartIndex = Index + 1;\r
58 }\r
59\r
60 if (PdbFileName[Index] == '.') {\r
61 EndIndex = Index;\r
62 }\r
63 }\r
64\r
65 Index1 = 0;\r
66 for (Index = StartIndex; Index < EndIndex; Index++) {\r
67 GaugeString[Index1] = PdbFileName[Index];\r
68 Index1++;\r
69 if (Index1 == PERF_TOKEN_LENGTH - 1) {\r
70 break;\r
71 }\r
72 }\r
73\r
74 GaugeString[Index1] = 0;\r
75 }\r
76\r
77 return ;\r
78}\r
79\r
2ce31132 80\r
81\r
878ddf1f 82STATIC\r
83CHAR8 *\r
84GetPdbPath (\r
85 VOID *ImageBase\r
86 )\r
87/*++\r
88\r
89Routine Description:\r
90\r
91 Located PDB path name in PE image\r
92\r
93Arguments:\r
94\r
95 ImageBase - base of PE to search\r
96\r
97Returns:\r
98\r
99 Pointer into image at offset of PDB file name if PDB file name is found,\r
100 Otherwise a pointer to an empty string.\r
101\r
102--*/\r
103{\r
2ce31132 104 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
105\r
106 ZeroMem (&ImageContext, sizeof (ImageContext));\r
107 ImageContext.Handle = ImageBase;\r
108 ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
878ddf1f 109\r
2ce31132 110 PeCoffLoaderGetImageInfo (&ImageContext);\r
111\r
112 return ImageContext.PdbPointer;\r
878ddf1f 113}\r
114\r
2ce31132 115\r
878ddf1f 116STATIC\r
117VOID\r
118GetNameFromHandle (\r
119 IN EFI_HANDLE Handle,\r
120 OUT CHAR8 *GaugeString\r
121 )\r
122{\r
123 EFI_STATUS Status;\r
124 EFI_LOADED_IMAGE_PROTOCOL *Image;\r
125 CHAR8 *PdbFileName;\r
126 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
127\r
128 AsciiStrCpy (GaugeString, " ");\r
129\r
130 //\r
131 // Get handle name from image protocol\r
132 //\r
133 Status = gBS->HandleProtocol (\r
134 Handle,\r
135 &gEfiLoadedImageProtocolGuid,\r
136 &Image\r
137 );\r
138\r
139 if (EFI_ERROR (Status)) {\r
140 Status = gBS->OpenProtocol (\r
141 Handle,\r
142 &gEfiDriverBindingProtocolGuid,\r
143 (VOID **) &DriverBinding,\r
144 NULL,\r
145 NULL,\r
146 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
147 );\r
148 if (EFI_ERROR (Status)) {\r
149 return ;\r
150 }\r
151 //\r
152 // Get handle name from image protocol\r
153 //\r
154 Status = gBS->HandleProtocol (\r
155 DriverBinding->ImageHandle,\r
156 &gEfiLoadedImageProtocolGuid,\r
157 &Image\r
158 );\r
159 }\r
160\r
161 PdbFileName = GetPdbPath (Image->ImageBase);\r
162\r
163 if (PdbFileName != NULL) {\r
164 GetShortPdbFileName (PdbFileName, GaugeString);\r
165 }\r
166\r
167 return ;\r
168}\r
169\r
170\r
171\r
172VOID\r
173WriteBootToOsPerformanceData (\r
174 VOID\r
175 )\r
176/*++\r
177\r
178Routine Description:\r
fa332de7 179\r
878ddf1f 180 Allocates a block of memory and writes performance data of booting to OS into it.\r
181\r
182Arguments:\r
fa332de7 183\r
878ddf1f 184 None\r
fa332de7 185\r
878ddf1f 186Returns:\r
187\r
188 None\r
189\r
190--*/\r
191{\r
192 EFI_STATUS Status;\r
193 EFI_CPU_ARCH_PROTOCOL *Cpu;\r
194 EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase;\r
195 UINT32 mAcpiLowMemoryLength;\r
196 UINT32 LimitCount;\r
197 PERF_HEADER mPerfHeader;\r
198 PERF_DATA mPerfData;\r
199 EFI_HANDLE *Handles;\r
200 UINTN NoHandles;\r
201 CHAR8 GaugeString[PERF_TOKEN_LENGTH];\r
202 UINT8 *Ptr;\r
203 UINT32 mIndex;\r
204 UINT64 Ticker;\r
205 UINT64 Freq;\r
206 UINT32 Duration;\r
207 UINT64 CurrentTicker;\r
208 UINT64 TimerPeriod;\r
209 UINTN LogEntryKey;\r
210 CONST VOID *Handle;\r
211 CONST CHAR8 *Token;\r
212 CONST CHAR8 *Module;\r
213 UINT64 StartTicker;\r
214 UINT64 EndTicker;\r
215\r
216 //\r
217 // Retrive time stamp count as early as possilbe\r
218 //\r
219 Ticker = AsmReadTsc ();\r
220\r
221 //\r
222 // Allocate a block of memory that contain performance data to OS\r
223 //\r
cb44bbdb 224 mAcpiLowMemoryBase = 0xFFFFFFFF;\r
878ddf1f 225 Status = gBS->AllocatePages (\r
cb44bbdb 226 AllocateMaxAddress,\r
227 EfiReservedMemoryType,\r
878ddf1f 228 4,\r
229 &mAcpiLowMemoryBase\r
230 );\r
231 if (EFI_ERROR (Status)) {\r
232 return ;\r
233 }\r
234\r
cb44bbdb 235 mAcpiLowMemoryLength = EFI_PAGES_TO_SIZE(4);\r
878ddf1f 236\r
237 Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));\r
238 LimitCount = (mAcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);\r
239\r
240 //\r
241 // Initialize performance data structure\r
242 //\r
243 ZeroMem (&mPerfHeader, sizeof (PERF_HEADER));\r
244\r
245 //\r
246 // Get CPU frequency\r
247 //\r
248 Status = gBS->LocateProtocol (\r
249 &gEfiCpuArchProtocolGuid,\r
250 NULL,\r
251 &Cpu\r
252 );\r
253 if (EFI_ERROR (Status)) {\r
cb44bbdb 254 gBS->FreePages (mAcpiLowMemoryBase, 4);\r
878ddf1f 255 return ;\r
256 }\r
257 //\r
258 // Get Cpu Frequency\r
259 //\r
260 Status = Cpu->GetTimerValue (Cpu, 0, &(CurrentTicker), &TimerPeriod);\r
261 if (EFI_ERROR (Status)) {\r
cb44bbdb 262 gBS->FreePages (mAcpiLowMemoryBase, 4);\r
878ddf1f 263 return ;\r
264 }\r
265\r
266 Freq = DivU64x32 (1000000000000, (UINTN) TimerPeriod);\r
267\r
268 mPerfHeader.CpuFreq = Freq;\r
269\r
270 //\r
271 // Record BDS raw performance data\r
272 //\r
273 mPerfHeader.BDSRaw = Ticker;\r
274\r
275 //\r
276 // Put Detailed performance data into memory\r
277 //\r
278 Handles = NULL;\r
279 Status = gBS->LocateHandleBuffer (\r
280 AllHandles,\r
281 NULL,\r
282 NULL,\r
283 &NoHandles,\r
284 &Handles\r
285 );\r
286 if (EFI_ERROR (Status)) {\r
cb44bbdb 287 gBS->FreePages (mAcpiLowMemoryBase, 4);\r
878ddf1f 288 return ;\r
289 }\r
290 //\r
291 // Get DXE drivers performance\r
292 //\r
293 for (mIndex = 0; mIndex < NoHandles; mIndex++) {\r
294 Ticker = 0;\r
295 LogEntryKey = 0;\r
296 while ((LogEntryKey = GetPerformanceMeasurement (\r
297 LogEntryKey,\r
298 &Handle,\r
299 &Token,\r
300 &Module,\r
301 &StartTicker,\r
302 &EndTicker)) != 0) {\r
303 if ((Handle == Handles[mIndex]) && (StartTicker < EndTicker)) {\r
304 Ticker += (EndTicker - StartTicker);\r
305 }\r
306 }\r
307\r
308 Duration = (UINT32) DivU64x32 (\r
309 Ticker,\r
310 (UINT32) Freq\r
311 );\r
312\r
313 if (Duration > 0) {\r
314 ZeroMem (&mPerfData, sizeof (PERF_DATA));\r
315\r
316 GetNameFromHandle (Handles[mIndex], GaugeString);\r
317\r
318 AsciiStrCpy (mPerfData.Token, GaugeString);\r
319 mPerfData.Duration = Duration;\r
320\r
321 CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
322 Ptr += sizeof (PERF_DATA);\r
323\r
324 mPerfHeader.Count++;\r
325 if (mPerfHeader.Count == LimitCount) {\r
326 goto Done;\r
327 }\r
328 }\r
329 }\r
330\r
fa332de7 331 FreePool (Handles);\r
878ddf1f 332\r
333 //\r
334 // Get inserted performance data\r
335 //\r
336 LogEntryKey = 0;\r
337 while ((LogEntryKey = GetPerformanceMeasurement (\r
338 LogEntryKey,\r
339 &Handle,\r
340 &Token,\r
341 &Module,\r
342 &StartTicker,\r
343 &EndTicker)) != 0) {\r
344 if ((Handle == NULL) && (StartTicker <= EndTicker)) {\r
345\r
346 ZeroMem (&mPerfData, sizeof (PERF_DATA));\r
347\r
348 AsciiStrnCpy (mPerfData.Token, Token, DXE_PERFORMANCE_STRING_SIZE);\r
349 mPerfData.Duration = (UINT32) DivU64x32 (\r
350 EndTicker - StartTicker,\r
351 (UINT32) Freq\r
352 );\r
353\r
354 CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
355 Ptr += sizeof (PERF_DATA);\r
356\r
357 mPerfHeader.Count++;\r
358 if (mPerfHeader.Count == LimitCount) {\r
359 goto Done;\r
360 }\r
361 }\r
362 }\r
363\r
364Done:\r
365\r
878ddf1f 366 mPerfHeader.Signiture = 0x66726550;\r
367\r
368 //\r
369 // Put performance data to memory\r
370 //\r
371 CopyMem (\r
372 (UINT32 *) (UINT32) mAcpiLowMemoryBase,\r
373 &mPerfHeader,\r
374 sizeof (PERF_HEADER)\r
375 );\r
376\r
377 gRT->SetVariable (\r
378 L"PerfDataMemAddr",\r
20515cd1 379 &gEfiGenericPlatformVariableGuid,\r
878ddf1f 380 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
381 sizeof (UINT32),\r
382 (VOID *) &mAcpiLowMemoryBase\r
383 );\r
384\r
385 return ;\r
386}\r