Message ID | 20181029033249.45363-7-ming.huang@linaro.org |
---|---|
State | New |
Headers | show |
Series | [edk2,edk2-platforms,v1,01/12] Silicon/Hisilicon/D06: Add watchdog to GTDT | expand |
On Mon, Oct 29, 2018 at 11:32:43AM +0800, Ming Huang wrote: > There is no variable to keep timezone and daylight, so read it from > the hardware first and create a new variable to keep it for the next > gettime process. Can you make use of EmbeddedPkg/RealTimeClockRuntimeDxe instead? / Leif > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ming Huang <ming.huang@linaro.org> > --- > Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf | 2 +- > Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h | 4 + > Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c | 175 +++++++++++++++++++- > 3 files changed, 179 insertions(+), 2 deletions(-) > > diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf > index 4e963fd453..8e559d7b70 100644 > --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf > +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf > @@ -42,4 +42,4 @@ > UefiRuntimeLib # Use EFiAtRuntime to check stage > > [Depex] > - gEfiCpuArchProtocolGuid > + gEfiCpuArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid > diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h > index f329108858..b95ebc654a 100644 > --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h > +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h > @@ -41,6 +41,10 @@ > #define M41T83_REGADDR_ALARM2DATE 0x15 > #define M41T83_REGADDR_ALARM2MONTH 0x14 > > +//UEFI SPEC 2.7,page 295 > +#define TIME_ZONE_MIN -1440 > +#define TIME_ZONE_MAX 1440 > + > typedef union { > struct { > UINT8 TD0:1; > diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c > index 1f50ad4b64..a2063aff76 100644 > --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c > +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c > @@ -32,6 +32,9 @@ extern I2C_DEVICE gRtcDevice; > > STATIC EFI_LOCK mRtcLock; > > +STATIC CONST CHAR16 mTimeZoneVariableName[] = L"M41T83RtcTimeZone"; > +STATIC CONST CHAR16 mDaylightVariableName[] = L"M41T83RtcDaylight"; > + > /** > Read RTC content through its registers. > > @@ -182,6 +185,7 @@ LibSetTime ( > RTC_M41T83_TIME BcdTime; > UINT16 CenturyBase = 2000; > UINTN LineNum = 0; > + UINTN EpochSeconds; > > if (NULL == Time) { > return EFI_INVALID_PARAMETER; > @@ -206,6 +210,21 @@ LibSetTime ( > > SetMem (&BcdTime, sizeof (RTC_M41T83_TIME), 0); > > + EpochSeconds = EfiTimeToEpoch (Time); > + > + // Adjust for the correct time zone, i.e. convert to UTC time zone > + if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { > + EpochSeconds -= Time->TimeZone * SEC_PER_MIN; > + } > + > + // Adjust for the correct period > + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) { > + // Convert to un-adjusted time, i.e. fall back one hour > + EpochSeconds -= SEC_PER_HOUR; > + } > + > + EpochToEfiTime (EpochSeconds, Time); > + > // Acquire RTC Lock to make access to RTC atomic > if (!EfiAtRuntime ()) { > EfiAcquireLock (&mRtcLock); > @@ -254,6 +273,43 @@ LibSetTime ( > LineNum = __LINE__; > goto Exit; > } > + // Save the current time zone information into non-volatile storage > + Status = EfiSetVariable ( > + (CHAR16 *)mTimeZoneVariableName, > + &gEfiCallerIdGuid, > + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, > + sizeof (Time->TimeZone), > + (VOID *)&(Time->TimeZone) > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "LibSetTime: can not save %s variable to non-volatile storage, Status = %r\n", > + mTimeZoneVariableName, > + Status > + )); > + LineNum = __LINE__; > + goto Exit; > + } > + > + // Save the current daylight information into non-volatile storage > + Status = EfiSetVariable ( > + (CHAR16 *)mDaylightVariableName, > + &gEfiCallerIdGuid, > + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, > + sizeof (Time->Daylight), > + (VOID *)&(Time->Daylight) > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "LibSetTime: can not to save %s variable to non-volatile storage, Status = %r\n", > + mDaylightVariableName, > + Status > + )); > + LineNum = __LINE__; > + goto Exit; > + } > > Exit: > OemReleaseOwnershipOfRtc (); > @@ -295,6 +351,10 @@ LibGetTime ( > UINTN LineNum = 0; > BOOLEAN IsTimeInvalid = FALSE; > UINT8 TimeTemp[7] = {0}; > + UINTN EpochSeconds; > + INT16 TimeZone; > + UINT8 Daylight; > + UINTN Size; > > // Ensure Time is a valid pointer > if (Time == NULL) { > @@ -336,7 +396,6 @@ LibGetTime ( > Time->Hour = BcdToDecimal8 (BcdTime.Hour.Bits.Hours); > Time->Minute = BcdToDecimal8 (BcdTime.Minute.Bits.Minutes); > Time->Second = BcdToDecimal8 (BcdTime.Second.Bits.Seconds); > - Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; > > if (!IsTimeValid (Time)) { > Status = EFI_DEVICE_ERROR; > @@ -345,6 +404,120 @@ LibGetTime ( > goto Exit; > } > > + EpochSeconds = EfiTimeToEpoch (Time); > + > + Size = sizeof (TimeZone); > + Status = EfiGetVariable ( > + (CHAR16 *)mTimeZoneVariableName, > + &gEfiCallerIdGuid, > + NULL, > + &Size, > + (VOID *)&TimeZone > + ); > + > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "LibGetTime: can not get %s variable, Status = %r\n", > + mTimeZoneVariableName, > + Status > + )); > + if (Status != EFI_NOT_FOUND) { > + LineNum = __LINE__; > + goto Exit; > + } > + > + // The time zone variable does not exist in non-volatile storage, so create it. > + Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; > + // Store it > + Status = EfiSetVariable ( > + (CHAR16 *)mTimeZoneVariableName, > + &gEfiCallerIdGuid, > + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, > + Size, > + (VOID *)&(Time->TimeZone) > + ); > + > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "LibGetTime: can not save %s variable to non-volatile storage, Status = %r\n", > + mTimeZoneVariableName, > + Status > + )); > + LineNum = __LINE__; > + goto Exit; > + } > + } else { > + // Got the time zone > + Time->TimeZone = TimeZone; > + > + // Check TimeZone bounds: -1440 to 1440 or 2047 > + if (((Time->TimeZone < TIME_ZONE_MIN) || (Time->TimeZone > TIME_ZONE_MAX)) > + && (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE)) { > + Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; > + } > + > + // Adjust for the correct time zone > + if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { > + EpochSeconds += Time->TimeZone * SEC_PER_MIN; > + } > + } > + > + // Get the current daylight information from non-volatile storage > + Size = sizeof (Daylight); > + Status = EfiGetVariable ( > + (CHAR16 *)mDaylightVariableName, > + &gEfiCallerIdGuid, > + NULL, > + &Size, > + (VOID *)&Daylight > + ); > + > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "LibGetTime: Failed to get %s variable, Status = %r\n", > + mDaylightVariableName, > + Status > + )); > + if (Status != EFI_NOT_FOUND) { > + goto Exit; > + } > + // The daylight variable does not exist in non-volatile storage, so create it. > + Time->Daylight = 0; > + // Store it > + Status = EfiSetVariable ( > + (CHAR16 *)mDaylightVariableName, > + &gEfiCallerIdGuid, > + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, > + Size, > + (VOID *)&(Time->Daylight) > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "LibGetTime: can not save %s variable to non-volatile storage, Status = %r\n", > + mDaylightVariableName, > + Status > + )); > + LineNum = __LINE__; > + goto Exit; > + } > + } else { > + // Got the daylight information > + Time->Daylight = Daylight; > + > + // Adjust for the correct period > + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) { > + // Convert to adjusted time, i.e. spring forwards one hour > + EpochSeconds += SEC_PER_HOUR; > + } > + } > + > + // Convert from internal 32-bit time to UEFI time > + EpochToEfiTime (EpochSeconds, Time); > + > Exit: > OemReleaseOwnershipOfRtc (); > // Release RTC Lock. > -- > 2.18.0 > _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
On 11/14/2018 7:52 AM, Leif Lindholm wrote: > On Mon, Oct 29, 2018 at 11:32:43AM +0800, Ming Huang wrote: >> There is no variable to keep timezone and daylight, so read it from >> the hardware first and create a new variable to keep it for the next >> gettime process. > > Can you make use of EmbeddedPkg/RealTimeClockRuntimeDxe instead? Do you mean merge this patch into EmbeddedPkg/RealTimeClockRuntimeDxe? > > / > Leif > >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Ming Huang <ming.huang@linaro.org> >> --- >> Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf | 2 +- >> Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h | 4 + >> Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c | 175 +++++++++++++++++++- >> 3 files changed, 179 insertions(+), 2 deletions(-) >> >> diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf >> index 4e963fd453..8e559d7b70 100644 >> --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf >> +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf >> @@ -42,4 +42,4 @@ >> UefiRuntimeLib # Use EFiAtRuntime to check stage >> >> [Depex] >> - gEfiCpuArchProtocolGuid >> + gEfiCpuArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid >> diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h >> index f329108858..b95ebc654a 100644 >> --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h >> +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h >> @@ -41,6 +41,10 @@ >> #define M41T83_REGADDR_ALARM2DATE 0x15 >> #define M41T83_REGADDR_ALARM2MONTH 0x14 >> >> +//UEFI SPEC 2.7,page 295 >> +#define TIME_ZONE_MIN -1440 >> +#define TIME_ZONE_MAX 1440 >> + >> typedef union { >> struct { >> UINT8 TD0:1; >> diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c >> index 1f50ad4b64..a2063aff76 100644 >> --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c >> +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c >> @@ -32,6 +32,9 @@ extern I2C_DEVICE gRtcDevice; >> >> STATIC EFI_LOCK mRtcLock; >> >> +STATIC CONST CHAR16 mTimeZoneVariableName[] = L"M41T83RtcTimeZone"; >> +STATIC CONST CHAR16 mDaylightVariableName[] = L"M41T83RtcDaylight"; >> + >> /** >> Read RTC content through its registers. >> >> @@ -182,6 +185,7 @@ LibSetTime ( >> RTC_M41T83_TIME BcdTime; >> UINT16 CenturyBase = 2000; >> UINTN LineNum = 0; >> + UINTN EpochSeconds; >> >> if (NULL == Time) { >> return EFI_INVALID_PARAMETER; >> @@ -206,6 +210,21 @@ LibSetTime ( >> >> SetMem (&BcdTime, sizeof (RTC_M41T83_TIME), 0); >> >> + EpochSeconds = EfiTimeToEpoch (Time); >> + >> + // Adjust for the correct time zone, i.e. convert to UTC time zone >> + if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { >> + EpochSeconds -= Time->TimeZone * SEC_PER_MIN; >> + } >> + >> + // Adjust for the correct period >> + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) { >> + // Convert to un-adjusted time, i.e. fall back one hour >> + EpochSeconds -= SEC_PER_HOUR; >> + } >> + >> + EpochToEfiTime (EpochSeconds, Time); >> + >> // Acquire RTC Lock to make access to RTC atomic >> if (!EfiAtRuntime ()) { >> EfiAcquireLock (&mRtcLock); >> @@ -254,6 +273,43 @@ LibSetTime ( >> LineNum = __LINE__; >> goto Exit; >> } >> + // Save the current time zone information into non-volatile storage >> + Status = EfiSetVariable ( >> + (CHAR16 *)mTimeZoneVariableName, >> + &gEfiCallerIdGuid, >> + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, >> + sizeof (Time->TimeZone), >> + (VOID *)&(Time->TimeZone) >> + ); >> + if (EFI_ERROR (Status)) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "LibSetTime: can not save %s variable to non-volatile storage, Status = %r\n", >> + mTimeZoneVariableName, >> + Status >> + )); >> + LineNum = __LINE__; >> + goto Exit; >> + } >> + >> + // Save the current daylight information into non-volatile storage >> + Status = EfiSetVariable ( >> + (CHAR16 *)mDaylightVariableName, >> + &gEfiCallerIdGuid, >> + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, >> + sizeof (Time->Daylight), >> + (VOID *)&(Time->Daylight) >> + ); >> + if (EFI_ERROR (Status)) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "LibSetTime: can not to save %s variable to non-volatile storage, Status = %r\n", >> + mDaylightVariableName, >> + Status >> + )); >> + LineNum = __LINE__; >> + goto Exit; >> + } >> >> Exit: >> OemReleaseOwnershipOfRtc (); >> @@ -295,6 +351,10 @@ LibGetTime ( >> UINTN LineNum = 0; >> BOOLEAN IsTimeInvalid = FALSE; >> UINT8 TimeTemp[7] = {0}; >> + UINTN EpochSeconds; >> + INT16 TimeZone; >> + UINT8 Daylight; >> + UINTN Size; >> >> // Ensure Time is a valid pointer >> if (Time == NULL) { >> @@ -336,7 +396,6 @@ LibGetTime ( >> Time->Hour = BcdToDecimal8 (BcdTime.Hour.Bits.Hours); >> Time->Minute = BcdToDecimal8 (BcdTime.Minute.Bits.Minutes); >> Time->Second = BcdToDecimal8 (BcdTime.Second.Bits.Seconds); >> - Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; >> >> if (!IsTimeValid (Time)) { >> Status = EFI_DEVICE_ERROR; >> @@ -345,6 +404,120 @@ LibGetTime ( >> goto Exit; >> } >> >> + EpochSeconds = EfiTimeToEpoch (Time); >> + >> + Size = sizeof (TimeZone); >> + Status = EfiGetVariable ( >> + (CHAR16 *)mTimeZoneVariableName, >> + &gEfiCallerIdGuid, >> + NULL, >> + &Size, >> + (VOID *)&TimeZone >> + ); >> + >> + if (EFI_ERROR (Status)) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "LibGetTime: can not get %s variable, Status = %r\n", >> + mTimeZoneVariableName, >> + Status >> + )); >> + if (Status != EFI_NOT_FOUND) { >> + LineNum = __LINE__; >> + goto Exit; >> + } >> + >> + // The time zone variable does not exist in non-volatile storage, so create it. >> + Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; >> + // Store it >> + Status = EfiSetVariable ( >> + (CHAR16 *)mTimeZoneVariableName, >> + &gEfiCallerIdGuid, >> + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, >> + Size, >> + (VOID *)&(Time->TimeZone) >> + ); >> + >> + if (EFI_ERROR (Status)) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "LibGetTime: can not save %s variable to non-volatile storage, Status = %r\n", >> + mTimeZoneVariableName, >> + Status >> + )); >> + LineNum = __LINE__; >> + goto Exit; >> + } >> + } else { >> + // Got the time zone >> + Time->TimeZone = TimeZone; >> + >> + // Check TimeZone bounds: -1440 to 1440 or 2047 >> + if (((Time->TimeZone < TIME_ZONE_MIN) || (Time->TimeZone > TIME_ZONE_MAX)) >> + && (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE)) { >> + Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; >> + } >> + >> + // Adjust for the correct time zone >> + if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { >> + EpochSeconds += Time->TimeZone * SEC_PER_MIN; >> + } >> + } >> + >> + // Get the current daylight information from non-volatile storage >> + Size = sizeof (Daylight); >> + Status = EfiGetVariable ( >> + (CHAR16 *)mDaylightVariableName, >> + &gEfiCallerIdGuid, >> + NULL, >> + &Size, >> + (VOID *)&Daylight >> + ); >> + >> + if (EFI_ERROR (Status)) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "LibGetTime: Failed to get %s variable, Status = %r\n", >> + mDaylightVariableName, >> + Status >> + )); >> + if (Status != EFI_NOT_FOUND) { >> + goto Exit; >> + } >> + // The daylight variable does not exist in non-volatile storage, so create it. >> + Time->Daylight = 0; >> + // Store it >> + Status = EfiSetVariable ( >> + (CHAR16 *)mDaylightVariableName, >> + &gEfiCallerIdGuid, >> + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, >> + Size, >> + (VOID *)&(Time->Daylight) >> + ); >> + if (EFI_ERROR (Status)) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "LibGetTime: can not save %s variable to non-volatile storage, Status = %r\n", >> + mDaylightVariableName, >> + Status >> + )); >> + LineNum = __LINE__; >> + goto Exit; >> + } >> + } else { >> + // Got the daylight information >> + Time->Daylight = Daylight; >> + >> + // Adjust for the correct period >> + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) { >> + // Convert to adjusted time, i.e. spring forwards one hour >> + EpochSeconds += SEC_PER_HOUR; >> + } >> + } >> + >> + // Convert from internal 32-bit time to UEFI time >> + EpochToEfiTime (EpochSeconds, Time); >> + >> Exit: >> OemReleaseOwnershipOfRtc (); >> // Release RTC Lock. >> -- >> 2.18.0 >> _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
On Wed, Nov 14, 2018 at 10:31:12PM +0800, Ming Huang wrote: > On 11/14/2018 7:52 AM, Leif Lindholm wrote: > > On Mon, Oct 29, 2018 at 11:32:43AM +0800, Ming Huang wrote: > >> There is no variable to keep timezone and daylight, so read it from > >> the hardware first and create a new variable to keep it for the next > >> gettime process. > > > > Can you make use of EmbeddedPkg/RealTimeClockRuntimeDxe instead? > > Do you mean merge this patch into EmbeddedPkg/RealTimeClockRuntimeDxe? If that makes sense. Certainly the bits that deal with saving timezone ariables should be in core rather than in a component-specific library. It already has NON_VOLATILE_TIME_SETTINGS. / Leif > > > > / > > Leif > > > >> Contributed-under: TianoCore Contribution Agreement 1.1 > >> Signed-off-by: Ming Huang <ming.huang@linaro.org> > >> --- > >> Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf | 2 +- > >> Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h | 4 + > >> Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c | 175 +++++++++++++++++++- > >> 3 files changed, 179 insertions(+), 2 deletions(-) > >> > >> diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf > >> index 4e963fd453..8e559d7b70 100644 > >> --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf > >> +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf > >> @@ -42,4 +42,4 @@ > >> UefiRuntimeLib # Use EFiAtRuntime to check stage > >> > >> [Depex] > >> - gEfiCpuArchProtocolGuid > >> + gEfiCpuArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid > >> diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h > >> index f329108858..b95ebc654a 100644 > >> --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h > >> +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h > >> @@ -41,6 +41,10 @@ > >> #define M41T83_REGADDR_ALARM2DATE 0x15 > >> #define M41T83_REGADDR_ALARM2MONTH 0x14 > >> > >> +//UEFI SPEC 2.7,page 295 > >> +#define TIME_ZONE_MIN -1440 > >> +#define TIME_ZONE_MAX 1440 > >> + > >> typedef union { > >> struct { > >> UINT8 TD0:1; > >> diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c > >> index 1f50ad4b64..a2063aff76 100644 > >> --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c > >> +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c > >> @@ -32,6 +32,9 @@ extern I2C_DEVICE gRtcDevice; > >> > >> STATIC EFI_LOCK mRtcLock; > >> > >> +STATIC CONST CHAR16 mTimeZoneVariableName[] = L"M41T83RtcTimeZone"; > >> +STATIC CONST CHAR16 mDaylightVariableName[] = L"M41T83RtcDaylight"; > >> + > >> /** > >> Read RTC content through its registers. > >> > >> @@ -182,6 +185,7 @@ LibSetTime ( > >> RTC_M41T83_TIME BcdTime; > >> UINT16 CenturyBase = 2000; > >> UINTN LineNum = 0; > >> + UINTN EpochSeconds; > >> > >> if (NULL == Time) { > >> return EFI_INVALID_PARAMETER; > >> @@ -206,6 +210,21 @@ LibSetTime ( > >> > >> SetMem (&BcdTime, sizeof (RTC_M41T83_TIME), 0); > >> > >> + EpochSeconds = EfiTimeToEpoch (Time); > >> + > >> + // Adjust for the correct time zone, i.e. convert to UTC time zone > >> + if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { > >> + EpochSeconds -= Time->TimeZone * SEC_PER_MIN; > >> + } > >> + > >> + // Adjust for the correct period > >> + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) { > >> + // Convert to un-adjusted time, i.e. fall back one hour > >> + EpochSeconds -= SEC_PER_HOUR; > >> + } > >> + > >> + EpochToEfiTime (EpochSeconds, Time); > >> + > >> // Acquire RTC Lock to make access to RTC atomic > >> if (!EfiAtRuntime ()) { > >> EfiAcquireLock (&mRtcLock); > >> @@ -254,6 +273,43 @@ LibSetTime ( > >> LineNum = __LINE__; > >> goto Exit; > >> } > >> + // Save the current time zone information into non-volatile storage > >> + Status = EfiSetVariable ( > >> + (CHAR16 *)mTimeZoneVariableName, > >> + &gEfiCallerIdGuid, > >> + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, > >> + sizeof (Time->TimeZone), > >> + (VOID *)&(Time->TimeZone) > >> + ); > >> + if (EFI_ERROR (Status)) { > >> + DEBUG (( > >> + DEBUG_ERROR, > >> + "LibSetTime: can not save %s variable to non-volatile storage, Status = %r\n", > >> + mTimeZoneVariableName, > >> + Status > >> + )); > >> + LineNum = __LINE__; > >> + goto Exit; > >> + } > >> + > >> + // Save the current daylight information into non-volatile storage > >> + Status = EfiSetVariable ( > >> + (CHAR16 *)mDaylightVariableName, > >> + &gEfiCallerIdGuid, > >> + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, > >> + sizeof (Time->Daylight), > >> + (VOID *)&(Time->Daylight) > >> + ); > >> + if (EFI_ERROR (Status)) { > >> + DEBUG (( > >> + DEBUG_ERROR, > >> + "LibSetTime: can not to save %s variable to non-volatile storage, Status = %r\n", > >> + mDaylightVariableName, > >> + Status > >> + )); > >> + LineNum = __LINE__; > >> + goto Exit; > >> + } > >> > >> Exit: > >> OemReleaseOwnershipOfRtc (); > >> @@ -295,6 +351,10 @@ LibGetTime ( > >> UINTN LineNum = 0; > >> BOOLEAN IsTimeInvalid = FALSE; > >> UINT8 TimeTemp[7] = {0}; > >> + UINTN EpochSeconds; > >> + INT16 TimeZone; > >> + UINT8 Daylight; > >> + UINTN Size; > >> > >> // Ensure Time is a valid pointer > >> if (Time == NULL) { > >> @@ -336,7 +396,6 @@ LibGetTime ( > >> Time->Hour = BcdToDecimal8 (BcdTime.Hour.Bits.Hours); > >> Time->Minute = BcdToDecimal8 (BcdTime.Minute.Bits.Minutes); > >> Time->Second = BcdToDecimal8 (BcdTime.Second.Bits.Seconds); > >> - Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; > >> > >> if (!IsTimeValid (Time)) { > >> Status = EFI_DEVICE_ERROR; > >> @@ -345,6 +404,120 @@ LibGetTime ( > >> goto Exit; > >> } > >> > >> + EpochSeconds = EfiTimeToEpoch (Time); > >> + > >> + Size = sizeof (TimeZone); > >> + Status = EfiGetVariable ( > >> + (CHAR16 *)mTimeZoneVariableName, > >> + &gEfiCallerIdGuid, > >> + NULL, > >> + &Size, > >> + (VOID *)&TimeZone > >> + ); > >> + > >> + if (EFI_ERROR (Status)) { > >> + DEBUG (( > >> + DEBUG_ERROR, > >> + "LibGetTime: can not get %s variable, Status = %r\n", > >> + mTimeZoneVariableName, > >> + Status > >> + )); > >> + if (Status != EFI_NOT_FOUND) { > >> + LineNum = __LINE__; > >> + goto Exit; > >> + } > >> + > >> + // The time zone variable does not exist in non-volatile storage, so create it. > >> + Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; > >> + // Store it > >> + Status = EfiSetVariable ( > >> + (CHAR16 *)mTimeZoneVariableName, > >> + &gEfiCallerIdGuid, > >> + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, > >> + Size, > >> + (VOID *)&(Time->TimeZone) > >> + ); > >> + > >> + if (EFI_ERROR (Status)) { > >> + DEBUG (( > >> + DEBUG_ERROR, > >> + "LibGetTime: can not save %s variable to non-volatile storage, Status = %r\n", > >> + mTimeZoneVariableName, > >> + Status > >> + )); > >> + LineNum = __LINE__; > >> + goto Exit; > >> + } > >> + } else { > >> + // Got the time zone > >> + Time->TimeZone = TimeZone; > >> + > >> + // Check TimeZone bounds: -1440 to 1440 or 2047 > >> + if (((Time->TimeZone < TIME_ZONE_MIN) || (Time->TimeZone > TIME_ZONE_MAX)) > >> + && (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE)) { > >> + Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; > >> + } > >> + > >> + // Adjust for the correct time zone > >> + if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { > >> + EpochSeconds += Time->TimeZone * SEC_PER_MIN; > >> + } > >> + } > >> + > >> + // Get the current daylight information from non-volatile storage > >> + Size = sizeof (Daylight); > >> + Status = EfiGetVariable ( > >> + (CHAR16 *)mDaylightVariableName, > >> + &gEfiCallerIdGuid, > >> + NULL, > >> + &Size, > >> + (VOID *)&Daylight > >> + ); > >> + > >> + if (EFI_ERROR (Status)) { > >> + DEBUG (( > >> + DEBUG_ERROR, > >> + "LibGetTime: Failed to get %s variable, Status = %r\n", > >> + mDaylightVariableName, > >> + Status > >> + )); > >> + if (Status != EFI_NOT_FOUND) { > >> + goto Exit; > >> + } > >> + // The daylight variable does not exist in non-volatile storage, so create it. > >> + Time->Daylight = 0; > >> + // Store it > >> + Status = EfiSetVariable ( > >> + (CHAR16 *)mDaylightVariableName, > >> + &gEfiCallerIdGuid, > >> + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, > >> + Size, > >> + (VOID *)&(Time->Daylight) > >> + ); > >> + if (EFI_ERROR (Status)) { > >> + DEBUG (( > >> + DEBUG_ERROR, > >> + "LibGetTime: can not save %s variable to non-volatile storage, Status = %r\n", > >> + mDaylightVariableName, > >> + Status > >> + )); > >> + LineNum = __LINE__; > >> + goto Exit; > >> + } > >> + } else { > >> + // Got the daylight information > >> + Time->Daylight = Daylight; > >> + > >> + // Adjust for the correct period > >> + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) { > >> + // Convert to adjusted time, i.e. spring forwards one hour > >> + EpochSeconds += SEC_PER_HOUR; > >> + } > >> + } > >> + > >> + // Convert from internal 32-bit time to UEFI time > >> + EpochToEfiTime (EpochSeconds, Time); > >> + > >> Exit: > >> OemReleaseOwnershipOfRtc (); > >> // Release RTC Lock. > >> -- > >> 2.18.0 > >> _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf index 4e963fd453..8e559d7b70 100644 --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf @@ -42,4 +42,4 @@ UefiRuntimeLib # Use EFiAtRuntime to check stage [Depex] - gEfiCpuArchProtocolGuid + gEfiCpuArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h index f329108858..b95ebc654a 100644 --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h @@ -41,6 +41,10 @@ #define M41T83_REGADDR_ALARM2DATE 0x15 #define M41T83_REGADDR_ALARM2MONTH 0x14 +//UEFI SPEC 2.7,page 295 +#define TIME_ZONE_MIN -1440 +#define TIME_ZONE_MAX 1440 + typedef union { struct { UINT8 TD0:1; diff --git a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c index 1f50ad4b64..a2063aff76 100644 --- a/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c +++ b/Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c @@ -32,6 +32,9 @@ extern I2C_DEVICE gRtcDevice; STATIC EFI_LOCK mRtcLock; +STATIC CONST CHAR16 mTimeZoneVariableName[] = L"M41T83RtcTimeZone"; +STATIC CONST CHAR16 mDaylightVariableName[] = L"M41T83RtcDaylight"; + /** Read RTC content through its registers. @@ -182,6 +185,7 @@ LibSetTime ( RTC_M41T83_TIME BcdTime; UINT16 CenturyBase = 2000; UINTN LineNum = 0; + UINTN EpochSeconds; if (NULL == Time) { return EFI_INVALID_PARAMETER; @@ -206,6 +210,21 @@ LibSetTime ( SetMem (&BcdTime, sizeof (RTC_M41T83_TIME), 0); + EpochSeconds = EfiTimeToEpoch (Time); + + // Adjust for the correct time zone, i.e. convert to UTC time zone + if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { + EpochSeconds -= Time->TimeZone * SEC_PER_MIN; + } + + // Adjust for the correct period + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) { + // Convert to un-adjusted time, i.e. fall back one hour + EpochSeconds -= SEC_PER_HOUR; + } + + EpochToEfiTime (EpochSeconds, Time); + // Acquire RTC Lock to make access to RTC atomic if (!EfiAtRuntime ()) { EfiAcquireLock (&mRtcLock); @@ -254,6 +273,43 @@ LibSetTime ( LineNum = __LINE__; goto Exit; } + // Save the current time zone information into non-volatile storage + Status = EfiSetVariable ( + (CHAR16 *)mTimeZoneVariableName, + &gEfiCallerIdGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (Time->TimeZone), + (VOID *)&(Time->TimeZone) + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "LibSetTime: can not save %s variable to non-volatile storage, Status = %r\n", + mTimeZoneVariableName, + Status + )); + LineNum = __LINE__; + goto Exit; + } + + // Save the current daylight information into non-volatile storage + Status = EfiSetVariable ( + (CHAR16 *)mDaylightVariableName, + &gEfiCallerIdGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (Time->Daylight), + (VOID *)&(Time->Daylight) + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "LibSetTime: can not to save %s variable to non-volatile storage, Status = %r\n", + mDaylightVariableName, + Status + )); + LineNum = __LINE__; + goto Exit; + } Exit: OemReleaseOwnershipOfRtc (); @@ -295,6 +351,10 @@ LibGetTime ( UINTN LineNum = 0; BOOLEAN IsTimeInvalid = FALSE; UINT8 TimeTemp[7] = {0}; + UINTN EpochSeconds; + INT16 TimeZone; + UINT8 Daylight; + UINTN Size; // Ensure Time is a valid pointer if (Time == NULL) { @@ -336,7 +396,6 @@ LibGetTime ( Time->Hour = BcdToDecimal8 (BcdTime.Hour.Bits.Hours); Time->Minute = BcdToDecimal8 (BcdTime.Minute.Bits.Minutes); Time->Second = BcdToDecimal8 (BcdTime.Second.Bits.Seconds); - Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; if (!IsTimeValid (Time)) { Status = EFI_DEVICE_ERROR; @@ -345,6 +404,120 @@ LibGetTime ( goto Exit; } + EpochSeconds = EfiTimeToEpoch (Time); + + Size = sizeof (TimeZone); + Status = EfiGetVariable ( + (CHAR16 *)mTimeZoneVariableName, + &gEfiCallerIdGuid, + NULL, + &Size, + (VOID *)&TimeZone + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "LibGetTime: can not get %s variable, Status = %r\n", + mTimeZoneVariableName, + Status + )); + if (Status != EFI_NOT_FOUND) { + LineNum = __LINE__; + goto Exit; + } + + // The time zone variable does not exist in non-volatile storage, so create it. + Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; + // Store it + Status = EfiSetVariable ( + (CHAR16 *)mTimeZoneVariableName, + &gEfiCallerIdGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + Size, + (VOID *)&(Time->TimeZone) + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "LibGetTime: can not save %s variable to non-volatile storage, Status = %r\n", + mTimeZoneVariableName, + Status + )); + LineNum = __LINE__; + goto Exit; + } + } else { + // Got the time zone + Time->TimeZone = TimeZone; + + // Check TimeZone bounds: -1440 to 1440 or 2047 + if (((Time->TimeZone < TIME_ZONE_MIN) || (Time->TimeZone > TIME_ZONE_MAX)) + && (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE)) { + Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; + } + + // Adjust for the correct time zone + if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { + EpochSeconds += Time->TimeZone * SEC_PER_MIN; + } + } + + // Get the current daylight information from non-volatile storage + Size = sizeof (Daylight); + Status = EfiGetVariable ( + (CHAR16 *)mDaylightVariableName, + &gEfiCallerIdGuid, + NULL, + &Size, + (VOID *)&Daylight + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "LibGetTime: Failed to get %s variable, Status = %r\n", + mDaylightVariableName, + Status + )); + if (Status != EFI_NOT_FOUND) { + goto Exit; + } + // The daylight variable does not exist in non-volatile storage, so create it. + Time->Daylight = 0; + // Store it + Status = EfiSetVariable ( + (CHAR16 *)mDaylightVariableName, + &gEfiCallerIdGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + Size, + (VOID *)&(Time->Daylight) + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "LibGetTime: can not save %s variable to non-volatile storage, Status = %r\n", + mDaylightVariableName, + Status + )); + LineNum = __LINE__; + goto Exit; + } + } else { + // Got the daylight information + Time->Daylight = Daylight; + + // Adjust for the correct period + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) { + // Convert to adjusted time, i.e. spring forwards one hour + EpochSeconds += SEC_PER_HOUR; + } + } + + // Convert from internal 32-bit time to UEFI time + EpochToEfiTime (EpochSeconds, Time); + Exit: OemReleaseOwnershipOfRtc (); // Release RTC Lock.
There is no variable to keep timezone and daylight, so read it from the hardware first and create a new variable to keep it for the next gettime process. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ming Huang <ming.huang@linaro.org> --- Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.inf | 2 +- Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClock.h | 4 + Silicon/Hisilicon/Library/M41T83RealTimeClockLib/M41T83RealTimeClockLib.c | 175 +++++++++++++++++++- 3 files changed, 179 insertions(+), 2 deletions(-) -- 2.18.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel