alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/SaveRestoreCmos/SaveCmosDxe/SaveCmosDxe.c

189 lines
5.8 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2014 - 2020 , 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/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/Uefilib.h>
#include <Library/CmosLib.h>
#include <Guid/CmosInVariable.h>
#include <ChipsetCmos.h>
VOID
DumpCmosInVariableValue (
UINT8 *CmosInVariable
)
{
UINTN Index;
for (Index = 0; Index < CMOS_TOTAL_LENGTH; Index += 8) {
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "%02x %02x %02x %02x %02x %02x %02x %02x", \
CmosInVariable[Index], CmosInVariable[Index+1], \
CmosInVariable[Index+2], CmosInVariable[Index+3], \
CmosInVariable[Index+4], CmosInVariable[Index+5], \
CmosInVariable[Index+6], CmosInVariable[Index+7] \
) );
}
return;
}
VOID
DumpCmosValue (
//[-start-190610-IB16990033-add]//
VOID
//[-end-190610-IB16990033-add]//
)
{
UINT8 Index;
for (Index = 0; Index < (CMOS_TOTAL_LENGTH/2); Index += 8) {
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "%02x %02x %02x %02x %02x %02x %02x %02x", \
ReadCmos8 (Index), ReadCmos8 (Index+1), \
ReadCmos8 (Index+2), ReadCmos8 (Index+3), \
ReadCmos8 (Index+4), ReadCmos8 (Index+5), \
ReadCmos8 (Index+6), ReadCmos8 (Index+7) \
) );
}
for (Index = 0; Index < (CMOS_TOTAL_LENGTH/2); Index += 8) {
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "%02x %02x %02x %02x %02x %02x %02x %02x", \
ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index), \
ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+1), \
ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+2), \
ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+3), \
ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+4), \
ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+5), \
ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+6), \
ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Index+7) \
) );
}
return;
}
/**
This function gets registered as a callback to run the SaveCmosCallback function.
@param[in] Event - A pointer to the Event that triggered the callback.
@param[in] Context - A pointer to private data registered with the callback function.
**/
VOID
EFIAPI
SaveCmosCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINT8 Cmosbuffer[CMOS_TOTAL_LENGTH];
UINT8 CmosInVariable[CMOS_TOTAL_LENGTH];
UINT8 Index;
UINT8 Address;
UINTN Size;
INTN Saveflag;
CMOS_ELEMENT *CmosElement;
Size = CMOS_TOTAL_LENGTH;
Saveflag = 0;
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "SaveCmosCallback Start" ) );
for (Index = 0, Address = 0; Address < (CMOS_TOTAL_LENGTH/2); Index++, Address++) {
Cmosbuffer[Index] = ReadCmos8 (Address);
}
for (Address = 0; Address < (CMOS_TOTAL_LENGTH/2); Index++, Address++) {
Cmosbuffer[Index] = ReadExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, Address);
}
Status = gRT->GetVariable (
L"CmosVariable",
&gCmosInVariableGuid,
NULL,
&Size,
&CmosInVariable
);
if (Status == EFI_SUCCESS) {
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "Current CmosVariable value" ) );
DumpCmosInVariableValue (CmosInVariable);
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "Current cmos value" ) );
DumpCmosValue ();
CmosElement = (CMOS_ELEMENT *)PcdGetPtr (PcdSaveCmosFieldCompareList);
Index = 0;
while (((CmosElement[Index].Start_Offset != 0) && (CmosElement[Index].Length != 0)) && Saveflag == 0) {
Address = CmosElement[Index].Start_Offset;
Saveflag = CompareMem (&CmosInVariable[Address], &Cmosbuffer[Address], CmosElement[Index].Length);
Index++;
}
if (Saveflag != 0) {
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "CmosVariable value is different from Cmos value" ) );
}
} else {
Saveflag = 1;
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "CmosVariable don't exist" ) );
}
if ( Saveflag != 0) {
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "Update CmosVariable !!" ) );
Status = gRT->SetVariable (
L"CmosVariable",
&gCmosInVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
Size,
(VOID *) Cmosbuffer
);
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "Save CmosVariable value" ) );
DumpCmosValue ();
} else {
DEBUG ( ( DEBUG_INFO | DEBUG_ERROR, "No update CmosVariable !!" ) );
}
///
/// Closed the event to avoid call twice when launch shell
///
gBS->CloseEvent (Event);
}
/**
Install ReadyToboot callback event for Saving CMOS value in Variable.
@param[in] ImageHandle - A handle for this module
@param[in] SystemTable - A pointer to the EFI System Table
@retval Status
**/
EFI_STATUS
EFIAPI
SaveCmosEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_EVENT ReadyToBootEvent;
///
/// Create callback to run SaveCmosCallback
///
Status = EfiCreateEventReadyToBootEx (
TPL_CALLBACK,
SaveCmosCallback,
NULL,
&ReadyToBootEvent
);
ASSERT_EFI_ERROR (Status);
return Status;
}