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