/** @file
  The realization of EFI_RAM_DISK_PROTOCOL.

  Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
  Copyright (c) Microsoft Corporation.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RamDiskImpl.h"

RAM_DISK_PRIVATE_DATA  mRamDiskPrivateDataTemplate = {
  RAM_DISK_PRIVATE_DATA_SIGNATURE,
  NULL
};

MEDIA_RAM_DISK_DEVICE_PATH  mRamDiskDeviceNodeTemplate = {
  {
    MEDIA_DEVICE_PATH,
    MEDIA_RAM_DISK_DP,
    {
      (UINT8)(sizeof (MEDIA_RAM_DISK_DEVICE_PATH)),
      (UINT8)((sizeof (MEDIA_RAM_DISK_DEVICE_PATH)) >> 8)
    }
  }
};

BOOLEAN  mRamDiskSsdtTableKeyValid = FALSE;
UINTN    mRamDiskSsdtTableKey;

/**
  Initialize the RAM disk device node.

  @param[in]      PrivateData     Points to RAM disk private data.
  @param[in, out] RamDiskDevNode  Points to the RAM disk device node.

**/
VOID
RamDiskInitDeviceNode (
  IN     RAM_DISK_PRIVATE_DATA       *PrivateData,
  IN OUT MEDIA_RAM_DISK_DEVICE_PATH  *RamDiskDevNode
  )
{
  WriteUnaligned64 (
    (UINT64 *)&(RamDiskDevNode->StartingAddr[0]),
    (UINT64)PrivateData->StartingAddr
    );
  WriteUnaligned64 (
    (UINT64 *)&(RamDiskDevNode->EndingAddr[0]),
    (UINT64)PrivateData->StartingAddr + PrivateData->Size - 1
    );
  CopyGuid (&RamDiskDevNode->TypeGuid, &PrivateData->TypeGuid);
  RamDiskDevNode->Instance = PrivateData->InstanceNumber;
}

/**
  Initialize and publish NVDIMM root device SSDT in ACPI table.

  @retval EFI_SUCCESS        The NVDIMM root device SSDT is published.
  @retval Others             The NVDIMM root device SSDT is not published.

**/
EFI_STATUS
RamDiskPublishSsdt (
  VOID
  )
{
  EFI_STATUS                   Status;
  EFI_ACPI_DESCRIPTION_HEADER  *Table;
  UINTN                        SectionInstance;
  UINTN                        TableSize;

  Status          = EFI_SUCCESS;
  SectionInstance = 0;

  //
  // Scan all the EFI raw section instances in FV to find the NVDIMM root
  // device SSDT.
  //
  while (TRUE) {
    Status = GetSectionFromFv (
               &gEfiCallerIdGuid,
               EFI_SECTION_RAW,
               SectionInstance,
               (VOID **)&Table,
               &TableSize
               );
    if (EFI_ERROR (Status)) {
      break;
    }

    if (Table->OemTableId == SIGNATURE_64 ('R', 'a', 'm', 'D', 'i', 's', 'k', ' ')) {
      Status = mAcpiTableProtocol->InstallAcpiTable (
                                     mAcpiTableProtocol,
                                     Table,
                                     TableSize,
                                     &mRamDiskSsdtTableKey
                                     );
      ASSERT_EFI_ERROR (Status);

      if (!EFI_ERROR (Status)) {
        mRamDiskSsdtTableKeyValid = TRUE;
      }

      FreePool (Table);
      return Status;
    } else {
      FreePool (Table);
      SectionInstance++;
    }
  }

  return Status;
}

/**
  Publish the RAM disk NVDIMM Firmware Interface Table (NFIT) to the ACPI
  table.

  @param[in] PrivateData          Points to RAM disk private data.

  @retval EFI_SUCCESS             The RAM disk NFIT has been published.
  @retval others                  The RAM disk NFIT has not been published.

**/
EFI_STATUS
RamDiskPublishNfit (
  IN RAM_DISK_PRIVATE_DATA  *PrivateData
  )
{
  EFI_STATUS                   Status;
  EFI_MEMORY_DESCRIPTOR        *MemoryMap;
  EFI_MEMORY_DESCRIPTOR        *MemoryMapEntry;
  EFI_MEMORY_DESCRIPTOR        *MemoryMapEnd;
  UINTN                        TableIndex;
  VOID                         *TableHeader;
  EFI_ACPI_TABLE_VERSION       TableVersion;
  UINTN                        TableKey;
  EFI_ACPI_DESCRIPTION_HEADER  *NfitHeader;
  EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE
           *SpaRange;
  VOID     *Nfit;
  UINT32   NfitLen;
  UINTN    MemoryMapSize;
  UINTN    MapKey;
  UINTN    DescriptorSize;
  UINT32   DescriptorVersion;
  UINT64   CurrentData;
  UINT8    Checksum;
  BOOLEAN  MemoryFound;

  //
  // Get the EFI memory map.
  //
  MemoryMapSize = 0;
  MemoryMap     = NULL;
  MemoryFound   = FALSE;

  Status = gBS->GetMemoryMap (
                  &MemoryMapSize,
                  MemoryMap,
                  &MapKey,
                  &DescriptorSize,
                  &DescriptorVersion
                  );
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
  do {
    MemoryMap = (EFI_MEMORY_DESCRIPTOR *)AllocatePool (MemoryMapSize);
    ASSERT (MemoryMap != NULL);
    Status = gBS->GetMemoryMap (
                    &MemoryMapSize,
                    MemoryMap,
                    &MapKey,
                    &DescriptorSize,
                    &DescriptorVersion
                    );
    if (EFI_ERROR (Status)) {
      FreePool (MemoryMap);
    }
  } while (Status == EFI_BUFFER_TOO_SMALL);

  ASSERT_EFI_ERROR (Status);

  MemoryMapEntry = MemoryMap;
  MemoryMapEnd   = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
  while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
    if ((MemoryMapEntry->Type == EfiReservedMemoryType) &&
        (MemoryMapEntry->PhysicalStart <= PrivateData->StartingAddr) &&
        (MemoryMapEntry->PhysicalStart +
         MultU64x32 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SIZE)
         >= PrivateData->StartingAddr + PrivateData->Size))
    {
      MemoryFound = TRUE;
      DEBUG ((
        DEBUG_INFO,
        "RamDiskPublishNfit: RAM disk with reserved memory type, will publish to NFIT.\n"
        ));
      break;
    }

    MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
  }

  FreePool (MemoryMap);

  if (!MemoryFound) {
    return EFI_NOT_FOUND;
  }

  //
  // Determine whether there is a NFIT already in the ACPI table.
  //
  Status      = EFI_SUCCESS;
  TableIndex  = 0;
  TableKey    = 0;
  TableHeader = NULL;

  while (!EFI_ERROR (Status)) {
    Status = mAcpiSdtProtocol->GetAcpiTable (
                                 TableIndex,
                                 (EFI_ACPI_SDT_HEADER **)&TableHeader,
                                 &TableVersion,
                                 &TableKey
                                 );
    if (!EFI_ERROR (Status)) {
      TableIndex++;

      if (((EFI_ACPI_SDT_HEADER *)TableHeader)->Signature ==
          EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE)
      {
        break;
      }
    }
  }

  if (!EFI_ERROR (Status)) {
    //
    // A NFIT is already in the ACPI table.
    //
    DEBUG ((
      DEBUG_INFO,
      "RamDiskPublishNfit: A NFIT is already exist in the ACPI Table.\n"
      ));

    NfitHeader = (EFI_ACPI_DESCRIPTION_HEADER *)TableHeader;
    NfitLen    = NfitHeader->Length + sizeof (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE);
    Nfit       = AllocateZeroPool (NfitLen);
    if (Nfit == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (Nfit, TableHeader, NfitHeader->Length);

    //
    // Update the NFIT head pointer.
    //
    NfitHeader = (EFI_ACPI_DESCRIPTION_HEADER *)Nfit;

    //
    // Uninstall the origin NFIT from the ACPI table.
    //
    Status = mAcpiTableProtocol->UninstallAcpiTable (
                                   mAcpiTableProtocol,
                                   TableKey
                                   );
    ASSERT_EFI_ERROR (Status);

    if (EFI_ERROR (Status)) {
      FreePool (Nfit);
      return Status;
    }

    //
    // Append the System Physical Address (SPA) Range Structure at the end
    // of the origin NFIT.
    //
    SpaRange = (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
               ((UINT8 *)Nfit + NfitHeader->Length);

    //
    // Update the length field of the NFIT
    //
    NfitHeader->Length = NfitLen;

    //
    // The checksum will be updated after the new contents are appended.
    //
    NfitHeader->Checksum = 0;
  } else {
    //
    // Assumption is made that if no NFIT is in the ACPI table, there is no
    // NVDIMM root device in the \SB scope.
    // Therefore, a NVDIMM root device will be reported via Secondary System
    // Description Table (SSDT).
    //
    Status = RamDiskPublishSsdt ();
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // No NFIT is in the ACPI table, we will create one here.
    //
    DEBUG ((
      DEBUG_INFO,
      "RamDiskPublishNfit: No NFIT is in the ACPI Table, will create one.\n"
      ));

    NfitLen = sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE) +
              sizeof (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE);
    Nfit = AllocateZeroPool (NfitLen);
    if (Nfit == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    SpaRange = (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
               ((UINT8 *)Nfit + sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE));

    NfitHeader                  = (EFI_ACPI_DESCRIPTION_HEADER *)Nfit;
    NfitHeader->Signature       = EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE;
    NfitHeader->Length          = NfitLen;
    NfitHeader->Revision        = EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION;
    NfitHeader->Checksum        = 0;
    NfitHeader->OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);
    NfitHeader->CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
    NfitHeader->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
    CurrentData                 = PcdGet64 (PcdAcpiDefaultOemTableId);
    CopyMem (NfitHeader->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (NfitHeader->OemId));
    CopyMem (&NfitHeader->OemTableId, &CurrentData, sizeof (UINT64));
  }

  //
  // Fill in the content of the SPA Range Structure.
  //
  SpaRange->Type                             = EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE;
  SpaRange->Length                           = sizeof (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE);
  SpaRange->SystemPhysicalAddressRangeBase   = PrivateData->StartingAddr;
  SpaRange->SystemPhysicalAddressRangeLength = PrivateData->Size;
  CopyGuid (&SpaRange->AddressRangeTypeGUID, &PrivateData->TypeGuid);

  Checksum             = CalculateCheckSum8 ((UINT8 *)Nfit, NfitHeader->Length);
  NfitHeader->Checksum = Checksum;

  //
  // Publish the NFIT to the ACPI table.
  // Note, since the NFIT might be modified by other driver, therefore, we
  // do not track the returning TableKey from the InstallAcpiTable().
  //
  Status = mAcpiTableProtocol->InstallAcpiTable (
                                 mAcpiTableProtocol,
                                 Nfit,
                                 NfitHeader->Length,
                                 &TableKey
                                 );
  ASSERT_EFI_ERROR (Status);

  FreePool (Nfit);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  PrivateData->InNfit = TRUE;

  return EFI_SUCCESS;
}

/**
  Unpublish the RAM disk NVDIMM Firmware Interface Table (NFIT) from the
  ACPI table.

  @param[in] PrivateData          Points to RAM disk private data.

  @retval EFI_SUCCESS             The RAM disk NFIT has been unpublished.
  @retval others                  The RAM disk NFIT has not been unpublished.

**/
EFI_STATUS
RamDiskUnpublishNfit (
  IN RAM_DISK_PRIVATE_DATA  *PrivateData
  )
{
  EFI_STATUS                   Status;
  UINTN                        TableIndex;
  VOID                         *TableHeader;
  EFI_ACPI_TABLE_VERSION       TableVersion;
  UINTN                        TableKey;
  EFI_ACPI_DESCRIPTION_HEADER  *NewNfitHeader;
  EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE
                                      *SpaRange;
  VOID                                *NewNfit;
  VOID                                *NewNfitPtr;
  EFI_ACPI_6_1_NFIT_STRUCTURE_HEADER  *NfitStructHeader;
  UINT32                              NewNfitLen;
  UINT32                              RemainLen;
  UINT8                               Checksum;

  //
  // Find the NFIT in the ACPI table.
  //
  Status      = EFI_SUCCESS;
  TableIndex  = 0;
  TableKey    = 0;
  TableHeader = NULL;

  while (!EFI_ERROR (Status)) {
    Status = mAcpiSdtProtocol->GetAcpiTable (
                                 TableIndex,
                                 (EFI_ACPI_SDT_HEADER **)&TableHeader,
                                 &TableVersion,
                                 &TableKey
                                 );
    if (!EFI_ERROR (Status)) {
      TableIndex++;

      if (((EFI_ACPI_SDT_HEADER *)TableHeader)->Signature ==
          EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE)
      {
        break;
      }
    }
  }

  if (EFI_ERROR (Status)) {
    //
    // No NFIT is found in the ACPI table.
    //
    return EFI_NOT_FOUND;
  }

  NewNfitLen = ((EFI_ACPI_DESCRIPTION_HEADER *)TableHeader)->Length -
               sizeof (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE);

  //
  // After removing this RAM disk from the NFIT, if no other structure is in
  // the NFIT, we just remove the NFIT and the SSDT which is used to report
  // the NVDIMM root device.
  //
  if (NewNfitLen == sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE)) {
    //
    // Remove the NFIT.
    //
    Status = mAcpiTableProtocol->UninstallAcpiTable (
                                   mAcpiTableProtocol,
                                   TableKey
                                   );
    ASSERT_EFI_ERROR (Status);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Remove the SSDT which is used by RamDiskDxe driver to report the NVDIMM
    // root device.
    // We do not care the return status since this SSDT might already be
    // uninstalled by other drivers to update the information of the NVDIMM
    // root device.
    //
    if (mRamDiskSsdtTableKeyValid) {
      mRamDiskSsdtTableKeyValid = FALSE;

      mAcpiTableProtocol->UninstallAcpiTable (
                            mAcpiTableProtocol,
                            mRamDiskSsdtTableKey
                            );
    }

    return EFI_SUCCESS;
  }

  NewNfit = AllocateZeroPool (NewNfitLen);
  if (NewNfit == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get a copy of the old NFIT header content.
  //
  CopyMem (NewNfit, TableHeader, sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE));
  NewNfitHeader           = (EFI_ACPI_DESCRIPTION_HEADER *)NewNfit;
  NewNfitHeader->Length   = NewNfitLen;
  NewNfitHeader->Checksum = 0;

  //
  // Copy the content of required NFIT structures.
  //
  NewNfitPtr       = (UINT8 *)NewNfit + sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE);
  RemainLen        = NewNfitLen - sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE);
  NfitStructHeader = (EFI_ACPI_6_1_NFIT_STRUCTURE_HEADER *)
                     ((UINT8 *)TableHeader + sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE));
  while (RemainLen > 0) {
    if ((NfitStructHeader->Type == EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE) &&
        (NfitStructHeader->Length == sizeof (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE)))
    {
      SpaRange = (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)NfitStructHeader;

      if ((SpaRange->SystemPhysicalAddressRangeBase == PrivateData->StartingAddr) &&
          (SpaRange->SystemPhysicalAddressRangeLength == PrivateData->Size) &&
          (CompareGuid (&SpaRange->AddressRangeTypeGUID, &PrivateData->TypeGuid)))
      {
        //
        // Skip the SPA Range Structure for the RAM disk to be unpublished
        // from NFIT.
        //
        NfitStructHeader = (EFI_ACPI_6_1_NFIT_STRUCTURE_HEADER *)
                           ((UINT8 *)NfitStructHeader + NfitStructHeader->Length);
        continue;
      }
    }

    //
    // Copy the content of origin NFIT.
    //
    CopyMem (NewNfitPtr, NfitStructHeader, NfitStructHeader->Length);
    NewNfitPtr = (UINT8 *)NewNfitPtr + NfitStructHeader->Length;

    //
    // Move to the header of next NFIT structure.
    //
    RemainLen       -= NfitStructHeader->Length;
    NfitStructHeader = (EFI_ACPI_6_1_NFIT_STRUCTURE_HEADER *)
                       ((UINT8 *)NfitStructHeader + NfitStructHeader->Length);
  }

  Checksum                = CalculateCheckSum8 ((UINT8 *)NewNfit, NewNfitHeader->Length);
  NewNfitHeader->Checksum = Checksum;

  Status = mAcpiTableProtocol->UninstallAcpiTable (
                                 mAcpiTableProtocol,
                                 TableKey
                                 );
  ASSERT_EFI_ERROR (Status);

  if (EFI_ERROR (Status)) {
    FreePool (NewNfit);
    return Status;
  }

  //
  // Publish the NFIT to the ACPI table.
  // Note, since the NFIT might be modified by other driver, therefore, we
  // do not track the returning TableKey from the InstallAcpiTable().
  //
  Status = mAcpiTableProtocol->InstallAcpiTable (
                                 mAcpiTableProtocol,
                                 NewNfit,
                                 NewNfitLen,
                                 &TableKey
                                 );
  ASSERT_EFI_ERROR (Status);

  FreePool (NewNfit);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Register a RAM disk with specified address, size and type.

  @param[in]  RamDiskBase    The base address of registered RAM disk.
  @param[in]  RamDiskSize    The size of registered RAM disk.
  @param[in]  RamDiskType    The type of registered RAM disk. The GUID can be
                             any of the values defined in section 9.3.6.9, or a
                             vendor defined GUID.
  @param[in]  ParentDevicePath
                             Pointer to the parent device path. If there is no
                             parent device path then ParentDevicePath is NULL.
  @param[out] DevicePath     On return, points to a pointer to the device path
                             of the RAM disk device.
                             If ParentDevicePath is not NULL, the returned
                             DevicePath is created by appending a RAM disk node
                             to the parent device path. If ParentDevicePath is
                             NULL, the returned DevicePath is a RAM disk device
                             path without appending. This function is
                             responsible for allocating the buffer DevicePath
                             with the boot service AllocatePool().

  @retval EFI_SUCCESS             The RAM disk is registered successfully.
  @retval EFI_INVALID_PARAMETER   DevicePath or RamDiskType is NULL.
                                  RamDiskSize is 0.
  @retval EFI_ALREADY_STARTED     A Device Path Protocol instance to be created
                                  is already present in the handle database.
  @retval EFI_OUT_OF_RESOURCES    The RAM disk register operation fails due to
                                  resource limitation.

**/
EFI_STATUS
EFIAPI
RamDiskRegister (
  IN UINT64                     RamDiskBase,
  IN UINT64                     RamDiskSize,
  IN EFI_GUID                   *RamDiskType,
  IN EFI_DEVICE_PATH            *ParentDevicePath     OPTIONAL,
  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath
  )
{
  EFI_STATUS                  Status;
  RAM_DISK_PRIVATE_DATA       *PrivateData;
  RAM_DISK_PRIVATE_DATA       *RegisteredPrivateData;
  MEDIA_RAM_DISK_DEVICE_PATH  *RamDiskDevNode;
  UINTN                       DevicePathSize;
  LIST_ENTRY                  *Entry;

  if ((0 == RamDiskSize) || (NULL == RamDiskType) || (NULL == DevicePath)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Add check to prevent data read across the memory boundary
  //
  if ((RamDiskSize > MAX_UINTN) ||
      (RamDiskBase > MAX_UINTN - RamDiskSize + 1))
  {
    return EFI_INVALID_PARAMETER;
  }

  RamDiskDevNode = NULL;

  //
  // Create a new RAM disk instance and initialize its private data
  //
  PrivateData = AllocateCopyPool (
                  sizeof (RAM_DISK_PRIVATE_DATA),
                  &mRamDiskPrivateDataTemplate
                  );
  if (NULL == PrivateData) {
    return EFI_OUT_OF_RESOURCES;
  }

  PrivateData->StartingAddr = RamDiskBase;
  PrivateData->Size         = RamDiskSize;
  CopyGuid (&PrivateData->TypeGuid, RamDiskType);
  InitializeListHead (&PrivateData->ThisInstance);

  //
  // Generate device path information for the registered RAM disk
  //
  RamDiskDevNode = AllocateCopyPool (
                     sizeof (MEDIA_RAM_DISK_DEVICE_PATH),
                     &mRamDiskDeviceNodeTemplate
                     );
  if (NULL == RamDiskDevNode) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  RamDiskInitDeviceNode (PrivateData, RamDiskDevNode);

  *DevicePath = AppendDevicePathNode (
                  ParentDevicePath,
                  (EFI_DEVICE_PATH_PROTOCOL *)RamDiskDevNode
                  );
  if (NULL == *DevicePath) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  PrivateData->DevicePath = *DevicePath;

  //
  // Check whether the created device path is already present in the handle
  // database
  //
  if (!IsListEmpty (&RegisteredRamDisks)) {
    DevicePathSize = GetDevicePathSize (PrivateData->DevicePath);

    BASE_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {
      RegisteredPrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
      if (DevicePathSize == GetDevicePathSize (RegisteredPrivateData->DevicePath)) {
        //
        // Compare device path
        //
        if ((CompareMem (
               PrivateData->DevicePath,
               RegisteredPrivateData->DevicePath,
               DevicePathSize
               )) == 0)
        {
          *DevicePath = NULL;
          Status      = EFI_ALREADY_STARTED;
          goto ErrorExit;
        }
      }
    }
  }

  //
  // Fill Block IO protocol informations for the RAM disk
  //
  RamDiskInitBlockIo (PrivateData);

  //
  // Install EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO(2)_PROTOCOL on a new
  // handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &PrivateData->Handle,
                  &gEfiBlockIoProtocolGuid,
                  &PrivateData->BlockIo,
                  &gEfiBlockIo2ProtocolGuid,
                  &PrivateData->BlockIo2,
                  &gEfiDevicePathProtocolGuid,
                  PrivateData->DevicePath,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Insert the newly created one to the registered RAM disk list
  //
  InsertTailList (&RegisteredRamDisks, &PrivateData->ThisInstance);

  gBS->ConnectController (PrivateData->Handle, NULL, NULL, TRUE);

  FreePool (RamDiskDevNode);

  if ((mAcpiTableProtocol != NULL) && (mAcpiSdtProtocol != NULL)) {
    RamDiskPublishNfit (PrivateData);
  }

  return EFI_SUCCESS;

ErrorExit:
  if (RamDiskDevNode != NULL) {
    FreePool (RamDiskDevNode);
  }

  if (PrivateData != NULL) {
    if (PrivateData->DevicePath) {
      FreePool (PrivateData->DevicePath);
    }

    FreePool (PrivateData);
  }

  return Status;
}

/**
  Unregister a RAM disk specified by DevicePath.

  @param[in] DevicePath      A pointer to the device path that describes a RAM
                             Disk device.

  @retval EFI_SUCCESS             The RAM disk is unregistered successfully.
  @retval EFI_INVALID_PARAMETER   DevicePath is NULL.
  @retval EFI_UNSUPPORTED         The device specified by DevicePath is not a
                                  valid ramdisk device path and not supported
                                  by the driver.
  @retval EFI_NOT_FOUND           The RAM disk pointed by DevicePath doesn't
                                  exist.

**/
EFI_STATUS
EFIAPI
RamDiskUnregister (
  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  LIST_ENTRY                  *Entry;
  LIST_ENTRY                  *NextEntry;
  BOOLEAN                     Found;
  UINT64                      StartingAddr;
  UINT64                      EndingAddr;
  EFI_DEVICE_PATH_PROTOCOL    *Header;
  MEDIA_RAM_DISK_DEVICE_PATH  *RamDiskDevNode;
  RAM_DISK_PRIVATE_DATA       *PrivateData;

  if (NULL == DevicePath) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Locate the RAM disk device node.
  //
  RamDiskDevNode = NULL;
  Header         = DevicePath;
  do {
    //
    // Test if the current device node is a RAM disk.
    //
    if ((MEDIA_DEVICE_PATH == Header->Type) &&
        (MEDIA_RAM_DISK_DP == Header->SubType))
    {
      RamDiskDevNode = (MEDIA_RAM_DISK_DEVICE_PATH *)Header;

      break;
    }

    Header = NextDevicePathNode (Header);
  } while ((Header->Type != END_DEVICE_PATH_TYPE));

  if (NULL == RamDiskDevNode) {
    return EFI_UNSUPPORTED;
  }

  Found        = FALSE;
  StartingAddr = ReadUnaligned64 ((UINT64 *)&(RamDiskDevNode->StartingAddr[0]));
  EndingAddr   = ReadUnaligned64 ((UINT64 *)&(RamDiskDevNode->EndingAddr[0]));

  if (!IsListEmpty (&RegisteredRamDisks)) {
    BASE_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {
      PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);

      //
      // Unregister the RAM disk given by its starting address, ending address
      // and type guid.
      //
      if ((StartingAddr == PrivateData->StartingAddr) &&
          (EndingAddr == PrivateData->StartingAddr + PrivateData->Size - 1) &&
          (CompareGuid (&RamDiskDevNode->TypeGuid, &PrivateData->TypeGuid)))
      {
        //
        // Remove the content for this RAM disk in NFIT.
        //
        if (PrivateData->InNfit) {
          RamDiskUnpublishNfit (PrivateData);
        }

        //
        // Uninstall the EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO(2)_PROTOCOL
        //
        gBS->UninstallMultipleProtocolInterfaces (
               PrivateData->Handle,
               &gEfiBlockIoProtocolGuid,
               &PrivateData->BlockIo,
               &gEfiBlockIo2ProtocolGuid,
               &PrivateData->BlockIo2,
               &gEfiDevicePathProtocolGuid,
               (EFI_DEVICE_PATH_PROTOCOL *)PrivateData->DevicePath,
               NULL
               );

        RemoveEntryList (&PrivateData->ThisInstance);

        if (RamDiskCreateHii == PrivateData->CreateMethod) {
          //
          // If a RAM disk is created within HII, then the RamDiskDxe driver
          // driver is responsible for freeing the allocated memory for the
          // RAM disk.
          //
          FreePool ((VOID *)(UINTN)PrivateData->StartingAddr);
        }

        FreePool (PrivateData->DevicePath);
        FreePool (PrivateData);
        Found = TRUE;

        break;
      }
    }
  }

  if (TRUE == Found) {
    return EFI_SUCCESS;
  } else {
    return EFI_NOT_FOUND;
  }
}
