blob: e2b87a74d21a1b22e6feb03a50ba15ae49ac732b [file] [log] [blame]
/** @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;
}