fwblockservice.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,514 行 · 第 1/4 页
C
1,514 行
EFI_DEVICE_ERROR - The block device is not functioning correctly and
could not be read
EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL
--*/
{
EFI_FVB_ATTRIBUTES Attributes;
UINTN LbaAddress;
UINTN LbaLength;
EFI_STATUS Status;
//
// Check for invalid conditions
//
if ((NumBytes == NULL) || (Buffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (*NumBytes == 0) {
return EFI_INVALID_PARAMETER;
}
Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Check if the FV is read enabled
//
FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
if ((Attributes & EFI_FVB_READ_STATUS) == 0) {
return EFI_ACCESS_DENIED;
}
//
// Perform boundary checks and adjust NumBytes
//
if (BlockOffset > LbaLength) {
return EFI_INVALID_PARAMETER;
}
if (LbaLength < (*NumBytes + BlockOffset)) {
*NumBytes = (UINT32) (LbaLength - BlockOffset);
Status = EFI_BAD_BUFFER_SIZE;
}
EfiCopyMem (Buffer, (UINT8 *) (LbaAddress + BlockOffset), (UINTN) (*NumBytes));
return Status;
}
EFI_STATUS
FvbWriteBlock (
IN UINTN Instance,
IN EFI_LBA Lba,
IN UINTN BlockOffset,
IN OUT UINTN *NumBytes,
IN UINT8 *Buffer,
IN ESAL_FWB_GLOBAL *Global,
IN BOOLEAN Virtual
)
/*++
Routine Description:
Writes specified number of bytes from the input buffer to the block
Arguments:
Instance - The FV instance to be written to
Lba - The starting logical block index to write to
BlockOffset - Offset into the block at which to begin writing
NumBytes - Pointer that on input contains the total size of
the buffer. On output, it contains the total number
of bytes actually written
Buffer - Pointer to a caller allocated buffer that contains
the source for the write
Global - Pointer to ESAL_FWB_GLOBAL that contains all
instance data
Virtual - Whether CPU is in virtual or physical mode
Returns:
EFI_SUCCESS - The firmware volume was written successfully
EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,
NumBytes contains the total number of bytes
actually written
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
EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL
--*/
{
EFI_FVB_ATTRIBUTES Attributes;
UINTN LbaAddress;
UINTN LbaLength;
EFI_STATUS Status;
//
// Check for invalid conditions
//
if ((NumBytes == NULL) || (Buffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (*NumBytes == 0) {
return EFI_INVALID_PARAMETER;
}
Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Check if the FV is write enabled
//
FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {
return EFI_ACCESS_DENIED;
}
//
// Perform boundary checks and adjust NumBytes
//
if (BlockOffset > LbaLength) {
return EFI_INVALID_PARAMETER;
}
if (LbaLength < (*NumBytes + BlockOffset)) {
*NumBytes = (UINT32) (LbaLength - BlockOffset);
Status = EFI_BAD_BUFFER_SIZE;
}
//
// Write data
//
EfiCopyMem ((UINT8 *) (LbaAddress + BlockOffset), Buffer, (UINTN) (*NumBytes));
return Status;
}
EFI_STATUS
FvbEraseBlock (
IN UINTN Instance,
IN EFI_LBA Lba,
IN ESAL_FWB_GLOBAL *Global,
IN BOOLEAN Virtual
)
/*++
Routine Description:
Erases and initializes a firmware volume block
Arguments:
Instance - The FV instance to be erased
Lba - The logical block index to be erased
Global - Pointer to ESAL_FWB_GLOBAL that contains all
instance data
Virtual - Whether CPU is in virtual or physical mode
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_INVALID_PARAMETER - Instance not found
--*/
{
EFI_FVB_ATTRIBUTES Attributes;
UINTN LbaAddress;
UINTN LbaLength;
EFI_STATUS Status;
UINT8 Data;
//
// Check if the FV is write enabled
//
FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {
return EFI_ACCESS_DENIED;
}
//
// Get the starting address of the block for erase.
//
Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);
if (EFI_ERROR (Status)) {
return Status;
}
if ((Attributes & EFI_FVB_ERASE_POLARITY) != 0) {
Data = 0xFF;
} else {
Data = 0x0;
}
EfiSetMem ((UINT8 *) LbaAddress, LbaLength, Data);
return EFI_SUCCESS;
}
EFI_STATUS
FvbEraseCustomBlockRange (
IN UINTN Instance,
IN EFI_LBA StartLba,
IN UINTN OffsetStartLba,
IN EFI_LBA LastLba,
IN UINTN OffsetLastLba,
IN ESAL_FWB_GLOBAL *Global,
IN BOOLEAN Virtual
)
/*++
Routine Description:
Erases and initializes a specified range of a firmware volume
Arguments:
Instance - The FV instance to be erased
StartLba - The starting logical block index to be erased
OffsetStartLba - Offset into the starting block at which to
begin erasing
LastLba - The last logical block index to be erased
OffsetStartLba - Offset into the last block at which to end erasing
Global - Pointer to ESAL_FWB_GLOBAL that contains all
instance data
Virtual - Whether CPU is in virtual or physical mode
Returns:
EFI_SUCCESS - The firmware volume was erased successfully
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_INVALID_PARAMETER - Instance not found
--*/
{
EFI_LBA Index;
UINTN LbaSize;
UINTN ScratchLbaSizeData;
//
// First LBA
//
FvbGetLbaAddress (Instance, StartLba, NULL, &LbaSize, NULL, Global, Virtual);
//
// Use the scratch space as the intermediate buffer to transfer data
// Back up the first LBA in scratch space.
//
FvbReadBlock (Instance, StartLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);
//
// erase now
//
FvbEraseBlock (Instance, StartLba, Global, Virtual);
ScratchLbaSizeData = OffsetStartLba;
//
// write the data back to the first block
//
if (ScratchLbaSizeData > 0) {
FvbWriteBlock (Instance, StartLba, 0, &ScratchLbaSizeData, Global->FvbScratchSpace[Virtual], Global, Virtual);
}
//
// Middle LBAs
//
if (LastLba > (StartLba + 1)) {
for (Index = (StartLba + 1); Index <= (LastLba - 1); Index++) {
FvbEraseBlock (Instance, Index, Global, Virtual);
}
}
//
// Last LBAs, the same as first LBAs
//
if (LastLba > StartLba) {
FvbGetLbaAddress (Instance, LastLba, NULL, &LbaSize, NULL, Global, Virtual);
FvbReadBlock (Instance, LastLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);
FvbEraseBlock (Instance, LastLba, Global, Virtual);
}
ScratchLbaSizeData = LbaSize - (OffsetStartLba + 1);
return FvbWriteBlock (
Instance,
LastLba,
(OffsetLastLba + 1),
&ScratchLbaSizeData,
Global->FvbScratchSpace[Virtual],
Global,
Virtual
);
}
EFI_STATUS
FvbSetVolumeAttributes (
IN UINTN Instance,
IN OUT EFI_FVB_ATTRIBUTES *Attributes,
IN ESAL_FWB_GLOBAL *Global,
IN BOOLEAN Virtual
)
/*++
Routine Description:
Modifies the current settings of the firmware volume according to the
input parameter, and returns the new setting of the volume
Arguments:
Instance - The FV instance whose attributes is going to be
modified
Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES
containing the desired firmware volume settings.
On successful return, it contains the new settings
of the firmware volume
Global - Pointer to ESAL_FWB_GLOBAL that contains all
instance data
Virtual - Whether CPU is in virtual or physical mode
Returns:
EFI_SUCCESS - Successfully returns
EFI_ACCESS_DENIED - The volume setting is locked and cannot be modified
EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are
in conflict with the capabilities as declared in the
firmware volume header
--*/
{
EFI_FW_VOL_INSTANCE *FwhInstance;
EFI_FVB_ATTRIBUTES OldAttributes;
EFI_FVB_ATTRIBUTES *AttribPtr;
UINT32 Capabilities;
UINT32 OldStatus;
UINT32 NewStatus;
EFI_STATUS Status;
//
// Find the right instance of the FVB private data
//
Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
ASSERT_EFI_ERROR (Status);
AttribPtr = (EFI_FVB_ATTRIBUTES *) &(FwhInstance->VolumeHeader.Attributes);
OldAttributes = *AttribPtr;
Capabilities = OldAttributes & EFI_FVB_CAPABILITIES;
OldStatus = OldAttributes & EFI_FVB_STATUS;
NewStatus = *Attributes & EFI_FVB_STATUS;
//
// If firmware volume is locked, no status bit can be updated
//
if (OldAttributes & EFI_FVB_LOCK_STATUS) {
if (OldStatus ^ NewStatus) {
return EFI_ACCESS_DENIED;
}
}
//
// Test read disable
//
if ((Capabilities & EFI_FVB_READ_DISABLED_CAP) == 0) {
if ((NewStatus & EFI_FVB_READ_STATUS) == 0) {
return EFI_INVALID_PARAMETER;
}
}
//
// Test read enable
//
if ((Capabilities & EFI_FVB_READ_ENABLED_CAP) == 0) {
if (NewStatus & EFI_FVB_READ_STATUS) {
return EFI_INVALID_PARAMETER;
}
}
//
// Test write disable
//
if ((Capabilities & EFI_FVB_WRITE_DISABLED_CAP) == 0) {
if ((NewStatus & EFI_FVB_WRITE_STATUS) == 0) {
return EFI_INVALID_PARAMETER;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?