]> git.proxmox.com Git - mirror_edk2.git/blob - ArmVirtPkg/Library/ArmVirtPL031FdtClientLib/ArmVirtPL031FdtClientLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <Uefi.h>
11
12 #include <Library/BaseLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/PcdLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
16
17 #include <Protocol/FdtClient.h>
18
19 RETURN_STATUS
20 EFIAPI
21 ArmVirtPL031FdtClientLibConstructor (
22 VOID
23 )
24 {
25 EFI_STATUS Status;
26 FDT_CLIENT_PROTOCOL *FdtClient;
27 INT32 Node;
28 CONST UINT64 *Reg;
29 UINT32 RegSize;
30 UINT64 RegBase;
31 RETURN_STATUS PcdStatus;
32
33 Status = gBS->LocateProtocol (
34 &gFdtClientProtocolGuid,
35 NULL,
36 (VOID **)&FdtClient
37 );
38 ASSERT_EFI_ERROR (Status);
39
40 Status = FdtClient->FindCompatibleNode (FdtClient, "arm,pl031", &Node);
41 if (EFI_ERROR (Status)) {
42 DEBUG ((
43 DEBUG_WARN,
44 "%a: No 'arm,pl031' compatible DT node found\n",
45 __FUNCTION__
46 ));
47 return EFI_SUCCESS;
48 }
49
50 Status = FdtClient->GetNodeProperty (
51 FdtClient,
52 Node,
53 "reg",
54 (CONST VOID **)&Reg,
55 &RegSize
56 );
57 if (EFI_ERROR (Status)) {
58 DEBUG ((
59 DEBUG_WARN,
60 "%a: No 'reg' property found in 'arm,pl031' compatible DT node\n",
61 __FUNCTION__
62 ));
63 return EFI_SUCCESS;
64 }
65
66 ASSERT (RegSize == 16);
67
68 RegBase = SwapBytes64 (Reg[0]);
69 ASSERT (RegBase < MAX_UINT32);
70
71 PcdStatus = PcdSet32S (PcdPL031RtcBase, (UINT32)RegBase);
72 ASSERT_RETURN_ERROR (PcdStatus);
73
74 DEBUG ((DEBUG_INFO, "Found PL031 RTC @ 0x%Lx\n", RegBase));
75
76 //
77 // UEFI takes ownership of the RTC hardware, and exposes its functionality
78 // through the UEFI Runtime Services GetTime, SetTime, etc. This means we
79 // need to disable it in the device tree to prevent the OS from attaching
80 // its device driver as well.
81 //
82 Status = FdtClient->SetNodeProperty (
83 FdtClient,
84 Node,
85 "status",
86 "disabled",
87 sizeof ("disabled")
88 );
89 if (EFI_ERROR (Status)) {
90 DEBUG ((DEBUG_WARN, "Failed to set PL031 status to 'disabled'\n"));
91 }
92
93 return EFI_SUCCESS;
94 }