Exemplo n.º 1
0
/**
  Loads a DXE capsule from some media into memory.

  This function, by whatever mechanism, retrieves a DXE capsule from some device
  and loads it into memory. Note that the published interface is device neutral.

  @param[in]     PeiServices       General-purpose services that are available
                                   to every PEIM
  @param[in]     This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
                                   instance.
  @param[in]     CapsuleInstance   Specifies which capsule instance to retrieve.
  @param[out]    Buffer            Specifies a caller-allocated buffer in which
                                   the requested recovery capsule will be returned.

  @retval EFI_SUCCESS        The capsule was loaded correctly.
  @retval EFI_DEVICE_ERROR   A device error occurred.
  @retval EFI_NOT_FOUND      A requested recovery DXE capsule cannot be found.

**/
EFI_STATUS
EFIAPI
LoadRecoveryCapsule (
    IN EFI_PEI_SERVICES                             **PeiServices,
    IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI           *This,
    IN UINTN                                        CapsuleInstance,
    OUT VOID                                        *Buffer
)
{
    EFI_STATUS            Status;
    PEI_FAT_PRIVATE_DATA  *PrivateData;
    UINTN                 Index;
    UINTN                 RecoveryCapsuleCount;
    PEI_FILE_HANDLE       Handle;
    UINTN                 NumberRecoveryCapsules;

    Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);

    if (EFI_ERROR (Status)) {
        return Status;
    }

    if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
        CapsuleInstance = CapsuleInstance + 1;
    }

    if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
        return EFI_NOT_FOUND;
    }

    PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);

    //
    // Search each volume in the root directory for the Recovery capsule
    //
    RecoveryCapsuleCount = 0;
    for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
        Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);
        if (EFI_ERROR (Status)) {
            continue;
        }

        if (CapsuleInstance - 1 == RecoveryCapsuleCount) {

            Status = FatReadFile (
                         PrivateData,
                         Handle,
                         (UINTN) (((PEI_FAT_FILE *) Handle)->FileSize),
                         Buffer
                     );
            return Status;
        }

        RecoveryCapsuleCount++;
    }

    return EFI_NOT_FOUND;
}
Exemplo n.º 2
0
/**
  Loads a DXE capsule from some media into memory.

  This function, by whatever mechanism, retrieves a DXE capsule from some device
  and loads it into memory. Note that the published interface is device neutral.

  @param[in]     PeiServices       General-purpose services that are available
                                   to every PEIM
  @param[in]     This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
                                   instance.
  @param[in]     CapsuleInstance   Specifies which capsule instance to retrieve.
  @param[out]    Buffer            Specifies a caller-allocated buffer in which
                                   the requested recovery capsule will be returned.

  @retval EFI_SUCCESS        The capsule was loaded correctly.
  @retval EFI_DEVICE_ERROR   A device error occurred.
  @retval EFI_NOT_FOUND      A requested recovery DXE capsule cannot be found.

**/
EFI_STATUS
EFIAPI
LoadRecoveryCapsule (
    IN EFI_PEI_SERVICES                             **PeiServices,
    IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI           *This,
    IN UINTN                                        CapsuleInstance,
    OUT VOID                                        *Buffer
)
{
    EFI_STATUS                      Status;
    PEI_CD_EXPRESS_PRIVATE_DATA     *PrivateData;
    EFI_PEI_RECOVERY_BLOCK_IO_PPI   *BlockIoPpi;
    EFI_PEI_RECOVERY_BLOCK_IO2_PPI  *BlockIo2Ppi;
    UINTN                           NumberRecoveryCapsules;

    Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);

    if (EFI_ERROR (Status)) {
        return Status;
    }

    if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
        CapsuleInstance = CapsuleInstance + 1;
    }

    if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
        return EFI_NOT_FOUND;
    }

    PrivateData = PEI_CD_EXPRESS_PRIVATE_DATA_FROM_THIS (This);
    BlockIoPpi  = PrivateData->CapsuleData[CapsuleInstance - 1].BlockIo;
    BlockIo2Ppi = PrivateData->CapsuleData[CapsuleInstance - 1].BlockIo2;

    if (BlockIo2Ppi != NULL) {
        Status = BlockIo2Ppi->ReadBlocks (
                     PeiServices,
                     BlockIo2Ppi,
                     PrivateData->CapsuleData[CapsuleInstance - 1].IndexBlock,
                     PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleStartLBA,
                     PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleSize,
                     Buffer
                 );
    } else {
        Status = BlockIoPpi->ReadBlocks (
                     PeiServices,
                     BlockIoPpi,
                     PrivateData->CapsuleData[CapsuleInstance - 1].IndexBlock,
                     PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleStartLBA,
                     PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleSize,
                     Buffer
                 );
    }
    return Status;
}
Exemplo n.º 3
0
/**
  Returns the size and type of the requested recovery capsule.

  This function gets the size and type of the capsule specified by CapsuleInstance.

  @param[in]  PeiServices       General-purpose services that are available to every PEIM
  @param[in]  This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
                                instance.
  @param[in]  CapsuleInstance   Specifies for which capsule instance to retrieve
                                the information.  This parameter must be between
                                one and the value returned by GetNumberRecoveryCapsules()
                                in NumberRecoveryCapsules.
  @param[out] Size              A pointer to a caller-allocated UINTN in which
                                the size of the requested recovery module is
                                returned.
  @param[out] CapsuleType       A pointer to a caller-allocated EFI_GUID in which
                                the type of the requested recovery capsule is
                                returned.  The semantic meaning of the value
                                returned is defined by the implementation.

  @retval EFI_SUCCESS        One or more capsules were discovered.
  @retval EFI_DEVICE_ERROR   A device error occurred.
  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.

**/
EFI_STATUS
EFIAPI
GetRecoveryCapsuleInfo (
    IN  EFI_PEI_SERVICES                              **PeiServices,
    IN  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI            *This,
    IN  UINTN                                         CapsuleInstance,
    OUT UINTN                                         *Size,
    OUT EFI_GUID                                      *CapsuleType
)
{
    PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData;
    UINTN                       NumberRecoveryCapsules;
    EFI_STATUS                  Status;

    Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);

    if (EFI_ERROR (Status)) {
        return Status;
    }

    if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
        CapsuleInstance = CapsuleInstance + 1;
    }

    if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
        return EFI_NOT_FOUND;
    }

    PrivateData = PEI_CD_EXPRESS_PRIVATE_DATA_FROM_THIS (This);

    *Size = PrivateData->CapsuleData[CapsuleInstance - 1].CapsuleSize;
    CopyMem (
        CapsuleType,
        &gRecoveryOnDataCdGuid,
        sizeof (EFI_GUID)
    );

    return EFI_SUCCESS;
}
Exemplo n.º 4
0
/**
  Returns the size and type of the requested recovery capsule.

  This function gets the size and type of the capsule specified by CapsuleInstance.

  @param[in]  PeiServices       General-purpose services that are available to every PEIM
  @param[in]  This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
                                instance.
  @param[in]  CapsuleInstance   Specifies for which capsule instance to retrieve
                                the information.  This parameter must be between
                                one and the value returned by GetNumberRecoveryCapsules()
                                in NumberRecoveryCapsules.
  @param[out] Size              A pointer to a caller-allocated UINTN in which
                                the size of the requested recovery module is
                                returned.
  @param[out] CapsuleType       A pointer to a caller-allocated EFI_GUID in which
                                the type of the requested recovery capsule is
                                returned.  The semantic meaning of the value
                                returned is defined by the implementation.

  @retval EFI_SUCCESS        One or more capsules were discovered.
  @retval EFI_DEVICE_ERROR   A device error occurred.
  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.

**/
EFI_STATUS
EFIAPI
GetRecoveryCapsuleInfo (
    IN  EFI_PEI_SERVICES                              **PeiServices,
    IN  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI            *This,
    IN  UINTN                                         CapsuleInstance,
    OUT UINTN                                         *Size,
    OUT EFI_GUID                                      *CapsuleType
)
{
    EFI_STATUS            Status;
    PEI_FAT_PRIVATE_DATA  *PrivateData;
    UINTN                 Index;
    UINTN                 BlockDeviceNo;
    UINTN                 RecoveryCapsuleCount;
    PEI_FILE_HANDLE       Handle;
    UINTN                 NumberRecoveryCapsules;

    Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);

    if (EFI_ERROR (Status)) {
        return Status;
    }

    if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
        CapsuleInstance = CapsuleInstance + 1;
    }

    if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
        return EFI_NOT_FOUND;
    }

    PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);

    //
    // Search each volume in the root directory for the Recovery capsule
    //
    RecoveryCapsuleCount = 0;
    for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
        Status = FindRecoveryFile (PrivateData, Index, PEI_FAT_RECOVERY_CAPSULE_WITHOUT_NT_EMULATOR, &Handle);

        if (EFI_ERROR (Status)) {
            continue;
        }

        if (CapsuleInstance - 1 == RecoveryCapsuleCount) {
            //
            // Get file size
            //
            *Size = (UINTN) (((PEI_FAT_FILE *) Handle)->FileSize);

            //
            // Find corresponding physical block device
            //
            BlockDeviceNo = PrivateData->Volume[Index].BlockDeviceNo;
            while (PrivateData->BlockDevice[BlockDeviceNo].Logical && BlockDeviceNo < PrivateData->BlockDeviceCount) {
                BlockDeviceNo = PrivateData->BlockDevice[BlockDeviceNo].ParentDevNo;
            }
            //
            // Fill in the Capsule Type GUID according to the block device type
            //
            if (BlockDeviceNo < PrivateData->BlockDeviceCount) {
                if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo2 != NULL) {
                    switch (PrivateData->BlockDevice[BlockDeviceNo].InterfaceType) {
                    case MSG_ATAPI_DP:
                        CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);
                        break;

                    case MSG_USB_DP:
                        CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);
                        break;

                    default:
                        break;
                    }
                }
                if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo != NULL) {
                    switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) {
                    case LegacyFloppy:
                        CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid);
                        break;

                    case IdeCDROM:
                    case IdeLS120:
                        CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);
                        break;

                    case UsbMassStorage:
                        CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);
                        break;

                    default:
                        break;
                    }
                }
            }

            return EFI_SUCCESS;
        }

        RecoveryCapsuleCount++;
    }

    return EFI_NOT_FOUND;
}