TianoCore EDK2 master
Loading...
Searching...
No Matches
KvmtoolRtcFdtClientLib.c
Go to the documentation of this file.
1
10#include <Library/BaseLib.h>
11#include <Library/DebugLib.h>
13#include <Library/PcdLib.h>
15#include <Protocol/FdtClient.h>
16
19#define RTC_INDEX_REG_OFFSET 0x0ULL
20
23#define RTC_TARGET_REG_OFFSET 0x1ULL
24
37 IN EFI_HANDLE ImageHandle,
38 IN EFI_PHYSICAL_ADDRESS RtcPageBase
39 )
40{
41 EFI_STATUS Status;
42
43 Status = gDS->AddMemorySpace (
45 RtcPageBase,
46 EFI_PAGE_SIZE,
47 EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP
48 );
49 if (EFI_ERROR (Status)) {
50 DEBUG ((
51 DEBUG_ERROR,
52 "Failed to add memory space. Status = %r\n",
53 Status
54 ));
55 return Status;
56 }
57
58 Status = gDS->AllocateMemorySpace (
61 0,
62 EFI_PAGE_SIZE,
63 &RtcPageBase,
64 ImageHandle,
65 NULL
66 );
67 if (EFI_ERROR (Status)) {
68 DEBUG ((
69 DEBUG_ERROR,
70 "Failed to allocate memory space. Status = %r\n",
71 Status
72 ));
73 gDS->RemoveMemorySpace (
74 RtcPageBase,
75 EFI_PAGE_SIZE
76 );
77 return Status;
78 }
79
80 Status = gDS->SetMemorySpaceAttributes (
81 RtcPageBase,
82 EFI_PAGE_SIZE,
83 EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP
84 );
85 if (EFI_ERROR (Status)) {
86 DEBUG ((
87 DEBUG_ERROR,
88 "Failed to set memory attributes. Status = %r\n",
89 Status
90 ));
91 gDS->FreeMemorySpace (
92 RtcPageBase,
93 EFI_PAGE_SIZE
94 );
95 gDS->RemoveMemorySpace (
96 RtcPageBase,
97 EFI_PAGE_SIZE
98 );
99 }
100
101 return Status;
102}
103
119EFIAPI
121 IN EFI_HANDLE ImageHandle,
122 IN EFI_SYSTEM_TABLE *SystemTable
123 )
124{
125 EFI_STATUS Status;
126 FDT_CLIENT_PROTOCOL *FdtClient;
127 INT32 Node;
128 CONST UINT32 *Reg;
129 UINT32 RegSize;
130 UINT64 RegBase;
131 UINT64 Range;
132 RETURN_STATUS PcdStatus;
133
134 Status = gBS->LocateProtocol (
135 &gFdtClientProtocolGuid,
136 NULL,
137 (VOID **)&FdtClient
138 );
139 ASSERT_EFI_ERROR (Status);
140
141 Status = FdtClient->FindCompatibleNode (
142 FdtClient,
143 "motorola,mc146818",
144 &Node
145 );
146 if (EFI_ERROR (Status)) {
147 DEBUG ((
148 DEBUG_ERROR,
149 "%a: No 'motorola,mc146818' compatible DT node found\n",
150 __func__
151 ));
152 return Status;
153 }
154
155 Status = FdtClient->GetNodeProperty (
156 FdtClient,
157 Node,
158 "reg",
159 (CONST VOID **)&Reg,
160 &RegSize
161 );
162 if (EFI_ERROR (Status)) {
163 DEBUG ((
164 DEBUG_ERROR,
165 "%a: No 'reg' property found in 'motorola,mc146818' compatible DT node\n",
166 __func__
167 ));
168 return Status;
169 }
170
171 ASSERT (RegSize == 16);
172
173 RegBase = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
174 Range = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
175 DEBUG ((
176 DEBUG_INFO,
177 "Found motorola,mc146818 RTC @ 0x%Lx Range = 0x%x\n",
178 RegBase,
179 Range
180 ));
181
182 // The address range must cover the RTC Index and the Target registers.
183 ASSERT (Range >= 0x2);
184
185 // RTC Index register is at offset 0x0
186 PcdStatus = PcdSet64S (
187 PcdRtcIndexRegister64,
188 (RegBase + RTC_INDEX_REG_OFFSET)
189 );
190 ASSERT_RETURN_ERROR (PcdStatus);
191
192 // RTC Target register is at offset 0x1
193 PcdStatus = PcdSet64S (
194 PcdRtcTargetRegister64,
195 (RegBase + RTC_TARGET_REG_OFFSET)
196 );
197 ASSERT_RETURN_ERROR (PcdStatus);
198
199 Status = KvmtoolRtcMapMemory (ImageHandle, (RegBase & ~EFI_PAGE_MASK));
200 if (EFI_ERROR (Status)) {
201 DEBUG ((
202 DEBUG_ERROR,
203 "Failed to map memory for motorola,mc146818. Status = %r\n",
204 Status
205 ));
206 return Status;
207 }
208
209 //
210 // UEFI takes ownership of the RTC hardware, and exposes its functionality
211 // through the UEFI Runtime Services GetTime, SetTime, etc. This means we
212 // need to disable it in the device tree to prevent the OS from attaching
213 // its device driver as well.
214 //
215 Status = FdtClient->SetNodeProperty (
216 FdtClient,
217 Node,
218 "status",
219 "disabled",
220 sizeof ("disabled")
221 );
222 if (EFI_ERROR (Status)) {
223 DEBUG ((
224 DEBUG_WARN,
225 "Failed to set motorola,mc146818 status to 'disabled', Status = %r\n",
226 Status
227 ));
228 }
229
230 return EFI_SUCCESS;
231}
UINT64 EFIAPI ReadUnaligned64(IN CONST UINT64 *Buffer)
Definition: Unaligned.c:204
UINT64 EFIAPI SwapBytes64(IN UINT64 Value)
Definition: SwapBytes64.c:25
EFI_DXE_SERVICES * gDS
EFI_STATUS EFIAPI KvmtoolRtcFdtClientLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC EFI_STATUS KvmtoolRtcMapMemory(IN EFI_HANDLE ImageHandle, IN EFI_PHYSICAL_ADDRESS RtcPageBase)
#define RTC_INDEX_REG_OFFSET
#define RTC_TARGET_REG_OFFSET
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define ASSERT_RETURN_ERROR(StatusParameter)
Definition: DebugLib.h:493
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdSet64S(TokenName, Value)
Definition: PcdLib.h:511
@ EfiGcdMemoryTypeMemoryMappedIo
Definition: PiDxeCis.h:44
@ EfiGcdAllocateAddress
Definition: PiDxeCis.h:107
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS