Firmware Block Services to support emulating non-volatile variables\r
by pretending that a memory buffer is storage for the NV variables.\r
\r
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
#include <Library/PlatformFvbLib.h>\r
#include "Fvb.h"\r
\r
+#define EFI_AUTHENTICATED_VARIABLE_GUID \\r
+{ 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }\r
+\r
//\r
// Virtual Address Change Event\r
//\r
a memory-mapped firmware volume. This function should be called\r
only for memory-mapped firmware volumes.\r
\r
- @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
\r
@param Address Pointer to a caller-allocated\r
EFI_PHYSICAL_ADDRESS that, on successful\r
EFI_STATUS\r
EFIAPI\r
FvbProtocolGetPhysicalAddress (\r
- IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
OUT EFI_PHYSICAL_ADDRESS *Address\r
)\r
{\r
retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).\r
\r
\r
- @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
\r
@param Lba Indicates the block for which to return the size.\r
\r
EFI_STATUS\r
EFIAPI\r
FvbProtocolGetBlockSize (\r
- IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
IN EFI_LBA Lba,\r
OUT UINTN *BlockSize,\r
OUT UINTN *NumberOfBlocks\r
The GetAttributes() function retrieves the attributes and\r
current settings of the block. Status Codes Returned\r
\r
- @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
\r
@param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the\r
attributes and current settings are\r
EFI_STATUS\r
EFIAPI\r
FvbProtocolGetAttributes (\r
- IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
OUT EFI_FVB_ATTRIBUTES_2 *Attributes\r
)\r
{\r
The SetAttributes() function sets configurable firmware volume\r
attributes and returns the new settings of the firmware volume.\r
\r
- @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
\r
@param Attributes On input, Attributes is a pointer to\r
EFI_FVB_ATTRIBUTES_2 that contains the\r
EFI_STATUS\r
EFIAPI\r
FvbProtocolSetAttributes (\r
- IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes\r
)\r
{\r
flushed to the hardware before the EraseBlocks() service\r
returns.\r
\r
- @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL\r
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL\r
instance.\r
\r
@param ... The variable argument list is a list of tuples.\r
EFI_STATUS\r
EFIAPI\r
FvbProtocolEraseBlocks (\r
- IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
...\r
)\r
{\r
EraseSize,\r
ERASED_UINT8\r
);\r
+ VA_START (args, This);\r
+ PlatformFvbBlocksErased (This, args);\r
+ VA_END (args);\r
}\r
\r
return EFI_SUCCESS;\r
fully flushed to the hardware before the Write() service\r
returns.\r
\r
- @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
\r
@param Lba The starting logical block index to write to.\r
\r
EFI_STATUS\r
EFIAPI\r
FvbProtocolWrite (\r
- IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
IN EFI_LBA Lba,\r
IN UINTN Offset,\r
IN OUT UINTN *NumBytes,\r
\r
if (*NumBytes > 0) {\r
CopyMem (FvbDataPtr, Buffer, *NumBytes);\r
- PlatformFvbDataWritten (This, Lba);\r
+ PlatformFvbDataWritten (This, Lba, Offset, *NumBytes, Buffer);\r
}\r
\r
return EFI_SUCCESS;\r
indicate the number of bytes actually read. The caller must be\r
aware that a read may be partially completed.\r
\r
- @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance.\r
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.\r
\r
@param Lba The starting logical block index\r
from which to read.\r
EFI_STATUS\r
EFIAPI\r
FvbProtocolRead (\r
- IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,\r
IN EFI_LBA Lba,\r
IN UINTN Offset,\r
IN OUT UINTN *NumBytes,\r
\r
if (*NumBytes > 0) {\r
CopyMem (Buffer, FvbDataPtr, *NumBytes);\r
+ PlatformFvbDataRead (This, Lba, Offset, *NumBytes, Buffer);\r
}\r
\r
return EFI_SUCCESS;\r
IN VOID *Ptr\r
)\r
{\r
+ //\r
+ // Templates for standard (non-authenticated) variable FV header\r
+ //\r
STATIC FVB_FV_HDR_AND_VARS_TEMPLATE FvAndVarTemplate = {\r
{ // EFI_FIRMWARE_VOLUME_HEADER FvHdr;\r
// UINT8 ZeroVector[16];\r
0,\r
\r
// UINT8 Reserved[1];\r
- 0,\r
+ {0},\r
\r
// UINT8 Revision;\r
EFI_FVH_REVISION,\r
\r
// EFI_FV_BLOCK_MAP_ENTRY BlockMap[1];\r
- { 2, // UINT32 NumBlocks;\r
- EMU_FVB_BLOCK_SIZE // UINT32 Length;\r
+ { \r
+ {\r
+ 2, // UINT32 NumBlocks;\r
+ EMU_FVB_BLOCK_SIZE // UINT32 Length;\r
+ }\r
}\r
},\r
// EFI_FV_BLOCK_MAP_ENTRY EndBlockMap;\r
0\r
}\r
};\r
- EFI_FIRMWARE_VOLUME_HEADER *Fv;\r
\r
//\r
- // Copy the template structure into the location\r
+ // Templates for authenticated variable FV header\r
//\r
- CopyMem (Ptr, (VOID*)&FvAndVarTemplate, sizeof (FvAndVarTemplate));\r
+ STATIC FVB_FV_HDR_AND_VARS_TEMPLATE FvAndAuthenticatedVarTemplate = {\r
+ { // EFI_FIRMWARE_VOLUME_HEADER FvHdr;\r
+ // UINT8 ZeroVector[16];\r
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },\r
\r
- //\r
- // Update the checksum for the FV header\r
- //\r
- Fv = (EFI_FIRMWARE_VOLUME_HEADER*) Ptr;\r
- Fv->Checksum = CalculateCheckSum16 (Ptr, Fv->HeaderLength);\r
-}\r
+ // EFI_GUID FileSystemGuid;\r
+ EFI_SYSTEM_NV_DATA_FV_GUID,\r
\r
+ // UINT64 FvLength;\r
+ EMU_FVB_SIZE,\r
\r
-/**\r
- Initializes the Fault Tolerant Write data structure\r
+ // UINT32 Signature;\r
+ EFI_FVH_SIGNATURE,\r
\r
- This data structure is used by the Fault Tolerant Write driver.\r
+ // EFI_FVB_ATTRIBUTES_2 Attributes;\r
+ 0x4feff,\r
\r
- @param[in] Buffer - Location for the FTW data structure\r
+ // UINT16 HeaderLength;\r
+ EMU_FV_HEADER_LENGTH,\r
\r
-**/\r
-VOID\r
-InitializeFtwState (\r
- IN VOID *Buffer\r
- )\r
-{\r
- EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *Hdr;\r
- UINT32 TempCrc;\r
- STATIC EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER DefaultFtw = {\r
- EFI_SYSTEM_NV_DATA_FV_GUID, // EFI_GUID Signature;\r
- ERASED_UINT32, // UINT32 Crc;\r
- ERASED_BIT, // UINT8 WorkingBlockValid : 1;\r
- ERASED_BIT, // UINT8 WorkingBlockInvalid : 1;\r
- 0, // UINT8 Reserved : 6;\r
- { 0, 0, 0 }, // UINT8 Reserved3[3];\r
- FTW_WRITE_QUEUE_SIZE // UINT64 WriteQueueSize;\r
- };\r
+ // UINT16 Checksum;\r
+ 0,\r
+\r
+ // UINT16 ExtHeaderOffset;\r
+ 0,\r
\r
- CopyMem (Buffer, (VOID*) &DefaultFtw, sizeof (DefaultFtw));\r
+ // UINT8 Reserved[1];\r
+ {0},\r
\r
- Hdr = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER*) Buffer;\r
+ // UINT8 Revision;\r
+ EFI_FVH_REVISION,\r
+\r
+ // EFI_FV_BLOCK_MAP_ENTRY BlockMap[1];\r
+ {\r
+ {\r
+ 2, // UINT32 NumBlocks;\r
+ EMU_FVB_BLOCK_SIZE // UINT32 Length;\r
+ }\r
+ }\r
+ },\r
+ // EFI_FV_BLOCK_MAP_ENTRY EndBlockMap;\r
+ { 0, 0 }, // End of block map\r
+ { // VARIABLE_STORE_HEADER VarHdr;\r
+ // EFI_GUID Signature; // need authenticated variables for secure boot\r
+ EFI_AUTHENTICATED_VARIABLE_GUID,\r
+\r
+ // UINT32 Size;\r
+ (\r
+ FixedPcdGet32 (PcdVariableStoreSize) -\r
+ OFFSET_OF (FVB_FV_HDR_AND_VARS_TEMPLATE, VarHdr)\r
+ ),\r
+\r
+ // UINT8 Format;\r
+ VARIABLE_STORE_FORMATTED,\r
+\r
+ // UINT8 State;\r
+ VARIABLE_STORE_HEALTHY,\r
+\r
+ // UINT16 Reserved;\r
+ 0,\r
+\r
+ // UINT32 Reserved1;\r
+ 0\r
+ }\r
+ };\r
+\r
+ EFI_FIRMWARE_VOLUME_HEADER *Fv;\r
\r
//\r
- // Calculate checksum.\r
- //\r
- // The Crc, WorkingBlockValid and WorkingBlockInvalid bits should\r
- // be set to the erased state before computing the checksum.\r
+ // Copy the template structure into the location\r
//\r
- gBS->CalculateCrc32 (Buffer, sizeof (DefaultFtw), &TempCrc);\r
- Hdr->Crc = TempCrc;\r
+ if (FeaturePcdGet (PcdSecureBootEnable) == FALSE) {\r
+ CopyMem (Ptr, (VOID*)&FvAndVarTemplate, sizeof (FvAndVarTemplate));\r
+ } else {\r
+ CopyMem (Ptr, (VOID*)&FvAndAuthenticatedVarTemplate, sizeof (FvAndAuthenticatedVarTemplate));\r
+ }\r
\r
//\r
- // Mark as valid.\r
+ // Update the checksum for the FV header\r
//\r
- Hdr->WorkingBlockValid = NOT_ERASED_BIT;\r
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER*) Ptr;\r
+ Fv->Checksum = CalculateCheckSum16 (Ptr, Fv->HeaderLength);\r
}\r
\r
-\r
/**\r
Main entry point.\r
\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ if (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) {\r
+ DEBUG ((EFI_D_INFO, "Disabling EMU Variable FVB since "\r
+ "flash variables appear to be supported.\n"));\r
+ return EFI_ABORTED;\r
+ }\r
+\r
//\r
// By default we will initialize the FV contents. But, if\r
// PcdEmuVariableNvStoreReserved is non-zero, then we will\r
SetMem (Ptr, EMU_FVB_SIZE, ERASED_UINT8);\r
InitializeFvAndVariableStoreHeaders (Ptr);\r
}\r
- PcdSet32 (PcdFlashNvStorageVariableBase, (UINT32)(UINTN) Ptr);\r
+ PcdSet64 (PcdFlashNvStorageVariableBase64, (UINT32)(UINTN) Ptr);\r
\r
//\r
// Initialize the Fault Tolerant Write data area\r
//\r
SubPtr = (VOID*) ((UINT8*) Ptr + PcdGet32 (PcdVariableStoreSize));\r
- if (Initialize) {\r
- InitializeFtwState (SubPtr);\r
- }\r
PcdSet32 (PcdFlashNvStorageFtwWorkingBase, (UINT32)(UINTN) SubPtr);\r
\r
//\r
Handle = 0;\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&Handle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
+ &gEfiFirmwareVolumeBlock2ProtocolGuid,\r
&mEmuVarsFvb.FwVolBlockInstance,\r
&gEfiDevicePathProtocolGuid,\r
&mEmuVarsFvb.DevicePath,\r