Exemplo n.º 1
0
EFI_STATUS
EFIAPI
FvbProtocolSetAttributes (
  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *This,
  IN OUT EFI_FVB_ATTRIBUTES_2                     *Attributes
  )
/*++

Routine Description:
  Sets Volume attributes. No polarity translations are done.

Arguments:
  This                  - Calling context
  Attributes            - output buffer which contains attributes

Returns:
  EFI_SUCCESS           - Successfully returns

**/
{
  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());
}
Exemplo n.º 2
0
//
// FVB protocol APIs
//
EFI_STATUS
EFIAPI
FvbProtocolGetPhysicalAddress (
  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *This,
  OUT EFI_PHYSICAL_ADDRESS                        *Address
  )
/*++

Routine Description:

  Retrieves the physical address of the device.

Arguments:

  This                  - Calling context
  Address               - Output buffer containing the address.

Returns:

Returns:
  EFI_SUCCESS           - Successfully returns

**/
{
  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());
}
Exemplo n.º 3
0
EFI_STATUS
EFIAPI
FvbProtocolGetBlockSize (
  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *This,
  IN  EFI_LBA                                     Lba,
  OUT UINTN                                       *BlockSize,
  OUT UINTN                                       *NumOfBlocks
  )
/*++

Routine Description:
  Retrieve the size of a logical block

Arguments:
  This                  - Calling context
  Lba                   - Indicates which block to return the size for.
  BlockSize             - A pointer to a caller allocated UINTN in which
                          the size of the block is returned
  NumOfBlocks           - a pointer to a caller allocated UINTN in which the
                          number of consecutive blocks starting with Lba is
                          returned. All blocks in this range have a size of
                          BlockSize

Returns:
  EFI_SUCCESS           - The firmware volume was read successfully and
                          contents are in Buffer

**/
{
  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  return FvbGetLbaAddress (
          FvbDevice->Instance,
          Lba,
          NULL,
          BlockSize,
          NumOfBlocks,
          mFvbModuleGlobal,
          EfiGoneVirtual ()
          );
}
Exemplo n.º 4
0
/**
  Check whether crypto service provided by Runtime Crypt protocol is ready to use.

  Crypto service is available if the call is in physical mode prior to
  SetVirtualAddressMap() or virtual mode after SetVirtualAddressMap(). If either
  of these two conditions are met, this routine will return TRUE; if neither of
  these conditions are met, this routine will return FALSE.

  @retval TRUE   The Crypto service is ready to use.
  @retval FALSE  The Crypto service is not available.

**/
BOOLEAN
EFIAPI
InternalIsCryptServiveAvailable (
  VOID
  )
{
  INT64    CpuMode;
  BOOLEAN  GoneVirtual;

  CpuMode = AsmCpuVirtual();
  if (CpuMode < 0) {
    //
    // CPU is in mixed mode, return failing the operation gracefully.
    //
    return FALSE;
  }

  GoneVirtual = EfiGoneVirtual();

  if ((CpuMode > 0) && !GoneVirtual) {
    //
    // CPU is in virtual mode, but SetVirtualAddressMap() has not been called,
    // so return failing the operation gracefully.
    //
    return FALSE;
  }

  if ((CpuMode == 0) && GoneVirtual) {
    //
    // CPU is in physical mode, but SetVirtualAddressMap() has been called,
    // so return failing the operation gracefully.
    //
    return FALSE;
  }

  return TRUE;
}
Exemplo n.º 5
0
EFI_STATUS
EFIAPI
FvbProtocolRead (
  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *This,
  IN EFI_LBA                                      Lba,
  IN UINTN                                        Offset,
  IN OUT UINTN                                    *NumBytes,
  IN UINT8                                        *Buffer
  )
/*++

Routine Description:

  Reads data beginning at Lba:Offset from FV. The Read terminates either
  when *NumBytes of data have been read, or when a block boundary is
  reached.  *NumBytes is updated to reflect the actual number of bytes
  written. The write opertion does not include erase. This routine will
  attempt to write only the specified bytes. If the writes do not stick,
  it will return an error.

Arguments:
  This                  - Calling context
  Lba                   - Block in which to begin Read
  Offset                - Offset in the block at which to begin Read
  NumBytes              - On input, indicates the requested write size. On
                          output, indicates the actual number of bytes Read
  Buffer                - Buffer containing source data for the Read.

Returns:
  EFI_SUCCESS           - The firmware volume was read successfully and
                          contents are in Buffer
  EFI_BAD_BUFFER_SIZE   - Read attempted across a LBA boundary. On output,
                          NumBytes contains the total number of bytes returned
                          in Buffer
  EFI_ACCESS_DENIED     - The firmware volume is in the ReadDisabled state
  EFI_DEVICE_ERROR      - The block device is not functioning correctly and
                          could not be read
  EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL

**/
{

  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  return FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());
}
Exemplo n.º 6
0
EFI_STATUS
EFIAPI
FvbProtocolEraseBlocks (
  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
  ...
  )
/*++

Routine Description:

  The EraseBlock() function erases one or more blocks as denoted by the
  variable argument list. The entire parameter list of blocks must be verified
  prior to erasing any blocks.  If a block is requested that does not exist
  within the associated firmware volume (it has a larger index than the last
  block of the firmware volume), the EraseBlock() function must return
  EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.

Arguments:
  This                  - Calling context
  ...                   - Starting LBA followed by Number of Lba to erase.
                          a -1 to terminate the list.

Returns:
  EFI_SUCCESS           - The erase request was successfully completed
  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state
  EFI_DEVICE_ERROR      - The block device is not functioning correctly and
                          could not be written. Firmware device may have been
                          partially erased

**/
{
  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
  EFI_FW_VOL_INSTANCE     *FwhInstance = NULL;
  UINTN                   NumOfBlocks;
  VA_LIST                 args;
  EFI_LBA                 StartingLba;
  UINTN                   NumOfLba;
  EFI_STATUS              Status;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  Status    = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());
  ASSERT_EFI_ERROR (Status);

  NumOfBlocks = FwhInstance->NumOfBlocks;

  VA_START (args, This);

  do {
    StartingLba = VA_ARG (args, EFI_LBA);
    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
      break;
    }

    NumOfLba = VA_ARG (args, UINTN);

    //
    // Check input parameters
    //
    if (NumOfLba == 0 || (StartingLba + NumOfLba) > NumOfBlocks) {
      VA_END (args);
      return EFI_INVALID_PARAMETER;
    }
  } while (1);

  VA_END (args);

  VA_START (args, This);
  do {
    StartingLba = VA_ARG (args, EFI_LBA);
    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
      break;
    }

    NumOfLba = VA_ARG (args, UINTN);

    while (NumOfLba > 0) {
      Status = FvbEraseBlock (FvbDevice->Instance, StartingLba, mFvbModuleGlobal, EfiGoneVirtual ());
      if (EFI_ERROR (Status)) {
        VA_END (args);
        return Status;
      }

      StartingLba++;
      NumOfLba--;
    }

  } while (1);

  VA_END (args);

  return EFI_SUCCESS;
}
Exemplo n.º 7
0
/**
  Communicates with a registered handler.
  
  This function provides a service to send and receive messages from a registered 
  UEFI service.  This function is part of the SMM Communication Protocol that may 
  be called in physical mode prior to SetVirtualAddressMap() and in virtual mode 
  after SetVirtualAddressMap().

  @param[in] This                The EFI_SMM_COMMUNICATION_PROTOCOL instance.
  @param[in, out] CommBuffer          A pointer to the buffer to convey into SMRAM.
  @param[in, out] CommSize            The size of the data buffer being passed in.On exit, the size of data
                                 being returned. Zero if the handler does not wish to reply with any data.

  @retval EFI_SUCCESS            The message was successfully posted.
  @retval EFI_INVALID_PARAMETER  The CommBuffer was NULL.
**/
EFI_STATUS
EFIAPI
SmmCommunicationCommunicate (
  IN CONST EFI_SMM_COMMUNICATION_PROTOCOL  *This,
  IN OUT VOID                              *CommBuffer,
  IN OUT UINTN                             *CommSize
  )
{
  EFI_STATUS                  Status;
  EFI_SMM_COMMUNICATE_HEADER  *CommunicateHeader;
  BOOLEAN                     OldInSmm;

  //
  // Check parameters
  //
  if ((CommBuffer == NULL) || (CommSize == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // CommSize must hold HeaderGuid and MessageLength
  //
  if (*CommSize < OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // If not already in SMM, then generate a Software SMI
  //
  if (!gSmmCorePrivate->InSmm && gSmmCorePrivate->SmmEntryPointRegistered) {
    //
    // Put arguments for Software SMI in gSmmCorePrivate
    //
    gSmmCorePrivate->CommunicationBuffer = CommBuffer;
    gSmmCorePrivate->BufferSize          = *CommSize;

    //
    // Generate Software SMI
    //
    Status = mSmmControl2->Trigger (mSmmControl2, NULL, NULL, FALSE, 0);
    if (EFI_ERROR (Status)) {
      return EFI_UNSUPPORTED;
    }

    //
    // Return status from software SMI 
    //
    *CommSize = gSmmCorePrivate->BufferSize;
    return gSmmCorePrivate->ReturnStatus;
  }

  //
  // If we are in SMM, then the execution mode must be physical, which means that
  // OS established virtual addresses can not be used.  If SetVirtualAddressMap()
  // has been called, then a direct invocation of the Software SMI is not 
  // not allowed so return EFI_INVALID_PARAMETER.
  //
  if (EfiGoneVirtual()) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // If we are not in SMM, don't allow call SmiManage() directly when SMRAM is closed or locked.
  //
  if ((!gSmmCorePrivate->InSmm) && (!mSmmAccess->OpenState || mSmmAccess->LockState)) {
    return EFI_INVALID_PARAMETER;
  }
 
  //
  // Save current InSmm state and set InSmm state to TRUE
  //
  OldInSmm = gSmmCorePrivate->InSmm;
  gSmmCorePrivate->InSmm = TRUE;

  //
  // Already in SMM and before SetVirtualAddressMap(), so call SmiManage() directly.
  //
  CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommBuffer;
  *CommSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
  Status = gSmmCorePrivate->Smst->SmiManage (
                                    &CommunicateHeader->HeaderGuid, 
                                    NULL, 
                                    CommunicateHeader->Data, 
                                    CommSize
                                    );

  //
  // Update CommunicationBuffer, BufferSize and ReturnStatus
  // Communicate service finished, reset the pointer to CommBuffer to NULL
  //
  *CommSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);

  //
  // Restore original InSmm state
  //
  gSmmCorePrivate->InSmm = OldInSmm;

  return (Status == EFI_WARN_INTERRUPT_SOURCE_QUIESCED) ? EFI_SUCCESS : EFI_NOT_FOUND;
}