diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 8be0a8e523..c12f40b738 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -85,6 +85,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include // // attributes for reserved memory before it is promoted to system memory @@ -272,15 +273,6 @@ extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; // Service Initialization Functions // -/** - Called to initialize the pool. - -**/ -VOID -CoreInitializePool ( - VOID - ); - VOID CoreSetMemoryTypeInformationRange ( IN EFI_PHYSICAL_ADDRESS Start, @@ -1240,80 +1232,6 @@ CoreGetMemoryMap ( OUT UINT32 *DescriptorVersion ); -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreInternalAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreePool ( - IN VOID *Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreInternalFreePool ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ); - /** Loads an EFI image into memory and returns a handle to the image. diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index ef383766b4..c475c4f49b 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -44,7 +44,6 @@ Hand/Handle.h Gcd/Gcd.c Gcd/Gcd.h - Mem/Pool.c Mem/Page.c Mem/MemData.c Mem/Imem.h @@ -103,6 +102,7 @@ PcdLib ImagePropertiesRecordLib CpuArchLib + MemoryPoolLib [Guids] gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/Imem.h index 2f0bf2bf63..dc971471e6 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Imem.h +++ b/MdeModulePkg/Core/Dxe/Mem/Imem.h @@ -9,22 +9,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef _IMEM_H_ #define _IMEM_H_ -// -// +---------------------------------------------------+ -// | 0..(EfiMaxMemoryType - 1) - Normal memory type | -// +---------------------------------------------------+ -// | EfiMaxMemoryType..0x6FFFFFFF - Invalid | -// +---------------------------------------------------+ -// | 0x70000000..0x7FFFFFFF - OEM reserved | -// +---------------------------------------------------+ -// | 0x80000000..0xFFFFFFFF - OS reserved | -// +---------------------------------------------------+ -// -#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 -#define MEMORY_TYPE_OS_RESERVED_MAX 0xFFFFFFFF -#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 -#define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF - // // MEMORY_MAP_ENTRY // @@ -80,41 +64,6 @@ CoreFreePoolPages ( IN UINTN NumberOfPages ); -/** - Internal function to allocate pool of a particular type. - Caller must have the memory lock held - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param NeedGuard Flag to indicate Guard page is needed or not - - @return The allocate pool, or NULL - -**/ -VOID * -CoreAllocatePoolI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - IN BOOLEAN NeedGuard - ); - -/** - Internal function to free a pool entry. - Caller must have the memory lock held - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer not valid - @retval EFI_SUCCESS Buffer successfully freed. - -**/ -EFI_STATUS -CoreFreePoolI ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ); - /** Enter critical section by gaining lock on gMemoryLock. diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 2bf6d5aee8..1627b99868 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -46,9 +46,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "ProcessorBind.h" #include "Uefi/UefiMultiPhase.h" -#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 -#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 - #define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) diff --git a/MdeModulePkg/Include/Library/MemoryPoolLib.h b/MdeModulePkg/Include/Library/MemoryPoolLib.h new file mode 100644 index 0000000000..b80dc71a70 --- /dev/null +++ b/MdeModulePkg/Include/Library/MemoryPoolLib.h @@ -0,0 +1,146 @@ +/** @file + UEFI Memory pool management functions. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MEMORY_POOL_LIB_H_ +#define _MEMORY_POOL_LIB_H_ + +// +// +---------------------------------------------------+ +// | 0..(EfiMaxMemoryType - 1) - Normal memory type | +// +---------------------------------------------------+ +// | EfiMaxMemoryType..0x6FFFFFFF - Invalid | +// +---------------------------------------------------+ +// | 0x70000000..0x7FFFFFFF - OEM reserved | +// +---------------------------------------------------+ +// | 0x80000000..0xFFFFFFFF - OS reserved | +// +---------------------------------------------------+ +// +#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 +#define MEMORY_TYPE_OS_RESERVED_MAX 0xFFFFFFFF +#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 +#define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF + +/** + Called to initialize the pool. + +**/ +VOID +CoreInitializePool ( + VOID + ); + +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +CoreInternalAllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +CoreAllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Internal function to allocate pool of a particular type. + Caller must have the memory lock held + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param NeedGuard Flag to indicate Guard page is needed or not + + @return The allocate pool, or NULL + +**/ +VOID * +CoreAllocatePoolI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + IN BOOLEAN NeedGuard + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + @param PoolType Pointer to pool type + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +CoreInternalFreePool ( + IN VOID *Buffer, + OUT EFI_MEMORY_TYPE *PoolType OPTIONAL + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +CoreFreePool ( + IN VOID *Buffer + ); + +/** + Internal function to free a pool entry. + Caller must have the memory lock held + + @param Buffer The allocated pool entry to free + @param PoolType Pointer to pool type + + @retval EFI_INVALID_PARAMETER Buffer not valid + @retval EFI_SUCCESS Buffer successfully freed. + +**/ +EFI_STATUS +CoreFreePoolI ( + IN VOID *Buffer, + OUT EFI_MEMORY_TYPE *PoolType OPTIONAL + ); + +#endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c new file mode 100644 index 0000000000..734f397c91 --- /dev/null +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c @@ -0,0 +1,9 @@ +/** @file + DXE Core functions necessary for pool management functions. + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h new file mode 100644 index 0000000000..898d5d7177 --- /dev/null +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h @@ -0,0 +1,317 @@ +/** @file + DXE Core functions necessary for pool management functions. + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#ifndef _INTERNAL_POOL_H_ +#define _INTERNAL_POOL_H_ + +extern BOOLEAN mOnGuarding; +extern EFI_LOCK gMemoryLock; + +#define GUARD_HEAP_TYPE_FREED BIT4 + +/** + Check to see if the pool at the given address should be guarded or not. + + @param[in] MemoryType Pool type to check. + + + @return TRUE The given type of pool should be guarded. + @return FALSE The given type of pool should not be guarded. +**/ +BOOLEAN +IsPoolTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType + ); + +/** + Initialize a basic mutual exclusion lock. Each lock + provides mutual exclusion access at it's task priority + level. Since there is no-premption (at any TPL) or + multiprocessor support, acquiring the lock only consists + of raising to the locks TPL. + + @param Lock The EFI_LOCK structure to initialize + + @retval EFI_SUCCESS Lock Owned. + @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. + +**/ +EFI_STATUS +CoreAcquireLockOrFail ( + IN EFI_LOCK *Lock + ); + +/** + Releases ownership of the mutual exclusion lock, and + restores the previous task priority level. + + @param Lock The lock to release + + @return Lock unowned + +**/ +VOID +CoreReleaseLock ( + IN EFI_LOCK *Lock + ); + +/** + Update memory profile information. + + @param CallerAddress Address of caller who call Allocate or Free. + @param Action This Allocate or Free action. + @param MemoryType Memory type. + EfiMaxMemoryType means the MemoryType is unknown. + @param Size Buffer size. + @param Buffer Buffer address. + @param ActionString String for memory profile action. + Only needed for user defined allocate action. + + @return EFI_SUCCESS Memory profile is updated. + @return EFI_UNSUPPORTED Memory profile is unsupported, + or memory profile for the image is not required, + or memory profile for the memory type is not required. + @return EFI_ACCESS_DENIED It is during memory profile data getting. + @return EFI_ABORTED Memory profile recording is not enabled. + @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. + @return EFI_NOT_FOUND No matched allocate info found for free action. + +**/ +EFI_STATUS +EFIAPI +CoreUpdateProfile ( + IN EFI_PHYSICAL_ADDRESS CallerAddress, + IN MEMORY_PROFILE_ACTION Action, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool + IN VOID *Buffer, + IN CHAR8 *ActionString OPTIONAL + ); + +/** + Install MemoryAttributesTable on memory allocation. + + @param[in] MemoryType EFI memory type. +**/ +VOID +InstallMemoryAttributesTableOnMemoryAllocation ( + IN EFI_MEMORY_TYPE MemoryType + ); + +/** + Internal function. Used by the pool functions to allocate pages + to back pool allocation requests. + + @param PoolType The type of memory for the new pool pages + @param NumberOfPages No of pages to allocate + @param Alignment Bits to align. + @param NeedGuard Flag to indicate Guard page is needed or not + + @return The allocated memory, or NULL + +**/ +VOID * +CoreAllocatePoolPages ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NumberOfPages, + IN UINTN Alignment, + IN BOOLEAN NeedGuard + ); + +/** + Exit critical section by releasing lock on gMemoryLock. + +**/ +VOID +CoreReleaseMemoryLock ( + VOID + ); + +/** + Set head Guard and tail Guard for the given memory range. + + @param[in] Memory Base address of memory to set guard for. + @param[in] NumberOfPages Memory size in pages. + + @return VOID. +**/ +VOID +SetGuardForMemory ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + Manage memory permission attributes on a memory range, according to the + configured DXE memory protection policy. + + @param OldType The old memory type of the range + @param NewType The new memory type of the range + @param Memory The base address of the range + @param Length The size of the range (in bytes) + + @return EFI_SUCCESS If the the CPU arch protocol is not installed yet + @return EFI_SUCCESS If no DXE memory protection policy has been configured + @return EFI_SUCCESS If OldType and NewType use the same permission attributes + @return other Return value of gCpu->SetMemoryAttributes() + +**/ +EFI_STATUS +EFIAPI +ApplyMemoryProtectionPolicy ( + IN EFI_MEMORY_TYPE OldType, + IN EFI_MEMORY_TYPE NewType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINT64 Length + ); + +/** + Check to see if the heap guard is enabled for page and/or pool allocation. + + @param[in] GuardType Specify the sub-type(s) of Heap Guard. + + @return TRUE/FALSE. +**/ +BOOLEAN +IsHeapGuardEnabled ( + UINT8 GuardType + ); + +/** + Adjust the pool head position to make sure the Guard page is adjavent to + pool tail or pool head. + + @param[in] Memory Base address of memory allocated. + @param[in] NoPages Number of pages actually allocated. + @param[in] Size Size of memory requested. + (plus pool head/tail overhead) + + @return Address of pool head. +**/ +VOID * +AdjustPoolHeadA ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages, + IN UINTN Size + ); + +/** + Raising to the task priority level of the mutual exclusion + lock, and then acquires ownership of the lock. + + @param Lock The lock to acquire + + @return Lock owned + +**/ +VOID +CoreAcquireLock ( + IN EFI_LOCK *Lock + ); + +/** + Enter critical section by gaining lock on gMemoryLock. + +**/ +VOID +CoreAcquireMemoryLock ( + VOID + ); + +/** + Internal function. Frees pool pages allocated via AllocatePoolPages () + + @param Memory The base address to free + @param NumberOfPages The number of pages to free + +**/ +VOID +CoreFreePoolPages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + Record freed pages as well as mark them as not-present, if enabled. + + @param[in] BaseAddress Base address of just freed pages. + @param[in] Pages Number of freed pages. + + @return VOID. +**/ +VOID +EFIAPI +GuardFreedPagesChecked ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Pages + ); + +/** + Adjust the start address and number of pages to free according to Guard. + + The purpose of this function is to keep the shared Guard page with adjacent + memory block if it's still in guard, or free it if no more sharing. Another + is to reserve pages as Guard pages in partial page free situation. + + @param[in,out] Memory Base address of memory to free. + @param[in,out] NumberOfPages Size of memory to free. + + @return VOID. +**/ +VOID +AdjustMemoryF ( + IN OUT EFI_PHYSICAL_ADDRESS *Memory, + IN OUT UINTN *NumberOfPages + ); + +/** + Unset head Guard and tail Guard for the given memory range. + + @param[in] Memory Base address of memory to unset guard for. + @param[in] NumberOfPages Memory size in pages. + + @return VOID. +**/ +VOID +UnsetGuardForMemory ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + Check to see if the page at the given address is guarded or not. + + @param[in] Address The address to check for. + + @return TRUE The page at Address is guarded. + @return FALSE The page at Address is not guarded. +**/ +BOOLEAN +EFIAPI +IsMemoryGuarded ( + IN EFI_PHYSICAL_ADDRESS Address + ); + +/** + Get the page base address according to pool head address. + + @param[in] Memory Head address of pool to free. + @param[in] NoPages Number of pages actually allocated. + @param[in] Size Size of memory requested. + (plus pool head/tail overhead) + + @return Address of pool head. +**/ +VOID * +AdjustPoolHeadF ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages, + IN UINTN Size + ); + +#endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf new file mode 100644 index 0000000000..a0bda89d15 --- /dev/null +++ b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf @@ -0,0 +1,39 @@ +## @file +# UEFI Memory pool management functions. +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MemoryPoolLib + FILE_GUID = 084a3534-da19-435e-8eeb-be08237ed403 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryPoolLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + InternalPool.c + InternalPool.h + Pool.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + UefiBootServicesTableLib + UefiLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c similarity index 95% rename from MdeModulePkg/Core/Dxe/Mem/Pool.c rename to MdeModulePkg/Library/MemoryPoolLib/Pool.c index 72293e6dfe..10344579f1 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -6,9 +6,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "DxeMain.h" -#include "Imem.h" -#include "HeapGuard.h" +#include + +#include +#include +#include +#include + +#include "InternalPool.h" STATIC EFI_LOCK mPoolMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); @@ -137,6 +142,7 @@ CoreInitializePool ( @return Pointer of Corresponding pool head. **/ +STATIC POOL * LookupPoolHead ( IN EFI_MEMORY_TYPE MemoryType diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 4260cc1883..08a6007878 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -143,6 +143,7 @@ MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf [LibraryClasses.IA32.DXE_CORE] CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf @@ -379,6 +380,7 @@ MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf + MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf