OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
AppleRtcRam.c
Go to the documentation of this file.
1
19#include <Guid/OcVariable.h>
21#include <Library/BaseMemoryLib.h>
22#include <Library/DebugLib.h>
23#include <Library/MemoryAllocationLib.h>
24#include <Library/OcMiscLib.h>
25#include <Library/OcRtcLib.h>
26#include <Library/UefiBootServicesTableLib.h>
27#include <Library/UefiLib.h>
28#include "OcRtcLibInternal.h"
29
30STATIC EFI_LOCK mAppleRtcRamLock;
33
34STATIC
35EFI_STATUS
37 IN UINT8 Address,
38 IN UINT8 *ValuePtr
39 )
40{
41 EFI_STATUS Status;
42
43 if (mEmulatedRtcStatus[Address]) {
44 return mEmulatedRtcArea[Address];
45 }
46
47 Status = EfiAcquireLockOrFail (&mAppleRtcRamLock);
48 if (EFI_ERROR (Status)) {
49 return Status;
50 }
51
52 *ValuePtr = OcRtcRead (Address);
53 EfiReleaseLock (&mAppleRtcRamLock);
54 return EFI_SUCCESS;
55}
56
57STATIC
58EFI_STATUS
60 IN UINT8 Address,
61 IN UINT8 Value
62 )
63{
64 EFI_STATUS Status;
65
66 if (mEmulatedRtcStatus[Address]) {
67 mEmulatedRtcArea[Address] = Value;
68 return EFI_SUCCESS;
69 }
70
71 Status = EfiAcquireLockOrFail (&mAppleRtcRamLock);
72 if (EFI_ERROR (Status)) {
73 return Status;
74 }
75
76 OcRtcWrite (Address, Value);
77 EfiReleaseLock (&mAppleRtcRamLock);
78 return EFI_SUCCESS;
79}
80
81STATIC
82EFI_STATUS
84 VOID
85 )
86{
87 EFI_STATUS Status;
88 UINTN Count;
89 UINT8 RegisterA;
90
91 for (Count = 0; Count < 100; ++Count) {
92 Status = EfiAcquireLockOrFail (&mAppleRtcRamLock);
93
94 if (!EFI_ERROR (Status)) {
96 EfiReleaseLock (&mAppleRtcRamLock);
97
98 if ((RegisterA & RTC_UPDATE_IN_PROGRESS) == 0) {
99 return EFI_SUCCESS;
100 }
101 }
102
103 //
104 // Wait 1 ms and retry.
105 //
106 gBS->Stall (1000);
107 }
108
109 return EFI_TIMEOUT;
110}
111
112STATIC
113UINTN
114EFIAPI
121
122STATIC
123EFI_STATUS
124EFIAPI
126 IN APPLE_RTC_RAM_PROTOCOL *This,
127 OUT UINT8 *Buffer,
128 IN UINTN BufferSize,
129 IN UINTN Address
130 )
131{
132 EFI_STATUS Status;
133 UINTN Index;
134 UINT8 Temp;
135
136 if ( (Buffer == NULL)
137 || (BufferSize == 0)
138 || (Address >= APPLE_RTC_TOTAL_SIZE)
139 || (BufferSize >= APPLE_RTC_TOTAL_SIZE)
140 || (Address + BufferSize > APPLE_RTC_TOTAL_SIZE))
141 {
142 return EFI_INVALID_PARAMETER;
143 }
144
145 for (Index = 0; Index < BufferSize; ++Index) {
146 Status = SyncRtcWaitForReady ();
147 if (EFI_ERROR (Status)) {
148 return Status;
149 }
150
151 Status = SyncRtcRead ((UINT8)Address, Buffer);
152 if (EFI_ERROR (Status)) {
153 return Status;
154 }
155
156 if (Address == APPLE_RTC_BG_COLOR_ADDR) {
157 Status = SyncRtcWaitForReady ();
158 if (EFI_ERROR (Status)) {
159 return Status;
160 }
161
163 if (EFI_ERROR (Status)) {
164 return Status;
165 }
166
167 if ((Temp ^ *Buffer) != 0xFF) {
168 *Buffer = 0;
169 }
170 }
171
172 ++Buffer;
173 ++Address;
174 }
175
176 return EFI_SUCCESS;
177}
178
179STATIC
180EFI_STATUS
181EFIAPI
183 IN APPLE_RTC_RAM_PROTOCOL *This,
184 IN CONST UINT8 *Buffer,
185 IN UINTN BufferSize,
186 IN UINTN Address
187 )
188{
189 EFI_STATUS Status;
190 UINT8 TempBuffer[APPLE_RTC_TOTAL_SIZE];
191 UINTN Index;
192 UINT16 Checksum;
193
194 if ( (Buffer == NULL)
195 || (BufferSize == 0)
196 || (Address < APPLE_RTC_CHECKSUM_START)
197 || (Address >= APPLE_RTC_TOTAL_SIZE)
198 || (BufferSize >= APPLE_RTC_TOTAL_SIZE)
199 || (Address + BufferSize > APPLE_RTC_TOTAL_SIZE))
200 {
201 return EFI_INVALID_PARAMETER;
202 }
203
204 Status = AppleRtcRamReadData (This, TempBuffer, APPLE_RTC_TOTAL_SIZE, 0);
205 if (EFI_ERROR (Status)) {
206 return Status;
207 }
208
209 for (Index = 0; Index < BufferSize; ++Index) {
210 if (Address != APPLE_RTC_BG_COMPLEMENT_ADDR) {
211 TempBuffer[Address] = *Buffer;
212
213 if (Address == APPLE_RTC_BG_COLOR_ADDR) {
214 TempBuffer[APPLE_RTC_BG_COMPLEMENT_ADDR] = (UINT8) ~((UINT32)*Buffer);
215 }
216 }
217
218 ++Buffer;
219 ++Address;
220 }
221
225
226 TempBuffer[APPLE_RTC_MAIN_CHECKSUM_ADDR1] = 0;
227 TempBuffer[APPLE_RTC_MAIN_CHECKSUM_ADDR2] = 0;
231
232 for (Index = APPLE_RTC_CHECKSUM_START; Index < APPLE_RTC_TOTAL_SIZE; ++Index) {
233 SyncRtcWrite ((UINT8)Index, TempBuffer[Index]);
234 }
235
236 return EFI_SUCCESS;
237}
238
239STATIC
240EFI_STATUS
241EFIAPI
244 )
245{
246 EFI_STATUS Status;
247 UINTN Index;
249
250 ZeroMem (Buffer, sizeof (Buffer));
251
252 for (Index = APPLE_RTC_CHECKSUM_START; Index < APPLE_RTC_CORE_SIZE; ++Index) {
253 Status = SyncRtcWaitForReady ();
254 if (!EFI_ERROR (Status)) {
255 SyncRtcRead ((UINT8)Index, &Buffer[Index]);
256 }
257 }
258
259 Status = SyncRtcWaitForReady ();
260 if (!EFI_ERROR (Status)) {
262 }
263
265 Status = SyncRtcWaitForReady ();
266 if (!EFI_ERROR (Status)) {
267 SyncRtcRead ((UINT8)Index, &Buffer[Index]);
268 }
269 }
270
271 return AppleRtcRamWriteData (
272 This,
276 );
277}
278
279STATIC
287
290 IN BOOLEAN Reinstall
291 )
292{
293 EFI_STATUS Status;
294 APPLE_RTC_RAM_PROTOCOL *Protocol;
295 UINT8 *RtcBlacklist;
296 UINTN Index;
297 UINTN RtcBlacklistSize;
298 EFI_HANDLE NewHandle;
299
300 DEBUG ((DEBUG_VERBOSE, "OCRTC: OcAppleRtcRamInstallProtocol\n"));
301
302 if (Reinstall) {
304 if (EFI_ERROR (Status)) {
305 DEBUG ((DEBUG_ERROR, "OCRTC: Uninstall failed - %r\n", Status));
306 return NULL;
307 }
308 } else {
309 Status = gBS->LocateProtocol (
311 NULL,
312 (VOID *)&Protocol
313 );
314
315 if (!EFI_ERROR (Status)) {
316 return Protocol;
317 }
318 }
319
320 DEBUG ((
321 DEBUG_INFO,
322 "OCRTC: Wake log is 0x%02X 0x%02X % 3d 0x%02X\n",
327 ));
328
329 Status = GetVariable2 (
332 (VOID **)&RtcBlacklist,
333 &RtcBlacklistSize
334 );
335
336 if (!EFI_ERROR (Status)) {
337 for (Index = 0; Index < RtcBlacklistSize; ++Index) {
338 mEmulatedRtcStatus[RtcBlacklist[Index]] = TRUE;
339 DEBUG ((DEBUG_INFO, "OCRTC: Blacklisted %02x address\n", RtcBlacklist[Index]));
340 }
341
342 FreePool (RtcBlacklist);
343 }
344
345 //
346 // Note, for debugging on QEMU this will need to changed to TPL_CALLBACK.
347 // By default we follow AppleRtcRam implementation.
348 // Also, AppleRtcRam function may be called after ExitBootServices or around
349 // GetMemoryMap, so debugging is not perfectly safe.
350 //
351 EfiInitializeLock (&mAppleRtcRamLock, TPL_NOTIFY);
352
353 //
354 // Note, Apple implementation calls AppleRtcRamReset on checksum mismatch.
355 //
356 NewHandle = NULL;
357 Status = gBS->InstallMultipleProtocolInterfaces (
358 &NewHandle,
360 (VOID *)&mAppleRtcRamProtocol,
361 NULL
362 );
363
364 if (EFI_ERROR (Status)) {
365 return NULL;
366 }
367
368 return &mAppleRtcRamProtocol;
369}
UINT8 Checksum
All 32 bits added together have to equal 1.
Definition AppleNec.h:77
#define APPLE_RTC_MAIN_CHECKSUM_BYTE1(Checksum)
Definition AppleRtc.h:397
#define APPLE_RTC_TOTAL_SIZE
Definition AppleRtc.h:344
#define APPLE_RTC_CORE_CHECKSUM_ADDR1
Definition AppleRtc.h:374
#define APPLE_RTC_BG_COLOR_ADDR
Definition AppleRtc.h:55
#define APPLE_RTC_RESERVED_LENGTH
Definition AppleRtc.h:122
#define APPLE_RTC_CORE_CHECKSUM_BYTE2(Checksum)
Definition AppleRtc.h:383
#define APPLE_RTC_CORE_CHECKSUM_ADDR2
Definition AppleRtc.h:375
#define APPLE_RTC_MAIN_CHECKSUM_ADDR2
Definition AppleRtc.h:390
#define APPLE_RTC_BG_COMPLEMENT_ADDR
Definition AppleRtc.h:56
#define APPLE_RTC_WL_EVENT_EXTRA_ADDR
Definition AppleRtc.h:215
#define APPLE_RTC_WL_EVENT_ADDR
Definition AppleRtc.h:214
#define APPLE_RTC_FIRMWARE_57_ADDR
Definition AppleRtc.h:101
#define APPLE_RTC_CORE_CHECKSUM_BYTE1(Checksum)
Definition AppleRtc.h:382
#define APPLE_RTC_TRACE_DATA_ADDR
Definition AppleRtc.h:182
#define APPLE_RTC_CORE_SIZE
Definition AppleRtc.h:339
#define APPLE_RTC_WL_MASK_ADDR
Definition AppleRtc.h:197
#define APPLE_RTC_MAIN_CHECKSUM_BYTE2(Checksum)
Definition AppleRtc.h:398
#define APPLE_RTC_CHECKSUM_START
Definition AppleRtc.h:334
#define APPLE_RTC_MAIN_CHECKSUM_ADDR1
Definition AppleRtc.h:389
#define APPLE_RTC_RESERVED_ADDR
Definition AppleRtc.h:117
STATIC EFI_STATUS SyncRtcRead(IN UINT8 Address, IN UINT8 *ValuePtr)
Definition AppleRtcRam.c:36
STATIC UINTN EFIAPI AppleRtcGetAvailableMemory(IN APPLE_RTC_RAM_PROTOCOL *This)
STATIC EFI_STATUS EFIAPI AppleRtcRamWriteData(IN APPLE_RTC_RAM_PROTOCOL *This, IN CONST UINT8 *Buffer, IN UINTN BufferSize, IN UINTN Address)
STATIC EFI_STATUS SyncRtcWrite(IN UINT8 Address, IN UINT8 Value)
Definition AppleRtcRam.c:59
STATIC EFI_LOCK mAppleRtcRamLock
Definition AppleRtcRam.c:30
STATIC EFI_STATUS EFIAPI AppleRtcRamReadData(IN APPLE_RTC_RAM_PROTOCOL *This, OUT UINT8 *Buffer, IN UINTN BufferSize, IN UINTN Address)
STATIC UINT8 mEmulatedRtcArea[APPLE_RTC_TOTAL_SIZE]
Definition AppleRtcRam.c:31
STATIC BOOLEAN mEmulatedRtcStatus[APPLE_RTC_TOTAL_SIZE]
Definition AppleRtcRam.c:32
STATIC APPLE_RTC_RAM_PROTOCOL mAppleRtcRamProtocol
STATIC EFI_STATUS SyncRtcWaitForReady(VOID)
Definition AppleRtcRam.c:83
APPLE_RTC_RAM_PROTOCOL * OcAppleRtcRamInstallProtocol(IN BOOLEAN Reinstall)
STATIC EFI_STATUS EFIAPI AppleRtcRamReset(IN APPLE_RTC_RAM_PROTOCOL *This)
EFI_GUID gAppleRtcRamProtocolGuid
EFI_BOOT_SERVICES * gBS
EFI_STATUS OcUninstallAllProtocolInstances(EFI_GUID *Protocol)
UINT8 OcRtcRead(IN UINT8 Offset)
Definition OcRtcLib.c:25
VOID OcRtcWrite(IN UINT8 Offset, IN UINT8 Value)
Definition OcRtcLib.c:47
UINT16 OcRtcChecksumApple(IN CONST VOID *Data, IN UINTN Size)
Definition OcRtcLib.c:70
#define RTC_UPDATE_IN_PROGRESS
#define RTC_ADDRESS_REGISTER_A
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
EFI_GUID gOcVendorVariableGuid
#define OC_RTC_BLACKLIST_VARIABLE_NAME
Definition OcVariable.h:80
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)