/** @file\r
FAT recovery PEIM entry point, Ppi Functions and FAT Api functions.\r
\r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
\r
-This program and the accompanying materials are licensed and made available\r
-under the terms and conditions of the BSD License which accompanies this\r
-distribution. The 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
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
BlockIo installation nofication function. Find out all the current BlockIO\r
PPIs in the system and add them into private data. Assume there is\r
\r
- @param PeiServices General purpose services available to every \r
- PEIM. \r
- @param NotifyDescriptor The typedef structure of the notification \r
- descriptor. Not used in this function. \r
- @param Ppi The typedef structure of the PPI descriptor. \r
- Not used in this function. \r
+ @param PeiServices General purpose services available to every\r
+ PEIM.\r
+ @param NotifyDescriptor The typedef structure of the notification\r
+ descriptor. Not used in this function.\r
+ @param Ppi The typedef structure of the PPI descriptor.\r
+ Not used in this function.\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
\r
/**\r
Discover all the block I/O devices to find the FAT volume.\r
\r
- @param PrivateData Global memory map for accessing global \r
- variables. \r
+ @param PrivateData Global memory map for accessing global\r
+ variables.\r
+ @param BlockIo2 Boolean to show whether using BlockIo2 or BlockIo\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
\r
**/\r
EFI_STATUS\r
UpdateBlocksAndVolumes (\r
- IN OUT PEI_FAT_PRIVATE_DATA *PrivateData\r
+ IN OUT PEI_FAT_PRIVATE_DATA *PrivateData,\r
+ IN BOOLEAN BlockIo2\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 Index;\r
- EFI_PEI_BLOCK_IO_MEDIA Media;\r
- PEI_FAT_VOLUME Volume;\r
- EFI_PEI_SERVICES **PeiServices;\r
+ EFI_STATUS Status;\r
+ EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor;\r
+ UINTN BlockIoPpiInstance;\r
+ EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIoPpi;\r
+ EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi;\r
+ UINTN NumberBlockDevices;\r
+ UINTN Index;\r
+ EFI_PEI_BLOCK_IO_MEDIA Media;\r
+ EFI_PEI_BLOCK_IO2_MEDIA Media2;\r
+ PEI_FAT_VOLUME Volume;\r
+ EFI_PEI_SERVICES **PeiServices;\r
\r
PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer ();\r
-\r
+ BlockIo2Ppi = NULL;\r
+ BlockIoPpi = NULL;\r
//\r
// Clean up caches\r
//\r
// Assuming all device Block Io Peims are dispatched already\r
//\r
for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_FAT_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {\r
- Status = PeiServicesLocatePpi (\r
- &gEfiPeiVirtualBlockIoPpiGuid,\r
- BlockIoPpiInstance,\r
- &TempPpiDescriptor,\r
- (VOID **) &BlockIoPpi\r
- );\r
+ if (BlockIo2) {\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiVirtualBlockIo2PpiGuid,\r
+ BlockIoPpiInstance,\r
+ &TempPpiDescriptor,\r
+ (VOID **) &BlockIo2Ppi\r
+ );\r
+ } else {\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiVirtualBlockIoPpiGuid,\r
+ BlockIoPpiInstance,\r
+ &TempPpiDescriptor,\r
+ (VOID **) &BlockIoPpi\r
+ );\r
+ }\r
if (EFI_ERROR (Status)) {\r
//\r
// Done with all Block Io Ppis\r
break;\r
}\r
\r
- Status = BlockIoPpi->GetNumberOfBlockDevices (\r
- PeiServices,\r
- BlockIoPpi,\r
- &NumberBlockDevices\r
- );\r
+ if (BlockIo2) {\r
+ Status = BlockIo2Ppi->GetNumberOfBlockDevices (\r
+ PeiServices,\r
+ BlockIo2Ppi,\r
+ &NumberBlockDevices\r
+ );\r
+ } else {\r
+ Status = BlockIoPpi->GetNumberOfBlockDevices (\r
+ PeiServices,\r
+ BlockIoPpi,\r
+ &NumberBlockDevices\r
+ );\r
+ }\r
if (EFI_ERROR (Status)) {\r
continue;\r
}\r
\r
for (Index = 1; Index <= NumberBlockDevices && PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE; Index++) {\r
\r
- Status = BlockIoPpi->GetBlockDeviceMediaInfo (\r
- PeiServices,\r
- BlockIoPpi,\r
- Index,\r
- &Media\r
- );\r
- if (EFI_ERROR (Status) || !Media.MediaPresent) {\r
- continue;\r
+ if (BlockIo2) {\r
+ Status = BlockIo2Ppi->GetBlockDeviceMediaInfo (\r
+ PeiServices,\r
+ BlockIo2Ppi,\r
+ Index,\r
+ &Media2\r
+ );\r
+ if (EFI_ERROR (Status) || !Media2.MediaPresent) {\r
+ continue;\r
+ }\r
+ PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo2 = BlockIo2Ppi;\r
+ PrivateData->BlockDevice[PrivateData->BlockDeviceCount].InterfaceType = Media2.InterfaceType;\r
+ PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media2.LastBlock;\r
+ PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = Media2.BlockSize;\r
+ } else {\r
+ Status = BlockIoPpi->GetBlockDeviceMediaInfo (\r
+ PeiServices,\r
+ BlockIoPpi,\r
+ Index,\r
+ &Media\r
+ );\r
+ if (EFI_ERROR (Status) || !Media.MediaPresent) {\r
+ continue;\r
+ }\r
+ PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo = BlockIoPpi;\r
+ PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType = Media.DeviceType;\r
+ PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media.LastBlock;\r
+ PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = (UINT32) Media.BlockSize;\r
}\r
\r
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = (UINT32) Media.BlockSize;\r
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media.LastBlock;\r
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign = 0;\r
+ PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign = 0;\r
//\r
// Not used here\r
//\r
PrivateData->BlockDevice[PrivateData->BlockDeviceCount].Logical = FALSE;\r
PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PartitionChecked = FALSE;\r
\r
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo = BlockIoPpi;\r
PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PhysicalDevNo = (UINT8) Index;\r
- PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType = Media.DeviceType;\r
-\r
PrivateData->BlockDeviceCount++;\r
}\r
}\r
BlockIo installation notification function. Find out all the current BlockIO\r
PPIs in the system and add them into private data. Assume there is\r
\r
- @param PeiServices General purpose services available to every \r
- PEIM. \r
- @param NotifyDescriptor The typedef structure of the notification \r
- descriptor. Not used in this function. \r
- @param Ppi The typedef structure of the PPI descriptor. \r
- Not used in this function. \r
+ @param PeiServices General purpose services available to every\r
+ PEIM.\r
+ @param NotifyDescriptor The typedef structure of the notification\r
+ descriptor. Not used in this function.\r
+ @param Ppi The typedef structure of the PPI descriptor.\r
+ Not used in this function.\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
\r
IN VOID *Ppi\r
)\r
{\r
- UpdateBlocksAndVolumes (mPrivateData);\r
-\r
+ if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiVirtualBlockIo2PpiGuid)) {\r
+ UpdateBlocksAndVolumes (mPrivateData, TRUE);\r
+ } else {\r
+ UpdateBlocksAndVolumes (mPrivateData, FALSE);\r
+ }\r
return EFI_SUCCESS;\r
}\r
\r
Installs the Device Recovery Module PPI, Initialize BlockIo Ppi\r
installation notification\r
\r
- @param FileHandle Handle of the file being invoked. Type \r
- EFI_PEI_FILE_HANDLE is defined in \r
- FfsFindNextFile(). \r
- @param PeiServices Describes the list of possible PEI Services. \r
+ @param FileHandle Handle of the file being invoked. Type\r
+ EFI_PEI_FILE_HANDLE is defined in\r
+ FfsFindNextFile().\r
+ @param PeiServices Describes the list of possible PEI Services.\r
\r
- @retval EFI_SUCCESS The entry point was executed successfully. \r
- @retval EFI_OUT_OF_RESOURCES There is no enough memory to complete the \r
+ @retval EFI_SUCCESS The entry point was executed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES There is no enough memory to complete the\r
operations.\r
\r
**/\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
+ PrivateData->PpiDescriptor.Ppi = &PrivateData->DeviceRecoveryPpi;\r
\r
Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor);\r
if (EFI_ERROR (Status)) {\r
//\r
PrivateData->BlockDeviceCount = 0;\r
\r
- UpdateBlocksAndVolumes (PrivateData);\r
+ UpdateBlocksAndVolumes (PrivateData, TRUE);\r
+ UpdateBlocksAndVolumes (PrivateData, FALSE);\r
\r
//\r
// PrivateData is allocated now, set it to the module variable\r
//\r
// Installs Block Io Ppi notification function\r
//\r
- PrivateData->NotifyDescriptor.Flags =\r
+ PrivateData->NotifyDescriptor[0].Flags =\r
+ (\r
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK\r
+ );\r
+ PrivateData->NotifyDescriptor[0].Guid = &gEfiPeiVirtualBlockIoPpiGuid;\r
+ PrivateData->NotifyDescriptor[0].Notify = BlockIoNotifyEntry;\r
+ PrivateData->NotifyDescriptor[1].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
+ PrivateData->NotifyDescriptor[1].Guid = &gEfiPeiVirtualBlockIo2PpiGuid;\r
+ PrivateData->NotifyDescriptor[1].Notify = BlockIoNotifyEntry;\r
+ return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor[0]);\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
+ 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
+ @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
+ @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
//\r
RecoveryCapsuleCount = 0;\r
for (Index = 0; Index < PrivateData->VolumeCount; Index++) {\r
- Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);\r
+ Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr(PcdRecoveryFileName), &Handle);\r
if (EFI_ERROR (Status)) {\r
continue;\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
+ @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
+ @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
+ @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
+ @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
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
RecoveryCapsuleCount = 0;\r
for (Index = 0; Index < PrivateData->VolumeCount; Index++) {\r
- Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);\r
+ Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr(PcdRecoveryFileName), &Handle);\r
\r
if (EFI_ERROR (Status)) {\r
continue;\r
// Fill in the Capsule Type GUID according to the block device type\r
//\r
if (BlockDeviceNo < PrivateData->BlockDeviceCount) {\r
- switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) {\r
- case LegacyFloppy:\r
- CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid);\r
- break;\r
-\r
- case IdeCDROM:\r
- case IdeLS120:\r
- CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);\r
- break;\r
-\r
- case UsbMassStorage:\r
- CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);\r
- break;\r
-\r
- default:\r
- break;\r
+ if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo2 != NULL) {\r
+ switch (PrivateData->BlockDevice[BlockDeviceNo].InterfaceType) {\r
+ case MSG_ATAPI_DP:\r
+ CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);\r
+ break;\r
+\r
+ case MSG_USB_DP:\r
+ CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);\r
+ break;\r
+\r
+ case MSG_NVME_NAMESPACE_DP:\r
+ CopyGuid (CapsuleType, &gRecoveryOnFatNvmeDiskGuid);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo != NULL) {\r
+ switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) {\r
+ case LegacyFloppy:\r
+ CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid);\r
+ break;\r
+\r
+ case IdeCDROM:\r
+ case IdeLS120:\r
+ CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);\r
+ break;\r
+\r
+ case UsbMassStorage:\r
+ CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
}\r
}\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
+ @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
+ @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
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
RecoveryCapsuleCount = 0;\r
for (Index = 0; Index < PrivateData->VolumeCount; Index++) {\r
- Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);\r
+ Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr(PcdRecoveryFileName), &Handle);\r
if (EFI_ERROR (Status)) {\r
continue;\r
}\r
This function finds the the recovery file named FileName on a specified FAT volume and returns\r
its FileHandle pointer.\r
\r
- @param PrivateData Global memory map for accessing global \r
- variables. \r
- @param VolumeIndex The index of the volume. \r
- @param FileName The recovery file name to find. \r
- @param Handle The output file handle. \r
+ @param PrivateData Global memory map for accessing global\r
+ variables.\r
+ @param VolumeIndex The index of the volume.\r
+ @param FileName The recovery file name to find.\r
+ @param Handle The output file handle.\r
\r
- @retval EFI_DEVICE_ERROR Some error occured when operating the FAT \r
- volume. \r
- @retval EFI_NOT_FOUND The recovery file was not found. \r
- @retval EFI_SUCCESS The recovery file was successfully found on the \r
+ @retval EFI_DEVICE_ERROR Some error occured when operating the FAT\r
+ volume.\r
+ @retval EFI_NOT_FOUND The recovery file was not found.\r
+ @retval EFI_SUCCESS The recovery file was successfully found on the\r
FAT volume.\r
\r
**/\r
//\r
// Construct root directory file\r
//\r
+ ZeroMem (&Parent, sizeof (PEI_FAT_FILE));\r
Parent.IsFixedRootDir = (BOOLEAN) ((PrivateData->Volume[VolumeIndex].FatType == Fat32) ? FALSE : TRUE);\r
Parent.Attributes = FAT_ATTR_DIRECTORY;\r
Parent.CurrentPos = 0;\r
//\r
Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);\r
while (Status == EFI_SUCCESS) {\r
+ //\r
+ // Compare whether the file name is recovery file name.\r
+ //\r
if (EngStriColl (PrivateData, FileName, File->FileName)) {\r
break;\r
}\r
return EFI_NOT_FOUND;\r
}\r
\r
+ //\r
+ // Get the recovery file, set its file position to 0.\r
+ //\r
+ if (File->StartingCluster != 0) {\r
+ Status = FatSetFilePos (PrivateData, File, 0);\r
+ }\r
+\r
*Handle = File;\r
\r
return EFI_SUCCESS;\r