]> git.proxmox.com Git - mirror_edk2.git/blobdiff - PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c
PcAtChipsetPkg: Add MMIO Support to RTC driver
[mirror_edk2.git] / PcAtChipsetPkg / PcatRealTimeClockRuntimeDxe / PcRtcEntry.c
index ccda6331373bfe4069b0a59495b5e5cc731c8fc8..606b88adafb7ef5d81e32e212794a5ccae9d0443 100644 (file)
@@ -2,16 +2,23 @@
   Provides Set/Get time operations.\r
 \r
 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.<BR>\r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
+#include <Library/DxeServicesTableLib.h>\r
 #include "PcRtc.h"\r
 \r
 PC_RTC_MODULE_GLOBALS  mModuleGlobal;\r
 \r
 EFI_HANDLE             mHandle = NULL;\r
 \r
+STATIC EFI_EVENT       mVirtualAddrChangeEvent;\r
+\r
+UINTN                  mRtcIndexRegister;\r
+UINTN                  mRtcTargetRegister;\r
+\r
 /**\r
   Returns the current time and date information, and the time-keeping capabilities\r
   of the hardware platform.\r
@@ -105,6 +112,30 @@ PcRtcEfiSetWakeupTime (
   return PcRtcSetWakeupTime (Enabled, Time, &mModuleGlobal);\r
 }\r
 \r
+/**\r
+  Fixup internal data so that EFI can be called in virtual mode.\r
+  Call the passed in Child Notify event and convert any pointers in\r
+  lib to virtual mode.\r
+\r
+  @param[in]    Event   The Event that is being processed\r
+  @param[in]    Context Event Context\r
+**/\r
+VOID\r
+EFIAPI\r
+LibRtcVirtualNotifyEvent (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+{\r
+  // Only needed if you are going to support the OS calling RTC functions in\r
+  // virtual mode. You will need to call EfiConvertPointer (). To convert any\r
+  // stored physical addresses to virtual address. After the OS transitions to\r
+  // calling in virtual mode, all future runtime calls will be made in virtual\r
+  // mode.\r
+  EfiConvertPointer (0x0, (VOID**)&mRtcIndexRegister);\r
+  EfiConvertPointer (0x0, (VOID**)&mRtcTargetRegister);\r
+}\r
+\r
 /**\r
   The user Entry Point for PcRTC module.\r
 \r
@@ -131,6 +162,11 @@ InitializePcRtc (
   EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_CALLBACK);\r
   mModuleGlobal.CenturyRtcAddress = GetCenturyRtcAddress ();\r
 \r
+  if (FeaturePcdGet (PcdRtcUseMmio)) {\r
+    mRtcIndexRegister = (UINTN)PcdGet64 (PcdRtcIndexRegister64);\r
+    mRtcTargetRegister = (UINTN)PcdGet64 (PcdRtcTargetRegister64);\r
+  }\r
+\r
   Status = PcRtcInit (&mModuleGlobal);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
@@ -165,7 +201,23 @@ InitializePcRtc (
                   NULL,\r
                   NULL\r
                   );\r
-  ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT_EFI_ERROR (Status);\r
+    return Status;\r
+  }\r
+\r
+  if (FeaturePcdGet (PcdRtcUseMmio)) {\r
+    // Register for the virtual address change event\r
+    Status = gBS->CreateEventEx (\r
+                    EVT_NOTIFY_SIGNAL,\r
+                    TPL_NOTIFY,\r
+                    LibRtcVirtualNotifyEvent,\r
+                    NULL,\r
+                    &gEfiEventVirtualAddressChangeGuid,\r
+                    &mVirtualAddrChangeEvent\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
 \r
   return Status;\r
 }\r