UefiPayloadPkg: Add a common FVB SMM module
This FVB module is used to initialize NV variable region and provide SMM FVB protocol to read/write SPI variable region. This module consume HOB gNvVariableInfoGuid and depends on FlashDeviceLib for the actual SPI device operate. During FVB initialization, it will initialize the variable region if the variable region is not valid. And it support to write initial variable data from FFS file if it is found. Signed-off-by: Guo Dong <guo.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Maurice Ma <maurice.ma@intel.com> Cc: Benjamin You <benjamin.you@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Reviewed-by: Benjamin You <benjamin.you@intel.com>
This commit is contained in:
139
UefiPayloadPkg/FvbRuntimeDxe/FvbServiceSmm.c
Normal file
139
UefiPayloadPkg/FvbRuntimeDxe/FvbServiceSmm.c
Normal file
@ -0,0 +1,139 @@
|
||||
/** @file
|
||||
SMM Firmware Volume Block Driver.
|
||||
|
||||
Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <PiSmm.h>
|
||||
#include <Library/SmmServicesTableLib.h>
|
||||
#include "FvbSmmCommon.h"
|
||||
#include "FvbService.h"
|
||||
|
||||
/**
|
||||
The function installs EFI_SMM_FIRMWARE_VOLUME_BLOCK protocol
|
||||
for each FV in the system.
|
||||
|
||||
@param[in] FwhInstance The pointer to a FW volume instance structure,
|
||||
which contains the information about one FV.
|
||||
@param[in] InstanceNum The instance number which can be used as a ID
|
||||
to locate this FwhInstance in other functions.
|
||||
|
||||
@retval EFI_SUCESS Installed successfully.
|
||||
@retval Else Did not install successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
InstallFvbProtocol (
|
||||
IN EFI_FW_VOL_INSTANCE *FwhInstance,
|
||||
IN UINTN InstanceNum
|
||||
)
|
||||
{
|
||||
EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE FvbHandle;
|
||||
FV_MEMMAP_DEVICE_PATH *FvDevicePath;
|
||||
VOID *TempPtr;
|
||||
|
||||
FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool (
|
||||
sizeof (EFI_FW_VOL_BLOCK_DEVICE),
|
||||
&mFvbDeviceTemplate
|
||||
);
|
||||
if (FvbDevice == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
FvbDevice->Instance = InstanceNum;
|
||||
FwVolHeader = &FwhInstance->VolumeHeader;
|
||||
|
||||
//
|
||||
// Set up the devicepath
|
||||
//
|
||||
if (FwVolHeader->ExtHeaderOffset == 0) {
|
||||
//
|
||||
// FV does not contains extension header, then produce MEMMAP_DEVICE_PATH
|
||||
//
|
||||
TempPtr = AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
|
||||
FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
|
||||
if (FvbDevice->DevicePath == NULL) {
|
||||
ASSERT (FALSE);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
FvDevicePath = (FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath;
|
||||
FvDevicePath->MemMapDevPath.StartingAddress = FwhInstance->FvBase;
|
||||
FvDevicePath->MemMapDevPath.EndingAddress = FwhInstance->FvBase + FwVolHeader->FvLength - 1;
|
||||
} else {
|
||||
TempPtr = AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);
|
||||
FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
|
||||
if (FvbDevice->DevicePath == NULL) {
|
||||
ASSERT (FALSE);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
CopyGuid (
|
||||
&((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName,
|
||||
(GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Install the SMM Firmware Volume Block Protocol and Device Path Protocol
|
||||
//
|
||||
FvbHandle = NULL;
|
||||
Status = gSmst->SmmInstallProtocolInterface (
|
||||
&FvbHandle,
|
||||
&gEfiSmmFirmwareVolumeBlockProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&FvbDevice->FwVolBlockInstance
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = gSmst->SmmInstallProtocolInterface (
|
||||
&FvbHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
FvbDevice->DevicePath
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Notify the Fvb wrapper driver SMM fvb is ready
|
||||
//
|
||||
FvbHandle = NULL;
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
&FvbHandle,
|
||||
&gEfiSmmFirmwareVolumeBlockProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&FvbDevice->FwVolBlockInstance
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
The driver entry point for SMM Firmware Volume Block Driver.
|
||||
|
||||
The function does the necessary initialization work
|
||||
Firmware Volume Block Driver.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the UEFI image.
|
||||
@param[in] SystemTable A pointer to the EFI system table.
|
||||
|
||||
@retval EFI_SUCCESS This funtion always return EFI_SUCCESS.
|
||||
It will ASSERT on errors.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvbSmmInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
FvbInitialize ();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
Reference in New Issue
Block a user