Reviewed-by: Fu Siyuan <siyuan...@intel.com>

> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, March 30, 2016 8:29 AM
> To: edk2-devel@lists.01.org
> Cc: Ni, Ruiyu <ruiyu...@intel.com>; Fu, Siyuan <siyuan...@intel.com>; Tian,
> Feng <feng.t...@intel.com>
> Subject: [Patch v3 2/3] MdeModulePkg/Bds: Free resources after ram disk
> boot finishes
> 
> The resource free includes to un-register the ram disk device and
> free the memory occupied by the ram disk.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ruiyu Ni <ruiyu...@intel.com>
> Cc: Siyuan Fu <siyuan...@intel.com>
> Cc: Feng Tian <feng.t...@intel.com>
> ---
>  MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c   | 155
> ++++++++++++++++++++-
>  .../Library/UefiBootManagerLib/InternalBm.h        |   1 +
>  .../UefiBootManagerLib/UefiBootManagerLib.inf      |   1 +
>  3 files changed, 153 insertions(+), 4 deletions(-)
> 
> diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> index 6e5c13b..598de26 100644
> --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
> @@ -1095,6 +1095,7 @@ BmMatchHttpBootDevicePath (
>    @param LoadFileHandle The handle of LoadFile instance.
>    @param FullPath       Return the full device path pointing to the load 
> option.
>    @param FileSize       Return the size of the load option.
> +  @param RamDiskHandle  Return the RAM Disk handle.
> 
>    @return  The load option buffer.
>  **/
> @@ -1102,7 +1103,8 @@ VOID *
>  BmGetFileBufferFromLoadFileSystem (
>    IN  EFI_HANDLE                      LoadFileHandle,
>    OUT EFI_DEVICE_PATH_PROTOCOL        **FullPath,
> -  OUT UINTN                           *FileSize
> +  OUT UINTN                           *FileSize,
> +  OUT EFI_HANDLE                      *RamDiskHandle
>    )
>  {
>    EFI_STATUS                      Status;
> @@ -1140,7 +1142,13 @@ BmGetFileBufferFromLoadFileSystem (
>      FreePool (Handles);
>    }
> 
> -  if (Index != HandleCount) {
> +  if (Index == HandleCount) {
> +    Handle = NULL;
> +  }
> +
> +  *RamDiskHandle = Handle;
> +
> +  if (Handle != NULL) {
>      return BmExpandMediaDevicePath (DevicePathFromHandle (Handle),
> FullPath, FileSize);
>    } else {
>      return NULL;
> @@ -1149,6 +1157,124 @@ BmGetFileBufferFromLoadFileSystem (
> 
> 
>  /**
> +  Return the RAM DISK handle created by LoadFile.
> +
> +  @param FilePath  The source file path.
> +
> +  @return RAM DISK handle.
> +**/
> +EFI_HANDLE
> +BmGetLoadFileRamDisk (
> +  EFI_DEVICE_PATH_PROTOCOL    *FilePath
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_DEVICE_PATH_PROTOCOL    *RamDiskDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL    *Node;
> +  EFI_HANDLE                  Handle;
> +
> +  Node = FilePath;
> +  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node,
> &Handle);
> +  if (!EFI_ERROR (Status) &&
> +      (DevicePathType (Node) == MEDIA_DEVICE_PATH) &&
> +      (DevicePathSubType (Node) == MEDIA_RAM_DISK_DP)
> +      ) {
> +
> +    //
> +    // Construct the device path pointing to RAM Disk
> +    //
> +    Node = NextDevicePathNode (Node);
> +    RamDiskDevicePath = DuplicateDevicePath (FilePath);
> +    ASSERT (RamDiskDevicePath != NULL);
> +    SetDevicePathEndNode ((VOID *) ((UINTN) RamDiskDevicePath + ((UINTN)
> Node - (UINTN) FilePath)));
> +
> +    //
> +    // Query the RAM Disk handle using the constructed device path.
> +    //
> +    Node = RamDiskDevicePath;
> +    Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &Node,
> &Handle);
> +    ASSERT ((Status == EFI_SUCCESS) && IsDevicePathEnd (Node));
> +    FreePool (RamDiskDevicePath);
> +    return Handle;
> +  }
> +
> +  return NULL;
> +}
> +
> +/**
> +  Return the buffer and buffer size occupied by the RAM Disk.
> +
> +  @param RamDiskHandle      RAM Disk handle.
> +  @param RamDiskSizeInPages Return RAM Disk size in pages.
> +
> +  @retval RAM Disk buffer.
> +**/
> +VOID *
> +BmGetRamDiskMemoryInfo (
> +  EFI_HANDLE                  RamDiskHandle,
> +  UINTN                       *RamDiskSizeInPages
> +  )
> +{
> +
> +  EFI_STATUS                  Status;
> +  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
> +  EFI_HANDLE                  Handle;
> +  UINT64                      StartingAddr;
> +  UINT64                      EndingAddr;
> +
> +  *RamDiskSizeInPages = 0;
> +  if (RamDiskHandle == NULL) {
> +    return NULL;
> +  }
> +  DevicePath = DevicePathFromHandle (RamDiskHandle);
> +
> +  //
> +  // Get the buffer occupied by RAM Disk.
> +  //
> +  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &DevicePath,
> &Handle);
> +  ASSERT_EFI_ERROR (Status);
> +  ASSERT ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
> (DevicePathSubType (DevicePath) == MEDIA_RAM_DISK_DP));
> +  StartingAddr = ReadUnaligned64 ((UINT64 *)
> ((MEDIA_RAM_DISK_DEVICE_PATH *) DevicePath)->StartingAddr);
> +  EndingAddr   = ReadUnaligned64 ((UINT64 *)
> ((MEDIA_RAM_DISK_DEVICE_PATH *) DevicePath)->EndingAddr);
> +  *RamDiskSizeInPages = EFI_SIZE_TO_PAGES ((UINTN) (EndingAddr -
> StartingAddr + 1));
> +  return (VOID *) (UINTN) StartingAddr;
> +}
> +
> +/**
> +  Destroy the RAM Disk handle.
> +
> +  The destroy operation includes to call RamDisk.Unregister to
> +  unregister the RAM DISK from RAM DISK driver, free the memory
> +  allocated for the RAM Disk.
> +
> +  @param RamDiskHandle   RAM Disk handle.
> +**/
> +VOID
> +BmDestroyRamDisk (
> +  EFI_HANDLE                  RamDiskHandle
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_RAM_DISK_PROTOCOL       *RamDisk;
> +  VOID                        *RamDiskBuffer;
> +  UINTN                       RamDiskSizeInPages;
> +
> +  if (RamDiskHandle == NULL) {
> +    return;
> +  }
> +  RamDiskBuffer = BmGetRamDiskMemoryInfo (RamDiskHandle,
> &RamDiskSizeInPages);
> +
> +  //
> +  // Destroy RAM Disk.
> +  //
> +  Status = gBS->LocateProtocol (&gEfiRamDiskProtocolGuid, NULL, (VOID *)
> &RamDisk);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = RamDisk->Unregister (DevicePathFromHandle (RamDiskHandle));
> +  ASSERT_EFI_ERROR (Status);
> +  FreePages (RamDiskBuffer, RamDiskSizeInPages);
> +}
> +
> +/**
>    Get the file buffer from the specified Load File instance.
> 
>    @param LoadFileHandle The specified Load File instance.
> @@ -1170,6 +1296,7 @@ BmGetFileBufferFromLoadFile (
>    EFI_LOAD_FILE_PROTOCOL              *LoadFile;
>    VOID                                *FileBuffer;
>    BOOLEAN                             LoadFileSystem;
> +  EFI_HANDLE                          RamDiskHandle;
>    UINTN                               BufferSize;
> 
>    *FileSize = 0;
> @@ -1204,7 +1331,13 @@ BmGetFileBufferFromLoadFile (
>    }
> 
>    if (LoadFileSystem) {
> -    FileBuffer = BmGetFileBufferFromLoadFileSystem (LoadFileHandle,
> FullPath, FileSize);
> +    FileBuffer = BmGetFileBufferFromLoadFileSystem (LoadFileHandle,
> FullPath, FileSize, &RamDiskHandle);
> +    if (FileBuffer == NULL) {
> +      //
> +      // If there is no bootable executable in the populated
> +      //
> +      BmDestroyRamDisk (RamDiskHandle);
> +    }
>    } else {
>      *FileSize = BufferSize;
>      *FullPath = DuplicateDevicePath (DevicePathFromHandle
> (LoadFileHandle));
> @@ -1432,6 +1565,7 @@ EfiBootManagerBoot (
>    UINTN                     OriginalOptionNumber;
>    EFI_DEVICE_PATH_PROTOCOL  *FilePath;
>    EFI_DEVICE_PATH_PROTOCOL  *Node;
> +  EFI_HANDLE                RamDiskHandle;
>    EFI_HANDLE                FvHandle;
>    VOID                      *FileBuffer;
>    UINTN                     FileSize;
> @@ -1512,10 +1646,14 @@ EfiBootManagerBoot (
>    //
>    // 5. Load EFI boot option to ImageHandle
>    //
> -  ImageHandle = NULL;
> +  ImageHandle   = NULL;
> +  RamDiskHandle = NULL;
>    if (DevicePathType (BootOption->FilePath) != BBS_DEVICE_PATH) {
>      Status     = EFI_NOT_FOUND;
>      FileBuffer = BmGetLoadOptionBuffer (BootOption->FilePath, &FilePath,
> &FileSize);
> +    if (FileBuffer != NULL) {
> +      RamDiskHandle = BmGetLoadFileRamDisk (FilePath);
> +    }
>      DEBUG_CODE (
>        if (FileBuffer != NULL && CompareMem (BootOption->FilePath, FilePath,
> GetDevicePathSize (FilePath)) != 0) {
>          DEBUG ((EFI_D_INFO, "[Bds] DevicePath expand: "));
> @@ -1552,6 +1690,10 @@ EfiBootManagerBoot (
>          (EFI_SOFTWARE_DXE_BS_DRIVER |
> EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)
>          );
>        BootOption->Status = Status;
> +      //
> +      // Destroy the RAM disk
> +      //
> +      BmDestroyRamDisk (RamDiskHandle);
>        return;
>      }
>    }
> @@ -1648,6 +1790,11 @@ EfiBootManagerBoot (
>    PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32)
> OptionNumber);
> 
>    //
> +  // Destroy the RAM disk
> +  //
> +  BmDestroyRamDisk (RamDiskHandle);
> +
> +  //
>    // Clear the Watchdog Timer after the image returns
>    //
>    gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
> diff --git a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
> b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
> index 7b6252a..4660323 100644
> --- a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
> +++ b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
> @@ -43,6 +43,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> KIND, EITHER EXPRESS OR IMPLIED.
>  #include <Protocol/DriverHealth.h>
>  #include <Protocol/FormBrowser2.h>
>  #include <Protocol/VariableLock.h>
> +#include <Protocol/RamDisk.h>
> 
>  #include <Guid/ZeroGuid.h>
>  #include <Guid/MemoryTypeInformation.h>
> diff --git
> a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> index e9e74b1..9d62d3d 100644
> --- a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> +++ b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> @@ -108,6 +108,7 @@
>    gEfiDiskInfoProtocolGuid                      ## SOMETIMES_CONSUMES
>    gEfiDriverHealthProtocolGuid                  ## SOMETIMES_CONSUMES
>    gEfiFormBrowser2ProtocolGuid                  ## SOMETIMES_CONSUMES
> +  gEfiRamDiskProtocolGuid                       ## SOMETIMES_CONSUMES
> 
>  [Pcd]
> 
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationCh
> ange      ## SOMETIMES_CONSUMES
> --
> 2.7.0.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to