On Tue, 26 Feb 2019 at 00:52, Pete Batard <p...@akeo.ie> wrote: > > LibGetTime(): > - Two variables were used for the epoch, where only one should have been. > - Also harmonize variable name to match the one used in LibSetTime. > LiBSetTime(): > - Address possible underflows if time is set to start of epoch. > - Ensure that time being read does actually match time that was manually > set (plus the time elapsed since), by subtracting number of seconds > since reset. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Pete Batard <p...@akeo.ie>
Thanks Pete Reviewed-by: Ard Biesheuvel <ard.biesheu...@linaro.org> Pushed as 9ab4ec518882..1342d7679e10 > --- > EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c | 34 > ++++++++++++++------ > 1 file changed, 25 insertions(+), 9 deletions(-) > > diff --git > a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c > b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c > index 4c354730d02b..5559106b696f 100644 > --- a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c > +++ b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c > @@ -54,13 +54,12 @@ LibGetTime ( > ) > { > EFI_STATUS Status; > - UINT32 EpochSeconds; > INT16 TimeZone; > UINT8 Daylight; > UINT64 Freq; > UINT64 Counter; > UINT64 Remainder; > - UINTN ElapsedSeconds; > + UINTN EpochSeconds; > UINTN Size; > > if (Time == NULL) { > @@ -75,13 +74,13 @@ LibGetTime ( > > // Get the epoch time from non-volatile storage > Size = sizeof (UINTN); > - ElapsedSeconds = 0; > + EpochSeconds = 0; > Status = EfiGetVariable ( > (CHAR16 *)mEpochVariableName, > &gEfiCallerIdGuid, > NULL, > &Size, > - (VOID *)&ElapsedSeconds > + (VOID *)&EpochSeconds > ); > // Fall back to compilation-time epoch if not set > if (EFI_ERROR (Status)) { > @@ -93,7 +92,7 @@ LibGetTime ( > // If you are attempting to use this library on such an environment, > please > // contact the edk2 mailing list, so we can try to add support for it. > // > - ElapsedSeconds = BUILD_EPOCH; > + EpochSeconds = BUILD_EPOCH; > DEBUG (( > DEBUG_INFO, > "LibGetTime: %s non volatile variable was not found - Using > compilation time epoch.\n", > @@ -101,7 +100,7 @@ LibGetTime ( > )); > } > Counter = GetPerformanceCounter (); > - ElapsedSeconds += DivU64x64Remainder (Counter, Freq, &Remainder); > + EpochSeconds += DivU64x64Remainder (Counter, Freq, &Remainder); > > // Get the current time zone information from non-volatile storage > Size = sizeof (TimeZone); > @@ -204,7 +203,7 @@ LibGetTime ( > } > } > > - EpochToEfiTime (ElapsedSeconds, Time); > + EpochToEfiTime (EpochSeconds, Time); > > // Because we use the performance counter, we can fill the Nanosecond > attribute > // provided that the remainder doesn't overflow 64-bit during > multiplication. > @@ -240,6 +239,9 @@ LibSetTime ( > ) > { > EFI_STATUS Status; > + UINT64 Freq; > + UINT64 Counter; > + UINT64 Remainder; > UINTN EpochSeconds; > > if (!IsTimeValid (Time)) { > @@ -249,16 +251,30 @@ LibSetTime ( > EpochSeconds = EfiTimeToEpoch (Time); > > // Adjust for the correct time zone, i.e. convert to UTC time zone > - if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) { > + if ((Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) > + && (EpochSeconds > Time->TimeZone * SEC_PER_MIN)) { > EpochSeconds -= Time->TimeZone * SEC_PER_MIN; > } > > // Adjust for the correct period > - if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) { > + if (((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) > + && (EpochSeconds > SEC_PER_HOUR)) { > // Convert to un-adjusted time, i.e. fall back one hour > EpochSeconds -= SEC_PER_HOUR; > } > > + // Use the performance counter to substract the number of seconds > + // since platform reset. Without this, setting time from the shell > + // and immediately reading it back would result in a forward time > + // offset, of the duration during which the platform has been up. > + Freq = GetPerformanceCounterProperties (NULL, NULL); > + if (Freq != 0) { > + Counter = GetPerformanceCounter (); > + if (EpochSeconds > DivU64x64Remainder (Counter, Freq, &Remainder)) { > + EpochSeconds -= DivU64x64Remainder (Counter, Freq, &Remainder); > + } > + } > + > // Save the current time zone information into non-volatile storage > Status = EfiSetVariable ( > (CHAR16 *)mTimeZoneVariableName, > -- > 2.17.0.windows.1 > _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel