From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: None (no SPF record) identity=mailfrom; client-ip=2a00:1450:4864:20::52a; helo=mail-ed1-x52a.google.com; envelope-from=pete@akeo.ie; receiver=edk2-devel@lists.01.org Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 7AFC3211CFBC6 for ; Mon, 25 Feb 2019 15:52:17 -0800 (PST) Received: by mail-ed1-x52a.google.com with SMTP id 10so9176751eds.7 for ; Mon, 25 Feb 2019 15:52:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=akeo-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PhpyvRRz0QpejQaR3KmJW3JuyOGXdp/1sGeI1nOQLuY=; b=ksfNZdKqUhy2P0n95DgxB3vI0wAin2cuU5QkHWpgZSrhOh4OVo45aH00WbZFIAw5X5 JQh1Ubd49HHmYjkp0WScikvlQdfT5DtGVPFcrOHe12BqHb9H7NPc8eabeCT/Lwq7vf3+ uW9xEiZkfaV6i4cdi8D4lL7MaATHeRQFsNAYtRhz3CSviGZLx05Gt0eUMFWpOJuKLik4 z+zXQLnfKCooC0mZ8uNNx9NJVqCOACFb58jZPKFLHud91FiP7L2eqLi03ihMbfXu7Jcu qt8ydiQDhDe0J4uPKK4msqti88h7peW7VTUNG/zrJzU6CG5iT7Y5Hi2R0UJ3MOkVDq+N GzwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PhpyvRRz0QpejQaR3KmJW3JuyOGXdp/1sGeI1nOQLuY=; b=l1KaQ1M2oWuRhlCbEQ1/iYXKpQeTEVQw3d7jacG4dmXRhhbFqFoNrBGjuSw5vrJ07u 0BqPq7jD2bkCLehvkI+o4VgDUM66BGptXP8xH6Waaj23e6qTvsbg6NQ8RvyxH3IMubi+ Egz0d50eXfQjMyNfe5Day4dMi+3CxNokUNoVhgfwzY7ShD4SAmoEBbUf5bXBatu3DE3N K5o2A+YE8bJiMgjLpx5aQtlb8DaGhtw51BTgEq9lQxMpeALdA+mle0GIP84D7XLxotAx hqv2MGb2jWcG3WKSY3Zg0/TOJ6WjmvnmfAy0K0/wXZdPM5sjxH4BxMQ9doQyNET5ldGK 8XRg== X-Gm-Message-State: AHQUAub60MpTbGSeQiBGTzgqj46Jgf/Hvclj4Xw4DYVjywq9gNyzNd4d n1A4B5gcLs8QeXFFPm3iLuTiFSXlYbU= X-Google-Smtp-Source: AHgI3IYsPPxO3r1P466K3OhdwHTjgfL2x70mKcxyEwWmIbSjbQS2ucWHHAWTLeceo1URoKnNQsAv7w== X-Received: by 2002:a17:906:3482:: with SMTP id g2mr14591856ejb.242.1551138735564; Mon, 25 Feb 2019 15:52:15 -0800 (PST) Received: from localhost.localdomain ([84.203.58.139]) by smtp.gmail.com with ESMTPSA id p47sm3006001eda.31.2019.02.25.15.52.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 15:52:14 -0800 (PST) From: Pete Batard To: edk2-devel@lists.01.org Date: Mon, 25 Feb 2019 23:52:02 +0000 Message-Id: <20190225235202.2252-2-pete@akeo.ie> X-Mailer: git-send-email 2.17.0.windows.1 In-Reply-To: <20190225235202.2252-1-pete@akeo.ie> References: <20190225235202.2252-1-pete@akeo.ie> Subject: [PATCH 1/1] EmbeddedPkg: Fix multiple Virtual RTC issues X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Feb 2019 23:52:17 -0000 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 --- 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