\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