ftwlite.c

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

C
971
字号
    }

    Ptr += MyLength;
  }
  //
  // Free MyBuffer
  //
  gBS->FreePool (MyBuffer);

  //
  // Set the SpareCompleteD in the FTW record,
  //
  MyOffset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;
  Status = FtwUpdateFvState (
            FtwLiteDevice->FtwFvBlock,
            FtwLiteDevice->FtwWorkSpaceLba,
            FtwLiteDevice->FtwWorkSpaceBase + MyOffset,
            SPARE_COMPLETED
            );
  if (EFI_ERROR (Status)) {
    gBS->FreePool (SpareBuffer);
    return EFI_ABORTED;
  }

  Record->SpareCompleted = FTW_VALID_STATE;

  //
  //  Since the content has already backuped in spare block, the write is
  //  guaranteed to be completed with fault tolerant manner.
  //
  Status = FtwWriteRecord (FtwLiteDevice, Fvb);
  if (EFI_ERROR (Status)) {
    gBS->FreePool (SpareBuffer);
    return EFI_ABORTED;
  }

  Record++;
  FtwLiteDevice->FtwLastRecord = Record;

  //
  // Restore spare backup buffer into spare block , if no failure happened during FtwWrite.
  //
  Status  = FtwEraseSpareBlock (FtwLiteDevice);
  Ptr     = SpareBuffer;
  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
    MyLength = FtwLiteDevice->SizeOfSpareBlock;
    Status = FtwLiteDevice->FtwBackupFvb->Write (
                                            FtwLiteDevice->FtwBackupFvb,
                                            FtwLiteDevice->FtwSpareLba + Index,
                                            0,
                                            &MyLength,
                                            Ptr
                                            );
    if (EFI_ERROR (Status)) {
      gBS->FreePool (SpareBuffer);
      return EFI_ABORTED;
    }

    Ptr += MyLength;
  }
  //
  // All success.
  //
  gBS->FreePool (SpareBuffer);

  DEBUG (
    (EFI_D_FTW_LITE,
    "FtwLite: Write() success, (Lba:Offset)=(%lx:0x%x), NumBytes: 0x%x\n",
    Lba,
    Offset,
    *NumBytes)
    );

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
FtwWriteRecord (
  IN EFI_FTW_LITE_DEVICE                   *FtwLiteDevice,
  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb
  )
/*++

Routine Description:
    Write a record with fault tolerant mannaer.
    Since the content has already backuped in spare block, the write is 
    guaranteed to be completed with fault tolerant manner.
    
Arguments:
    FtwLiteDevice       - The private data of FTW_LITE driver
    Fvb                 - The FVB protocol that provides services for 
                          reading, writing, and erasing the target block.

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

--*/
{
  EFI_STATUS          Status;
  EFI_FTW_LITE_RECORD *Record;
  EFI_LBA             WorkSpaceLbaOffset;
  UINTN               Offset;

  //
  // Spare Complete but Destination not complete,
  // Recover the targt block with the spare block.
  //
  Record = FtwLiteDevice->FtwLastRecord;

  //
  // IF target block is working block, THEN Flush Spare Block To Working Block;
  // ELSE IF target block is boot block, THEN Flush Spare Block To boot Block;
  // ELSE flush spare block to normal target block.ENDIF
  //
  if (IsInWorkingBlock (FtwLiteDevice, Fvb, Record->Lba)) {
    //
    // If target block is working block, Attention:
    // it's required to set SPARE_COMPLETED to spare block.
    //
    WorkSpaceLbaOffset = FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba;
    Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;
    Status = FtwUpdateFvState (
              FtwLiteDevice->FtwBackupFvb,
                         FtwLiteDevice->FtwSpareLba + WorkSpaceLbaOffset,
              FtwLiteDevice->FtwWorkSpaceBase + Offset,
              SPARE_COMPLETED
              );
    ASSERT_EFI_ERROR (Status);

    Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);
  } else if (IsBootBlock (FtwLiteDevice, Fvb, Record->Lba)) {
    //
    // Update boot block
    //
    Status = FlushSpareBlockToBootBlock (FtwLiteDevice);
  } else {
    //
    // Update blocks other than working block or boot block
    //
    Status = FlushSpareBlockToTargetBlock (FtwLiteDevice, Fvb, Record->Lba);
  }

  ASSERT_EFI_ERROR (Status);

  //
  // Set WriteCompleted flag in record
  //
  Offset = (UINT8 *) Record - FtwLiteDevice->FtwWorkSpace;
  Status = FtwUpdateFvState (
            FtwLiteDevice->FtwFvBlock,
            FtwLiteDevice->FtwWorkSpaceLba,
            FtwLiteDevice->FtwWorkSpaceBase + Offset,
            WRITE_COMPLETED
            );
  ASSERT_EFI_ERROR (Status);

  Record->WriteCompleted = FTW_VALID_STATE;
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
FtwRestart (
  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice
  )
/*++

Routine Description:
    Restarts a previously interrupted write. The caller must provide the 
    block protocol needed to complete the interrupted write.
    
Arguments:
    FtwLiteDevice       - The private data of FTW_LITE driver
    FvbHandle           - The handle of FVB protocol that provides services for 
                          reading, writing, and erasing the target block.

Returns:
    EFI_SUCCESS         - The function completed successfully
    EFI_ACCESS_DENIED   - No pending writes exist
    EFI_NOT_FOUND       - FVB protocol not found by the handle
    EFI_ABORTED         - The function could not complete successfully

--*/
{
  EFI_STATUS                          Status;
  EFI_FTW_LITE_RECORD                 *Record;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;
  EFI_DEV_PATH_PTR                    DevPathPtr;

  //
  // Spare Completed but Destination not complete,
  // Recover the targt block with the spare block.
  //
  Record = FtwLiteDevice->FtwLastRecord;

  //
  // Only support memory mapped FVB device path by now.
  //
  DevPathPtr.MemMap = (MEMMAP_DEVICE_PATH *) &Record->DevPath;
  if (!((DevPathPtr.MemMap->Header.Type == HARDWARE_DEVICE_PATH) && (DevPathPtr.MemMap->Header.SubType == HW_MEMMAP_DP))
      ) {
    DEBUG ((EFI_D_FTW_LITE, "FtwLite: FVB Device Path is not memory mapped\n"));
    return EFI_ABORTED;
  }

  Status = GetFvbByAddress (DevPathPtr.MemMap->StartingAddress, &Fvb);
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }
  //
  //  Since the content has already backuped in spare block, the write is
  //  guaranteed to be completed with fault tolerant manner.
  //
  Status = FtwWriteRecord (FtwLiteDevice, Fvb);
  DEBUG ((EFI_D_FTW_INFO, "FtwLite: Restart() - %r\n", Status));

  Record++;
  FtwLiteDevice->FtwLastRecord = Record;

  //
  // Erase Spare block
  // This is restart, no need to keep spareblock content.
  //
  FtwEraseSpareBlock (FtwLiteDevice);

  return Status;
}

STATIC
EFI_STATUS
FtwAbort (
  IN EFI_FTW_LITE_DEVICE    *FtwLiteDevice
  )
/*++

Routine Description:
    Aborts all previous allocated writes.

Arguments:
    FtwLiteDevice    - The private data of FTW_LITE driver

Returns:
    EFI_SUCCESS      - The function completed successfully
    EFI_ABORTED      - The function could not complete successfully.
    EFI_NOT_FOUND    - No allocated writes exist.

--*/
{
  EFI_STATUS  Status;
  UINTN       Offset;

  if (FtwLiteDevice->FtwLastRecord->WriteCompleted == FTW_VALID_STATE) {
    return EFI_NOT_FOUND;
  }
  //
  // Update the complete state of the header as VALID and abort.
  //
  Offset = (UINT8 *) FtwLiteDevice->FtwLastRecord - FtwLiteDevice->FtwWorkSpace;
  Status = FtwUpdateFvState (
            FtwLiteDevice->FtwFvBlock,
            FtwLiteDevice->FtwWorkSpaceLba,
            FtwLiteDevice->FtwWorkSpaceBase + Offset,
            WRITE_COMPLETED
            );
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  FtwLiteDevice->FtwLastRecord->WriteCompleted  = FTW_VALID_STATE;

  Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);

  //
  // Erase the spare block
  //
  Status = FtwEraseSpareBlock (FtwLiteDevice);

  DEBUG ((EFI_D_FTW_INFO, "FtwLite: Abort() success \n"));
  return EFI_SUCCESS;
}

EFI_DRIVER_ENTRY_POINT (InitializeFtwLite)

EFI_STATUS
EFIAPI
InitializeFtwLite (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
/*++
  Routine Description: 
    This function is the entry point of the Fault Tolerant Write driver.
  
  Arguments: 
    ImageHandle   - EFI_HANDLE: A handle for the image that is initializing 
                    this driver
    SystemTable   - EFI_SYSTEM_TABLE: A pointer to the EFI system table
        
  Returns:  
    EFI_SUCCESS           - FTW has finished the initialization
    EFI_ABORTED           - FTW initialization error

--*/
{
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;
  UINTN                               Index;
  EFI_HANDLE                          *HandleBuffer;
  UINTN                               HandleCount;
  EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;
  EFI_PHYSICAL_ADDRESS                BaseAddress;
  EFI_FTW_LITE_DEVICE                 *FtwLiteDevice;
  EFI_FTW_LITE_RECORD                 *Record;
  UINTN                               Length;
  EFI_STATUS                          Status;
  UINTN                               Offset;
  VOID                                *HobList;
  VOID                                *Buffer;
  EFI_FLASH_MAP_ENTRY_DATA            *FlashMapEntry;
  EFI_FV_BLOCK_MAP_ENTRY              *FvbMapEntry;
  UINT32                              LbaIndex;
  EFI_LBA                                   WorkSpaceLbaOffset;

⌨️ 快捷键说明

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