]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPlatformPkg/PL031RealTimeClock: Fixed driver to support UEFI Runtime Services
authorOlivier Martin <olivier.martin@arm.com>
Tue, 8 Apr 2014 17:59:00 +0000 (17:59 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 8 Apr 2014 17:59:00 +0000 (17:59 +0000)
- Removed PCD base address from the macro definition. The base address needs to be fixup when the driver runs in UEFI Runtime mode
- Added the PL031 controller memory region to the Runtime UEFI Memory Mapped IO
- Caught the gEfiEventVirtualAddressChangeGuid event to fixup the PL031 Base address

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15435 6f19259b-4bc3-4df7-8a09-765794883524

ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h
ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf

index 4c559c0c952bbe75f39cc9be3b2ddfb6816635ac..76fbd0eb8225f68f3867a42a36adfcf9f52c85c1 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
 /** @file\r
 *\r
-*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.\r
 *\r
 *  This program and the accompanying materials\r
 *  are licensed and made available under the terms and conditions of the BSD License\r
 *\r
 *  This program and the accompanying materials\r
 *  are licensed and made available under the terms and conditions of the BSD License\r
 #define __PL031_REAL_TIME_CLOCK_H__\r
 \r
 // PL031 Registers\r
 #define __PL031_REAL_TIME_CLOCK_H__\r
 \r
 // PL031 Registers\r
-#define PL031_RTC_DR_DATA_REGISTER                      ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x000)\r
-#define PL031_RTC_MR_MATCH_REGISTER                     ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x004)\r
-#define PL031_RTC_LR_LOAD_REGISTER                      ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x008)\r
-#define PL031_RTC_CR_CONTROL_REGISTER                   ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x00C)\r
-#define PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER      ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x010)\r
-#define PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER           ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x014)\r
-#define PL031_RTC_MIS_MASKED_IRQ_STATUS_REGISTER        ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x018)\r
-#define PL031_RTC_ICR_IRQ_CLEAR_REGISTER                ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x01C)\r
-#define PL031_RTC_PERIPH_ID0                            ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFE0)\r
-#define PL031_RTC_PERIPH_ID1                            ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFE4)\r
-#define PL031_RTC_PERIPH_ID2                            ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFE8)\r
-#define PL031_RTC_PERIPH_ID3                            ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFEC)\r
-#define PL031_RTC_PCELL_ID0                             ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFF0)\r
-#define PL031_RTC_PCELL_ID1                             ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFF4)\r
-#define PL031_RTC_PCELL_ID2                             ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFF8)\r
-#define PL031_RTC_PCELL_ID3                             ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFFC)\r
+#define PL031_RTC_DR_DATA_REGISTER                      0x000\r
+#define PL031_RTC_MR_MATCH_REGISTER                     0x004\r
+#define PL031_RTC_LR_LOAD_REGISTER                      0x008\r
+#define PL031_RTC_CR_CONTROL_REGISTER                   0x00C\r
+#define PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER      0x010\r
+#define PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER           0x014\r
+#define PL031_RTC_MIS_MASKED_IRQ_STATUS_REGISTER        0x018\r
+#define PL031_RTC_ICR_IRQ_CLEAR_REGISTER                0x01C\r
+#define PL031_RTC_PERIPH_ID0                            0xFE0\r
+#define PL031_RTC_PERIPH_ID1                            0xFE4\r
+#define PL031_RTC_PERIPH_ID2                            0xFE8\r
+#define PL031_RTC_PERIPH_ID3                            0xFEC\r
+#define PL031_RTC_PCELL_ID0                             0xFF0\r
+#define PL031_RTC_PCELL_ID1                             0xFF4\r
+#define PL031_RTC_PCELL_ID2                             0xFF8\r
+#define PL031_RTC_PCELL_ID3                             0xFFC\r
 \r
 // PL031 Values\r
 #define PL031_RTC_ENABLED                               0x00000001\r
 \r
 // PL031 Values\r
 #define PL031_RTC_ENABLED                               0x00000001\r
index 980f809b2c6ccbc5832030144906dc1bedbb6bc6..b43d8dc4ba2fd69dda62aff22e230fbf96849d95 100644 (file)
@@ -4,7 +4,7 @@
   Currently this driver does not support runtime virtual calling.\r
 \r
   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
   Currently this driver does not support runtime virtual calling.\r
 \r
   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
-  Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>\r
+  Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/ArmPlatformSysConfigLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/ArmPlatformSysConfigLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiRuntimeLib.h>\r
+\r
 #include <Protocol/RealTimeClock.h>\r
 #include <Protocol/RealTimeClock.h>\r
+\r
 #include <Guid/GlobalVariable.h>\r
 #include <Guid/GlobalVariable.h>\r
+#include <Guid/EventGroup.h>\r
+\r
 #include <Drivers/PL031RealTimeClock.h>\r
 \r
 #include <ArmPlatform.h>\r
 #include <Drivers/PL031RealTimeClock.h>\r
 \r
 #include <ArmPlatform.h>\r
@@ -37,6 +43,8 @@
 STATIC CONST CHAR16  mTimeZoneVariableName[] = L"PL031RtcTimeZone";\r
 STATIC CONST CHAR16  mDaylightVariableName[] = L"PL031RtcDaylight";\r
 STATIC BOOLEAN       mPL031Initialized = FALSE;\r
 STATIC CONST CHAR16  mTimeZoneVariableName[] = L"PL031RtcTimeZone";\r
 STATIC CONST CHAR16  mDaylightVariableName[] = L"PL031RtcDaylight";\r
 STATIC BOOLEAN       mPL031Initialized = FALSE;\r
+STATIC EFI_EVENT     mRtcVirtualAddrChangeEvent;\r
+STATIC UINTN         mPL031RtcBase;\r
 \r
 EFI_STATUS\r
 IdentifyPL031 (\r
 \r
 EFI_STATUS\r
 IdentifyPL031 (\r
@@ -46,19 +54,19 @@ IdentifyPL031 (
   EFI_STATUS    Status;\r
 \r
   // Check if this is a PrimeCell Peripheral\r
   EFI_STATUS    Status;\r
 \r
   // Check if this is a PrimeCell Peripheral\r
-  if (  (MmioRead8 (PL031_RTC_PCELL_ID0) != 0x0D)\r
-      || (MmioRead8 (PL031_RTC_PCELL_ID1) != 0xF0)\r
-      || (MmioRead8 (PL031_RTC_PCELL_ID2) != 0x05)\r
-      || (MmioRead8 (PL031_RTC_PCELL_ID3) != 0xB1)) {\r
+  if (  (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID0) != 0x0D)\r
+      || (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID1) != 0xF0)\r
+      || (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID2) != 0x05)\r
+      || (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID3) != 0xB1)) {\r
     Status = EFI_NOT_FOUND;\r
     goto EXIT;\r
   }\r
 \r
   // Check if this PrimeCell Peripheral is the PL031 Real Time Clock\r
     Status = EFI_NOT_FOUND;\r
     goto EXIT;\r
   }\r
 \r
   // Check if this PrimeCell Peripheral is the PL031 Real Time Clock\r
-  if (  (MmioRead8 (PL031_RTC_PERIPH_ID0) != 0x31)\r
-      || (MmioRead8 (PL031_RTC_PERIPH_ID1) != 0x10)\r
-      || ((MmioRead8 (PL031_RTC_PERIPH_ID2) & 0xF) != 0x04)\r
-      || (MmioRead8 (PL031_RTC_PERIPH_ID3) != 0x00)) {\r
+  if (  (MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID0) != 0x31)\r
+      || (MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID1) != 0x10)\r
+      || ((MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID2) & 0xF) != 0x04)\r
+      || (MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID3) != 0x00)) {\r
     Status = EFI_NOT_FOUND;\r
     goto EXIT;\r
   }\r
     Status = EFI_NOT_FOUND;\r
     goto EXIT;\r
   }\r
@@ -83,18 +91,18 @@ InitializePL031 (
   }\r
 \r
   // Ensure interrupts are masked. We do not want RTC interrupts in UEFI\r
   }\r
 \r
   // Ensure interrupts are masked. We do not want RTC interrupts in UEFI\r
-  if ((MmioRead32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER) & PL031_SET_IRQ_MASK) != PL031_SET_IRQ_MASK) {\r
-    MmioOr32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER, PL031_SET_IRQ_MASK);\r
+  if ((MmioRead32 (mPL031RtcBase + PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER) & PL031_SET_IRQ_MASK) != PL031_SET_IRQ_MASK) {\r
+    MmioOr32 (mPL031RtcBase + PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER, PL031_SET_IRQ_MASK);\r
   }\r
 \r
   // Clear any existing interrupts\r
   }\r
 \r
   // Clear any existing interrupts\r
-  if ((MmioRead32 (PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER) & PL031_IRQ_TRIGGERED) == PL031_IRQ_TRIGGERED) {\r
-    MmioOr32 (PL031_RTC_ICR_IRQ_CLEAR_REGISTER, PL031_CLEAR_IRQ);\r
+  if ((MmioRead32 (mPL031RtcBase + PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER) & PL031_IRQ_TRIGGERED) == PL031_IRQ_TRIGGERED) {\r
+    MmioOr32 (mPL031RtcBase + PL031_RTC_ICR_IRQ_CLEAR_REGISTER, PL031_CLEAR_IRQ);\r
   }\r
 \r
   // Start the clock counter\r
   }\r
 \r
   // Start the clock counter\r
-  if ((MmioRead32 (PL031_RTC_CR_CONTROL_REGISTER) & PL031_RTC_ENABLED) != PL031_RTC_ENABLED) {\r
-    MmioOr32 (PL031_RTC_CR_CONTROL_REGISTER, PL031_RTC_ENABLED);\r
+  if ((MmioRead32 (mPL031RtcBase + PL031_RTC_CR_CONTROL_REGISTER) & PL031_RTC_ENABLED) != PL031_RTC_ENABLED) {\r
+    MmioOr32 (mPL031RtcBase + PL031_RTC_CR_CONTROL_REGISTER, PL031_RTC_ENABLED);\r
   }\r
 \r
   mPL031Initialized = TRUE;\r
   }\r
 \r
   mPL031Initialized = TRUE;\r
@@ -267,7 +275,7 @@ LibGetTime (
   Status = ArmPlatformSysConfigGet (SYS_CFG_RTC, &EpochSeconds);\r
   if (Status == EFI_UNSUPPORTED) {\r
     // Battery backed up hardware RTC does not exist, revert to PL031\r
   Status = ArmPlatformSysConfigGet (SYS_CFG_RTC, &EpochSeconds);\r
   if (Status == EFI_UNSUPPORTED) {\r
     // Battery backed up hardware RTC does not exist, revert to PL031\r
-    EpochSeconds = MmioRead32 (PL031_RTC_DR_DATA_REGISTER);\r
+    EpochSeconds = MmioRead32 (mPL031RtcBase + PL031_RTC_DR_DATA_REGISTER);\r
     Status = EFI_SUCCESS;\r
   } else if (EFI_ERROR (Status)) {\r
     // Battery backed up hardware RTC exists but could not be read due to error. Abort.\r
     Status = EFI_SUCCESS;\r
   } else if (EFI_ERROR (Status)) {\r
     // Battery backed up hardware RTC exists but could not be read due to error. Abort.\r
@@ -275,7 +283,7 @@ LibGetTime (
   } else {\r
     // Battery backed up hardware RTC exists and we read the time correctly from it.\r
     // Now sync the PL031 to the new time.\r
   } else {\r
     // Battery backed up hardware RTC exists and we read the time correctly from it.\r
     // Now sync the PL031 to the new time.\r
-    MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);\r
+    MmioWrite32 (mPL031RtcBase + PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);\r
   }\r
 \r
   // Ensure Time is a valid pointer\r
   }\r
 \r
   // Ensure Time is a valid pointer\r
@@ -484,7 +492,7 @@ LibSetTime (
 \r
 \r
   // Set the PL031\r
 \r
 \r
   // Set the PL031\r
-  MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);\r
+  MmioWrite32 (mPL031RtcBase + PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);\r
 \r
   // The accesses to Variable Services can be very slow, because we may be writing to Flash.\r
   // Do this after having set the RTC.\r
 \r
   // The accesses to Variable Services can be very slow, because we may be writing to Flash.\r
   // Do this after having set the RTC.\r
@@ -579,7 +587,30 @@ LibSetWakeupTime (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
+/**\r
+  Fixup internal data so that EFI can be call in virtual mode.\r
+  Call the passed in Child Notify event and convert any pointers in\r
+  lib to virtual mode.\r
 \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
+  //\r
+  // Only needed if you are going to support the OS calling RTC functions in virtual mode.\r
+  // You will need to call EfiConvertPointer (). To convert any stored physical addresses\r
+  // to virtual address. After the OS transitions to calling in virtual mode, all future\r
+  // runtime calls will be made in virtual mode.\r
+  //\r
+  EfiConvertPointer (0x0, (VOID**)&mPL031RtcBase);\r
+  return;\r
+}\r
 \r
 /**\r
   This is the declaration of an EFI image entry point. This can be the entry point to an application\r
 \r
 /**\r
   This is the declaration of an EFI image entry point. This can be the entry point to an application\r
@@ -601,6 +632,24 @@ LibRtcInitialize (
   EFI_STATUS    Status;\r
   EFI_HANDLE    Handle;\r
 \r
   EFI_STATUS    Status;\r
   EFI_HANDLE    Handle;\r
 \r
+  // Initialize RTC Base Address\r
+  mPL031RtcBase = PcdGet32 (PcdPL031RtcBase);\r
+\r
+  // Declare the controller as EFI_MEMORY_RUNTIME\r
+  Status = gDS->AddMemorySpace (\r
+                  EfiGcdMemoryTypeMemoryMappedIo,\r
+                  mPL031RtcBase, SIZE_4KB,\r
+                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = gDS->SetMemorySpaceAttributes (mPL031RtcBase, SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   // Setup the setters and getters\r
   gRT->GetTime       = LibGetTime;\r
   gRT->SetTime       = LibSetTime;\r
   // Setup the setters and getters\r
   gRT->GetTime       = LibGetTime;\r
   gRT->SetTime       = LibSetTime;\r
@@ -614,31 +663,20 @@ LibRtcInitialize (
                   &gEfiRealTimeClockArchProtocolGuid,  NULL,\r
                   NULL\r
                  );\r
                   &gEfiRealTimeClockArchProtocolGuid,  NULL,\r
                   NULL\r
                  );\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
 \r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Fixup internal data so that EFI can be call 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
   //\r
   //\r
-  // Only needed if you are going to support the OS calling RTC functions in virtual mode.\r
-  // You will need to call EfiConvertPointer (). To convert any stored physical addresses\r
-  // to virtual address. After the OS transitions to calling in virtual mode, all future\r
-  // runtime calls will be made in virtual mode.\r
+  // Register for the virtual address change event\r
   //\r
   //\r
-  return;\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  LibRtcVirtualNotifyEvent,\r
+                  NULL,\r
+                  &gEfiEventVirtualAddressChangeGuid,\r
+                  &mRtcVirtualAddrChangeEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
 }\r
 }\r
index add982ce8e4b442819ccbaddc3eeba00d51c5b4c..3a98fc757e3df8a3e5bd3f8dd86433a63822dfb5 100644 (file)
@@ -1,7 +1,7 @@
 #/** @file\r
 #\r
 # Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
 #/** @file\r
 #\r
 # Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-# Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>\r
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
   DebugLib\r
   PcdLib\r
   ArmPlatformSysConfigLib\r
   DebugLib\r
   PcdLib\r
   ArmPlatformSysConfigLib\r
+  DxeServicesTableLib\r
+  UefiRuntimeLib\r
+\r
+[Guids]\r
+  gEfiEventVirtualAddressChangeGuid\r
 \r
 [Pcd]\r
   gArmPlatformTokenSpaceGuid.PcdPL031RtcBase\r
 \r
 [Pcd]\r
   gArmPlatformTokenSpaceGuid.PcdPL031RtcBase\r