Ejemplo 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_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;
}
Ejemplo n.º 2
0
/**
  Finds out all the current Block IO PPIs in the system and add them into private data.

  @param PrivateData                    The private data structure that contains recovery module information.
  @param BlockIo2                       Boolean to show whether using BlockIo2 or BlockIo.

  @retval EFI_SUCCESS                   The blocks and volumes are updated successfully.

**/
EFI_STATUS
UpdateBlocksAndVolumes (
    IN OUT PEI_CD_EXPRESS_PRIVATE_DATA     *PrivateData,
    IN     BOOLEAN                         BlockIo2
)
{
    EFI_STATUS                      Status;
    EFI_PEI_PPI_DESCRIPTOR          *TempPpiDescriptor;
    UINTN                           BlockIoPpiInstance;
    EFI_PEI_RECOVERY_BLOCK_IO_PPI   *BlockIoPpi;
    EFI_PEI_RECOVERY_BLOCK_IO2_PPI  *BlockIo2Ppi;
    UINTN                           NumberBlockDevices;
    UINTN                           IndexBlockDevice;
    EFI_PEI_BLOCK_IO_MEDIA          Media;
    EFI_PEI_BLOCK_IO2_MEDIA         Media2;
    EFI_PEI_SERVICES                **PeiServices;

    IndexBlockDevice = 0;
    BlockIo2Ppi      = NULL;
    BlockIoPpi       = NULL;
    //
    // Find out all Block Io Ppi instances within the system
    // Assuming all device Block Io Peims are dispatched already
    //
    for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_CD_EXPRESS_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {
        if (BlockIo2) {
            Status = PeiServicesLocatePpi (
                         &gEfiPeiVirtualBlockIo2PpiGuid,
                         BlockIoPpiInstance,
                         &TempPpiDescriptor,
                         (VOID **) &BlockIo2Ppi
                     );
        } else {
            Status = PeiServicesLocatePpi (
                         &gEfiPeiVirtualBlockIoPpiGuid,
                         BlockIoPpiInstance,
                         &TempPpiDescriptor,
                         (VOID **) &BlockIoPpi
                     );
        }
        if (EFI_ERROR (Status)) {
            //
            // Done with all Block Io Ppis
            //
            break;
        }

        PeiServices = (EFI_PEI_SERVICES  **) GetPeiServicesTablePointer ();
        if (BlockIo2) {
            Status = BlockIo2Ppi->GetNumberOfBlockDevices (
                         PeiServices,
                         BlockIo2Ppi,
                         &NumberBlockDevices
                     );
        } else {
            Status = BlockIoPpi->GetNumberOfBlockDevices (
                         PeiServices,
                         BlockIoPpi,
                         &NumberBlockDevices
                     );
        }
        if (EFI_ERROR (Status) || (NumberBlockDevices == 0)) {
            continue;
        }
        //
        // Just retrieve the first block, should emulate all blocks.
        //
        for (IndexBlockDevice = 1; IndexBlockDevice <= NumberBlockDevices && PrivateData->CapsuleCount < PEI_CD_EXPRESS_MAX_CAPSULE_NUMBER; IndexBlockDevice ++) {
            if (BlockIo2) {
                Status = BlockIo2Ppi->GetBlockDeviceMediaInfo (
                             PeiServices,
                             BlockIo2Ppi,
                             IndexBlockDevice,
                             &Media2
                         );
                if (EFI_ERROR (Status) ||
                        !Media2.MediaPresent ||
                        ((Media2.InterfaceType != MSG_ATAPI_DP) && (Media2.InterfaceType != MSG_USB_DP)) ||
                        (Media2.BlockSize != PEI_CD_BLOCK_SIZE)
                   ) {
                    continue;
                }
                DEBUG ((EFI_D_INFO, "PeiCdExpress InterfaceType is %d\n", Media2.InterfaceType));
                DEBUG ((EFI_D_INFO, "PeiCdExpress MediaPresent is %d\n", Media2.MediaPresent));
                DEBUG ((EFI_D_INFO, "PeiCdExpress BlockSize is  0x%x\n", Media2.BlockSize));
            } else {
                Status = BlockIoPpi->GetBlockDeviceMediaInfo (
                             PeiServices,
                             BlockIoPpi,
                             IndexBlockDevice,
                             &Media
                         );
                if (EFI_ERROR (Status) ||
                        !Media.MediaPresent ||
                        ((Media.DeviceType != IdeCDROM) && (Media.DeviceType != UsbMassStorage)) ||
                        (Media.BlockSize != PEI_CD_BLOCK_SIZE)
                   ) {
                    continue;
                }
                DEBUG ((EFI_D_INFO, "PeiCdExpress DeviceType is %d\n", Media.DeviceType));
                DEBUG ((EFI_D_INFO, "PeiCdExpress MediaPresent is %d\n", Media.MediaPresent));
                DEBUG ((EFI_D_INFO, "PeiCdExpress BlockSize is  0x%x\n", Media.BlockSize));
            }

            DEBUG ((EFI_D_INFO, "PeiCdExpress Status is %d\n", Status));

            DEBUG ((EFI_D_INFO, "IndexBlockDevice is %d\n", IndexBlockDevice));
            PrivateData->CapsuleData[PrivateData->CapsuleCount].IndexBlock = IndexBlockDevice;
            if (BlockIo2) {
                PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo2 = BlockIo2Ppi;
            } else {
                PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo  = BlockIoPpi;
            }
            Status = FindRecoveryCapsules (PrivateData);
            DEBUG ((EFI_D_INFO, "Status is %d\n", Status));

            if (EFI_ERROR (Status)) {
                continue;
            }

            PrivateData->CapsuleCount++;
        }

    }

    return EFI_SUCCESS;
}
Ejemplo n.º 3
0
/**
  Finds out the recovery capsule in the current volume.

  @param PrivateData                    The private data structure that contains recovery module information.

  @retval EFI_SUCCESS                   The recovery capsule is successfully found in the volume.
  @retval EFI_NOT_FOUND                 The recovery capsule is not found in the volume.

**/
EFI_STATUS
EFIAPI
FindRecoveryCapsules (
    IN OUT PEI_CD_EXPRESS_PRIVATE_DATA            *PrivateData
)
{
    EFI_STATUS                      Status;
    UINTN                           Lba;
    EFI_PEI_RECOVERY_BLOCK_IO_PPI   *BlockIoPpi;
    EFI_PEI_RECOVERY_BLOCK_IO2_PPI  *BlockIo2Ppi;
    UINTN                           BufferSize;
    UINT8                           *Buffer;
    UINT8                           Type;
    UINT8                           *StandardID;
    UINT32                          RootDirLBA;
    PEI_CD_EXPRESS_DIR_FILE_RECORD  *RoorDirRecord;
    UINTN                           VolumeSpaceSize;
    BOOLEAN                         StartOfVolume;
    UINTN                           OriginalLBA;
    UINTN                           IndexBlockDevice;

    Buffer      = PrivateData->BlockBuffer;
    BufferSize  = PEI_CD_BLOCK_SIZE;

    Lba         = 16;
    //
    // The volume descriptor starts on Lba 16
    //
    IndexBlockDevice = PrivateData->CapsuleData[PrivateData->CapsuleCount].IndexBlock;
    BlockIoPpi       = PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo;
    BlockIo2Ppi      = PrivateData->CapsuleData[PrivateData->CapsuleCount].BlockIo2;

    VolumeSpaceSize = 0;
    StartOfVolume   = TRUE;
    OriginalLBA     = 16;

    while (TRUE) {
        SetMem (Buffer, BufferSize, 0);
        if (BlockIo2Ppi != NULL) {
            Status = BlockIo2Ppi->ReadBlocks (
                         (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (),
                         BlockIo2Ppi,
                         IndexBlockDevice,
                         Lba,
                         BufferSize,
                         Buffer
                     );
        } else {
            Status = BlockIoPpi->ReadBlocks (
                         (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (),
                         BlockIoPpi,
                         IndexBlockDevice,
                         Lba,
                         BufferSize,
                         Buffer
                     );
        }
        if (EFI_ERROR (Status)) {
            return Status;
        }

        StandardID = (UINT8 *) (Buffer + PEI_CD_EXPRESS_STANDARD_ID_OFFSET);
        if (!StringCmp (StandardID, (UINT8 *) PEI_CD_STANDARD_ID, PEI_CD_EXPRESS_STANDARD_ID_SIZE, TRUE)) {
            break;
        }

        if (StartOfVolume) {
            OriginalLBA   = Lba;
            StartOfVolume = FALSE;
        }

        Type = *(UINT8 *) (Buffer + PEI_CD_EXPRESS_VOLUME_TYPE_OFFSET);
        if (Type == PEI_CD_EXPRESS_VOLUME_TYPE_TERMINATOR) {
            if (VolumeSpaceSize == 0) {
                break;
            } else {
                Lba             = (OriginalLBA + VolumeSpaceSize);
                VolumeSpaceSize = 0;
                StartOfVolume   = TRUE;
                continue;
            }
        }

        if (Type != PEI_CD_EXPRESS_VOLUME_TYPE_PRIMARY) {
            Lba++;
            continue;
        }

        VolumeSpaceSize = *(UINT32 *) (Buffer + PEI_CD_EXPRESS_VOLUME_SPACE_OFFSET);

        RoorDirRecord   = (PEI_CD_EXPRESS_DIR_FILE_RECORD *) (Buffer + PEI_CD_EXPRESS_ROOT_DIR_RECORD_OFFSET);
        RootDirLBA      = RoorDirRecord->LocationOfExtent[0];

        Status          = RetrieveCapsuleFileFromRoot (PrivateData, BlockIoPpi, BlockIo2Ppi, IndexBlockDevice, RootDirLBA);
        if (!EFI_ERROR (Status)) {
            //
            // Just look for the first primary descriptor
            //
            return EFI_SUCCESS;
        }

        Lba++;
    }

    return EFI_NOT_FOUND;
}
Ejemplo n.º 4
0
/**
  Discover all the block I/O devices to find the FAT volume.

  @param  PrivateData             Global memory map for accessing global
                                  variables.
  @param  BlockIo2                Boolean to show whether using BlockIo2 or BlockIo

  @retval EFI_SUCCESS             The function completed successfully.

**/
EFI_STATUS
UpdateBlocksAndVolumes (
    IN OUT PEI_FAT_PRIVATE_DATA            *PrivateData,
    IN     BOOLEAN                         BlockIo2
)
{
    EFI_STATUS                     Status;
    EFI_PEI_PPI_DESCRIPTOR         *TempPpiDescriptor;
    UINTN                          BlockIoPpiInstance;
    EFI_PEI_RECOVERY_BLOCK_IO_PPI  *BlockIoPpi;
    EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2Ppi;
    UINTN                          NumberBlockDevices;
    UINTN                          Index;
    EFI_PEI_BLOCK_IO_MEDIA         Media;
    EFI_PEI_BLOCK_IO2_MEDIA        Media2;
    PEI_FAT_VOLUME                 Volume;
    EFI_PEI_SERVICES               **PeiServices;

    PeiServices = (EFI_PEI_SERVICES **) GetPeiServicesTablePointer ();
    BlockIo2Ppi = NULL;
    BlockIoPpi  = NULL;
    //
    // Clean up caches
    //
    for (Index = 0; Index < PEI_FAT_CACHE_SIZE; Index++) {
        PrivateData->CacheBuffer[Index].Valid = FALSE;
    }

    PrivateData->BlockDeviceCount = 0;

    //
    // Find out all Block Io Ppi instances within the system
    // Assuming all device Block Io Peims are dispatched already
    //
    for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_FAT_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {
        if (BlockIo2) {
            Status = PeiServicesLocatePpi (
                         &gEfiPeiVirtualBlockIo2PpiGuid,
                         BlockIoPpiInstance,
                         &TempPpiDescriptor,
                         (VOID **) &BlockIo2Ppi
                     );
        } else {
            Status = PeiServicesLocatePpi (
                         &gEfiPeiVirtualBlockIoPpiGuid,
                         BlockIoPpiInstance,
                         &TempPpiDescriptor,
                         (VOID **) &BlockIoPpi
                     );
        }
        if (EFI_ERROR (Status)) {
            //
            // Done with all Block Io Ppis
            //
            break;
        }

        if (BlockIo2) {
            Status = BlockIo2Ppi->GetNumberOfBlockDevices (
                         PeiServices,
                         BlockIo2Ppi,
                         &NumberBlockDevices
                     );
        } else {
            Status = BlockIoPpi->GetNumberOfBlockDevices (
                         PeiServices,
                         BlockIoPpi,
                         &NumberBlockDevices
                     );
        }
        if (EFI_ERROR (Status)) {
            continue;
        }

        for (Index = 1; Index <= NumberBlockDevices && PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE; Index++) {

            if (BlockIo2) {
                Status = BlockIo2Ppi->GetBlockDeviceMediaInfo (
                             PeiServices,
                             BlockIo2Ppi,
                             Index,
                             &Media2
                         );
                if (EFI_ERROR (Status) || !Media2.MediaPresent) {
                    continue;
                }
                PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo2        = BlockIo2Ppi;
                PrivateData->BlockDevice[PrivateData->BlockDeviceCount].InterfaceType   = Media2.InterfaceType;
                PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock       = Media2.LastBlock;
                PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize       = Media2.BlockSize;
            } else {
                Status = BlockIoPpi->GetBlockDeviceMediaInfo (
                             PeiServices,
                             BlockIoPpi,
                             Index,
                             &Media
                         );
                if (EFI_ERROR (Status) || !Media.MediaPresent) {
                    continue;
                }
                PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo    = BlockIoPpi;
                PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType    = Media.DeviceType;
                PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock  = Media.LastBlock;
                PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize  = (UINT32) Media.BlockSize;
            }

            PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign = 0;
            //
            // Not used here
            //
            PrivateData->BlockDevice[PrivateData->BlockDeviceCount].Logical           = FALSE;
            PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PartitionChecked  = FALSE;

            PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PhysicalDevNo     = (UINT8) Index;
            PrivateData->BlockDeviceCount++;
        }
    }
    //
    // Find out all logical devices
    //
    FatFindPartitions (PrivateData);

    //
    // Build up file system volume array
    //
    PrivateData->VolumeCount = 0;
    for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) {
        Volume.BlockDeviceNo  = Index;
        Status                = FatGetBpbInfo (PrivateData, &Volume);
        if (Status == EFI_SUCCESS) {
            //
            // Add the detected volume to the volume array
            //
            CopyMem (
                (UINT8 *) &(PrivateData->Volume[PrivateData->VolumeCount]),
                (UINT8 *) &Volume,
                sizeof (PEI_FAT_VOLUME)
            );
            PrivateData->VolumeCount += 1;
            if (PrivateData->VolumeCount >= PEI_FAT_MAX_VOLUME) {
                break;
            }
        }
    }

    return EFI_SUCCESS;
}