ftwworkspace.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 567 行 · 第 1/2 页

C
567
字号
/*++

Copyright (c) 2004, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 

Module Name:

  FtwWorkSpace.c
  
Abstract:

Revision History

--*/

#include "FtwLite.h"

BOOLEAN
IsValidWorkSpace (
  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader
  )
/*++

Routine Description:
    Check to see if it is a valid work space.

Arguments:
    WorkingHeader - Pointer of working block header 

Returns:
    EFI_SUCCESS   - The function completed successfully
    EFI_ABORTED   - The function could not complete successfully.

--*/
{
  EFI_STATUS                              Status;
  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER WorkingBlockHeader;

  ASSERT (WorkingHeader != NULL);
  if (WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) {
    return FALSE;
  }
  //
  // Check signature with gEfiSystemNvDataFvGuid
  //
  if (!EfiCompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) {
    return FALSE;
  }
  //
  // Check the CRC of header
  //
  EfiCopyMem (
    &WorkingBlockHeader,
    WorkingHeader,
    sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)
    );

  //
  // Filter out the Crc and State fields
  //
  EfiSetMem (
    &WorkingBlockHeader.Crc,
    sizeof (UINT32),
    FTW_ERASED_BYTE
    );
  WorkingBlockHeader.WorkingBlockValid    = FTW_ERASE_POLARITY;
  WorkingBlockHeader.WorkingBlockInvalid  = FTW_ERASE_POLARITY;

  //
  // Calculate the Crc of woking block header
  //
  Status = gBS->CalculateCrc32 (
                  (UINT8 *) &WorkingBlockHeader,
                  sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
                  &WorkingBlockHeader.Crc
                  );
  ASSERT_EFI_ERROR (Status);

  if (WorkingBlockHeader.Crc != WorkingHeader->Crc) {
    DEBUG ((EFI_D_FTW_LITE, "FtwLite: Work block header CRC check error\n"));
    return FALSE;
  }

  return TRUE;
}

EFI_STATUS
InitWorkSpaceHeader (
  IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader
  )
/*++

Routine Description:
    Initialize a work space when there is no work space.

Arguments:
    WorkingHeader - Pointer of working block header 

Returns:
    EFI_SUCCESS   - The function completed successfully
    EFI_ABORTED   - The function could not complete successfully.

--*/
{
  EFI_STATUS  Status;

  ASSERT (WorkingHeader != NULL);

  //
  // Here using gEfiSystemNvDataFvGuid as the signature.
  //
  EfiCopyMem (
    &WorkingHeader->Signature,
    &gEfiSystemNvDataFvGuid,
    sizeof (EFI_GUID)
    );
  WorkingHeader->WriteQueueSize = FTW_WORKING_QUEUE_SIZE;

  //
  // Crc is calculated with all the fields except Crc and STATE
  //
  WorkingHeader->WorkingBlockValid    = FTW_ERASE_POLARITY;
  WorkingHeader->WorkingBlockInvalid  = FTW_ERASE_POLARITY;
  EfiSetMem (&WorkingHeader->Crc, sizeof (UINT32), FTW_ERASED_BYTE);

  //
  // Calculate the CRC value
  //
  Status = gBS->CalculateCrc32 (
                  (UINT8 *) WorkingHeader,
                  sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
                  &WorkingHeader->Crc
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Restore the WorkingBlockValid flag to VALID state
  //
  WorkingHeader->WorkingBlockValid    = FTW_VALID_STATE;
  WorkingHeader->WorkingBlockInvalid  = FTW_INVALID_STATE;

  return EFI_SUCCESS;
}

EFI_STATUS
FtwUpdateFvState (
  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvBlock,
  IN EFI_LBA                             Lba,
  IN UINTN                               Offset,
  IN UINT8                               NewBit
  )
/*++

Routine Description:
    Update a bit of state on a block device. The location of the bit is 
    calculated by the (Lba, Offset, bit). Here bit is determined by the 
    the name of a certain bit.

Arguments:
    FvBlock    - FVB Protocol interface to access SrcBlock and DestBlock
    Lba        - Lba of a block
    Offset     - Offset on the Lba
    NewBit     - New value that will override the old value if it can be change

Returns:
    EFI_SUCCESS   - A state bit has been updated successfully
    Others        - Access block device error.

Notes:
    Assume all bits of State are inside the same BYTE. 

    EFI_ABORTED   - Read block fail
--*/
{
  EFI_STATUS  Status;
  UINT8       State;
  UINTN       Length;

  //
  // Read state from device, assume State is only one byte.
  //
  Length  = sizeof (UINT8);
  Status  = FvBlock->Read (FvBlock, Lba, Offset, &Length, &State);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  State ^= FTW_POLARITY_REVERT;
  State |= NewBit;
  State ^= FTW_POLARITY_REVERT;

  //
  // Write state back to device
  //
  Length  = sizeof (UINT8);
  Status  = FvBlock->Write (FvBlock, Lba, Offset, &Length, &State);

  return Status;
}

EFI_STATUS
FtwGetLastRecord (
  IN  EFI_FTW_LITE_DEVICE  *FtwLiteDevice,
  OUT EFI_FTW_LITE_RECORD  **FtwLastRecord
  )
/*++

Routine Description:
    Get the last Write record pointer. 
    The last record is the record whose 'complete' state hasn't been set.
    After all, this header may be a EMPTY header entry for next Allocate. 

Arguments:
    FtwLiteDevice   - Private data of this driver
    FtwLastRecord   - Pointer to retrieve the last write record

Returns:
    EFI_SUCCESS     - Get the last write record successfully
    EFI_ABORTED     - The FTW work space is damaged

--*/
{
  EFI_FTW_LITE_RECORD *Record;

  Record = (EFI_FTW_LITE_RECORD *) (FtwLiteDevice->FtwWorkSpaceHeader + 1);
  while (Record->WriteCompleted == FTW_VALID_STATE) {
    //
    // If Offset exceed the FTW work space boudary, return error.
    //
    if ((UINTN) ((UINT8 *) Record - FtwLiteDevice->FtwWorkSpace) > FtwLiteDevice->FtwWorkSpaceSize) {
      return EFI_ABORTED;
    }

    Record++;
  }
  //
  // Last write record is found
  //
  *FtwLastRecord = Record;
  return EFI_SUCCESS;
}

EFI_STATUS
WorkSpaceRefresh (
  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice
  )
/*++

Routine Description:
    Read from working block to refresh the work space in memory.

Arguments:
    FtwLiteDevice     - Point to private data of FTW driver

Returns:
    EFI_SUCCESS   - The function completed successfully
    EFI_ABORTED   - The function could not complete successfully.

--*/
{
  EFI_STATUS          Status;
  UINTN               Length;
  UINTN               Offset;
  EFI_FTW_LITE_RECORD *Record;

  //
  // Initialize WorkSpace as FTW_ERASED_BYTE
  //
  EfiSetMem (
    FtwLiteDevice->FtwWorkSpace,
    FtwLiteDevice->FtwWorkSpaceSize,
    FTW_ERASED_BYTE
    );

  //
  // Read from working block
  //
  Length = FtwLiteDevice->FtwWorkSpaceSize;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?