alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/Platform/MsdmUpdateSmm/MsdmUpdateSmm.c

214 lines
6.4 KiB
C

/** @file
This driver handle msdm OA data between variable and SPI ROM
;******************************************************************************
;* Copyright (c) 2021, Insyde Software Corporation. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include <Uefi.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/SmmServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Protocol/SmmFwBlockService.h>
#include <Protocol/SmmVariable.h>
#include <IndustryStandard/Oa3_0.h>
static EFI_GUID gMsdmAddressGuid = MEMORY_ADDRESS_FOR_MSDM_GUID;
EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *mSmmFwBlockService = NULL;
EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable = NULL;
UINTN mRomBaseAddress;
UINTN mMsdmDataSize;
/**
Erasing MSDM OA data from SPI ROM NvStorageMsdmData region.
**/
VOID
OA30EraseFromRom (
VOID
)
{
EFI_STATUS Status;
Status = mSmmFwBlockService->EraseBlocks (
mSmmFwBlockService,
mRomBaseAddress,
&mMsdmDataSize
);
if (!EFI_ERROR (Status)) {
//
// Delete MsdmErase variable.
//
Status = mSmmVariable->SmmSetVariable (
L"MsdmErase",
&gMsdmAddressGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
NULL
);
if (!EFI_ERROR (Status)) {
return;
} else {
DEBUG ((DEBUG_WARN, "Erasing Msdm data from NvStorageMsdmData Success, but MsdmErase Variable did NOT been removed. Status : %r\n", Status));
}
} else {
DEBUG ((DEBUG_WARN, "NvStorageMsdmData Erasing Failed. Status : %r\n", Status));
}
return;
}
/**
Writing MSDM OA data from Variable to SPI ROM NvStorageMsdmData region.
**/
VOID
OA30UpdateToRom (
IN UINT8 *MsdmData
)
{
EFI_STATUS Status;
Status = mSmmFwBlockService->EraseBlocks (
mSmmFwBlockService,
mRomBaseAddress,
&mMsdmDataSize
);
if (!EFI_ERROR(Status)) {
Status = mSmmFwBlockService->Write (
mSmmFwBlockService,
mRomBaseAddress,
&mMsdmDataSize,
MsdmData
);
if (!EFI_ERROR (Status)) {
//
// Delete MsdmUpdate variable.
//
Status = mSmmVariable->SmmSetVariable (
L"MsdmUpdate",
&gMsdmAddressGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
NULL
);
if (!EFI_ERROR (Status)) {
return;
} else {
DEBUG ((DEBUG_WARN, "Update Msdm to ROM Success but MsdmUpdate Variable did NOT been removed. Status : %r\n", Status));
}
} else {
DEBUG ((DEBUG_WARN, "Update Msdm to ROM Failed. Status : %r\n", Status));
}
} else {
DEBUG ((DEBUG_WARN, "NvStorageMsdmData Erasing Failed. Status : %r\n", Status));
}
return;
}
/**
Handle msdm OA data between variable and SPI ROM
@param[in] ImageHandle Image handle of this driver.
@param[in] SystemTable Pointer to standard EFI system table.
@retval EFI_SUCCESS Msdm Data was updated to ROM or removed form ROM Successful.
@retval !EFI_SUCCESS Fail or NoNeed to update.
**/
EFI_STATUS
EFIAPI
UpdateMsdmSmmEntry (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINT8 Erase;
UINTN DataSize;
UINT8 *MsdmData;
Status = EFI_SUCCESS;
Erase = 0;
DataSize = 0;
MsdmData = NULL;
mRomBaseAddress = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataBase);
mMsdmDataSize = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataSize);
Status = gSmst->SmmLocateProtocol (
&gEfiSmmFwBlockServiceProtocolGuid,
NULL,
&mSmmFwBlockService
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "FW Block Service Protocol Locate Failed. Status : %r\n", Status));
return Status;
}
//
// Locate SMM Variable Protocol
//
Status = gSmst->SmmLocateProtocol (
&gEfiSmmVariableProtocolGuid,
NULL,
(VOID **) &mSmmVariable
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Smm Variable Protocol Locate Failed. Status : %r\n", Status));
return Status;
}
//
// Erase Msdm Data.
//
DataSize = sizeof (UINT8);
Status = mSmmVariable->SmmGetVariable (
L"MsdmErase",
&gMsdmAddressGuid,
NULL,
&DataSize,
(UINTN*) &Erase
);
if (!EFI_ERROR (Status)) {
OA30EraseFromRom ();
}
//
// Update Msdm data.
//
Status = gSmst->SmmAllocatePool (
EfiRuntimeServicesData,
mMsdmDataSize,
&MsdmData
);
DEBUG ((DEBUG_INFO, "Allocate pool for MSDM Data Status : %r\n", Status));
if (!EFI_ERROR (Status)) {
Status = mSmmVariable->SmmGetVariable (
L"MsdmUpdate",
&gMsdmAddressGuid,
NULL,
&mMsdmDataSize,
MsdmData
);
if (!EFI_ERROR (Status)) {
OA30UpdateToRom (MsdmData);
}
}
if (MsdmData != NULL) {
gSmst->SmmFreePool (MsdmData);
}
return Status;
}