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

Reply via email to