#\r
# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
# Copyright (c) 2017, AMD Inc. All rights reserved.<BR>\r
+# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.<BR>\r
#\r
# SPDX-License-Identifier: BSD-2-Clause-Patent\r
#\r
# @Prompt Configure HPET to use MSI.\r
gPcAtChipsetPkgTokenSpaceGuid.PcdHpetMsiEnable|TRUE|BOOLEAN|0x00001000\r
\r
+ ## Indicates the RTC port registers are in MMIO space, or in I/O space.\r
+ # Default is I/O space.<BR><BR>\r
+ # TRUE - RTC port registers are in MMIO space.<BR>\r
+ # FALSE - RTC port registers are in I/O space.<BR>\r
+ # @Prompt RTC port registers use MMIO.\r
+ gPcAtChipsetPkgTokenSpaceGuid.PcdRtcUseMmio|FALSE|BOOLEAN|0x00000021\r
+\r
[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule]\r
## This PCD specifies the base address of the HPET timer.\r
# @Prompt HPET base address.\r
# @Expression 0x80000001 | gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear < gPcAtChipsetPkgTokenSpaceGuid.PcdMinimalValidYear + 100\r
gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear|2097|UINT16|0x0000000E\r
\r
+ ## Specifies RTC Index Register address in MMIO space.\r
+ # @Prompt RTC Index Register address\r
+ gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister64|0x0|UINT64|0x00000022\r
+\r
+ ## Specifies RTC Target Register address in MMIO space.\r
+ # @Prompt RTC Target Register address\r
+ gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister64|0x0|UINT64|0x00000023\r
+\r
[PcdsFixedAtBuild, PcdsPatchableInModule]\r
## Defines the ACPI register set base address.\r
# The invalid 0xFFFF is as its default value. It must be configured to the real value.\r
\r
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2017, AMD Inc. All rights reserved.<BR>\r
+Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
\r
#include "PcRtc.h"\r
\r
+extern UINTN mRtcIndexRegister;\r
+extern UINTN mRtcTargetRegister;\r
+\r
//\r
// Days of month.\r
//\r
IN EFI_TIME *To\r
);\r
\r
+/**\r
+ Read RTC content through its registers using IO access.\r
+\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+\r
+ @return The data of UINT8 type read from RTC.\r
+**/\r
+STATIC\r
+UINT8\r
+IoRtcRead (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ IoWrite8 (\r
+ PcdGet8 (PcdRtcIndexRegister),\r
+ (UINT8)(Address | (UINT8)(IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80))\r
+ );\r
+ return IoRead8 (PcdGet8 (PcdRtcTargetRegister));\r
+}\r
+\r
+/**\r
+ Write RTC through its registers using IO access.\r
+\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+ @param Data The content you want to write into RTC.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+IoRtcWrite (\r
+ IN UINTN Address,\r
+ IN UINT8 Data\r
+ )\r
+{\r
+ IoWrite8 (\r
+ PcdGet8 (PcdRtcIndexRegister),\r
+ (UINT8)(Address | (UINT8)(IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80))\r
+ );\r
+ IoWrite8 (PcdGet8 (PcdRtcTargetRegister), Data);\r
+}\r
+\r
+/**\r
+ Read RTC content through its registers using MMIO access.\r
+\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+\r
+ @return The data of UINT8 type read from RTC.\r
+**/\r
+STATIC\r
+UINT8\r
+MmioRtcRead (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ MmioWrite8 (\r
+ mRtcIndexRegister,\r
+ (UINT8)(Address | (UINT8)(MmioRead8 (mRtcIndexRegister) & 0x80))\r
+ );\r
+ return MmioRead8 (mRtcTargetRegister);\r
+}\r
+\r
+/**\r
+ Write RTC through its registers using MMIO access.\r
+\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+ @param Data The content you want to write into RTC.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+MmioRtcWrite (\r
+ IN UINTN Address,\r
+ IN UINT8 Data\r
+ )\r
+{\r
+ MmioWrite8 (\r
+ mRtcIndexRegister,\r
+ (UINT8)(Address | (UINT8)(MmioRead8 (mRtcIndexRegister) & 0x80))\r
+ );\r
+ MmioWrite8 (mRtcTargetRegister, Data);\r
+}\r
+\r
/**\r
Read RTC content through its registers.\r
\r
- @param Address Address offset of RTC. It is recommended to use macros such as\r
- RTC_ADDRESS_SECONDS.\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
\r
@return The data of UINT8 type read from RTC.\r
**/\r
+STATIC\r
UINT8\r
RtcRead (\r
- IN UINT8 Address\r
+ IN UINTN Address\r
)\r
{\r
- IoWrite8 (PcdGet8 (PcdRtcIndexRegister), (UINT8) (Address | (UINT8) (IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80)));\r
- return IoRead8 (PcdGet8 (PcdRtcTargetRegister));\r
+ if (FeaturePcdGet (PcdRtcUseMmio)) {\r
+ return MmioRtcRead (Address);\r
+ }\r
+\r
+ return IoRtcRead (Address);\r
}\r
\r
/**\r
Write RTC through its registers.\r
\r
- @param Address Address offset of RTC. It is recommended to use macros such as\r
- RTC_ADDRESS_SECONDS.\r
- @param Data The content you want to write into RTC.\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+ @param Data The content you want to write into RTC.\r
\r
**/\r
+STATIC\r
VOID\r
RtcWrite (\r
- IN UINT8 Address,\r
+ IN UINTN Address,\r
IN UINT8 Data\r
)\r
{\r
- IoWrite8 (PcdGet8 (PcdRtcIndexRegister), (UINT8) (Address | (UINT8) (IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80)));\r
- IoWrite8 (PcdGet8 (PcdRtcTargetRegister), Data);\r
+ if (FeaturePcdGet (PcdRtcUseMmio)) {\r
+ MmioRtcWrite (Address, Data);\r
+ } else {\r
+ IoRtcWrite (Address, Data);\r
+ }\r
}\r
\r
/**\r
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
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
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
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
#\r
# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
# Copyright (c) 2017, AMD Inc. All rights reserved.<BR>\r
+# Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.<BR>\r
#\r
# SPDX-License-Identifier: BSD-2-Clause-Patent\r
#\r
## SOMETIMES_CONSUMES ## SystemTable\r
gEfiAcpiTableGuid\r
\r
+ gEfiEventVirtualAddressChangeGuid\r
+\r
+[FeaturePcd]\r
+ gPcAtChipsetPkgTokenSpaceGuid.PcdRtcUseMmio ## CONSUMES\r
+\r
[FixedPcd]\r
gPcAtChipsetPkgTokenSpaceGuid.PcdInitialValueRtcRegisterA ## CONSUMES\r
gPcAtChipsetPkgTokenSpaceGuid.PcdInitialValueRtcRegisterB ## CONSUMES\r
gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear ## CONSUMES\r
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister ## CONSUMES\r
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister ## CONSUMES\r
+ gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister64 ## CONSUMES\r
+ gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister64 ## CONSUMES\r
\r
[Depex]\r
gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid\r