mirror of https://github.com/acidanthera/audk.git
77 lines
2.2 KiB
C
77 lines
2.2 KiB
C
/** @file
|
|
FDT client library for ARM's PL031 RTC driver
|
|
|
|
Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <Uefi.h>
|
|
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/PcdLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
|
|
#include <Protocol/FdtClient.h>
|
|
|
|
RETURN_STATUS
|
|
EFIAPI
|
|
ArmVirtPL031FdtClientLibConstructor (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
FDT_CLIENT_PROTOCOL *FdtClient;
|
|
INT32 Node;
|
|
CONST UINT64 *Reg;
|
|
UINT32 RegSize;
|
|
UINT64 RegBase;
|
|
RETURN_STATUS PcdStatus;
|
|
|
|
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);
|
|
|
|
PcdStatus = PcdSet32S (PcdPL031RtcBase, (UINT32)RegBase);
|
|
ASSERT_RETURN_ERROR (PcdStatus);
|
|
|
|
DEBUG ((EFI_D_INFO, "Found PL031 RTC @ 0x%Lx\n", RegBase));
|
|
|
|
//
|
|
// 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;
|
|
}
|