]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c
MdeModulePkg DxeCore/PiSmmCore/MemoryProfileInfo: Fix EBC and VS2013 build failure.
[mirror_edk2.git] / MdeModulePkg / Application / MemoryProfileInfo / MemoryProfileInfo.c
CommitLineData
84edd20b
SZ
1/** @file\r
2 \r
3 Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
4 This program and the accompanying materials \r
5 are licensed and made available under the terms and conditions of the BSD License \r
6 which accompanies this distribution. The full text of the license may be found at \r
7 http://opensource.org/licenses/bsd-license.php \r
8\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12**/\r
13\r
14#include <Uefi.h>\r
15#include <PiDxe.h>\r
16#include <Library/BaseLib.h>\r
17#include <Library/BaseMemoryLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/UefiLib.h>\r
20#include <Library/UefiApplicationEntryPoint.h>\r
21#include <Library/UefiBootServicesTableLib.h>\r
22#include <Library/UefiRuntimeServicesTableLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/DxeServicesLib.h>\r
25#include <Library/PeCoffGetEntryPointLib.h>\r
26#include <Library/PrintLib.h>\r
27\r
28#include <Protocol/SmmCommunication.h>\r
29#include <Protocol/SmmAccess2.h>\r
30\r
31#include <Guid/ZeroGuid.h>\r
32#include <Guid/MemoryProfile.h>\r
33\r
34CHAR16 *mActionString[] = {\r
35 L"Unknown",\r
36 L"AllocatePages",\r
37 L"FreePages",\r
38 L"AllocatePool",\r
39 L"FreePool",\r
40};\r
41\r
42CHAR16 *mMemoryTypeString[] = {\r
43 L"EfiReservedMemoryType",\r
44 L"EfiLoaderCode",\r
45 L"EfiLoaderData",\r
46 L"EfiBootServicesCode",\r
47 L"EfiBootServicesData",\r
48 L"EfiRuntimeServicesCode",\r
49 L"EfiRuntimeServicesData",\r
50 L"EfiConventionalMemory",\r
51 L"EfiUnusableMemory",\r
52 L"EfiACPIReclaimMemory",\r
53 L"EfiACPIMemoryNVS",\r
54 L"EfiMemoryMappedIO",\r
55 L"EfiMemoryMappedIOPortSpace",\r
56 L"EfiPalCode",\r
57 L"EfiOSReserved",\r
58};\r
59\r
60CHAR16 *mSubsystemString[] = {\r
61 L"Unknown",\r
62 L"NATIVE",\r
63 L"WINDOWS_GUI",\r
64 L"WINDOWS_CUI",\r
65 L"Unknown",\r
66 L"Unknown",\r
67 L"Unknown",\r
68 L"POSIX_CUI",\r
69 L"Unknown",\r
70 L"WINDOWS_CE_GUI",\r
71 L"EFI_APPLICATION",\r
72 L"EFI_BOOT_SERVICE_DRIVER",\r
73 L"EFI_RUNTIME_DRIVER",\r
74 L"EFI_ROM",\r
75 L"XBOX",\r
76 L"Unknown",\r
77};\r
78\r
79CHAR16 *mFileTypeString[] = {\r
80 L"Unknown",\r
81 L"RAW",\r
82 L"FREEFORM",\r
83 L"SECURITY_CORE",\r
84 L"PEI_CORE",\r
85 L"DXE_CORE",\r
86 L"PEIM",\r
87 L"DRIVER",\r
88 L"COMBINED_PEIM_DRIVER",\r
89 L"APPLICATION",\r
90 L"SMM",\r
91 L"FIRMWARE_VOLUME_IMAGE",\r
92 L"COMBINED_SMM_DXE",\r
93 L"SMM_CORE",\r
94};\r
95\r
96#define PROFILE_NAME_STRING_LENGTH 36\r
97CHAR16 mNameString[PROFILE_NAME_STRING_LENGTH + 1];\r
98\r
99/** \r
100 Get the file name portion of the Pdb File Name.\r
101 \r
102 The portion of the Pdb File Name between the last backslash and\r
103 either a following period or the end of the string is converted\r
104 to Unicode and copied into UnicodeBuffer. The name is truncated,\r
105 if necessary, to ensure that UnicodeBuffer is not overrun.\r
106 \r
107 @param[in] PdbFileName Pdb file name.\r
108 @param[out] UnicodeBuffer The resultant Unicode File Name.\r
109 \r
110**/\r
111VOID\r
112GetShortPdbFileName (\r
113 IN CHAR8 *PdbFileName,\r
114 OUT CHAR16 *UnicodeBuffer\r
115 )\r
116{\r
117 UINTN IndexA; // Current work location within an ASCII string.\r
118 UINTN IndexU; // Current work location within a Unicode string.\r
119 UINTN StartIndex;\r
120 UINTN EndIndex;\r
121\r
122 ZeroMem (UnicodeBuffer, PROFILE_NAME_STRING_LENGTH * sizeof (CHAR16));\r
123\r
124 if (PdbFileName == NULL) {\r
125 StrnCpy (UnicodeBuffer, L" ", 1);\r
126 } else {\r
127 StartIndex = 0;\r
128 for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++);\r
129 for (IndexA = 0; PdbFileName[IndexA] != 0; IndexA++) {\r
130 if (PdbFileName[IndexA] == '\\') {\r
131 StartIndex = IndexA + 1;\r
132 }\r
133\r
134 if (PdbFileName[IndexA] == '.') {\r
135 EndIndex = IndexA;\r
136 }\r
137 }\r
138\r
139 IndexU = 0;\r
140 for (IndexA = StartIndex; IndexA < EndIndex; IndexA++) {\r
141 UnicodeBuffer[IndexU] = (CHAR16) PdbFileName[IndexA];\r
142 IndexU++;\r
143 if (IndexU >= PROFILE_NAME_STRING_LENGTH) {\r
144 UnicodeBuffer[PROFILE_NAME_STRING_LENGTH] = 0;\r
145 break;\r
146 }\r
147 }\r
148 }\r
149}\r
150\r
151/** \r
152 Get a human readable name for an image.\r
153 The following methods will be tried orderly:\r
154 1. Image PDB\r
155 2. FFS UI section\r
156 3. Image GUID\r
157\r
158 @param[in] DriverInfo Pointer to memory profile driver info.\r
159\r
160 @post The resulting Unicode name string is stored in the mNameString global array.\r
161\r
162**/\r
163VOID\r
164GetDriverNameString (\r
165 IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo\r
166 )\r
167{\r
168 EFI_STATUS Status;\r
169 CHAR8 *PdbFileName;\r
170 CHAR16 *NameString;\r
171 UINTN StringSize;\r
172\r
173 //\r
174 // Method 1: Get the name string from image PDB\r
175 //\r
176 if ((DriverInfo->ImageBase != 0) && (DriverInfo->FileType != EFI_FV_FILETYPE_SMM) && (DriverInfo->FileType != EFI_FV_FILETYPE_SMM_CORE)) {\r
177 PdbFileName = PeCoffLoaderGetPdbPointer ((VOID *) (UINTN) DriverInfo->ImageBase);\r
178\r
179 if (PdbFileName != NULL) {\r
180 GetShortPdbFileName (PdbFileName, mNameString);\r
181 return;\r
182 }\r
183 }\r
184\r
185 if (!CompareGuid (&DriverInfo->FileName, &gZeroGuid)) {\r
186 //\r
187 // Try to get the image's FFS UI section by image GUID\r
188 //\r
189 NameString = NULL;\r
190 StringSize = 0;\r
191 Status = GetSectionFromAnyFv (\r
192 &DriverInfo->FileName,\r
193 EFI_SECTION_USER_INTERFACE,\r
194 0,\r
195 (VOID **) &NameString,\r
196 &StringSize\r
197 );\r
198 if (!EFI_ERROR (Status)) {\r
199 //\r
200 // Method 2: Get the name string from FFS UI section\r
201 //\r
202 StrnCpy (mNameString, NameString, PROFILE_NAME_STRING_LENGTH);\r
203 mNameString[PROFILE_NAME_STRING_LENGTH] = 0;\r
204 FreePool (NameString);\r
205 return;\r
206 }\r
207 }\r
208\r
209 //\r
210 // Method 3: Get the name string from image GUID\r
211 //\r
212 UnicodeSPrint (mNameString, sizeof (mNameString), L"%g", &DriverInfo->FileName);\r
213}\r
214\r
215/**\r
216 Dump memory profile allocate information.\r
217\r
218 @param[in] DriverInfo Pointer to memory profile driver info.\r
219 @param[in] AllocIndex Memory profile alloc info index.\r
220 @param[in] AllocInfo Pointer to memory profile alloc info.\r
221\r
222 @return Pointer to next memory profile alloc info.\r
223\r
224**/\r
225MEMORY_PROFILE_ALLOC_INFO *\r
226DumpMemoryProfileAllocInfo (\r
227 IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo,\r
228 IN UINTN AllocIndex,\r
229 IN MEMORY_PROFILE_ALLOC_INFO *AllocInfo\r
230 )\r
231{\r
232 if (AllocInfo->Header.Signature != MEMORY_PROFILE_ALLOC_INFO_SIGNATURE) {\r
233 return NULL;\r
234 }\r
235 Print (L" MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex);\r
236 Print (L" Signature - 0x%08x\n", AllocInfo->Header.Signature);\r
237 Print (L" Length - 0x%04x\n", AllocInfo->Header.Length);\r
238 Print (L" Revision - 0x%04x\n", AllocInfo->Header.Revision); \r
239 Print (L" CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo->CallerAddress, (UINTN) (AllocInfo->CallerAddress - DriverInfo->ImageBase));\r
240 Print (L" SequenceId - 0x%08x\n", AllocInfo->SequenceId);\r
241 Print (L" Action - 0x%08x (%s)\n", AllocInfo->Action, mActionString[(AllocInfo->Action < sizeof(mActionString)/sizeof(mActionString[0])) ? AllocInfo->Action : 0]);\r
242 Print (L" MemoryType - 0x%08x (%s)\n", AllocInfo->MemoryType, mMemoryTypeString[(AllocInfo->MemoryType < sizeof(mMemoryTypeString)/sizeof(mMemoryTypeString[0])) ? AllocInfo->MemoryType : (sizeof(mMemoryTypeString)/sizeof(mMemoryTypeString[0]) - 1)]);\r
243 Print (L" Buffer - 0x%016lx\n", AllocInfo->Buffer);\r
244 Print (L" Size - 0x%016lx\n", AllocInfo->Size);\r
245\r
246 return (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) AllocInfo + AllocInfo->Header.Length);\r
247}\r
248\r
249/**\r
250 Dump memory profile driver information.\r
251\r
252 @param[in] DriverIndex Memory profile driver info index.\r
253 @param[in] DriverInfo Pointer to memory profile driver info.\r
254\r
255 @return Pointer to next memory profile driver info.\r
256\r
257**/\r
258MEMORY_PROFILE_DRIVER_INFO *\r
259DumpMemoryProfileDriverInfo (\r
260 IN UINTN DriverIndex,\r
261 IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo\r
262 )\r
263{\r
264 UINTN TypeIndex;\r
265 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
266 UINTN AllocIndex;\r
267\r
268 if (DriverInfo->Header.Signature != MEMORY_PROFILE_DRIVER_INFO_SIGNATURE) {\r
269 return NULL;\r
270 }\r
271 Print (L" MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex);\r
272 Print (L" Signature - 0x%08x\n", DriverInfo->Header.Signature);\r
273 Print (L" Length - 0x%04x\n", DriverInfo->Header.Length);\r
274 Print (L" Revision - 0x%04x\n", DriverInfo->Header.Revision); \r
275 GetDriverNameString (DriverInfo);\r
276 Print (L" FileName - %s\n", &mNameString);\r
277 Print (L" ImageBase - 0x%016lx\n", DriverInfo->ImageBase);\r
278 Print (L" ImageSize - 0x%016lx\n", DriverInfo->ImageSize);\r
279 Print (L" EntryPoint - 0x%016lx\n", DriverInfo->EntryPoint);\r
280 Print (L" ImageSubsystem - 0x%04x (%s)\n", DriverInfo->ImageSubsystem, mSubsystemString[(DriverInfo->ImageSubsystem < sizeof(mSubsystemString)/sizeof(mSubsystemString[0])) ? DriverInfo->ImageSubsystem : 0]);\r
281 Print (L" FileType - 0x%02x (%s)\n", DriverInfo->FileType, mFileTypeString[(DriverInfo->FileType < sizeof(mFileTypeString)/sizeof(mFileTypeString[0])) ? DriverInfo->FileType : 0]);\r
282 Print (L" CurrentUsage - 0x%016lx\n", DriverInfo->CurrentUsage);\r
283 Print (L" PeakUsage - 0x%016lx\n", DriverInfo->PeakUsage);\r
284 for (TypeIndex = 0; TypeIndex <= EfiMaxMemoryType; TypeIndex++) {\r
285 if ((DriverInfo->CurrentUsageByType[TypeIndex] != 0) ||\r
286 (DriverInfo->PeakUsageByType[TypeIndex] != 0)) {\r
287 Print (L" CurrentUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex, DriverInfo->CurrentUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);\r
288 Print (L" PeakUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex, DriverInfo->PeakUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);\r
289 }\r
290 }\r
291 Print (L" AllocRecordCount - 0x%08x\n", DriverInfo->AllocRecordCount);\r
292\r
293 AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) DriverInfo + DriverInfo->Header.Length);\r
294 for (AllocIndex = 0; AllocIndex < DriverInfo->AllocRecordCount; AllocIndex++) {\r
295 AllocInfo = DumpMemoryProfileAllocInfo (DriverInfo, AllocIndex, AllocInfo);\r
296 if (AllocInfo == NULL) {\r
297 return NULL;\r
298 }\r
299 }\r
300 return (MEMORY_PROFILE_DRIVER_INFO *) AllocInfo;\r
301}\r
302\r
303/**\r
304 Dump memory profile context information.\r
305\r
306 @param[in] Context Pointer to memory profile context.\r
307\r
308 @return Pointer to the end of memory profile context buffer.\r
309\r
310**/\r
311VOID *\r
312DumpMemoryProfileContext (\r
313 IN MEMORY_PROFILE_CONTEXT *Context\r
314 )\r
315{\r
316 UINTN TypeIndex;\r
317 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
318 UINTN DriverIndex;\r
319\r
320 if (Context->Header.Signature != MEMORY_PROFILE_CONTEXT_SIGNATURE) {\r
321 return NULL;\r
322 }\r
323 Print (L"MEMORY_PROFILE_CONTEXT\n");\r
324 Print (L" Signature - 0x%08x\n", Context->Header.Signature);\r
325 Print (L" Length - 0x%04x\n", Context->Header.Length);\r
326 Print (L" Revision - 0x%04x\n", Context->Header.Revision); \r
327 Print (L" CurrentTotalUsage - 0x%016lx\n", Context->CurrentTotalUsage);\r
328 Print (L" PeakTotalUsage - 0x%016lx\n", Context->PeakTotalUsage);\r
329 for (TypeIndex = 0; TypeIndex <= EfiMaxMemoryType; TypeIndex++) {\r
330 if ((Context->CurrentTotalUsageByType[TypeIndex] != 0) ||\r
331 (Context->PeakTotalUsageByType[TypeIndex] != 0)) {\r
332 Print (L" CurrentTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex, Context->CurrentTotalUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);\r
333 Print (L" PeakTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex, Context->PeakTotalUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);\r
334 }\r
335 }\r
336 Print (L" TotalImageSize - 0x%016lx\n", Context->TotalImageSize);\r
337 Print (L" ImageCount - 0x%08x\n", Context->ImageCount);\r
338 Print (L" SequenceCount - 0x%08x\n", Context->SequenceCount);\r
339\r
340 DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) ((UINTN) Context + Context->Header.Length);\r
341 for (DriverIndex = 0; DriverIndex < Context->ImageCount; DriverIndex++) {\r
342 DriverInfo = DumpMemoryProfileDriverInfo (DriverIndex, DriverInfo);\r
343 if (DriverInfo == NULL) {\r
344 return NULL;\r
345 }\r
346 }\r
347 return (VOID *) DriverInfo;\r
348}\r
349\r
350/**\r
351 Dump memory profile descriptor information.\r
352\r
353 @param[in] DescriptorIndex Memory profile descriptor index.\r
354 @param[in] Descriptor Pointer to memory profile descriptor.\r
355\r
356 @return Pointer to next memory profile descriptor.\r
357\r
358**/\r
359MEMORY_PROFILE_DESCRIPTOR *\r
360DumpMemoryProfileDescriptor (\r
361 IN UINTN DescriptorIndex,\r
362 IN MEMORY_PROFILE_DESCRIPTOR *Descriptor\r
363 )\r
364{\r
365 if (Descriptor->Header.Signature != MEMORY_PROFILE_DESCRIPTOR_SIGNATURE) {\r
366 return NULL;\r
367 }\r
368 Print (L" MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex);\r
369 Print (L" Signature - 0x%08x\n", Descriptor->Header.Signature);\r
370 Print (L" Length - 0x%04x\n", Descriptor->Header.Length);\r
371 Print (L" Revision - 0x%04x\n", Descriptor->Header.Revision); \r
372 Print (L" Address - 0x%016lx\n", Descriptor->Address);\r
373 Print (L" Size - 0x%016lx\n", Descriptor->Size);\r
374\r
375 return (MEMORY_PROFILE_DESCRIPTOR *) ((UINTN) Descriptor + Descriptor->Header.Length);\r
376}\r
377\r
378/**\r
379 Dump memory profile free memory information.\r
380\r
381 @param[in] FreeMemory Pointer to memory profile free memory.\r
382\r
383 @return Pointer to the end of memory profile free memory buffer.\r
384\r
385**/\r
386VOID *\r
387DumpMemoryProfileFreeMemory (\r
388 IN MEMORY_PROFILE_FREE_MEMORY *FreeMemory\r
389 )\r
390{\r
391 MEMORY_PROFILE_DESCRIPTOR *Descriptor;\r
392 UINTN DescriptorIndex;\r
393\r
394 if (FreeMemory->Header.Signature != MEMORY_PROFILE_FREE_MEMORY_SIGNATURE) {\r
395 return NULL;\r
396 }\r
397 Print (L"MEMORY_PROFILE_FREE_MEMORY\n");\r
398 Print (L" Signature - 0x%08x\n", FreeMemory->Header.Signature);\r
399 Print (L" Length - 0x%04x\n", FreeMemory->Header.Length);\r
400 Print (L" Revision - 0x%04x\n", FreeMemory->Header.Revision); \r
401 Print (L" TotalFreeMemoryPages - 0x%016lx\n", FreeMemory->TotalFreeMemoryPages);\r
402 Print (L" FreeMemoryEntryCount - 0x%08x\n", FreeMemory->FreeMemoryEntryCount);\r
403\r
404 Descriptor = (MEMORY_PROFILE_DESCRIPTOR *) ((UINTN) FreeMemory + FreeMemory->Header.Length);\r
405 for (DescriptorIndex = 0; DescriptorIndex < FreeMemory->FreeMemoryEntryCount; DescriptorIndex++) {\r
406 Descriptor = DumpMemoryProfileDescriptor (DescriptorIndex, Descriptor);\r
407 if (Descriptor == NULL) {\r
408 return NULL;\r
409 }\r
410 }\r
411\r
412 return (VOID *) Descriptor;\r
413}\r
414\r
415/**\r
416 Dump memory profile memory range information.\r
417\r
418 @param[in] MemoryRange Pointer to memory profile memory range.\r
419\r
420 @return Pointer to the end of memory profile memory range buffer.\r
421\r
422**/\r
423VOID *\r
424DumpMemoryProfileMemoryRange (\r
425 IN MEMORY_PROFILE_MEMORY_RANGE *MemoryRange\r
426 )\r
427{\r
428 MEMORY_PROFILE_DESCRIPTOR *Descriptor;\r
429 UINTN DescriptorIndex;\r
430\r
431 if (MemoryRange->Header.Signature != MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE) {\r
432 return NULL;\r
433 }\r
434 Print (L"MEMORY_PROFILE_MEMORY_RANGE\n");\r
435 Print (L" Signature - 0x%08x\n", MemoryRange->Header.Signature);\r
436 Print (L" Length - 0x%04x\n", MemoryRange->Header.Length);\r
437 Print (L" Revision - 0x%04x\n", MemoryRange->Header.Revision); \r
438 Print (L" MemoryRangeCount - 0x%08x\n", MemoryRange->MemoryRangeCount);\r
439\r
440 Descriptor = (MEMORY_PROFILE_DESCRIPTOR *) ((UINTN) MemoryRange + MemoryRange->Header.Length);\r
441 for (DescriptorIndex = 0; DescriptorIndex < MemoryRange->MemoryRangeCount; DescriptorIndex++) {\r
442 Descriptor = DumpMemoryProfileDescriptor (DescriptorIndex, Descriptor);\r
443 if (Descriptor == NULL) {\r
444 return NULL;\r
445 }\r
446 }\r
447\r
448 return (VOID *) Descriptor;\r
449}\r
450\r
451/**\r
452 Scan memory profile by Signature.\r
453\r
454 @param[in] ProfileBuffer Memory profile base address.\r
455 @param[in] ProfileSize Memory profile size.\r
456 @param[in] Signature Signature.\r
457\r
458 @return Pointer to the stucture with the signature.\r
459\r
460**/\r
461VOID *\r
462ScanMemoryProfileBySignature (\r
463 IN PHYSICAL_ADDRESS ProfileBuffer,\r
464 IN UINT64 ProfileSize,\r
465 IN UINT32 Signature\r
466 )\r
467{\r
468 MEMORY_PROFILE_COMMON_HEADER *CommonHeader;\r
469 UINTN ProfileEnd;\r
470\r
471 ProfileEnd = (UINTN) (ProfileBuffer + ProfileSize);\r
472 CommonHeader = (MEMORY_PROFILE_COMMON_HEADER *) (UINTN) ProfileBuffer;\r
473 while ((UINTN) CommonHeader < ProfileEnd) {\r
474 if (CommonHeader->Signature == Signature) {\r
475 //\r
476 // Found it.\r
477 //\r
478 return (VOID *) CommonHeader;\r
479 }\r
480 CommonHeader = (MEMORY_PROFILE_COMMON_HEADER *) ((UINTN) CommonHeader + CommonHeader->Length);\r
481 }\r
482\r
483 return NULL;\r
484}\r
485\r
486/**\r
487 Dump memory profile information.\r
488\r
489 @param[in] ProfileBuffer Memory profile base address.\r
490 @param[in] ProfileSize Memory profile size.\r
491\r
492**/\r
493VOID\r
494DumpMemoryProfile (\r
495 IN PHYSICAL_ADDRESS ProfileBuffer,\r
496 IN UINT64 ProfileSize\r
497 )\r
498{\r
499 MEMORY_PROFILE_CONTEXT *Context;\r
500 MEMORY_PROFILE_FREE_MEMORY *FreeMemory;\r
501 MEMORY_PROFILE_MEMORY_RANGE *MemoryRange;\r
502\r
503 Context = (MEMORY_PROFILE_CONTEXT *) ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_CONTEXT_SIGNATURE);\r
504 if (Context != NULL) {\r
505 DumpMemoryProfileContext (Context);\r
506 }\r
507\r
508 FreeMemory = (MEMORY_PROFILE_FREE_MEMORY *) ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE);\r
509 if (FreeMemory != NULL) {\r
510 DumpMemoryProfileFreeMemory (FreeMemory);\r
511 }\r
512\r
513 MemoryRange = (MEMORY_PROFILE_MEMORY_RANGE *) ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE);\r
514 if (MemoryRange != NULL) {\r
515 DumpMemoryProfileMemoryRange (MemoryRange);\r
516 }\r
517}\r
518\r
519/**\r
520 Get and dump UEFI memory profile data.\r
521\r
522 @return EFI_SUCCESS Get the memory profile data successfully.\r
523 @return other Fail to get the memory profile data.\r
524\r
525**/\r
526EFI_STATUS\r
527GetUefiMemoryProfileData (\r
528 VOID\r
529 )\r
530{\r
531 EFI_STATUS Status;\r
532 EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol;\r
533 VOID *Data;\r
534 UINT64 Size;\r
535\r
536 Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **) &ProfileProtocol);\r
537 if (EFI_ERROR (Status)) {\r
538 DEBUG ((EFI_D_ERROR, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status));\r
539 return Status;\r
540 }\r
541\r
542 Size = 0;\r
543 Data = NULL;\r
544 Status = ProfileProtocol->GetData (\r
545 ProfileProtocol,\r
546 &Size,\r
547 Data\r
548 );\r
549 if (Status != EFI_BUFFER_TOO_SMALL) {\r
550 Print (L"UefiMemoryProfile: GetData - %r\n", Status);\r
551 return Status;\r
552 }\r
553\r
554 //\r
555 // Add one sizeof (MEMORY_PROFILE_ALLOC_INFO) to Size for this AllocatePool action.\r
556 //\r
557 Size = Size + sizeof (MEMORY_PROFILE_ALLOC_INFO);\r
558 Data = AllocateZeroPool ((UINTN) Size);\r
559 if (Data == NULL) {\r
f4420027 560 Status = EFI_OUT_OF_RESOURCES;\r
84edd20b
SZ
561 Print (L"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size, Status);\r
562 return Status;\r
563 }\r
564\r
565 Status = ProfileProtocol->GetData (\r
566 ProfileProtocol,\r
567 &Size,\r
568 Data\r
569 );\r
570 if (EFI_ERROR (Status)) {\r
571 FreePool (Data);\r
572 Print (L"UefiMemoryProfile: GetData - %r\n", Status);\r
573 return Status;\r
574 }\r
575\r
576\r
577 Print (L"UefiMemoryProfileSize - 0x%x\n", Size);\r
578 Print (L"======= UefiMemoryProfile begin =======\n");\r
579 DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) Data, Size);\r
580 Print (L"======= UefiMemoryProfile end =======\n\n\n");\r
581\r
582 FreePool (Data);\r
583\r
584 return EFI_SUCCESS;\r
585}\r
586\r
587/**\r
588 Get and dump SMRAM profile data.\r
589\r
590 @return EFI_SUCCESS Get the SMRAM profile data successfully.\r
591 @return other Fail to get the SMRAM profile data.\r
592\r
593**/\r
594EFI_STATUS\r
595GetSmramProfileData (\r
596 VOID\r
597 )\r
598{\r
599 EFI_STATUS Status;\r
600 UINTN CommSize;\r
f4420027 601 UINT8 *CommBuffer;\r
84edd20b
SZ
602 EFI_SMM_COMMUNICATE_HEADER *CommHeader;\r
603 SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *CommGetProfileInfo;\r
604 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *CommGetProfileData;\r
605 UINT64 ProfileSize;\r
606 PHYSICAL_ADDRESS ProfileBuffer;\r
607 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;\r
608\r
609 Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication);\r
610 if (EFI_ERROR (Status)) {\r
611 DEBUG ((EFI_D_ERROR, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status));\r
612 return Status;\r
613 }\r
614\r
f4420027
SZ
615 CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA);\r
616 CommBuffer = AllocateZeroPool (CommSize);\r
617 if (CommBuffer == NULL) {\r
618 Status = EFI_OUT_OF_RESOURCES;\r
619 Print (L"SmramProfile: AllocateZeroPool (0x%x) for comm buffer - %r\n", CommSize, Status);\r
620 return Status;\r
621 }\r
622\r
84edd20b
SZ
623 //\r
624 // Get Size\r
625 //\r
626 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];\r
627 CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));\r
628 CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO);\r
629\r
630 CommGetProfileInfo = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
631 CommGetProfileInfo->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO;\r
632 CommGetProfileInfo->Header.DataLength = sizeof (*CommGetProfileInfo);\r
633 CommGetProfileInfo->Header.ReturnStatus = (UINT64)-1;\r
634 CommGetProfileInfo->ProfileSize = 0;\r
635\r
636 CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
637 Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
638 if (EFI_ERROR (Status)) {\r
f4420027 639 FreePool (CommBuffer);\r
84edd20b
SZ
640 DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status));\r
641 return Status;\r
642 }\r
643\r
644 if (CommGetProfileInfo->Header.ReturnStatus != 0) {\r
645 Print (L"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo->Header.ReturnStatus);\r
646 return EFI_SUCCESS;\r
647 }\r
648\r
649 ProfileSize = CommGetProfileInfo->ProfileSize;\r
650\r
651 //\r
652 // Get Data\r
653 //\r
654 ProfileBuffer = (PHYSICAL_ADDRESS) (UINTN) AllocateZeroPool ((UINTN) ProfileSize);\r
655 if (ProfileBuffer == 0) {\r
f4420027
SZ
656 FreePool (CommBuffer);\r
657 Status = EFI_OUT_OF_RESOURCES;\r
658 Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", (UINTN) ProfileSize, Status);\r
659 return Status;\r
84edd20b
SZ
660 }\r
661\r
662 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];\r
663 CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid));\r
664 CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA);\r
665\r
f4420027 666 CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
84edd20b
SZ
667 CommGetProfileData->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA;\r
668 CommGetProfileData->Header.DataLength = sizeof (*CommGetProfileData);\r
669 CommGetProfileData->Header.ReturnStatus = (UINT64)-1;\r
670 CommGetProfileData->ProfileSize = ProfileSize;\r
671 CommGetProfileData->ProfileBuffer = ProfileBuffer;\r
672\r
673 CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
674 Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
675 ASSERT_EFI_ERROR (Status);\r
676\r
677 if (CommGetProfileData->Header.ReturnStatus != 0) {\r
f4420027
SZ
678 FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer);\r
679 FreePool (CommBuffer);\r
84edd20b
SZ
680 Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus);\r
681 return EFI_SUCCESS;\r
682 }\r
683\r
684\r
685 Print (L"SmramProfileSize - 0x%x\n", CommGetProfileData->ProfileSize);\r
686 Print (L"======= SmramProfile begin =======\n");\r
687 DumpMemoryProfile (CommGetProfileData->ProfileBuffer, CommGetProfileData->ProfileSize);\r
688 Print (L"======= SmramProfile end =======\n\n\n");\r
689\r
690 FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer);\r
f4420027 691 FreePool (CommBuffer);\r
84edd20b
SZ
692\r
693 return EFI_SUCCESS;\r
694}\r
695\r
696/**\r
697 The user Entry Point for Application. The user code starts with this function\r
698 as the real entry point for the image goes into a library that calls this function.\r
699\r
700 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
701 @param[in] SystemTable A pointer to the EFI System Table.\r
702 \r
703 @retval EFI_SUCCESS The entry point is executed successfully.\r
704 @retval other Some error occurs when executing this entry point.\r
705\r
706**/\r
707EFI_STATUS\r
708EFIAPI\r
709UefiMain (\r
710 IN EFI_HANDLE ImageHandle,\r
711 IN EFI_SYSTEM_TABLE *SystemTable\r
712 )\r
713{\r
714 EFI_STATUS Status;\r
715\r
716 Status = GetUefiMemoryProfileData ();\r
717 if (EFI_ERROR (Status)) {\r
718 DEBUG ((EFI_D_ERROR, "GetUefiMemoryProfileData - %r\n", Status));\r
719 }\r
720\r
721 Status = GetSmramProfileData ();\r
722 if (EFI_ERROR (Status)) {\r
723 DEBUG ((EFI_D_ERROR, "GetSmramProfileData - %r\n", Status));\r
724 }\r
725\r
726 return EFI_SUCCESS;\r
727}\r