240 lines
6.1 KiB
C
240 lines
6.1 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/UefiRuntimeServicesTableLib.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/IoLib.h>
|
|
#include <Library/UefiLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Protocol/LenovoVariable.h>
|
|
#include <Guid/LfcVariableGuid.h>
|
|
#include <Library/LfcEcLib.h>
|
|
|
|
/**
|
|
Check if it is a leap year.
|
|
|
|
@param[in] Time The time to be checked.
|
|
|
|
@retval TRUE It is a leap year.
|
|
@retval FALSE It is NOT a leap year.
|
|
**/
|
|
BOOLEAN
|
|
IsItLeapYear (
|
|
IN EFI_TIME *Time
|
|
)
|
|
{
|
|
if (Time->Year % 4 == 0) {
|
|
if (Time->Year % 100 == 0) {
|
|
if (Time->Year % 400 == 0) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
} else {
|
|
return TRUE;
|
|
}
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
EFI_STATUS
|
|
TimeAddHours (
|
|
IN OUT EFI_TIME *Time,
|
|
IN UINT16 AddHours
|
|
)
|
|
{
|
|
EFI_TIME TheTime;
|
|
UINT8 MonthDays[13];
|
|
UINT8 MonthDaysLeapYear[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
|
UINT8 MonthDaysNoLeapYear[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
|
UINT16 MonthDaysSum[13];
|
|
UINT16 MonthDaysSumLeapYear[13] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
|
|
UINT16 MonthDaysSumNoLeapYear[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
|
|
UINTN Index;
|
|
UINTN Days = 0;
|
|
UINTN Hours = 0;
|
|
|
|
TheTime = *Time;
|
|
|
|
//Based on beginning of saved time year, get saved time hours sum.
|
|
if (IsItLeapYear(&TheTime)) {
|
|
for (Index = 0; Index < 13; Index++) {
|
|
MonthDays[Index] = MonthDaysLeapYear[Index];
|
|
}
|
|
} else {
|
|
for (Index = 0; Index < 13; Index++) {
|
|
MonthDays[Index] = MonthDaysNoLeapYear[Index];
|
|
}
|
|
}
|
|
|
|
for (Index = 0; Index < TheTime.Month; Index++) {
|
|
Days += MonthDays[Index];
|
|
}
|
|
Days += TheTime.Day;
|
|
|
|
Hours = (Days - 1) * 24 + TheTime.Hour;
|
|
|
|
//Add parameter AddHours
|
|
Hours += AddHours;
|
|
|
|
//Get wanted time
|
|
Days = (Hours / 24) + 1;
|
|
TheTime.Hour = Hours % 24;
|
|
|
|
while (TRUE) {
|
|
if (IsItLeapYear(&TheTime)) {
|
|
for (Index = 0; Index < 13; Index++) {
|
|
MonthDaysSum[Index] = MonthDaysSumLeapYear[Index];
|
|
}
|
|
} else {
|
|
for (Index = 0; Index < 13; Index++) {
|
|
MonthDaysSum[Index] = MonthDaysSumNoLeapYear[Index];
|
|
}
|
|
}
|
|
|
|
if (Days > MonthDaysSum[12]) {
|
|
TheTime.Year++;
|
|
Days -= MonthDaysSum[12];
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (Index = 0; Index < 13; Index++) {
|
|
if (Days <= MonthDaysSum[Index]) {
|
|
TheTime.Month = (UINT8) Index;
|
|
TheTime.Day = (UINT8) (Days - MonthDaysSum[Index-1]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (TheTime.Year < 2099) {
|
|
*Time = TheTime;
|
|
return EFI_SUCCESS;
|
|
} else {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Correct RTC time, year support to 2099.
|
|
**/
|
|
EFI_STATUS
|
|
RollbackRtcTimeCallBack (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 SaveTime[6] = {0};
|
|
UINTN TempDataLength = sizeof (SaveTime);
|
|
EFI_TIME TheTime;
|
|
UINT16 BatteryTimerCount;
|
|
|
|
//Get saved time from variable - "SaveCurrentTime"
|
|
Status = gRT->GetVariable (
|
|
L"SaveCurrentTime",
|
|
&gLfcVariableGuid,
|
|
NULL,
|
|
&TempDataLength,
|
|
SaveTime
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//Get system default time format
|
|
Status = gRT->GetTime (&TheTime, NULL);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
TheTime.Second = BcdToDecimal8(SaveTime[0]);
|
|
TheTime.Minute = BcdToDecimal8(SaveTime[1]);
|
|
TheTime.Hour = BcdToDecimal8(SaveTime[2]);
|
|
TheTime.Day = BcdToDecimal8(SaveTime[3]);
|
|
TheTime.Month = BcdToDecimal8(SaveTime[4]);
|
|
TheTime.Year = 2000 + BcdToDecimal8(SaveTime[5]);
|
|
TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
|
|
TheTime.Daylight = 0;
|
|
|
|
//Get battery timer count from EC - hours.
|
|
Status = LfcEcLibGetBatteryTimerCount(&BatteryTimerCount);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//Time add battery timer count (hours)
|
|
Status = TimeAddHours(&TheTime, BatteryTimerCount);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//Set new Time
|
|
Status = gRT->SetTime(&TheTime);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//Delete variable - "SaveCurrentTime"
|
|
Status = gRT->SetVariable (
|
|
L"SaveCurrentTime",
|
|
&gLfcVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
0,
|
|
SaveTime
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
// Add battery first use data
|
|
Status = LfcEcLibGetBatteryFirstUsedDate();
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
Remove RTC Battery DXE 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
|
|
L05RemoveRtcBatteryDxeEntry (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_EVENT Event;
|
|
|
|
Status = EfiCreateEventReadyToBootEx (
|
|
TPL_CALLBACK,
|
|
RollbackRtcTimeCallBack,
|
|
NULL,
|
|
&Event
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|