alder_lake_bios/Lcfc/LfcPkg/RemoveRtcBattery/RemoveRtcBatterySmm/RemoveRtcBatterySmm.c

128 lines
3.8 KiB
C

/** @file
;******************************************************************************
;*
;* Copyright (c) 2012 - 2020, Hefei LCFC Information Technology Co.Ltd.
;* And/or its affiliates. All rights reserved.
;* Hefei LCFC Information Technology Co.Ltd. PROPRIETARY/CONFIDENTIAL.
;* Use is subject to license terms.
;*
;******************************************************************************
*/
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/SmmServicesTableLib.h>
#include <Lfc.h>
#include <Protocol/SmmSxDispatch2.h>
#include <Protocol/SmmSwDispatch2.h>
#include <Protocol/SmmVariable.h>
#include <Protocol/LenovoVariable.h>
#include <Guid/LfcVariableGuid.h>
#define CMOS_DATA_PORT 0x71
#define CMOS_ADDR_PORT 0x70
//LCFCTODO: Need confirm if this software SMI conflict with other.
#define REMOVE_RTC_BATTERY_SMI 0xCE
EFI_STATUS
EFIAPI
SaveCurrentTimeCallback (
IN EFI_HANDLE DispatchHandle,
IN CONST VOID *Context OPTIONAL,
IN OUT VOID *CommBuffer OPTIONAL,
IN OUT UINTN *CommBufferSize OPTIONAL
)
{
EFI_STATUS Status;
EFI_SMM_VARIABLE_PROTOCOL *SmmVariable;
UINT8 SaveTime[6] = {0};
UINT32 TempDataLength = sizeof (SaveTime);
//Read Current Time - Second
IoWrite8(CMOS_ADDR_PORT, 0x00);
SaveTime[0] = IoRead8(CMOS_DATA_PORT);
//Read Current Time - Minute
IoWrite8(CMOS_ADDR_PORT, 0x02);
SaveTime[1] = IoRead8(CMOS_DATA_PORT);
//Read Current Time - Hour
IoWrite8(CMOS_ADDR_PORT, 0x04);
SaveTime[2] = IoRead8(CMOS_DATA_PORT);
//Read Current Time - Day
IoWrite8(CMOS_ADDR_PORT, 0x07);
SaveTime[3] = IoRead8(CMOS_DATA_PORT);
//Read Current Time - Month
IoWrite8(CMOS_ADDR_PORT, 0x08);
SaveTime[4] = IoRead8(CMOS_DATA_PORT);
//Read Current Time - Year
IoWrite8(CMOS_ADDR_PORT, 0x09);
SaveTime[5] = IoRead8(CMOS_DATA_PORT);
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, &SmmVariable);
if (EFI_ERROR (Status)) {
return Status;
} else {
//Save current time into variable - "SaveCurrentTime"
SmmVariable->SmmSetVariable (
L"SaveCurrentTime",
&gLfcVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
TempDataLength,
SaveTime
);
return EFI_SUCCESS;
}
}
/**
Remove RTC Battery SMM entry.
Remove RTC battery then ship support, RTC time will lost.
This solution will save current RTC time, then add battery count, generate new time and set it.
@param ImageHandle The firmware allocated handle for the UEFI image.
@param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
L05RemoveRtcBatterySmmEntry (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
EFI_SMM_SW_REGISTER_CONTEXT SwContext;
EFI_HANDLE SwHandle;
Status = gSmst->SmmLocateProtocol (
&gEfiSmmSwDispatch2ProtocolGuid,
NULL,
&SwDispatch
);
ASSERT_EFI_ERROR (Status);
//Save current time SMI
SwContext.SwSmiInputValue = REMOVE_RTC_BATTERY_SMI;
Status = SwDispatch->Register (
SwDispatch,
SaveCurrentTimeCallback,
&SwContext,
&SwHandle
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}