mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-26 16:47:40 +01:00
620401dca6
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
401 lines
16 KiB
C
401 lines
16 KiB
C
/** @file
|
|
Copyright (C) 2020, vit9696. All rights reserved.
|
|
|
|
All rights reserved.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
**/
|
|
|
|
#ifndef APPLE_RTC_H
|
|
#define APPLE_RTC_H
|
|
|
|
/**
|
|
Sample RTC memory dump from MBP12,1 running 10.15.4:
|
|
|
|
00: 33 02 01 00 12 22 04 16 04 20 26 02 70 80 FF FF
|
|
10: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
|
20: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
|
30: 01 FE 20 FF FF FF FF FF F8 11 FF FF FF 00 1A 7C
|
|
40: 00 00 00 00 FE 00 00 00 00 00 00 00 00 00 00 00
|
|
50: 00 00 00 00 00 00 00 FF 0B D1 80 00 05 00 00 00
|
|
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
70: 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF
|
|
80: 44 45 41 44 00 00 00 00 00 00 00 00 00 00 00 00
|
|
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
B0: 76 CF 85 13 00 00 00 00 00 00 00 00 00 00 00 00
|
|
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
**/
|
|
|
|
/**
|
|
APPLE_RTC_BG_COLOR_ADDR - background colour.
|
|
APPLE_RTC_BG_COMPLEMENT_ADDR - complementary byte to background colour.
|
|
|
|
0x00 - Grey background (applies to 10.9 and older).
|
|
0x01 - Black background (applies to 10.10 and newer).
|
|
|
|
Valid pair gives APPLE_RTC_BG_COLOR_ADDR ^ APPLE_RTC_BG_COMPLEMENT_ADDR == 0xFF.
|
|
Otherwise background colour should be treated as 0, grey.
|
|
|
|
Prior to rebooting to MacEFI firmare upgrade /usr/libexec/efiupdater
|
|
removes DefaultBackgroundColor NVRAM variable and resets background to black.
|
|
|
|
When performing hibernate wake OSInfo writes chooses the background colour
|
|
based on reported macOS version (grey for 10.9 and below, black otherwise).
|
|
**/
|
|
#define APPLE_RTC_BG_COLOR_ADDR 0x30
|
|
#define APPLE_RTC_BG_COMPLEMENT_ADDR 0x31
|
|
|
|
/**
|
|
APPLE_RTC_BG_COLOR_ADDR values.
|
|
**/
|
|
#define APPLE_RTC_BG_COLOR_GRAY 0x00
|
|
#define APPLE_RTC_BG_COLOR_BLACK 0x01
|
|
|
|
/**
|
|
By default masked out with 0xF8.
|
|
Connected thunderbolt devices can set 3 lower bits.
|
|
BIT3 seems to be set when InstallWindowsUEFI was present at boot.
|
|
|
|
See ThunderboltNhi and PchInitDxe.
|
|
**/
|
|
#define APPLE_RTC_FIRMWARE_STATE_ADDR 0x38
|
|
|
|
/**
|
|
Used by ApplePlatformInit, 1 byte.
|
|
**/
|
|
#define APPLE_RTC_FIRMWARE_3D_ADDR 0x3D
|
|
|
|
/**
|
|
Bitmask of started test indices.
|
|
Little endian 32-bit number.
|
|
Note: memory testing statuses are a bit more complicated,
|
|
but we do not need too much detail atm.
|
|
**/
|
|
#define APPLE_RTC_MEM_TEST_ACCEPT_ADDR 0x44
|
|
|
|
/**
|
|
Bitmask of request test indices.
|
|
Little endian 32-bit number.
|
|
**/
|
|
#define APPLE_RTC_MEM_TEST_REQUEST_ADDR 0x48
|
|
|
|
/**
|
|
Bitmask of performed test indices.
|
|
Little endian 32-bit number.
|
|
**/
|
|
#define APPLE_RTC_MEM_TEST_RESULT_ADDR 0x4C
|
|
|
|
/**
|
|
Another unknown reserved address.
|
|
**/
|
|
#define APPLE_RTC_FIRMWARE_57_ADDR 0x57
|
|
|
|
/**
|
|
Firmware boot progress, mostly maintained by AppleBds.
|
|
|
|
0x00, 0x01, 0x02 - Set by RomIntegrityPei.
|
|
0x04 - Normal boot started. At this step AppleBds will process hibernation,
|
|
enable video output, check battery state, perform memory test, etc.
|
|
0x05 - Exit Boot Services called. Set in AppleBds event handler.
|
|
**/
|
|
#define APPLE_RTC_FIRMWARE_PROGRESS_ADDR 0x5C
|
|
|
|
/**
|
|
Apple RTC reserved memory area for unclear purposes, normally filled with FF.
|
|
Should not be erased during PRAM reset (CMD+OPT+P+R).
|
|
**/
|
|
#define APPLE_RTC_RESERVED_ADDR 0x78
|
|
|
|
/**
|
|
Apple RTC reserved memory size.
|
|
**/
|
|
#define APPLE_RTC_RESERVED_LENGTH 8
|
|
|
|
/**
|
|
Hibernation image encryption data, a copy of IOHibernateRTCVariables.
|
|
See AppleRTCHibernateVars type in AppleHibernate.h for the definition.
|
|
- Valid hibernation image encryption data starts with "AAPL" magic.
|
|
- Erased hibernation image encryption data starts with "DEAD" magic.
|
|
Normally handled by AppleBds prior to transfering control to the bootloader.
|
|
**/
|
|
#define APPLE_RTC_HIBERNATION_KEY_ADDR 0x80
|
|
|
|
/**
|
|
Effectively equals to sizeof (AppleRTCHibernateVars).
|
|
**/
|
|
#define APPLE_RTC_HIBERNATION_KEY_LENGTH 0x2C
|
|
|
|
/**
|
|
Firmware upgrade control and status byte.
|
|
|
|
0x00 - Normal boot. AppleBds resets to this value upon BOOT_ON_FLASH_UPDATE
|
|
prior to running BootRomFlash. BootRomFlash may itself reset to this
|
|
value on successful(?) flashing. Mirrored to NOBP SMC key.
|
|
0x01 - Alternative unsuccessful (?) result of firmware flashing written
|
|
by BootRomFlash. Mirrored to NOBP SMC key. Also set in ApplePlatformInit.
|
|
0x02 - Schedule firmware upgrade. Closed-source bless part writes this value
|
|
when intending to upgrade MacEFI firmware.
|
|
0x03 - Peform firmware upgrade. BootRomFlash writes this value prior to
|
|
rebooting into BOOT_ON_FLASH_UPDATE mode. Might be needed due to region
|
|
unlock.
|
|
**/
|
|
#define APPLE_RTC_FIRMWARE_UPGRADE_ADDR 0xAC
|
|
|
|
/**
|
|
AppleBds zeroes this byte at the same time it reaches normal booting phase (0x4)
|
|
in APPLE_RTC_FIRMWARE_PROGRESS_ADDR. This may be set to non-zero value by ApplePlatformInit.
|
|
**/
|
|
#define APPLE_RTC_FIRMWARE_CHECK_ADDR 0xAF
|
|
|
|
/**
|
|
Data contained in RTC allowing to trace various power management events.
|
|
Called via AppleRTC::rtcRecordTracePoint and also used for EfiBoot wake log.
|
|
**/
|
|
#define APPLE_RTC_TRACE_POINT_ADDR 0xB0
|
|
|
|
/**
|
|
Trace point data contains a total of 8 bytes, but they seem to have varying purpose.
|
|
**/
|
|
#define APPLE_RTC_TRACE_POINT_LENGTH 8
|
|
|
|
/**
|
|
Trace data is a 32-bit value, which format depends on the phase
|
|
(APPLE_RTC_TRACE_PHASE_ADDR) the platform is currently in.
|
|
|
|
For the kernel this may e.g. contain PCI device index currently put
|
|
in sleep or being awoken (kIOPMTracePointSleepPowerPlaneDrivers
|
|
or kIOPMTracePointWakePowerPlaneDrivers).
|
|
|
|
For EfiBoot this is named hibernatin wake log. It is also written to
|
|
wake-failure NVRAM variable (and later DeviceTree).
|
|
**/
|
|
#define APPLE_RTC_TRACE_DATA_ADDR 0xB0
|
|
|
|
/**
|
|
Trace data length.
|
|
**/
|
|
#define APPLE_RTC_TRACE_DATA_LENGTH 4
|
|
|
|
/**
|
|
Mask of events, which happened during booting.
|
|
These events are appended during the boot progress.
|
|
|
|
Note, unlike APPLE_RTC_WL_EVENT_ADDR/APPLE_RTC_WL_EVENT_EXTRA_ADDR,
|
|
which only get updated in hibernate wake, this value is always written
|
|
when a non-zero event is supplied.
|
|
**/
|
|
#define APPLE_RTC_WL_MASK_ADDR 0xB1
|
|
|
|
/**
|
|
Known event bits.
|
|
**/
|
|
#define APPLE_RTC_WL_MASK_BOOT_STARTED BIT0 ///< Called early at boot.efi startup.
|
|
#define APPLE_RTC_WL_MASK_BOOT_FAILED BIT1 ///< gBS->Exit: Boot failed; will sleep for 10 seconds before exiting.
|
|
#define APPLE_RTC_WL_MASK_BOOT_KERNEL BIT2 ///< Called right before jumping to the kernel code.
|
|
#define APPLE_RTC_WL_MASK_CS_UNLOCKED BIT3 ///< Set along with APPLE_RTC_WL_CS_VOLUME_UNLOCKED.
|
|
#define APPLE_RTC_WL_MASK_HIB_CLEAR_KEYS BIT4 ///< Removed boot-image-key, EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_MASK_HIB_CLEAR_IMG BIT5 ///< Removed boot-image, will reboot now.
|
|
#define APPLE_RTC_WL_MASK_BOOT_RESET BIT6 ///< gBS->Reset was called.
|
|
|
|
/**
|
|
Event index that happened last during booting.
|
|
0xB2 is the event type and 0xB3 is its subtype.
|
|
**/
|
|
#define APPLE_RTC_WL_EVENT_ADDR 0xB2
|
|
#define APPLE_RTC_WL_EVENT_EXTRA_ADDR 0xB3
|
|
|
|
/**
|
|
Known events.
|
|
**/
|
|
#define APPLE_RTC_WL_EVENT_DEFAULT 0 ///< For everything.
|
|
#define APPLE_RTC_WL_INIT_DEVICE_TREE 2 ///< Before first "Start InitDeviceTree".
|
|
#define APPLE_RTC_WL_KERNEL_ALLOC_CALL_GATE 3 ///< After "End InitDeviceTree".
|
|
#define APPLE_RTC_WL_INIT_MEMORY_CONFIG 4 ///< Before "Start InitMemoryConfig".
|
|
#define APPLE_RTC_WL_HIB_CHECK 5 ///< Before "Start CheckHibernate".
|
|
#define APPLE_RTC_WL_CS_LOAD_CONFIGURATION 6 ///< Before "Start LoadCoreStorageConfiguration".
|
|
#define APPLE_RTC_WL_GET_FDE_KEY 7 ///< Before reading HBKP key.
|
|
#define APPLE_RTC_WL_HIB_WAKE_START 8 ///< Before reading FACP table.
|
|
#define APPLE_RTC_WL_HIB_GET_MMAP 9 ///< Before GetMemoryMap for hibernation.
|
|
#define APPLE_RTC_WL_HIB_HWSIG_VALID 10 ///< After confirming FACP signature validity with the image.
|
|
#define APPLE_RTC_WL_HIB_MEM_ALLOC 11 ///< Before restore1CodePhysPage / runtimePages allocation.
|
|
#define APPLE_RTC_WL_HIB_SPLASH 12 ///< Before "Start OpenBootGraphics".
|
|
#define APPLE_RTC_WL_HIB_READ 13 ///< After "Start hibernate read".
|
|
#define APPLE_RTC_WL_HIB_HANDOFF 14 ///< Before adjusting IOHibernateImageHeader and booting kernel.
|
|
#define APPLE_RTC_WL_HIB_EXIT_BOOT_SERVICES 15 ///< Done ExitBootServices for hibernate, EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_HIB_KERNEL_START 16 ///< Calling kernel entry point for hibernate.
|
|
#define APPLE_RTC_WL_HIB_FINISH_FDE 17 ///< After "Start FinishFDEHibernate".
|
|
#define APPLE_RTC_WL_HIB_WIRED_KEY_VALID 18 ///< Before APPLE_RTC_WL_HIBERNATE_WAKE_START with valid FDE key.
|
|
#define APPLE_RTC_WL_RECOVERY_OS_FOUND 19 ///< After detecting com.apple.recovery.boot in boot path.
|
|
#define APPLE_RTC_WL_CS_VOLUME_UNLOCKED 20 ///< After "End UnlockCoreStorageVolumeKey" with EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_KERNEL_LOAD_CACHE_FAIL 22 ///< Failed to load kernel cache, EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_HIB_BS_MISSING 23 ///< Missing boot-signature, EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_HIB_BIK_MISSING 24 ///< Missing boot-image-key, EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_RECOVERY_OS_REBOOT 25 ///< Before rebooting into recovery with APPLE_RTC_WL_MASK_BOOT_RESET.
|
|
#define APPLE_RTC_WL_LOGIN_WINDOW_PWRESET 26 ///< Requested FDE password recovery.
|
|
#define APPLE_RTC_WL_LOGIN_WINDOW_GUEST 27 ///< Chose guest in FV2 login window, will gBS->Reset now.
|
|
#define APPLE_RTC_WL_LOGIN_WINDOW_RESET 28 ///< Chose reset in FV2 login window, will gBS->Reset now.
|
|
#define APPLE_RTC_WL_LOGIN_WINDOW_HIB 29 ///< Will save hibernation data after FV2 login window and shutdown.
|
|
#define APPLE_RTC_WL_LOGIN_WINDOW_SHUTDOWN 30 ///< Chose shutdown in FV2 login window, will gBS->Reset now.
|
|
#define APPLE_RTC_WL_LOGIN_WINDOW_FAIL 31 ///< After "End LoginWindow Initialize", EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_HIB_ABORT_SAFE_MODE 32 ///< Hibernation aborted due to safe mode, after "Start CheckHibernate".
|
|
#define APPLE_RTC_WL_HIB_BI_ALLOC 33 ///< Failed to allocate memory for boot-image, EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_HIB_BI_MISSING 34 ///< Missing boot-image variable or 0 size, EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_HIB_BI_INVALID 35 ///< Did not find valid data in boot-image.
|
|
#define APPLE_RTC_WL_HIB_BI_DP_ALLOC 36 ///< Failed to allocate boot-image device path(?).
|
|
#define APPLE_RTC_WL_HIB_BI_DP_ZERO 37 ///< boot-image contains empty DP(?).
|
|
#define APPLE_RTC_WL_HIB_BI_DP_MISSING 38 ///< Failed to locate boot-image device path, EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_HIB_BI_DP_NO_DISK_IO 39 ///< Failed to find Disk I/O protocol, EFI_STATUS in EXTRA.
|
|
#define APPLE_RTC_WL_HIB_BI_DP_NI_BLOCK_IO 40 ///< Failed to find Block I/O protocol, EFI_STATUS in EXTRA.
|
|
|
|
/**
|
|
Certain components have the ability to log their wake progress
|
|
directly via RTC. See XNU IOPMPrivate.h for more details.
|
|
|
|
LoginWindow - 4 bits
|
|
CoreDisplay - 8 bits
|
|
CoreGraphics - 8 bits
|
|
|
|
Apparently these look mostly unused, at least in release builds.
|
|
CoreDisplay is known to report 0 (very helpful) on screen wake.
|
|
I guess we can abuse them if we want.
|
|
**/
|
|
#define APPLE_RTC_TRACE_LOGIN_WINDOW_ADDR 0xB4
|
|
#define APPLE_RTC_TRACE_CORE_DISPLAY_ADDR 0xB5
|
|
#define APPLE_RTC_TRACE_CORE_GRAPHICS_ADDR 0xB6
|
|
|
|
/**
|
|
Trace point power phase e.g. kIOPMTracePointSystemUp.
|
|
See XNU IOPMPrivate.h for more details.
|
|
**/
|
|
#define APPLE_RTC_TRACE_PHASE_ADDR 0xB7
|
|
|
|
/**
|
|
256-bit full disk encryption (FDE) key used for authenticated restart.
|
|
AppleRTC and other kexts name it key stash.
|
|
|
|
Written by AppleRTC at the request of IOHibernateSMCVariables I/O registry
|
|
entry submitted either by XNU kernel or AppleFDEKeyStore.kext. The variable
|
|
itself is a pair of 64-bit values: key size and key address in kernel memory.
|
|
|
|
This was replaced with HBKP SMC key in modern Macs.
|
|
|
|
*** VirtualSMC addendum ***
|
|
|
|
Since this value is no longer used due to HBKP present in almost every Mac
|
|
we badly abuse this area when vertualising SMC.
|
|
|
|
When HBKP SMC key is written VirtualSMC AES-128 encrypts the submitted value
|
|
with a unique key and writes the result to an NVRAM variable (vsmc-key).
|
|
The AES encryption key goes to RTC at this addrress instead.
|
|
Afterwards the EFI module implementing SMC protocol performs the decryption.
|
|
|
|
TODO: Replace AES with one-time pad, i.e. increase the temporary key size
|
|
to 256 bits and just XOR the value. This will break old VirtualSmc.efi
|
|
module, but we do not care anymore.
|
|
**/
|
|
#define APPLE_RTC_FDE_KEY_ADDR 0xD0
|
|
|
|
/**
|
|
FDE key maximum and default, as AES-256-XTS has 256-bit key.
|
|
For smaller keys remaining bytes are zeroed.
|
|
**/
|
|
#define APPLE_RTC_FDE_KEY_LENGTH 0x20
|
|
|
|
/**
|
|
FDE key state. Normally written by ApplePlatformInit.
|
|
|
|
0x00 - The key is either present or not.
|
|
0x41 - The key is not present, and should be copied to RTC from HBKP
|
|
SMC key prior to transfering control to the bootloader. After the
|
|
copying succeeds this value is overwritten with 0x00. Normally
|
|
this is done by AppleBds.
|
|
**/
|
|
#define APPLE_RTC_FDE_STATE_ADDR 0xF0
|
|
|
|
/**
|
|
Known values for APPLE_RTC_FDE_STATE_ADDR.
|
|
**/
|
|
#define APPLE_RTC_FDE_STATE_DEFAULT 0x00
|
|
#define APPLE_RTC_FDE_STATE_NEED_KEY 0x41
|
|
|
|
/**
|
|
Checksum is calculated starting from this address.
|
|
**/
|
|
#define APPLE_RTC_CHECKSUM_START 0x0E
|
|
|
|
/**
|
|
First 64 bytes are RTC core and are hashed separately.
|
|
**/
|
|
#define APPLE_RTC_CORE_SIZE 0x40
|
|
|
|
/**
|
|
All Apple hardware cares about 256 bytes of RTC memory.
|
|
**/
|
|
#define APPLE_RTC_TOTAL_SIZE 0x100
|
|
|
|
/**
|
|
Apple checksum custom CRC polynomial.
|
|
Apple checksum is a modified version of ANSI CRC16 in REFIN mode (0xA001 poly).
|
|
See http://zlib.net/crc_v3.txt for more details.
|
|
|
|
Effective poly is 0x2001 due to a bitwise OR with BIT15.
|
|
The change turns CRC16 into CRC14, making BIT14 and BIT15 always zero.
|
|
This modification is commonly found in legacy Phoenix firmwares,
|
|
where it was used for password hashing as found by dogbert:
|
|
http://sites.google.com/site/dogber1/blag/pwgen-5dec.py
|
|
**/
|
|
#define APPLE_RTC_CHECKSUM_POLYNOMIAL 0x2001
|
|
|
|
/**
|
|
Apple checksum rounds.
|
|
|
|
Only 7 shifts per byte are performed instead of the usual 8.
|
|
This might improve checksum quality against specific data, but the exact
|
|
reasons are unknown. The algorithm did not change since its introduction
|
|
in 10.4.x, and since Apple Developer Transition Kit was based on Phoenix
|
|
firmware, this could just be a quick change to get a different checksum.
|
|
**/
|
|
#define APPLE_RTC_CHECKSUM_ROUNDS 7
|
|
|
|
/**
|
|
Checksum for Apple RTC with core part of the memory hashed:
|
|
[APPLE_RTC_CHECKSUM_SART, APPLE_RTC_CORE_SIZE).
|
|
**/
|
|
#define APPLE_RTC_CORE_CHECKSUM_ADDR1 0x3E
|
|
#define APPLE_RTC_CORE_CHECKSUM_ADDR2 0x3F
|
|
|
|
/**
|
|
Apple RTC core checksum to byte convertion macros.
|
|
BYTE1 BIT0~BIT7 = CHECKSUM BIT0~BIT7
|
|
BYTE2 BIT1~BIT7 = CHECKSUM BIT8~BIT14
|
|
**/
|
|
#define APPLE_RTC_CORE_CHECKSUM_BYTE1(Checksum) ((UINT8) ((UINT32) (Checksum) & 0xFFU))
|
|
#define APPLE_RTC_CORE_CHECKSUM_BYTE2(Checksum) ((UINT8) (((UINT32) (Checksum) >> 7U) & 0xFEU))
|
|
|
|
/**
|
|
Checksum for Apple RTC with all the memory hashed:
|
|
[APPLE_RTC_CHECKSUM_SART, APPLE_RTC_TOTAL_SIZE).
|
|
**/
|
|
#define APPLE_RTC_MAIN_CHECKSUM_ADDR1 0x58
|
|
#define APPLE_RTC_MAIN_CHECKSUM_ADDR2 0x59
|
|
|
|
/**
|
|
Apple RTC main checksum to byte convertion macros.
|
|
BYTE1 BIT0~BIT7 = CHECKSUM BIT0~BIT7
|
|
BYTE2 BIT0~BIT7 = CHECKSUM BIT8~BIT15
|
|
**/
|
|
#define APPLE_RTC_MAIN_CHECKSUM_BYTE1(Checksum) ((UINT8) (((UINT32) (Checksum) >> 8U) & 0xFFU))
|
|
#define APPLE_RTC_MAIN_CHECKSUM_BYTE2(Checksum) ((UINT8) ((UINT32) (Checksum) & 0xFFU))
|
|
|
|
#endif // APPLE_RTC_H
|