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