The cached copy gRT of SystemTable->RuntimeServices is not updated by SetVirtualAddressMap (), which prevent us from using the RTC under the OS, as we call [Get|Set]Variable() through gRT at runtime.
Replace gRT with mRT, which we update ourselves on a virtual address change event. Signed-off-by: Ard Biesheuvel <[email protected]> --- This is likely the wrong way to address this, hence the 'RFC' but it is required for the RTC to be usable under Linux after installing the virtual address map. It appears that the cached copy gRT (owned by UefiRuntimeServicesTableLib) is not wired up the virtual address change event, which results in us dereferencing the physical address of the runtime services table. The contents themselves have been converted, just not the value of gRT. If there is a 'proper' way to deal with this (or just a better one), I would love to hear about it. Cheers, Ard. .../PL031RealTimeClockLib/PL031RealTimeClockLib.c | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c index b43d8dc4ba2f..56204881ce86 100644 --- a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c +++ b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c @@ -40,11 +40,12 @@ #include <ArmPlatform.h> -STATIC CONST CHAR16 mTimeZoneVariableName[] = L"PL031RtcTimeZone"; -STATIC CONST CHAR16 mDaylightVariableName[] = L"PL031RtcDaylight"; -STATIC BOOLEAN mPL031Initialized = FALSE; -STATIC EFI_EVENT mRtcVirtualAddrChangeEvent; -STATIC UINTN mPL031RtcBase; +STATIC CONST CHAR16 mTimeZoneVariableName[] = L"PL031RtcTimeZone"; +STATIC CONST CHAR16 mDaylightVariableName[] = L"PL031RtcDaylight"; +STATIC BOOLEAN mPL031Initialized = FALSE; +STATIC EFI_EVENT mRtcVirtualAddrChangeEvent; +STATIC UINTN mPL031RtcBase; +STATIC EFI_RUNTIME_SERVICES *mRT; EFI_STATUS IdentifyPL031 ( @@ -294,7 +295,7 @@ LibGetTime ( // Get the current time zone information from non-volatile storage Size = sizeof (TimeZone); - Status = gRT->GetVariable ( + Status = mRT->GetVariable ( (CHAR16 *)mTimeZoneVariableName, &gEfiCallerIdGuid, NULL, @@ -312,7 +313,7 @@ LibGetTime ( // The time zone variable does not exist in non-volatile storage, so create it. Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; // Store it - Status = gRT->SetVariable ( + Status = mRT->SetVariable ( (CHAR16 *)mTimeZoneVariableName, &gEfiCallerIdGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, @@ -346,7 +347,7 @@ LibGetTime ( // Get the current daylight information from non-volatile storage Size = sizeof (Daylight); - Status = gRT->GetVariable ( + Status = mRT->GetVariable ( (CHAR16 *)mDaylightVariableName, &gEfiCallerIdGuid, NULL, @@ -364,7 +365,7 @@ LibGetTime ( // The daylight variable does not exist in non-volatile storage, so create it. Time->Daylight = 0; // Store it - Status = gRT->SetVariable ( + Status = mRT->SetVariable ( (CHAR16 *)mDaylightVariableName, &gEfiCallerIdGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, @@ -498,7 +499,7 @@ LibSetTime ( // Do this after having set the RTC. // Save the current time zone information into non-volatile storage - Status = gRT->SetVariable ( + Status = mRT->SetVariable ( (CHAR16 *)mTimeZoneVariableName, &gEfiCallerIdGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, @@ -516,7 +517,7 @@ LibSetTime ( } // Save the current daylight information into non-volatile storage - Status = gRT->SetVariable ( + Status = mRT->SetVariable ( (CHAR16 *)mDaylightVariableName, &gEfiCallerIdGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, @@ -609,6 +610,7 @@ LibRtcVirtualNotifyEvent ( // runtime calls will be made in virtual mode. // EfiConvertPointer (0x0, (VOID**)&mPL031RtcBase); + EfiConvertPointer (0x0, (VOID**)&mRT); return; } @@ -656,6 +658,8 @@ LibRtcInitialize ( gRT->GetWakeupTime = LibGetWakeupTime; gRT->SetWakeupTime = LibSetWakeupTime; + mRT = gRT; + // Install the protocol Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( -- 1.8.3.2 ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/ _______________________________________________ edk2-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/edk2-devel
