]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Add CD Express PEIM
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 12 Jul 2011 20:36:05 +0000 (20:36 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 12 Jul 2011 20:36:05 +0000 (20:36 +0000)
Signed-off-by: jljusten
Reviewed-by: mdkinney
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12012 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Include/Guid/RecoveryDevice.h [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf [new file with mode: 0644]
MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.c [new file with mode: 0644]
MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.h [new file with mode: 0644]

diff --git a/MdeModulePkg/Include/Guid/RecoveryDevice.h b/MdeModulePkg/Include/Guid/RecoveryDevice.h
new file mode 100644 (file)
index 0000000..ad25065
--- /dev/null
@@ -0,0 +1,60 @@
+/** @file\r
+  Defines Name GUIDs to represent a Recovery Capsule loaded from a recovery device.\r
+\r
+  These are contracts between the recovery module and device recovery module\r
+  that convey the name of a given recovery module type.\r
+\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution.  The\r
+full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _RECOVERY_DEVICE_H_\r
+#define _RECOVERY_DEVICE_H_\r
+\r
+///\r
+/// The Global ID used to identify a recovery capsule that was loaded from a CD/DVD device.\r
+///\r
+#define RECOVERY_ON_DATA_CD_GUID \\r
+  { \\r
+    0x5cac0099, 0x0dc9, 0x48e5, {0x80, 0x68, 0xbb, 0x95, 0xf5, 0x40, 0x0a, 0x9f } \\r
+  };\r
+\r
+///\r
+/// The Global ID used to identify a recovery capsule that was loaded from floppy device.\r
+///\r
+#define RECOVERY_ON_FAT_FLOPPY_DISK_GUID \\r
+  { \\r
+    0x2e3d2e75, 0x9b2e, 0x412d, {0xb4, 0xb1, 0x70, 0x41, 0x6b, 0x87, 0x0, 0xff } \\r
+  };\r
+\r
+///\r
+/// The Global ID used to identify a recovery capsule that was loaded from IDE hard drive.\r
+///\r
+#define RECOVERY_ON_FAT_IDE_DISK_GUID \\r
+  { \\r
+    0xb38573b6, 0x6200, 0x4ac5, {0xb5, 0x1d, 0x82, 0xe6, 0x59, 0x38, 0xd7, 0x83 } \\r
+  };\r
+\r
+///\r
+/// The Global ID used to identify a recovery capsule that was loaded from USB BOT device.\r
+///\r
+#define RECOVERY_ON_FAT_USB_DISK_GUID \\r
+  { \\r
+    0x0ffbce19, 0x324c, 0x4690, {0xa0, 0x09, 0x98, 0xc6, 0xae, 0x2e, 0xb1, 0x86 } \\r
+  };\r
+\r
+extern EFI_GUID gRecoveryOnDataCdGuid;\r
+extern EFI_GUID gRecoveryOnFatFloppyDiskGuid;\r
+extern EFI_GUID gRecoveryOnFatIdeDiskGuid;\r
+extern EFI_GUID gRecoveryOnFatUsbDiskGuid;\r
+\r
+#endif\r
index 0efd29a29a3b37ade46a4410025b595368401aca..92e56ded559f6ccf7a7681f0dfe3099599bdb969 100644 (file)
   #  Include/Guid/EventIdle.h\r
   gIdleLoopEventGuid  = { 0x3c8d294c, 0x5fc3, 0x4451, { 0xbb, 0x31, 0xc4, 0xc0, 0x32, 0x29, 0x5e, 0x6c } }\r
 \r
+  ## Include/Guid/RecoveryDevice.h\r
+  gRecoveryOnFatUsbDiskGuid          = { 0x0FFBCE19, 0x324C, 0x4690, { 0xA0, 0x09, 0x98, 0xC6, 0xAE, 0x2E, 0xB1, 0x86 }}\r
+\r
+  ## Include/Guid/RecoveryDevice.h\r
+  gRecoveryOnFatIdeDiskGuid          = { 0xB38573B6, 0x6200, 0x4AC5, { 0xB5, 0x1D, 0x82, 0xE6, 0x59, 0x38, 0xD7, 0x83 }}\r
+\r
+  ## Include/Guid/RecoveryDevice.h\r
+  gRecoveryOnFatFloppyDiskGuid       = { 0x2E3D2E75, 0x9B2E, 0x412D, { 0xB4, 0xB1, 0x70, 0x41, 0x6B, 0x87, 0x00, 0xFF }}\r
+\r
+  ## Include/Guid/RecoveryDevice.h\r
+  gRecoveryOnDataCdGuid              = { 0x5CAC0099, 0x0DC9, 0x48E5, { 0x80, 0x68, 0xBB, 0x95, 0xF5, 0x40, 0x0A, 0x9F }}\r
+\r
 [Ppis]\r
   ## Include/Ppi/AtaController.h\r
   gPeiAtaControllerPpiGuid       = { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a, 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d }}\r
index 1e8cd5419e61eae2069b11a95412d287cffd738a..171a8d0323ea7e19d28673dfc93dc8808b544699 100644 (file)
   MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf\r
   MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf\r
   MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf\r
+  MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf\r
   MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/MemoryTest/GenericMemoryTestDxe/GenericMemoryTestDxe.inf\r
diff --git a/MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf b/MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf
new file mode 100644 (file)
index 0000000..287f1ff
--- /dev/null
@@ -0,0 +1,69 @@
+## @file\r
+# Component description file for PeiCdExpress module.\r
+#\r
+# This module reads data from CDROM device by all installed block IO ppi and \r
+# finds whether there is Recovery data in the device. If it finds recovery\r
+# data, it will install Device Recovery Module PPI.\r
+#\r
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions\r
+# of the BSD License which accompanies this distribution.  The\r
+# full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = CdExpressPei\r
+  FILE_GUID                      = 31e147a6-d39a-4147-9da3-befd4d523243\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = CdExpressPeimEntry\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  PeiCdExpress.c\r
+  PeiCdExpress.h\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  PeimEntryPoint\r
+  DebugLib\r
+  PeiServicesTablePointerLib\r
+  PeiServicesLib\r
+  MemoryAllocationLib\r
+  PcdLib\r
+\r
+[Guids]\r
+  gRecoveryOnDataCdGuid                         # ALWAYS_CONSUMED\r
+\r
+\r
+[Ppis]\r
+  gEfiPeiVirtualBlockIoPpiGuid                  # PPI_NOTIFY SOMETIMES_CONSUMED\r
+  gEfiPeiDeviceRecoveryModulePpiGuid            # PPI ALWAYS_PRODUCED\r
+\r
+[FeaturePcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport               ## CONSUMES\r
+\r
+[Depex]\r
+  gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid\r
+\r
+\r
+\r
diff --git a/MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.c b/MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.c
new file mode 100644 (file)
index 0000000..ee0b4e6
--- /dev/null
@@ -0,0 +1,618 @@
+/** @file\r
+  Source file for CD recovery PEIM\r
+\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution.  The\r
+full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "PeiCdExpress.h"\r
+\r
+PEI_CD_EXPRESS_PRIVATE_DATA *mPrivateData = NULL;\r
+\r
+/**\r
+  Installs the Device Recovery Module PPI, Initialize BlockIo Ppi \r
+  installation notification\r
+\r
+  @param  FileHandle            The file handle of the image.\r
+  @param  PeiServices           General purpose services available to every PEIM.\r
+\r
+  @retval EFI_SUCCESS           The function completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  There is not enough system memory.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CdExpressPeimEntry (\r
+  IN EFI_PEI_FILE_HANDLE       FileHandle,\r
+  IN CONST EFI_PEI_SERVICES    **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData;\r
+\r
+  if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  PrivateData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*PrivateData)));\r
+  if (PrivateData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Initialize Private Data (to zero, as is required by subsequent operations)\r
+  //\r
+  ZeroMem (PrivateData, sizeof (*PrivateData));\r
+  PrivateData->Signature    = PEI_CD_EXPRESS_PRIVATE_DATA_SIGNATURE;\r
+\r
+  PrivateData->BlockBuffer  = AllocatePages (EFI_SIZE_TO_PAGES (PEI_CD_BLOCK_SIZE));\r
+  if (PrivateData->BlockBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  PrivateData->CapsuleCount = 0;\r
+  Status                    = UpdateBlocksAndVolumes (PrivateData);\r
+\r
+  //\r
+  // Installs Ppi\r
+  //\r
+  PrivateData->DeviceRecoveryPpi.GetNumberRecoveryCapsules  = GetNumberRecoveryCapsules;\r
+  PrivateData->DeviceRecoveryPpi.GetRecoveryCapsuleInfo     = GetRecoveryCapsuleInfo;\r
+  PrivateData->DeviceRecoveryPpi.LoadRecoveryCapsule        = LoadRecoveryCapsule;\r
+\r
+  PrivateData->PpiDescriptor.Flags                          = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
+  PrivateData->PpiDescriptor.Guid = &gEfiPeiDeviceRecoveryModulePpiGuid;\r
+  PrivateData->PpiDescriptor.Ppi = &PrivateData->DeviceRecoveryPpi;\r
+\r
+  Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  //\r
+  // PrivateData is allocated now, set it to the module variable\r
+  //\r
+  mPrivateData = PrivateData;\r
+\r
+  //\r
+  // Installs Block Io Ppi notification function\r
+  //\r
+  PrivateData->NotifyDescriptor.Flags =\r
+    (\r
+      EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |\r
+      EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST\r
+    );\r
+  PrivateData->NotifyDescriptor.Guid    = &gEfiPeiVirtualBlockIoPpiGuid;\r
+  PrivateData->NotifyDescriptor.Notify  = BlockIoNotifyEntry;\r
+  return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor);\r
+\r
+}\r
+\r
+/**\r
+  BlockIo installation notification function. \r
+  \r
+  This function finds out all the current Block IO PPIs in the system and add them\r
+  into private data.\r
+\r
+  @param  PeiServices            Indirect reference to the PEI Services Table.\r
+  @param  NotifyDescriptor       Address of the notification descriptor data structure.\r
+  @param  Ppi                    Address of the PPI that was installed.\r
+\r
+  @retval EFI_SUCCESS            The function completes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BlockIoNotifyEntry (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
+  )\r
+{\r
+  UpdateBlocksAndVolumes (mPrivateData);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Finds out all the current Block IO PPIs in the system and add them into private data.\r
+\r
+  @param PrivateData                    The private data structure that contains recovery module information.\r
+\r
+  @retval EFI_SUCCESS                   The blocks and volumes are updated successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdateBlocksAndVolumes (\r
+  IN OUT PEI_CD_EXPRESS_PRIVATE_DATA     *PrivateData\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_PEI_PPI_DESCRIPTOR          *TempPpiDescriptor;\r
+  UINTN                           BlockIoPpiInstance;\r
+  EFI_PEI_RECOVERY_BLOCK_IO_PPI   *BlockIoPpi;\r
+  UINTN                           NumberBlockDevices;\r
+  UINTN                           IndexBlockDevice;\r
+  EFI_PEI_BLOCK_IO_MEDIA          Media;\r
+  EFI_PEI_SERVICES                **PeiServices;\r
+\r
+  IndexBlockDevice = 0;\r
+  //\r
+  // Find out all Block Io Ppi instances within the system\r
+  // Assuming all device Block Io Peims are dispatched already\r
+  //\r
+  for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_CD_EXPRESS_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {\r
+    Status = PeiServicesLocatePpi (\r
+                              &gEfiPeiVirtualBlockIoPpiGuid,\r
+                              BlockIoPpiInstance,\r
+                              &TempPpiDescriptor,\r
+                              (VOID **) &BlockIoPpi\r
+                              );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Done with all Block Io Ppis\r
+      //\r
+      break;\r
+    }\r
+\r
+    PeiServices = (EFI_PEI_SERVICES  **) GetPeiServicesTablePointer ();\r
+    Status = BlockIoPpi->GetNumberOfBlockDevices (\r
+                          PeiServices,\r
+                          BlockIoPpi,\r
+                          &NumberBlockDevices\r
+                          );\r
+    if (EFI_ERROR (Status) || (NumberBlockDevices == 0)) {\r
+      continue;\r
+    }\r
+    //\r
+    // Just retrieve the first block, should emulate all blocks.\r
+    //\r
+    for (IndexBlockDevice = 1; IndexBlockDevice <= NumberBlockDevices && PrivateData->CapsuleCount < PEI_CD_EXPRESS_MAX_CAPSULE_NUMBER; IndexBlockDevice ++) {\r
+      Status = BlockIoPpi->GetBlockDeviceMediaInfo (\r
+                            PeiServices,\r
+                            BlockIoPpi,\r
+                            IndexBlockDevice,\r
+                            &Media\r
+                            );\r
+      if (EFI_ERROR (Status) ||\r
+          !Media.MediaPresent ||\r
+           ((Media.DeviceType != IdeCDROM) && (Media.DeviceType != UsbMassStorage)) ||\r
+          (Media.BlockSize != PEI_CD_BLOCK_SIZE)\r
+          ) {\r
+        continue;\r
+      }\r
+\r
+      DEBUG ((EFI_D_INFO, "PeiCdExpress DeviceType is   %d\n", Media.DeviceType));\r
+      DEBUG ((EFI_D_INFO, "PeiCdExpress MediaPresent is %d\n", Media.MediaPresent));\r
+      DEBUG ((EFI_D_INFO, "PeiCdExpress BlockSize is  0x%x\n", Media.BlockSize));\r
+      DEBUG ((EFI_D_INFO, "PeiCdExpress Status is %d\n", Status));\r
+\r
+      DEBUG ((EFI_D_INFO, "IndexBlockDevice is %d\n", IndexBlockDevice));\r
+      PrivateData->CapsuleData[PrivateData->CapsuleCount].IndexBlock = IndexBlockDevice;  \r
+      PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo    = BlockIoPpi;\r
+      Status = FindRecoveryCapsules (PrivateData);\r
+      DEBUG ((EFI_D_INFO, "Status is %d\n", Status));\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        continue;\r
+      }\r
+  \r
+      PrivateData->CapsuleCount++;\r
+    }\r
+\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Finds out the recovery capsule in the current volume.\r
+\r
+  @param PrivateData                    The private data structure that contains recovery module information.\r
+\r
+  @retval EFI_SUCCESS                   The recovery capsule is successfully found in the volume.\r
+  @retval EFI_NOT_FOUND                 The recovery capsule is not found in the volume.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FindRecoveryCapsules (\r
+  IN OUT PEI_CD_EXPRESS_PRIVATE_DATA            *PrivateData\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  UINTN                           Lba;\r
+  EFI_PEI_RECOVERY_BLOCK_IO_PPI   *BlockIoPpi;\r
+  UINTN                           BufferSize;\r
+  UINT8                           *Buffer;\r
+  UINT8                           Type;\r
+  UINT8                           *StandardID;\r
+  UINT32                          RootDirLBA;\r
+  PEI_CD_EXPRESS_DIR_FILE_RECORD  *RoorDirRecord;\r
+  UINTN                           VolumeSpaceSize;\r
+  BOOLEAN                         StartOfVolume;\r
+  UINTN                           OriginalLBA;\r
+  UINTN                           IndexBlockDevice;\r
+\r
+  Buffer      = PrivateData->BlockBuffer;\r
+  BufferSize  = PEI_CD_BLOCK_SIZE;\r
+\r
+  Lba         = 16;\r
+  //\r
+  // The volume descriptor starts on Lba 16\r
+  //\r
+  IndexBlockDevice = PrivateData->CapsuleData[PrivateData->CapsuleCount].IndexBlock;\r
+  BlockIoPpi       = PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo;\r
+\r
+  VolumeSpaceSize = 0;\r
+  StartOfVolume   = TRUE;\r
+  OriginalLBA     = 16;\r
+\r
+  while (TRUE) {\r
+    SetMem (Buffer, BufferSize, 0);\r
+    Status = BlockIoPpi->ReadBlocks (\r
+                          PrivateData->PeiServices,\r
+                          BlockIoPpi,\r
+                          IndexBlockDevice,\r
+                          Lba,\r
+                          BufferSize,\r
+                          Buffer\r
+                          );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    StandardID = (UINT8 *) (Buffer + PEI_CD_EXPRESS_STANDARD_ID_OFFSET);\r
+    if (!StringCmp (StandardID, (UINT8 *) PEI_CD_STANDARD_ID, PEI_CD_EXPRESS_STANDARD_ID_SIZE, TRUE)) {\r
+      break;\r
+    }\r
+\r
+    if (StartOfVolume) {\r
+      OriginalLBA   = Lba;\r
+      StartOfVolume = FALSE;\r
+    }\r
+\r
+    Type = *(UINT8 *) (Buffer + PEI_CD_EXPRESS_VOLUME_TYPE_OFFSET);\r
+    if (Type == PEI_CD_EXPRESS_VOLUME_TYPE_TERMINATOR) {\r
+      if (VolumeSpaceSize == 0) {\r
+        break;\r
+      } else {\r
+        Lba             = (OriginalLBA + VolumeSpaceSize);\r
+        VolumeSpaceSize = 0;\r
+        StartOfVolume   = TRUE;\r
+        continue;\r
+      }\r
+    }\r
+\r
+    if (Type != PEI_CD_EXPRESS_VOLUME_TYPE_PRIMARY) {\r
+      Lba++;\r
+      continue;\r
+    }\r
+\r
+    VolumeSpaceSize = *(UINT32 *) (Buffer + PEI_CD_EXPRESS_VOLUME_SPACE_OFFSET);\r
+\r
+    RoorDirRecord   = (PEI_CD_EXPRESS_DIR_FILE_RECORD *) (Buffer + PEI_CD_EXPRESS_ROOT_DIR_RECORD_OFFSET);\r
+    RootDirLBA      = RoorDirRecord->LocationOfExtent[0];\r
+\r
+    Status          = RetrieveCapsuleFileFromRoot (PrivateData, BlockIoPpi, IndexBlockDevice, RootDirLBA);\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Just look for the first primary descriptor\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    Lba++;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Retrieves the recovery capsule in root directory of the current volume.\r
+\r
+  @param PrivateData                    The private data structure that contains recovery module information.\r
+  @param BlockIoPpi                     The Block IO PPI used to access the volume.\r
+  @param IndexBlockDevice               The index of current block device.\r
+  @param Lba                            The starting logic block address to retrieve capsule.\r
+\r
+  @retval EFI_SUCCESS                   The recovery capsule is successfully found in the volume.\r
+  @retval EFI_NOT_FOUND                 The recovery capsule is not found in the volume.\r
+  @retval Others                        \r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RetrieveCapsuleFileFromRoot (\r
+  IN OUT PEI_CD_EXPRESS_PRIVATE_DATA        *PrivateData,\r
+  IN EFI_PEI_RECOVERY_BLOCK_IO_PPI          *BlockIoPpi,\r
+  IN UINTN                                  IndexBlockDevice,\r
+  IN UINT32                                 Lba\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  UINTN                           BufferSize;\r
+  UINT8                           *Buffer;\r
+  PEI_CD_EXPRESS_DIR_FILE_RECORD  *FileRecord;\r
+  UINTN                           Index;\r
+\r
+  Buffer      = PrivateData->BlockBuffer;\r
+  BufferSize  = PEI_CD_BLOCK_SIZE;\r
+\r
+  SetMem (Buffer, BufferSize, 0);\r
+\r
+  Status = BlockIoPpi->ReadBlocks (\r
+                        PrivateData->PeiServices,\r
+                        BlockIoPpi,\r
+                        IndexBlockDevice,\r
+                        Lba,\r
+                        BufferSize,\r
+                        Buffer\r
+                        );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  while (1) {\r
+    FileRecord = (PEI_CD_EXPRESS_DIR_FILE_RECORD *) Buffer;\r
+\r
+    if (FileRecord->Length == 0) {\r
+      break;\r
+    }\r
+    //\r
+    // Not intend to check other flag now\r
+    //\r
+    if ((FileRecord->Flag & PEI_CD_EXPRESS_DIR_FILE_REC_FLAG_ISDIR) != 0) {\r
+      Buffer += FileRecord->Length;\r
+      continue;\r
+    }\r
+\r
+    for (Index = 0; Index < FileRecord->FileIDLength; Index++) {\r
+      if (FileRecord->FileID[Index] == ';') {\r
+        break;\r
+      }\r
+    }\r
+\r
+    if (Index != (sizeof (PEI_RECOVERY_FILE_NAME) - 1)) {\r
+      Buffer += FileRecord->Length;\r
+      continue;\r
+    }\r
+\r
+    if (!StringCmp (FileRecord->FileID, (UINT8 *) PEI_RECOVERY_FILE_NAME, sizeof (PEI_RECOVERY_FILE_NAME) - 1, FALSE)) {\r
+      Buffer += FileRecord->Length;\r
+      continue;\r
+    }\r
+\r
+    PrivateData->CapsuleData[PrivateData->CapsuleCount].CapsuleStartLBA = FileRecord->LocationOfExtent[0];\r
+    PrivateData->CapsuleData[PrivateData->CapsuleCount].CapsuleSize =\r
+      (\r
+        FileRecord->DataLength[0] /\r
+        PEI_CD_BLOCK_SIZE +\r
+        1\r
+      ) *\r
+      PEI_CD_BLOCK_SIZE;\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Returns the number of DXE capsules residing on the device.\r
+\r
+  This function searches for DXE capsules from the associated device and returns\r
+  the number and maximum size in bytes of the capsules discovered. Entry 1 is \r
+  assumed to be the highest load priority and entry N is assumed to be the lowest \r
+  priority.\r
+\r
+  @param[in]  PeiServices              General-purpose services that are available \r
+                                       to every PEIM\r
+  @param[in]  This                     Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI\r
+                                       instance.\r
+  @param[out] NumberRecoveryCapsules   Pointer to a caller-allocated UINTN. On \r
+                                       output, *NumberRecoveryCapsules contains \r
+                                       the number of recovery capsule images \r
+                                       available for retrieval from this PEIM \r
+                                       instance.\r
+\r
+  @retval EFI_SUCCESS        One or more capsules were discovered.\r
+  @retval EFI_DEVICE_ERROR   A device error occurred.\r
+  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetNumberRecoveryCapsules (\r
+  IN EFI_PEI_SERVICES                               **PeiServices,\r
+  IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI             *This,\r
+  OUT UINTN                                         *NumberRecoveryCapsules\r
+  )\r
+{\r
+  PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData;\r
+\r
+  PrivateData = PEI_CD_EXPRESS_PRIVATE_DATA_FROM_THIS (This);\r
+  UpdateBlocksAndVolumes (PrivateData);\r
+  *NumberRecoveryCapsules = PrivateData->CapsuleCount;\r
+\r
+  if (*NumberRecoveryCapsules == 0) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Returns the size and type of the requested recovery capsule.\r
+\r
+  This function gets the size and type of the capsule specified by CapsuleInstance.\r
+\r
+  @param[in]  PeiServices       General-purpose services that are available to every PEIM\r
+  @param[in]  This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI \r
+                                instance.\r
+  @param[in]  CapsuleInstance   Specifies for which capsule instance to retrieve \r
+                                the information.  This parameter must be between \r
+                                one and the value returned by GetNumberRecoveryCapsules() \r
+                                in NumberRecoveryCapsules.\r
+  @param[out] Size              A pointer to a caller-allocated UINTN in which \r
+                                the size of the requested recovery module is \r
+                                returned.\r
+  @param[out] CapsuleType       A pointer to a caller-allocated EFI_GUID in which \r
+                                the type of the requested recovery capsule is \r
+                                returned.  The semantic meaning of the value \r
+                                returned is defined by the implementation.\r
+\r
+  @retval EFI_SUCCESS        One or more capsules were discovered.\r
+  @retval EFI_DEVICE_ERROR   A device error occurred.\r
+  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetRecoveryCapsuleInfo (\r
+  IN  EFI_PEI_SERVICES                              **PeiServices,\r
+  IN  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI            *This,\r
+  IN  UINTN                                         CapsuleInstance,\r
+  OUT UINTN                                         *Size,\r
+  OUT EFI_GUID                                      *CapsuleType\r
+  )\r
+{\r
+  PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData;\r
+  UINTN                       NumberRecoveryCapsules;\r
+  EFI_STATUS                  Status;\r
+\r
+  Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
+    CapsuleInstance = CapsuleInstance + 1;\r
+  }\r
+\r
+  if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  PrivateData = PEI_CD_EXPRESS_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  *Size = PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleSize;\r
+  CopyMem (\r
+    CapsuleType,\r
+    &gRecoveryOnDataCdGuid,\r
+    sizeof (EFI_GUID)\r
+    );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Loads a DXE capsule from some media into memory.\r
+\r
+  This function, by whatever mechanism, retrieves a DXE capsule from some device\r
+  and loads it into memory. Note that the published interface is device neutral.\r
+\r
+  @param[in]     PeiServices       General-purpose services that are available \r
+                                   to every PEIM\r
+  @param[in]     This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI\r
+                                   instance.\r
+  @param[in]     CapsuleInstance   Specifies which capsule instance to retrieve.\r
+  @param[out]    Buffer            Specifies a caller-allocated buffer in which \r
+                                   the requested recovery capsule will be returned.\r
+\r
+  @retval EFI_SUCCESS        The capsule was loaded correctly.\r
+  @retval EFI_DEVICE_ERROR   A device error occurred.\r
+  @retval EFI_NOT_FOUND      A requested recovery DXE capsule cannot be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LoadRecoveryCapsule (\r
+  IN EFI_PEI_SERVICES                             **PeiServices,\r
+  IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI           *This,\r
+  IN UINTN                                        CapsuleInstance,\r
+  OUT VOID                                        *Buffer\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  PEI_CD_EXPRESS_PRIVATE_DATA     *PrivateData;\r
+  EFI_PEI_RECOVERY_BLOCK_IO_PPI   *BlockIoPpi;\r
+  UINTN                           NumberRecoveryCapsules;\r
+\r
+  Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
+    CapsuleInstance = CapsuleInstance + 1;\r
+  }\r
+\r
+  if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  PrivateData = PEI_CD_EXPRESS_PRIVATE_DATA_FROM_THIS (This);\r
+  BlockIoPpi  = PrivateData->CapsuleData[CapsuleInstance - 1].BlockIo;\r
+\r
+  Status = BlockIoPpi->ReadBlocks (\r
+                        PrivateData->PeiServices,\r
+                        BlockIoPpi,\r
+                        PrivateData->CapsuleData[CapsuleInstance - 1].IndexBlock,\r
+                        PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleStartLBA,\r
+                        PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleSize,\r
+                        Buffer\r
+                        );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function compares two ASCII strings in case sensitive/insensitive way.\r
+\r
+  @param  Source1           The first string.\r
+  @param  Source2           The second string.\r
+  @param  Size              The maximum comparison length.\r
+  @param  CaseSensitive     Flag to indicate whether the comparison is case sensitive.\r
+\r
+  @retval TRUE              The two strings are the same.\r
+  @retval FALSE             The two string are not the same.\r
+\r
+**/\r
+BOOLEAN\r
+StringCmp (\r
+  IN UINT8      *Source1,\r
+  IN UINT8      *Source2,\r
+  IN UINTN      Size,\r
+  IN BOOLEAN    CaseSensitive\r
+  )\r
+{\r
+  UINTN Index;\r
+  UINT8 Dif;\r
+\r
+  for (Index = 0; Index < Size; Index++) {\r
+    if (Source1[Index] == Source2[Index]) {\r
+      continue;\r
+    }\r
+\r
+    if (!CaseSensitive) {\r
+      Dif = (UINT8) ((Source1[Index] > Source2[Index]) ? (Source1[Index] - Source2[Index]) : (Source2[Index] - Source1[Index]));\r
+      if (Dif == ('a' - 'A')) {\r
+        continue;\r
+      }\r
+    }\r
+\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
diff --git a/MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.h b/MdeModulePkg/Universal/Disk/CdExpressPei/PeiCdExpress.h
new file mode 100644 (file)
index 0000000..99edd3d
--- /dev/null
@@ -0,0 +1,297 @@
+/** @file\r
+  Header file for CD recovery PEIM\r
+\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution.  The\r
+full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _PEI_CD_EXPRESS_H_\r
+#define _PEI_CD_EXPRESS_H_\r
+\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Ppi/BlockIo.h>\r
+#include <Guid/RecoveryDevice.h>\r
+#include <Ppi/DeviceRecoveryModule.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PeimEntryPoint.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+\r
+#pragma pack(1)\r
+\r
+#define PEI_CD_EXPRESS_MAX_BLOCK_IO_PPI   8\r
+#define PEI_CD_EXPRESS_MAX_CAPSULE_NUMBER 16\r
+\r
+#define PEI_CD_BLOCK_SIZE                 0x800\r
+#define PEI_MEMMORY_PAGE_SIZE             0x1000\r
+\r
+//\r
+// Recovery file name (in root directory)\r
+//\r
+#define PEI_RECOVERY_FILE_NAME  "FVMAIN.FV"\r
+\r
+//\r
+// Following are defined according to ISO-9660 specification\r
+//\r
+#define PEI_CD_STANDARD_ID                      "CD001"\r
+#define PEI_CD_EXPRESS_STANDARD_ID_SIZE         5\r
+\r
+#define PEI_CD_EXPRESS_VOLUME_TYPE_OFFSET       0\r
+#define PEI_CD_EXPRESS_STANDARD_ID_OFFSET       1\r
+#define PEI_CD_EXPRESS_VOLUME_SPACE_OFFSET      80\r
+#define PEI_CD_EXPRESS_ROOT_DIR_RECORD_OFFSET   156\r
+\r
+#define PEI_CD_EXPRESS_VOLUME_TYPE_PRIMARY      1\r
+#define PEI_CD_EXPRESS_VOLUME_TYPE_TERMINATOR   255\r
+\r
+#define PEI_CD_EXPRESS_DIR_FILE_REC_FLAG_ISDIR  0x02\r
+\r
+typedef struct {\r
+  UINTN                           CapsuleStartLBA;\r
+  UINTN                           CapsuleSize;\r
+  UINTN                           IndexBlock;\r
+  EFI_PEI_RECOVERY_BLOCK_IO_PPI   *BlockIo;\r
+} PEI_CD_EXPRESS_CAPSULE_DATA;\r
+\r
+#define PEI_CD_EXPRESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('p', 'c', 'd', 'e')\r
+\r
+typedef struct {\r
+\r
+  UINTN                                 Signature;\r
+  EFI_PEI_SERVICES                      **PeiServices;\r
+  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI    DeviceRecoveryPpi;\r
+  EFI_PEI_PPI_DESCRIPTOR                PpiDescriptor;\r
+  EFI_PEI_NOTIFY_DESCRIPTOR             NotifyDescriptor;\r
+\r
+  UINT8                                 *BlockBuffer;\r
+  UINTN                                 CapsuleCount;\r
+  PEI_CD_EXPRESS_CAPSULE_DATA           CapsuleData[PEI_CD_EXPRESS_MAX_CAPSULE_NUMBER];\r
+\r
+} PEI_CD_EXPRESS_PRIVATE_DATA;\r
+\r
+#define PEI_CD_EXPRESS_PRIVATE_DATA_FROM_THIS(a) \\r
+  CR (a, \\r
+          PEI_CD_EXPRESS_PRIVATE_DATA, \\r
+          DeviceRecoveryPpi, \\r
+          PEI_CD_EXPRESS_PRIVATE_DATA_SIGNATURE \\r
+      )\r
+\r
+typedef struct {\r
+  UINT8   Length;\r
+  UINT8   ExtendedAttributeRecordLength;\r
+  UINT32  LocationOfExtent[2];\r
+  UINT32  DataLength[2];\r
+  UINT8   DateTime[7];\r
+  UINT8   Flag;\r
+  UINT8   FileUnitSize;\r
+  UINT8   InterleaveGapSize;\r
+  UINT32  VolumeSequenceNumber;\r
+  UINT8   FileIDLength;\r
+  UINT8   FileID[1];\r
+} PEI_CD_EXPRESS_DIR_FILE_RECORD;\r
+\r
+/**\r
+  BlockIo installation notification function. \r
+  \r
+  This function finds out all the current Block IO PPIs in the system and add them\r
+  into private data.\r
+\r
+  @param  PeiServices            Indirect reference to the PEI Services Table.\r
+  @param  NotifyDescriptor       Address of the notification descriptor data structure.\r
+  @param  Ppi                    Address of the PPI that was installed.\r
+\r
+  @retval EFI_SUCCESS            The function completes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BlockIoNotifyEntry (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
+  );\r
+\r
+/**\r
+  Finds out all the current Block IO PPIs in the system and add them into private data.\r
+\r
+  @param PrivateData                    The private data structure that contains recovery module information.\r
+\r
+  @retval EFI_SUCCESS                   The blocks and volumes are updated successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdateBlocksAndVolumes (\r
+  IN OUT PEI_CD_EXPRESS_PRIVATE_DATA     *PrivateData\r
+  );\r
+\r
+/**\r
+  Returns the number of DXE capsules residing on the device.\r
+\r
+  This function searches for DXE capsules from the associated device and returns\r
+  the number and maximum size in bytes of the capsules discovered. Entry 1 is \r
+  assumed to be the highest load priority and entry N is assumed to be the lowest \r
+  priority.\r
+\r
+  @param[in]  PeiServices              General-purpose services that are available \r
+                                       to every PEIM\r
+  @param[in]  This                     Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI\r
+                                       instance.\r
+  @param[out] NumberRecoveryCapsules   Pointer to a caller-allocated UINTN. On \r
+                                       output, *NumberRecoveryCapsules contains \r
+                                       the number of recovery capsule images \r
+                                       available for retrieval from this PEIM \r
+                                       instance.\r
+\r
+  @retval EFI_SUCCESS        One or more capsules were discovered.\r
+  @retval EFI_DEVICE_ERROR   A device error occurred.\r
+  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetNumberRecoveryCapsules (\r
+  IN EFI_PEI_SERVICES                               **PeiServices,\r
+  IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI             *This,\r
+  OUT UINTN                                         *NumberRecoveryCapsules\r
+  );\r
+\r
+/**\r
+  Returns the size and type of the requested recovery capsule.\r
+\r
+  This function gets the size and type of the capsule specified by CapsuleInstance.\r
+\r
+  @param[in]  PeiServices       General-purpose services that are available to every PEIM\r
+  @param[in]  This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI \r
+                                instance.\r
+  @param[in]  CapsuleInstance   Specifies for which capsule instance to retrieve \r
+                                the information.  This parameter must be between \r
+                                one and the value returned by GetNumberRecoveryCapsules() \r
+                                in NumberRecoveryCapsules.\r
+  @param[out] Size              A pointer to a caller-allocated UINTN in which \r
+                                the size of the requested recovery module is \r
+                                returned.\r
+  @param[out] CapsuleType       A pointer to a caller-allocated EFI_GUID in which \r
+                                the type of the requested recovery capsule is \r
+                                returned.  The semantic meaning of the value \r
+                                returned is defined by the implementation.\r
+\r
+  @retval EFI_SUCCESS        One or more capsules were discovered.\r
+  @retval EFI_DEVICE_ERROR   A device error occurred.\r
+  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetRecoveryCapsuleInfo (\r
+  IN  EFI_PEI_SERVICES                              **PeiServices,\r
+  IN  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI            *This,\r
+  IN  UINTN                                         CapsuleInstance,\r
+  OUT UINTN                                         *Size,\r
+  OUT EFI_GUID                                      *CapsuleType\r
+  );\r
+\r
+/**\r
+  Loads a DXE capsule from some media into memory.\r
+\r
+  This function, by whatever mechanism, retrieves a DXE capsule from some device\r
+  and loads it into memory. Note that the published interface is device neutral.\r
+\r
+  @param[in]     PeiServices       General-purpose services that are available \r
+                                   to every PEIM\r
+  @param[in]     This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI\r
+                                   instance.\r
+  @param[in]     CapsuleInstance   Specifies which capsule instance to retrieve.\r
+  @param[out]    Buffer            Specifies a caller-allocated buffer in which \r
+                                   the requested recovery capsule will be returned.\r
+\r
+  @retval EFI_SUCCESS        The capsule was loaded correctly.\r
+  @retval EFI_DEVICE_ERROR   A device error occurred.\r
+  @retval EFI_NOT_FOUND      A requested recovery DXE capsule cannot be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LoadRecoveryCapsule (\r
+  IN EFI_PEI_SERVICES                             **PeiServices,\r
+  IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI           *This,\r
+  IN UINTN                                        CapsuleInstance,\r
+  OUT VOID                                        *Buffer\r
+  );\r
+\r
+/**\r
+  Finds out the recovery capsule in the current volume.\r
+\r
+  @param PrivateData                    The private data structure that contains recovery module information.\r
+\r
+  @retval EFI_SUCCESS                   The recovery capsule is successfully found in the volume.\r
+  @retval EFI_NOT_FOUND                 The recovery capsule is not found in the volume.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FindRecoveryCapsules (\r
+  IN OUT PEI_CD_EXPRESS_PRIVATE_DATA            *PrivateData\r
+  );\r
+\r
+/**\r
+  Retrieves the recovery capsule in root directory of the current volume.\r
+\r
+  @param PrivateData                    The private data structure that contains recovery module information.\r
+  @param BlockIoPpi                     The Block IO PPI used to access the volume.\r
+  @param IndexBlockDevice               The index of current block device.\r
+  @param Lba                            The starting logic block address to retrieve capsule.\r
+\r
+  @retval EFI_SUCCESS                   The recovery capsule is successfully found in the volume.\r
+  @retval EFI_NOT_FOUND                 The recovery capsule is not found in the volume.\r
+  @retval Others                        \r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RetrieveCapsuleFileFromRoot (\r
+  IN OUT PEI_CD_EXPRESS_PRIVATE_DATA        *PrivateData,\r
+  IN EFI_PEI_RECOVERY_BLOCK_IO_PPI          *BlockIoPpi,\r
+  IN UINTN                                  IndexBlockDevice,\r
+  IN UINT32                                 Lba\r
+  );\r
+\r
+\r
+/**\r
+  This function compares two ASCII strings in case sensitive/insensitive way.\r
+\r
+  @param  Source1           The first string.\r
+  @param  Source2           The second string.\r
+  @param  Size              The maximum comparison length.\r
+  @param  CaseSensitive     Flag to indicate whether the comparison is case sensitive.\r
+\r
+  @retval TRUE              The two strings are the same.\r
+  @retval FALSE             The two string are not the same.\r
+\r
+**/\r
+BOOLEAN\r
+StringCmp (\r
+  IN UINT8      *Source1,\r
+  IN UINT8      *Source2,\r
+  IN UINTN      Size,\r
+  IN BOOLEAN    CaseSensitive\r
+  );\r
+\r
+#pragma pack()\r
+\r
+#endif\r