]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c
Vlv2TbltDevicePkg: fix ASSERT_EFI_ERROR() typos
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / SmramProfileRecord.c
CommitLineData
84edd20b
SZ
1/** @file\r
2 Support routines for SMRAM profile.\r
3\r
c3592c86 4 Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
84edd20b
SZ
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php.\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "PiSmmCore.h"\r
16\r
17#define IS_SMRAM_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT1) != 0)\r
18\r
19typedef struct {\r
20 UINT32 Signature;\r
21 MEMORY_PROFILE_CONTEXT Context;\r
22 LIST_ENTRY *DriverInfoList;\r
23} MEMORY_PROFILE_CONTEXT_DATA;\r
24\r
25typedef struct {\r
26 UINT32 Signature;\r
27 MEMORY_PROFILE_DRIVER_INFO DriverInfo;\r
28 LIST_ENTRY *AllocInfoList;\r
29 LIST_ENTRY Link;\r
30} MEMORY_PROFILE_DRIVER_INFO_DATA;\r
31\r
32typedef struct {\r
33 UINT32 Signature;\r
34 MEMORY_PROFILE_ALLOC_INFO AllocInfo;\r
35 LIST_ENTRY Link;\r
36} MEMORY_PROFILE_ALLOC_INFO_DATA;\r
37\r
38//\r
39// When free memory less than 4 pages, dump it.\r
40//\r
41#define SMRAM_INFO_DUMP_PAGE_THRESHOLD 4\r
42\r
43GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_FREE_MEMORY mSmramFreeMemory = {\r
44 {\r
45 MEMORY_PROFILE_FREE_MEMORY_SIGNATURE,\r
46 sizeof (MEMORY_PROFILE_FREE_MEMORY),\r
47 MEMORY_PROFILE_FREE_MEMORY_REVISION\r
48 },\r
49 0,\r
50 0\r
51};\r
52\r
53GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mImageQueue = INITIALIZE_LIST_HEAD_VARIABLE (mImageQueue);\r
54GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA mSmramProfileContext = {\r
55 MEMORY_PROFILE_CONTEXT_SIGNATURE,\r
56 {\r
57 {\r
58 MEMORY_PROFILE_CONTEXT_SIGNATURE,\r
59 sizeof (MEMORY_PROFILE_CONTEXT),\r
60 MEMORY_PROFILE_CONTEXT_REVISION\r
61 },\r
62 0,\r
63 0,\r
64 {0},\r
65 {0},\r
66 0,\r
67 0,\r
68 0\r
69 },\r
70 &mImageQueue,\r
71};\r
63aa86b0 72GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA *mSmramProfileContextPtr = NULL;\r
84edd20b
SZ
73\r
74BOOLEAN mSmramReadyToLock;\r
75BOOLEAN mSmramProfileRecordingStatus = FALSE;\r
76\r
63aa86b0
SZ
77/**\r
78 Dump SMRAM infromation.\r
79\r
80**/\r
81VOID\r
82DumpSmramInfo (\r
83 VOID\r
84 );\r
85\r
84edd20b
SZ
86/**\r
87 Return SMRAM profile context.\r
88\r
89 @return SMRAM profile context.\r
90\r
91**/\r
92MEMORY_PROFILE_CONTEXT_DATA *\r
93GetSmramProfileContext (\r
94 VOID\r
95 )\r
96{\r
97 return mSmramProfileContextPtr;\r
98}\r
99\r
100/**\r
101 Retrieves the magic value from the PE/COFF header.\r
102\r
103 @param Hdr The buffer in which to return the PE32, PE32+, or TE header.\r
104\r
105 @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32\r
106 @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+\r
107\r
108**/\r
109UINT16\r
110InternalPeCoffGetPeHeaderMagicValue (\r
111 IN EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr\r
112 )\r
113{\r
114 //\r
115 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value\r
116 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the\r
117 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
118 // then override the returned value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
119 //\r
120 if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
121 return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
122 }\r
123 //\r
124 // Return the magic value from the PC/COFF Optional Header\r
125 //\r
126 return Hdr.Pe32->OptionalHeader.Magic;\r
127}\r
128\r
129/**\r
130 Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.\r
131 If Pe32Data is NULL, then ASSERT().\r
132\r
133 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.\r
134\r
135 @return The Subsystem of the PE/COFF image.\r
136\r
137**/\r
138UINT16\r
139InternalPeCoffGetSubsystem (\r
140 IN VOID *Pe32Data\r
141 )\r
142{\r
143 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
144 EFI_IMAGE_DOS_HEADER *DosHdr;\r
145 UINT16 Magic;\r
146\r
147 ASSERT (Pe32Data != NULL);\r
148\r
149 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;\r
150 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
151 //\r
152 // DOS image header is present, so read the PE header after the DOS image header.\r
153 //\r
154 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
155 } else {\r
156 //\r
157 // DOS image header is not present, so PE header is at the image base.\r
158 //\r
159 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data;\r
160 }\r
161\r
162 if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
163 return Hdr.Te->Subsystem;\r
164 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
165 Magic = InternalPeCoffGetPeHeaderMagicValue (Hdr);\r
166 if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
167 return Hdr.Pe32->OptionalHeader.Subsystem;\r
168 } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
169 return Hdr.Pe32Plus->OptionalHeader.Subsystem;\r
170 }\r
171 }\r
172\r
173 return 0x0000;\r
174}\r
175\r
176/**\r
177 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded\r
178 into system memory with the PE/COFF Loader Library functions.\r
179\r
180 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry\r
181 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then\r
182 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.\r
183 If Pe32Data is NULL, then ASSERT().\r
184 If EntryPoint is NULL, then ASSERT().\r
185\r
186 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.\r
187 @param EntryPoint The pointer to entry point to the PE/COFF image to return.\r
188\r
189 @retval RETURN_SUCCESS EntryPoint was returned.\r
190 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.\r
191\r
192**/\r
193RETURN_STATUS\r
194InternalPeCoffGetEntryPoint (\r
195 IN VOID *Pe32Data,\r
196 OUT VOID **EntryPoint\r
197 )\r
198{\r
199 EFI_IMAGE_DOS_HEADER *DosHdr;\r
200 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
201\r
202 ASSERT (Pe32Data != NULL);\r
203 ASSERT (EntryPoint != NULL);\r
204\r
205 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;\r
206 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
207 //\r
208 // DOS image header is present, so read the PE header after the DOS image header.\r
209 //\r
210 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
211 } else {\r
212 //\r
213 // DOS image header is not present, so PE header is at the image base.\r
214 //\r
215 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data;\r
216 }\r
217\r
218 //\r
219 // Calculate the entry point relative to the start of the image.\r
220 // AddressOfEntryPoint is common for PE32 & PE32+\r
221 //\r
222 if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
223 *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);\r
224 return RETURN_SUCCESS;\r
225 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
226 *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));\r
227 return RETURN_SUCCESS;\r
228 }\r
229\r
230 return RETURN_UNSUPPORTED;\r
231}\r
232\r
233/**\r
234 Build driver info.\r
235\r
236 @param ContextData Memory profile context.\r
237 @param FileName File name of the image.\r
238 @param ImageBase Image base address.\r
239 @param ImageSize Image size.\r
240 @param EntryPoint Entry point of the image.\r
241 @param ImageSubsystem Image subsystem of the image.\r
242\r
243 @param FileType File type of the image.\r
244\r
245 @return Pointer to memory profile driver info.\r
246\r
247**/\r
248MEMORY_PROFILE_DRIVER_INFO_DATA *\r
249BuildDriverInfo (\r
250 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,\r
251 IN EFI_GUID *FileName,\r
252 IN PHYSICAL_ADDRESS ImageBase,\r
253 IN UINT64 ImageSize,\r
254 IN PHYSICAL_ADDRESS EntryPoint,\r
255 IN UINT16 ImageSubsystem,\r
256 IN EFI_FV_FILETYPE FileType\r
257 )\r
258{\r
259 EFI_STATUS Status;\r
260 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
261 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
262 VOID *EntryPointInImage;\r
263\r
264 //\r
265 // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action.\r
266 //\r
267 Status = SmmInternalAllocatePool (\r
268 EfiRuntimeServicesData,\r
269 sizeof (*DriverInfoData) + sizeof (LIST_ENTRY),\r
270 (VOID **) &DriverInfoData\r
271 );\r
272 if (EFI_ERROR (Status)) {\r
273 return NULL;\r
274 }\r
275\r
276 ZeroMem (DriverInfoData, sizeof (*DriverInfoData));\r
277\r
278 DriverInfo = &DriverInfoData->DriverInfo;\r
279 DriverInfoData->Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE;\r
280 DriverInfo->Header.Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE;\r
281 DriverInfo->Header.Length = sizeof (MEMORY_PROFILE_DRIVER_INFO);\r
282 DriverInfo->Header.Revision = MEMORY_PROFILE_DRIVER_INFO_REVISION;\r
283 if (FileName != NULL) {\r
284 CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID));\r
285 }\r
286 DriverInfo->ImageBase = ImageBase;\r
287 DriverInfo->ImageSize = ImageSize;\r
288 DriverInfo->EntryPoint = EntryPoint;\r
289 DriverInfo->ImageSubsystem = ImageSubsystem;\r
290 if ((EntryPoint != 0) && ((EntryPoint < ImageBase) || (EntryPoint >= (ImageBase + ImageSize)))) {\r
291 //\r
292 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.\r
293 // So patch ImageBuffer here to align the EntryPoint.\r
294 //\r
295 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageBase, &EntryPointInImage);\r
296 ASSERT_EFI_ERROR (Status);\r
297 DriverInfo->ImageBase = ImageBase + EntryPoint - (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;\r
298 }\r
299 DriverInfo->FileType = FileType;\r
300 DriverInfoData->AllocInfoList = (LIST_ENTRY *) (DriverInfoData + 1);\r
301 InitializeListHead (DriverInfoData->AllocInfoList);\r
302 DriverInfo->CurrentUsage = 0;\r
303 DriverInfo->PeakUsage = 0;\r
304 DriverInfo->AllocRecordCount = 0;\r
305\r
306 InsertTailList (ContextData->DriverInfoList, &DriverInfoData->Link);\r
307 ContextData->Context.ImageCount ++;\r
308 ContextData->Context.TotalImageSize += DriverInfo->ImageSize;\r
309\r
310 return DriverInfoData;\r
311}\r
312\r
313/**\r
314 Register image to DXE.\r
315\r
316 @param FileName File name of the image.\r
317 @param ImageBase Image base address.\r
318 @param ImageSize Image size.\r
319 @param FileType File type of the image.\r
320\r
321**/\r
322VOID\r
323RegisterImageToDxe (\r
324 IN EFI_GUID *FileName,\r
325 IN PHYSICAL_ADDRESS ImageBase,\r
326 IN UINT64 ImageSize,\r
327 IN EFI_FV_FILETYPE FileType\r
328 )\r
329{\r
330 EFI_STATUS Status;\r
331 EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol;\r
332 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;\r
333 UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];\r
334\r
335 if (IS_SMRAM_PROFILE_ENABLED) {\r
336\r
337 FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;\r
338 Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **) &ProfileProtocol);\r
339 if (!EFI_ERROR (Status)) {\r
340 EfiInitializeFwVolDevicepathNode (FilePath, FileName);\r
341 SetDevicePathEndNode (FilePath + 1);\r
342\r
343 Status = ProfileProtocol->RegisterImage (\r
344 ProfileProtocol,\r
345 (EFI_DEVICE_PATH_PROTOCOL *) FilePath,\r
346 ImageBase,\r
347 ImageSize,\r
348 FileType\r
349 );\r
350 }\r
351 }\r
352}\r
353\r
354/**\r
355 Unregister image from DXE.\r
356\r
357 @param FileName File name of the image.\r
358 @param ImageBase Image base address.\r
359 @param ImageSize Image size.\r
360\r
361**/\r
362VOID\r
363UnregisterImageFromDxe (\r
364 IN EFI_GUID *FileName,\r
365 IN PHYSICAL_ADDRESS ImageBase,\r
366 IN UINT64 ImageSize\r
367 )\r
368{\r
369 EFI_STATUS Status;\r
370 EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol;\r
371 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;\r
372 UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];\r
373\r
374 if (IS_SMRAM_PROFILE_ENABLED) {\r
375\r
376 FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;\r
377 Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID *) &ProfileProtocol);\r
378 if (!EFI_ERROR (Status)) {\r
379 EfiInitializeFwVolDevicepathNode (FilePath, FileName);\r
380 SetDevicePathEndNode (FilePath + 1);\r
381\r
382 Status = ProfileProtocol->UnregisterImage (\r
383 ProfileProtocol,\r
384 (EFI_DEVICE_PATH_PROTOCOL *) FilePath,\r
385 ImageBase,\r
386 ImageSize\r
387 );\r
388 }\r
389 }\r
390}\r
391\r
392/**\r
393 Register SMM Core to SMRAM profile.\r
394\r
395 @param ContextData SMRAM profile context.\r
396\r
397 @retval TRUE Register success.\r
398 @retval FALSE Register fail.\r
399\r
400**/\r
401BOOLEAN\r
402RegisterSmmCore (\r
403 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData\r
404 )\r
405{\r
406 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
407 PHYSICAL_ADDRESS ImageBase;\r
408\r
409 ASSERT (ContextData != NULL);\r
410\r
411 RegisterImageToDxe (\r
412 &gEfiCallerIdGuid,\r
413 gSmmCorePrivate->PiSmmCoreImageBase,\r
414 gSmmCorePrivate->PiSmmCoreImageSize,\r
415 EFI_FV_FILETYPE_SMM_CORE\r
416 );\r
417\r
418 ImageBase = gSmmCorePrivate->PiSmmCoreImageBase;\r
419 DriverInfoData = BuildDriverInfo (\r
420 ContextData,\r
421 &gEfiCallerIdGuid,\r
422 ImageBase,\r
423 gSmmCorePrivate->PiSmmCoreImageSize,\r
424 gSmmCorePrivate->PiSmmCoreEntryPoint,\r
425 InternalPeCoffGetSubsystem ((VOID *) (UINTN) ImageBase),\r
426 EFI_FV_FILETYPE_SMM_CORE\r
427 );\r
428 if (DriverInfoData == NULL) {\r
429 return FALSE;\r
430 }\r
431\r
432 return TRUE;\r
433}\r
434\r
435/**\r
436 Initialize SMRAM profile.\r
437\r
438**/\r
439VOID\r
440SmramProfileInit (\r
441 VOID\r
442 )\r
443{\r
444 MEMORY_PROFILE_CONTEXT_DATA *SmramProfileContext;\r
445\r
446 if (!IS_SMRAM_PROFILE_ENABLED) {\r
447 return;\r
448 }\r
449\r
450 SmramProfileContext = GetSmramProfileContext ();\r
451 if (SmramProfileContext != NULL) {\r
452 return;\r
453 }\r
454\r
455 mSmramProfileRecordingStatus = TRUE;\r
456 mSmramProfileContextPtr = &mSmramProfileContext;\r
457\r
458 RegisterSmmCore (&mSmramProfileContext);\r
459\r
460 DEBUG ((EFI_D_INFO, "SmramProfileInit SmramProfileContext - 0x%x\n", &mSmramProfileContext));\r
461}\r
462\r
463/**\r
464 Register SMM image to SMRAM profile.\r
465\r
466 @param DriverEntry SMM image info.\r
467 @param RegisterToDxe Register image to DXE.\r
468\r
469 @retval TRUE Register success.\r
470 @retval FALSE Register fail.\r
471\r
472**/\r
473BOOLEAN\r
474RegisterSmramProfileImage (\r
475 IN EFI_SMM_DRIVER_ENTRY *DriverEntry,\r
476 IN BOOLEAN RegisterToDxe\r
477 )\r
478{\r
479 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
480 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
481\r
482 if (!IS_SMRAM_PROFILE_ENABLED) {\r
483 return FALSE;\r
484 }\r
485\r
486 if (RegisterToDxe) {\r
487 RegisterImageToDxe (\r
488 &DriverEntry->FileName,\r
489 DriverEntry->ImageBuffer,\r
490 EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage),\r
491 EFI_FV_FILETYPE_SMM\r
492 );\r
493 }\r
494\r
495 ContextData = GetSmramProfileContext ();\r
496 if (ContextData == NULL) {\r
497 return FALSE;\r
498 }\r
499\r
500 DriverInfoData = BuildDriverInfo (\r
501 ContextData,\r
502 &DriverEntry->FileName,\r
503 DriverEntry->ImageBuffer,\r
504 EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage),\r
505 DriverEntry->ImageEntryPoint,\r
506 InternalPeCoffGetSubsystem ((VOID *) (UINTN) DriverEntry->ImageBuffer),\r
507 EFI_FV_FILETYPE_SMM\r
508 );\r
509 if (DriverInfoData == NULL) {\r
510 return FALSE;\r
511 }\r
512\r
513 return TRUE;\r
514}\r
515\r
516/**\r
517 Search image from memory profile.\r
518\r
519 @param ContextData Memory profile context.\r
520 @param FileName Image file name.\r
521 @param Address Image Address.\r
522\r
523 @return Pointer to memory profile driver info.\r
524\r
525**/\r
526MEMORY_PROFILE_DRIVER_INFO_DATA *\r
527GetMemoryProfileDriverInfoByFileNameAndAddress (\r
528 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,\r
529 IN EFI_GUID *FileName,\r
530 IN PHYSICAL_ADDRESS Address\r
531 )\r
532{\r
533 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
534 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
535 LIST_ENTRY *DriverLink;\r
536 LIST_ENTRY *DriverInfoList;\r
537\r
538 DriverInfoList = ContextData->DriverInfoList;\r
539\r
540 for (DriverLink = DriverInfoList->ForwardLink;\r
541 DriverLink != DriverInfoList;\r
542 DriverLink = DriverLink->ForwardLink) {\r
543 DriverInfoData = CR (\r
544 DriverLink,\r
545 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
546 Link,\r
547 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
548 );\r
549 DriverInfo = &DriverInfoData->DriverInfo;\r
550 if ((CompareGuid (&DriverInfo->FileName, FileName)) &&\r
551 (Address >= DriverInfo->ImageBase) &&\r
552 (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) {\r
553 return DriverInfoData;\r
554 }\r
555 }\r
556\r
557 return NULL;\r
558}\r
559\r
560/**\r
561 Search dummy image from SMRAM profile.\r
562\r
563 @param ContextData Memory profile context.\r
564\r
565 @return Pointer to memory profile driver info.\r
566\r
567**/\r
568MEMORY_PROFILE_DRIVER_INFO_DATA *\r
569FindDummyImage (\r
570 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData\r
571 )\r
572{\r
573 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
574 LIST_ENTRY *DriverLink;\r
575 LIST_ENTRY *DriverInfoList;\r
576\r
577 DriverInfoList = ContextData->DriverInfoList;\r
578\r
579 for (DriverLink = DriverInfoList->ForwardLink;\r
580 DriverLink != DriverInfoList;\r
581 DriverLink = DriverLink->ForwardLink) {\r
582 DriverInfoData = CR (\r
583 DriverLink,\r
584 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
585 Link,\r
586 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
587 );\r
588 if (CompareGuid (&gZeroGuid, &DriverInfoData->DriverInfo.FileName)) {\r
589 return DriverInfoData;\r
590 }\r
591 }\r
592\r
593 return BuildDriverInfo (ContextData, &gZeroGuid, 0, 0, 0, 0, 0);\r
594}\r
595\r
596/**\r
597 Search image from memory profile.\r
598 It will return image, if (Address >= ImageBuffer) AND (Address < ImageBuffer + ImageSize)\r
599\r
600 @param ContextData Memory profile context.\r
601 @param Address Image or Function address.\r
602\r
603 @return Pointer to memory profile driver info.\r
604\r
605**/\r
606MEMORY_PROFILE_DRIVER_INFO_DATA *\r
607GetMemoryProfileDriverInfoFromAddress (\r
608 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,\r
609 IN PHYSICAL_ADDRESS Address\r
610 )\r
611{\r
612 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
613 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
614 LIST_ENTRY *DriverLink;\r
615 LIST_ENTRY *DriverInfoList;\r
616\r
617 DriverInfoList = ContextData->DriverInfoList;\r
618\r
619 for (DriverLink = DriverInfoList->ForwardLink;\r
620 DriverLink != DriverInfoList;\r
621 DriverLink = DriverLink->ForwardLink) {\r
622 DriverInfoData = CR (\r
623 DriverLink,\r
624 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
625 Link,\r
626 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
627 );\r
628 DriverInfo = &DriverInfoData->DriverInfo;\r
629 if ((Address >= DriverInfo->ImageBase) &&\r
630 (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) {\r
631 return DriverInfoData;\r
632 }\r
633 }\r
634\r
635 //\r
636 // Should never come here.\r
637 //\r
638 return FindDummyImage (ContextData);\r
639}\r
640\r
641/**\r
642 Unregister image from SMRAM profile.\r
643\r
644 @param DriverEntry SMM image info.\r
645 @param UnregisterFromDxe Unregister image from DXE.\r
646\r
647 @retval TRUE Unregister success.\r
648 @retval FALSE Unregister fail.\r
649\r
650**/\r
651BOOLEAN\r
652UnregisterSmramProfileImage (\r
653 IN EFI_SMM_DRIVER_ENTRY *DriverEntry,\r
654 IN BOOLEAN UnregisterFromDxe\r
655 )\r
656{\r
657 EFI_STATUS Status;\r
658 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
659 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
660 EFI_GUID *FileName;\r
661 PHYSICAL_ADDRESS ImageAddress;\r
662 VOID *EntryPointInImage;\r
663\r
664 if (!IS_SMRAM_PROFILE_ENABLED) {\r
665 return FALSE;\r
666 }\r
667\r
668 if (UnregisterFromDxe) {\r
669 UnregisterImageFromDxe (\r
670 &DriverEntry->FileName,\r
671 DriverEntry->ImageBuffer,\r
672 EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)\r
673 );\r
674 }\r
675\r
676 ContextData = GetSmramProfileContext ();\r
677 if (ContextData == NULL) {\r
678 return FALSE;\r
679 }\r
680\r
681 DriverInfoData = NULL;\r
682 FileName = &DriverEntry->FileName;\r
683 ImageAddress = DriverEntry->ImageBuffer;\r
684 if ((DriverEntry->ImageEntryPoint < ImageAddress) || (DriverEntry->ImageEntryPoint >= (ImageAddress + EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)))) {\r
685 //\r
686 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.\r
687 // So patch ImageAddress here to align the EntryPoint.\r
688 //\r
689 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageAddress, &EntryPointInImage);\r
690 ASSERT_EFI_ERROR (Status);\r
691 ImageAddress = ImageAddress + (UINTN) DriverEntry->ImageEntryPoint - (UINTN) EntryPointInImage;\r
692 }\r
693 if (FileName != NULL) {\r
694 DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress);\r
695 }\r
696 if (DriverInfoData == NULL) {\r
697 DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageAddress);\r
698 }\r
699 if (DriverInfoData == NULL) {\r
700 return FALSE;\r
701 }\r
702\r
703 ContextData->Context.TotalImageSize -= DriverInfoData->DriverInfo.ImageSize;\r
704\r
705 DriverInfoData->DriverInfo.ImageBase = 0;\r
706 DriverInfoData->DriverInfo.ImageSize = 0;\r
707\r
708 if (DriverInfoData->DriverInfo.PeakUsage == 0) {\r
709 ContextData->Context.ImageCount --;\r
710 RemoveEntryList (&DriverInfoData->Link);\r
711 //\r
712 // Use SmmInternalFreePool() that will not update profile for this FreePool action.\r
713 //\r
714 SmmInternalFreePool (DriverInfoData);\r
715 }\r
716\r
717 return TRUE;\r
718}\r
719\r
720/**\r
721 Return if this memory type needs to be recorded into memory profile.\r
ca949d9d 722 Only need to record EfiRuntimeServicesCode and EfiRuntimeServicesData for SMRAM profile.\r
84edd20b
SZ
723\r
724 @param MemoryType Memory type.\r
725\r
726 @retval TRUE This memory type need to be recorded.\r
727 @retval FALSE This memory type need not to be recorded.\r
728\r
729**/\r
730BOOLEAN\r
731SmmCoreNeedRecordProfile (\r
732 IN EFI_MEMORY_TYPE MemoryType\r
733 )\r
734{\r
735 UINT64 TestBit;\r
736\r
ca949d9d
SZ
737 if (MemoryType != EfiRuntimeServicesCode &&\r
738 MemoryType != EfiRuntimeServicesData) {\r
739 return FALSE;\r
84edd20b
SZ
740 }\r
741\r
ca949d9d
SZ
742 TestBit = LShiftU64 (1, MemoryType);\r
743\r
84edd20b
SZ
744 if ((PcdGet64 (PcdMemoryProfileMemoryType) & TestBit) != 0) {\r
745 return TRUE;\r
746 } else {\r
747 return FALSE;\r
748 }\r
749}\r
750\r
751/**\r
752 Convert EFI memory type to profile memory index. The rule is:\r
ca949d9d
SZ
753 If BIOS memory type (0 ~ EfiMaxMemoryType - 1), ProfileMemoryIndex = MemoryType.\r
754 As SMRAM profile is only to record EfiRuntimeServicesCode and EfiRuntimeServicesData,\r
755 so return input memory type directly.\r
84edd20b
SZ
756\r
757 @param MemoryType Memory type.\r
758\r
759 @return EFI memory type as profile memory index.\r
760\r
761**/\r
762EFI_MEMORY_TYPE\r
763GetProfileMemoryIndex (\r
764 IN EFI_MEMORY_TYPE MemoryType\r
765 )\r
766{\r
ca949d9d 767 return MemoryType;\r
84edd20b
SZ
768}\r
769\r
770/**\r
771 Update SMRAM profile FreeMemoryPages information\r
772\r
773 @param ContextData Memory profile context.\r
774\r
775**/\r
776VOID\r
777SmramProfileUpdateFreePages (\r
778 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData\r
779 )\r
780{\r
781 LIST_ENTRY *Node;\r
782 FREE_PAGE_LIST *Pages;\r
783 LIST_ENTRY *FreePageList;\r
784 UINTN NumberOfPages;\r
785\r
786 NumberOfPages = 0;\r
787 FreePageList = &mSmmMemoryMap;\r
788 for (Node = FreePageList->BackLink;\r
789 Node != FreePageList;\r
790 Node = Node->BackLink) {\r
791 Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
792 NumberOfPages += Pages->NumberOfPages;\r
793 }\r
794\r
795 mSmramFreeMemory.TotalFreeMemoryPages = NumberOfPages;\r
796\r
797 if (NumberOfPages <= SMRAM_INFO_DUMP_PAGE_THRESHOLD) {\r
798 DumpSmramInfo ();\r
799 }\r
800}\r
801\r
802/**\r
803 Update SMRAM profile Allocate information.\r
804\r
805 @param CallerAddress Address of caller who call Allocate.\r
806 @param Action This Allocate action.\r
807 @param MemoryType Memory type.\r
808 @param Size Buffer size.\r
809 @param Buffer Buffer address.\r
810\r
811 @retval TRUE Profile udpate success.\r
812 @retval FALSE Profile update fail.\r
813\r
814**/\r
815BOOLEAN\r
816SmmCoreUpdateProfileAllocate (\r
817 IN PHYSICAL_ADDRESS CallerAddress,\r
818 IN MEMORY_PROFILE_ACTION Action,\r
819 IN EFI_MEMORY_TYPE MemoryType,\r
820 IN UINTN Size,\r
821 IN VOID *Buffer\r
822 )\r
823{\r
824 EFI_STATUS Status;\r
825 MEMORY_PROFILE_CONTEXT *Context;\r
826 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
827 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
828 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
829 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
830 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
831 EFI_MEMORY_TYPE ProfileMemoryIndex;\r
832\r
f4420027
SZ
833 AllocInfoData = NULL;\r
834\r
84edd20b
SZ
835 ContextData = GetSmramProfileContext ();\r
836 if (ContextData == NULL) {\r
837 return FALSE;\r
838 }\r
839\r
840 DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress);\r
841 ASSERT (DriverInfoData != NULL);\r
842\r
843 //\r
844 // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action.\r
845 //\r
846 Status = SmmInternalAllocatePool (\r
847 EfiRuntimeServicesData,\r
848 sizeof (*AllocInfoData),\r
849 (VOID **) &AllocInfoData\r
850 );\r
851 if (EFI_ERROR (Status)) {\r
852 return FALSE;\r
853 }\r
854 AllocInfo = &AllocInfoData->AllocInfo;\r
855 AllocInfoData->Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE;\r
856 AllocInfo->Header.Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE;\r
857 AllocInfo->Header.Length = sizeof (MEMORY_PROFILE_ALLOC_INFO);\r
858 AllocInfo->Header.Revision = MEMORY_PROFILE_ALLOC_INFO_REVISION;\r
859 AllocInfo->CallerAddress = CallerAddress;\r
860 AllocInfo->SequenceId = ContextData->Context.SequenceCount;\r
861 AllocInfo->Action = Action;\r
862 AllocInfo->MemoryType = MemoryType;\r
863 AllocInfo->Buffer = (PHYSICAL_ADDRESS) (UINTN) Buffer;\r
864 AllocInfo->Size = Size;\r
865\r
866 InsertTailList (DriverInfoData->AllocInfoList, &AllocInfoData->Link);\r
867\r
868 ProfileMemoryIndex = GetProfileMemoryIndex (MemoryType);\r
869\r
870 DriverInfo = &DriverInfoData->DriverInfo;\r
871 DriverInfo->CurrentUsage += Size;\r
872 if (DriverInfo->PeakUsage < DriverInfo->CurrentUsage) {\r
873 DriverInfo->PeakUsage = DriverInfo->CurrentUsage;\r
874 }\r
875 DriverInfo->CurrentUsageByType[ProfileMemoryIndex] += Size;\r
876 if (DriverInfo->PeakUsageByType[ProfileMemoryIndex] < DriverInfo->CurrentUsageByType[ProfileMemoryIndex]) {\r
877 DriverInfo->PeakUsageByType[ProfileMemoryIndex] = DriverInfo->CurrentUsageByType[ProfileMemoryIndex];\r
878 }\r
879 DriverInfo->AllocRecordCount ++;\r
880\r
881 Context = &ContextData->Context;\r
882 Context->CurrentTotalUsage += Size;\r
883 if (Context->PeakTotalUsage < Context->CurrentTotalUsage) {\r
884 Context->PeakTotalUsage = Context->CurrentTotalUsage;\r
885 }\r
886 Context->CurrentTotalUsageByType[ProfileMemoryIndex] += Size;\r
887 if (Context->PeakTotalUsageByType[ProfileMemoryIndex] < Context->CurrentTotalUsageByType[ProfileMemoryIndex]) {\r
888 Context->PeakTotalUsageByType[ProfileMemoryIndex] = Context->CurrentTotalUsageByType[ProfileMemoryIndex];\r
889 }\r
890 Context->SequenceCount ++;\r
891\r
892 SmramProfileUpdateFreePages (ContextData);\r
893 return TRUE;\r
894}\r
895\r
896/**\r
897 Get memory profile alloc info from memory profile\r
898\r
899 @param DriverInfoData Driver info\r
900 @param Action This Free action\r
901 @param Size Buffer size\r
902 @param Buffer Buffer address\r
903\r
904 @return Pointer to memory profile alloc info.\r
905**/\r
906MEMORY_PROFILE_ALLOC_INFO_DATA *\r
907GetMemoryProfileAllocInfoFromAddress (\r
908 IN MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData,\r
909 IN MEMORY_PROFILE_ACTION Action,\r
910 IN UINTN Size,\r
911 IN VOID *Buffer\r
912 )\r
913{\r
914 LIST_ENTRY *AllocInfoList;\r
915 LIST_ENTRY *AllocLink;\r
916 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
917 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
918\r
919 AllocInfoList = DriverInfoData->AllocInfoList;\r
920\r
921 for (AllocLink = AllocInfoList->ForwardLink;\r
922 AllocLink != AllocInfoList;\r
923 AllocLink = AllocLink->ForwardLink) {\r
924 AllocInfoData = CR (\r
925 AllocLink,\r
926 MEMORY_PROFILE_ALLOC_INFO_DATA,\r
927 Link,\r
928 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE\r
929 );\r
930 AllocInfo = &AllocInfoData->AllocInfo;\r
931 if (AllocInfo->Action != Action) {\r
932 continue;\r
933 }\r
934 switch (Action) {\r
935 case MemoryProfileActionAllocatePages:\r
936 if ((AllocInfo->Buffer <= (PHYSICAL_ADDRESS) (UINTN) Buffer) &&\r
937 ((AllocInfo->Buffer + AllocInfo->Size) >= ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size))) {\r
938 return AllocInfoData;\r
939 }\r
940 break;\r
941 case MemoryProfileActionAllocatePool:\r
942 if (AllocInfo->Buffer == (PHYSICAL_ADDRESS) (UINTN) Buffer) {\r
943 return AllocInfoData;\r
944 }\r
945 break;\r
946 default:\r
947 ASSERT (FALSE);\r
948 break;\r
949 }\r
950 }\r
951\r
952 return NULL;\r
953}\r
954\r
955/**\r
956 Update SMRAM profile Free information.\r
957\r
958 @param CallerAddress Address of caller who call Free.\r
959 @param Action This Free action.\r
960 @param Size Buffer size.\r
961 @param Buffer Buffer address.\r
962\r
963 @retval TRUE Profile udpate success.\r
964 @retval FALSE Profile update fail.\r
965\r
966**/\r
967BOOLEAN\r
968SmmCoreUpdateProfileFree (\r
969 IN PHYSICAL_ADDRESS CallerAddress,\r
970 IN MEMORY_PROFILE_ACTION Action,\r
971 IN UINTN Size,\r
972 IN VOID *Buffer\r
973 )\r
974{\r
975 MEMORY_PROFILE_CONTEXT *Context;\r
976 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
977 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
978 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
979 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
980 LIST_ENTRY *DriverLink;\r
981 LIST_ENTRY *DriverInfoList;\r
982 MEMORY_PROFILE_DRIVER_INFO_DATA *ThisDriverInfoData;\r
983 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
984 EFI_MEMORY_TYPE ProfileMemoryIndex;\r
985\r
986 ContextData = GetSmramProfileContext ();\r
987 if (ContextData == NULL) {\r
988 return FALSE;\r
989 }\r
990\r
991 DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress);\r
992 ASSERT (DriverInfoData != NULL);\r
993\r
994 switch (Action) {\r
995 case MemoryProfileActionFreePages:\r
996 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer);\r
997 break;\r
998 case MemoryProfileActionFreePool:\r
999 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer);\r
1000 break;\r
1001 default:\r
1002 ASSERT (FALSE);\r
1003 AllocInfoData = NULL;\r
1004 break;\r
1005 }\r
1006 if (AllocInfoData == NULL) {\r
1007 //\r
1008 // Legal case, because driver A might free memory allocated by driver B, by some protocol.\r
1009 //\r
1010 DriverInfoList = ContextData->DriverInfoList;\r
1011\r
1012 for (DriverLink = DriverInfoList->ForwardLink;\r
1013 DriverLink != DriverInfoList;\r
1014 DriverLink = DriverLink->ForwardLink) {\r
1015 ThisDriverInfoData = CR (\r
1016 DriverLink,\r
1017 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
1018 Link,\r
1019 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
1020 );\r
1021 switch (Action) {\r
1022 case MemoryProfileActionFreePages:\r
1023 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer);\r
1024 break;\r
1025 case MemoryProfileActionFreePool:\r
1026 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer);\r
1027 break;\r
1028 default:\r
1029 ASSERT (FALSE);\r
1030 AllocInfoData = NULL;\r
1031 break;\r
1032 }\r
1033 if (AllocInfoData != NULL) {\r
1034 DriverInfoData = ThisDriverInfoData;\r
1035 break;\r
1036 }\r
1037 }\r
1038\r
1039 if (AllocInfoData == NULL) {\r
1040 //\r
1041 // No matched allocate operation is found for this free operation.\r
1042 // It is because the specified memory type allocate operation has been\r
1043 // filtered by CoreNeedRecordProfile(), but free operations have no\r
1044 // memory type information, they can not be filtered by CoreNeedRecordProfile().\r
1045 // Then, they will be filtered here.\r
1046 //\r
1047 return FALSE;\r
1048 }\r
1049 }\r
1050\r
1051 Context = &ContextData->Context;\r
1052 DriverInfo = &DriverInfoData->DriverInfo;\r
1053 AllocInfo = &AllocInfoData->AllocInfo;\r
1054\r
1055 ProfileMemoryIndex = GetProfileMemoryIndex (AllocInfo->MemoryType);\r
1056\r
1057 Context->CurrentTotalUsage -= AllocInfo->Size;\r
1058 Context->CurrentTotalUsageByType[ProfileMemoryIndex] -= AllocInfo->Size;\r
1059\r
1060 DriverInfo->CurrentUsage -= AllocInfo->Size;\r
1061 DriverInfo->CurrentUsageByType[ProfileMemoryIndex] -= AllocInfo->Size;\r
1062 DriverInfo->AllocRecordCount --;\r
1063\r
1064 RemoveEntryList (&AllocInfoData->Link);\r
1065\r
1066 if (Action == MemoryProfileActionFreePages) {\r
1067 if (AllocInfo->Buffer != (PHYSICAL_ADDRESS) (UINTN) Buffer) {\r
1068 SmmCoreUpdateProfileAllocate (\r
1069 AllocInfo->CallerAddress,\r
1070 MemoryProfileActionAllocatePages,\r
1071 AllocInfo->MemoryType,\r
1072 (UINTN) ((PHYSICAL_ADDRESS) (UINTN) Buffer - AllocInfo->Buffer),\r
1073 (VOID *) (UINTN) AllocInfo->Buffer\r
1074 );\r
1075 }\r
1076 if (AllocInfo->Buffer + AllocInfo->Size != ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)) {\r
1077 SmmCoreUpdateProfileAllocate (\r
1078 AllocInfo->CallerAddress,\r
1079 MemoryProfileActionAllocatePages,\r
1080 AllocInfo->MemoryType,\r
1081 (UINTN) ((AllocInfo->Buffer + AllocInfo->Size) - ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)),\r
1082 (VOID *) ((UINTN) Buffer + Size)\r
1083 );\r
1084 }\r
1085 }\r
1086\r
1087 //\r
1088 // Use SmmInternalFreePool() that will not update profile for this FreePool action.\r
1089 //\r
1090 SmmInternalFreePool (AllocInfoData);\r
1091\r
1092 return TRUE;\r
1093}\r
1094\r
1095/**\r
1096 Update SMRAM profile information.\r
1097\r
1098 @param CallerAddress Address of caller who call Allocate or Free.\r
1099 @param Action This Allocate or Free action.\r
1100 @param MemoryType Memory type.\r
1101 @param Size Buffer size.\r
1102 @param Buffer Buffer address.\r
1103\r
1104 @retval TRUE Profile udpate success.\r
1105 @retval FALSE Profile update fail.\r
1106\r
1107**/\r
1108BOOLEAN\r
1109SmmCoreUpdateProfile (\r
1110 IN PHYSICAL_ADDRESS CallerAddress,\r
1111 IN MEMORY_PROFILE_ACTION Action,\r
1112 IN EFI_MEMORY_TYPE MemoryType, // Valid for AllocatePages/AllocatePool\r
1113 IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool\r
1114 IN VOID *Buffer\r
1115 )\r
1116{\r
1117 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1118\r
1119 if (!IS_SMRAM_PROFILE_ENABLED) {\r
1120 return FALSE;\r
1121 }\r
1122\r
1123 if (!mSmramProfileRecordingStatus) {\r
1124 return FALSE;\r
1125 }\r
1126\r
1127 //\r
1128 // Free operations have no memory type information, so skip the check.\r
1129 //\r
1130 if ((Action == MemoryProfileActionAllocatePages) || (Action == MemoryProfileActionAllocatePool)) {\r
1131 //\r
1132 // Only record limited MemoryType.\r
1133 //\r
1134 if (!SmmCoreNeedRecordProfile (MemoryType)) {\r
1135 return FALSE;\r
1136 }\r
1137 }\r
1138\r
1139 ContextData = GetSmramProfileContext ();\r
1140 if (ContextData == NULL) {\r
1141 return FALSE;\r
1142 }\r
1143\r
1144 switch (Action) {\r
1145 case MemoryProfileActionAllocatePages:\r
1146 SmmCoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer);\r
1147 break;\r
1148 case MemoryProfileActionFreePages:\r
1149 SmmCoreUpdateProfileFree (CallerAddress, Action, Size, Buffer);\r
1150 break;\r
1151 case MemoryProfileActionAllocatePool:\r
1152 SmmCoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer);\r
1153 break;\r
1154 case MemoryProfileActionFreePool:\r
1155 SmmCoreUpdateProfileFree (CallerAddress, Action, 0, Buffer);\r
1156 break;\r
1157 default:\r
1158 ASSERT (FALSE);\r
1159 break;\r
1160 }\r
1161\r
1162 return TRUE;\r
1163}\r
1164\r
1165/**\r
1166 SMRAM profile ready to lock callback function.\r
1167\r
1168**/\r
1169VOID\r
1170SmramProfileReadyToLock (\r
1171 VOID\r
1172 )\r
1173{\r
1174 if (!IS_SMRAM_PROFILE_ENABLED) {\r
1175 return;\r
1176 }\r
1177\r
1178 DEBUG ((EFI_D_INFO, "SmramProfileReadyToLock\n"));\r
1179 mSmramReadyToLock = TRUE;\r
1180}\r
1181\r
1182////////////////////\r
1183\r
84edd20b
SZ
1184/**\r
1185 Get SMRAM profile data size.\r
1186\r
1187 @return SMRAM profile data size.\r
1188\r
1189**/\r
1190UINTN\r
1191SmramProfileGetDataSize (\r
1192 VOID\r
1193 )\r
1194{\r
1195 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1196 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
1197 LIST_ENTRY *DriverInfoList;\r
1198 LIST_ENTRY *DriverLink;\r
1199 UINTN TotalSize;\r
1200 LIST_ENTRY *Node;\r
1201 LIST_ENTRY *FreePageList;\r
1202 LIST_ENTRY *FreePoolList;\r
1203 FREE_POOL_HEADER *Pool;\r
1204 UINTN PoolListIndex;\r
1205 UINTN Index;\r
1206\r
1207 ContextData = GetSmramProfileContext ();\r
1208 if (ContextData == NULL) {\r
1209 return 0;\r
1210 }\r
1211\r
1212 TotalSize = sizeof (MEMORY_PROFILE_CONTEXT);\r
1213 TotalSize += sizeof (MEMORY_PROFILE_DRIVER_INFO) * (UINTN) ContextData->Context.ImageCount;\r
1214\r
1215 DriverInfoList = ContextData->DriverInfoList;\r
1216 for (DriverLink = DriverInfoList->ForwardLink;\r
1217 DriverLink != DriverInfoList;\r
1218 DriverLink = DriverLink->ForwardLink) {\r
1219 DriverInfoData = CR (\r
1220 DriverLink,\r
1221 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
1222 Link,\r
1223 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
1224 );\r
1225 TotalSize += sizeof (MEMORY_PROFILE_ALLOC_INFO) * (UINTN) DriverInfoData->DriverInfo.AllocRecordCount;\r
1226 }\r
1227\r
1228\r
1229 Index = 0;\r
1230 FreePageList = &mSmmMemoryMap;\r
1231 for (Node = FreePageList->BackLink;\r
1232 Node != FreePageList;\r
1233 Node = Node->BackLink) {\r
1234 Index++;\r
1235 }\r
1236 for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {\r
1237 FreePoolList = &mSmmPoolLists[PoolListIndex];\r
1238 for (Node = FreePoolList->BackLink;\r
1239 Node != FreePoolList;\r
1240 Node = Node->BackLink) {\r
1241 Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);\r
1242 if (Pool->Header.Available) {\r
1243 Index++;\r
1244 }\r
1245 }\r
1246 }\r
1247\r
1248\r
1249 TotalSize += (sizeof (MEMORY_PROFILE_FREE_MEMORY) + Index * sizeof (MEMORY_PROFILE_DESCRIPTOR));\r
1250 TotalSize += (sizeof (MEMORY_PROFILE_MEMORY_RANGE) + mFullSmramRangeCount * sizeof (MEMORY_PROFILE_DESCRIPTOR));\r
1251\r
1252 return TotalSize;\r
1253}\r
1254\r
1255/**\r
1256 Copy SMRAM profile data.\r
1257\r
1258 @param ProfileBuffer The buffer to hold SMRAM profile data.\r
c3592c86
SZ
1259 @param ProfileSize On input, profile buffer size.\r
1260 On output, actual profile data size copied.\r
1261 @param ProfileOffset On input, profile buffer offset to copy.\r
1262 On output, next time profile buffer offset to copy.\r
84edd20b
SZ
1263\r
1264**/\r
1265VOID\r
1266SmramProfileCopyData (\r
c3592c86
SZ
1267 OUT VOID *ProfileBuffer,\r
1268 IN OUT UINT64 *ProfileSize,\r
1269 IN OUT UINT64 *ProfileOffset\r
84edd20b
SZ
1270 )\r
1271{\r
1272 MEMORY_PROFILE_CONTEXT *Context;\r
1273 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
1274 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
1275 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1276 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
1277 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
1278 LIST_ENTRY *DriverInfoList;\r
1279 LIST_ENTRY *DriverLink;\r
1280 LIST_ENTRY *AllocInfoList;\r
1281 LIST_ENTRY *AllocLink;\r
1282 LIST_ENTRY *Node;\r
1283 FREE_PAGE_LIST *Pages;\r
1284 LIST_ENTRY *FreePageList;\r
1285 LIST_ENTRY *FreePoolList;\r
1286 FREE_POOL_HEADER *Pool;\r
1287 UINTN PoolListIndex;\r
1288 UINT32 Index;\r
1289 MEMORY_PROFILE_FREE_MEMORY *FreeMemory;\r
1290 MEMORY_PROFILE_MEMORY_RANGE *MemoryRange;\r
1291 MEMORY_PROFILE_DESCRIPTOR *MemoryProfileDescriptor;\r
c3592c86
SZ
1292 UINT64 Offset;\r
1293 UINT64 RemainingSize;\r
84edd20b
SZ
1294\r
1295 ContextData = GetSmramProfileContext ();\r
1296 if (ContextData == NULL) {\r
1297 return ;\r
1298 }\r
1299\r
c3592c86
SZ
1300 RemainingSize = *ProfileSize;\r
1301 Offset = 0;\r
1302\r
1303 if (*ProfileOffset < sizeof (MEMORY_PROFILE_CONTEXT)) {\r
1304 if (RemainingSize >= sizeof (MEMORY_PROFILE_CONTEXT)) {\r
1305 Context = ProfileBuffer;\r
1306 CopyMem (Context, &ContextData->Context, sizeof (MEMORY_PROFILE_CONTEXT));\r
1307 RemainingSize -= sizeof (MEMORY_PROFILE_CONTEXT);\r
1308 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_CONTEXT);\r
1309 } else {\r
1310 goto Done;\r
1311 }\r
1312 }\r
1313 Offset += sizeof (MEMORY_PROFILE_CONTEXT);\r
84edd20b
SZ
1314\r
1315 DriverInfoList = ContextData->DriverInfoList;\r
1316 for (DriverLink = DriverInfoList->ForwardLink;\r
1317 DriverLink != DriverInfoList;\r
1318 DriverLink = DriverLink->ForwardLink) {\r
1319 DriverInfoData = CR (\r
1320 DriverLink,\r
1321 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
1322 Link,\r
1323 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
1324 );\r
c3592c86
SZ
1325 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DRIVER_INFO))) {\r
1326 if (RemainingSize >= sizeof (MEMORY_PROFILE_DRIVER_INFO)) {\r
1327 DriverInfo = ProfileBuffer;\r
1328 CopyMem (DriverInfo, &DriverInfoData->DriverInfo, sizeof (MEMORY_PROFILE_DRIVER_INFO));\r
1329 RemainingSize -= sizeof (MEMORY_PROFILE_DRIVER_INFO);\r
1330 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DRIVER_INFO);\r
1331 } else {\r
1332 goto Done;\r
1333 }\r
1334 }\r
1335 Offset += sizeof (MEMORY_PROFILE_DRIVER_INFO);\r
84edd20b
SZ
1336\r
1337 AllocInfoList = DriverInfoData->AllocInfoList;\r
1338 for (AllocLink = AllocInfoList->ForwardLink;\r
1339 AllocLink != AllocInfoList;\r
1340 AllocLink = AllocLink->ForwardLink) {\r
1341 AllocInfoData = CR (\r
1342 AllocLink,\r
1343 MEMORY_PROFILE_ALLOC_INFO_DATA,\r
1344 Link,\r
1345 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE\r
1346 );\r
c3592c86
SZ
1347 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_ALLOC_INFO))) {\r
1348 if (RemainingSize >= sizeof (MEMORY_PROFILE_ALLOC_INFO)) {\r
1349 AllocInfo = ProfileBuffer;\r
1350 CopyMem (AllocInfo, &AllocInfoData->AllocInfo, sizeof (MEMORY_PROFILE_ALLOC_INFO));\r
1351 RemainingSize -= sizeof (MEMORY_PROFILE_ALLOC_INFO);\r
1352 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_ALLOC_INFO);\r
1353 } else {\r
1354 goto Done;\r
1355 }\r
1356 }\r
1357 Offset += sizeof (MEMORY_PROFILE_ALLOC_INFO);\r
84edd20b 1358 }\r
84edd20b
SZ
1359 }\r
1360\r
1361\r
c3592c86
SZ
1362 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_FREE_MEMORY))) {\r
1363 if (RemainingSize >= sizeof (MEMORY_PROFILE_FREE_MEMORY)) {\r
1364 FreeMemory = ProfileBuffer;\r
1365 CopyMem (FreeMemory, &mSmramFreeMemory, sizeof (MEMORY_PROFILE_FREE_MEMORY));\r
1366 Index = 0;\r
1367 FreePageList = &mSmmMemoryMap;\r
1368 for (Node = FreePageList->BackLink;\r
1369 Node != FreePageList;\r
1370 Node = Node->BackLink) {\r
1371 Index++;\r
1372 }\r
1373 for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {\r
1374 FreePoolList = &mSmmPoolLists[MAX_POOL_INDEX - PoolListIndex - 1];\r
1375 for (Node = FreePoolList->BackLink;\r
1376 Node != FreePoolList;\r
1377 Node = Node->BackLink) {\r
1378 Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);\r
1379 if (Pool->Header.Available) {\r
1380 Index++;\r
1381 }\r
1382 }\r
1383 }\r
1384 FreeMemory->FreeMemoryEntryCount = Index;\r
1385\r
1386 RemainingSize -= sizeof (MEMORY_PROFILE_FREE_MEMORY);\r
1387 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_FREE_MEMORY);\r
1388 } else {\r
1389 goto Done;\r
1390 }\r
1391 }\r
1392 Offset += sizeof (MEMORY_PROFILE_FREE_MEMORY);\r
84edd20b
SZ
1393 FreePageList = &mSmmMemoryMap;\r
1394 for (Node = FreePageList->BackLink;\r
1395 Node != FreePageList;\r
1396 Node = Node->BackLink) {\r
c3592c86
SZ
1397 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) {\r
1398 if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) {\r
1399 Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
1400 MemoryProfileDescriptor = ProfileBuffer;\r
1401 MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;\r
1402 MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1403 MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;\r
1404 MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pages;\r
1405 MemoryProfileDescriptor->Size = EFI_PAGES_TO_SIZE (Pages->NumberOfPages);\r
1406\r
1407 RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1408 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1409 } else {\r
1410 goto Done;\r
1411 }\r
1412 }\r
1413 Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
84edd20b
SZ
1414 }\r
1415 for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {\r
1416 FreePoolList = &mSmmPoolLists[MAX_POOL_INDEX - PoolListIndex - 1];\r
1417 for (Node = FreePoolList->BackLink;\r
1418 Node != FreePoolList;\r
1419 Node = Node->BackLink) {\r
1420 Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);\r
1421 if (Pool->Header.Available) {\r
c3592c86
SZ
1422 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) {\r
1423 if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) {\r
1424 MemoryProfileDescriptor = ProfileBuffer;\r
1425 MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;\r
1426 MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1427 MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;\r
1428 MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pool;\r
1429 MemoryProfileDescriptor->Size = Pool->Header.Size;\r
1430\r
1431 RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1432 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1433 } else {\r
1434 goto Done;\r
1435 }\r
1436 }\r
1437 Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1438 }\r
1439 }\r
1440 }\r
1441\r
1442 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_MEMORY_RANGE))) {\r
1443 if (RemainingSize >= sizeof (MEMORY_PROFILE_MEMORY_RANGE)) {\r
1444 MemoryRange = ProfileBuffer;\r
1445 MemoryRange->Header.Signature = MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE;\r
1446 MemoryRange->Header.Length = sizeof (MEMORY_PROFILE_MEMORY_RANGE);\r
1447 MemoryRange->Header.Revision = MEMORY_PROFILE_MEMORY_RANGE_REVISION;\r
1448 MemoryRange->MemoryRangeCount = (UINT32) mFullSmramRangeCount;\r
1449\r
1450 RemainingSize -= sizeof (MEMORY_PROFILE_MEMORY_RANGE);\r
1451 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_MEMORY_RANGE);\r
1452 } else {\r
1453 goto Done;\r
1454 }\r
1455 }\r
1456 Offset += sizeof (MEMORY_PROFILE_MEMORY_RANGE);\r
1457 for (Index = 0; Index < mFullSmramRangeCount; Index++) {\r
1458 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) {\r
1459 if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) {\r
1460 MemoryProfileDescriptor = ProfileBuffer;\r
84edd20b
SZ
1461 MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;\r
1462 MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1463 MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;\r
c3592c86
SZ
1464 MemoryProfileDescriptor->Address = mFullSmramRanges[Index].PhysicalStart;\r
1465 MemoryProfileDescriptor->Size = mFullSmramRanges[Index].PhysicalSize;\r
1466\r
1467 RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1468 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1469 } else {\r
1470 goto Done;\r
84edd20b
SZ
1471 }\r
1472 }\r
c3592c86 1473 Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
84edd20b 1474 }\r
84edd20b 1475\r
c3592c86
SZ
1476Done:\r
1477 //\r
1478 // On output, actual profile data size copied.\r
1479 //\r
1480 *ProfileSize -= RemainingSize;\r
1481 //\r
1482 // On output, next time profile buffer offset to copy.\r
1483 //\r
1484 *ProfileOffset = Offset;\r
84edd20b
SZ
1485}\r
1486\r
1487/**\r
1488 SMRAM profile handler to get profile info.\r
1489\r
1490 @param SmramProfileParameterGetInfo The parameter of SMM profile get size.\r
1491\r
1492**/\r
1493VOID\r
1494SmramProfileHandlerGetInfo (\r
1495 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *SmramProfileParameterGetInfo\r
1496 )\r
1497{\r
1498 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1499 BOOLEAN SmramProfileRecordingStatus;\r
1500\r
1501 ContextData = GetSmramProfileContext ();\r
1502 if (ContextData == NULL) {\r
1503 return ;\r
1504 }\r
1505\r
1506 SmramProfileRecordingStatus = mSmramProfileRecordingStatus;\r
1507 mSmramProfileRecordingStatus = FALSE;\r
1508\r
1509 SmramProfileParameterGetInfo->ProfileSize = SmramProfileGetDataSize();\r
1510 SmramProfileParameterGetInfo->Header.ReturnStatus = 0;\r
1511\r
1512 mSmramProfileRecordingStatus = SmramProfileRecordingStatus;\r
1513}\r
1514\r
1515/**\r
1516 SMRAM profile handler to get profile data.\r
1517\r
1518 @param SmramProfileParameterGetData The parameter of SMM profile get data.\r
1519\r
1520**/\r
1521VOID\r
1522SmramProfileHandlerGetData (\r
1523 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *SmramProfileParameterGetData\r
1524 )\r
1525{\r
1526 UINT64 ProfileSize;\r
c3592c86 1527 UINT64 ProfileOffset;\r
84edd20b
SZ
1528 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA SmramProfileGetData;\r
1529 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1530 BOOLEAN SmramProfileRecordingStatus;\r
1531\r
1532 ContextData = GetSmramProfileContext ();\r
1533 if (ContextData == NULL) {\r
1534 return ;\r
1535 }\r
1536\r
1537 SmramProfileRecordingStatus = mSmramProfileRecordingStatus;\r
1538 mSmramProfileRecordingStatus = FALSE;\r
1539\r
1540\r
1541 CopyMem (&SmramProfileGetData, SmramProfileParameterGetData, sizeof (SmramProfileGetData));\r
1542\r
1543 ProfileSize = SmramProfileGetDataSize();\r
1544\r
1545 //\r
1546 // Sanity check\r
1547 //\r
842b1242 1548 if (!SmmIsBufferOutsideSmmValid ((UINTN) SmramProfileGetData.ProfileBuffer, (UINTN) ProfileSize)) {\r
84edd20b
SZ
1549 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetData: SMM ProfileBuffer in SMRAM or overflow!\n"));\r
1550 SmramProfileParameterGetData->ProfileSize = ProfileSize;\r
1551 SmramProfileParameterGetData->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_ACCESS_DENIED;\r
1552 goto Done;\r
1553 }\r
1554\r
1555 if (SmramProfileGetData.ProfileSize < ProfileSize) {\r
1556 SmramProfileParameterGetData->ProfileSize = ProfileSize;\r
1557 SmramProfileParameterGetData->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_BUFFER_TOO_SMALL;\r
1558 goto Done;\r
1559 }\r
1560\r
c3592c86
SZ
1561 ProfileOffset = 0;\r
1562 SmramProfileCopyData ((VOID *) (UINTN) SmramProfileGetData.ProfileBuffer, &ProfileSize, &ProfileOffset);\r
84edd20b 1563 SmramProfileParameterGetData->ProfileSize = ProfileSize;\r
84edd20b
SZ
1564 SmramProfileParameterGetData->Header.ReturnStatus = 0;\r
1565\r
1566Done:\r
1567 mSmramProfileRecordingStatus = SmramProfileRecordingStatus;\r
1568}\r
1569\r
c3592c86
SZ
1570/**\r
1571 SMRAM profile handler to get profile data by offset.\r
1572\r
1573 @param SmramProfileParameterGetDataByOffset The parameter of SMM profile get data by offset.\r
1574\r
1575**/\r
1576VOID\r
1577SmramProfileHandlerGetDataByOffset (\r
1578 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *SmramProfileParameterGetDataByOffset\r
1579 )\r
1580{\r
1581 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET SmramProfileGetDataByOffset;\r
1582 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1583 BOOLEAN SmramProfileRecordingStatus;\r
1584\r
1585 ContextData = GetSmramProfileContext ();\r
1586 if (ContextData == NULL) {\r
1587 return ;\r
1588 }\r
1589\r
1590 SmramProfileRecordingStatus = mSmramProfileRecordingStatus;\r
1591 mSmramProfileRecordingStatus = FALSE;\r
1592\r
1593\r
1594 CopyMem (&SmramProfileGetDataByOffset, SmramProfileParameterGetDataByOffset, sizeof (SmramProfileGetDataByOffset));\r
1595\r
1596 //\r
1597 // Sanity check\r
1598 //\r
1599 if (!SmmIsBufferOutsideSmmValid ((UINTN) SmramProfileGetDataByOffset.ProfileBuffer, (UINTN) SmramProfileGetDataByOffset.ProfileSize)) {\r
1600 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetDataByOffset: SMM ProfileBuffer in SMRAM or overflow!\n"));\r
1601 SmramProfileParameterGetDataByOffset->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_ACCESS_DENIED;\r
1602 goto Done;\r
1603 }\r
1604\r
1605 SmramProfileCopyData ((VOID *) (UINTN) SmramProfileGetDataByOffset.ProfileBuffer, &SmramProfileGetDataByOffset.ProfileSize, &SmramProfileGetDataByOffset.ProfileOffset);\r
1606 CopyMem (SmramProfileParameterGetDataByOffset, &SmramProfileGetDataByOffset, sizeof (SmramProfileGetDataByOffset));\r
1607 SmramProfileParameterGetDataByOffset->Header.ReturnStatus = 0;\r
1608\r
1609Done:\r
1610 mSmramProfileRecordingStatus = SmramProfileRecordingStatus;\r
1611}\r
1612\r
84edd20b
SZ
1613/**\r
1614 SMRAM profile handler to register SMM image.\r
1615\r
1616 @param SmramProfileParameterRegisterImage The parameter of SMM profile register image.\r
1617\r
1618**/\r
1619VOID\r
1620SmramProfileHandlerRegisterImage (\r
1621 IN SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE *SmramProfileParameterRegisterImage\r
1622 )\r
1623{\r
1624 EFI_STATUS Status;\r
1625 EFI_SMM_DRIVER_ENTRY DriverEntry;\r
1626 VOID *EntryPointInImage;\r
1627 BOOLEAN Ret;\r
1628\r
1629 ZeroMem (&DriverEntry, sizeof (DriverEntry));\r
1630 CopyMem (&DriverEntry.FileName, &SmramProfileParameterRegisterImage->FileName, sizeof(EFI_GUID));\r
1631 DriverEntry.ImageBuffer = SmramProfileParameterRegisterImage->ImageBuffer;\r
1632 DriverEntry.NumberOfPage = (UINTN) SmramProfileParameterRegisterImage->NumberOfPage;\r
1633 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage);\r
1634 ASSERT_EFI_ERROR (Status);\r
1635 DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;\r
1636\r
1637 Ret = RegisterSmramProfileImage (&DriverEntry, FALSE);\r
1638 if (Ret) {\r
1639 SmramProfileParameterRegisterImage->Header.ReturnStatus = 0;\r
1640 }\r
1641}\r
1642\r
1643/**\r
1644 SMRAM profile handler to unregister SMM image.\r
1645\r
1646 @param SmramProfileParameterUnregisterImage The parameter of SMM profile unregister image.\r
1647\r
1648**/\r
1649VOID\r
1650SmramProfileHandlerUnregisterImage (\r
1651 IN SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE *SmramProfileParameterUnregisterImage\r
1652 )\r
1653{\r
1654 EFI_STATUS Status;\r
1655 EFI_SMM_DRIVER_ENTRY DriverEntry;\r
1656 VOID *EntryPointInImage;\r
1657 BOOLEAN Ret;\r
1658\r
1659 ZeroMem (&DriverEntry, sizeof (DriverEntry));\r
1660 CopyMem (&DriverEntry.FileName, &SmramProfileParameterUnregisterImage->FileName, sizeof (EFI_GUID));\r
1661 DriverEntry.ImageBuffer = SmramProfileParameterUnregisterImage->ImageBuffer;\r
1662 DriverEntry.NumberOfPage = (UINTN) SmramProfileParameterUnregisterImage->NumberOfPage;\r
1663 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage);\r
1664 ASSERT_EFI_ERROR (Status);\r
1665 DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;\r
1666\r
1667 Ret = UnregisterSmramProfileImage (&DriverEntry, FALSE);\r
1668 if (Ret) {\r
1669 SmramProfileParameterUnregisterImage->Header.ReturnStatus = 0;\r
1670 }\r
1671}\r
1672\r
1673/**\r
1674 Dispatch function for a Software SMI handler.\r
1675\r
1676 Caution: This function may receive untrusted input.\r
1677 Communicate buffer and buffer size are external input, so this function will do basic validation.\r
1678\r
1679 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
1680 @param Context Points to an optional handler context which was specified when the\r
1681 handler was registered.\r
1682 @param CommBuffer A pointer to a collection of data in memory that will\r
1683 be conveyed from a non-SMM environment into an SMM environment.\r
1684 @param CommBufferSize The size of the CommBuffer.\r
1685\r
1686 @retval EFI_SUCCESS Command is handled successfully.\r
1687\r
1688**/\r
1689EFI_STATUS\r
1690EFIAPI\r
1691SmramProfileHandler (\r
1692 IN EFI_HANDLE DispatchHandle,\r
1693 IN CONST VOID *Context OPTIONAL,\r
1694 IN OUT VOID *CommBuffer OPTIONAL,\r
1695 IN OUT UINTN *CommBufferSize OPTIONAL\r
1696 )\r
1697{\r
1698 SMRAM_PROFILE_PARAMETER_HEADER *SmramProfileParameterHeader;\r
1699 UINTN TempCommBufferSize;\r
1700\r
1701 DEBUG ((EFI_D_ERROR, "SmramProfileHandler Enter\n"));\r
1702\r
1703 //\r
1704 // If input is invalid, stop processing this SMI\r
1705 //\r
1706 if (CommBuffer == NULL || CommBufferSize == NULL) {\r
1707 return EFI_SUCCESS;\r
1708 }\r
1709\r
1710 TempCommBufferSize = *CommBufferSize;\r
1711\r
1712 if (TempCommBufferSize < sizeof (SMRAM_PROFILE_PARAMETER_HEADER)) {\r
1713 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
1714 return EFI_SUCCESS;\r
1715 }\r
1716\r
842b1242 1717 if (mSmramReadyToLock && !SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
84edd20b
SZ
1718 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer in SMRAM or overflow!\n"));\r
1719 return EFI_SUCCESS;\r
1720 }\r
1721\r
1722 SmramProfileParameterHeader = (SMRAM_PROFILE_PARAMETER_HEADER *) ((UINTN) CommBuffer);\r
1723\r
1724 SmramProfileParameterHeader->ReturnStatus = (UINT64)-1;\r
1725\r
1726 if (GetSmramProfileContext () == NULL) {\r
1727 SmramProfileParameterHeader->ReturnStatus = (UINT64) (INT64) (INTN) EFI_UNSUPPORTED;\r
1728 return EFI_SUCCESS;\r
1729 }\r
1730\r
1731 switch (SmramProfileParameterHeader->Command) {\r
1732 case SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO:\r
1733 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetInfo\n"));\r
1734 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO)) {\r
1735 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
1736 return EFI_SUCCESS;\r
1737 }\r
1738 SmramProfileHandlerGetInfo ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) (UINTN) CommBuffer);\r
1739 break;\r
1740 case SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA:\r
1741 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetData\n"));\r
1742 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA)) {\r
1743 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
1744 return EFI_SUCCESS;\r
1745 }\r
1746 SmramProfileHandlerGetData ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *) (UINTN) CommBuffer);\r
1747 break;\r
c3592c86
SZ
1748 case SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET:\r
1749 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetDataByOffset\n"));\r
1750 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET)) {\r
1751 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
1752 return EFI_SUCCESS;\r
1753 }\r
1754 SmramProfileHandlerGetDataByOffset ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) (UINTN) CommBuffer);\r
1755 break;\r
84edd20b
SZ
1756 case SMRAM_PROFILE_COMMAND_REGISTER_IMAGE:\r
1757 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerRegisterImage\n"));\r
1758 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE)) {\r
1759 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
1760 return EFI_SUCCESS;\r
1761 }\r
1762 if (mSmramReadyToLock) {\r
1763 return EFI_SUCCESS;\r
1764 }\r
1765 SmramProfileHandlerRegisterImage ((SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE *) (UINTN) CommBuffer);\r
1766 break;\r
1767 case SMRAM_PROFILE_COMMAND_UNREGISTER_IMAGE:\r
1768 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerUnregisterImage\n"));\r
1769 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE)) {\r
1770 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
1771 return EFI_SUCCESS;\r
1772 }\r
1773 if (mSmramReadyToLock) {\r
1774 return EFI_SUCCESS;\r
1775 }\r
1776 SmramProfileHandlerUnregisterImage ((SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE *) (UINTN) CommBuffer);\r
1777 break;\r
1778 default:\r
1779 break;\r
1780 }\r
1781\r
1782 DEBUG ((EFI_D_ERROR, "SmramProfileHandler Exit\n"));\r
1783\r
1784 return EFI_SUCCESS;\r
1785}\r
1786\r
1787/**\r
1788 Register SMRAM profile handler.\r
1789\r
1790**/\r
1791VOID\r
1792RegisterSmramProfileHandler (\r
1793 VOID\r
1794 )\r
1795{\r
1796 EFI_STATUS Status;\r
1797 EFI_HANDLE DispatchHandle;\r
1798\r
1799 if (!IS_SMRAM_PROFILE_ENABLED) {\r
1800 return;\r
1801 }\r
1802\r
1803 Status = SmiHandlerRegister (\r
1804 SmramProfileHandler,\r
1805 &gEdkiiMemoryProfileGuid,\r
1806 &DispatchHandle\r
1807 );\r
1808 ASSERT_EFI_ERROR (Status);\r
1809}\r
1810\r
1811////////////////////\r
1812\r
1813/**\r
1814 Dump SMRAM range.\r
1815\r
1816**/\r
1817VOID\r
1818DumpSmramRange (\r
1819 VOID\r
1820 )\r
1821{\r
1822 UINTN Index;\r
1823 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1824 BOOLEAN SmramProfileRecordingStatus;\r
1825\r
1826 ContextData = GetSmramProfileContext ();\r
1827 if (ContextData == NULL) {\r
1828 return ;\r
1829 }\r
1830\r
1831 SmramProfileRecordingStatus = mSmramProfileRecordingStatus;\r
1832 mSmramProfileRecordingStatus = FALSE;\r
1833\r
1834 DEBUG ((EFI_D_INFO, "FullSmramRange address - 0x%08x\n", mFullSmramRanges));\r
1835\r
1836 DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n"));\r
1837\r
1838 DEBUG ((EFI_D_INFO, "FullSmramRange:\n"));\r
1839 for (Index = 0; Index < mFullSmramRangeCount; Index++) {\r
1840 DEBUG ((EFI_D_INFO, " FullSmramRange (0x%x)\n", Index));\r
1841 DEBUG ((EFI_D_INFO, " PhysicalStart - 0x%016lx\n", mFullSmramRanges[Index].PhysicalStart));\r
1842 DEBUG ((EFI_D_INFO, " CpuStart - 0x%016lx\n", mFullSmramRanges[Index].CpuStart));\r
1843 DEBUG ((EFI_D_INFO, " PhysicalSize - 0x%016lx\n", mFullSmramRanges[Index].PhysicalSize));\r
1844 DEBUG ((EFI_D_INFO, " RegionState - 0x%016lx\n", mFullSmramRanges[Index].RegionState));\r
1845 }\r
1846\r
1847 DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n"));\r
1848\r
1849 mSmramProfileRecordingStatus = SmramProfileRecordingStatus;\r
1850}\r
1851\r
1852/**\r
1853 Dump SMRAM free page list.\r
1854\r
1855**/\r
1856VOID\r
1857DumpFreePagesList (\r
1858 VOID\r
1859 )\r
1860{\r
1861 LIST_ENTRY *FreePageList;\r
1862 LIST_ENTRY *Node;\r
1863 FREE_PAGE_LIST *Pages;\r
1864 UINTN Index;\r
1865 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1866 BOOLEAN SmramProfileRecordingStatus;\r
1867\r
1868 ContextData = GetSmramProfileContext ();\r
1869 if (ContextData == NULL) {\r
1870 return ;\r
1871 }\r
1872\r
1873 SmramProfileRecordingStatus = mSmramProfileRecordingStatus;\r
1874 mSmramProfileRecordingStatus = FALSE;\r
1875\r
1876 DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n"));\r
1877\r
1878 DEBUG ((EFI_D_INFO, "FreePagesList:\n"));\r
1879 FreePageList = &mSmmMemoryMap;\r
1880 for (Node = FreePageList->BackLink, Index = 0;\r
1881 Node != FreePageList;\r
1882 Node = Node->BackLink, Index++) {\r
1883 Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
1884 DEBUG ((EFI_D_INFO, " Index - 0x%x\n", Index));\r
1885 DEBUG ((EFI_D_INFO, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS) (UINTN) Pages));\r
1886 DEBUG ((EFI_D_INFO, " NumberOfPages - 0x%08x\n", Pages->NumberOfPages));\r
1887 }\r
1888\r
1889 DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n"));\r
1890\r
1891 mSmramProfileRecordingStatus = SmramProfileRecordingStatus;\r
1892}\r
1893\r
1894/**\r
1895 Dump SMRAM free pool list.\r
1896\r
1897**/\r
1898VOID\r
1899DumpFreePoolList (\r
1900 VOID\r
1901 )\r
1902{\r
1903 LIST_ENTRY *FreePoolList;\r
1904 LIST_ENTRY *Node;\r
1905 FREE_POOL_HEADER *Pool;\r
1906 UINTN Index;\r
1907 UINTN PoolListIndex;\r
1908 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1909 BOOLEAN SmramProfileRecordingStatus;\r
1910\r
1911 ContextData = GetSmramProfileContext ();\r
1912 if (ContextData == NULL) {\r
1913 return ;\r
1914 }\r
1915\r
1916 SmramProfileRecordingStatus = mSmramProfileRecordingStatus;\r
1917 mSmramProfileRecordingStatus = FALSE;\r
1918\r
1919 DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n"));\r
1920\r
1921 for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {\r
1922 DEBUG ((EFI_D_INFO, "FreePoolList (%d):\n", PoolListIndex));\r
1923 FreePoolList = &mSmmPoolLists[PoolListIndex];\r
1924 for (Node = FreePoolList->BackLink, Index = 0;\r
1925 Node != FreePoolList;\r
1926 Node = Node->BackLink, Index++) {\r
1927 Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);\r
1928 DEBUG ((EFI_D_INFO, " Index - 0x%x\n", Index));\r
1929 DEBUG ((EFI_D_INFO, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS) (UINTN) Pool));\r
1930 DEBUG ((EFI_D_INFO, " Size - 0x%08x\n", Pool->Header.Size));\r
1931 DEBUG ((EFI_D_INFO, " Available - 0x%02x\n", Pool->Header.Available));\r
1932 }\r
1933 }\r
1934\r
1935 DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n"));\r
1936\r
1937 mSmramProfileRecordingStatus = SmramProfileRecordingStatus;\r
1938}\r
1939\r
1940GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mActionString[] = {\r
1941 L"Unknown",\r
1942 L"AllocatePages",\r
1943 L"FreePages",\r
1944 L"AllocatePool",\r
1945 L"FreePool",\r
1946};\r
1947\r
ca949d9d
SZ
1948typedef struct {\r
1949 EFI_MEMORY_TYPE MemoryType;\r
1950 CHAR16 *MemoryTypeStr;\r
1951} PROFILE_MEMORY_TYPE_STRING;\r
1952\r
1953GLOBAL_REMOVE_IF_UNREFERENCED PROFILE_MEMORY_TYPE_STRING mMemoryTypeString[] = {\r
1954 {EfiRuntimeServicesCode, L"EfiRuntimeServicesCode"},\r
1955 {EfiRuntimeServicesData, L"EfiRuntimeServicesData"}\r
84edd20b
SZ
1956};\r
1957\r
ca949d9d
SZ
1958/**\r
1959 Memory type to string.\r
1960\r
1961 @param[in] MemoryType Memory type.\r
1962\r
1963 @return Pointer to string.\r
1964\r
1965**/\r
1966CHAR16 *\r
1967ProfileMemoryTypeToStr (\r
1968 IN EFI_MEMORY_TYPE MemoryType\r
1969 )\r
1970{\r
1971 UINTN Index;\r
1972 for (Index = 0; Index < sizeof (mMemoryTypeString) / sizeof (mMemoryTypeString[0]); Index++) {\r
1973 if (mMemoryTypeString[Index].MemoryType == MemoryType) {\r
1974 return mMemoryTypeString[Index].MemoryTypeStr;\r
1975 }\r
1976 }\r
1977\r
1978 return L"UnexpectedMemoryType";\r
1979}\r
84edd20b
SZ
1980\r
1981/**\r
1982 Dump SMRAM profile.\r
1983\r
1984**/\r
1985VOID\r
1986DumpSmramProfile (\r
1987 VOID\r
1988 )\r
1989{\r
1990 MEMORY_PROFILE_CONTEXT *Context;\r
1991 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
1992 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
1993 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1994 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
1995 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
1996 LIST_ENTRY *SmramDriverInfoList;\r
1997 UINTN DriverIndex;\r
1998 LIST_ENTRY *DriverLink;\r
1999 LIST_ENTRY *AllocInfoList;\r
2000 UINTN AllocIndex;\r
2001 LIST_ENTRY *AllocLink;\r
2002 BOOLEAN SmramProfileRecordingStatus;\r
2003 UINTN TypeIndex;\r
2004\r
2005 ContextData = GetSmramProfileContext ();\r
2006 if (ContextData == NULL) {\r
2007 return ;\r
2008 }\r
2009\r
2010 SmramProfileRecordingStatus = mSmramProfileRecordingStatus;\r
2011 mSmramProfileRecordingStatus = FALSE;\r
2012\r
2013 Context = &ContextData->Context;\r
2014 DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n"));\r
2015 DEBUG ((EFI_D_INFO, "MEMORY_PROFILE_CONTEXT\n"));\r
2016\r
2017 DEBUG ((EFI_D_INFO, " CurrentTotalUsage - 0x%016lx\n", Context->CurrentTotalUsage));\r
2018 DEBUG ((EFI_D_INFO, " PeakTotalUsage - 0x%016lx\n", Context->PeakTotalUsage));\r
ca949d9d 2019 for (TypeIndex = 0; TypeIndex < sizeof (Context->CurrentTotalUsageByType) / sizeof (Context->CurrentTotalUsageByType[0]); TypeIndex++) {\r
84edd20b
SZ
2020 if ((Context->CurrentTotalUsageByType[TypeIndex] != 0) ||\r
2021 (Context->PeakTotalUsageByType[TypeIndex] != 0)) {\r
ca949d9d
SZ
2022 DEBUG ((EFI_D_INFO, " CurrentTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex, Context->CurrentTotalUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex)));\r
2023 DEBUG ((EFI_D_INFO, " PeakTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex, Context->PeakTotalUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex)));\r
84edd20b
SZ
2024 }\r
2025 }\r
2026 DEBUG ((EFI_D_INFO, " TotalImageSize - 0x%016lx\n", Context->TotalImageSize));\r
2027 DEBUG ((EFI_D_INFO, " ImageCount - 0x%08x\n", Context->ImageCount));\r
2028 DEBUG ((EFI_D_INFO, " SequenceCount - 0x%08x\n", Context->SequenceCount));\r
2029\r
2030 SmramDriverInfoList = ContextData->DriverInfoList;\r
2031 for (DriverLink = SmramDriverInfoList->ForwardLink, DriverIndex = 0;\r
2032 DriverLink != SmramDriverInfoList;\r
2033 DriverLink = DriverLink->ForwardLink, DriverIndex++) {\r
2034 DriverInfoData = CR (\r
2035 DriverLink,\r
2036 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
2037 Link,\r
2038 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
2039 );\r
2040 DriverInfo = &DriverInfoData->DriverInfo;\r
2041 DEBUG ((EFI_D_INFO, " MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex));\r
2042 DEBUG ((EFI_D_INFO, " FileName - %g\n", &DriverInfo->FileName));\r
2043 DEBUG ((EFI_D_INFO, " ImageBase - 0x%016lx\n", DriverInfo->ImageBase));\r
2044 DEBUG ((EFI_D_INFO, " ImageSize - 0x%016lx\n", DriverInfo->ImageSize));\r
2045 DEBUG ((EFI_D_INFO, " EntryPoint - 0x%016lx\n", DriverInfo->EntryPoint));\r
2046 DEBUG ((EFI_D_INFO, " ImageSubsystem - 0x%04x\n", DriverInfo->ImageSubsystem));\r
2047 DEBUG ((EFI_D_INFO, " FileType - 0x%02x\n", DriverInfo->FileType));\r
2048 DEBUG ((EFI_D_INFO, " CurrentUsage - 0x%016lx\n", DriverInfo->CurrentUsage));\r
2049 DEBUG ((EFI_D_INFO, " PeakUsage - 0x%016lx\n", DriverInfo->PeakUsage));\r
ca949d9d 2050 for (TypeIndex = 0; TypeIndex < sizeof (DriverInfo->CurrentUsageByType) / sizeof (DriverInfo->CurrentUsageByType[0]); TypeIndex++) {\r
84edd20b
SZ
2051 if ((DriverInfo->CurrentUsageByType[TypeIndex] != 0) ||\r
2052 (DriverInfo->PeakUsageByType[TypeIndex] != 0)) {\r
ca949d9d
SZ
2053 DEBUG ((EFI_D_INFO, " CurrentUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex, DriverInfo->CurrentUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex)));\r
2054 DEBUG ((EFI_D_INFO, " PeakUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex, DriverInfo->PeakUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex)));\r
84edd20b
SZ
2055 }\r
2056 }\r
2057 DEBUG ((EFI_D_INFO, " AllocRecordCount - 0x%08x\n", DriverInfo->AllocRecordCount));\r
2058\r
2059 AllocInfoList = DriverInfoData->AllocInfoList;\r
2060 for (AllocLink = AllocInfoList->ForwardLink, AllocIndex = 0;\r
2061 AllocLink != AllocInfoList;\r
2062 AllocLink = AllocLink->ForwardLink, AllocIndex++) {\r
2063 AllocInfoData = CR (\r
2064 AllocLink,\r
2065 MEMORY_PROFILE_ALLOC_INFO_DATA,\r
2066 Link,\r
2067 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE\r
2068 );\r
2069 AllocInfo = &AllocInfoData->AllocInfo;\r
2070 DEBUG ((EFI_D_INFO, " MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex));\r
2071 DEBUG ((EFI_D_INFO, " CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo->CallerAddress, AllocInfo->CallerAddress - DriverInfo->ImageBase));\r
2072 DEBUG ((EFI_D_INFO, " SequenceId - 0x%08x\n", AllocInfo->SequenceId));\r
2073 DEBUG ((EFI_D_INFO, " Action - 0x%08x (%s)\n", AllocInfo->Action, mActionString[(AllocInfo->Action < sizeof(mActionString)/sizeof(mActionString[0])) ? AllocInfo->Action : 0]));\r
2074 DEBUG ((EFI_D_INFO, " MemoryType - 0x%08x\n", AllocInfo->MemoryType));\r
2075 DEBUG ((EFI_D_INFO, " Buffer - 0x%016lx\n", AllocInfo->Buffer));\r
2076 DEBUG ((EFI_D_INFO, " Size - 0x%016lx\n", AllocInfo->Size));\r
2077 }\r
2078 }\r
2079\r
2080 DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n"));\r
2081\r
2082 mSmramProfileRecordingStatus = SmramProfileRecordingStatus;\r
2083}\r
2084\r
2085/**\r
2086 Dump SMRAM infromation.\r
2087\r
2088**/\r
2089VOID\r
2090DumpSmramInfo (\r
2091 VOID\r
2092 )\r
2093{\r
2094 DEBUG_CODE (\r
2095 if (IS_SMRAM_PROFILE_ENABLED) {\r
2096 DumpSmramProfile ();\r
2097 DumpFreePagesList ();\r
2098 DumpFreePoolList ();\r
2099 DumpSmramRange ();\r
2100 }\r
2101 );\r
2102}\r
2103\r