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