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