]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c
MdeModulePkg/Core/PiSmmCore: Fix various typos
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / SmramProfileRecord.c
CommitLineData
84edd20b
SZ
1/** @file\r
2 Support routines for SMRAM profile.\r
3\r
d1102dba 4 Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
84edd20b
SZ
6\r
7**/\r
8\r
9#include "PiSmmCore.h"\r
10\r
11#define IS_SMRAM_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT1) != 0)\r
e524f680
SZ
12#define IS_UEFI_MEMORY_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0)\r
13\r
14#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \\r
15 ((ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)))\r
84edd20b
SZ
16\r
17typedef struct {\r
18 UINT32 Signature;\r
19 MEMORY_PROFILE_CONTEXT Context;\r
20 LIST_ENTRY *DriverInfoList;\r
21} MEMORY_PROFILE_CONTEXT_DATA;\r
22\r
23typedef struct {\r
24 UINT32 Signature;\r
25 MEMORY_PROFILE_DRIVER_INFO DriverInfo;\r
26 LIST_ENTRY *AllocInfoList;\r
e524f680 27 CHAR8 *PdbString;\r
84edd20b
SZ
28 LIST_ENTRY Link;\r
29} MEMORY_PROFILE_DRIVER_INFO_DATA;\r
30\r
31typedef struct {\r
32 UINT32 Signature;\r
33 MEMORY_PROFILE_ALLOC_INFO AllocInfo;\r
e524f680 34 CHAR8 *ActionString;\r
84edd20b
SZ
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 73\r
6e6ceae6
SZ
74GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmramReadyToLock;\r
75GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmramProfileGettingStatus = FALSE;\r
76GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmramProfileRecordingEnable = MEMORY_PROFILE_RECORDING_DISABLE;\r
77GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_PROTOCOL *mSmramProfileDriverPath;\r
78GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmramProfileDriverPathSize;\r
84edd20b 79\r
63aa86b0 80/**\r
4be497df 81 Dump SMRAM information.\r
63aa86b0
SZ
82\r
83**/\r
84VOID\r
85DumpSmramInfo (\r
86 VOID\r
87 );\r
88\r
e524f680
SZ
89/**\r
90 Get memory profile data.\r
91\r
92 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
93 @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer.\r
94 On return, points to the size of the data returned in ProfileBuffer.\r
95 @param[out] ProfileBuffer Profile buffer.\r
d1102dba 96\r
e524f680
SZ
97 @return EFI_SUCCESS Get the memory profile data successfully.\r
98 @return EFI_UNSUPPORTED Memory profile is unsupported.\r
d1102dba 99 @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data.\r
e524f680
SZ
100 ProfileSize is updated with the size required.\r
101\r
102**/\r
103EFI_STATUS\r
104EFIAPI\r
105SmramProfileProtocolGetData (\r
106 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
107 IN OUT UINT64 *ProfileSize,\r
108 OUT VOID *ProfileBuffer\r
109 );\r
110\r
111/**\r
112 Register image to memory profile.\r
113\r
114 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
115 @param[in] FilePath File path of the image.\r
116 @param[in] ImageBase Image base address.\r
117 @param[in] ImageSize Image size.\r
118 @param[in] FileType File type of the image.\r
119\r
120 @return EFI_SUCCESS Register successfully.\r
121 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
122 or memory profile for the image is not required.\r
123 @return EFI_OUT_OF_RESOURCE No enough resource for this register.\r
124\r
125**/\r
126EFI_STATUS\r
127EFIAPI\r
128SmramProfileProtocolRegisterImage (\r
129 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
130 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
131 IN PHYSICAL_ADDRESS ImageBase,\r
132 IN UINT64 ImageSize,\r
133 IN EFI_FV_FILETYPE FileType\r
134 );\r
135\r
136/**\r
137 Unregister image from memory profile.\r
138\r
139 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
140 @param[in] FilePath File path of the image.\r
141 @param[in] ImageBase Image base address.\r
142 @param[in] ImageSize Image size.\r
143\r
144 @return EFI_SUCCESS Unregister successfully.\r
145 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
146 or memory profile for the image is not required.\r
147 @return EFI_NOT_FOUND The image is not found.\r
148\r
149**/\r
150EFI_STATUS\r
151EFIAPI\r
152SmramProfileProtocolUnregisterImage (\r
153 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
154 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
155 IN PHYSICAL_ADDRESS ImageBase,\r
156 IN UINT64 ImageSize\r
157 );\r
158\r
159/**\r
160 Get memory profile recording state.\r
161\r
162 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
163 @param[out] RecordingState Recording state.\r
164\r
165 @return EFI_SUCCESS Memory profile recording state is returned.\r
166 @return EFI_UNSUPPORTED Memory profile is unsupported.\r
167 @return EFI_INVALID_PARAMETER RecordingState is NULL.\r
168\r
169**/\r
170EFI_STATUS\r
171EFIAPI\r
172SmramProfileProtocolGetRecordingState (\r
173 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
174 OUT BOOLEAN *RecordingState\r
175 );\r
176\r
177/**\r
178 Set memory profile recording state.\r
179\r
180 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
181 @param[in] RecordingState Recording state.\r
182\r
183 @return EFI_SUCCESS Set memory profile recording state successfully.\r
184 @return EFI_UNSUPPORTED Memory profile is unsupported.\r
185\r
186**/\r
187EFI_STATUS\r
188EFIAPI\r
189SmramProfileProtocolSetRecordingState (\r
190 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
191 IN BOOLEAN RecordingState\r
192 );\r
193\r
194/**\r
195 Record memory profile of multilevel caller.\r
196\r
197 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
198 @param[in] CallerAddress Address of caller.\r
199 @param[in] Action Memory profile action.\r
200 @param[in] MemoryType Memory type.\r
201 EfiMaxMemoryType means the MemoryType is unknown.\r
202 @param[in] Buffer Buffer address.\r
203 @param[in] Size Buffer size.\r
204 @param[in] ActionString String for memory profile action.\r
205 Only needed for user defined allocate action.\r
206\r
207 @return EFI_SUCCESS Memory profile is updated.\r
208 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
209 or memory profile for the image is not required,\r
210 or memory profile for the memory type is not required.\r
211 @return EFI_ACCESS_DENIED It is during memory profile data getting.\r
212 @return EFI_ABORTED Memory profile recording is not enabled.\r
213 @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action.\r
214 @return EFI_NOT_FOUND No matched allocate info found for free action.\r
215\r
216**/\r
217EFI_STATUS\r
218EFIAPI\r
219SmramProfileProtocolRecord (\r
220 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
221 IN PHYSICAL_ADDRESS CallerAddress,\r
222 IN MEMORY_PROFILE_ACTION Action,\r
223 IN EFI_MEMORY_TYPE MemoryType,\r
224 IN VOID *Buffer,\r
225 IN UINTN Size,\r
226 IN CHAR8 *ActionString OPTIONAL\r
227 );\r
228\r
6e6ceae6 229GLOBAL_REMOVE_IF_UNREFERENCED EDKII_SMM_MEMORY_PROFILE_PROTOCOL mSmmProfileProtocol = {\r
e524f680
SZ
230 SmramProfileProtocolGetData,\r
231 SmramProfileProtocolRegisterImage,\r
232 SmramProfileProtocolUnregisterImage,\r
233 SmramProfileProtocolGetRecordingState,\r
234 SmramProfileProtocolSetRecordingState,\r
235 SmramProfileProtocolRecord,\r
236};\r
237\r
84edd20b
SZ
238/**\r
239 Return SMRAM profile context.\r
240\r
241 @return SMRAM profile context.\r
242\r
243**/\r
244MEMORY_PROFILE_CONTEXT_DATA *\r
245GetSmramProfileContext (\r
246 VOID\r
247 )\r
248{\r
249 return mSmramProfileContextPtr;\r
250}\r
251\r
84edd20b
SZ
252/**\r
253 Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.\r
254 If Pe32Data is NULL, then ASSERT().\r
255\r
256 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.\r
257\r
258 @return The Subsystem of the PE/COFF image.\r
259\r
260**/\r
261UINT16\r
262InternalPeCoffGetSubsystem (\r
263 IN VOID *Pe32Data\r
264 )\r
265{\r
266 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
267 EFI_IMAGE_DOS_HEADER *DosHdr;\r
268 UINT16 Magic;\r
269\r
270 ASSERT (Pe32Data != NULL);\r
271\r
272 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;\r
273 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
274 //\r
275 // DOS image header is present, so read the PE header after the DOS image header.\r
276 //\r
277 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
278 } else {\r
279 //\r
280 // DOS image header is not present, so PE header is at the image base.\r
281 //\r
282 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data;\r
283 }\r
284\r
285 if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
286 return Hdr.Te->Subsystem;\r
287 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
05cfd73f 288 Magic = Hdr.Pe32->OptionalHeader.Magic;\r
84edd20b
SZ
289 if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
290 return Hdr.Pe32->OptionalHeader.Subsystem;\r
291 } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
292 return Hdr.Pe32Plus->OptionalHeader.Subsystem;\r
293 }\r
294 }\r
295\r
296 return 0x0000;\r
297}\r
298\r
299/**\r
300 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded\r
301 into system memory with the PE/COFF Loader Library functions.\r
302\r
303 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry\r
304 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then\r
305 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.\r
306 If Pe32Data is NULL, then ASSERT().\r
307 If EntryPoint is NULL, then ASSERT().\r
308\r
309 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.\r
310 @param EntryPoint The pointer to entry point to the PE/COFF image to return.\r
311\r
312 @retval RETURN_SUCCESS EntryPoint was returned.\r
313 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.\r
314\r
315**/\r
316RETURN_STATUS\r
317InternalPeCoffGetEntryPoint (\r
318 IN VOID *Pe32Data,\r
319 OUT VOID **EntryPoint\r
320 )\r
321{\r
322 EFI_IMAGE_DOS_HEADER *DosHdr;\r
323 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
324\r
325 ASSERT (Pe32Data != NULL);\r
326 ASSERT (EntryPoint != NULL);\r
327\r
328 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;\r
329 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
330 //\r
331 // DOS image header is present, so read the PE header after the DOS image header.\r
332 //\r
333 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
334 } else {\r
335 //\r
336 // DOS image header is not present, so PE header is at the image base.\r
337 //\r
338 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data;\r
339 }\r
340\r
341 //\r
342 // Calculate the entry point relative to the start of the image.\r
343 // AddressOfEntryPoint is common for PE32 & PE32+\r
344 //\r
345 if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
346 *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);\r
347 return RETURN_SUCCESS;\r
348 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
349 *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));\r
350 return RETURN_SUCCESS;\r
351 }\r
352\r
353 return RETURN_UNSUPPORTED;\r
354}\r
355\r
356/**\r
357 Build driver info.\r
358\r
359 @param ContextData Memory profile context.\r
360 @param FileName File name of the image.\r
361 @param ImageBase Image base address.\r
362 @param ImageSize Image size.\r
363 @param EntryPoint Entry point of the image.\r
364 @param ImageSubsystem Image subsystem of the image.\r
84edd20b
SZ
365 @param FileType File type of the image.\r
366\r
367 @return Pointer to memory profile driver info.\r
368\r
369**/\r
370MEMORY_PROFILE_DRIVER_INFO_DATA *\r
371BuildDriverInfo (\r
372 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,\r
373 IN EFI_GUID *FileName,\r
374 IN PHYSICAL_ADDRESS ImageBase,\r
375 IN UINT64 ImageSize,\r
376 IN PHYSICAL_ADDRESS EntryPoint,\r
377 IN UINT16 ImageSubsystem,\r
378 IN EFI_FV_FILETYPE FileType\r
379 )\r
380{\r
381 EFI_STATUS Status;\r
382 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
383 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
384 VOID *EntryPointInImage;\r
e524f680
SZ
385 CHAR8 *PdbString;\r
386 UINTN PdbSize;\r
387 UINTN PdbOccupiedSize;\r
388\r
389 PdbSize = 0;\r
390 PdbOccupiedSize = 0;\r
391 PdbString = NULL;\r
392 if (ImageBase != 0) {\r
393 PdbString = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageBase);\r
394 if (PdbString != NULL) {\r
395 PdbSize = AsciiStrSize (PdbString);\r
396 PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64));\r
397 }\r
398 }\r
84edd20b
SZ
399\r
400 //\r
401 // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action.\r
402 //\r
403 Status = SmmInternalAllocatePool (\r
404 EfiRuntimeServicesData,\r
e524f680 405 sizeof (*DriverInfoData) + sizeof (LIST_ENTRY) + PdbSize,\r
84edd20b
SZ
406 (VOID **) &DriverInfoData\r
407 );\r
408 if (EFI_ERROR (Status)) {\r
409 return NULL;\r
410 }\r
d8162f5b 411 ASSERT (DriverInfoData != NULL);\r
84edd20b
SZ
412\r
413 ZeroMem (DriverInfoData, sizeof (*DriverInfoData));\r
414\r
415 DriverInfo = &DriverInfoData->DriverInfo;\r
416 DriverInfoData->Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE;\r
417 DriverInfo->Header.Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE;\r
e524f680 418 DriverInfo->Header.Length = (UINT16) (sizeof (MEMORY_PROFILE_DRIVER_INFO) + PdbOccupiedSize);\r
84edd20b
SZ
419 DriverInfo->Header.Revision = MEMORY_PROFILE_DRIVER_INFO_REVISION;\r
420 if (FileName != NULL) {\r
421 CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID));\r
422 }\r
423 DriverInfo->ImageBase = ImageBase;\r
424 DriverInfo->ImageSize = ImageSize;\r
425 DriverInfo->EntryPoint = EntryPoint;\r
426 DriverInfo->ImageSubsystem = ImageSubsystem;\r
427 if ((EntryPoint != 0) && ((EntryPoint < ImageBase) || (EntryPoint >= (ImageBase + ImageSize)))) {\r
428 //\r
429 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.\r
430 // So patch ImageBuffer here to align the EntryPoint.\r
431 //\r
432 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageBase, &EntryPointInImage);\r
433 ASSERT_EFI_ERROR (Status);\r
434 DriverInfo->ImageBase = ImageBase + EntryPoint - (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;\r
435 }\r
436 DriverInfo->FileType = FileType;\r
437 DriverInfoData->AllocInfoList = (LIST_ENTRY *) (DriverInfoData + 1);\r
438 InitializeListHead (DriverInfoData->AllocInfoList);\r
439 DriverInfo->CurrentUsage = 0;\r
440 DriverInfo->PeakUsage = 0;\r
441 DriverInfo->AllocRecordCount = 0;\r
e524f680
SZ
442 if (PdbSize != 0) {\r
443 DriverInfo->PdbStringOffset = (UINT16) sizeof (MEMORY_PROFILE_DRIVER_INFO);\r
444 DriverInfoData->PdbString = (CHAR8 *) (DriverInfoData->AllocInfoList + 1);\r
445 CopyMem (DriverInfoData->PdbString, PdbString, PdbSize);\r
446 } else {\r
447 DriverInfo->PdbStringOffset = 0;\r
448 DriverInfoData->PdbString = NULL;\r
449 }\r
84edd20b
SZ
450\r
451 InsertTailList (ContextData->DriverInfoList, &DriverInfoData->Link);\r
452 ContextData->Context.ImageCount ++;\r
453 ContextData->Context.TotalImageSize += DriverInfo->ImageSize;\r
454\r
455 return DriverInfoData;\r
456}\r
457\r
458/**\r
459 Register image to DXE.\r
460\r
461 @param FileName File name of the image.\r
462 @param ImageBase Image base address.\r
463 @param ImageSize Image size.\r
464 @param FileType File type of the image.\r
465\r
466**/\r
467VOID\r
468RegisterImageToDxe (\r
469 IN EFI_GUID *FileName,\r
470 IN PHYSICAL_ADDRESS ImageBase,\r
471 IN UINT64 ImageSize,\r
472 IN EFI_FV_FILETYPE FileType\r
473 )\r
474{\r
475 EFI_STATUS Status;\r
476 EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol;\r
477 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;\r
478 UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];\r
479\r
e524f680 480 if (IS_UEFI_MEMORY_PROFILE_ENABLED) {\r
84edd20b
SZ
481\r
482 FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;\r
483 Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **) &ProfileProtocol);\r
484 if (!EFI_ERROR (Status)) {\r
485 EfiInitializeFwVolDevicepathNode (FilePath, FileName);\r
486 SetDevicePathEndNode (FilePath + 1);\r
487\r
488 Status = ProfileProtocol->RegisterImage (\r
489 ProfileProtocol,\r
490 (EFI_DEVICE_PATH_PROTOCOL *) FilePath,\r
491 ImageBase,\r
492 ImageSize,\r
493 FileType\r
494 );\r
495 }\r
496 }\r
497}\r
498\r
499/**\r
500 Unregister image from DXE.\r
501\r
502 @param FileName File name of the image.\r
503 @param ImageBase Image base address.\r
504 @param ImageSize Image size.\r
505\r
506**/\r
507VOID\r
508UnregisterImageFromDxe (\r
509 IN EFI_GUID *FileName,\r
510 IN PHYSICAL_ADDRESS ImageBase,\r
511 IN UINT64 ImageSize\r
512 )\r
513{\r
514 EFI_STATUS Status;\r
515 EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol;\r
516 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;\r
517 UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];\r
518\r
e524f680 519 if (IS_UEFI_MEMORY_PROFILE_ENABLED) {\r
84edd20b
SZ
520\r
521 FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;\r
522 Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID *) &ProfileProtocol);\r
523 if (!EFI_ERROR (Status)) {\r
524 EfiInitializeFwVolDevicepathNode (FilePath, FileName);\r
525 SetDevicePathEndNode (FilePath + 1);\r
526\r
527 Status = ProfileProtocol->UnregisterImage (\r
528 ProfileProtocol,\r
529 (EFI_DEVICE_PATH_PROTOCOL *) FilePath,\r
530 ImageBase,\r
531 ImageSize\r
532 );\r
533 }\r
534 }\r
535}\r
536\r
e524f680
SZ
537/**\r
538 Return if record for this driver is needed..\r
539\r
540 @param DriverFilePath Driver file path.\r
541\r
542 @retval TRUE Record for this driver is needed.\r
543 @retval FALSE Record for this driver is not needed.\r
544\r
545**/\r
546BOOLEAN\r
547NeedRecordThisDriver (\r
548 IN EFI_DEVICE_PATH_PROTOCOL *DriverFilePath\r
549 )\r
550{\r
551 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
552 EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance;\r
553 UINTN DevicePathSize;\r
554 UINTN FilePathSize;\r
555\r
556 if (!IsDevicePathValid (mSmramProfileDriverPath, mSmramProfileDriverPathSize)) {\r
557 //\r
558 // Invalid Device Path means record all.\r
559 //\r
560 return TRUE;\r
561 }\r
d1102dba 562\r
e524f680
SZ
563 //\r
564 // Record FilePath without end node.\r
565 //\r
566 FilePathSize = GetDevicePathSize (DriverFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
567\r
568 DevicePathInstance = mSmramProfileDriverPath;\r
569 do {\r
570 //\r
571 // Find End node (it might be END_ENTIRE or END_INSTANCE)\r
572 //\r
573 TmpDevicePath = DevicePathInstance;\r
574 while (!IsDevicePathEndType (TmpDevicePath)) {\r
575 TmpDevicePath = NextDevicePathNode (TmpDevicePath);\r
576 }\r
577\r
578 //\r
579 // Do not compare END node\r
580 //\r
581 DevicePathSize = (UINTN)TmpDevicePath - (UINTN)DevicePathInstance;\r
582 if ((FilePathSize == DevicePathSize) &&\r
583 (CompareMem (DriverFilePath, DevicePathInstance, DevicePathSize) == 0)) {\r
584 return TRUE;\r
585 }\r
586\r
587 //\r
588 // Get next instance\r
589 //\r
590 DevicePathInstance = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)DevicePathInstance + DevicePathSize + DevicePathNodeLength(TmpDevicePath));\r
591 } while (DevicePathSubType (TmpDevicePath) != END_ENTIRE_DEVICE_PATH_SUBTYPE);\r
592\r
593 return FALSE;\r
594}\r
595\r
84edd20b
SZ
596/**\r
597 Register SMM Core to SMRAM profile.\r
598\r
599 @param ContextData SMRAM profile context.\r
600\r
601 @retval TRUE Register success.\r
602 @retval FALSE Register fail.\r
603\r
604**/\r
605BOOLEAN\r
606RegisterSmmCore (\r
607 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData\r
608 )\r
609{\r
610 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
611 PHYSICAL_ADDRESS ImageBase;\r
e524f680
SZ
612 UINT8 TempBuffer[sizeof(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH_PROTOCOL)];\r
613 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;\r
84edd20b 614\r
e524f680
SZ
615 FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempBuffer;\r
616 EfiInitializeFwVolDevicepathNode (FilePath, &gEfiCallerIdGuid);\r
617 SetDevicePathEndNode (FilePath + 1);\r
84edd20b 618\r
e524f680
SZ
619 if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *) FilePath)) {\r
620 return FALSE;\r
621 }\r
84edd20b
SZ
622\r
623 ImageBase = gSmmCorePrivate->PiSmmCoreImageBase;\r
624 DriverInfoData = BuildDriverInfo (\r
625 ContextData,\r
626 &gEfiCallerIdGuid,\r
627 ImageBase,\r
628 gSmmCorePrivate->PiSmmCoreImageSize,\r
629 gSmmCorePrivate->PiSmmCoreEntryPoint,\r
630 InternalPeCoffGetSubsystem ((VOID *) (UINTN) ImageBase),\r
631 EFI_FV_FILETYPE_SMM_CORE\r
632 );\r
633 if (DriverInfoData == NULL) {\r
634 return FALSE;\r
635 }\r
636\r
637 return TRUE;\r
638}\r
639\r
640/**\r
641 Initialize SMRAM profile.\r
642\r
643**/\r
644VOID\r
645SmramProfileInit (\r
646 VOID\r
647 )\r
648{\r
649 MEMORY_PROFILE_CONTEXT_DATA *SmramProfileContext;\r
650\r
e524f680
SZ
651 RegisterImageToDxe (\r
652 &gEfiCallerIdGuid,\r
653 gSmmCorePrivate->PiSmmCoreImageBase,\r
654 gSmmCorePrivate->PiSmmCoreImageSize,\r
655 EFI_FV_FILETYPE_SMM_CORE\r
656 );\r
657\r
84edd20b
SZ
658 if (!IS_SMRAM_PROFILE_ENABLED) {\r
659 return;\r
660 }\r
661\r
662 SmramProfileContext = GetSmramProfileContext ();\r
663 if (SmramProfileContext != NULL) {\r
664 return;\r
665 }\r
666\r
e524f680
SZ
667 mSmramProfileGettingStatus = FALSE;\r
668 if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT7) != 0) {\r
669 mSmramProfileRecordingEnable = MEMORY_PROFILE_RECORDING_DISABLE;\r
670 } else {\r
671 mSmramProfileRecordingEnable = MEMORY_PROFILE_RECORDING_ENABLE;\r
672 }\r
673 mSmramProfileDriverPathSize = PcdGetSize (PcdMemoryProfileDriverPath);\r
674 mSmramProfileDriverPath = AllocateCopyPool (mSmramProfileDriverPathSize, PcdGetPtr (PcdMemoryProfileDriverPath));\r
84edd20b
SZ
675 mSmramProfileContextPtr = &mSmramProfileContext;\r
676\r
677 RegisterSmmCore (&mSmramProfileContext);\r
678\r
679 DEBUG ((EFI_D_INFO, "SmramProfileInit SmramProfileContext - 0x%x\n", &mSmramProfileContext));\r
680}\r
681\r
e524f680
SZ
682/**\r
683 Install SMRAM profile protocol.\r
684\r
685**/\r
686VOID\r
687SmramProfileInstallProtocol (\r
688 VOID\r
689 )\r
690{\r
691 EFI_HANDLE Handle;\r
692 EFI_STATUS Status;\r
693\r
694 if (!IS_SMRAM_PROFILE_ENABLED) {\r
695 return;\r
696 }\r
697\r
698 Handle = NULL;\r
699 Status = SmmInstallProtocolInterface (\r
700 &Handle,\r
701 &gEdkiiSmmMemoryProfileGuid,\r
702 EFI_NATIVE_INTERFACE,\r
703 &mSmmProfileProtocol\r
704 );\r
705 ASSERT_EFI_ERROR (Status);\r
706}\r
707\r
708/**\r
709 Get the GUID file name from the file path.\r
710\r
711 @param FilePath File path.\r
712\r
713 @return The GUID file name from the file path.\r
714\r
715**/\r
716EFI_GUID *\r
717GetFileNameFromFilePath (\r
718 IN EFI_DEVICE_PATH_PROTOCOL *FilePath\r
719 )\r
720{\r
721 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *ThisFilePath;\r
722 EFI_GUID *FileName;\r
723\r
724 FileName = NULL;\r
725 if (FilePath != NULL) {\r
726 ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) FilePath;\r
727 while (!IsDevicePathEnd (ThisFilePath)) {\r
728 FileName = EfiGetNameGuidFromFwVolDevicePathNode (ThisFilePath);\r
729 if (FileName != NULL) {\r
730 break;\r
731 }\r
732 ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) NextDevicePathNode (ThisFilePath);\r
733 }\r
734 }\r
735\r
736 return FileName;\r
737}\r
738\r
84edd20b
SZ
739/**\r
740 Register SMM image to SMRAM profile.\r
741\r
742 @param DriverEntry SMM image info.\r
743 @param RegisterToDxe Register image to DXE.\r
744\r
e524f680
SZ
745 @return EFI_SUCCESS Register successfully.\r
746 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
747 or memory profile for the image is not required.\r
748 @return EFI_OUT_OF_RESOURCES No enough resource for this register.\r
84edd20b
SZ
749\r
750**/\r
e524f680 751EFI_STATUS\r
84edd20b
SZ
752RegisterSmramProfileImage (\r
753 IN EFI_SMM_DRIVER_ENTRY *DriverEntry,\r
754 IN BOOLEAN RegisterToDxe\r
755 )\r
756{\r
757 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
758 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
e524f680
SZ
759 UINT8 TempBuffer[sizeof(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH_PROTOCOL)];\r
760 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;\r
84edd20b
SZ
761\r
762 if (RegisterToDxe) {\r
763 RegisterImageToDxe (\r
764 &DriverEntry->FileName,\r
765 DriverEntry->ImageBuffer,\r
766 EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage),\r
767 EFI_FV_FILETYPE_SMM\r
768 );\r
769 }\r
770\r
e524f680
SZ
771 if (!IS_SMRAM_PROFILE_ENABLED) {\r
772 return EFI_UNSUPPORTED;\r
773 }\r
774\r
775 FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempBuffer;\r
776 EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName);\r
777 SetDevicePathEndNode (FilePath + 1);\r
778\r
779 if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *) FilePath)) {\r
780 return EFI_UNSUPPORTED;\r
781 }\r
782\r
84edd20b
SZ
783 ContextData = GetSmramProfileContext ();\r
784 if (ContextData == NULL) {\r
e524f680 785 return EFI_UNSUPPORTED;\r
84edd20b
SZ
786 }\r
787\r
788 DriverInfoData = BuildDriverInfo (\r
789 ContextData,\r
790 &DriverEntry->FileName,\r
791 DriverEntry->ImageBuffer,\r
792 EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage),\r
793 DriverEntry->ImageEntryPoint,\r
794 InternalPeCoffGetSubsystem ((VOID *) (UINTN) DriverEntry->ImageBuffer),\r
795 EFI_FV_FILETYPE_SMM\r
796 );\r
797 if (DriverInfoData == NULL) {\r
e524f680 798 return EFI_OUT_OF_RESOURCES;\r
84edd20b
SZ
799 }\r
800\r
e524f680 801 return EFI_SUCCESS;\r
84edd20b
SZ
802}\r
803\r
804/**\r
805 Search image from memory profile.\r
806\r
807 @param ContextData Memory profile context.\r
808 @param FileName Image file name.\r
809 @param Address Image Address.\r
810\r
811 @return Pointer to memory profile driver info.\r
812\r
813**/\r
814MEMORY_PROFILE_DRIVER_INFO_DATA *\r
815GetMemoryProfileDriverInfoByFileNameAndAddress (\r
816 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,\r
817 IN EFI_GUID *FileName,\r
818 IN PHYSICAL_ADDRESS Address\r
819 )\r
820{\r
821 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
822 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
823 LIST_ENTRY *DriverLink;\r
824 LIST_ENTRY *DriverInfoList;\r
825\r
826 DriverInfoList = ContextData->DriverInfoList;\r
827\r
828 for (DriverLink = DriverInfoList->ForwardLink;\r
829 DriverLink != DriverInfoList;\r
830 DriverLink = DriverLink->ForwardLink) {\r
831 DriverInfoData = CR (\r
832 DriverLink,\r
833 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
834 Link,\r
835 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
836 );\r
837 DriverInfo = &DriverInfoData->DriverInfo;\r
838 if ((CompareGuid (&DriverInfo->FileName, FileName)) &&\r
839 (Address >= DriverInfo->ImageBase) &&\r
840 (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) {\r
841 return DriverInfoData;\r
842 }\r
843 }\r
844\r
845 return NULL;\r
846}\r
847\r
84edd20b
SZ
848/**\r
849 Search image from memory profile.\r
850 It will return image, if (Address >= ImageBuffer) AND (Address < ImageBuffer + ImageSize)\r
851\r
852 @param ContextData Memory profile context.\r
853 @param Address Image or Function address.\r
854\r
855 @return Pointer to memory profile driver info.\r
856\r
857**/\r
858MEMORY_PROFILE_DRIVER_INFO_DATA *\r
859GetMemoryProfileDriverInfoFromAddress (\r
860 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,\r
861 IN PHYSICAL_ADDRESS Address\r
862 )\r
863{\r
864 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
865 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
866 LIST_ENTRY *DriverLink;\r
867 LIST_ENTRY *DriverInfoList;\r
868\r
869 DriverInfoList = ContextData->DriverInfoList;\r
870\r
871 for (DriverLink = DriverInfoList->ForwardLink;\r
872 DriverLink != DriverInfoList;\r
873 DriverLink = DriverLink->ForwardLink) {\r
874 DriverInfoData = CR (\r
875 DriverLink,\r
876 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
877 Link,\r
878 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
879 );\r
880 DriverInfo = &DriverInfoData->DriverInfo;\r
881 if ((Address >= DriverInfo->ImageBase) &&\r
882 (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) {\r
883 return DriverInfoData;\r
884 }\r
885 }\r
886\r
e524f680 887 return NULL;\r
84edd20b
SZ
888}\r
889\r
890/**\r
891 Unregister image from SMRAM profile.\r
892\r
893 @param DriverEntry SMM image info.\r
894 @param UnregisterFromDxe Unregister image from DXE.\r
895\r
e524f680
SZ
896 @return EFI_SUCCESS Unregister successfully.\r
897 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
898 or memory profile for the image is not required.\r
899 @return EFI_NOT_FOUND The image is not found.\r
84edd20b
SZ
900\r
901**/\r
e524f680 902EFI_STATUS\r
84edd20b
SZ
903UnregisterSmramProfileImage (\r
904 IN EFI_SMM_DRIVER_ENTRY *DriverEntry,\r
905 IN BOOLEAN UnregisterFromDxe\r
906 )\r
907{\r
908 EFI_STATUS Status;\r
909 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
910 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
911 EFI_GUID *FileName;\r
912 PHYSICAL_ADDRESS ImageAddress;\r
913 VOID *EntryPointInImage;\r
e524f680
SZ
914 UINT8 TempBuffer[sizeof(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH_PROTOCOL)];\r
915 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;\r
84edd20b
SZ
916\r
917 if (UnregisterFromDxe) {\r
918 UnregisterImageFromDxe (\r
919 &DriverEntry->FileName,\r
920 DriverEntry->ImageBuffer,\r
921 EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)\r
922 );\r
923 }\r
924\r
e524f680
SZ
925 if (!IS_SMRAM_PROFILE_ENABLED) {\r
926 return EFI_UNSUPPORTED;\r
927 }\r
928\r
929 FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempBuffer;\r
930 EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName);\r
931 SetDevicePathEndNode (FilePath + 1);\r
932\r
933 if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *) FilePath)) {\r
934 return EFI_UNSUPPORTED;\r
935 }\r
936\r
84edd20b
SZ
937 ContextData = GetSmramProfileContext ();\r
938 if (ContextData == NULL) {\r
e524f680 939 return EFI_UNSUPPORTED;\r
84edd20b
SZ
940 }\r
941\r
942 DriverInfoData = NULL;\r
943 FileName = &DriverEntry->FileName;\r
944 ImageAddress = DriverEntry->ImageBuffer;\r
945 if ((DriverEntry->ImageEntryPoint < ImageAddress) || (DriverEntry->ImageEntryPoint >= (ImageAddress + EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)))) {\r
946 //\r
947 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.\r
948 // So patch ImageAddress here to align the EntryPoint.\r
949 //\r
950 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageAddress, &EntryPointInImage);\r
951 ASSERT_EFI_ERROR (Status);\r
952 ImageAddress = ImageAddress + (UINTN) DriverEntry->ImageEntryPoint - (UINTN) EntryPointInImage;\r
953 }\r
954 if (FileName != NULL) {\r
955 DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress);\r
956 }\r
957 if (DriverInfoData == NULL) {\r
958 DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageAddress);\r
959 }\r
960 if (DriverInfoData == NULL) {\r
e524f680 961 return EFI_NOT_FOUND;\r
84edd20b
SZ
962 }\r
963\r
964 ContextData->Context.TotalImageSize -= DriverInfoData->DriverInfo.ImageSize;\r
965\r
e524f680
SZ
966 // Keep the ImageBase for RVA calculation in Application.\r
967 //DriverInfoData->DriverInfo.ImageBase = 0;\r
84edd20b
SZ
968 DriverInfoData->DriverInfo.ImageSize = 0;\r
969\r
970 if (DriverInfoData->DriverInfo.PeakUsage == 0) {\r
971 ContextData->Context.ImageCount --;\r
972 RemoveEntryList (&DriverInfoData->Link);\r
973 //\r
974 // Use SmmInternalFreePool() that will not update profile for this FreePool action.\r
975 //\r
976 SmmInternalFreePool (DriverInfoData);\r
977 }\r
978\r
e524f680 979 return EFI_SUCCESS;\r
84edd20b
SZ
980}\r
981\r
982/**\r
983 Return if this memory type needs to be recorded into memory profile.\r
ca949d9d 984 Only need to record EfiRuntimeServicesCode and EfiRuntimeServicesData for SMRAM profile.\r
84edd20b
SZ
985\r
986 @param MemoryType Memory type.\r
987\r
988 @retval TRUE This memory type need to be recorded.\r
989 @retval FALSE This memory type need not to be recorded.\r
990\r
991**/\r
992BOOLEAN\r
993SmmCoreNeedRecordProfile (\r
994 IN EFI_MEMORY_TYPE MemoryType\r
995 )\r
996{\r
997 UINT64 TestBit;\r
998\r
ca949d9d
SZ
999 if (MemoryType != EfiRuntimeServicesCode &&\r
1000 MemoryType != EfiRuntimeServicesData) {\r
1001 return FALSE;\r
84edd20b
SZ
1002 }\r
1003\r
ca949d9d
SZ
1004 TestBit = LShiftU64 (1, MemoryType);\r
1005\r
84edd20b
SZ
1006 if ((PcdGet64 (PcdMemoryProfileMemoryType) & TestBit) != 0) {\r
1007 return TRUE;\r
1008 } else {\r
1009 return FALSE;\r
1010 }\r
1011}\r
1012\r
1013/**\r
1014 Convert EFI memory type to profile memory index. The rule is:\r
ca949d9d
SZ
1015 If BIOS memory type (0 ~ EfiMaxMemoryType - 1), ProfileMemoryIndex = MemoryType.\r
1016 As SMRAM profile is only to record EfiRuntimeServicesCode and EfiRuntimeServicesData,\r
1017 so return input memory type directly.\r
84edd20b
SZ
1018\r
1019 @param MemoryType Memory type.\r
1020\r
1021 @return EFI memory type as profile memory index.\r
1022\r
1023**/\r
1024EFI_MEMORY_TYPE\r
1025GetProfileMemoryIndex (\r
1026 IN EFI_MEMORY_TYPE MemoryType\r
1027 )\r
1028{\r
ca949d9d 1029 return MemoryType;\r
84edd20b
SZ
1030}\r
1031\r
1032/**\r
1033 Update SMRAM profile FreeMemoryPages information\r
1034\r
1035 @param ContextData Memory profile context.\r
1036\r
1037**/\r
1038VOID\r
1039SmramProfileUpdateFreePages (\r
1040 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData\r
1041 )\r
1042{\r
1043 LIST_ENTRY *Node;\r
1044 FREE_PAGE_LIST *Pages;\r
1045 LIST_ENTRY *FreePageList;\r
1046 UINTN NumberOfPages;\r
1047\r
1048 NumberOfPages = 0;\r
1049 FreePageList = &mSmmMemoryMap;\r
1050 for (Node = FreePageList->BackLink;\r
1051 Node != FreePageList;\r
1052 Node = Node->BackLink) {\r
1053 Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
1054 NumberOfPages += Pages->NumberOfPages;\r
1055 }\r
1056\r
1057 mSmramFreeMemory.TotalFreeMemoryPages = NumberOfPages;\r
1058\r
1059 if (NumberOfPages <= SMRAM_INFO_DUMP_PAGE_THRESHOLD) {\r
1060 DumpSmramInfo ();\r
1061 }\r
1062}\r
1063\r
1064/**\r
1065 Update SMRAM profile Allocate information.\r
1066\r
1067 @param CallerAddress Address of caller who call Allocate.\r
1068 @param Action This Allocate action.\r
1069 @param MemoryType Memory type.\r
1070 @param Size Buffer size.\r
1071 @param Buffer Buffer address.\r
e524f680 1072 @param ActionString String for memory profile action.\r
84edd20b 1073\r
e524f680
SZ
1074 @return EFI_SUCCESS Memory profile is updated.\r
1075 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
1076 or memory profile for the image is not required.\r
1077 @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action.\r
84edd20b
SZ
1078\r
1079**/\r
e524f680 1080EFI_STATUS\r
84edd20b
SZ
1081SmmCoreUpdateProfileAllocate (\r
1082 IN PHYSICAL_ADDRESS CallerAddress,\r
1083 IN MEMORY_PROFILE_ACTION Action,\r
1084 IN EFI_MEMORY_TYPE MemoryType,\r
1085 IN UINTN Size,\r
e524f680
SZ
1086 IN VOID *Buffer,\r
1087 IN CHAR8 *ActionString OPTIONAL\r
84edd20b
SZ
1088 )\r
1089{\r
1090 EFI_STATUS Status;\r
e524f680
SZ
1091 MEMORY_PROFILE_CONTEXT *Context;\r
1092 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
1093 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
84edd20b
SZ
1094 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1095 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
1096 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
1097 EFI_MEMORY_TYPE ProfileMemoryIndex;\r
e524f680
SZ
1098 MEMORY_PROFILE_ACTION BasicAction;\r
1099 UINTN ActionStringSize;\r
1100 UINTN ActionStringOccupiedSize;\r
84edd20b 1101\r
e524f680 1102 BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK;\r
f4420027 1103\r
84edd20b
SZ
1104 ContextData = GetSmramProfileContext ();\r
1105 if (ContextData == NULL) {\r
e524f680 1106 return EFI_UNSUPPORTED;\r
84edd20b
SZ
1107 }\r
1108\r
1109 DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress);\r
e524f680
SZ
1110 if (DriverInfoData == NULL) {\r
1111 return EFI_UNSUPPORTED;\r
1112 }\r
1113\r
1114 ActionStringSize = 0;\r
1115 ActionStringOccupiedSize = 0;\r
1116 if (ActionString != NULL) {\r
1117 ActionStringSize = AsciiStrSize (ActionString);\r
1118 ActionStringOccupiedSize = GET_OCCUPIED_SIZE (ActionStringSize, sizeof (UINT64));\r
1119 }\r
84edd20b
SZ
1120\r
1121 //\r
1122 // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action.\r
1123 //\r
e524f680 1124 AllocInfoData = NULL;\r
84edd20b
SZ
1125 Status = SmmInternalAllocatePool (\r
1126 EfiRuntimeServicesData,\r
e524f680 1127 sizeof (*AllocInfoData) + ActionStringSize,\r
84edd20b
SZ
1128 (VOID **) &AllocInfoData\r
1129 );\r
1130 if (EFI_ERROR (Status)) {\r
e524f680
SZ
1131 return EFI_OUT_OF_RESOURCES;\r
1132 }\r
1133 ASSERT (AllocInfoData != NULL);\r
1134\r
1135 //\r
1136 // Only update SequenceCount if and only if it is basic action.\r
1137 //\r
1138 if (Action == BasicAction) {\r
1139 ContextData->Context.SequenceCount ++;\r
84edd20b 1140 }\r
e524f680 1141\r
84edd20b
SZ
1142 AllocInfo = &AllocInfoData->AllocInfo;\r
1143 AllocInfoData->Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE;\r
1144 AllocInfo->Header.Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE;\r
e524f680 1145 AllocInfo->Header.Length = (UINT16) (sizeof (MEMORY_PROFILE_ALLOC_INFO) + ActionStringOccupiedSize);\r
84edd20b
SZ
1146 AllocInfo->Header.Revision = MEMORY_PROFILE_ALLOC_INFO_REVISION;\r
1147 AllocInfo->CallerAddress = CallerAddress;\r
1148 AllocInfo->SequenceId = ContextData->Context.SequenceCount;\r
1149 AllocInfo->Action = Action;\r
1150 AllocInfo->MemoryType = MemoryType;\r
1151 AllocInfo->Buffer = (PHYSICAL_ADDRESS) (UINTN) Buffer;\r
1152 AllocInfo->Size = Size;\r
e524f680
SZ
1153 if (ActionString != NULL) {\r
1154 AllocInfo->ActionStringOffset = (UINT16) sizeof (MEMORY_PROFILE_ALLOC_INFO);\r
1155 AllocInfoData->ActionString = (CHAR8 *) (AllocInfoData + 1);\r
1156 CopyMem (AllocInfoData->ActionString, ActionString, ActionStringSize);\r
1157 } else {\r
1158 AllocInfo->ActionStringOffset = 0;\r
1159 AllocInfoData->ActionString = NULL;\r
1160 }\r
84edd20b
SZ
1161\r
1162 InsertTailList (DriverInfoData->AllocInfoList, &AllocInfoData->Link);\r
1163\r
e524f680 1164 Context = &ContextData->Context;\r
84edd20b 1165 DriverInfo = &DriverInfoData->DriverInfo;\r
84edd20b
SZ
1166 DriverInfo->AllocRecordCount ++;\r
1167\r
e524f680
SZ
1168 //\r
1169 // Update summary if and only if it is basic action.\r
1170 //\r
1171 if (Action == BasicAction) {\r
1172 ProfileMemoryIndex = GetProfileMemoryIndex (MemoryType);\r
1173\r
1174 DriverInfo->CurrentUsage += Size;\r
1175 if (DriverInfo->PeakUsage < DriverInfo->CurrentUsage) {\r
1176 DriverInfo->PeakUsage = DriverInfo->CurrentUsage;\r
1177 }\r
1178 DriverInfo->CurrentUsageByType[ProfileMemoryIndex] += Size;\r
1179 if (DriverInfo->PeakUsageByType[ProfileMemoryIndex] < DriverInfo->CurrentUsageByType[ProfileMemoryIndex]) {\r
1180 DriverInfo->PeakUsageByType[ProfileMemoryIndex] = DriverInfo->CurrentUsageByType[ProfileMemoryIndex];\r
1181 }\r
1182\r
1183 Context->CurrentTotalUsage += Size;\r
1184 if (Context->PeakTotalUsage < Context->CurrentTotalUsage) {\r
1185 Context->PeakTotalUsage = Context->CurrentTotalUsage;\r
1186 }\r
1187 Context->CurrentTotalUsageByType[ProfileMemoryIndex] += Size;\r
1188 if (Context->PeakTotalUsageByType[ProfileMemoryIndex] < Context->CurrentTotalUsageByType[ProfileMemoryIndex]) {\r
1189 Context->PeakTotalUsageByType[ProfileMemoryIndex] = Context->CurrentTotalUsageByType[ProfileMemoryIndex];\r
1190 }\r
1191\r
1192 SmramProfileUpdateFreePages (ContextData);\r
84edd20b 1193 }\r
84edd20b 1194\r
e524f680 1195 return EFI_SUCCESS;\r
84edd20b
SZ
1196}\r
1197\r
1198/**\r
1199 Get memory profile alloc info from memory profile\r
1200\r
1201 @param DriverInfoData Driver info\r
e524f680 1202 @param BasicAction This Free basic action\r
84edd20b
SZ
1203 @param Size Buffer size\r
1204 @param Buffer Buffer address\r
1205\r
1206 @return Pointer to memory profile alloc info.\r
1207**/\r
1208MEMORY_PROFILE_ALLOC_INFO_DATA *\r
1209GetMemoryProfileAllocInfoFromAddress (\r
1210 IN MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData,\r
e524f680 1211 IN MEMORY_PROFILE_ACTION BasicAction,\r
84edd20b
SZ
1212 IN UINTN Size,\r
1213 IN VOID *Buffer\r
1214 )\r
1215{\r
1216 LIST_ENTRY *AllocInfoList;\r
1217 LIST_ENTRY *AllocLink;\r
1218 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
1219 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
1220\r
1221 AllocInfoList = DriverInfoData->AllocInfoList;\r
1222\r
1223 for (AllocLink = AllocInfoList->ForwardLink;\r
1224 AllocLink != AllocInfoList;\r
1225 AllocLink = AllocLink->ForwardLink) {\r
1226 AllocInfoData = CR (\r
1227 AllocLink,\r
1228 MEMORY_PROFILE_ALLOC_INFO_DATA,\r
1229 Link,\r
1230 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE\r
1231 );\r
1232 AllocInfo = &AllocInfoData->AllocInfo;\r
e524f680 1233 if ((AllocInfo->Action & MEMORY_PROFILE_ACTION_BASIC_MASK) != BasicAction) {\r
84edd20b
SZ
1234 continue;\r
1235 }\r
e524f680 1236 switch (BasicAction) {\r
84edd20b
SZ
1237 case MemoryProfileActionAllocatePages:\r
1238 if ((AllocInfo->Buffer <= (PHYSICAL_ADDRESS) (UINTN) Buffer) &&\r
1239 ((AllocInfo->Buffer + AllocInfo->Size) >= ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size))) {\r
1240 return AllocInfoData;\r
1241 }\r
1242 break;\r
1243 case MemoryProfileActionAllocatePool:\r
1244 if (AllocInfo->Buffer == (PHYSICAL_ADDRESS) (UINTN) Buffer) {\r
1245 return AllocInfoData;\r
1246 }\r
1247 break;\r
1248 default:\r
1249 ASSERT (FALSE);\r
1250 break;\r
1251 }\r
1252 }\r
1253\r
1254 return NULL;\r
1255}\r
1256\r
1257/**\r
1258 Update SMRAM profile Free information.\r
1259\r
1260 @param CallerAddress Address of caller who call Free.\r
1261 @param Action This Free action.\r
1262 @param Size Buffer size.\r
1263 @param Buffer Buffer address.\r
1264\r
e524f680
SZ
1265 @return EFI_SUCCESS Memory profile is updated.\r
1266 @return EFI_UNSUPPORTED Memory profile is unsupported.\r
1267 @return EFI_NOT_FOUND No matched allocate info found for free action.\r
84edd20b
SZ
1268\r
1269**/\r
e524f680 1270EFI_STATUS\r
84edd20b
SZ
1271SmmCoreUpdateProfileFree (\r
1272 IN PHYSICAL_ADDRESS CallerAddress,\r
1273 IN MEMORY_PROFILE_ACTION Action,\r
1274 IN UINTN Size,\r
1275 IN VOID *Buffer\r
1276 )\r
1277{\r
1278 MEMORY_PROFILE_CONTEXT *Context;\r
1279 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
1280 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
1281 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1282 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
1283 LIST_ENTRY *DriverLink;\r
1284 LIST_ENTRY *DriverInfoList;\r
1285 MEMORY_PROFILE_DRIVER_INFO_DATA *ThisDriverInfoData;\r
1286 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
1287 EFI_MEMORY_TYPE ProfileMemoryIndex;\r
e524f680
SZ
1288 MEMORY_PROFILE_ACTION BasicAction;\r
1289 BOOLEAN Found;\r
1290\r
1291 BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK;\r
84edd20b
SZ
1292\r
1293 ContextData = GetSmramProfileContext ();\r
1294 if (ContextData == NULL) {\r
e524f680 1295 return EFI_UNSUPPORTED;\r
84edd20b
SZ
1296 }\r
1297\r
1298 DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress);\r
84edd20b 1299\r
e524f680
SZ
1300 //\r
1301 // Do not return if DriverInfoData == NULL here,\r
1302 // because driver A might free memory allocated by driver B.\r
1303 //\r
1304\r
1305 //\r
1306 // Need use do-while loop to find all possible record,\r
1307 // because one address might be recorded multiple times.\r
1308 //\r
1309 Found = FALSE;\r
1310 AllocInfoData = NULL;\r
1311 do {\r
1312 if (DriverInfoData != NULL) {\r
1313 switch (BasicAction) {\r
84edd20b 1314 case MemoryProfileActionFreePages:\r
e524f680 1315 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer);\r
84edd20b
SZ
1316 break;\r
1317 case MemoryProfileActionFreePool:\r
e524f680 1318 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer);\r
84edd20b
SZ
1319 break;\r
1320 default:\r
1321 ASSERT (FALSE);\r
1322 AllocInfoData = NULL;\r
1323 break;\r
1324 }\r
84edd20b 1325 }\r
84edd20b
SZ
1326 if (AllocInfoData == NULL) {\r
1327 //\r
e524f680 1328 // Legal case, because driver A might free memory allocated by driver B, by some protocol.\r
84edd20b 1329 //\r
e524f680
SZ
1330 DriverInfoList = ContextData->DriverInfoList;\r
1331\r
1332 for (DriverLink = DriverInfoList->ForwardLink;\r
1333 DriverLink != DriverInfoList;\r
1334 DriverLink = DriverLink->ForwardLink) {\r
1335 ThisDriverInfoData = CR (\r
1336 DriverLink,\r
1337 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
1338 Link,\r
1339 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
1340 );\r
1341 switch (BasicAction) {\r
1342 case MemoryProfileActionFreePages:\r
1343 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer);\r
1344 break;\r
1345 case MemoryProfileActionFreePool:\r
1346 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer);\r
1347 break;\r
1348 default:\r
1349 ASSERT (FALSE);\r
1350 AllocInfoData = NULL;\r
1351 break;\r
1352 }\r
1353 if (AllocInfoData != NULL) {\r
1354 DriverInfoData = ThisDriverInfoData;\r
1355 break;\r
1356 }\r
1357 }\r
84edd20b 1358\r
e524f680
SZ
1359 if (AllocInfoData == NULL) {\r
1360 //\r
1361 // If (!Found), no matched allocate info is found for this free action.\r
1362 // It is because the specified memory type allocate actions have been filtered by\r
1363 // CoreNeedRecordProfile(), but free actions have no memory type information,\r
1364 // they can not be filtered by CoreNeedRecordProfile(). Then, they will be\r
1365 // filtered here.\r
1366 //\r
1367 // If (Found), it is normal exit path.\r
1368 return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);\r
1369 }\r
1370 }\r
84edd20b 1371\r
9cda0af7
HW
1372 ASSERT (DriverInfoData != NULL);\r
1373 ASSERT (AllocInfoData != NULL);\r
1374\r
e524f680 1375 Found = TRUE;\r
84edd20b 1376\r
e524f680
SZ
1377 Context = &ContextData->Context;\r
1378 DriverInfo = &DriverInfoData->DriverInfo;\r
1379 AllocInfo = &AllocInfoData->AllocInfo;\r
84edd20b 1380\r
e524f680
SZ
1381 DriverInfo->AllocRecordCount --;\r
1382 //\r
1383 // Update summary if and only if it is basic action.\r
1384 //\r
1385 if (AllocInfo->Action == (AllocInfo->Action & MEMORY_PROFILE_ACTION_BASIC_MASK)) {\r
1386 ProfileMemoryIndex = GetProfileMemoryIndex (AllocInfo->MemoryType);\r
84edd20b 1387\r
e524f680
SZ
1388 Context->CurrentTotalUsage -= AllocInfo->Size;\r
1389 Context->CurrentTotalUsageByType[ProfileMemoryIndex] -= AllocInfo->Size;\r
84edd20b 1390\r
e524f680
SZ
1391 DriverInfo->CurrentUsage -= AllocInfo->Size;\r
1392 DriverInfo->CurrentUsageByType[ProfileMemoryIndex] -= AllocInfo->Size;\r
84edd20b 1393 }\r
84edd20b 1394\r
e524f680
SZ
1395 RemoveEntryList (&AllocInfoData->Link);\r
1396\r
1397 if (BasicAction == MemoryProfileActionFreePages) {\r
1398 if (AllocInfo->Buffer != (PHYSICAL_ADDRESS) (UINTN) Buffer) {\r
1399 SmmCoreUpdateProfileAllocate (\r
1400 AllocInfo->CallerAddress,\r
1401 AllocInfo->Action,\r
1402 AllocInfo->MemoryType,\r
1403 (UINTN) ((PHYSICAL_ADDRESS) (UINTN) Buffer - AllocInfo->Buffer),\r
1404 (VOID *) (UINTN) AllocInfo->Buffer,\r
1405 AllocInfoData->ActionString\r
1406 );\r
1407 }\r
1408 if (AllocInfo->Buffer + AllocInfo->Size != ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)) {\r
1409 SmmCoreUpdateProfileAllocate (\r
1410 AllocInfo->CallerAddress,\r
1411 AllocInfo->Action,\r
1412 AllocInfo->MemoryType,\r
1413 (UINTN) ((AllocInfo->Buffer + AllocInfo->Size) - ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)),\r
1414 (VOID *) ((UINTN) Buffer + Size),\r
1415 AllocInfoData->ActionString\r
1416 );\r
1417 }\r
1418 }\r
84edd20b 1419\r
e524f680
SZ
1420 //\r
1421 // Use SmmInternalFreePool() that will not update profile for this FreePool action.\r
1422 //\r
1423 SmmInternalFreePool (AllocInfoData);\r
1424 } while (TRUE);\r
84edd20b
SZ
1425}\r
1426\r
1427/**\r
1428 Update SMRAM profile information.\r
1429\r
1430 @param CallerAddress Address of caller who call Allocate or Free.\r
1431 @param Action This Allocate or Free action.\r
1432 @param MemoryType Memory type.\r
e524f680 1433 EfiMaxMemoryType means the MemoryType is unknown.\r
84edd20b
SZ
1434 @param Size Buffer size.\r
1435 @param Buffer Buffer address.\r
e524f680
SZ
1436 @param ActionString String for memory profile action.\r
1437 Only needed for user defined allocate action.\r
1438\r
1439 @return EFI_SUCCESS Memory profile is updated.\r
1440 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
1441 or memory profile for the image is not required,\r
1442 or memory profile for the memory type is not required.\r
1443 @return EFI_ACCESS_DENIED It is during memory profile data getting.\r
1444 @return EFI_ABORTED Memory profile recording is not enabled.\r
1445 @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action.\r
1446 @return EFI_NOT_FOUND No matched allocate info found for free action.\r
84edd20b
SZ
1447\r
1448**/\r
e524f680
SZ
1449EFI_STATUS\r
1450EFIAPI\r
84edd20b
SZ
1451SmmCoreUpdateProfile (\r
1452 IN PHYSICAL_ADDRESS CallerAddress,\r
1453 IN MEMORY_PROFILE_ACTION Action,\r
1454 IN EFI_MEMORY_TYPE MemoryType, // Valid for AllocatePages/AllocatePool\r
1455 IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool\r
e524f680
SZ
1456 IN VOID *Buffer,\r
1457 IN CHAR8 *ActionString OPTIONAL\r
84edd20b
SZ
1458 )\r
1459{\r
e524f680 1460 EFI_STATUS Status;\r
84edd20b 1461 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
e524f680 1462 MEMORY_PROFILE_ACTION BasicAction;\r
84edd20b
SZ
1463\r
1464 if (!IS_SMRAM_PROFILE_ENABLED) {\r
e524f680 1465 return EFI_UNSUPPORTED;\r
84edd20b
SZ
1466 }\r
1467\r
e524f680
SZ
1468 if (mSmramProfileGettingStatus) {\r
1469 return EFI_ACCESS_DENIED;\r
1470 }\r
1471\r
1472 if (!mSmramProfileRecordingEnable) {\r
1473 return EFI_ABORTED;\r
84edd20b
SZ
1474 }\r
1475\r
e524f680
SZ
1476 //\r
1477 // Get the basic action to know how to process the record\r
1478 //\r
1479 BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK;\r
1480\r
84edd20b
SZ
1481 //\r
1482 // Free operations have no memory type information, so skip the check.\r
1483 //\r
e524f680 1484 if ((BasicAction == MemoryProfileActionAllocatePages) || (BasicAction == MemoryProfileActionAllocatePool)) {\r
84edd20b
SZ
1485 //\r
1486 // Only record limited MemoryType.\r
1487 //\r
1488 if (!SmmCoreNeedRecordProfile (MemoryType)) {\r
e524f680 1489 return EFI_UNSUPPORTED;\r
84edd20b
SZ
1490 }\r
1491 }\r
1492\r
1493 ContextData = GetSmramProfileContext ();\r
1494 if (ContextData == NULL) {\r
e524f680 1495 return EFI_UNSUPPORTED;\r
84edd20b
SZ
1496 }\r
1497\r
e524f680 1498 switch (BasicAction) {\r
84edd20b 1499 case MemoryProfileActionAllocatePages:\r
e524f680 1500 Status = SmmCoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer, ActionString);\r
84edd20b
SZ
1501 break;\r
1502 case MemoryProfileActionFreePages:\r
e524f680 1503 Status = SmmCoreUpdateProfileFree (CallerAddress, Action, Size, Buffer);\r
84edd20b
SZ
1504 break;\r
1505 case MemoryProfileActionAllocatePool:\r
e524f680 1506 Status = SmmCoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer, ActionString);\r
84edd20b
SZ
1507 break;\r
1508 case MemoryProfileActionFreePool:\r
e524f680 1509 Status = SmmCoreUpdateProfileFree (CallerAddress, Action, 0, Buffer);\r
84edd20b
SZ
1510 break;\r
1511 default:\r
1512 ASSERT (FALSE);\r
e524f680 1513 Status = EFI_UNSUPPORTED;\r
84edd20b
SZ
1514 break;\r
1515 }\r
1516\r
e524f680 1517 return Status;\r
84edd20b
SZ
1518}\r
1519\r
1520/**\r
1521 SMRAM profile ready to lock callback function.\r
1522\r
1523**/\r
1524VOID\r
1525SmramProfileReadyToLock (\r
1526 VOID\r
1527 )\r
1528{\r
1529 if (!IS_SMRAM_PROFILE_ENABLED) {\r
1530 return;\r
1531 }\r
1532\r
1533 DEBUG ((EFI_D_INFO, "SmramProfileReadyToLock\n"));\r
1534 mSmramReadyToLock = TRUE;\r
1535}\r
1536\r
1537////////////////////\r
1538\r
84edd20b
SZ
1539/**\r
1540 Get SMRAM profile data size.\r
1541\r
1542 @return SMRAM profile data size.\r
1543\r
1544**/\r
1545UINTN\r
1546SmramProfileGetDataSize (\r
1547 VOID\r
1548 )\r
1549{\r
e524f680
SZ
1550 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1551 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
1552 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
1553 LIST_ENTRY *DriverInfoList;\r
1554 LIST_ENTRY *DriverLink;\r
1555 LIST_ENTRY *AllocInfoList;\r
1556 LIST_ENTRY *AllocLink;\r
1557 UINTN TotalSize;\r
1558 LIST_ENTRY *Node;\r
1559 LIST_ENTRY *FreePageList;\r
1560 LIST_ENTRY *FreePoolList;\r
1561 FREE_POOL_HEADER *Pool;\r
1562 UINTN PoolListIndex;\r
1563 UINTN Index;\r
5f4d3e17 1564 UINTN SmmPoolTypeIndex;\r
84edd20b
SZ
1565\r
1566 ContextData = GetSmramProfileContext ();\r
1567 if (ContextData == NULL) {\r
1568 return 0;\r
1569 }\r
1570\r
1571 TotalSize = sizeof (MEMORY_PROFILE_CONTEXT);\r
84edd20b
SZ
1572\r
1573 DriverInfoList = ContextData->DriverInfoList;\r
1574 for (DriverLink = DriverInfoList->ForwardLink;\r
1575 DriverLink != DriverInfoList;\r
1576 DriverLink = DriverLink->ForwardLink) {\r
1577 DriverInfoData = CR (\r
1578 DriverLink,\r
1579 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
1580 Link,\r
1581 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
1582 );\r
e524f680
SZ
1583 TotalSize += DriverInfoData->DriverInfo.Header.Length;\r
1584\r
1585 AllocInfoList = DriverInfoData->AllocInfoList;\r
1586 for (AllocLink = AllocInfoList->ForwardLink;\r
1587 AllocLink != AllocInfoList;\r
1588 AllocLink = AllocLink->ForwardLink) {\r
1589 AllocInfoData = CR (\r
1590 AllocLink,\r
1591 MEMORY_PROFILE_ALLOC_INFO_DATA,\r
1592 Link,\r
1593 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE\r
1594 );\r
1595 TotalSize += AllocInfoData->AllocInfo.Header.Length;\r
1596 }\r
84edd20b
SZ
1597 }\r
1598\r
1599\r
1600 Index = 0;\r
1601 FreePageList = &mSmmMemoryMap;\r
1602 for (Node = FreePageList->BackLink;\r
1603 Node != FreePageList;\r
1604 Node = Node->BackLink) {\r
1605 Index++;\r
1606 }\r
5f4d3e17
JY
1607 for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) {\r
1608 for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {\r
1609 FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][PoolListIndex];\r
1610 for (Node = FreePoolList->BackLink;\r
1611 Node != FreePoolList;\r
1612 Node = Node->BackLink) {\r
1613 Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);\r
1614 if (Pool->Header.Available) {\r
1615 Index++;\r
1616 }\r
84edd20b
SZ
1617 }\r
1618 }\r
1619 }\r
1620\r
84edd20b
SZ
1621 TotalSize += (sizeof (MEMORY_PROFILE_FREE_MEMORY) + Index * sizeof (MEMORY_PROFILE_DESCRIPTOR));\r
1622 TotalSize += (sizeof (MEMORY_PROFILE_MEMORY_RANGE) + mFullSmramRangeCount * sizeof (MEMORY_PROFILE_DESCRIPTOR));\r
1623\r
1624 return TotalSize;\r
1625}\r
1626\r
1627/**\r
1628 Copy SMRAM profile data.\r
1629\r
1630 @param ProfileBuffer The buffer to hold SMRAM profile data.\r
c3592c86
SZ
1631 @param ProfileSize On input, profile buffer size.\r
1632 On output, actual profile data size copied.\r
1633 @param ProfileOffset On input, profile buffer offset to copy.\r
1634 On output, next time profile buffer offset to copy.\r
84edd20b
SZ
1635\r
1636**/\r
1637VOID\r
1638SmramProfileCopyData (\r
c3592c86
SZ
1639 OUT VOID *ProfileBuffer,\r
1640 IN OUT UINT64 *ProfileSize,\r
1641 IN OUT UINT64 *ProfileOffset\r
84edd20b
SZ
1642 )\r
1643{\r
1644 MEMORY_PROFILE_CONTEXT *Context;\r
1645 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
1646 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
1647 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1648 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
1649 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
1650 LIST_ENTRY *DriverInfoList;\r
1651 LIST_ENTRY *DriverLink;\r
1652 LIST_ENTRY *AllocInfoList;\r
1653 LIST_ENTRY *AllocLink;\r
1654 LIST_ENTRY *Node;\r
1655 FREE_PAGE_LIST *Pages;\r
1656 LIST_ENTRY *FreePageList;\r
1657 LIST_ENTRY *FreePoolList;\r
1658 FREE_POOL_HEADER *Pool;\r
1659 UINTN PoolListIndex;\r
1660 UINT32 Index;\r
1661 MEMORY_PROFILE_FREE_MEMORY *FreeMemory;\r
1662 MEMORY_PROFILE_MEMORY_RANGE *MemoryRange;\r
1663 MEMORY_PROFILE_DESCRIPTOR *MemoryProfileDescriptor;\r
c3592c86
SZ
1664 UINT64 Offset;\r
1665 UINT64 RemainingSize;\r
e524f680
SZ
1666 UINTN PdbSize;\r
1667 UINTN ActionStringSize;\r
5f4d3e17 1668 UINTN SmmPoolTypeIndex;\r
84edd20b
SZ
1669\r
1670 ContextData = GetSmramProfileContext ();\r
1671 if (ContextData == NULL) {\r
1672 return ;\r
1673 }\r
1674\r
c3592c86
SZ
1675 RemainingSize = *ProfileSize;\r
1676 Offset = 0;\r
1677\r
1678 if (*ProfileOffset < sizeof (MEMORY_PROFILE_CONTEXT)) {\r
1679 if (RemainingSize >= sizeof (MEMORY_PROFILE_CONTEXT)) {\r
1680 Context = ProfileBuffer;\r
1681 CopyMem (Context, &ContextData->Context, sizeof (MEMORY_PROFILE_CONTEXT));\r
1682 RemainingSize -= sizeof (MEMORY_PROFILE_CONTEXT);\r
1683 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_CONTEXT);\r
1684 } else {\r
1685 goto Done;\r
1686 }\r
1687 }\r
1688 Offset += sizeof (MEMORY_PROFILE_CONTEXT);\r
84edd20b
SZ
1689\r
1690 DriverInfoList = ContextData->DriverInfoList;\r
1691 for (DriverLink = DriverInfoList->ForwardLink;\r
1692 DriverLink != DriverInfoList;\r
1693 DriverLink = DriverLink->ForwardLink) {\r
1694 DriverInfoData = CR (\r
1695 DriverLink,\r
1696 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
1697 Link,\r
1698 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
1699 );\r
e524f680
SZ
1700 if (*ProfileOffset < (Offset + DriverInfoData->DriverInfo.Header.Length)) {\r
1701 if (RemainingSize >= DriverInfoData->DriverInfo.Header.Length) {\r
c3592c86
SZ
1702 DriverInfo = ProfileBuffer;\r
1703 CopyMem (DriverInfo, &DriverInfoData->DriverInfo, sizeof (MEMORY_PROFILE_DRIVER_INFO));\r
e524f680
SZ
1704 if (DriverInfo->PdbStringOffset != 0) {\r
1705 PdbSize = AsciiStrSize (DriverInfoData->PdbString);\r
1706 CopyMem ((VOID *) ((UINTN) DriverInfo + DriverInfo->PdbStringOffset), DriverInfoData->PdbString, PdbSize);\r
1707 }\r
1708 RemainingSize -= DriverInfo->Header.Length;\r
1709 ProfileBuffer = (UINT8 *) ProfileBuffer + DriverInfo->Header.Length;\r
c3592c86
SZ
1710 } else {\r
1711 goto Done;\r
1712 }\r
1713 }\r
e524f680 1714 Offset += DriverInfoData->DriverInfo.Header.Length;\r
84edd20b
SZ
1715\r
1716 AllocInfoList = DriverInfoData->AllocInfoList;\r
1717 for (AllocLink = AllocInfoList->ForwardLink;\r
1718 AllocLink != AllocInfoList;\r
1719 AllocLink = AllocLink->ForwardLink) {\r
1720 AllocInfoData = CR (\r
1721 AllocLink,\r
1722 MEMORY_PROFILE_ALLOC_INFO_DATA,\r
1723 Link,\r
1724 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE\r
1725 );\r
e524f680
SZ
1726 if (*ProfileOffset < (Offset + AllocInfoData->AllocInfo.Header.Length)) {\r
1727 if (RemainingSize >= AllocInfoData->AllocInfo.Header.Length) {\r
c3592c86
SZ
1728 AllocInfo = ProfileBuffer;\r
1729 CopyMem (AllocInfo, &AllocInfoData->AllocInfo, sizeof (MEMORY_PROFILE_ALLOC_INFO));\r
e524f680
SZ
1730 if (AllocInfo->ActionStringOffset) {\r
1731 ActionStringSize = AsciiStrSize (AllocInfoData->ActionString);\r
1732 CopyMem ((VOID *) ((UINTN) AllocInfo + AllocInfo->ActionStringOffset), AllocInfoData->ActionString, ActionStringSize);\r
1733 }\r
1734 RemainingSize -= AllocInfo->Header.Length;\r
1735 ProfileBuffer = (UINT8 *) ProfileBuffer + AllocInfo->Header.Length;\r
c3592c86
SZ
1736 } else {\r
1737 goto Done;\r
1738 }\r
1739 }\r
e524f680 1740 Offset += AllocInfoData->AllocInfo.Header.Length;\r
84edd20b 1741 }\r
84edd20b
SZ
1742 }\r
1743\r
1744\r
c3592c86
SZ
1745 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_FREE_MEMORY))) {\r
1746 if (RemainingSize >= sizeof (MEMORY_PROFILE_FREE_MEMORY)) {\r
1747 FreeMemory = ProfileBuffer;\r
1748 CopyMem (FreeMemory, &mSmramFreeMemory, sizeof (MEMORY_PROFILE_FREE_MEMORY));\r
1749 Index = 0;\r
1750 FreePageList = &mSmmMemoryMap;\r
1751 for (Node = FreePageList->BackLink;\r
1752 Node != FreePageList;\r
1753 Node = Node->BackLink) {\r
1754 Index++;\r
1755 }\r
5f4d3e17
JY
1756 for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) {\r
1757 for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {\r
1758 FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][MAX_POOL_INDEX - PoolListIndex - 1];\r
1759 for (Node = FreePoolList->BackLink;\r
1760 Node != FreePoolList;\r
1761 Node = Node->BackLink) {\r
1762 Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);\r
1763 if (Pool->Header.Available) {\r
1764 Index++;\r
1765 }\r
c3592c86
SZ
1766 }\r
1767 }\r
1768 }\r
1769 FreeMemory->FreeMemoryEntryCount = Index;\r
1770\r
1771 RemainingSize -= sizeof (MEMORY_PROFILE_FREE_MEMORY);\r
1772 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_FREE_MEMORY);\r
1773 } else {\r
1774 goto Done;\r
1775 }\r
1776 }\r
1777 Offset += sizeof (MEMORY_PROFILE_FREE_MEMORY);\r
84edd20b
SZ
1778 FreePageList = &mSmmMemoryMap;\r
1779 for (Node = FreePageList->BackLink;\r
1780 Node != FreePageList;\r
1781 Node = Node->BackLink) {\r
c3592c86
SZ
1782 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) {\r
1783 if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) {\r
1784 Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
1785 MemoryProfileDescriptor = ProfileBuffer;\r
1786 MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;\r
1787 MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1788 MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;\r
1789 MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pages;\r
1790 MemoryProfileDescriptor->Size = EFI_PAGES_TO_SIZE (Pages->NumberOfPages);\r
1791\r
1792 RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1793 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1794 } else {\r
1795 goto Done;\r
1796 }\r
1797 }\r
1798 Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
84edd20b 1799 }\r
5f4d3e17
JY
1800 for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) {\r
1801 for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {\r
1802 FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][MAX_POOL_INDEX - PoolListIndex - 1];\r
1803 for (Node = FreePoolList->BackLink;\r
1804 Node != FreePoolList;\r
1805 Node = Node->BackLink) {\r
1806 Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);\r
1807 if (Pool->Header.Available) {\r
1808 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) {\r
1809 if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) {\r
1810 MemoryProfileDescriptor = ProfileBuffer;\r
1811 MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;\r
1812 MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1813 MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;\r
1814 MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pool;\r
1815 MemoryProfileDescriptor->Size = Pool->Header.Size;\r
1816\r
1817 RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1818 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1819 } else {\r
1820 goto Done;\r
1821 }\r
c3592c86 1822 }\r
5f4d3e17 1823 Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
c3592c86 1824 }\r
c3592c86
SZ
1825 }\r
1826 }\r
1827 }\r
1828\r
1829 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_MEMORY_RANGE))) {\r
1830 if (RemainingSize >= sizeof (MEMORY_PROFILE_MEMORY_RANGE)) {\r
1831 MemoryRange = ProfileBuffer;\r
1832 MemoryRange->Header.Signature = MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE;\r
1833 MemoryRange->Header.Length = sizeof (MEMORY_PROFILE_MEMORY_RANGE);\r
1834 MemoryRange->Header.Revision = MEMORY_PROFILE_MEMORY_RANGE_REVISION;\r
1835 MemoryRange->MemoryRangeCount = (UINT32) mFullSmramRangeCount;\r
1836\r
1837 RemainingSize -= sizeof (MEMORY_PROFILE_MEMORY_RANGE);\r
1838 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_MEMORY_RANGE);\r
1839 } else {\r
1840 goto Done;\r
1841 }\r
1842 }\r
1843 Offset += sizeof (MEMORY_PROFILE_MEMORY_RANGE);\r
1844 for (Index = 0; Index < mFullSmramRangeCount; Index++) {\r
1845 if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) {\r
1846 if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) {\r
1847 MemoryProfileDescriptor = ProfileBuffer;\r
84edd20b
SZ
1848 MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;\r
1849 MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1850 MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;\r
c3592c86
SZ
1851 MemoryProfileDescriptor->Address = mFullSmramRanges[Index].PhysicalStart;\r
1852 MemoryProfileDescriptor->Size = mFullSmramRanges[Index].PhysicalSize;\r
1853\r
1854 RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1855 ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
1856 } else {\r
1857 goto Done;\r
84edd20b
SZ
1858 }\r
1859 }\r
c3592c86 1860 Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR);\r
84edd20b 1861 }\r
84edd20b 1862\r
c3592c86
SZ
1863Done:\r
1864 //\r
1865 // On output, actual profile data size copied.\r
1866 //\r
1867 *ProfileSize -= RemainingSize;\r
1868 //\r
1869 // On output, next time profile buffer offset to copy.\r
1870 //\r
1871 *ProfileOffset = Offset;\r
84edd20b
SZ
1872}\r
1873\r
e524f680
SZ
1874/**\r
1875 Get memory profile data.\r
1876\r
1877 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
1878 @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer.\r
1879 On return, points to the size of the data returned in ProfileBuffer.\r
1880 @param[out] ProfileBuffer Profile buffer.\r
d1102dba 1881\r
e524f680
SZ
1882 @return EFI_SUCCESS Get the memory profile data successfully.\r
1883 @return EFI_UNSUPPORTED Memory profile is unsupported.\r
d1102dba 1884 @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data.\r
e524f680
SZ
1885 ProfileSize is updated with the size required.\r
1886\r
1887**/\r
1888EFI_STATUS\r
1889EFIAPI\r
1890SmramProfileProtocolGetData (\r
1891 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
1892 IN OUT UINT64 *ProfileSize,\r
1893 OUT VOID *ProfileBuffer\r
1894 )\r
1895{\r
1896 UINT64 Size;\r
1897 UINT64 Offset;\r
1898 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
1899 BOOLEAN SmramProfileGettingStatus;\r
1900\r
1901 ContextData = GetSmramProfileContext ();\r
1902 if (ContextData == NULL) {\r
1903 return EFI_UNSUPPORTED;\r
1904 }\r
1905\r
1906 SmramProfileGettingStatus = mSmramProfileGettingStatus;\r
1907 mSmramProfileGettingStatus = TRUE;\r
1908\r
1909 Size = SmramProfileGetDataSize ();\r
1910\r
1911 if (*ProfileSize < Size) {\r
1912 *ProfileSize = Size;\r
1913 mSmramProfileGettingStatus = SmramProfileGettingStatus;\r
1914 return EFI_BUFFER_TOO_SMALL;\r
1915 }\r
1916\r
1917 Offset = 0;\r
1918 SmramProfileCopyData (ProfileBuffer, &Size, &Offset);\r
1919 *ProfileSize = Size;\r
1920\r
1921 mSmramProfileGettingStatus = SmramProfileGettingStatus;\r
1922 return EFI_SUCCESS;\r
1923}\r
1924\r
1925/**\r
1926 Register image to memory profile.\r
1927\r
1928 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
1929 @param[in] FilePath File path of the image.\r
1930 @param[in] ImageBase Image base address.\r
1931 @param[in] ImageSize Image size.\r
1932 @param[in] FileType File type of the image.\r
1933\r
1934 @return EFI_SUCCESS Register successfully.\r
1935 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
1936 or memory profile for the image is not required.\r
1937 @return EFI_OUT_OF_RESOURCES No enough resource for this register.\r
1938\r
1939**/\r
1940EFI_STATUS\r
1941EFIAPI\r
1942SmramProfileProtocolRegisterImage (\r
1943 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
1944 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
1945 IN PHYSICAL_ADDRESS ImageBase,\r
1946 IN UINT64 ImageSize,\r
1947 IN EFI_FV_FILETYPE FileType\r
1948 )\r
1949{\r
1950 EFI_STATUS Status;\r
1951 EFI_SMM_DRIVER_ENTRY DriverEntry;\r
1952 VOID *EntryPointInImage;\r
1953 EFI_GUID *Name;\r
d1102dba 1954\r
e524f680
SZ
1955 ZeroMem (&DriverEntry, sizeof (DriverEntry));\r
1956 Name = GetFileNameFromFilePath (FilePath);\r
1957 if (Name != NULL) {\r
1958 CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID));\r
1959 }\r
1960 DriverEntry.ImageBuffer = ImageBase;\r
1961 DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN) ImageSize);\r
1962 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage);\r
1963 ASSERT_EFI_ERROR (Status);\r
1964 DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;\r
1965\r
1966 return RegisterSmramProfileImage (&DriverEntry, FALSE);\r
1967}\r
1968\r
1969/**\r
1970 Unregister image from memory profile.\r
1971\r
1972 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
1973 @param[in] FilePath File path of the image.\r
1974 @param[in] ImageBase Image base address.\r
1975 @param[in] ImageSize Image size.\r
1976\r
1977 @return EFI_SUCCESS Unregister successfully.\r
1978 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
1979 or memory profile for the image is not required.\r
1980 @return EFI_NOT_FOUND The image is not found.\r
1981\r
1982**/\r
1983EFI_STATUS\r
1984EFIAPI\r
1985SmramProfileProtocolUnregisterImage (\r
1986 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
1987 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
1988 IN PHYSICAL_ADDRESS ImageBase,\r
1989 IN UINT64 ImageSize\r
1990 )\r
1991{\r
1992 EFI_STATUS Status;\r
1993 EFI_SMM_DRIVER_ENTRY DriverEntry;\r
1994 VOID *EntryPointInImage;\r
1995 EFI_GUID *Name;\r
1996\r
1997 ZeroMem (&DriverEntry, sizeof (DriverEntry));\r
1998 Name = GetFileNameFromFilePath (FilePath);\r
1999 if (Name != NULL) {\r
2000 CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID));\r
2001 }\r
2002 DriverEntry.ImageBuffer = ImageBase;\r
2003 DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN) ImageSize);\r
2004 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage);\r
2005 ASSERT_EFI_ERROR (Status);\r
2006 DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;\r
2007\r
2008 return UnregisterSmramProfileImage (&DriverEntry, FALSE);\r
2009}\r
2010\r
2011/**\r
2012 Get memory profile recording state.\r
2013\r
2014 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
2015 @param[out] RecordingState Recording state.\r
2016\r
2017 @return EFI_SUCCESS Memory profile recording state is returned.\r
2018 @return EFI_UNSUPPORTED Memory profile is unsupported.\r
2019 @return EFI_INVALID_PARAMETER RecordingState is NULL.\r
2020\r
2021**/\r
2022EFI_STATUS\r
2023EFIAPI\r
2024SmramProfileProtocolGetRecordingState (\r
2025 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
2026 OUT BOOLEAN *RecordingState\r
2027 )\r
2028{\r
2029 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
2030\r
2031 ContextData = GetSmramProfileContext ();\r
2032 if (ContextData == NULL) {\r
2033 return EFI_UNSUPPORTED;\r
2034 }\r
2035\r
2036 if (RecordingState == NULL) {\r
2037 return EFI_INVALID_PARAMETER;\r
2038 }\r
2039 *RecordingState = mSmramProfileRecordingEnable;\r
2040 return EFI_SUCCESS;\r
2041}\r
2042\r
2043/**\r
2044 Set memory profile recording state.\r
2045\r
2046 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
2047 @param[in] RecordingState Recording state.\r
2048\r
2049 @return EFI_SUCCESS Set memory profile recording state successfully.\r
2050 @return EFI_UNSUPPORTED Memory profile is unsupported.\r
2051\r
2052**/\r
2053EFI_STATUS\r
2054EFIAPI\r
2055SmramProfileProtocolSetRecordingState (\r
2056 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
2057 IN BOOLEAN RecordingState\r
2058 )\r
2059{\r
2060 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
2061\r
2062 ContextData = GetSmramProfileContext ();\r
2063 if (ContextData == NULL) {\r
2064 return EFI_UNSUPPORTED;\r
2065 }\r
2066\r
2067 mSmramProfileRecordingEnable = RecordingState;\r
2068 return EFI_SUCCESS;\r
2069}\r
2070\r
2071/**\r
2072 Record memory profile of multilevel caller.\r
2073\r
2074 @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance.\r
2075 @param[in] CallerAddress Address of caller.\r
2076 @param[in] Action Memory profile action.\r
2077 @param[in] MemoryType Memory type.\r
2078 EfiMaxMemoryType means the MemoryType is unknown.\r
2079 @param[in] Buffer Buffer address.\r
2080 @param[in] Size Buffer size.\r
2081 @param[in] ActionString String for memory profile action.\r
2082 Only needed for user defined allocate action.\r
2083\r
2084 @return EFI_SUCCESS Memory profile is updated.\r
2085 @return EFI_UNSUPPORTED Memory profile is unsupported,\r
2086 or memory profile for the image is not required,\r
2087 or memory profile for the memory type is not required.\r
2088 @return EFI_ACCESS_DENIED It is during memory profile data getting.\r
2089 @return EFI_ABORTED Memory profile recording is not enabled.\r
2090 @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action.\r
2091 @return EFI_NOT_FOUND No matched allocate info found for free action.\r
2092\r
2093**/\r
2094EFI_STATUS\r
2095EFIAPI\r
2096SmramProfileProtocolRecord (\r
2097 IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,\r
2098 IN PHYSICAL_ADDRESS CallerAddress,\r
2099 IN MEMORY_PROFILE_ACTION Action,\r
2100 IN EFI_MEMORY_TYPE MemoryType,\r
2101 IN VOID *Buffer,\r
2102 IN UINTN Size,\r
2103 IN CHAR8 *ActionString OPTIONAL\r
2104 )\r
2105{\r
2106 return SmmCoreUpdateProfile (CallerAddress, Action, MemoryType, Size, Buffer, ActionString);\r
2107}\r
2108\r
84edd20b
SZ
2109/**\r
2110 SMRAM profile handler to get profile info.\r
2111\r
2112 @param SmramProfileParameterGetInfo The parameter of SMM profile get size.\r
2113\r
2114**/\r
2115VOID\r
2116SmramProfileHandlerGetInfo (\r
2117 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *SmramProfileParameterGetInfo\r
2118 )\r
2119{\r
2120 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
e524f680 2121 BOOLEAN SmramProfileGettingStatus;\r
84edd20b
SZ
2122\r
2123 ContextData = GetSmramProfileContext ();\r
2124 if (ContextData == NULL) {\r
2125 return ;\r
2126 }\r
2127\r
e524f680
SZ
2128 SmramProfileGettingStatus = mSmramProfileGettingStatus;\r
2129 mSmramProfileGettingStatus = TRUE;\r
84edd20b
SZ
2130\r
2131 SmramProfileParameterGetInfo->ProfileSize = SmramProfileGetDataSize();\r
2132 SmramProfileParameterGetInfo->Header.ReturnStatus = 0;\r
2133\r
e524f680 2134 mSmramProfileGettingStatus = SmramProfileGettingStatus;\r
84edd20b
SZ
2135}\r
2136\r
2137/**\r
2138 SMRAM profile handler to get profile data.\r
2139\r
2140 @param SmramProfileParameterGetData The parameter of SMM profile get data.\r
2141\r
2142**/\r
2143VOID\r
2144SmramProfileHandlerGetData (\r
2145 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *SmramProfileParameterGetData\r
2146 )\r
2147{\r
2148 UINT64 ProfileSize;\r
c3592c86 2149 UINT64 ProfileOffset;\r
84edd20b
SZ
2150 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA SmramProfileGetData;\r
2151 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
e524f680 2152 BOOLEAN SmramProfileGettingStatus;\r
84edd20b
SZ
2153\r
2154 ContextData = GetSmramProfileContext ();\r
2155 if (ContextData == NULL) {\r
2156 return ;\r
2157 }\r
2158\r
e524f680
SZ
2159 SmramProfileGettingStatus = mSmramProfileGettingStatus;\r
2160 mSmramProfileGettingStatus = TRUE;\r
84edd20b
SZ
2161\r
2162\r
2163 CopyMem (&SmramProfileGetData, SmramProfileParameterGetData, sizeof (SmramProfileGetData));\r
2164\r
2165 ProfileSize = SmramProfileGetDataSize();\r
2166\r
2167 //\r
2168 // Sanity check\r
2169 //\r
842b1242 2170 if (!SmmIsBufferOutsideSmmValid ((UINTN) SmramProfileGetData.ProfileBuffer, (UINTN) ProfileSize)) {\r
84edd20b
SZ
2171 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetData: SMM ProfileBuffer in SMRAM or overflow!\n"));\r
2172 SmramProfileParameterGetData->ProfileSize = ProfileSize;\r
2173 SmramProfileParameterGetData->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_ACCESS_DENIED;\r
2174 goto Done;\r
2175 }\r
2176\r
2177 if (SmramProfileGetData.ProfileSize < ProfileSize) {\r
2178 SmramProfileParameterGetData->ProfileSize = ProfileSize;\r
2179 SmramProfileParameterGetData->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_BUFFER_TOO_SMALL;\r
2180 goto Done;\r
2181 }\r
2182\r
c3592c86
SZ
2183 ProfileOffset = 0;\r
2184 SmramProfileCopyData ((VOID *) (UINTN) SmramProfileGetData.ProfileBuffer, &ProfileSize, &ProfileOffset);\r
84edd20b 2185 SmramProfileParameterGetData->ProfileSize = ProfileSize;\r
84edd20b
SZ
2186 SmramProfileParameterGetData->Header.ReturnStatus = 0;\r
2187\r
2188Done:\r
e524f680 2189 mSmramProfileGettingStatus = SmramProfileGettingStatus;\r
84edd20b
SZ
2190}\r
2191\r
c3592c86
SZ
2192/**\r
2193 SMRAM profile handler to get profile data by offset.\r
2194\r
2195 @param SmramProfileParameterGetDataByOffset The parameter of SMM profile get data by offset.\r
2196\r
2197**/\r
2198VOID\r
2199SmramProfileHandlerGetDataByOffset (\r
2200 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *SmramProfileParameterGetDataByOffset\r
2201 )\r
2202{\r
2203 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET SmramProfileGetDataByOffset;\r
2204 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
e524f680 2205 BOOLEAN SmramProfileGettingStatus;\r
c3592c86
SZ
2206\r
2207 ContextData = GetSmramProfileContext ();\r
2208 if (ContextData == NULL) {\r
2209 return ;\r
2210 }\r
2211\r
e524f680
SZ
2212 SmramProfileGettingStatus = mSmramProfileGettingStatus;\r
2213 mSmramProfileGettingStatus = TRUE;\r
c3592c86
SZ
2214\r
2215\r
2216 CopyMem (&SmramProfileGetDataByOffset, SmramProfileParameterGetDataByOffset, sizeof (SmramProfileGetDataByOffset));\r
2217\r
2218 //\r
2219 // Sanity check\r
2220 //\r
2221 if (!SmmIsBufferOutsideSmmValid ((UINTN) SmramProfileGetDataByOffset.ProfileBuffer, (UINTN) SmramProfileGetDataByOffset.ProfileSize)) {\r
2222 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetDataByOffset: SMM ProfileBuffer in SMRAM or overflow!\n"));\r
2223 SmramProfileParameterGetDataByOffset->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_ACCESS_DENIED;\r
2224 goto Done;\r
2225 }\r
2226\r
2227 SmramProfileCopyData ((VOID *) (UINTN) SmramProfileGetDataByOffset.ProfileBuffer, &SmramProfileGetDataByOffset.ProfileSize, &SmramProfileGetDataByOffset.ProfileOffset);\r
2228 CopyMem (SmramProfileParameterGetDataByOffset, &SmramProfileGetDataByOffset, sizeof (SmramProfileGetDataByOffset));\r
2229 SmramProfileParameterGetDataByOffset->Header.ReturnStatus = 0;\r
2230\r
2231Done:\r
e524f680 2232 mSmramProfileGettingStatus = SmramProfileGettingStatus;\r
c3592c86
SZ
2233}\r
2234\r
84edd20b
SZ
2235/**\r
2236 SMRAM profile handler to register SMM image.\r
2237\r
2238 @param SmramProfileParameterRegisterImage The parameter of SMM profile register image.\r
2239\r
2240**/\r
2241VOID\r
2242SmramProfileHandlerRegisterImage (\r
2243 IN SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE *SmramProfileParameterRegisterImage\r
2244 )\r
2245{\r
2246 EFI_STATUS Status;\r
2247 EFI_SMM_DRIVER_ENTRY DriverEntry;\r
2248 VOID *EntryPointInImage;\r
84edd20b
SZ
2249\r
2250 ZeroMem (&DriverEntry, sizeof (DriverEntry));\r
2251 CopyMem (&DriverEntry.FileName, &SmramProfileParameterRegisterImage->FileName, sizeof(EFI_GUID));\r
2252 DriverEntry.ImageBuffer = SmramProfileParameterRegisterImage->ImageBuffer;\r
2253 DriverEntry.NumberOfPage = (UINTN) SmramProfileParameterRegisterImage->NumberOfPage;\r
2254 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage);\r
2255 ASSERT_EFI_ERROR (Status);\r
2256 DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;\r
2257\r
e524f680
SZ
2258 Status = RegisterSmramProfileImage (&DriverEntry, FALSE);\r
2259 if (!EFI_ERROR (Status)) {\r
84edd20b
SZ
2260 SmramProfileParameterRegisterImage->Header.ReturnStatus = 0;\r
2261 }\r
2262}\r
2263\r
2264/**\r
2265 SMRAM profile handler to unregister SMM image.\r
2266\r
2267 @param SmramProfileParameterUnregisterImage The parameter of SMM profile unregister image.\r
2268\r
2269**/\r
2270VOID\r
2271SmramProfileHandlerUnregisterImage (\r
2272 IN SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE *SmramProfileParameterUnregisterImage\r
2273 )\r
2274{\r
2275 EFI_STATUS Status;\r
2276 EFI_SMM_DRIVER_ENTRY DriverEntry;\r
2277 VOID *EntryPointInImage;\r
84edd20b
SZ
2278\r
2279 ZeroMem (&DriverEntry, sizeof (DriverEntry));\r
2280 CopyMem (&DriverEntry.FileName, &SmramProfileParameterUnregisterImage->FileName, sizeof (EFI_GUID));\r
2281 DriverEntry.ImageBuffer = SmramProfileParameterUnregisterImage->ImageBuffer;\r
2282 DriverEntry.NumberOfPage = (UINTN) SmramProfileParameterUnregisterImage->NumberOfPage;\r
2283 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage);\r
2284 ASSERT_EFI_ERROR (Status);\r
2285 DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;\r
2286\r
e524f680
SZ
2287 Status = UnregisterSmramProfileImage (&DriverEntry, FALSE);\r
2288 if (!EFI_ERROR (Status)) {\r
84edd20b
SZ
2289 SmramProfileParameterUnregisterImage->Header.ReturnStatus = 0;\r
2290 }\r
2291}\r
2292\r
2293/**\r
2294 Dispatch function for a Software SMI handler.\r
2295\r
2296 Caution: This function may receive untrusted input.\r
2297 Communicate buffer and buffer size are external input, so this function will do basic validation.\r
2298\r
2299 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
2300 @param Context Points to an optional handler context which was specified when the\r
2301 handler was registered.\r
2302 @param CommBuffer A pointer to a collection of data in memory that will\r
2303 be conveyed from a non-SMM environment into an SMM environment.\r
2304 @param CommBufferSize The size of the CommBuffer.\r
2305\r
2306 @retval EFI_SUCCESS Command is handled successfully.\r
2307\r
2308**/\r
2309EFI_STATUS\r
2310EFIAPI\r
2311SmramProfileHandler (\r
2312 IN EFI_HANDLE DispatchHandle,\r
2313 IN CONST VOID *Context OPTIONAL,\r
2314 IN OUT VOID *CommBuffer OPTIONAL,\r
2315 IN OUT UINTN *CommBufferSize OPTIONAL\r
2316 )\r
2317{\r
2318 SMRAM_PROFILE_PARAMETER_HEADER *SmramProfileParameterHeader;\r
2319 UINTN TempCommBufferSize;\r
e524f680 2320 SMRAM_PROFILE_PARAMETER_RECORDING_STATE *ParameterRecordingState;\r
84edd20b
SZ
2321\r
2322 DEBUG ((EFI_D_ERROR, "SmramProfileHandler Enter\n"));\r
2323\r
2324 //\r
2325 // If input is invalid, stop processing this SMI\r
2326 //\r
2327 if (CommBuffer == NULL || CommBufferSize == NULL) {\r
2328 return EFI_SUCCESS;\r
2329 }\r
2330\r
2331 TempCommBufferSize = *CommBufferSize;\r
2332\r
2333 if (TempCommBufferSize < sizeof (SMRAM_PROFILE_PARAMETER_HEADER)) {\r
2334 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
2335 return EFI_SUCCESS;\r
2336 }\r
2337\r
842b1242 2338 if (mSmramReadyToLock && !SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
84edd20b
SZ
2339 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer in SMRAM or overflow!\n"));\r
2340 return EFI_SUCCESS;\r
2341 }\r
2342\r
2343 SmramProfileParameterHeader = (SMRAM_PROFILE_PARAMETER_HEADER *) ((UINTN) CommBuffer);\r
2344\r
2345 SmramProfileParameterHeader->ReturnStatus = (UINT64)-1;\r
2346\r
2347 if (GetSmramProfileContext () == NULL) {\r
2348 SmramProfileParameterHeader->ReturnStatus = (UINT64) (INT64) (INTN) EFI_UNSUPPORTED;\r
2349 return EFI_SUCCESS;\r
2350 }\r
2351\r
2352 switch (SmramProfileParameterHeader->Command) {\r
2353 case SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO:\r
2354 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetInfo\n"));\r
2355 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO)) {\r
2356 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
2357 return EFI_SUCCESS;\r
2358 }\r
2359 SmramProfileHandlerGetInfo ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) (UINTN) CommBuffer);\r
2360 break;\r
2361 case SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA:\r
2362 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetData\n"));\r
2363 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA)) {\r
2364 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
2365 return EFI_SUCCESS;\r
2366 }\r
2367 SmramProfileHandlerGetData ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *) (UINTN) CommBuffer);\r
2368 break;\r
c3592c86
SZ
2369 case SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET:\r
2370 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetDataByOffset\n"));\r
2371 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET)) {\r
2372 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
2373 return EFI_SUCCESS;\r
2374 }\r
2375 SmramProfileHandlerGetDataByOffset ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) (UINTN) CommBuffer);\r
2376 break;\r
84edd20b
SZ
2377 case SMRAM_PROFILE_COMMAND_REGISTER_IMAGE:\r
2378 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerRegisterImage\n"));\r
2379 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE)) {\r
2380 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
2381 return EFI_SUCCESS;\r
2382 }\r
2383 if (mSmramReadyToLock) {\r
2384 return EFI_SUCCESS;\r
2385 }\r
2386 SmramProfileHandlerRegisterImage ((SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE *) (UINTN) CommBuffer);\r
2387 break;\r
2388 case SMRAM_PROFILE_COMMAND_UNREGISTER_IMAGE:\r
2389 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerUnregisterImage\n"));\r
2390 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE)) {\r
2391 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
2392 return EFI_SUCCESS;\r
2393 }\r
2394 if (mSmramReadyToLock) {\r
2395 return EFI_SUCCESS;\r
2396 }\r
2397 SmramProfileHandlerUnregisterImage ((SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE *) (UINTN) CommBuffer);\r
2398 break;\r
e524f680
SZ
2399 case SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE:\r
2400 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetRecordingState\n"));\r
2401 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE)) {\r
2402 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
2403 return EFI_SUCCESS;\r
2404 }\r
2405 ParameterRecordingState = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *) (UINTN) CommBuffer;\r
2406 ParameterRecordingState->RecordingState = mSmramProfileRecordingEnable;\r
2407 ParameterRecordingState->Header.ReturnStatus = 0;\r
2408 break;\r
2409 case SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE:\r
2410 DEBUG ((EFI_D_ERROR, "SmramProfileHandlerSetRecordingState\n"));\r
2411 if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE)) {\r
2412 DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));\r
2413 return EFI_SUCCESS;\r
2414 }\r
2415 ParameterRecordingState = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *) (UINTN) CommBuffer;\r
2416 mSmramProfileRecordingEnable = ParameterRecordingState->RecordingState;\r
2417 ParameterRecordingState->Header.ReturnStatus = 0;\r
2418 break;\r
2419\r
84edd20b
SZ
2420 default:\r
2421 break;\r
2422 }\r
2423\r
2424 DEBUG ((EFI_D_ERROR, "SmramProfileHandler Exit\n"));\r
2425\r
2426 return EFI_SUCCESS;\r
2427}\r
2428\r
2429/**\r
2430 Register SMRAM profile handler.\r
2431\r
2432**/\r
2433VOID\r
2434RegisterSmramProfileHandler (\r
2435 VOID\r
2436 )\r
2437{\r
2438 EFI_STATUS Status;\r
2439 EFI_HANDLE DispatchHandle;\r
2440\r
2441 if (!IS_SMRAM_PROFILE_ENABLED) {\r
2442 return;\r
2443 }\r
2444\r
2445 Status = SmiHandlerRegister (\r
2446 SmramProfileHandler,\r
2447 &gEdkiiMemoryProfileGuid,\r
2448 &DispatchHandle\r
2449 );\r
2450 ASSERT_EFI_ERROR (Status);\r
2451}\r
2452\r
2453////////////////////\r
2454\r
2455/**\r
2456 Dump SMRAM range.\r
2457\r
2458**/\r
2459VOID\r
2460DumpSmramRange (\r
2461 VOID\r
2462 )\r
2463{\r
2464 UINTN Index;\r
2465 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
e524f680 2466 BOOLEAN SmramProfileGettingStatus;\r
84edd20b
SZ
2467\r
2468 ContextData = GetSmramProfileContext ();\r
2469 if (ContextData == NULL) {\r
2470 return ;\r
2471 }\r
2472\r
e524f680
SZ
2473 SmramProfileGettingStatus = mSmramProfileGettingStatus;\r
2474 mSmramProfileGettingStatus = TRUE;\r
84edd20b
SZ
2475\r
2476 DEBUG ((EFI_D_INFO, "FullSmramRange address - 0x%08x\n", mFullSmramRanges));\r
2477\r
2478 DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n"));\r
2479\r
2480 DEBUG ((EFI_D_INFO, "FullSmramRange:\n"));\r
2481 for (Index = 0; Index < mFullSmramRangeCount; Index++) {\r
2482 DEBUG ((EFI_D_INFO, " FullSmramRange (0x%x)\n", Index));\r
2483 DEBUG ((EFI_D_INFO, " PhysicalStart - 0x%016lx\n", mFullSmramRanges[Index].PhysicalStart));\r
2484 DEBUG ((EFI_D_INFO, " CpuStart - 0x%016lx\n", mFullSmramRanges[Index].CpuStart));\r
2485 DEBUG ((EFI_D_INFO, " PhysicalSize - 0x%016lx\n", mFullSmramRanges[Index].PhysicalSize));\r
2486 DEBUG ((EFI_D_INFO, " RegionState - 0x%016lx\n", mFullSmramRanges[Index].RegionState));\r
2487 }\r
2488\r
2489 DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n"));\r
2490\r
e524f680 2491 mSmramProfileGettingStatus = SmramProfileGettingStatus;\r
84edd20b
SZ
2492}\r
2493\r
2494/**\r
2495 Dump SMRAM free page list.\r
2496\r
2497**/\r
2498VOID\r
2499DumpFreePagesList (\r
2500 VOID\r
2501 )\r
2502{\r
2503 LIST_ENTRY *FreePageList;\r
2504 LIST_ENTRY *Node;\r
2505 FREE_PAGE_LIST *Pages;\r
2506 UINTN Index;\r
2507 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
e524f680 2508 BOOLEAN SmramProfileGettingStatus;\r
84edd20b
SZ
2509\r
2510 ContextData = GetSmramProfileContext ();\r
2511 if (ContextData == NULL) {\r
2512 return ;\r
2513 }\r
2514\r
e524f680
SZ
2515 SmramProfileGettingStatus = mSmramProfileGettingStatus;\r
2516 mSmramProfileGettingStatus = TRUE;\r
84edd20b
SZ
2517\r
2518 DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n"));\r
2519\r
2520 DEBUG ((EFI_D_INFO, "FreePagesList:\n"));\r
2521 FreePageList = &mSmmMemoryMap;\r
2522 for (Node = FreePageList->BackLink, Index = 0;\r
2523 Node != FreePageList;\r
2524 Node = Node->BackLink, Index++) {\r
2525 Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
2526 DEBUG ((EFI_D_INFO, " Index - 0x%x\n", Index));\r
2527 DEBUG ((EFI_D_INFO, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS) (UINTN) Pages));\r
2528 DEBUG ((EFI_D_INFO, " NumberOfPages - 0x%08x\n", Pages->NumberOfPages));\r
2529 }\r
2530\r
2531 DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n"));\r
2532\r
e524f680 2533 mSmramProfileGettingStatus = SmramProfileGettingStatus;\r
84edd20b
SZ
2534}\r
2535\r
2536/**\r
2537 Dump SMRAM free pool list.\r
2538\r
2539**/\r
2540VOID\r
2541DumpFreePoolList (\r
2542 VOID\r
2543 )\r
2544{\r
e524f680
SZ
2545 LIST_ENTRY *FreePoolList;\r
2546 LIST_ENTRY *Node;\r
2547 FREE_POOL_HEADER *Pool;\r
2548 UINTN Index;\r
2549 UINTN PoolListIndex;\r
84edd20b 2550 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
e524f680 2551 BOOLEAN SmramProfileGettingStatus;\r
5f4d3e17 2552 UINTN SmmPoolTypeIndex;\r
84edd20b
SZ
2553\r
2554 ContextData = GetSmramProfileContext ();\r
2555 if (ContextData == NULL) {\r
2556 return ;\r
2557 }\r
2558\r
e524f680
SZ
2559 SmramProfileGettingStatus = mSmramProfileGettingStatus;\r
2560 mSmramProfileGettingStatus = TRUE;\r
84edd20b 2561\r
5f4d3e17
JY
2562 DEBUG ((DEBUG_INFO, "======= SmramProfile begin =======\n"));\r
2563\r
2564 for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) {\r
2565 for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {\r
2566 DEBUG ((DEBUG_INFO, "FreePoolList(%d)(%d):\n", SmmPoolTypeIndex, PoolListIndex));\r
2567 FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][PoolListIndex];\r
2568 for (Node = FreePoolList->BackLink, Index = 0;\r
2569 Node != FreePoolList;\r
2570 Node = Node->BackLink, Index++) {\r
2571 Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);\r
2572 DEBUG ((DEBUG_INFO, " Index - 0x%x\n", Index));\r
2573 DEBUG ((DEBUG_INFO, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS) (UINTN) Pool));\r
2574 DEBUG ((DEBUG_INFO, " Size - 0x%08x\n", Pool->Header.Size));\r
2575 DEBUG ((DEBUG_INFO, " Available - 0x%02x\n", Pool->Header.Available));\r
2576 }\r
84edd20b
SZ
2577 }\r
2578 }\r
2579\r
5f4d3e17 2580 DEBUG ((DEBUG_INFO, "======= SmramProfile end =======\n"));\r
84edd20b 2581\r
e524f680 2582 mSmramProfileGettingStatus = SmramProfileGettingStatus;\r
84edd20b
SZ
2583}\r
2584\r
e524f680
SZ
2585GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *mSmmActionString[] = {\r
2586 "SmmUnknown",\r
2587 "gSmst->SmmAllocatePages",\r
2588 "gSmst->SmmFreePages",\r
2589 "gSmst->SmmAllocatePool",\r
2590 "gSmst->SmmFreePool",\r
84edd20b
SZ
2591};\r
2592\r
e524f680
SZ
2593typedef struct {\r
2594 MEMORY_PROFILE_ACTION Action;\r
2595 CHAR8 *String;\r
2596} ACTION_STRING;\r
2597\r
6e6ceae6 2598GLOBAL_REMOVE_IF_UNREFERENCED ACTION_STRING mExtActionString[] = {\r
e524f680
SZ
2599 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, "Lib:AllocatePages"},\r
2600 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, "Lib:AllocateRuntimePages"},\r
2601 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES, "Lib:AllocateReservedPages"},\r
2602 {MEMORY_PROFILE_ACTION_LIB_FREE_PAGES, "Lib:FreePages"},\r
2603 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, "Lib:AllocateAlignedPages"},\r
2604 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, "Lib:AllocateAlignedRuntimePages"},\r
2605 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES, "Lib:AllocateAlignedReservedPages"},\r
2606 {MEMORY_PROFILE_ACTION_LIB_FREE_ALIGNED_PAGES, "Lib:FreeAlignedPages"},\r
2607 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, "Lib:AllocatePool"},\r
2608 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, "Lib:AllocateRuntimePool"},\r
2609 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL, "Lib:AllocateReservedPool"},\r
2610 {MEMORY_PROFILE_ACTION_LIB_FREE_POOL, "Lib:FreePool"},\r
2611 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, "Lib:AllocateZeroPool"},\r
2612 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, "Lib:AllocateRuntimeZeroPool"},\r
2613 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL, "Lib:AllocateReservedZeroPool"},\r
2614 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, "Lib:AllocateCopyPool"},\r
2615 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, "Lib:AllocateRuntimeCopyPool"},\r
2616 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL, "Lib:AllocateReservedCopyPool"},\r
2617 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, "Lib:ReallocatePool"},\r
2618 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, "Lib:ReallocateRuntimePool"},\r
2619 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL, "Lib:ReallocateReservedPool"},\r
2620};\r
2621\r
ca949d9d
SZ
2622typedef struct {\r
2623 EFI_MEMORY_TYPE MemoryType;\r
e524f680 2624 CHAR8 *MemoryTypeStr;\r
ca949d9d
SZ
2625} PROFILE_MEMORY_TYPE_STRING;\r
2626\r
2627GLOBAL_REMOVE_IF_UNREFERENCED PROFILE_MEMORY_TYPE_STRING mMemoryTypeString[] = {\r
e524f680
SZ
2628 {EfiRuntimeServicesCode, "EfiRuntimeServicesCode"},\r
2629 {EfiRuntimeServicesData, "EfiRuntimeServicesData"}\r
84edd20b
SZ
2630};\r
2631\r
ca949d9d
SZ
2632/**\r
2633 Memory type to string.\r
2634\r
2635 @param[in] MemoryType Memory type.\r
2636\r
2637 @return Pointer to string.\r
2638\r
2639**/\r
e524f680 2640CHAR8 *\r
ca949d9d
SZ
2641ProfileMemoryTypeToStr (\r
2642 IN EFI_MEMORY_TYPE MemoryType\r
2643 )\r
2644{\r
2645 UINTN Index;\r
8368951f 2646 for (Index = 0; Index < ARRAY_SIZE (mMemoryTypeString); Index++) {\r
ca949d9d
SZ
2647 if (mMemoryTypeString[Index].MemoryType == MemoryType) {\r
2648 return mMemoryTypeString[Index].MemoryTypeStr;\r
2649 }\r
2650 }\r
2651\r
e524f680
SZ
2652 return "UnexpectedMemoryType";\r
2653}\r
2654\r
2655/**\r
2656 Action to string.\r
2657\r
2658 @param[in] Action Profile action.\r
2659\r
2660 @return Pointer to string.\r
2661\r
2662**/\r
2663CHAR8 *\r
2664ProfileActionToStr (\r
2665 IN MEMORY_PROFILE_ACTION Action\r
2666 )\r
2667{\r
2668 UINTN Index;\r
2669 UINTN ActionStringCount;\r
2670 CHAR8 **ActionString;\r
2671\r
2672 ActionString = mSmmActionString;\r
8368951f 2673 ActionStringCount = ARRAY_SIZE (mSmmActionString);\r
e524f680
SZ
2674\r
2675 if ((UINTN) (UINT32) Action < ActionStringCount) {\r
2676 return ActionString[Action];\r
2677 }\r
8368951f 2678 for (Index = 0; Index < ARRAY_SIZE (mExtActionString); Index++) {\r
e524f680
SZ
2679 if (mExtActionString[Index].Action == Action) {\r
2680 return mExtActionString[Index].String;\r
2681 }\r
2682 }\r
2683\r
2684 return ActionString[0];\r
ca949d9d 2685}\r
84edd20b
SZ
2686\r
2687/**\r
2688 Dump SMRAM profile.\r
2689\r
2690**/\r
2691VOID\r
2692DumpSmramProfile (\r
2693 VOID\r
2694 )\r
2695{\r
2696 MEMORY_PROFILE_CONTEXT *Context;\r
2697 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
2698 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
2699 MEMORY_PROFILE_CONTEXT_DATA *ContextData;\r
2700 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;\r
2701 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;\r
2702 LIST_ENTRY *SmramDriverInfoList;\r
2703 UINTN DriverIndex;\r
2704 LIST_ENTRY *DriverLink;\r
2705 LIST_ENTRY *AllocInfoList;\r
2706 UINTN AllocIndex;\r
2707 LIST_ENTRY *AllocLink;\r
e524f680 2708 BOOLEAN SmramProfileGettingStatus;\r
84edd20b
SZ
2709 UINTN TypeIndex;\r
2710\r
2711 ContextData = GetSmramProfileContext ();\r
2712 if (ContextData == NULL) {\r
2713 return ;\r
2714 }\r
2715\r
e524f680
SZ
2716 SmramProfileGettingStatus = mSmramProfileGettingStatus;\r
2717 mSmramProfileGettingStatus = TRUE;\r
84edd20b
SZ
2718\r
2719 Context = &ContextData->Context;\r
2720 DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n"));\r
2721 DEBUG ((EFI_D_INFO, "MEMORY_PROFILE_CONTEXT\n"));\r
2722\r
2723 DEBUG ((EFI_D_INFO, " CurrentTotalUsage - 0x%016lx\n", Context->CurrentTotalUsage));\r
2724 DEBUG ((EFI_D_INFO, " PeakTotalUsage - 0x%016lx\n", Context->PeakTotalUsage));\r
ca949d9d 2725 for (TypeIndex = 0; TypeIndex < sizeof (Context->CurrentTotalUsageByType) / sizeof (Context->CurrentTotalUsageByType[0]); TypeIndex++) {\r
84edd20b
SZ
2726 if ((Context->CurrentTotalUsageByType[TypeIndex] != 0) ||\r
2727 (Context->PeakTotalUsageByType[TypeIndex] != 0)) {\r
e524f680
SZ
2728 DEBUG ((EFI_D_INFO, " CurrentTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, Context->CurrentTotalUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex)));\r
2729 DEBUG ((EFI_D_INFO, " PeakTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, Context->PeakTotalUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex)));\r
84edd20b
SZ
2730 }\r
2731 }\r
2732 DEBUG ((EFI_D_INFO, " TotalImageSize - 0x%016lx\n", Context->TotalImageSize));\r
2733 DEBUG ((EFI_D_INFO, " ImageCount - 0x%08x\n", Context->ImageCount));\r
2734 DEBUG ((EFI_D_INFO, " SequenceCount - 0x%08x\n", Context->SequenceCount));\r
2735\r
2736 SmramDriverInfoList = ContextData->DriverInfoList;\r
2737 for (DriverLink = SmramDriverInfoList->ForwardLink, DriverIndex = 0;\r
2738 DriverLink != SmramDriverInfoList;\r
2739 DriverLink = DriverLink->ForwardLink, DriverIndex++) {\r
2740 DriverInfoData = CR (\r
2741 DriverLink,\r
2742 MEMORY_PROFILE_DRIVER_INFO_DATA,\r
2743 Link,\r
2744 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
2745 );\r
2746 DriverInfo = &DriverInfoData->DriverInfo;\r
2747 DEBUG ((EFI_D_INFO, " MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex));\r
2748 DEBUG ((EFI_D_INFO, " FileName - %g\n", &DriverInfo->FileName));\r
2749 DEBUG ((EFI_D_INFO, " ImageBase - 0x%016lx\n", DriverInfo->ImageBase));\r
2750 DEBUG ((EFI_D_INFO, " ImageSize - 0x%016lx\n", DriverInfo->ImageSize));\r
2751 DEBUG ((EFI_D_INFO, " EntryPoint - 0x%016lx\n", DriverInfo->EntryPoint));\r
2752 DEBUG ((EFI_D_INFO, " ImageSubsystem - 0x%04x\n", DriverInfo->ImageSubsystem));\r
2753 DEBUG ((EFI_D_INFO, " FileType - 0x%02x\n", DriverInfo->FileType));\r
2754 DEBUG ((EFI_D_INFO, " CurrentUsage - 0x%016lx\n", DriverInfo->CurrentUsage));\r
2755 DEBUG ((EFI_D_INFO, " PeakUsage - 0x%016lx\n", DriverInfo->PeakUsage));\r
ca949d9d 2756 for (TypeIndex = 0; TypeIndex < sizeof (DriverInfo->CurrentUsageByType) / sizeof (DriverInfo->CurrentUsageByType[0]); TypeIndex++) {\r
84edd20b
SZ
2757 if ((DriverInfo->CurrentUsageByType[TypeIndex] != 0) ||\r
2758 (DriverInfo->PeakUsageByType[TypeIndex] != 0)) {\r
e524f680
SZ
2759 DEBUG ((EFI_D_INFO, " CurrentUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, DriverInfo->CurrentUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex)));\r
2760 DEBUG ((EFI_D_INFO, " PeakUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, DriverInfo->PeakUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex)));\r
84edd20b
SZ
2761 }\r
2762 }\r
2763 DEBUG ((EFI_D_INFO, " AllocRecordCount - 0x%08x\n", DriverInfo->AllocRecordCount));\r
2764\r
2765 AllocInfoList = DriverInfoData->AllocInfoList;\r
2766 for (AllocLink = AllocInfoList->ForwardLink, AllocIndex = 0;\r
2767 AllocLink != AllocInfoList;\r
2768 AllocLink = AllocLink->ForwardLink, AllocIndex++) {\r
2769 AllocInfoData = CR (\r
2770 AllocLink,\r
2771 MEMORY_PROFILE_ALLOC_INFO_DATA,\r
2772 Link,\r
2773 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE\r
2774 );\r
2775 AllocInfo = &AllocInfoData->AllocInfo;\r
2776 DEBUG ((EFI_D_INFO, " MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex));\r
2777 DEBUG ((EFI_D_INFO, " CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo->CallerAddress, AllocInfo->CallerAddress - DriverInfo->ImageBase));\r
2778 DEBUG ((EFI_D_INFO, " SequenceId - 0x%08x\n", AllocInfo->SequenceId));\r
e524f680
SZ
2779 if ((AllocInfo->Action & MEMORY_PROFILE_ACTION_USER_DEFINED_MASK) != 0) {\r
2780 if (AllocInfoData->ActionString != NULL) {\r
2781 DEBUG ((EFI_D_INFO, " Action - 0x%08x (%a)\n", AllocInfo->Action, AllocInfoData->ActionString));\r
2782 } else {\r
2783 DEBUG ((EFI_D_INFO, " Action - 0x%08x (UserDefined-0x%08x)\n", AllocInfo->Action, AllocInfo->Action));\r
2784 }\r
2785 } else {\r
2786 DEBUG ((EFI_D_INFO, " Action - 0x%08x (%a)\n", AllocInfo->Action, ProfileActionToStr (AllocInfo->Action)));\r
2787 }\r
2788 DEBUG ((EFI_D_INFO, " MemoryType - 0x%08x (%a)\n", AllocInfo->MemoryType, ProfileMemoryTypeToStr (AllocInfo->MemoryType)));\r
84edd20b
SZ
2789 DEBUG ((EFI_D_INFO, " Buffer - 0x%016lx\n", AllocInfo->Buffer));\r
2790 DEBUG ((EFI_D_INFO, " Size - 0x%016lx\n", AllocInfo->Size));\r
2791 }\r
2792 }\r
2793\r
2794 DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n"));\r
2795\r
e524f680 2796 mSmramProfileGettingStatus = SmramProfileGettingStatus;\r
84edd20b
SZ
2797}\r
2798\r
2799/**\r
4be497df 2800 Dump SMRAM information.\r
84edd20b
SZ
2801\r
2802**/\r
2803VOID\r
2804DumpSmramInfo (\r
2805 VOID\r
2806 )\r
2807{\r
2808 DEBUG_CODE (\r
2809 if (IS_SMRAM_PROFILE_ENABLED) {\r
2810 DumpSmramProfile ();\r
2811 DumpFreePagesList ();\r
2812 DumpFreePoolList ();\r
2813 DumpSmramRange ();\r
2814 }\r
2815 );\r
2816}\r
2817\r