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