summaryrefslogtreecommitdiffstats
path: root/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
diff options
context:
space:
mode:
authorSami Mujawar <sami.mujawar@arm.com>2020-10-02 22:13:55 +0100
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-10-16 17:21:04 +0000
commit015be4075f6cfef03bc08c0e3eb7286dd80c8e8b (patch)
tree10a8b77cdf5f508a8218a456236c404a2c9e053e /PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
parenta7d977040bd82b89d1fe5ef32d488bfd10db2dbc (diff)
downloadedk2-015be4075f6cfef03bc08c0e3eb7286dd80c8e8b.tar.gz
edk2-015be4075f6cfef03bc08c0e3eb7286dd80c8e8b.tar.bz2
edk2-015be4075f6cfef03bc08c0e3eb7286dd80c8e8b.zip
PcAtChipsetPkg: Add MMIO Support to RTC driver
Some virtual machine managers like Kvmtool emulate the MC146818 RTC controller in the MMIO space so that architectures that do not support I/O Mapped I/O can use the RTC. This patch adds MMIO support to the RTC controller driver. The PCD PcdRtcUseMmio has been added to select I/O or MMIO support. If PcdRtcUseMmio is: TRUE - Indicates the RTC port registers are in MMIO space. FALSE - Indicates the RTC port registers are in I/O space. Default is I/O space. Additionally two new PCDs PcdRtcIndexRegister64 and PcdRtcTargetRegister64 have been introduced to provide the base address for the RTC registers in the MMIO space. When MMIO support is selected (PcdRtcUseMmio == TRUE) the driver converts the pointers to the RTC MMIO registers so that the RTC registers are accessible post ExitBootServices. Signed-off-by: Sami Mujawar <sami.mujawar@arm.com> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com> Acked-by: Laszlo Ersek <lersek@redhat.com>
Diffstat (limited to 'PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c')
-rw-r--r--PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c120
1 files changed, 109 insertions, 11 deletions
diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
index 52af179417..64f36f6fbb 100644
--- a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
+++ b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
@@ -3,6 +3,7 @@
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
+Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -10,6 +11,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "PcRtc.h"
+extern UINTN mRtcIndexRegister;
+extern UINTN mRtcTargetRegister;
+
//
// Days of month.
//
@@ -54,38 +58,132 @@ IsWithinOneDay (
);
/**
+ Read RTC content through its registers using IO access.
+
+ @param Address Address offset of RTC. It is recommended to use
+ macros such as RTC_ADDRESS_SECONDS.
+
+ @return The data of UINT8 type read from RTC.
+**/
+STATIC
+UINT8
+IoRtcRead (
+ IN UINTN Address
+ )
+{
+ IoWrite8 (
+ PcdGet8 (PcdRtcIndexRegister),
+ (UINT8)(Address | (UINT8)(IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80))
+ );
+ return IoRead8 (PcdGet8 (PcdRtcTargetRegister));
+}
+
+/**
+ Write RTC through its registers using IO access.
+
+ @param Address Address offset of RTC. It is recommended to use
+ macros such as RTC_ADDRESS_SECONDS.
+ @param Data The content you want to write into RTC.
+
+**/
+STATIC
+VOID
+IoRtcWrite (
+ IN UINTN Address,
+ IN UINT8 Data
+ )
+{
+ IoWrite8 (
+ PcdGet8 (PcdRtcIndexRegister),
+ (UINT8)(Address | (UINT8)(IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80))
+ );
+ IoWrite8 (PcdGet8 (PcdRtcTargetRegister), Data);
+}
+
+/**
+ Read RTC content through its registers using MMIO access.
+
+ @param Address Address offset of RTC. It is recommended to use
+ macros such as RTC_ADDRESS_SECONDS.
+
+ @return The data of UINT8 type read from RTC.
+**/
+STATIC
+UINT8
+MmioRtcRead (
+ IN UINTN Address
+ )
+{
+ MmioWrite8 (
+ mRtcIndexRegister,
+ (UINT8)(Address | (UINT8)(MmioRead8 (mRtcIndexRegister) & 0x80))
+ );
+ return MmioRead8 (mRtcTargetRegister);
+}
+
+/**
+ Write RTC through its registers using MMIO access.
+
+ @param Address Address offset of RTC. It is recommended to use
+ macros such as RTC_ADDRESS_SECONDS.
+ @param Data The content you want to write into RTC.
+
+**/
+STATIC
+VOID
+MmioRtcWrite (
+ IN UINTN Address,
+ IN UINT8 Data
+ )
+{
+ MmioWrite8 (
+ mRtcIndexRegister,
+ (UINT8)(Address | (UINT8)(MmioRead8 (mRtcIndexRegister) & 0x80))
+ );
+ MmioWrite8 (mRtcTargetRegister, Data);
+}
+
+/**
Read RTC content through its registers.
- @param Address Address offset of RTC. It is recommended to use macros such as
- RTC_ADDRESS_SECONDS.
+ @param Address Address offset of RTC. It is recommended to use
+ macros such as RTC_ADDRESS_SECONDS.
@return The data of UINT8 type read from RTC.
**/
+STATIC
UINT8
RtcRead (
- IN UINT8 Address
+ IN UINTN Address
)
{
- IoWrite8 (PcdGet8 (PcdRtcIndexRegister), (UINT8) (Address | (UINT8) (IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80)));
- return IoRead8 (PcdGet8 (PcdRtcTargetRegister));
+ if (FeaturePcdGet (PcdRtcUseMmio)) {
+ return MmioRtcRead (Address);
+ }
+
+ return IoRtcRead (Address);
}
/**
Write RTC through its registers.
- @param Address Address offset of RTC. It is recommended to use macros such as
- RTC_ADDRESS_SECONDS.
- @param Data The content you want to write into RTC.
+ @param Address Address offset of RTC. It is recommended to use
+ macros such as RTC_ADDRESS_SECONDS.
+ @param Data The content you want to write into RTC.
**/
+STATIC
VOID
RtcWrite (
- IN UINT8 Address,
+ IN UINTN Address,
IN UINT8 Data
)
{
- IoWrite8 (PcdGet8 (PcdRtcIndexRegister), (UINT8) (Address | (UINT8) (IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80)));
- IoWrite8 (PcdGet8 (PcdRtcTargetRegister), Data);
+ if (FeaturePcdGet (PcdRtcUseMmio)) {
+ MmioRtcWrite (Address, Data);
+ } else {
+ IoRtcWrite (Address, Data);
+ }
}
/**