]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c
ff1940431c2f7f429245021fa1ce4445d557c64e
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Mem / MemoryProfileRecord.c
1 /** @file
2 Support routines for UEFI memory profile.
3
4 Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "DxeMain.h"
16 #include "Imem.h"
17
18 #define IS_UEFI_MEMORY_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0)
19
20 #define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
21 ((ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)))
22
23 typedef struct {
24 UINT32 Signature;
25 MEMORY_PROFILE_CONTEXT Context;
26 LIST_ENTRY *DriverInfoList;
27 } MEMORY_PROFILE_CONTEXT_DATA;
28
29 typedef struct {
30 UINT32 Signature;
31 MEMORY_PROFILE_DRIVER_INFO DriverInfo;
32 LIST_ENTRY *AllocInfoList;
33 CHAR8 *PdbString;
34 LIST_ENTRY Link;
35 } MEMORY_PROFILE_DRIVER_INFO_DATA;
36
37 typedef struct {
38 UINT32 Signature;
39 MEMORY_PROFILE_ALLOC_INFO AllocInfo;
40 CHAR8 *ActionString;
41 LIST_ENTRY Link;
42 } MEMORY_PROFILE_ALLOC_INFO_DATA;
43
44
45 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mImageQueue = INITIALIZE_LIST_HEAD_VARIABLE (mImageQueue);
46 GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA mMemoryProfileContext = {
47 MEMORY_PROFILE_CONTEXT_SIGNATURE,
48 {
49 {
50 MEMORY_PROFILE_CONTEXT_SIGNATURE,
51 sizeof (MEMORY_PROFILE_CONTEXT),
52 MEMORY_PROFILE_CONTEXT_REVISION
53 },
54 0,
55 0,
56 {0},
57 {0},
58 0,
59 0,
60 0
61 },
62 &mImageQueue,
63 };
64 GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA *mMemoryProfileContextPtr = NULL;
65
66 GLOBAL_REMOVE_IF_UNREFERENCED EFI_LOCK mMemoryProfileLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
67 GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mMemoryProfileGettingStatus = FALSE;
68 GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mMemoryProfileRecordingEnable = MEMORY_PROFILE_RECORDING_DISABLE;
69 GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_PROTOCOL *mMemoryProfileDriverPath;
70 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mMemoryProfileDriverPathSize;
71
72 /**
73 Get memory profile data.
74
75 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
76 @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer.
77 On return, points to the size of the data returned in ProfileBuffer.
78 @param[out] ProfileBuffer Profile buffer.
79
80 @return EFI_SUCCESS Get the memory profile data successfully.
81 @return EFI_UNSUPPORTED Memory profile is unsupported.
82 @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data.
83 ProfileSize is updated with the size required.
84
85 **/
86 EFI_STATUS
87 EFIAPI
88 ProfileProtocolGetData (
89 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
90 IN OUT UINT64 *ProfileSize,
91 OUT VOID *ProfileBuffer
92 );
93
94 /**
95 Register image to memory profile.
96
97 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
98 @param[in] FilePath File path of the image.
99 @param[in] ImageBase Image base address.
100 @param[in] ImageSize Image size.
101 @param[in] FileType File type of the image.
102
103 @return EFI_SUCCESS Register successfully.
104 @return EFI_UNSUPPORTED Memory profile is unsupported,
105 or memory profile for the image is not required.
106 @return EFI_OUT_OF_RESOURCE No enough resource for this register.
107
108 **/
109 EFI_STATUS
110 EFIAPI
111 ProfileProtocolRegisterImage (
112 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
113 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
114 IN PHYSICAL_ADDRESS ImageBase,
115 IN UINT64 ImageSize,
116 IN EFI_FV_FILETYPE FileType
117 );
118
119 /**
120 Unregister image from memory profile.
121
122 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
123 @param[in] FilePath File path of the image.
124 @param[in] ImageBase Image base address.
125 @param[in] ImageSize Image size.
126
127 @return EFI_SUCCESS Unregister successfully.
128 @return EFI_UNSUPPORTED Memory profile is unsupported,
129 or memory profile for the image is not required.
130 @return EFI_NOT_FOUND The image is not found.
131
132 **/
133 EFI_STATUS
134 EFIAPI
135 ProfileProtocolUnregisterImage (
136 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
137 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
138 IN PHYSICAL_ADDRESS ImageBase,
139 IN UINT64 ImageSize
140 );
141
142 /**
143 Get memory profile recording state.
144
145 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
146 @param[out] RecordingState Recording state.
147
148 @return EFI_SUCCESS Memory profile recording state is returned.
149 @return EFI_UNSUPPORTED Memory profile is unsupported.
150 @return EFI_INVALID_PARAMETER RecordingState is NULL.
151
152 **/
153 EFI_STATUS
154 EFIAPI
155 ProfileProtocolGetRecordingState (
156 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
157 OUT BOOLEAN *RecordingState
158 );
159
160 /**
161 Set memory profile recording state.
162
163 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
164 @param[in] RecordingState Recording state.
165
166 @return EFI_SUCCESS Set memory profile recording state successfully.
167 @return EFI_UNSUPPORTED Memory profile is unsupported.
168
169 **/
170 EFI_STATUS
171 EFIAPI
172 ProfileProtocolSetRecordingState (
173 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
174 IN BOOLEAN RecordingState
175 );
176
177 /**
178 Record memory profile of multilevel caller.
179
180 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
181 @param[in] CallerAddress Address of caller.
182 @param[in] Action Memory profile action.
183 @param[in] MemoryType Memory type.
184 EfiMaxMemoryType means the MemoryType is unknown.
185 @param[in] Buffer Buffer address.
186 @param[in] Size Buffer size.
187 @param[in] ActionString String for memory profile action.
188 Only needed for user defined allocate action.
189
190 @return EFI_SUCCESS Memory profile is updated.
191 @return EFI_UNSUPPORTED Memory profile is unsupported,
192 or memory profile for the image is not required,
193 or memory profile for the memory type is not required.
194 @return EFI_ACCESS_DENIED It is during memory profile data getting.
195 @return EFI_ABORTED Memory profile recording is not enabled.
196 @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action.
197 @return EFI_NOT_FOUND No matched allocate info found for free action.
198
199 **/
200 EFI_STATUS
201 EFIAPI
202 ProfileProtocolRecord (
203 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
204 IN PHYSICAL_ADDRESS CallerAddress,
205 IN MEMORY_PROFILE_ACTION Action,
206 IN EFI_MEMORY_TYPE MemoryType,
207 IN VOID *Buffer,
208 IN UINTN Size,
209 IN CHAR8 *ActionString OPTIONAL
210 );
211
212 GLOBAL_REMOVE_IF_UNREFERENCED EDKII_MEMORY_PROFILE_PROTOCOL mProfileProtocol = {
213 ProfileProtocolGetData,
214 ProfileProtocolRegisterImage,
215 ProfileProtocolUnregisterImage,
216 ProfileProtocolGetRecordingState,
217 ProfileProtocolSetRecordingState,
218 ProfileProtocolRecord,
219 };
220
221 /**
222 Acquire lock on mMemoryProfileLock.
223 **/
224 VOID
225 CoreAcquireMemoryProfileLock (
226 VOID
227 )
228 {
229 CoreAcquireLock (&mMemoryProfileLock);
230 }
231
232 /**
233 Release lock on mMemoryProfileLock.
234 **/
235 VOID
236 CoreReleaseMemoryProfileLock (
237 VOID
238 )
239 {
240 CoreReleaseLock (&mMemoryProfileLock);
241 }
242
243 /**
244 Return memory profile context.
245
246 @return Memory profile context.
247
248 **/
249 MEMORY_PROFILE_CONTEXT_DATA *
250 GetMemoryProfileContext (
251 VOID
252 )
253 {
254 return mMemoryProfileContextPtr;
255 }
256
257 /**
258 Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.
259 If Pe32Data is NULL, then ASSERT().
260
261 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
262
263 @return The Subsystem of the PE/COFF image.
264
265 **/
266 UINT16
267 InternalPeCoffGetSubsystem (
268 IN VOID *Pe32Data
269 )
270 {
271 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
272 EFI_IMAGE_DOS_HEADER *DosHdr;
273 UINT16 Magic;
274
275 ASSERT (Pe32Data != NULL);
276
277 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;
278 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
279 //
280 // DOS image header is present, so read the PE header after the DOS image header.
281 //
282 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
283 } else {
284 //
285 // DOS image header is not present, so PE header is at the image base.
286 //
287 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data;
288 }
289
290 if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
291 return Hdr.Te->Subsystem;
292 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
293 Magic = Hdr.Pe32->OptionalHeader.Magic;
294 if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
295 return Hdr.Pe32->OptionalHeader.Subsystem;
296 } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
297 return Hdr.Pe32Plus->OptionalHeader.Subsystem;
298 }
299 }
300
301 return 0x0000;
302 }
303
304 /**
305 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
306 into system memory with the PE/COFF Loader Library functions.
307
308 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
309 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
310 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
311 If Pe32Data is NULL, then ASSERT().
312 If EntryPoint is NULL, then ASSERT().
313
314 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
315 @param EntryPoint The pointer to entry point to the PE/COFF image to return.
316
317 @retval RETURN_SUCCESS EntryPoint was returned.
318 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
319
320 **/
321 RETURN_STATUS
322 InternalPeCoffGetEntryPoint (
323 IN VOID *Pe32Data,
324 OUT VOID **EntryPoint
325 )
326 {
327 EFI_IMAGE_DOS_HEADER *DosHdr;
328 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
329
330 ASSERT (Pe32Data != NULL);
331 ASSERT (EntryPoint != NULL);
332
333 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;
334 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
335 //
336 // DOS image header is present, so read the PE header after the DOS image header.
337 //
338 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
339 } else {
340 //
341 // DOS image header is not present, so PE header is at the image base.
342 //
343 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data;
344 }
345
346 //
347 // Calculate the entry point relative to the start of the image.
348 // AddressOfEntryPoint is common for PE32 & PE32+
349 //
350 if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
351 *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);
352 return RETURN_SUCCESS;
353 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
354 *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
355 return RETURN_SUCCESS;
356 }
357
358 return RETURN_UNSUPPORTED;
359 }
360
361 /**
362 Build driver info.
363
364 @param ContextData Memory profile context.
365 @param FileName File name of the image.
366 @param ImageBase Image base address.
367 @param ImageSize Image size.
368 @param EntryPoint Entry point of the image.
369 @param ImageSubsystem Image subsystem of the image.
370 @param FileType File type of the image.
371
372 @return Pointer to memory profile driver info.
373
374 **/
375 MEMORY_PROFILE_DRIVER_INFO_DATA *
376 BuildDriverInfo (
377 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,
378 IN EFI_GUID *FileName,
379 IN PHYSICAL_ADDRESS ImageBase,
380 IN UINT64 ImageSize,
381 IN PHYSICAL_ADDRESS EntryPoint,
382 IN UINT16 ImageSubsystem,
383 IN EFI_FV_FILETYPE FileType
384 )
385 {
386 EFI_STATUS Status;
387 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;
388 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
389 VOID *EntryPointInImage;
390 CHAR8 *PdbString;
391 UINTN PdbSize;
392 UINTN PdbOccupiedSize;
393
394 PdbSize = 0;
395 PdbOccupiedSize = 0;
396 PdbString = NULL;
397 if (ImageBase != 0) {
398 PdbString = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageBase);
399 if (PdbString != NULL) {
400 PdbSize = AsciiStrSize (PdbString);
401 PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64));
402 }
403 }
404
405 //
406 // Use CoreInternalAllocatePool() that will not update profile for this AllocatePool action.
407 //
408 Status = CoreInternalAllocatePool (
409 EfiBootServicesData,
410 sizeof (*DriverInfoData) + sizeof (LIST_ENTRY) + PdbSize,
411 (VOID **) &DriverInfoData
412 );
413 if (EFI_ERROR (Status)) {
414 return NULL;
415 }
416 ASSERT (DriverInfoData != NULL);
417
418 ZeroMem (DriverInfoData, sizeof (*DriverInfoData));
419
420 DriverInfo = &DriverInfoData->DriverInfo;
421 DriverInfoData->Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE;
422 DriverInfo->Header.Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE;
423 DriverInfo->Header.Length = (UINT16) (sizeof (MEMORY_PROFILE_DRIVER_INFO) + PdbOccupiedSize);
424 DriverInfo->Header.Revision = MEMORY_PROFILE_DRIVER_INFO_REVISION;
425 if (FileName != NULL) {
426 CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID));
427 }
428 DriverInfo->ImageBase = ImageBase;
429 DriverInfo->ImageSize = ImageSize;
430 DriverInfo->EntryPoint = EntryPoint;
431 DriverInfo->ImageSubsystem = ImageSubsystem;
432 if ((EntryPoint != 0) && ((EntryPoint < ImageBase) || (EntryPoint >= (ImageBase + ImageSize)))) {
433 //
434 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
435 // So patch ImageBuffer here to align the EntryPoint.
436 //
437 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageBase, &EntryPointInImage);
438 ASSERT_EFI_ERROR (Status);
439 DriverInfo->ImageBase = ImageBase + EntryPoint - (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;
440 }
441 DriverInfo->FileType = FileType;
442 DriverInfoData->AllocInfoList = (LIST_ENTRY *) (DriverInfoData + 1);
443 InitializeListHead (DriverInfoData->AllocInfoList);
444 DriverInfo->CurrentUsage = 0;
445 DriverInfo->PeakUsage = 0;
446 DriverInfo->AllocRecordCount = 0;
447 if (PdbSize != 0) {
448 DriverInfo->PdbStringOffset = (UINT16) sizeof (MEMORY_PROFILE_DRIVER_INFO);
449 DriverInfoData->PdbString = (CHAR8 *) (DriverInfoData->AllocInfoList + 1);
450 CopyMem (DriverInfoData->PdbString, PdbString, PdbSize);
451 } else {
452 DriverInfo->PdbStringOffset = 0;
453 DriverInfoData->PdbString = NULL;
454 }
455
456 InsertTailList (ContextData->DriverInfoList, &DriverInfoData->Link);
457 ContextData->Context.ImageCount ++;
458 ContextData->Context.TotalImageSize += DriverInfo->ImageSize;
459
460 return DriverInfoData;
461 }
462
463 /**
464 Return if record for this driver is needed..
465
466 @param DriverFilePath Driver file path.
467
468 @retval TRUE Record for this driver is needed.
469 @retval FALSE Record for this driver is not needed.
470
471 **/
472 BOOLEAN
473 NeedRecordThisDriver (
474 IN EFI_DEVICE_PATH_PROTOCOL *DriverFilePath
475 )
476 {
477 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
478 EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance;
479 UINTN DevicePathSize;
480 UINTN FilePathSize;
481
482 if (!IsDevicePathValid (mMemoryProfileDriverPath, mMemoryProfileDriverPathSize)) {
483 //
484 // Invalid Device Path means record all.
485 //
486 return TRUE;
487 }
488
489 //
490 // Record FilePath without END node.
491 //
492 FilePathSize = GetDevicePathSize (DriverFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
493
494 DevicePathInstance = mMemoryProfileDriverPath;
495 do {
496 //
497 // Find END node (it might be END_ENTIRE or END_INSTANCE).
498 //
499 TmpDevicePath = DevicePathInstance;
500 while (!IsDevicePathEndType (TmpDevicePath)) {
501 TmpDevicePath = NextDevicePathNode (TmpDevicePath);
502 }
503
504 //
505 // Do not compare END node.
506 //
507 DevicePathSize = (UINTN)TmpDevicePath - (UINTN)DevicePathInstance;
508 if ((FilePathSize == DevicePathSize) &&
509 (CompareMem (DriverFilePath, DevicePathInstance, DevicePathSize) == 0)) {
510 return TRUE;
511 }
512
513 //
514 // Get next instance.
515 //
516 DevicePathInstance = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)DevicePathInstance + DevicePathSize + DevicePathNodeLength(TmpDevicePath));
517 } while (DevicePathSubType (TmpDevicePath) != END_ENTIRE_DEVICE_PATH_SUBTYPE);
518
519 return FALSE;
520 }
521
522 /**
523 Register DXE Core to memory profile.
524
525 @param HobStart The start address of the HOB.
526 @param ContextData Memory profile context.
527
528 @retval TRUE Register success.
529 @retval FALSE Register fail.
530
531 **/
532 BOOLEAN
533 RegisterDxeCore (
534 IN VOID *HobStart,
535 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData
536 )
537 {
538 EFI_PEI_HOB_POINTERS DxeCoreHob;
539 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
540 PHYSICAL_ADDRESS ImageBase;
541 UINT8 TempBuffer[sizeof(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH_PROTOCOL)];
542 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;
543
544 ASSERT (ContextData != NULL);
545
546 //
547 // Searching for image hob
548 //
549 DxeCoreHob.Raw = HobStart;
550 while ((DxeCoreHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw)) != NULL) {
551 if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
552 //
553 // Find Dxe Core HOB
554 //
555 break;
556 }
557 DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob);
558 }
559 ASSERT (DxeCoreHob.Raw != NULL);
560
561 FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempBuffer;
562 EfiInitializeFwVolDevicepathNode (FilePath, &DxeCoreHob.MemoryAllocationModule->ModuleName);
563 SetDevicePathEndNode (FilePath + 1);
564
565 if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *) FilePath)) {
566 return FALSE;
567 }
568
569 ImageBase = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;
570 DriverInfoData = BuildDriverInfo (
571 ContextData,
572 &DxeCoreHob.MemoryAllocationModule->ModuleName,
573 ImageBase,
574 DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength,
575 DxeCoreHob.MemoryAllocationModule->EntryPoint,
576 InternalPeCoffGetSubsystem ((VOID *) (UINTN) ImageBase),
577 EFI_FV_FILETYPE_DXE_CORE
578 );
579 if (DriverInfoData == NULL) {
580 return FALSE;
581 }
582
583 return TRUE;
584 }
585
586 /**
587 Initialize memory profile.
588
589 @param HobStart The start address of the HOB.
590
591 **/
592 VOID
593 MemoryProfileInit (
594 IN VOID *HobStart
595 )
596 {
597 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
598
599 if (!IS_UEFI_MEMORY_PROFILE_ENABLED) {
600 return;
601 }
602
603 ContextData = GetMemoryProfileContext ();
604 if (ContextData != NULL) {
605 return;
606 }
607
608 mMemoryProfileGettingStatus = FALSE;
609 if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT7) != 0) {
610 mMemoryProfileRecordingEnable = MEMORY_PROFILE_RECORDING_DISABLE;
611 } else {
612 mMemoryProfileRecordingEnable = MEMORY_PROFILE_RECORDING_ENABLE;
613 }
614 mMemoryProfileDriverPathSize = PcdGetSize (PcdMemoryProfileDriverPath);
615 mMemoryProfileDriverPath = AllocateCopyPool (mMemoryProfileDriverPathSize, PcdGetPtr (PcdMemoryProfileDriverPath));
616 mMemoryProfileContextPtr = &mMemoryProfileContext;
617
618 RegisterDxeCore (HobStart, &mMemoryProfileContext);
619
620 DEBUG ((EFI_D_INFO, "MemoryProfileInit MemoryProfileContext - 0x%x\n", &mMemoryProfileContext));
621 }
622
623 /**
624 Install memory profile protocol.
625
626 **/
627 VOID
628 MemoryProfileInstallProtocol (
629 VOID
630 )
631 {
632 EFI_HANDLE Handle;
633 EFI_STATUS Status;
634
635 if (!IS_UEFI_MEMORY_PROFILE_ENABLED) {
636 return;
637 }
638
639 Handle = NULL;
640 Status = CoreInstallMultipleProtocolInterfaces (
641 &Handle,
642 &gEdkiiMemoryProfileGuid,
643 &mProfileProtocol,
644 NULL
645 );
646 ASSERT_EFI_ERROR (Status);
647 }
648
649 /**
650 Get the GUID file name from the file path.
651
652 @param FilePath File path.
653
654 @return The GUID file name from the file path.
655
656 **/
657 EFI_GUID *
658 GetFileNameFromFilePath (
659 IN EFI_DEVICE_PATH_PROTOCOL *FilePath
660 )
661 {
662 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *ThisFilePath;
663 EFI_GUID *FileName;
664
665 FileName = NULL;
666 if (FilePath != NULL) {
667 ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) FilePath;
668 while (!IsDevicePathEnd (ThisFilePath)) {
669 FileName = EfiGetNameGuidFromFwVolDevicePathNode (ThisFilePath);
670 if (FileName != NULL) {
671 break;
672 }
673 ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) NextDevicePathNode (ThisFilePath);
674 }
675 }
676
677 return FileName;
678 }
679
680 /**
681 Register image to memory profile.
682
683 @param DriverEntry Image info.
684 @param FileType Image file type.
685
686 @return EFI_SUCCESS Register successfully.
687 @return EFI_UNSUPPORTED Memory profile is unsupported,
688 or memory profile for the image is not required.
689 @return EFI_OUT_OF_RESOURCES No enough resource for this register.
690
691 **/
692 EFI_STATUS
693 RegisterMemoryProfileImage (
694 IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry,
695 IN EFI_FV_FILETYPE FileType
696 )
697 {
698 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
699 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
700
701 if (!IS_UEFI_MEMORY_PROFILE_ENABLED) {
702 return EFI_UNSUPPORTED;
703 }
704
705 if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) {
706 return EFI_UNSUPPORTED;
707 }
708
709 ContextData = GetMemoryProfileContext ();
710 if (ContextData == NULL) {
711 return EFI_UNSUPPORTED;
712 }
713
714 DriverInfoData = BuildDriverInfo (
715 ContextData,
716 GetFileNameFromFilePath (DriverEntry->Info.FilePath),
717 DriverEntry->ImageContext.ImageAddress,
718 DriverEntry->ImageContext.ImageSize,
719 DriverEntry->ImageContext.EntryPoint,
720 DriverEntry->ImageContext.ImageType,
721 FileType
722 );
723 if (DriverInfoData == NULL) {
724 return EFI_OUT_OF_RESOURCES;
725 }
726
727 return EFI_SUCCESS;
728 }
729
730 /**
731 Search image from memory profile.
732
733 @param ContextData Memory profile context.
734 @param FileName Image file name.
735 @param Address Image Address.
736
737 @return Pointer to memory profile driver info.
738
739 **/
740 MEMORY_PROFILE_DRIVER_INFO_DATA *
741 GetMemoryProfileDriverInfoByFileNameAndAddress (
742 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,
743 IN EFI_GUID *FileName,
744 IN PHYSICAL_ADDRESS Address
745 )
746 {
747 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;
748 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
749 LIST_ENTRY *DriverLink;
750 LIST_ENTRY *DriverInfoList;
751
752 DriverInfoList = ContextData->DriverInfoList;
753
754 for (DriverLink = DriverInfoList->ForwardLink;
755 DriverLink != DriverInfoList;
756 DriverLink = DriverLink->ForwardLink) {
757 DriverInfoData = CR (
758 DriverLink,
759 MEMORY_PROFILE_DRIVER_INFO_DATA,
760 Link,
761 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
762 );
763 DriverInfo = &DriverInfoData->DriverInfo;
764 if ((CompareGuid (&DriverInfo->FileName, FileName)) &&
765 (Address >= DriverInfo->ImageBase) &&
766 (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) {
767 return DriverInfoData;
768 }
769 }
770
771 return NULL;
772 }
773
774 /**
775 Search image from memory profile.
776 It will return image, if (Address >= ImageBuffer) AND (Address < ImageBuffer + ImageSize).
777
778 @param ContextData Memory profile context.
779 @param Address Image or Function address.
780
781 @return Pointer to memory profile driver info.
782
783 **/
784 MEMORY_PROFILE_DRIVER_INFO_DATA *
785 GetMemoryProfileDriverInfoFromAddress (
786 IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,
787 IN PHYSICAL_ADDRESS Address
788 )
789 {
790 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;
791 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
792 LIST_ENTRY *DriverLink;
793 LIST_ENTRY *DriverInfoList;
794
795 DriverInfoList = ContextData->DriverInfoList;
796
797 for (DriverLink = DriverInfoList->ForwardLink;
798 DriverLink != DriverInfoList;
799 DriverLink = DriverLink->ForwardLink) {
800 DriverInfoData = CR (
801 DriverLink,
802 MEMORY_PROFILE_DRIVER_INFO_DATA,
803 Link,
804 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
805 );
806 DriverInfo = &DriverInfoData->DriverInfo;
807 if ((Address >= DriverInfo->ImageBase) &&
808 (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) {
809 return DriverInfoData;
810 }
811 }
812
813 return NULL;
814 }
815
816 /**
817 Unregister image from memory profile.
818
819 @param DriverEntry Image info.
820
821 @return EFI_SUCCESS Unregister successfully.
822 @return EFI_UNSUPPORTED Memory profile is unsupported,
823 or memory profile for the image is not required.
824 @return EFI_NOT_FOUND The image is not found.
825
826 **/
827 EFI_STATUS
828 UnregisterMemoryProfileImage (
829 IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry
830 )
831 {
832 EFI_STATUS Status;
833 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
834 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
835 EFI_GUID *FileName;
836 PHYSICAL_ADDRESS ImageAddress;
837 VOID *EntryPointInImage;
838
839 if (!IS_UEFI_MEMORY_PROFILE_ENABLED) {
840 return EFI_UNSUPPORTED;
841 }
842
843 if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) {
844 return EFI_UNSUPPORTED;
845 }
846
847 ContextData = GetMemoryProfileContext ();
848 if (ContextData == NULL) {
849 return EFI_UNSUPPORTED;
850 }
851
852 DriverInfoData = NULL;
853 FileName = GetFileNameFromFilePath (DriverEntry->Info.FilePath);
854 ImageAddress = DriverEntry->ImageContext.ImageAddress;
855 if ((DriverEntry->ImageContext.EntryPoint < ImageAddress) || (DriverEntry->ImageContext.EntryPoint >= (ImageAddress + DriverEntry->ImageContext.ImageSize))) {
856 //
857 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
858 // So patch ImageAddress here to align the EntryPoint.
859 //
860 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageAddress, &EntryPointInImage);
861 ASSERT_EFI_ERROR (Status);
862 ImageAddress = ImageAddress + (UINTN) DriverEntry->ImageContext.EntryPoint - (UINTN) EntryPointInImage;
863 }
864 if (FileName != NULL) {
865 DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress);
866 }
867 if (DriverInfoData == NULL) {
868 DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageAddress);
869 }
870 if (DriverInfoData == NULL) {
871 return EFI_NOT_FOUND;
872 }
873
874 ContextData->Context.TotalImageSize -= DriverInfoData->DriverInfo.ImageSize;
875
876 // Keep the ImageBase for RVA calculation in Application.
877 //DriverInfoData->DriverInfo.ImageBase = 0;
878 DriverInfoData->DriverInfo.ImageSize = 0;
879
880 if (DriverInfoData->DriverInfo.PeakUsage == 0) {
881 ContextData->Context.ImageCount --;
882 RemoveEntryList (&DriverInfoData->Link);
883 //
884 // Use CoreInternalFreePool() that will not update profile for this FreePool action.
885 //
886 CoreInternalFreePool (DriverInfoData, NULL);
887 }
888
889 return EFI_SUCCESS;
890 }
891
892 /**
893 Return if this memory type needs to be recorded into memory profile.
894 If BIOS memory type (0 ~ EfiMaxMemoryType - 1), it checks bit (1 << MemoryType).
895 If OS memory type (0x80000000 ~ 0xFFFFFFFF), it checks bit63 - 0x8000000000000000.
896 If OEM memory type (0x70000000 ~ 0x7FFFFFFF), it checks bit62 - 0x4000000000000000.
897
898 @param MemoryType Memory type.
899
900 @retval TRUE This memory type need to be recorded.
901 @retval FALSE This memory type need not to be recorded.
902
903 **/
904 BOOLEAN
905 CoreNeedRecordProfile (
906 IN EFI_MEMORY_TYPE MemoryType
907 )
908 {
909 UINT64 TestBit;
910
911 if ((UINT32) MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) {
912 TestBit = BIT63;
913 } else if ((UINT32) MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) {
914 TestBit = BIT62;
915 } else {
916 TestBit = LShiftU64 (1, MemoryType);
917 }
918
919 if ((PcdGet64 (PcdMemoryProfileMemoryType) & TestBit) != 0) {
920 return TRUE;
921 } else {
922 return FALSE;
923 }
924 }
925
926 /**
927 Convert EFI memory type to profile memory index. The rule is:
928 If BIOS memory type (0 ~ EfiMaxMemoryType - 1), ProfileMemoryIndex = MemoryType.
929 If OS memory type (0x80000000 ~ 0xFFFFFFFF), ProfileMemoryIndex = EfiMaxMemoryType.
930 If OEM memory type (0x70000000 ~ 0x7FFFFFFF), ProfileMemoryIndex = EfiMaxMemoryType + 1.
931
932 @param MemoryType Memory type.
933
934 @return Profile memory index.
935
936 **/
937 UINTN
938 GetProfileMemoryIndex (
939 IN EFI_MEMORY_TYPE MemoryType
940 )
941 {
942 if ((UINT32) MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) {
943 return EfiMaxMemoryType;
944 } else if ((UINT32) MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) {
945 return EfiMaxMemoryType + 1;
946 } else {
947 return MemoryType;
948 }
949 }
950
951 /**
952 Update memory profile Allocate information.
953
954 @param CallerAddress Address of caller who call Allocate.
955 @param Action This Allocate action.
956 @param MemoryType Memory type.
957 @param Size Buffer size.
958 @param Buffer Buffer address.
959 @param ActionString String for memory profile action.
960
961 @return EFI_SUCCESS Memory profile is updated.
962 @return EFI_UNSUPPORTED Memory profile is unsupported,
963 or memory profile for the image is not required.
964 @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action.
965
966 **/
967 EFI_STATUS
968 CoreUpdateProfileAllocate (
969 IN PHYSICAL_ADDRESS CallerAddress,
970 IN MEMORY_PROFILE_ACTION Action,
971 IN EFI_MEMORY_TYPE MemoryType,
972 IN UINTN Size,
973 IN VOID *Buffer,
974 IN CHAR8 *ActionString OPTIONAL
975 )
976 {
977 EFI_STATUS Status;
978 MEMORY_PROFILE_CONTEXT *Context;
979 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;
980 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;
981 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
982 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
983 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;
984 UINTN ProfileMemoryIndex;
985 MEMORY_PROFILE_ACTION BasicAction;
986 UINTN ActionStringSize;
987 UINTN ActionStringOccupiedSize;
988
989 BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK;
990
991 ContextData = GetMemoryProfileContext ();
992 if (ContextData == NULL) {
993 return EFI_UNSUPPORTED;
994 }
995
996 DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress);
997 if (DriverInfoData == NULL) {
998 return EFI_UNSUPPORTED;
999 }
1000
1001 ActionStringSize = 0;
1002 ActionStringOccupiedSize = 0;
1003 if (ActionString != NULL) {
1004 ActionStringSize = AsciiStrSize (ActionString);
1005 ActionStringOccupiedSize = GET_OCCUPIED_SIZE (ActionStringSize, sizeof (UINT64));
1006 }
1007
1008 //
1009 // Use CoreInternalAllocatePool() that will not update profile for this AllocatePool action.
1010 //
1011 AllocInfoData = NULL;
1012 Status = CoreInternalAllocatePool (
1013 EfiBootServicesData,
1014 sizeof (*AllocInfoData) + ActionStringSize,
1015 (VOID **) &AllocInfoData
1016 );
1017 if (EFI_ERROR (Status)) {
1018 return EFI_OUT_OF_RESOURCES;
1019 }
1020 ASSERT (AllocInfoData != NULL);
1021
1022 //
1023 // Only update SequenceCount if and only if it is basic action.
1024 //
1025 if (Action == BasicAction) {
1026 ContextData->Context.SequenceCount ++;
1027 }
1028
1029 AllocInfo = &AllocInfoData->AllocInfo;
1030 AllocInfoData->Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE;
1031 AllocInfo->Header.Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE;
1032 AllocInfo->Header.Length = (UINT16) (sizeof (MEMORY_PROFILE_ALLOC_INFO) + ActionStringOccupiedSize);
1033 AllocInfo->Header.Revision = MEMORY_PROFILE_ALLOC_INFO_REVISION;
1034 AllocInfo->CallerAddress = CallerAddress;
1035 AllocInfo->SequenceId = ContextData->Context.SequenceCount;
1036 AllocInfo->Action = Action;
1037 AllocInfo->MemoryType = MemoryType;
1038 AllocInfo->Buffer = (PHYSICAL_ADDRESS) (UINTN) Buffer;
1039 AllocInfo->Size = Size;
1040 if (ActionString != NULL) {
1041 AllocInfo->ActionStringOffset = (UINT16) sizeof (MEMORY_PROFILE_ALLOC_INFO);
1042 AllocInfoData->ActionString = (CHAR8 *) (AllocInfoData + 1);
1043 CopyMem (AllocInfoData->ActionString, ActionString, ActionStringSize);
1044 } else {
1045 AllocInfo->ActionStringOffset = 0;
1046 AllocInfoData->ActionString = NULL;
1047 }
1048
1049 InsertTailList (DriverInfoData->AllocInfoList, &AllocInfoData->Link);
1050
1051 Context = &ContextData->Context;
1052 DriverInfo = &DriverInfoData->DriverInfo;
1053 DriverInfo->AllocRecordCount ++;
1054
1055 //
1056 // Update summary if and only if it is basic action.
1057 //
1058 if (Action == BasicAction) {
1059 ProfileMemoryIndex = GetProfileMemoryIndex (MemoryType);
1060
1061 DriverInfo->CurrentUsage += Size;
1062 if (DriverInfo->PeakUsage < DriverInfo->CurrentUsage) {
1063 DriverInfo->PeakUsage = DriverInfo->CurrentUsage;
1064 }
1065 DriverInfo->CurrentUsageByType[ProfileMemoryIndex] += Size;
1066 if (DriverInfo->PeakUsageByType[ProfileMemoryIndex] < DriverInfo->CurrentUsageByType[ProfileMemoryIndex]) {
1067 DriverInfo->PeakUsageByType[ProfileMemoryIndex] = DriverInfo->CurrentUsageByType[ProfileMemoryIndex];
1068 }
1069
1070 Context->CurrentTotalUsage += Size;
1071 if (Context->PeakTotalUsage < Context->CurrentTotalUsage) {
1072 Context->PeakTotalUsage = Context->CurrentTotalUsage;
1073 }
1074 Context->CurrentTotalUsageByType[ProfileMemoryIndex] += Size;
1075 if (Context->PeakTotalUsageByType[ProfileMemoryIndex] < Context->CurrentTotalUsageByType[ProfileMemoryIndex]) {
1076 Context->PeakTotalUsageByType[ProfileMemoryIndex] = Context->CurrentTotalUsageByType[ProfileMemoryIndex];
1077 }
1078 }
1079
1080 return EFI_SUCCESS;
1081 }
1082
1083 /**
1084 Get memory profile alloc info from memory profile.
1085
1086 @param DriverInfoData Driver info.
1087 @param BasicAction This Free basic action.
1088 @param Size Buffer size.
1089 @param Buffer Buffer address.
1090
1091 @return Pointer to memory profile alloc info.
1092
1093 **/
1094 MEMORY_PROFILE_ALLOC_INFO_DATA *
1095 GetMemoryProfileAllocInfoFromAddress (
1096 IN MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData,
1097 IN MEMORY_PROFILE_ACTION BasicAction,
1098 IN UINTN Size,
1099 IN VOID *Buffer
1100 )
1101 {
1102 LIST_ENTRY *AllocInfoList;
1103 LIST_ENTRY *AllocLink;
1104 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;
1105 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;
1106
1107 AllocInfoList = DriverInfoData->AllocInfoList;
1108
1109 for (AllocLink = AllocInfoList->ForwardLink;
1110 AllocLink != AllocInfoList;
1111 AllocLink = AllocLink->ForwardLink) {
1112 AllocInfoData = CR (
1113 AllocLink,
1114 MEMORY_PROFILE_ALLOC_INFO_DATA,
1115 Link,
1116 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
1117 );
1118 AllocInfo = &AllocInfoData->AllocInfo;
1119 if ((AllocInfo->Action & MEMORY_PROFILE_ACTION_BASIC_MASK) != BasicAction) {
1120 continue;
1121 }
1122 switch (BasicAction) {
1123 case MemoryProfileActionAllocatePages:
1124 if ((AllocInfo->Buffer <= (PHYSICAL_ADDRESS) (UINTN) Buffer) &&
1125 ((AllocInfo->Buffer + AllocInfo->Size) >= ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size))) {
1126 return AllocInfoData;
1127 }
1128 break;
1129 case MemoryProfileActionAllocatePool:
1130 if (AllocInfo->Buffer == (PHYSICAL_ADDRESS) (UINTN) Buffer) {
1131 return AllocInfoData;
1132 }
1133 break;
1134 default:
1135 ASSERT (FALSE);
1136 break;
1137 }
1138 }
1139
1140 return NULL;
1141 }
1142
1143 /**
1144 Update memory profile Free information.
1145
1146 @param CallerAddress Address of caller who call Free.
1147 @param Action This Free action.
1148 @param Size Buffer size.
1149 @param Buffer Buffer address.
1150
1151 @return EFI_SUCCESS Memory profile is updated.
1152 @return EFI_UNSUPPORTED Memory profile is unsupported.
1153 @return EFI_NOT_FOUND No matched allocate info found for free action.
1154
1155 **/
1156 EFI_STATUS
1157 CoreUpdateProfileFree (
1158 IN PHYSICAL_ADDRESS CallerAddress,
1159 IN MEMORY_PROFILE_ACTION Action,
1160 IN UINTN Size,
1161 IN VOID *Buffer
1162 )
1163 {
1164 MEMORY_PROFILE_CONTEXT *Context;
1165 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;
1166 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;
1167 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
1168 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
1169 LIST_ENTRY *DriverLink;
1170 LIST_ENTRY *DriverInfoList;
1171 MEMORY_PROFILE_DRIVER_INFO_DATA *ThisDriverInfoData;
1172 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;
1173 UINTN ProfileMemoryIndex;
1174 MEMORY_PROFILE_ACTION BasicAction;
1175 BOOLEAN Found;
1176
1177 BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK;
1178
1179 ContextData = GetMemoryProfileContext ();
1180 if (ContextData == NULL) {
1181 return EFI_UNSUPPORTED;
1182 }
1183
1184 DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress);
1185
1186 //
1187 // Do not return if DriverInfoData == NULL here,
1188 // because driver A might free memory allocated by driver B.
1189 //
1190
1191 //
1192 // Need use do-while loop to find all possible records,
1193 // because one address might be recorded multiple times.
1194 //
1195 Found = FALSE;
1196 AllocInfoData = NULL;
1197 do {
1198 if (DriverInfoData != NULL) {
1199 switch (BasicAction) {
1200 case MemoryProfileActionFreePages:
1201 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer);
1202 break;
1203 case MemoryProfileActionFreePool:
1204 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer);
1205 break;
1206 default:
1207 ASSERT (FALSE);
1208 AllocInfoData = NULL;
1209 break;
1210 }
1211 }
1212 if (AllocInfoData == NULL) {
1213 //
1214 // Legal case, because driver A might free memory allocated by driver B, by some protocol.
1215 //
1216 DriverInfoList = ContextData->DriverInfoList;
1217
1218 for (DriverLink = DriverInfoList->ForwardLink;
1219 DriverLink != DriverInfoList;
1220 DriverLink = DriverLink->ForwardLink) {
1221 ThisDriverInfoData = CR (
1222 DriverLink,
1223 MEMORY_PROFILE_DRIVER_INFO_DATA,
1224 Link,
1225 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1226 );
1227 switch (BasicAction) {
1228 case MemoryProfileActionFreePages:
1229 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer);
1230 break;
1231 case MemoryProfileActionFreePool:
1232 AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer);
1233 break;
1234 default:
1235 ASSERT (FALSE);
1236 AllocInfoData = NULL;
1237 break;
1238 }
1239 if (AllocInfoData != NULL) {
1240 DriverInfoData = ThisDriverInfoData;
1241 break;
1242 }
1243 }
1244
1245 if (AllocInfoData == NULL) {
1246 //
1247 // If (!Found), no matched allocate info is found for this free action.
1248 // It is because the specified memory type allocate actions have been filtered by
1249 // CoreNeedRecordProfile(), but free actions may have no memory type information,
1250 // they can not be filtered by CoreNeedRecordProfile(). Then, they will be
1251 // filtered here.
1252 //
1253 // If (Found), it is normal exit path.
1254 return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
1255 }
1256 }
1257
1258 ASSERT (DriverInfoData != NULL);
1259 ASSERT (AllocInfoData != NULL);
1260
1261 Found = TRUE;
1262
1263 Context = &ContextData->Context;
1264 DriverInfo = &DriverInfoData->DriverInfo;
1265 AllocInfo = &AllocInfoData->AllocInfo;
1266
1267 DriverInfo->AllocRecordCount --;
1268 //
1269 // Update summary if and only if it is basic action.
1270 //
1271 if (AllocInfo->Action == (AllocInfo->Action & MEMORY_PROFILE_ACTION_BASIC_MASK)) {
1272 ProfileMemoryIndex = GetProfileMemoryIndex (AllocInfo->MemoryType);
1273
1274 Context->CurrentTotalUsage -= AllocInfo->Size;
1275 Context->CurrentTotalUsageByType[ProfileMemoryIndex] -= AllocInfo->Size;
1276
1277 DriverInfo->CurrentUsage -= AllocInfo->Size;
1278 DriverInfo->CurrentUsageByType[ProfileMemoryIndex] -= AllocInfo->Size;
1279 }
1280
1281 RemoveEntryList (&AllocInfoData->Link);
1282
1283 if (BasicAction == MemoryProfileActionFreePages) {
1284 if (AllocInfo->Buffer != (PHYSICAL_ADDRESS) (UINTN) Buffer) {
1285 CoreUpdateProfileAllocate (
1286 AllocInfo->CallerAddress,
1287 AllocInfo->Action,
1288 AllocInfo->MemoryType,
1289 (UINTN) ((PHYSICAL_ADDRESS) (UINTN) Buffer - AllocInfo->Buffer),
1290 (VOID *) (UINTN) AllocInfo->Buffer,
1291 AllocInfoData->ActionString
1292 );
1293 }
1294 if (AllocInfo->Buffer + AllocInfo->Size != ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)) {
1295 CoreUpdateProfileAllocate (
1296 AllocInfo->CallerAddress,
1297 AllocInfo->Action,
1298 AllocInfo->MemoryType,
1299 (UINTN) ((AllocInfo->Buffer + AllocInfo->Size) - ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)),
1300 (VOID *) ((UINTN) Buffer + Size),
1301 AllocInfoData->ActionString
1302 );
1303 }
1304 }
1305
1306 //
1307 // Use CoreInternalFreePool() that will not update profile for this FreePool action.
1308 //
1309 CoreInternalFreePool (AllocInfoData, NULL);
1310 } while (TRUE);
1311 }
1312
1313 /**
1314 Update memory profile information.
1315
1316 @param CallerAddress Address of caller who call Allocate or Free.
1317 @param Action This Allocate or Free action.
1318 @param MemoryType Memory type.
1319 EfiMaxMemoryType means the MemoryType is unknown.
1320 @param Size Buffer size.
1321 @param Buffer Buffer address.
1322 @param ActionString String for memory profile action.
1323 Only needed for user defined allocate action.
1324
1325 @return EFI_SUCCESS Memory profile is updated.
1326 @return EFI_UNSUPPORTED Memory profile is unsupported,
1327 or memory profile for the image is not required,
1328 or memory profile for the memory type is not required.
1329 @return EFI_ACCESS_DENIED It is during memory profile data getting.
1330 @return EFI_ABORTED Memory profile recording is not enabled.
1331 @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action.
1332 @return EFI_NOT_FOUND No matched allocate info found for free action.
1333
1334 **/
1335 EFI_STATUS
1336 EFIAPI
1337 CoreUpdateProfile (
1338 IN PHYSICAL_ADDRESS CallerAddress,
1339 IN MEMORY_PROFILE_ACTION Action,
1340 IN EFI_MEMORY_TYPE MemoryType,
1341 IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool
1342 IN VOID *Buffer,
1343 IN CHAR8 *ActionString OPTIONAL
1344 )
1345 {
1346 EFI_STATUS Status;
1347 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
1348 MEMORY_PROFILE_ACTION BasicAction;
1349
1350 if (!IS_UEFI_MEMORY_PROFILE_ENABLED) {
1351 return EFI_UNSUPPORTED;
1352 }
1353
1354 if (mMemoryProfileGettingStatus) {
1355 return EFI_ACCESS_DENIED;
1356 }
1357
1358 if (!mMemoryProfileRecordingEnable) {
1359 return EFI_ABORTED;
1360 }
1361
1362 //
1363 // Get the basic action to know how to process the record
1364 //
1365 BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK;
1366
1367 //
1368 // EfiMaxMemoryType means the MemoryType is unknown.
1369 //
1370 if (MemoryType != EfiMaxMemoryType) {
1371 //
1372 // Only record limited MemoryType.
1373 //
1374 if (!CoreNeedRecordProfile (MemoryType)) {
1375 return EFI_UNSUPPORTED;
1376 }
1377 }
1378
1379 ContextData = GetMemoryProfileContext ();
1380 if (ContextData == NULL) {
1381 return EFI_UNSUPPORTED;
1382 }
1383
1384 CoreAcquireMemoryProfileLock ();
1385 switch (BasicAction) {
1386 case MemoryProfileActionAllocatePages:
1387 Status = CoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer, ActionString);
1388 break;
1389 case MemoryProfileActionFreePages:
1390 Status = CoreUpdateProfileFree (CallerAddress, Action, Size, Buffer);
1391 break;
1392 case MemoryProfileActionAllocatePool:
1393 Status = CoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer, ActionString);
1394 break;
1395 case MemoryProfileActionFreePool:
1396 Status = CoreUpdateProfileFree (CallerAddress, Action, 0, Buffer);
1397 break;
1398 default:
1399 ASSERT (FALSE);
1400 Status = EFI_UNSUPPORTED;
1401 break;
1402 }
1403 CoreReleaseMemoryProfileLock ();
1404
1405 return Status;
1406 }
1407
1408 ////////////////////
1409
1410 /**
1411 Get memory profile data size.
1412
1413 @return Memory profile data size.
1414
1415 **/
1416 UINTN
1417 MemoryProfileGetDataSize (
1418 VOID
1419 )
1420 {
1421 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
1422 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
1423 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;
1424 LIST_ENTRY *DriverInfoList;
1425 LIST_ENTRY *DriverLink;
1426 LIST_ENTRY *AllocInfoList;
1427 LIST_ENTRY *AllocLink;
1428 UINTN TotalSize;
1429
1430
1431 ContextData = GetMemoryProfileContext ();
1432 if (ContextData == NULL) {
1433 return 0;
1434 }
1435
1436 TotalSize = sizeof (MEMORY_PROFILE_CONTEXT);
1437
1438 DriverInfoList = ContextData->DriverInfoList;
1439 for (DriverLink = DriverInfoList->ForwardLink;
1440 DriverLink != DriverInfoList;
1441 DriverLink = DriverLink->ForwardLink) {
1442 DriverInfoData = CR (
1443 DriverLink,
1444 MEMORY_PROFILE_DRIVER_INFO_DATA,
1445 Link,
1446 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1447 );
1448 TotalSize += DriverInfoData->DriverInfo.Header.Length;
1449
1450 AllocInfoList = DriverInfoData->AllocInfoList;
1451 for (AllocLink = AllocInfoList->ForwardLink;
1452 AllocLink != AllocInfoList;
1453 AllocLink = AllocLink->ForwardLink) {
1454 AllocInfoData = CR (
1455 AllocLink,
1456 MEMORY_PROFILE_ALLOC_INFO_DATA,
1457 Link,
1458 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
1459 );
1460 TotalSize += AllocInfoData->AllocInfo.Header.Length;
1461 }
1462 }
1463
1464 return TotalSize;
1465 }
1466
1467 /**
1468 Copy memory profile data.
1469
1470 @param ProfileBuffer The buffer to hold memory profile data.
1471
1472 **/
1473 VOID
1474 MemoryProfileCopyData (
1475 IN VOID *ProfileBuffer
1476 )
1477 {
1478 MEMORY_PROFILE_CONTEXT *Context;
1479 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;
1480 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;
1481 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
1482 MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
1483 MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData;
1484 LIST_ENTRY *DriverInfoList;
1485 LIST_ENTRY *DriverLink;
1486 LIST_ENTRY *AllocInfoList;
1487 LIST_ENTRY *AllocLink;
1488 UINTN PdbSize;
1489 UINTN ActionStringSize;
1490
1491 ContextData = GetMemoryProfileContext ();
1492 if (ContextData == NULL) {
1493 return ;
1494 }
1495
1496 Context = ProfileBuffer;
1497 CopyMem (Context, &ContextData->Context, sizeof (MEMORY_PROFILE_CONTEXT));
1498 DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) (Context + 1);
1499
1500 DriverInfoList = ContextData->DriverInfoList;
1501 for (DriverLink = DriverInfoList->ForwardLink;
1502 DriverLink != DriverInfoList;
1503 DriverLink = DriverLink->ForwardLink) {
1504 DriverInfoData = CR (
1505 DriverLink,
1506 MEMORY_PROFILE_DRIVER_INFO_DATA,
1507 Link,
1508 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1509 );
1510 CopyMem (DriverInfo, &DriverInfoData->DriverInfo, sizeof (MEMORY_PROFILE_DRIVER_INFO));
1511 if (DriverInfo->PdbStringOffset != 0) {
1512 PdbSize = AsciiStrSize (DriverInfoData->PdbString);
1513 CopyMem ((VOID *) ((UINTN) DriverInfo + DriverInfo->PdbStringOffset), DriverInfoData->PdbString, PdbSize);
1514 }
1515 AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) DriverInfo + DriverInfo->Header.Length);
1516
1517 AllocInfoList = DriverInfoData->AllocInfoList;
1518 for (AllocLink = AllocInfoList->ForwardLink;
1519 AllocLink != AllocInfoList;
1520 AllocLink = AllocLink->ForwardLink) {
1521 AllocInfoData = CR (
1522 AllocLink,
1523 MEMORY_PROFILE_ALLOC_INFO_DATA,
1524 Link,
1525 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
1526 );
1527 CopyMem (AllocInfo, &AllocInfoData->AllocInfo, sizeof (MEMORY_PROFILE_ALLOC_INFO));
1528 if (AllocInfo->ActionStringOffset != 0) {
1529 ActionStringSize = AsciiStrSize (AllocInfoData->ActionString);
1530 CopyMem ((VOID *) ((UINTN) AllocInfo + AllocInfo->ActionStringOffset), AllocInfoData->ActionString, ActionStringSize);
1531 }
1532 AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) AllocInfo + AllocInfo->Header.Length);
1533 }
1534
1535 DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) AllocInfo;
1536 }
1537 }
1538
1539 /**
1540 Get memory profile data.
1541
1542 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1543 @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer.
1544 On return, points to the size of the data returned in ProfileBuffer.
1545 @param[out] ProfileBuffer Profile buffer.
1546
1547 @return EFI_SUCCESS Get the memory profile data successfully.
1548 @return EFI_UNSUPPORTED Memory profile is unsupported.
1549 @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data.
1550 ProfileSize is updated with the size required.
1551
1552 **/
1553 EFI_STATUS
1554 EFIAPI
1555 ProfileProtocolGetData (
1556 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
1557 IN OUT UINT64 *ProfileSize,
1558 OUT VOID *ProfileBuffer
1559 )
1560 {
1561 UINTN Size;
1562 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
1563 BOOLEAN MemoryProfileGettingStatus;
1564
1565 ContextData = GetMemoryProfileContext ();
1566 if (ContextData == NULL) {
1567 return EFI_UNSUPPORTED;
1568 }
1569
1570 MemoryProfileGettingStatus = mMemoryProfileGettingStatus;
1571 mMemoryProfileGettingStatus = TRUE;
1572
1573 Size = MemoryProfileGetDataSize ();
1574
1575 if (*ProfileSize < Size) {
1576 *ProfileSize = Size;
1577 mMemoryProfileGettingStatus = MemoryProfileGettingStatus;
1578 return EFI_BUFFER_TOO_SMALL;
1579 }
1580
1581 *ProfileSize = Size;
1582 MemoryProfileCopyData (ProfileBuffer);
1583
1584 mMemoryProfileGettingStatus = MemoryProfileGettingStatus;
1585 return EFI_SUCCESS;
1586 }
1587
1588 /**
1589 Register image to memory profile.
1590
1591 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1592 @param[in] FilePath File path of the image.
1593 @param[in] ImageBase Image base address.
1594 @param[in] ImageSize Image size.
1595 @param[in] FileType File type of the image.
1596
1597 @return EFI_SUCCESS Register successfully.
1598 @return EFI_UNSUPPORTED Memory profile is unsupported,
1599 or memory profile for the image is not required.
1600 @return EFI_OUT_OF_RESOURCES No enough resource for this register.
1601
1602 **/
1603 EFI_STATUS
1604 EFIAPI
1605 ProfileProtocolRegisterImage (
1606 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
1607 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
1608 IN PHYSICAL_ADDRESS ImageBase,
1609 IN UINT64 ImageSize,
1610 IN EFI_FV_FILETYPE FileType
1611 )
1612 {
1613 EFI_STATUS Status;
1614 LOADED_IMAGE_PRIVATE_DATA DriverEntry;
1615 VOID *EntryPointInImage;
1616
1617 ZeroMem (&DriverEntry, sizeof (DriverEntry));
1618 DriverEntry.Info.FilePath = FilePath;
1619 DriverEntry.ImageContext.ImageAddress = ImageBase;
1620 DriverEntry.ImageContext.ImageSize = ImageSize;
1621 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageBase, &EntryPointInImage);
1622 ASSERT_EFI_ERROR (Status);
1623 DriverEntry.ImageContext.EntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;
1624 DriverEntry.ImageContext.ImageType = InternalPeCoffGetSubsystem ((VOID *) (UINTN) ImageBase);
1625
1626 return RegisterMemoryProfileImage (&DriverEntry, FileType);
1627 }
1628
1629 /**
1630 Unregister image from memory profile.
1631
1632 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1633 @param[in] FilePath File path of the image.
1634 @param[in] ImageBase Image base address.
1635 @param[in] ImageSize Image size.
1636
1637 @return EFI_SUCCESS Unregister successfully.
1638 @return EFI_UNSUPPORTED Memory profile is unsupported,
1639 or memory profile for the image is not required.
1640 @return EFI_NOT_FOUND The image is not found.
1641
1642 **/
1643 EFI_STATUS
1644 EFIAPI
1645 ProfileProtocolUnregisterImage (
1646 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
1647 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
1648 IN PHYSICAL_ADDRESS ImageBase,
1649 IN UINT64 ImageSize
1650 )
1651 {
1652 EFI_STATUS Status;
1653 LOADED_IMAGE_PRIVATE_DATA DriverEntry;
1654 VOID *EntryPointInImage;
1655
1656 ZeroMem (&DriverEntry, sizeof (DriverEntry));
1657 DriverEntry.Info.FilePath = FilePath;
1658 DriverEntry.ImageContext.ImageAddress = ImageBase;
1659 DriverEntry.ImageContext.ImageSize = ImageSize;
1660 Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageBase, &EntryPointInImage);
1661 ASSERT_EFI_ERROR (Status);
1662 DriverEntry.ImageContext.EntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage;
1663
1664 return UnregisterMemoryProfileImage (&DriverEntry);
1665 }
1666
1667 /**
1668 Get memory profile recording state.
1669
1670 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1671 @param[out] RecordingState Recording state.
1672
1673 @return EFI_SUCCESS Memory profile recording state is returned.
1674 @return EFI_UNSUPPORTED Memory profile is unsupported.
1675 @return EFI_INVALID_PARAMETER RecordingState is NULL.
1676
1677 **/
1678 EFI_STATUS
1679 EFIAPI
1680 ProfileProtocolGetRecordingState (
1681 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
1682 OUT BOOLEAN *RecordingState
1683 )
1684 {
1685 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
1686
1687 ContextData = GetMemoryProfileContext ();
1688 if (ContextData == NULL) {
1689 return EFI_UNSUPPORTED;
1690 }
1691
1692 if (RecordingState == NULL) {
1693 return EFI_INVALID_PARAMETER;
1694 }
1695 *RecordingState = mMemoryProfileRecordingEnable;
1696 return EFI_SUCCESS;
1697 }
1698
1699 /**
1700 Set memory profile recording state.
1701
1702 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1703 @param[in] RecordingState Recording state.
1704
1705 @return EFI_SUCCESS Set memory profile recording state successfully.
1706 @return EFI_UNSUPPORTED Memory profile is unsupported.
1707
1708 **/
1709 EFI_STATUS
1710 EFIAPI
1711 ProfileProtocolSetRecordingState (
1712 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
1713 IN BOOLEAN RecordingState
1714 )
1715 {
1716 MEMORY_PROFILE_CONTEXT_DATA *ContextData;
1717
1718 ContextData = GetMemoryProfileContext ();
1719 if (ContextData == NULL) {
1720 return EFI_UNSUPPORTED;
1721 }
1722
1723 mMemoryProfileRecordingEnable = RecordingState;
1724 return EFI_SUCCESS;
1725 }
1726
1727 /**
1728 Record memory profile of multilevel caller.
1729
1730 @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance.
1731 @param[in] CallerAddress Address of caller.
1732 @param[in] Action Memory profile action.
1733 @param[in] MemoryType Memory type.
1734 EfiMaxMemoryType means the MemoryType is unknown.
1735 @param[in] Buffer Buffer address.
1736 @param[in] Size Buffer size.
1737 @param[in] ActionString String for memory profile action.
1738 Only needed for user defined allocate action.
1739
1740 @return EFI_SUCCESS Memory profile is updated.
1741 @return EFI_UNSUPPORTED Memory profile is unsupported,
1742 or memory profile for the image is not required,
1743 or memory profile for the memory type is not required.
1744 @return EFI_ACCESS_DENIED It is during memory profile data getting.
1745 @return EFI_ABORTED Memory profile recording is not enabled.
1746 @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action.
1747 @return EFI_NOT_FOUND No matched allocate info found for free action.
1748
1749 **/
1750 EFI_STATUS
1751 EFIAPI
1752 ProfileProtocolRecord (
1753 IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
1754 IN PHYSICAL_ADDRESS CallerAddress,
1755 IN MEMORY_PROFILE_ACTION Action,
1756 IN EFI_MEMORY_TYPE MemoryType,
1757 IN VOID *Buffer,
1758 IN UINTN Size,
1759 IN CHAR8 *ActionString OPTIONAL
1760 )
1761 {
1762 return CoreUpdateProfile (CallerAddress, Action, MemoryType, Size, Buffer, ActionString);
1763 }
1764
1765 ////////////////////