fwblockservice.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,514 行 · 第 1/4 页
C
1,514 行
could not be written. Firmware device may have been
partially erased
--*/
{
EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
FvbDevice = FVB_EXTEND_DEVICE_FROM_THIS (This);
return FvbEraseCustomBlockRange (
FvbDevice->Instance,
StartLba,
OffsetStartLba,
LastLba,
OffsetLastLba,
mFvbModuleGlobal,
EfiGoneVirtual ()
);
}
STATIC
EFI_STATUS
ValidateFvHeader (
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
)
/*++
Routine Description:
Check the integrity of firmware volume header
Arguments:
FwVolHeader - A pointer to a firmware volume header
Returns:
EFI_SUCCESS - The firmware volume is consistent
EFI_NOT_FOUND - The firmware volume has corrupted. So it is not an FV
--*/
{
UINT16 *Ptr;
UINT16 HeaderLength;
UINT16 Checksum;
//
// Verify the header revision, header signature, length
// Length of FvBlock cannot be 2**64-1
// HeaderLength cannot be an odd number
//
if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
(FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
(FwVolHeader->FvLength == ((UINTN) -1)) ||
((FwVolHeader->HeaderLength & 0x01) != 0)
) {
return EFI_NOT_FOUND;
}
//
// Verify the header checksum
//
HeaderLength = (UINT16) (FwVolHeader->HeaderLength / 2);
Ptr = (UINT16 *) FwVolHeader;
Checksum = 0;
while (HeaderLength > 0) {
Checksum = Checksum + (*Ptr);
Ptr ++;
HeaderLength --;
}
if (Checksum != 0) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
FvbInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
This function does common initialization for FVB services
Arguments:
Returns:
--*/
{
EFI_STATUS Status;
EFI_FW_VOL_INSTANCE *FwhInstance;
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
VOID *HobList;
EFI_DXE_SERVICES *DxeServices;
VOID *FirmwareVolumeHobList;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
UINT32 BufferSize;
EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;
EFI_HANDLE FwbHandle;
EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface;
EFI_DEVICE_PATH_PROTOCOL *TempFwbDevicePath;
FV_DEVICE_PATH TempFvbDevicePathData;
UINT32 MaxLbaSize;
EFI_PHYSICAL_ADDRESS BaseAddress;
UINT64 Length;
UINTN NumOfBlocks;
EfiInitializeRuntimeDriverLib (ImageHandle, SystemTable, FvbVirtualddressChangeEvent);
Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
//
// No FV HOBs found
//
ASSERT_EFI_ERROR (Status);
//
// Get the DXE services table
//
DxeServices = NULL;
Status = EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &DxeServices);;
ASSERT_EFI_ERROR (Status);
//
// Allocate runtime services data for global variable, which contains
// the private data of all firmware volume block instances
//
Status = gBS->AllocatePool (
EfiRuntimeServicesData,
sizeof (ESAL_FWB_GLOBAL),
&mFvbModuleGlobal
);
ASSERT_EFI_ERROR (Status);
//
// Calculate the total size for all firmware volume block instances
//
BufferSize = 0;
FirmwareVolumeHobList = HobList;
do {
Status = GetNextFirmwareVolumeHob (
&FirmwareVolumeHobList,
&BaseAddress,
&Length
);
if (EFI_ERROR (Status)) {
break;
}
//
// Check if it is a "real" flash
//
Status = DxeServices->GetMemorySpaceDescriptor (
BaseAddress,
&Descriptor
);
if (EFI_ERROR (Status)) {
break;
}
if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {
continue;
}
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;
Status = ValidateFvHeader (FwVolHeader);
if (EFI_ERROR (Status)) {
//
// Get FvbInfo
//
Status = GetFvbInfo (Length, &FwVolHeader);
if (EFI_ERROR (Status)) {
continue;
}
}
BufferSize += (sizeof (EFI_FW_VOL_INSTANCE) + FwVolHeader->HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER));
} while (TRUE);
//
// Only need to allocate once. There is only one copy of physical memory for
// the private data of each FV instance. But in virtual mode or in physical
// mode, the address of the the physical memory may be different.
//
Status = gBS->AllocatePool (
EfiRuntimeServicesData,
BufferSize,
&mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]
);
ASSERT_EFI_ERROR (Status);
//
// Make a virtual copy of the FvInstance pointer.
//
FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];
mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;
mFvbModuleGlobal->NumFv = 0;
FirmwareVolumeHobList = HobList;
MaxLbaSize = 0;
//
// Fill in the private data of each firmware volume block instance
//
do {
Status = GetNextFirmwareVolumeHob (
&FirmwareVolumeHobList,
&BaseAddress,
&Length
);
if (EFI_ERROR (Status)) {
break;
}
//
// Check if it is a "real" flash
//
Status = DxeServices->GetMemorySpaceDescriptor (
BaseAddress,
&Descriptor
);
if (EFI_ERROR (Status)) {
break;
}
if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {
continue;
}
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;
Status = ValidateFvHeader (FwVolHeader);
if (EFI_ERROR (Status)) {
//
// Get FvbInfo to provide in FwhInstance.
//
Status = GetFvbInfo (Length, &FwVolHeader);
if (EFI_ERROR (Status)) {
continue;
}
//
// Write healthy FV header back.
//
EfiCopyMem (
(VOID *) (UINTN) BaseAddress,
(VOID *) FwVolHeader,
FwVolHeader->HeaderLength
);
}
FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;
FwhInstance->FvBase[FVB_VIRTUAL] = (UINTN) BaseAddress;
EfiCopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);
FwVolHeader = &(FwhInstance->VolumeHeader);
EfiInitializeLock (&(FwhInstance->FvbDevLock), EFI_TPL_HIGH_LEVEL);
NumOfBlocks = 0;
for (PtrBlockMapEntry = FwVolHeader->FvBlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {
//
// Get the maximum size of a block. The size will be used to allocate
// buffer for Scratch space, the intermediate buffer for FVB extension
// protocol
//
if (MaxLbaSize < PtrBlockMapEntry->BlockLength) {
MaxLbaSize = PtrBlockMapEntry->BlockLength;
}
NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;
}
//
// The total number of blocks in the FV.
//
FwhInstance->NumOfBlocks = NumOfBlocks;
//
// Add a FVB Protocol Instance
//
Status = gBS->AllocatePool (
EfiRuntimeServicesData,
sizeof (EFI_FW_VOL_BLOCK_DEVICE),
&FvbDevice
);
ASSERT_EFI_ERROR (Status);
EfiCopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));
FvbDevice->Instance = mFvbModuleGlobal->NumFv;
mFvbModuleGlobal->NumFv++;
//
// Set up the devicepath
//
FvbDevice->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;
FvbDevice->DevicePath.MemMapDevPath.EndingAddress = BaseAddress + (FwVolHeader->FvLength - 1);
//
// Find a handle with a matching device path that has supports FW Block protocol
//
TempFwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &TempFvbDevicePathData;
EfiCopyMem (TempFwbDevicePath, &FvbDevice->DevicePath, sizeof (FV_DEVICE_PATH));
Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &TempFwbDevicePath, &FwbHandle);
if (EFI_ERROR (Status)) {
//
// LocateDevicePath fails so install a new interface and device path
//
FwbHandle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&FwbHandle,
&gEfiFirmwareVolumeBlockProtocolGuid,
&FvbDevice->FwVolBlockInstance,
&gEfiDevicePathProtocolGuid,
&FvbDevice->DevicePath,
NULL
);
ASSERT_EFI_ERROR (Status);
} else if (EfiIsDevicePathEnd (TempFwbDevicePath)) {
//
// Device allready exists, so reinstall the FVB protocol
//
Status = gBS->HandleProtocol (
FwbHandle,
&gEfiFirmwareVolumeBlockProtocolGuid,
&OldFwbInterface
);
ASSERT_EFI_ERROR (Status);
Status = gBS->ReinstallProtocolInterface (
FwbHandle,
&gEfiFirmwareVolumeBlockProtocolGuid,
OldFwbInterface,
&FvbDevice->FwVolBlockInstance
);
ASSERT_EFI_ERROR (Status);
} else {
//
// There was a FVB protocol on an End Device Path node
//
ASSERT (FALSE);
}
//
// Install FVB Extension Protocol on the same handle
//
Status = gBS->InstallMultipleProtocolInterfaces (
&FwbHandle,
&gEfiFvbExtensionProtocolGuid,
&FvbDevice->FvbExtension,
&gEfiAlternateFvBlockGuid,
NULL,
NULL
);
ASSERT_EFI_ERROR (Status);
FwhInstance = (EFI_FW_VOL_INSTANCE *)
(
(UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +
(sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
);
} while (TRUE);
//
// Allocate for scratch space, an intermediate buffer for FVB extention
//
Status = gBS->AllocatePool (
EfiRuntimeServicesData,
MaxLbaSize,
&mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL]
);
ASSERT_EFI_ERROR (Status);
mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL] = mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL];
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?