Exemple #1
0
/**
  Register image to memory profile.

  @param FileName       File name of the image.
  @param ImageBase      Image base address.
  @param ImageSize      Image size.
  @param FileType       File type of the image.

**/
VOID
RegisterMemoryProfileImage (
  IN EFI_GUID                       *FileName,
  IN PHYSICAL_ADDRESS               ImageBase,
  IN UINT64                         ImageSize,
  IN EFI_FV_FILETYPE                FileType
  )
{
  EFI_STATUS                        Status;
  EDKII_MEMORY_PROFILE_PROTOCOL     *ProfileProtocol;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;
  UINT8                             TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];

  if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0) {

    FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;
    Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **) &ProfileProtocol);
    if (!EFI_ERROR (Status)) {
      EfiInitializeFwVolDevicepathNode (FilePath, FileName);
      SetDevicePathEndNode (FilePath + 1);

      Status = ProfileProtocol->RegisterImage (
                                  ProfileProtocol,
                                  (EFI_DEVICE_PATH_PROTOCOL *) FilePath,
                                  ImageBase,
                                  ImageSize,
                                  FileType
                                  );
    }
  }
}
Exemple #2
0
/**
  Convert FvHandle and DriverName into an EFI device path

  @param  Fv                    Fv protocol, needed to read Depex info out of
                                FLASH.
  @param  FvHandle              Handle for Fv, needed in the
                                EFI_SMM_DRIVER_ENTRY so that the PE image can be
                                read out of the FV at a later time.
  @param  DriverName            Name of driver to add to mDiscoveredList.

  @return Pointer to device path constructed from FvHandle and DriverName

**/
EFI_DEVICE_PATH_PROTOCOL *
SmmFvToDevicePath (
  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
  IN  EFI_HANDLE                      FvHandle,
  IN  EFI_GUID                        *DriverName
  )
{
  EFI_STATUS                          Status;
  EFI_DEVICE_PATH_PROTOCOL            *FvDevicePath;
  EFI_DEVICE_PATH_PROTOCOL            *FileNameDevicePath;

  //
  // Remember the device path of the FV
  //
  Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
  if (EFI_ERROR (Status)) {
    FileNameDevicePath = NULL;
  } else {
    //
    // Build a device path to the file in the FV to pass into gBS->LoadImage
    //
    EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);
    SetDevicePathEndNode (&mFvDevicePath.End);

    //
    // Note: FileNameDevicePath is in DXE memory
    //
    FileNameDevicePath = AppendDevicePath (
                            FvDevicePath,
                            (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
                            );
  }
  return FileNameDevicePath;
}
Exemple #3
0
EFI_DEVICE_PATH *
FvFileDevicePath (
  IN  EFI_HANDLE   FvHandle,
  IN  EFI_GUID     *NameGuid
  )
{
  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH NewNode;

  DevicePath = DevicePathFromHandle (FvHandle);

  EfiInitializeFwVolDevicepathNode (&NewNode, NameGuid);

  return AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&NewNode);
}
Exemple #4
0
VOID
PlatformRegisterFvBootOption (
  EFI_GUID                         *FileGuid,
  CHAR16                           *Description,
  UINT32                           Attributes
  )
{
  EFI_STATUS                        Status;
  UINTN                             OptionIndex;
  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
  UINTN                             BootOptionCount;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;

  Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
  ASSERT_EFI_ERROR (Status);

  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
  DevicePath = AppendDevicePathNode (
                 DevicePathFromHandle (LoadedImage->DeviceHandle),
                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
                 );

  Status = EfiBootManagerInitializeLoadOption (
             &NewOption,
             LoadOptionNumberUnassigned,
             LoadOptionTypeBoot,
             Attributes,
             Description,
             DevicePath,
             NULL,
             0
             );
  if (!EFI_ERROR (Status)) {
    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);

    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);

    if (OptionIndex == -1) {
      Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);
      ASSERT_EFI_ERROR (Status);
    }
    EfiBootManagerFreeLoadOption (&NewOption);
    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
  }
}
STATIC
EFI_STATUS
CreatePlatformBootOptionFromGuid (
  IN     EFI_GUID                        *FileGuid,
  IN     CHAR16                          *Description,
  IN OUT EFI_BOOT_MANAGER_LOAD_OPTION    *BootOption
  )
{
  EFI_STATUS                             Status;
  EFI_DEVICE_PATH                        *DevicePath;
  EFI_DEVICE_PATH                        *TempDevicePath;
  EFI_LOADED_IMAGE_PROTOCOL              *LoadedImage;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH      FileNode;

  Status = gBS->HandleProtocol (
                  gImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **) &LoadedImage
                  );
  ASSERT_EFI_ERROR (Status);
  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
  TempDevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
  ASSERT (TempDevicePath != NULL);
  DevicePath = AppendDevicePathNode (
                 TempDevicePath,
                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
                 );
  ASSERT (DevicePath != NULL);
  Status = EfiBootManagerInitializeLoadOption (
             BootOption,
             LoadOptionNumberUnassigned,
             LoadOptionTypeBoot,
             LOAD_OPTION_ACTIVE,
             Description,
             DevicePath,
             NULL,
             0
             );
  FreePool (DevicePath);
  return Status;
}
/**
  Generate device path include the input file guid info.

  @param  FileGuid     Input file guid for the BootManagerMenuApp.

  @retval DevicePath for BootManagerMenuApp.
**/
EFI_DEVICE_PATH *
FvFilePath (
  EFI_GUID                     *FileGuid
  )
{

  EFI_STATUS                         Status;
  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  FileNode;

  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);

  Status = gBS->HandleProtocol (
                  gImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **) &LoadedImage
                  );
  ASSERT_EFI_ERROR (Status);

  return AppendDevicePathNode (
           DevicePathFromHandle (LoadedImage->DeviceHandle),
           (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
           );
}
Exemple #7
0
EFI_DEVICE_PATH *
FvFilePath (
  UINTN                         FvBaseAddress,
  UINTN                         FvSize,
  EFI_GUID                     *FileGuid
  )
{
  
  EFI_STATUS                         Status;
  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  FileNode;
  EFI_HANDLE                         FvProtocolHandle; 
  EFI_HANDLE                         *FvHandleBuffer;
  UINTN                              FvHandleCount;
  EFI_FV_FILETYPE                    Type;
  UINTN                              Size;
  EFI_FV_FILE_ATTRIBUTES             Attributes;
  UINT32                             AuthenticationStatus;
  EFI_FIRMWARE_VOLUME2_PROTOCOL      *Fv;
  UINTN                              Index;

  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);

  if (FvBaseAddress == 0) {
    Status = gBS->HandleProtocol (
                  gImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **) &LoadedImage
                  );
    ASSERT_EFI_ERROR (Status);
    return AppendDevicePathNode (
           DevicePathFromHandle (LoadedImage->DeviceHandle),
           (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
           );
  }
  else {
    //
    // Expose Payload file in FV
    //  
    gDS->ProcessFirmwareVolume (
           (VOID *)FvBaseAddress,
           (UINT32)FvSize,
           &FvProtocolHandle
           );

    //
    // Find out the handle of FV containing the playload file
    //
    FvHandleBuffer = NULL;
    gBS->LocateHandleBuffer (
          ByProtocol,
          &gEfiFirmwareVolume2ProtocolGuid,
          NULL,
          &FvHandleCount,
          &FvHandleBuffer
          );
    for (Index = 0; Index < FvHandleCount; Index++) {
      gBS->HandleProtocol (
            FvHandleBuffer[Index],
            &gEfiFirmwareVolume2ProtocolGuid,
            (VOID **) &Fv
            );
      Status = Fv->ReadFile (
                  Fv,
                  FileGuid,
                  NULL,
                  &Size,
                  &Type,
                  &Attributes,
                  &AuthenticationStatus
                  );
      if (!EFI_ERROR (Status)) {
        break;
      }
    }
    if (Index < FvHandleCount) {
      return AppendDevicePathNode (
            DevicePathFromHandle (FvHandleBuffer[Index]),
            (  EFI_DEVICE_PATH_PROTOCOL *) &FileNode
            );
    }
  }
  return NULL;
}
Exemple #8
0
/**
Internal work function to fill in EFI_OPEN_FILE information for the FV

@param  File        Open file handle
@param  FileName    Name of file after device stripped off


**/
EFI_STATUS
EblFvFileDevicePath (
  IN OUT EFI_OPEN_FILE  *File,
  IN  CHAR8             *FileName,
  IN  CONST UINT64      OpenMode
  )
{
  EFI_STATUS                          Status;
  EFI_STATUS                          GetNextFileStatus;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH   DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
  UINTN                               Key;
  UINT32                              AuthenticationStatus;
  CHAR8                               AsciiSection[MAX_PATHNAME];
  VOID                                *Section;
  UINTN                               SectionSize;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;
  EFI_LBA                             Lba;
  UINTN                               BlockSize;
  UINTN                               NumberOfBlocks;
  EFI_FIRMWARE_VOLUME_HEADER          *FvHeader = NULL;
  UINTN                               Index;


  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&File->Fv);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Get FVB Info about the handle
  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
  if (!EFI_ERROR (Status)) {
    Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
    if (!EFI_ERROR (Status)) {
      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)File->FvStart;
      File->FvHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
      for (Index = 0; FvHeader->BlockMap[Index].Length !=0; Index++) {
        File->FvHeaderSize += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
      }

      for (Lba = 0, File->FvSize = 0, NumberOfBlocks = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
        Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks);
        if (EFI_ERROR (Status)) {
          break;
        }
      }
    }
  }


  DevicePath = DevicePathFromHandle (File->EfiHandle);

  if (*FileName == '\0') {
    File->DevicePath = DuplicateDevicePath (DevicePath);
    File->Size = File->FvSize;
    File->MaxPosition = File->Size;
  } else {
    Key = 0;
    do {
      File->FvType = EFI_FV_FILETYPE_ALL;
      GetNextFileStatus = File->Fv->GetNextFile (
        File->Fv,
        &Key,
        &File->FvType,
        &File->FvNameGuid,
        &File->FvAttributes,
        &File->Size
        );
      if (!EFI_ERROR (GetNextFileStatus)) {
        // Compare GUID first
        Status = CompareGuidToString (&File->FvNameGuid, FileName);
        if (!EFI_ERROR(Status)) {
          break;
        }

        Section = NULL;
        Status = File->Fv->ReadSection (
          File->Fv,
          &File->FvNameGuid,
          EFI_SECTION_USER_INTERFACE,
          0,
          &Section,
          &SectionSize,
          &AuthenticationStatus
          );
        if (!EFI_ERROR (Status)) {
          UnicodeStrToAsciiStr (Section, AsciiSection);
          if (AsciiStriCmp (FileName, AsciiSection) == 0) {
            FreePool (Section);
            break;
          }
          FreePool (Section);
        }
      }
    } while (!EFI_ERROR (GetNextFileStatus));

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

    if (OpenMode != EFI_SECTION_ALL) {
      // Calculate the size of the section we are targeting
      Section = NULL;
      File->Size = 0;
      Status = File->Fv->ReadSection (
        File->Fv,
        &File->FvNameGuid,
        (EFI_SECTION_TYPE)OpenMode,
        0,
        &Section,
        &File->Size,
        &AuthenticationStatus
        );
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    File->MaxPosition = File->Size;
    EfiInitializeFwVolDevicepathNode (&DevicePathNode, &File->FvNameGuid);
    File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode);
  }


  // FVB not required if FV was soft loaded...
  return EFI_SUCCESS;
}
Exemple #9
0
/**
  Searches all the available firmware volumes and returns the file device path of first matching
  FFS section.

  This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid.
  The order that the firmware volumes is searched is not deterministic. For each FFS file found a search
  is made for FFS sections of type SectionType.

  If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
  the search will be retried with a section type of EFI_SECTION_PE32.
  This function must be called with a TPL <= TPL_NOTIFY.

  If NameGuid is NULL, then ASSERT().

   @param  NameGuid             A pointer to to the FFS filename GUID to search for
                                within any of the firmware volumes in the platform.
   @param  SectionType          Indicates the FFS section type to search for within
                                the FFS file specified by NameGuid.
   @param  SectionInstance      Indicates which section instance within the FFS file
                                specified by NameGuid to retrieve.
   @param  FvFileDevicePath     Device path for the target FFS
                                file.

   @retval  EFI_SUCCESS           The specified file device path of FFS section was returned.
   @retval  EFI_NOT_FOUND         The specified file device path of FFS section could not be found.
   @retval  EFI_DEVICE_ERROR      The FFS section could not be retrieves due to a
                                  device error.
   @retval  EFI_ACCESS_DENIED     The FFS section could not be retrieves because the
                                  firmware volume that contains the matching FFS section does not
                                  allow reads.
   @retval  EFI_INVALID_PARAMETER FvFileDevicePath is NULL.

**/
EFI_STATUS
EFIAPI
GetFileDevicePathFromAnyFv (
  IN CONST  EFI_GUID                  *NameGuid,
  IN        EFI_SECTION_TYPE          SectionType,
  IN        UINTN                     SectionInstance,
  OUT       EFI_DEVICE_PATH_PROTOCOL  **FvFileDevicePath
  )
{
  EFI_STATUS                        Status;
  EFI_HANDLE                        *HandleBuffer;
  UINTN                             HandleCount;
  UINTN                             Index;
  EFI_HANDLE                        FvHandle;
  EFI_DEVICE_PATH_PROTOCOL          *FvDevicePath;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *TempFvFileDevicePath;
  VOID                              *Buffer;
  UINTN                             Size;

  if (FvFileDevicePath == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  HandleBuffer         = NULL;
  FvDevicePath         = NULL;
  TempFvFileDevicePath = NULL;
  Buffer               = NULL;
  Size                 = 0;

  //
  // Search the FV that contain the caller's FFS first.
  // FV builder can choose to build FFS into the this FV
  // so that this implementation of GetSectionFromAnyFv
  // will locate the FFS faster.
  //
  FvHandle = InternalImageHandleToFvHandle (gImageHandle);
  Status = InternalGetSectionFromFv (
             FvHandle,
             NameGuid,
             SectionType,
             SectionInstance,
             &Buffer,
             &Size
             );
  if (!EFI_ERROR (Status)) {
    goto Done;
  }

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiFirmwareVolume2ProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  for (Index = 0; Index < HandleCount; Index++) {
    //
    // Skip the FV that contain the caller's FFS
    //
    if (HandleBuffer[Index] != FvHandle) {
      Status = InternalGetSectionFromFv (
                 HandleBuffer[Index],
                 NameGuid,
                 SectionType,
                 SectionInstance,
                 &Buffer,
                 &Size
                 );

      if (!EFI_ERROR (Status)) {
        //
        // Update FvHandle to the current handle.
        //
        FvHandle = HandleBuffer[Index];
        goto Done;
      }
    }
  }

  if (Index == HandleCount) {
    Status = EFI_NOT_FOUND;
  }

Done:
  if (Status == EFI_SUCCESS) {
    //
    // Build a device path to the file in the FV to pass into gBS->LoadImage
    //
    Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
    if (EFI_ERROR (Status)) {
      *FvFileDevicePath = NULL;
    } else {
      TempFvFileDevicePath = AllocateZeroPool (sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + END_DEVICE_PATH_LENGTH);
      if (TempFvFileDevicePath == NULL) {
        *FvFileDevicePath = NULL;
        return EFI_OUT_OF_RESOURCES;
      }
      EfiInitializeFwVolDevicepathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)TempFvFileDevicePath, NameGuid);
      SetDevicePathEndNode (NextDevicePathNode (TempFvFileDevicePath));
      *FvFileDevicePath = AppendDevicePath (
                            FvDevicePath,
                            (EFI_DEVICE_PATH_PROTOCOL *)TempFvFileDevicePath
                            );
      FreePool (TempFvFileDevicePath);
    }
  }

  if (Buffer != NULL) {
    FreePool (Buffer);
  }

  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
  }

  return Status;
}