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