]> git.proxmox.com Git - mirror_edk2.git/blob - ArmVirtPkg/Library/ArmVirtPL031FdtClientLib/ArmVirtPL031FdtClientLib.c
82de7a51b32e8ea6de0c4b62a44378cf57dd1ad3
[mirror_edk2.git] / ArmVirtPkg / Library / ArmVirtPL031FdtClientLib / ArmVirtPL031FdtClientLib.c
1 /** @file
2 FDT client library for ARM's PL031 RTC driver
3
4 Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include <Uefi.h>
17
18 #include <Library/BaseLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PcdLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22
23 #include <Protocol/FdtClient.h>
24
25 RETURN_STATUS
26 EFIAPI
27 ArmVirtPL031FdtClientLibConstructor (
28 VOID
29 )
30 {
31 EFI_STATUS Status;
32 FDT_CLIENT_PROTOCOL *FdtClient;
33 INT32 Node;
34 CONST UINT64 *Reg;
35 UINT32 RegSize;
36 UINT64 RegBase;
37 RETURN_STATUS PcdStatus;
38
39 Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
40 (VOID **)&FdtClient);
41 ASSERT_EFI_ERROR (Status);
42
43 Status = FdtClient->FindCompatibleNode (FdtClient, "arm,pl031", &Node);
44 if (EFI_ERROR (Status)) {
45 DEBUG ((EFI_D_WARN, "%a: No 'arm,pl031' compatible DT node found\n",
46 __FUNCTION__));
47 return EFI_SUCCESS;
48 }
49
50 Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg",
51 (CONST VOID **)&Reg, &RegSize);
52 if (EFI_ERROR (Status)) {
53 DEBUG ((EFI_D_WARN,
54 "%a: No 'reg' property found in 'arm,pl031' compatible DT node\n",
55 __FUNCTION__));
56 return EFI_SUCCESS;
57 }
58
59 ASSERT (RegSize == 16);
60
61 RegBase = SwapBytes64 (Reg[0]);
62 ASSERT (RegBase < MAX_UINT32);
63
64 PcdStatus = PcdSet32S (PcdPL031RtcBase, (UINT32)RegBase);
65 ASSERT_RETURN_ERROR (PcdStatus);
66
67 DEBUG ((EFI_D_INFO, "Found PL031 RTC @ 0x%Lx\n", RegBase));
68
69 if (!FeaturePcdGet (PcdPureAcpiBoot)) {
70 //
71 // UEFI takes ownership of the RTC hardware, and exposes its functionality
72 // through the UEFI Runtime Services GetTime, SetTime, etc. This means we
73 // need to disable it in the device tree to prevent the OS from attaching
74 // its device driver as well.
75 //
76 Status = FdtClient->SetNodeProperty (FdtClient, Node, "status",
77 "disabled", sizeof ("disabled"));
78 if (EFI_ERROR (Status)) {
79 DEBUG ((EFI_D_WARN, "Failed to set PL031 status to 'disabled'\n"));
80 }
81 }
82
83 return EFI_SUCCESS;
84 }