diff --git a/ArmVirtPkg/Library/ArmVirtPL031FdtClientLib/ArmVirtPL031FdtClientLib.c b/ArmVirtPkg/Library/ArmVirtPL031FdtClientLib/ArmVirtPL031FdtClientLib.c new file mode 100644 index 0000000000..3c4e44caa2 --- /dev/null +++ b/ArmVirtPkg/Library/ArmVirtPL031FdtClientLib/ArmVirtPL031FdtClientLib.c @@ -0,0 +1,82 @@ +/** @file + FDT client library for ARM's PL031 RTC driver + + Copyright (c) 2016, Linaro Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include + +#include + +RETURN_STATUS +EFIAPI +ArmVirtPL031FdtClientLibConstructor ( + VOID + ) +{ + EFI_STATUS Status; + FDT_CLIENT_PROTOCOL *FdtClient; + INT32 Node; + CONST UINT64 *Reg; + UINT32 RegSize; + UINT64 RegBase; + + Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, + (VOID **)&FdtClient); + ASSERT_EFI_ERROR (Status); + + Status = FdtClient->FindCompatibleNode (FdtClient, "arm,pl031", &Node); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_WARN, "%a: No 'arm,pl031' compatible DT node found\n", + __FUNCTION__)); + return EFI_SUCCESS; + } + + Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", + (CONST VOID **)&Reg, &RegSize); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_WARN, + "%a: No 'reg' property found in 'arm,pl031' compatible DT node\n", + __FUNCTION__)); + return EFI_SUCCESS; + } + + ASSERT (RegSize == 16); + + RegBase = SwapBytes64 (Reg[0]); + ASSERT (RegBase < MAX_UINT32); + + PcdSet32 (PcdPL031RtcBase, (UINT32)RegBase); + + DEBUG ((EFI_D_INFO, "Found PL031 RTC @ 0x%Lx\n", RegBase)); + + if (!FeaturePcdGet (PcdPureAcpiBoot)) { + // + // UEFI takes ownership of the RTC hardware, and exposes its functionality + // through the UEFI Runtime Services GetTime, SetTime, etc. This means we + // need to disable it in the device tree to prevent the OS from attaching + // its device driver as well. + // + Status = FdtClient->SetNodeProperty (FdtClient, Node, "status", + "disabled", sizeof ("disabled")); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_WARN, "Failed to set PL031 status to 'disabled'\n")); + } + } + + return EFI_SUCCESS; +} diff --git a/ArmVirtPkg/Library/ArmVirtPL031FdtClientLib/ArmVirtPL031FdtClientLib.inf b/ArmVirtPkg/Library/ArmVirtPL031FdtClientLib/ArmVirtPL031FdtClientLib.inf new file mode 100644 index 0000000000..32dbff6f08 --- /dev/null +++ b/ArmVirtPkg/Library/ArmVirtPL031FdtClientLib/ArmVirtPL031FdtClientLib.inf @@ -0,0 +1,49 @@ +#/** @file +# FDT client library for ARM's PL031 RTC driver +# +# Copyright (c) 2016, Linaro Ltd. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmVirtPL031FdtClientLib + FILE_GUID = 13173319-B270-4669-8592-3BB2B31E9E29 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmVirtPL031FdtClientLib|DXE_DRIVER DXE_RUNTIME_DRIVER + CONSTRUCTOR = ArmVirtPL031FdtClientLibConstructor + +[Sources] + ArmVirtPL031FdtClientLib.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + ArmVirtPkg/ArmVirtPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + UefiBootServicesTableLib + +[Protocols] + gFdtClientProtocolGuid ## CONSUMES + +[Pcd] + gArmPlatformTokenSpaceGuid.PcdPL031RtcBase + +[FeaturePcd] + gArmVirtTokenSpaceGuid.PcdPureAcpiBoot + +[Depex] + gFdtClientProtocolGuid