mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-21 12:44:50 +02:00
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:
parent
a7d977040b
commit
015be4075f
@ -6,6 +6,7 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
# Copyright (c) 2017, AMD Inc. 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
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
@ -41,6 +42,13 @@
|
|||||||
# @Prompt Configure HPET to use MSI.
|
# @Prompt Configure HPET to use MSI.
|
||||||
gPcAtChipsetPkgTokenSpaceGuid.PcdHpetMsiEnable|TRUE|BOOLEAN|0x00001000
|
gPcAtChipsetPkgTokenSpaceGuid.PcdHpetMsiEnable|TRUE|BOOLEAN|0x00001000
|
||||||
|
|
||||||
|
## Indicates the RTC port registers are in MMIO space, or in I/O space.
|
||||||
|
# Default is I/O space.<BR><BR>
|
||||||
|
# TRUE - RTC port registers are in MMIO space.<BR>
|
||||||
|
# FALSE - RTC port registers are in I/O space.<BR>
|
||||||
|
# @Prompt RTC port registers use MMIO.
|
||||||
|
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcUseMmio|FALSE|BOOLEAN|0x00000021
|
||||||
|
|
||||||
[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule]
|
[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule]
|
||||||
## This PCD specifies the base address of the HPET timer.
|
## This PCD specifies the base address of the HPET timer.
|
||||||
# @Prompt HPET base address.
|
# @Prompt HPET base address.
|
||||||
@ -68,6 +76,14 @@
|
|||||||
# @Expression 0x80000001 | gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear < gPcAtChipsetPkgTokenSpaceGuid.PcdMinimalValidYear + 100
|
# @Expression 0x80000001 | gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear < gPcAtChipsetPkgTokenSpaceGuid.PcdMinimalValidYear + 100
|
||||||
gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear|2097|UINT16|0x0000000E
|
gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear|2097|UINT16|0x0000000E
|
||||||
|
|
||||||
|
## Specifies RTC Index Register address in MMIO space.
|
||||||
|
# @Prompt RTC Index Register address
|
||||||
|
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister64|0x0|UINT64|0x00000022
|
||||||
|
|
||||||
|
## Specifies RTC Target Register address in MMIO space.
|
||||||
|
# @Prompt RTC Target Register address
|
||||||
|
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister64|0x0|UINT64|0x00000023
|
||||||
|
|
||||||
[PcdsFixedAtBuild, PcdsPatchableInModule]
|
[PcdsFixedAtBuild, PcdsPatchableInModule]
|
||||||
## Defines the ACPI register set base address.
|
## Defines the ACPI register set base address.
|
||||||
# The invalid 0xFFFF is as its default value. It must be configured to the real value.
|
# The invalid 0xFFFF is as its default value. It must be configured to the real value.
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
Copyright (c) 2017, AMD Inc. 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
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
@ -10,6 +11,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
|
|
||||||
#include "PcRtc.h"
|
#include "PcRtc.h"
|
||||||
|
|
||||||
|
extern UINTN mRtcIndexRegister;
|
||||||
|
extern UINTN mRtcTargetRegister;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Days of month.
|
// Days of month.
|
||||||
//
|
//
|
||||||
@ -54,38 +58,132 @@ IsWithinOneDay (
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Read RTC content through its registers.
|
Read RTC content through its registers using IO access.
|
||||||
|
|
||||||
@param Address Address offset of RTC. It is recommended to use macros such as
|
@param Address Address offset of RTC. It is recommended to use
|
||||||
RTC_ADDRESS_SECONDS.
|
macros such as RTC_ADDRESS_SECONDS.
|
||||||
|
|
||||||
@return The data of UINT8 type read from RTC.
|
@return The data of UINT8 type read from RTC.
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
UINT8
|
UINT8
|
||||||
RtcRead (
|
IoRtcRead (
|
||||||
IN UINT8 Address
|
IN UINTN Address
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IoWrite8 (PcdGet8 (PcdRtcIndexRegister), (UINT8) (Address | (UINT8) (IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80)));
|
IoWrite8 (
|
||||||
|
PcdGet8 (PcdRtcIndexRegister),
|
||||||
|
(UINT8)(Address | (UINT8)(IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80))
|
||||||
|
);
|
||||||
return IoRead8 (PcdGet8 (PcdRtcTargetRegister));
|
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.
|
||||||
|
|
||||||
|
@return The data of UINT8 type read from RTC.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINT8
|
||||||
|
RtcRead (
|
||||||
|
IN UINTN Address
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (FeaturePcdGet (PcdRtcUseMmio)) {
|
||||||
|
return MmioRtcRead (Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IoRtcRead (Address);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Write RTC through its registers.
|
Write RTC through its registers.
|
||||||
|
|
||||||
@param Address Address offset of RTC. It is recommended to use macros such as
|
@param Address Address offset of RTC. It is recommended to use
|
||||||
RTC_ADDRESS_SECONDS.
|
macros such as RTC_ADDRESS_SECONDS.
|
||||||
@param Data The content you want to write into RTC.
|
@param Data The content you want to write into RTC.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
RtcWrite (
|
RtcWrite (
|
||||||
IN UINT8 Address,
|
IN UINTN Address,
|
||||||
IN UINT8 Data
|
IN UINT8 Data
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IoWrite8 (PcdGet8 (PcdRtcIndexRegister), (UINT8) (Address | (UINT8) (IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80)));
|
if (FeaturePcdGet (PcdRtcUseMmio)) {
|
||||||
IoWrite8 (PcdGet8 (PcdRtcTargetRegister), Data);
|
MmioRtcWrite (Address, Data);
|
||||||
|
} else {
|
||||||
|
IoRtcWrite (Address, Data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,16 +2,23 @@
|
|||||||
Provides Set/Get time operations.
|
Provides Set/Get time operations.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
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
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include <Library/DxeServicesTableLib.h>
|
||||||
#include "PcRtc.h"
|
#include "PcRtc.h"
|
||||||
|
|
||||||
PC_RTC_MODULE_GLOBALS mModuleGlobal;
|
PC_RTC_MODULE_GLOBALS mModuleGlobal;
|
||||||
|
|
||||||
EFI_HANDLE mHandle = NULL;
|
EFI_HANDLE mHandle = NULL;
|
||||||
|
|
||||||
|
STATIC EFI_EVENT mVirtualAddrChangeEvent;
|
||||||
|
|
||||||
|
UINTN mRtcIndexRegister;
|
||||||
|
UINTN mRtcTargetRegister;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the current time and date information, and the time-keeping capabilities
|
Returns the current time and date information, and the time-keeping capabilities
|
||||||
of the hardware platform.
|
of the hardware platform.
|
||||||
@ -105,6 +112,30 @@ PcRtcEfiSetWakeupTime (
|
|||||||
return PcRtcSetWakeupTime (Enabled, Time, &mModuleGlobal);
|
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.
|
The user Entry Point for PcRTC module.
|
||||||
|
|
||||||
@ -131,6 +162,11 @@ InitializePcRtc (
|
|||||||
EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_CALLBACK);
|
EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_CALLBACK);
|
||||||
mModuleGlobal.CenturyRtcAddress = GetCenturyRtcAddress ();
|
mModuleGlobal.CenturyRtcAddress = GetCenturyRtcAddress ();
|
||||||
|
|
||||||
|
if (FeaturePcdGet (PcdRtcUseMmio)) {
|
||||||
|
mRtcIndexRegister = (UINTN)PcdGet64 (PcdRtcIndexRegister64);
|
||||||
|
mRtcTargetRegister = (UINTN)PcdGet64 (PcdRtcTargetRegister64);
|
||||||
|
}
|
||||||
|
|
||||||
Status = PcRtcInit (&mModuleGlobal);
|
Status = PcRtcInit (&mModuleGlobal);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
@ -165,7 +201,23 @@ InitializePcRtc (
|
|||||||
NULL,
|
NULL,
|
||||||
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
# Copyright (c) 2017, AMD Inc. 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
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
@ -61,6 +62,11 @@
|
|||||||
## SOMETIMES_CONSUMES ## SystemTable
|
## SOMETIMES_CONSUMES ## SystemTable
|
||||||
gEfiAcpiTableGuid
|
gEfiAcpiTableGuid
|
||||||
|
|
||||||
|
gEfiEventVirtualAddressChangeGuid
|
||||||
|
|
||||||
|
[FeaturePcd]
|
||||||
|
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcUseMmio ## CONSUMES
|
||||||
|
|
||||||
[FixedPcd]
|
[FixedPcd]
|
||||||
gPcAtChipsetPkgTokenSpaceGuid.PcdInitialValueRtcRegisterA ## CONSUMES
|
gPcAtChipsetPkgTokenSpaceGuid.PcdInitialValueRtcRegisterA ## CONSUMES
|
||||||
gPcAtChipsetPkgTokenSpaceGuid.PcdInitialValueRtcRegisterB ## CONSUMES
|
gPcAtChipsetPkgTokenSpaceGuid.PcdInitialValueRtcRegisterB ## CONSUMES
|
||||||
@ -72,6 +78,8 @@
|
|||||||
gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear ## CONSUMES
|
gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear ## CONSUMES
|
||||||
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister ## CONSUMES
|
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister ## CONSUMES
|
||||||
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister ## CONSUMES
|
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister ## CONSUMES
|
||||||
|
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister64 ## CONSUMES
|
||||||
|
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister64 ## CONSUMES
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid
|
gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid
|
||||||
|
Loading…
x
Reference in New Issue
Block a user