2020-02-15 15:51:18 +01:00
/*
* refit / main . c
* Main code for the boot menu
*
* Copyright ( c ) 2006 - 2010 Christoph Pfisterer
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are
* met :
*
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
*
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the
* distribution .
*
* * Neither the name of Christoph Pfisterer nor the names of the
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2020-08-17 21:40:52 +02:00
# include <Platform.h> // Only use angled for Platform, else, xcode project won't compile
2020-04-24 18:24:34 +02:00
# include "../cpp_foundation/XString.h"
2020-02-15 15:51:18 +01:00
# include "../cpp_util/globals_ctor.h"
# include "../cpp_util/globals_dtor.h"
2020-02-23 12:21:28 +01:00
# include "../cpp_unit_test/all_tests.h"
2020-02-15 15:51:18 +01:00
2020-03-13 14:11:58 +01:00
# include "../entry_scan/entry_scan.h"
# include "../libeg/nanosvg.h"
2020-02-29 08:30:21 +01:00
# include "../gui/menu_items/menu_globals.h"
# include "menu.h"
# include "../Platform/Settings.h"
# include "../Platform/DataHubCpu.h"
# include "../Platform/Events.h"
# include "screen.h"
# include "../entry_scan/bootscreen.h"
# include "../Platform/Nvram.h"
2020-04-05 14:25:39 +02:00
# include "../entry_scan/common.h"
# include "../gui/shared_with_menu.h"
2020-04-16 09:15:26 +02:00
# include "../Platform/platformdata.h"
# include "../Platform/guid.h"
# include "../Platform/APFS.h"
# include "../Platform/cpu.h"
# include "../Platform/smbios.h"
# include "../Platform/AcpiPatcher.h"
# include "../Platform/Hibernate.h"
# include "../Platform/LegacyBoot.h"
# include "../Platform/PlatformDriverOverride.h"
# include "../Platform/Edid.h"
# include "../Platform/Console.h"
# include "../Platform/Net.h"
# include "../Platform/spd.h"
# include "../Platform/Injectors.h"
# include "../Platform/StartupSound.h"
# include "../Platform/BootOptions.h"
2020-04-16 11:09:22 +02:00
# include "../Platform/boot.h"
# include "../Platform/kext_inject.h"
2020-08-09 17:55:30 +02:00
# include "../gui/REFIT_MENU_SCREEN.h"
2020-02-20 13:53:27 +01:00
2020-09-07 00:19:48 +02:00
extern " C " {
# include "../../OpenCorePkg/Include/Acidanthera/OpenCore.h"
}
2020-02-15 15:51:18 +01:00
# ifndef DEBUG_ALL
2020-02-18 19:49:54 +01:00
# define DEBUG_MAIN 1
2020-02-15 15:51:18 +01:00
# else
# define DEBUG_MAIN DEBUG_ALL
# endif
# if DEBUG_MAIN == 0
# define DBG(...)
# else
# define DBG(...) DebugLog(DEBUG_MAIN, __VA_ARGS__)
# endif
# ifndef HIBERNATE
# define HIBERNATE 0
# endif
# ifndef CHECK_SMC
# define CHECK_SMC 0
# endif
2020-04-16 11:09:22 +02:00
# define PCAT_RTC_ADDRESS_REGISTER 0x70
# define PCAT_RTC_DATA_REGISTER 0x71
2020-02-15 15:51:18 +01:00
// variables
BOOLEAN gGuiIsReady = FALSE ;
BOOLEAN gThemeNeedInit = TRUE ;
BOOLEAN DoHibernateWake = FALSE ;
EFI_HANDLE ConsoleInHandle ;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL * SimpleTextEx ;
EFI_KEY_DATA KeyData ;
2020-06-18 18:08:00 +02:00
EFI_HANDLE AudioDriverHandle ;
2020-02-17 21:41:09 +01:00
CONST CHAR8 * AudioOutputNames [ ] = {
2020-02-15 15:51:18 +01:00
" LineOut " ,
" Speaker " ,
" Headphones " ,
" SPDIF " ,
" Garniture " ,
" HDMI " ,
" Other "
} ;
extern VOID HelpRefit ( VOID ) ;
extern VOID AboutRefit ( VOID ) ;
2020-05-01 18:26:28 +02:00
//extern BOOLEAN BooterPatch(IN UINT8 *BooterData, IN UINT64 BooterSize, LOADER_ENTRY *Entry);
2020-02-15 15:51:18 +01:00
extern UINTN ConfigsNum ;
extern CHAR16 * ConfigsList [ ] ;
extern UINTN DsdtsNum ;
extern CHAR16 * DsdtsList [ ] ;
extern EFI_AUDIO_IO_PROTOCOL * AudioIo ;
2020-08-25 17:35:19 +02:00
extern EFI_DXE_SERVICES * gDS ;
2020-02-21 22:22:30 +01:00
//#ifdef _cplusplus
//void FreePool(const wchar_t * A)
//{
// FreePool((VOID*)A);
//}
//#endif
2020-02-20 13:53:27 +01:00
2020-02-15 15:51:18 +01:00
static EFI_STATUS LoadEFIImageList ( IN EFI_DEVICE_PATH * * DevicePaths ,
2020-04-27 11:50:49 +02:00
IN CONST XStringW & ImageTitle ,
2020-02-15 15:51:18 +01:00
OUT UINTN * ErrorInStep ,
OUT EFI_HANDLE * NewImageHandle )
{
EFI_STATUS Status , ReturnStatus ;
EFI_HANDLE ChildImageHandle = 0 ;
UINTN DevicePathIndex ;
CHAR16 ErrorInfo [ 256 ] ;
2020-04-27 11:50:49 +02:00
DBG ( " Loading %ls " , ImageTitle . wc_str ( ) ) ;
2020-02-15 15:51:18 +01:00
if ( ErrorInStep ! = NULL ) {
* ErrorInStep = 0 ;
}
if ( NewImageHandle ! = NULL ) {
* NewImageHandle = NULL ;
}
// load the image into memory
ReturnStatus = Status = EFI_NOT_FOUND ; // in case the list is empty
for ( DevicePathIndex = 0 ; DevicePaths [ DevicePathIndex ] ! = NULL ; DevicePathIndex + + ) {
ReturnStatus = Status = gBS - > LoadImage ( FALSE , SelfImageHandle , DevicePaths [ DevicePathIndex ] , NULL , 0 , & ChildImageHandle ) ;
2020-08-25 17:35:19 +02:00
DBG ( " status=%s " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
if ( ReturnStatus ! = EFI_NOT_FOUND )
break ;
}
2020-04-27 11:50:49 +02:00
snwprintf ( ErrorInfo , 512 , " while loading %ls " , ImageTitle . wc_str ( ) ) ;
2020-02-15 15:51:18 +01:00
if ( CheckError ( Status , ErrorInfo ) ) {
if ( ErrorInStep ! = NULL )
* ErrorInStep = 1 ;
PauseForKey ( L " press any key " ) ;
goto bailout ;
}
if ( ! EFI_ERROR ( ReturnStatus ) ) { //why unload driver?!
if ( NewImageHandle ! = NULL ) {
* NewImageHandle = ChildImageHandle ;
}
2020-02-23 12:20:22 +01:00
# ifdef JIEF_DEBUG
2020-02-18 07:03:14 +01:00
EFI_LOADED_IMAGE_PROTOCOL * loadedBootImage = NULL ;
if ( ! EFI_ERROR ( Status = gBS - > HandleProtocol ( ChildImageHandle , & gEfiLoadedImageProtocolGuid , ( void * * ) ( & loadedBootImage ) ) ) ) {
2020-04-27 11:50:49 +02:00
DBG ( " %S : Image base = 0x%llx " , ImageTitle . wc_str ( ) , ( uintptr_t ) loadedBootImage - > ImageBase ) ; // Jief : Do not change this, it's used by grep to feed the debugger
2020-02-18 07:03:14 +01:00
} else {
DBG ( " Can't get loaded image protocol " ) ;
}
# endif
2020-02-15 15:51:18 +01:00
goto bailout ;
}
// unload the image, we don't care if it works or not...
Status = gBS - > UnloadImage ( ChildImageHandle ) ;
bailout :
DBG ( " \n " ) ;
return ReturnStatus ;
}
static EFI_STATUS StartEFILoadedImage ( IN EFI_HANDLE ChildImageHandle ,
2020-08-11 08:00:19 +02:00
IN CONST XString8Array & LoadOptions , IN CONST CHAR16 * LoadOptionsPrefix ,
2020-04-27 11:50:49 +02:00
IN CONST XStringW & ImageTitle ,
2020-02-15 15:51:18 +01:00
OUT UINTN * ErrorInStep )
{
2020-04-11 19:55:47 +02:00
EFI_STATUS Status , ReturnStatus ;
EFI_LOADED_IMAGE_PROTOCOL * ChildLoadedImage ;
CHAR16 ErrorInfo [ 256 ] ;
2020-04-05 14:25:39 +02:00
// CHAR16 *FullLoadOptions = NULL;
2020-04-27 21:20:16 +02:00
XStringW loadOptionsW ; // This has to be declared here, so it's not be freed before calling StartImage
2020-02-15 15:51:18 +01:00
2020-03-25 19:32:44 +01:00
// DBG("Starting %ls\n", ImageTitle);
2020-02-15 15:51:18 +01:00
if ( ErrorInStep ! = NULL ) {
* ErrorInStep = 0 ;
}
ReturnStatus = Status = EFI_NOT_FOUND ; // in case no image handle was specified
if ( ChildImageHandle = = NULL ) {
if ( ErrorInStep ! = NULL ) * ErrorInStep = 1 ;
goto bailout ;
}
// set load options
2020-04-05 14:25:39 +02:00
if ( ! LoadOptions . isEmpty ( ) ) {
2020-02-15 15:51:18 +01:00
ReturnStatus = Status = gBS - > HandleProtocol ( ChildImageHandle , & gEfiLoadedImageProtocolGuid , ( VOID * * ) & ChildLoadedImage ) ;
if ( CheckError ( Status , L " while getting a LoadedImageProtocol handle " ) ) {
if ( ErrorInStep ! = NULL )
* ErrorInStep = 2 ;
goto bailout_unload ;
}
if ( LoadOptionsPrefix ! = NULL ) {
// NOTE: That last space is also added by the EFI shell and seems to be significant
// when passing options to Apple's boot.efi...
2020-08-12 17:15:47 +02:00
loadOptionsW = SWPrintf ( " %ls %s " , LoadOptionsPrefix , LoadOptions . ConcatAll ( " " _XS8 ) . c_str ( ) ) ;
2020-04-05 14:25:39 +02:00
} else {
2020-08-12 17:15:47 +02:00
loadOptionsW = SWPrintf ( " %s " , LoadOptions . ConcatAll ( " " _XS8 ) . c_str ( ) ) ; // Jief : should we add a space ? Wasn't the case before big refactoring. Yes, a space required.
2020-02-15 15:51:18 +01:00
}
// NOTE: We also include the terminating null in the length for safety.
2020-04-05 14:25:39 +02:00
ChildLoadedImage - > LoadOptionsSize = ( UINT32 ) loadOptionsW . sizeInBytes ( ) + sizeof ( wchar_t ) ;
2020-04-26 15:07:30 +02:00
ChildLoadedImage - > LoadOptions = loadOptionsW . wc_str ( ) ; //will it be deleted after the procedure exit? Yes, if we don't copy loadOptionsW, so it'll be freed at the end of method
2020-02-15 15:51:18 +01:00
//((UINT32)StrLen(LoadOptions) + 1) * sizeof(CHAR16);
2020-04-27 11:50:49 +02:00
DBG ( " start image '%ls' \n " , ImageTitle . s ( ) ) ;
2020-04-11 19:55:47 +02:00
DBG ( " Using load options '%ls' \n " , ( CHAR16 * ) ChildLoadedImage - > LoadOptions ) ;
2020-02-15 15:51:18 +01:00
}
//DBG("Image loaded at: %p\n", ChildLoadedImage->ImageBase);
//PauseForKey(L"continue");
// close open file handles
UninitRefitLib ( ) ;
// turn control over to the image
//
// Before calling the image, enable the Watchdog Timer for
// the 5 Minute period - Slice - NO! For slow driver and slow disk we need more
//
gBS - > SetWatchdogTimer ( 600 , 0x0000 , 0x00 , NULL ) ;
ReturnStatus = Status = gBS - > StartImage ( ChildImageHandle , NULL , NULL ) ;
//
// Clear the Watchdog Timer after the image returns
//
gBS - > SetWatchdogTimer ( 0x0000 , 0x0000 , 0x0000 , NULL ) ;
//PauseForKey(L"Returned from StartImage\n");
// control returns here when the child image calls Exit()
2020-04-27 11:50:49 +02:00
if ( ImageTitle . notEmpty ( ) ) {
snwprintf ( ErrorInfo , 512 , " returned from %ls " , ImageTitle . s ( ) ) ;
2020-02-15 15:51:18 +01:00
}
if ( CheckError ( Status , ErrorInfo ) ) {
if ( ErrorInStep ! = NULL )
* ErrorInStep = 3 ;
}
if ( ! EFI_ERROR ( ReturnStatus ) ) { //why unload driver?!
goto bailout ;
}
bailout_unload :
// unload the image, we don't care if it works or not...
Status = gBS - > UnloadImage ( ChildImageHandle ) ;
bailout :
return ReturnStatus ;
}
static EFI_STATUS LoadEFIImage ( IN EFI_DEVICE_PATH * DevicePath ,
2020-04-27 11:50:49 +02:00
IN CONST XStringW & ImageTitle ,
2020-02-15 15:51:18 +01:00
OUT UINTN * ErrorInStep ,
OUT EFI_HANDLE * NewImageHandle )
{
EFI_DEVICE_PATH * DevicePaths [ 2 ] ;
# ifdef ENABLE_SECURE_BOOT
// Verify secure boot policy
if ( gSettings . SecureBoot & & gSettings . SecureBootSetupMode ) {
// Only verify if in forced secure boot mode
EFI_STATUS Status = VerifySecureBootImage ( DevicePath ) ;
if ( EFI_ERROR ( Status ) ) {
return Status ;
}
}
# endif // ENABLE_SECURE_BOOT
// Load the image now
DevicePaths [ 0 ] = DevicePath ;
DevicePaths [ 1 ] = NULL ;
return LoadEFIImageList ( DevicePaths , ImageTitle , ErrorInStep , NewImageHandle ) ;
}
static EFI_STATUS StartEFIImage ( IN EFI_DEVICE_PATH * DevicePath ,
2020-08-11 08:00:19 +02:00
IN CONST XString8Array & LoadOptions , IN CONST CHAR16 * LoadOptionsPrefix ,
2020-04-27 11:50:49 +02:00
IN CONST XStringW & ImageTitle ,
2020-02-15 15:51:18 +01:00
OUT UINTN * ErrorInStep ,
OUT EFI_HANDLE * NewImageHandle )
{
EFI_STATUS Status ;
EFI_HANDLE ChildImageHandle = NULL ;
Status = LoadEFIImage ( DevicePath , ImageTitle , ErrorInStep , & ChildImageHandle ) ;
if ( ! EFI_ERROR ( Status ) ) {
Status = StartEFILoadedImage ( ChildImageHandle , LoadOptions , LoadOptionsPrefix , ImageTitle , ErrorInStep ) ;
}
if ( NewImageHandle ! = NULL ) {
* NewImageHandle = ChildImageHandle ;
}
return Status ;
}
/*
static EFI_STATUS StartEFIImageList ( IN EFI_DEVICE_PATH * * DevicePaths ,
IN CHAR16 * LoadOptions , IN CHAR16 * LoadOptionsPrefix ,
IN CHAR16 * ImageTitle ,
OUT UINTN * ErrorInStep ,
OUT EFI_HANDLE * NewImageHandle )
{
EFI_STATUS Status ;
EFI_HANDLE ChildImageHandle = NULL ;
Status = LoadEFIImageList ( DevicePaths , ImageTitle , ErrorInStep , & ChildImageHandle ) ;
if ( ! EFI_ERROR ( Status ) ) {
Status = StartEFILoadedImage ( ChildImageHandle , LoadOptions , LoadOptionsPrefix , ImageTitle , ErrorInStep ) ;
}
if ( NewImageHandle ! = NULL ) {
* NewImageHandle = ChildImageHandle ;
}
return Status ;
}
*/
2020-02-18 19:49:54 +01:00
/*
static CONST CHAR8 * SearchString (
2020-02-17 21:41:09 +01:00
IN CONST CHAR8 * Source ,
2020-02-15 15:51:18 +01:00
IN UINT64 SourceSize ,
2020-02-17 21:41:09 +01:00
IN CONST CHAR8 * Search ,
2020-02-15 15:51:18 +01:00
IN UINTN SearchSize
)
{
2020-02-17 21:41:09 +01:00
CONST CHAR8 * End = Source + SourceSize ;
2020-02-15 15:51:18 +01:00
while ( Source < End ) {
if ( CompareMem ( Source , Search , SearchSize ) = = 0 ) {
return Source ;
} else {
Source + + ;
}
}
return NULL ;
}
2020-02-18 19:49:54 +01:00
*/
2020-02-15 15:51:18 +01:00
# ifdef DUMP_KERNEL_KEXT_PATCHES
VOID DumpKernelAndKextPatches ( KERNEL_AND_KEXT_PATCHES * Patches )
{
if ( ! Patches ) {
DBG ( " Kernel and Kext Patches null pointer \n " ) ;
return ;
}
DBG ( " Kernel and Kext Patches at %p: \n " , Patches ) ;
DBG ( " \t Allowed: %c \n " , gSettings . KextPatchesAllowed ? ' y ' : ' n ' ) ;
DBG ( " \t Debug: %c \n " , Patches - > KPDebug ? ' y ' : ' n ' ) ;
2020-05-09 10:55:33 +02:00
// DBG("\tKernelCpu: %c\n", Patches->KPKernelCpu ? 'y' : 'n');
2020-02-15 15:51:18 +01:00
DBG ( " \t KernelLapic: %c \n " , Patches - > KPKernelLapic ? ' y ' : ' n ' ) ;
DBG ( " \t KernelXCPM: %c \n " , Patches - > KPKernelXCPM ? ' y ' : ' n ' ) ;
DBG ( " \t KernelPm: %c \n " , Patches - > KPKernelPm ? ' y ' : ' n ' ) ;
DBG ( " \t AppleIntelCPUPM: %c \n " , Patches - > KPAppleIntelCPUPM ? ' y ' : ' n ' ) ;
DBG ( " \t AppleRTC: %c \n " , Patches - > KPAppleRTC ? ' y ' : ' n ' ) ;
// Dell smbios truncate fix
DBG ( " \t DellSMBIOSPatch: %c \n " , Patches - > KPDELLSMBIOS ? ' y ' : ' n ' ) ;
2020-03-25 19:32:44 +01:00
DBG ( " \t FakeCPUID: 0x%X \n " , Patches - > FakeCPUID ) ;
2020-04-11 17:36:40 +02:00
DBG ( " \t ATIController: %s \n " , ( Patches - > KPATIConnectorsController = = NULL ) ? " (null) " : Patches - > KPATIConnectorsController ) ;
2020-02-15 15:51:18 +01:00
DBG ( " \t ATIDataLength: %d \n " , Patches - > KPATIConnectorsDataLen ) ;
2020-08-12 17:15:47 +02:00
DBG ( " \t %d Kexts to load \n " , Patches - > ForceKexts . size ( ) ) ;
2020-02-15 15:51:18 +01:00
if ( Patches - > ForceKexts ) {
INTN i = 0 ;
2020-08-12 17:15:47 +02:00
for ( ; i < Patches - > ForceKexts . size ( ) ; + + i ) {
2020-03-25 19:32:44 +01:00
DBG ( " \t KextToLoad[%d]: %ls \n " , i , Patches - > ForceKexts [ i ] ) ;
2020-02-15 15:51:18 +01:00
}
}
2020-08-12 17:15:47 +02:00
DBG ( " \t %d Kexts to patch \n " , Patches - > KextPatches . size ( ) ) ;
2020-02-15 15:51:18 +01:00
if ( Patches - > KextPatches ) {
INTN i = 0 ;
2020-08-12 17:15:47 +02:00
for ( ; i < Patches - > KextPatches . size ( ) ; + + i ) {
2020-02-15 15:51:18 +01:00
if ( Patches - > KextPatches [ i ] . IsPlistPatch ) {
2020-03-25 19:32:44 +01:00
DBG ( " \t KextPatchPlist[%d]: %d bytes, %s \n " , i , Patches - > KextPatches [ i ] . DataLen , Patches - > KextPatches [ i ] . Name ) ;
2020-02-15 15:51:18 +01:00
} else {
2020-03-25 19:32:44 +01:00
DBG ( " \t KextPatch[%d]: %d bytes, %s \n " , i , Patches - > KextPatches [ i ] . DataLen , Patches - > KextPatches [ i ] . Name ) ;
2020-02-15 15:51:18 +01:00
}
}
}
}
# endif
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : FilterKextPatches ( )
2020-02-15 15:51:18 +01:00
{
2020-08-12 17:15:47 +02:00
if ( gSettings . KextPatchesAllowed & & KernelAndKextPatches . KextPatches . size ( ) > 0 ) {
2020-02-15 15:51:18 +01:00
DBG ( " Filtering KextPatches: \n " ) ;
2020-08-12 17:15:47 +02:00
for ( size_t i = 0 ; i < KernelAndKextPatches . KextPatches . size ( ) ; i + + ) {
DBG ( " - [%02zu]: %s :: %s :: [OS: %s | MatchOS: %s | MatchBuild: %s] " ,
2020-02-15 15:51:18 +01:00
i ,
2020-08-12 17:15:47 +02:00
KernelAndKextPatches . KextPatches [ i ] . Label . c_str ( ) ,
2020-08-11 14:43:53 +02:00
KernelAndKextPatches . KextPatches [ i ] . IsPlistPatch ? " PlistPatch " : " BinPatch " ,
2020-08-12 17:15:47 +02:00
OSVersion . c_str ( ) ,
KernelAndKextPatches . KextPatches [ i ] . MatchOS . notEmpty ( ) ? KernelAndKextPatches . KextPatches [ i ] . MatchOS . c_str ( ) : " All " ,
KernelAndKextPatches . KextPatches [ i ] . MatchBuild . notEmpty ( ) ? KernelAndKextPatches . KextPatches [ i ] . MatchBuild . c_str ( ) : " All "
2020-02-15 15:51:18 +01:00
) ;
2020-08-11 14:43:53 +02:00
if ( ! KernelAndKextPatches . KextPatches [ i ] . MenuItem . BValue ) {
2020-02-15 15:51:18 +01:00
DBG ( " ==> disabled by user \n " ) ;
continue ;
}
2020-08-12 17:15:47 +02:00
if ( ( BuildVersion . notEmpty ( ) ) & & ( KernelAndKextPatches . KextPatches [ i ] . MatchBuild . notEmpty ( ) ) ) {
2020-08-11 14:43:53 +02:00
KernelAndKextPatches . KextPatches [ i ] . MenuItem . BValue = IsPatchEnabled ( KernelAndKextPatches . KextPatches [ i ] . MatchBuild , BuildVersion ) ;
DBG ( " ==> %s \n " , KernelAndKextPatches . KextPatches [ i ] . MenuItem . BValue ? " allowed " : " not allowed " ) ;
2020-02-15 15:51:18 +01:00
continue ;
}
2020-08-11 14:43:53 +02:00
KernelAndKextPatches . KextPatches [ i ] . MenuItem . BValue = IsPatchEnabled ( KernelAndKextPatches . KextPatches [ i ] . MatchOS , OSVersion ) ;
DBG ( " ==> %s \n " , KernelAndKextPatches . KextPatches [ i ] . MenuItem . BValue ? " allowed " : " not allowed " ) ;
2020-02-15 15:51:18 +01:00
}
}
}
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : FilterKernelPatches ( )
2020-02-15 15:51:18 +01:00
{
2020-08-12 17:15:47 +02:00
if ( gSettings . KernelPatchesAllowed & & KernelAndKextPatches . KernelPatches . notEmpty ( ) ) {
2020-02-15 15:51:18 +01:00
DBG ( " Filtering KernelPatches: \n " ) ;
2020-08-12 17:15:47 +02:00
for ( size_t i = 0 ; i < KernelAndKextPatches . KernelPatches . size ( ) ; + + i ) {
DBG ( " - [%02zu]: %s :: [OS: %s | MatchOS: %s | MatchBuild: %s] " ,
2020-02-15 15:51:18 +01:00
i ,
2020-08-12 17:15:47 +02:00
KernelAndKextPatches . KernelPatches [ i ] . Label . c_str ( ) ,
OSVersion . c_str ( ) ,
KernelAndKextPatches . KernelPatches [ i ] . MatchOS . notEmpty ( ) ? KernelAndKextPatches . KernelPatches [ i ] . MatchOS . c_str ( ) : " All " ,
KernelAndKextPatches . KernelPatches [ i ] . MatchBuild . notEmpty ( ) ? KernelAndKextPatches . KernelPatches [ i ] . MatchBuild . c_str ( ) : " no "
2020-02-15 15:51:18 +01:00
) ;
2020-08-11 14:43:53 +02:00
if ( ! KernelAndKextPatches . KernelPatches [ i ] . MenuItem . BValue ) {
2020-02-15 15:51:18 +01:00
DBG ( " ==> disabled by user \n " ) ;
continue ;
}
2020-08-12 17:15:47 +02:00
if ( ( BuildVersion . notEmpty ( ) ) & & ( KernelAndKextPatches . KernelPatches [ i ] . MatchBuild . notEmpty ( ) ) ) {
2020-08-11 14:43:53 +02:00
KernelAndKextPatches . KernelPatches [ i ] . MenuItem . BValue = IsPatchEnabled ( KernelAndKextPatches . KernelPatches [ i ] . MatchBuild , BuildVersion ) ;
DBG ( " ==> %s by build \n " , KernelAndKextPatches . KernelPatches [ i ] . MenuItem . BValue ? " allowed " : " not allowed " ) ;
2020-02-15 15:51:18 +01:00
continue ;
}
2020-08-11 14:43:53 +02:00
KernelAndKextPatches . KernelPatches [ i ] . MenuItem . BValue = IsPatchEnabled ( KernelAndKextPatches . KernelPatches [ i ] . MatchOS , OSVersion ) ;
DBG ( " ==> %s by OS \n " , KernelAndKextPatches . KernelPatches [ i ] . MenuItem . BValue ? " allowed " : " not allowed " ) ;
2020-02-15 15:51:18 +01:00
}
}
}
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : FilterBootPatches ( )
2020-02-15 15:51:18 +01:00
{
2020-08-12 17:15:47 +02:00
if ( KernelAndKextPatches . BootPatches . notEmpty ( ) ) {
2020-02-15 15:51:18 +01:00
DBG ( " Filtering BootPatches: \n " ) ;
2020-08-12 17:15:47 +02:00
for ( size_t i = 0 ; i < KernelAndKextPatches . BootPatches . size ( ) ; + + i ) {
DBG ( " - [%02zu]: %s :: [OS: %s | MatchOS: %s | MatchBuild: %s] " ,
2020-02-15 15:51:18 +01:00
i ,
2020-08-12 17:15:47 +02:00
KernelAndKextPatches . BootPatches [ i ] . Label . c_str ( ) ,
OSVersion . c_str ( ) ,
KernelAndKextPatches . BootPatches [ i ] . MatchOS . notEmpty ( ) ? KernelAndKextPatches . BootPatches [ i ] . MatchOS . c_str ( ) : " All " ,
KernelAndKextPatches . BootPatches [ i ] . MatchBuild . notEmpty ( ) ? KernelAndKextPatches . BootPatches [ i ] . MatchBuild . c_str ( ) : " no "
2020-02-15 15:51:18 +01:00
) ;
2020-08-11 14:43:53 +02:00
if ( ! KernelAndKextPatches . BootPatches [ i ] . MenuItem . BValue ) {
2020-02-15 15:51:18 +01:00
DBG ( " ==> disabled by user \n " ) ;
continue ;
}
2020-08-12 17:15:47 +02:00
if ( ( BuildVersion . notEmpty ( ) ) & & ( KernelAndKextPatches . BootPatches [ i ] . MatchBuild . notEmpty ( ) ) ) {
2020-08-11 14:43:53 +02:00
KernelAndKextPatches . BootPatches [ i ] . MenuItem . BValue = IsPatchEnabled ( KernelAndKextPatches . BootPatches [ i ] . MatchBuild , BuildVersion ) ;
DBG ( " ==> %s by build \n " , KernelAndKextPatches . BootPatches [ i ] . MenuItem . BValue ? " allowed " : " not allowed " ) ;
2020-02-15 15:51:18 +01:00
continue ;
}
2020-08-11 14:43:53 +02:00
KernelAndKextPatches . BootPatches [ i ] . MenuItem . BValue = IsPatchEnabled ( KernelAndKextPatches . BootPatches [ i ] . MatchOS , OSVersion ) ;
DBG ( " ==> %s by OS \n " , KernelAndKextPatches . BootPatches [ i ] . MenuItem . BValue ? " allowed " : " not allowed " ) ;
2020-02-15 15:51:18 +01:00
}
}
}
2020-07-14 10:20:54 +02:00
/*
2020-02-15 15:51:18 +01:00
VOID ReadSIPCfg ( )
{
UINT32 csrCfg = gSettings . CsrActiveConfig & CSR_VALID_FLAGS ;
2020-08-15 15:47:56 +02:00
CHAR16 * csrLog = ( __typeof__ ( csrLog ) ) AllocateZeroPool ( SVALUE_MAX_SIZE ) ;
2020-02-15 15:51:18 +01:00
if ( csrCfg & CSR_ALLOW_UNTRUSTED_KEXTS )
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , L " CSR_ALLOW_UNTRUSTED_KEXTS " ) ;
if ( csrCfg & CSR_ALLOW_UNRESTRICTED_FS )
2020-08-09 17:55:30 +02:00
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , P__oolPrint ( L " %a%a " , StrLen ( csrLog ) ? " | " : " " , " CSR_ALLOW_UNRESTRICTED_FS " ) ) ;
2020-02-15 15:51:18 +01:00
if ( csrCfg & CSR_ALLOW_TASK_FOR_PID )
2020-08-09 17:55:30 +02:00
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , P__oolPrint ( L " %a%a " , StrLen ( csrLog ) ? " | " : " " , " CSR_ALLOW_TASK_FOR_PID " ) ) ;
2020-02-15 15:51:18 +01:00
if ( csrCfg & CSR_ALLOW_KERNEL_DEBUGGER )
2020-08-09 17:55:30 +02:00
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , P__oolPrint ( L " %a%a " , StrLen ( csrLog ) ? " | " : " " , " CSR_ALLOW_KERNEL_DEBUGGER " ) ) ;
2020-02-15 15:51:18 +01:00
if ( csrCfg & CSR_ALLOW_APPLE_INTERNAL )
2020-08-09 17:55:30 +02:00
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , P__oolPrint ( L " %a%a " , StrLen ( csrLog ) ? " | " : " " , " CSR_ALLOW_APPLE_INTERNAL " ) ) ;
2020-02-15 15:51:18 +01:00
if ( csrCfg & CSR_ALLOW_UNRESTRICTED_DTRACE )
2020-08-09 17:55:30 +02:00
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , P__oolPrint ( L " %a%a " , StrLen ( csrLog ) ? " | " : " " , " CSR_ALLOW_UNRESTRICTED_DTRACE " ) ) ;
2020-02-15 15:51:18 +01:00
if ( csrCfg & CSR_ALLOW_UNRESTRICTED_NVRAM )
2020-08-09 17:55:30 +02:00
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , P__oolPrint ( L " %a%a " , StrLen ( csrLog ) ? " | " : " " , " CSR_ALLOW_UNRESTRICTED_NVRAM " ) ) ;
2020-02-15 15:51:18 +01:00
if ( csrCfg & CSR_ALLOW_DEVICE_CONFIGURATION )
2020-08-09 17:55:30 +02:00
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , P__oolPrint ( L " %a%a " , StrLen ( csrLog ) ? " | " : " " , " CSR_ALLOW_DEVICE_CONFIGURATION " ) ) ;
2020-02-15 15:51:18 +01:00
if ( csrCfg & CSR_ALLOW_ANY_RECOVERY_OS )
2020-08-09 17:55:30 +02:00
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , P__oolPrint ( L " %a%a " , StrLen ( csrLog ) ? " | " : " " , " CSR_ALLOW_ANY_RECOVERY_OS " ) ) ;
2020-02-15 15:51:18 +01:00
if ( csrCfg & CSR_ALLOW_UNAPPROVED_KEXTS )
2020-08-09 17:55:30 +02:00
StrCatS ( csrLog , SVALUE_MAX_SIZE / 2 , P__oolPrint ( L " %a%a " , StrLen ( csrLog ) ? " | " : " " , " CSR_ALLOW_UNAPPROVED_KEXTS " ) ) ;
2020-02-15 15:51:18 +01:00
if ( StrLen ( csrLog ) ) {
2020-03-25 19:32:44 +01:00
DBG ( " CSR_CFG: %ls \n " , csrLog ) ;
2020-02-15 15:51:18 +01:00
}
FreePool ( csrLog ) ;
}
2020-07-14 10:20:54 +02:00
*/
2020-02-15 15:51:18 +01:00
//
// Null ConOut OutputString() implementation - for blocking
// text output from boot.efi when booting in graphics mode
//
EFI_STATUS EFIAPI
2020-02-20 17:24:30 +01:00
NullConOutOutputString ( IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * This , IN CONST CHAR16 * String ) {
2020-02-15 15:51:18 +01:00
return EFI_SUCCESS ;
}
//
// EFI OS loader functions
//
2020-04-01 14:57:32 +02:00
//EG_PIXEL DarkBackgroundPixel = { 0x0, 0x0, 0x0, 0xFF };
2020-02-15 15:51:18 +01:00
2020-02-18 19:49:54 +01:00
VOID CheckEmptyFB ( )
{
BOOLEAN EmptyFB = ( gSettings . IgPlatform = = 0x00050000 ) | |
( gSettings . IgPlatform = = 0x01620007 ) | |
( gSettings . IgPlatform = = 0x04120004 ) | |
( gSettings . IgPlatform = = 0x19120001 ) | |
( gSettings . IgPlatform = = 0x59120003 ) | |
( gSettings . IgPlatform = = 0x3E910003 ) ;
if ( EmptyFB ) {
gPlatformFeature | = PT_FEATURE_HAS_HEADLESS_GPU ;
} else {
gPlatformFeature & = ~ PT_FEATURE_HAS_HEADLESS_GPU ;
}
}
2020-05-01 18:26:28 +02:00
VOID LOADER_ENTRY : : StartLoader ( )
2020-02-15 15:51:18 +01:00
{
2020-09-07 00:19:48 +02:00
if ( OSVersion . startWith ( " 11 " ) ) {
StartLoader11 ( ) ;
return ;
}
2020-02-15 15:51:18 +01:00
EFI_STATUS Status ;
EFI_TEXT_STRING ConOutOutputString = 0 ;
EFI_HANDLE ImageHandle = NULL ;
EFI_LOADED_IMAGE * LoadedImage = NULL ;
2020-02-17 21:41:09 +01:00
CONST CHAR8 * InstallerVersion ;
2020-08-25 17:35:19 +02:00
TagDict * dict = NULL ;
2020-02-15 15:51:18 +01:00
UINTN i ;
2020-03-10 15:05:39 +01:00
NSVGfont * font ; // , *nextFont;
2020-02-15 15:51:18 +01:00
// DBG("StartLoader() start\n");
DbgHeader ( " StartLoader " ) ;
2020-08-09 17:55:30 +02:00
if ( Settings . notEmpty ( ) ) {
DBG ( " Settings: %ls \n " , Settings . wc_str ( ) ) ;
2020-05-01 18:26:28 +02:00
Status = LoadUserSettings ( SelfRootDir , Settings , & dict ) ;
2020-02-15 15:51:18 +01:00
if ( ! EFI_ERROR ( Status ) ) {
2020-08-09 17:55:30 +02:00
DBG ( " - found custom settings for this entry: %ls \n " , Settings . wc_str ( ) ) ;
2020-02-15 15:51:18 +01:00
gBootChanged = TRUE ;
2020-08-25 17:35:19 +02:00
Status = GetUserSettings ( dict ) ;
2020-02-15 15:51:18 +01:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - ... but: %s \n " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
} else {
if ( ( gSettings . CpuFreqMHz > 100 ) & & ( gSettings . CpuFreqMHz < 20000 ) ) {
gCPUStructure . MaxSpeed = gSettings . CpuFreqMHz ;
}
2020-05-01 18:26:28 +02:00
//CopyMem(KernelAndKextPatches,
2020-02-15 15:51:18 +01:00
// &gSettings.KernelAndKextPatches,
// sizeof(KERNEL_AND_KEXT_PATCHES));
//DBG("Custom KernelAndKextPatches copyed to started entry\n");
}
} else {
2020-08-25 17:35:19 +02:00
DBG ( " - [!] LoadUserSettings failed: %s \n " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
}
2020-03-25 19:32:44 +01:00
DBG ( " Finally: ExternalClock=%lluMHz BusSpeed=%llukHz CPUFreq=%uMHz " ,
2020-02-15 15:51:18 +01:00
DivU64x32 ( gCPUStructure . ExternalClock + kilo - 1 , kilo ) ,
DivU64x32 ( gCPUStructure . FSBFrequency + kilo - 1 , kilo ) ,
gCPUStructure . MaxSpeed ) ;
if ( gSettings . QPI ) {
2020-03-25 19:32:44 +01:00
DBG ( " QPI: hw.busfrequency=%lluHz \n " , MultU64x32 ( gSettings . QPI , Mega ) ) ;
2020-02-15 15:51:18 +01:00
} else {
// to match the value of hw.busfrequency in the terminal
2020-03-25 19:32:44 +01:00
DBG ( " PIS: hw.busfrequency=%lluHz \n " , MultU64x32 ( LShiftU64 ( DivU64x32 ( gCPUStructure . ExternalClock + kilo - 1 , kilo ) , 2 ) , Mega ) ) ;
2020-02-15 15:51:18 +01:00
}
//Free memory
for ( i = 0 ; i < ConfigsNum ; i + + ) {
if ( ConfigsList [ i ] ) {
FreePool ( ConfigsList [ i ] ) ;
ConfigsList [ i ] = NULL ;
}
}
for ( i = 0 ; i < DsdtsNum ; i + + ) {
if ( DsdtsList [ i ] ) {
FreePool ( DsdtsList [ i ] ) ;
DsdtsList [ i ] = NULL ;
}
}
2020-03-03 21:44:07 +01:00
OptionMenu . FreeMenu ( ) ;
2020-02-15 15:51:18 +01:00
//there is a place to free memory
// GuiAnime
// mainParser
// BuiltinIcons
// OSIcons
2020-03-10 14:00:02 +01:00
NSVGfontChain * fontChain = fontsDB ;
while ( fontChain ) {
font = fontChain - > font ;
2020-03-13 09:44:45 +01:00
NSVGfontChain * nextChain = fontChain - > next ;
2020-03-10 14:00:02 +01:00
if ( font ) {
nsvg__deleteFont ( font ) ;
fontChain - > font = NULL ;
}
2020-03-13 09:44:45 +01:00
FreePool ( fontChain ) ;
2020-03-13 13:13:08 +01:00
fontChain = nextChain ;
2020-02-15 15:51:18 +01:00
}
2020-03-13 13:13:08 +01:00
fontsDB = NULL ;
2020-03-10 14:00:02 +01:00
// nsvg__deleteParser(mainParser); //temporary disabled
2020-02-27 15:34:29 +01:00
//destruct_globals_objects(NULL); //we can't destruct our globals here. We need, for example, Volumes.
2020-02-15 15:51:18 +01:00
2020-05-01 18:26:28 +02:00
//DumpKernelAndKextPatches(KernelAndKextPatches);
2020-03-13 09:44:45 +01:00
DBG ( " start loader \n " ) ;
2020-09-07 00:19:48 +02:00
XStringW devicePathString = DevicePathToXStringW ( DevicePath ) ;
2020-02-15 15:51:18 +01:00
// Load image into memory (will be started later)
2020-05-01 18:26:28 +02:00
Status = LoadEFIImage ( DevicePath , LoaderPath . basename ( ) , NULL , & ImageHandle ) ;
2020-02-15 15:51:18 +01:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " Image is not loaded, status=%s \n " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
return ; // no reason to continue if loading image failed
}
2020-05-01 18:26:28 +02:00
egClearScreen ( & BootBgColor ) ; //if not set then it is already MenuBackgroundPixel
2020-02-15 15:51:18 +01:00
// KillMouse();
2020-05-01 18:26:28 +02:00
// if (LoaderType == OSTYPE_OSX) {
if ( OSTYPE_IS_OSX ( LoaderType ) | |
OSTYPE_IS_OSX_RECOVERY ( LoaderType ) | |
OSTYPE_IS_OSX_INSTALLER ( LoaderType ) ) {
2020-02-15 15:51:18 +01:00
// To display progress bar properly (especially in FV2 mode) boot.efi needs to be in graphics mode.
// Unfortunately many UEFI implementations change the resolution when SetMode happens.
// This is not what boot.efi expects, and it freely calls SetMode at its will.
// As a result we see progress bar at improper resolution and the background is also missing (10.12.x+).
//
// libeg already has a workaround for SetMode behaviour, so we extend it for boot.efi support.
// The approach tries to be follows:
// 1. Ensure we have graphics mode set (since it is a must in the future).
// 2. Request text mode for boot.efi, which it expects by default (here a SetMode libeg hack will trigger
// on problematic UEFI implementations like AMI).
egSetGraphicsModeEnabled ( TRUE ) ;
egSetGraphicsModeEnabled ( FALSE ) ;
DBG ( " GetOSVersion: " ) ;
//needed for boot.efi patcher
Status = gBS - > HandleProtocol ( ImageHandle , & gEfiLoadedImageProtocolGuid , ( VOID * * ) & LoadedImage ) ;
// Correct OSVersion if it was not found
// This should happen only for 10.7-10.9 OSTYPE_OSX_INSTALLER
// For these cases, take OSVersion from loaded boot.efi image in memory
2020-08-12 17:15:47 +02:00
if ( /*LoaderType == OSTYPE_OSX_INSTALLER ||*/ OSVersion . isEmpty ( ) ) {
2020-02-15 15:51:18 +01:00
if ( ! EFI_ERROR ( Status ) ) {
// version in boot.efi appears as "Mac OS X 10.?"
/*
Start OSName Mac OS X 10.12 End OSName Start OSVendor Apple Inc . End
*/
2020-02-18 19:49:54 +01:00
// InstallerVersion = SearchString((CHAR8*)LoadedImage->ImageBase, LoadedImage->ImageSize, "Mac OS X ", 9);
InstallerVersion = AsciiStrStr ( ( CHAR8 * ) LoadedImage - > ImageBase , " Mac OS X " ) ;
2020-02-15 15:51:18 +01:00
if ( InstallerVersion ! = NULL ) { // string was found
InstallerVersion + = 9 ; // advance to version location
2020-05-16 21:30:29 +02:00
if ( strncmp ( InstallerVersion , " 10.7 " , 4 ) & &
strncmp ( InstallerVersion , " 10.8 " , 4 ) & &
strncmp ( InstallerVersion , " 10.9 " , 4 ) & &
strncmp ( InstallerVersion , " 10.10 " , 5 ) & &
strncmp ( InstallerVersion , " 10.11 " , 5 ) & &
strncmp ( InstallerVersion , " 10.12 " , 5 ) & &
strncmp ( InstallerVersion , " 10.13 " , 5 ) & &
strncmp ( InstallerVersion , " 10.14 " , 5 ) & &
2020-06-22 20:47:45 +02:00
strncmp ( InstallerVersion , " 10.15 " , 5 ) & &
2020-07-13 08:59:31 +02:00
strncmp ( InstallerVersion , " 10.16 " , 5 ) & &
strncmp ( InstallerVersion , " 11.0 " , 4 ) ) {
2020-02-15 15:51:18 +01:00
InstallerVersion = NULL ; // flag known version was not found
}
if ( InstallerVersion ! = NULL ) { // known version was found in image
2020-08-12 17:15:47 +02:00
OSVersion . takeValueFrom ( InstallerVersion ) ;
DBG ( " Corrected OSVersion: %s \n " , OSVersion . c_str ( ) ) ;
2020-02-15 15:51:18 +01:00
}
}
}
2020-08-12 17:15:47 +02:00
BuildVersion . setEmpty ( ) ;
2020-02-15 15:51:18 +01:00
}
2020-08-12 17:15:47 +02:00
if ( BuildVersion . notEmpty ( ) ) {
DBG ( " %s (%s) \n " , OSVersion . c_str ( ) , BuildVersion . c_str ( ) ) ;
2020-02-15 15:51:18 +01:00
} else {
2020-08-12 17:15:47 +02:00
DBG ( " %s \n " , OSVersion . c_str ( ) ) ;
2020-02-15 15:51:18 +01:00
}
2020-08-12 17:15:47 +02:00
if ( OSVersion . notEmpty ( ) & & ( AsciiOSVersionToUint64 ( OSVersion ) > = AsciiOSVersionToUint64 ( " 10.11 " _XS8 ) ) ) {
2020-05-01 18:26:28 +02:00
if ( OSFLAG_ISSET ( Flags , OSFLAG_NOSIP ) ) {
2020-07-14 10:20:54 +02:00
gSettings . CsrActiveConfig = ( UINT32 ) 0xB7F ;
2020-02-15 15:51:18 +01:00
gSettings . BooterConfig = 0x28 ;
}
2020-07-14 10:20:54 +02:00
// ReadSIPCfg();
2020-02-15 15:51:18 +01:00
}
2020-05-01 18:26:28 +02:00
FilterKextPatches ( ) ;
FilterKernelPatches ( ) ;
FilterBootPatches ( ) ;
if ( LoadedImage & & ! BooterPatch ( ( UINT8 * ) LoadedImage - > ImageBase , LoadedImage - > ImageSize ) ) {
2020-02-15 15:51:18 +01:00
DBG ( " Will not patch boot.efi \n " ) ;
}
// Set boot argument for kernel if no caches, this should force kernel loading
2020-05-01 18:26:28 +02:00
if ( OSFLAG_ISSET ( Flags , OSFLAG_NOCACHES ) & & ! LoadOptions . containsStartWithIC ( " Kernel= " ) ) {
2020-04-30 08:03:56 +02:00
XString8 KernelLocation ;
2020-02-15 15:51:18 +01:00
2020-08-12 17:15:47 +02:00
if ( OSVersion . notEmpty ( ) & & AsciiOSVersionToUint64 ( OSVersion ) < = AsciiOSVersionToUint64 ( " 10.9 " _XS8 ) ) {
2020-08-11 08:00:19 +02:00
KernelLocation . S8Printf ( " \" Kernel=/mach_kernel \" " ) ;
2020-02-15 15:51:18 +01:00
} else {
// used for 10.10, 10.11, and new version.
2020-08-11 08:00:19 +02:00
KernelLocation . S8Printf ( " \" Kernel=/System/Library/Kernels/kernel \" " ) ;
2020-02-15 15:51:18 +01:00
}
2020-05-01 18:26:28 +02:00
LoadOptions . AddID ( KernelLocation ) ;
2020-02-15 15:51:18 +01:00
}
//we are booting OSX - restore emulation if it's not installed before g boot.efi
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > InstallEmulation ( gEmuVariableControl ) ;
}
// first patchACPI and find PCIROOT and RTC
// but before ACPI patch we need smbios patch
2020-02-18 19:49:54 +01:00
CheckEmptyFB ( ) ;
2020-02-15 15:51:18 +01:00
PatchSmbios ( ) ;
// DBG("PatchACPI\n");
2020-05-01 18:26:28 +02:00
PatchACPI ( Volume , OSVersion ) ;
2020-02-15 15:51:18 +01:00
// If KPDebug is true boot in verbose mode to see the debug messages
2020-08-11 14:43:53 +02:00
if ( KernelAndKextPatches . KPDebug ) {
2020-05-01 18:30:22 +02:00
LoadOptions . AddID ( " -v " _XS8 ) ;
2020-02-15 15:51:18 +01:00
}
DbgHeader ( " RestSetup macOS " ) ;
// DBG("SetDevices\n");
2020-05-01 18:26:28 +02:00
SetDevices ( this ) ;
2020-02-15 15:51:18 +01:00
// DBG("SetFSInjection\n");
2020-05-01 18:26:28 +02:00
SetFSInjection ( ) ;
2020-02-15 15:51:18 +01:00
//PauseForKey(L"SetFSInjection");
// DBG("SetVariablesForOSX\n");
2020-05-01 18:26:28 +02:00
SetVariablesForOSX ( this ) ;
2020-02-15 15:51:18 +01:00
// DBG("SetVariablesForOSX\n");
2020-05-01 18:26:28 +02:00
EventsInitialize ( this ) ;
2020-02-15 15:51:18 +01:00
// DBG("FinalizeSmbios\n");
FinalizeSmbios ( ) ;
SetCPUProperties ( ) ;
2020-05-01 18:26:28 +02:00
if ( OSFLAG_ISSET ( Flags , OSFLAG_HIBERNATED ) ) {
DoHibernateWake = PrepareHibernation ( Volume ) ;
2020-02-15 15:51:18 +01:00
}
SetupDataForOSX ( DoHibernateWake ) ;
2020-04-05 14:25:39 +02:00
if ( gDriversFlags . AptioFixLoaded & &
! DoHibernateWake & &
2020-05-01 18:26:28 +02:00
! LoadOptions . containsStartWithIC ( " slide= " ) ) {
2020-02-15 15:51:18 +01:00
// Add slide=0 argument for ML+ if not present
2020-05-01 18:30:22 +02:00
LoadOptions . AddID ( " slide=0 " _XS8 ) ;
2020-02-15 15:51:18 +01:00
}
/**
* syscl - append " -xcpm " argument conditionally if set KernelXCPM on Intel Haswell + low - end CPUs
*/
2020-08-11 14:43:53 +02:00
if ( KernelAndKextPatches . KPKernelXCPM & &
2020-02-15 15:51:18 +01:00
gCPUStructure . Vendor = = CPU_VENDOR_INTEL & & gCPUStructure . Model > = CPU_MODEL_HASWELL & &
( AsciiStrStr ( gCPUStructure . BrandString , " Celeron " ) | | AsciiStrStr ( gCPUStructure . BrandString , " Pentium " ) ) & &
2020-08-12 17:15:47 +02:00
( AsciiOSVersionToUint64 ( OSVersion ) > = AsciiOSVersionToUint64 ( " 10.8.5 " _XS8 ) ) & &
( AsciiOSVersionToUint64 ( OSVersion ) < AsciiOSVersionToUint64 ( " 10.12 " _XS8 ) ) & &
2020-05-01 18:26:28 +02:00
( ! LoadOptions . containsIC ( " -xcpm " ) ) ) {
2020-02-15 15:51:18 +01:00
// add "-xcpm" argv if not present on Haswell+ Celeron/Pentium
2020-05-01 18:30:22 +02:00
LoadOptions . AddID ( " -xcpm " _XS8 ) ;
2020-02-15 15:51:18 +01:00
}
// add -xcpm on Ivy Bridge if set KernelXCPM and system version is 10.8.5 - 10.11.x
2020-08-11 14:43:53 +02:00
if ( KernelAndKextPatches . KPKernelXCPM & &
2020-02-15 15:51:18 +01:00
gCPUStructure . Model = = CPU_MODEL_IVY_BRIDGE & &
2020-08-12 17:15:47 +02:00
( AsciiOSVersionToUint64 ( OSVersion ) > = AsciiOSVersionToUint64 ( " 10.8.5 " _XS8 ) ) & &
( AsciiOSVersionToUint64 ( OSVersion ) < AsciiOSVersionToUint64 ( " 10.12 " _XS8 ) ) & &
2020-05-01 18:26:28 +02:00
( ! LoadOptions . containsIC ( " -xcpm " ) ) ) {
2020-02-15 15:51:18 +01:00
// add "-xcpm" argv if not present on Ivy Bridge
2020-05-01 18:30:22 +02:00
LoadOptions . AddID ( " -xcpm " _XS8 ) ;
2020-02-15 15:51:18 +01:00
}
2020-02-18 19:49:54 +01:00
if ( AudioIo ) {
2020-06-18 18:08:00 +02:00
AudioIo - > StopPlayback ( AudioIo ) ;
// CheckSyncSound(true);
EFI_DRIVER_BINDING_PROTOCOL * DriverBinding = NULL ;
Status = gBS - > HandleProtocol ( AudioDriverHandle , & gEfiDriverBindingProtocolGuid , ( VOID * * ) & DriverBinding ) ;
if ( DriverBinding ) {
DriverBinding - > Stop ( DriverBinding , AudioDriverHandle , 0 , NULL ) ;
}
2020-02-18 19:49:54 +01:00
}
2020-02-15 15:51:18 +01:00
2020-03-25 19:32:44 +01:00
// DBG("Set FakeCPUID: 0x%X\n", gSettings.FakeCPUID);
2020-02-15 15:51:18 +01:00
// DBG("LoadKexts\n");
// LoadKexts writes to DataHub, where large writes can prevent hibernate wake (happens when several kexts present in Clover's kexts dir)
if ( ! DoHibernateWake ) {
2020-05-01 18:26:28 +02:00
LoadKexts ( ) ;
2020-02-15 15:51:18 +01:00
}
// blocking boot.efi output if -v is not specified
// note: this blocks output even if -v is specified in
// /Library/Preferences/SystemConfiguration/com.apple.Boot.plist
// which is wrong
// apianti - only block console output if using graphics
// but don't block custom boot logo
2020-06-18 18:08:00 +02:00
if ( LoadOptions . containsIC ( " -v " ) ) {
2020-05-01 18:26:28 +02:00
Flags = OSFLAG_UNSET ( Flags , OSFLAG_USEGRAPHICS ) ;
2020-06-18 18:08:00 +02:00
}
2020-02-15 15:51:18 +01:00
}
2020-05-01 18:26:28 +02:00
else if ( OSTYPE_IS_WINDOWS ( LoaderType ) ) {
2020-02-15 15:51:18 +01:00
if ( AudioIo ) {
AudioIo - > StopPlayback ( AudioIo ) ;
}
DBG ( " Closing events for Windows \n " ) ;
gBS - > CloseEvent ( OnReadyToBootEvent ) ;
gBS - > CloseEvent ( ExitBootServiceEvent ) ;
gBS - > CloseEvent ( mSimpleFileSystemChangeEvent ) ;
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
PatchACPI_OtherOS ( L " Windows " , FALSE ) ;
//PauseForKey(L"continue");
}
2020-05-01 18:26:28 +02:00
else if ( OSTYPE_IS_LINUX ( LoaderType ) | | ( LoaderType = = OSTYPE_LINEFI ) ) {
2020-02-15 15:51:18 +01:00
DBG ( " Closing events for Linux \n " ) ;
gBS - > CloseEvent ( OnReadyToBootEvent ) ;
gBS - > CloseEvent ( ExitBootServiceEvent ) ;
gBS - > CloseEvent ( mSimpleFileSystemChangeEvent ) ;
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
//FinalizeSmbios();
PatchACPI_OtherOS ( L " Linux " , FALSE ) ;
//PauseForKey(L"continue");
}
if ( gSettings . LastBootedVolume ) {
2020-08-07 10:23:46 +02:00
if ( APFSTargetUUID . notEmpty ( ) ) {
// Jief : we need to LoaderPath. If not, GUI can't know which target was selected.
SetStartupDiskVolume ( Volume , LoaderPath ) ;
} else {
// Jief : I'm not sure why NullXStringW was given if LoaderType == OSTYPE_OSX.
// Let's do it like it was before when not in case of APFSTargetUUID
SetStartupDiskVolume ( Volume , LoaderType = = OSTYPE_OSX ? NullXStringW : LoaderPath ) ;
}
2020-08-15 15:47:56 +02:00
} else if ( gSettings . DefaultVolume . notEmpty ( ) ) {
2020-02-15 15:51:18 +01:00
// DefaultVolume specified in Config.plist or in Boot Option
// we'll remove macOS Startup Disk vars which may be present if it is used
// to reboot into another volume
RemoveStartupDiskVolume ( ) ;
}
/*
{
// UINT32 machineSignature = 0;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * FadtPointer = NULL ;
EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * Facs = NULL ;
// DBG("---dump hibernations data---\n");
FadtPointer = GetFadt ( ) ;
if ( FadtPointer ! = NULL ) {
Facs = ( EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * ) ( UINTN ) ( FadtPointer - > FirmwareCtrl ) ;
DBG ( " Firmware wake address=%08lx \n " , Facs - > FirmwareWakingVector ) ;
DBG ( " Firmware wake 64 addr=%16llx \n " , Facs - > XFirmwareWakingVector ) ;
DBG ( " Hardware signature =%08lx \n " , Facs - > HardwareSignature ) ;
DBG ( " GlobalLock =%08lx \n " , Facs - > GlobalLock ) ;
DBG ( " Flags =%08lx \n " , Facs - > Flags ) ;
2020-03-25 19:32:44 +01:00
DBG ( " HS at offset 0x%08X \n " , OFFSET_OF ( EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE , HardwareSignature ) ) ;
2020-02-15 15:51:18 +01:00
// machineSignature = Facs->HardwareSignature;
}
}
*/
// DBG("BeginExternalScreen\n");
2020-05-01 18:26:28 +02:00
BeginExternalScreen ( OSFLAG_ISSET ( Flags , OSFLAG_USEGRAPHICS ) /*, L"Booting OS"*/ ) ;
2020-02-15 15:51:18 +01:00
2020-05-01 18:30:22 +02:00
if ( ! OSTYPE_IS_WINDOWS ( LoaderType ) & & ! OSTYPE_IS_LINUX ( LoaderType ) ) {
2020-05-01 18:26:28 +02:00
if ( OSFLAG_ISSET ( Flags , OSFLAG_USEGRAPHICS ) ) {
2020-02-15 15:51:18 +01:00
// save orig OutputString and replace it with
// null implementation
ConOutOutputString = gST - > ConOut - > OutputString ;
gST - > ConOut - > OutputString = NullConOutOutputString ;
}
// Initialize the boot screen
2020-05-01 18:26:28 +02:00
if ( EFI_ERROR ( Status = InitBootScreen ( this ) ) ) {
2020-08-25 17:35:19 +02:00
if ( Status ! = EFI_ABORTED ) DBG ( " Failed to initialize custom boot screen: %s! \n " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
else if ( EFI_ERROR ( Status = LockBootScreen ( ) ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " Failed to lock custom boot screen: %s! \n " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
} // !OSTYPE_IS_WINDOWS
2020-05-01 18:26:28 +02:00
if ( OSTYPE_IS_OSX ( LoaderType ) | |
OSTYPE_IS_OSX_RECOVERY ( LoaderType ) | |
OSTYPE_IS_OSX_INSTALLER ( LoaderType ) ) {
2020-02-15 15:51:18 +01:00
if ( DoHibernateWake ) {
DBG ( " Closing events for wake \n " ) ;
gBS - > CloseEvent ( OnReadyToBootEvent ) ;
gBS - > CloseEvent ( ExitBootServiceEvent ) ;
gBS - > CloseEvent ( mSimpleFileSystemChangeEvent ) ;
// gBS->CloseEvent (mVirtualAddressChangeEvent);
// When doing hibernate wake, save to DataHub only up to initial size of log
SavePreBootLog = FALSE ;
} else {
// delete boot-switch-vars if exists
Status = gRT - > SetVariable ( L " boot-switch-vars " , & gEfiAppleBootGuid ,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS ,
0 , NULL ) ;
DeleteNvramVariable ( L " IOHibernateRTCVariables " , & gEfiAppleBootGuid ) ;
DeleteNvramVariable ( L " boot-image " , & gEfiAppleBootGuid ) ;
}
SetupBooterLog ( ! DoHibernateWake ) ;
}
2020-09-07 00:19:48 +02:00
DBG ( " Closing log \n " ) ;
if ( SavePreBootLog ) {
Status = SaveBooterLog ( SelfRootDir , PREBOOT_LOG ) ;
if ( EFI_ERROR ( Status ) ) {
/*Status = */ SaveBooterLog ( NULL , PREBOOT_LOG ) ;
}
}
// DBG("StartEFIImage\n");
// StartEFIImage(DevicePath, LoadOptions,
// Basename(LoaderPath), Basename(LoaderPath), NULL, NULL);
// DBG("StartEFILoadedImage\n");
StartEFILoadedImage ( ImageHandle , LoadOptions , Basename ( LoaderPath . wc_str ( ) ) , LoaderPath . basename ( ) , NULL ) ;
// Unlock boot screen
if ( EFI_ERROR ( Status = UnlockBootScreen ( ) ) ) {
DBG ( " Failed to unlock custom boot screen: %s! \n " , efiStrError ( Status ) ) ;
}
if ( OSFLAG_ISSET ( Flags , OSFLAG_USEGRAPHICS ) ) {
// return back orig OutputString
gST - > ConOut - > OutputString = ConOutOutputString ;
}
// PauseForKey(L"FinishExternalScreen");
FinishExternalScreen ( ) ;
// PauseForKey(L"System started?!");
}
extern " C " {
# include <Library/OcVirtualFsLib.h>
# include <Library/OcConfigurationLib.h>
# include <Library/OcDevicePathLib.h>
# include <Library/OcDebugLogLib.h>
extern OC_GLOBAL_CONFIG mOpenCoreConfiguration ;
extern OC_STORAGE_CONTEXT mOpenCoreStorage ;
extern OC_CPU_INFO mOpenCoreCpuInfo ;
extern OC_BOOTSTRAP_PROTOCOL mOpenCoreBootStrap ;
extern OC_RSA_PUBLIC_KEY * mOpenCoreVaultKey ;
EFI_STATUS
EFIAPI
OcKernelFileOpen (
IN EFI_FILE_PROTOCOL * This ,
OUT EFI_FILE_PROTOCOL * * NewHandle ,
IN CHAR16 * FileName ,
IN UINT64 OpenMode ,
IN UINT64 Attributes
) ;
EFI_STATUS
EFIAPI
InternalEfiLoadImage (
IN BOOLEAN BootPolicy ,
IN EFI_HANDLE ParentImageHandle ,
IN EFI_DEVICE_PATH_PROTOCOL * DevicePath ,
IN VOID * SourceBuffer OPTIONAL ,
IN UINTN SourceSize ,
OUT EFI_HANDLE * ImageHandle
) ;
EFI_STATUS
EFIAPI
OcStartImage (
IN EFI_HANDLE ImageHandle ,
OUT UINTN * ExitDataSize ,
OUT CHAR16 * * ExitData OPTIONAL
) ;
VOID
OcLoadBooterUefiSupport (
IN OC_GLOBAL_CONFIG * Config
) ;
2020-09-07 16:44:24 +02:00
UINT64
InternalCalculateARTFrequencyIntel (
OUT UINT64 * CPUFrequency ,
OUT UINT64 * TscAdjustPtr OPTIONAL ,
IN BOOLEAN Recalculate
) ;
2020-09-07 00:19:48 +02:00
} // extern "C"
# define OC_STRING_ASSIGN(ocString, value) do { \
ocString . DynValue = NULL ; \
strcpy ( ocString . Value , value ) ; \
ocString . MaxSize = sizeof ( ocString . Value ) ; \
ocString . Size = strlen ( value ) + 1 ; \
} while ( 0 )
2020-09-08 11:33:35 +02:00
# define OC_STRING_ASSIGN_N(ocString, value, len) do { \
ocString . DynValue = NULL ; \
memcpy ( ocString . Value , value , len ) ; \
ocString . MaxSize = sizeof ( ocString . Value ) ; \
ocString . Size = len ; \
} while ( 0 )
2020-09-07 00:19:48 +02:00
2020-09-08 23:25:26 +02:00
size_t setKextAtPos ( XObjArray < SIDELOAD_KEXT > * kextArrayPtr , const XString8 & kextName , size_t pos )
{
XObjArray < SIDELOAD_KEXT > & kextArray = * kextArrayPtr ;
for ( size_t kextIdx = 0 ; kextIdx < kextArray . size ( ) ; kextIdx + + ) {
if ( XString8 ( LString8 ( mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > BundlePath . Value ) ) . contains ( kextName ) ) {
if ( pos > = kextArray . size ( ) ) panic ( " pos >= kextArray.size() " ) ;
OC_KERNEL_ADD_ENTRY * entry = mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] ;
mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] = mOpenCoreConfiguration . Kernel . Add . Values [ pos ] ;
mOpenCoreConfiguration . Kernel . Add . Values [ pos ] = entry ;
return pos + 1 ;
}
}
return pos ;
}
2020-09-07 00:19:48 +02:00
VOID LOADER_ENTRY : : StartLoader11 ( )
{
EFI_STATUS Status ;
EFI_TEXT_STRING ConOutOutputString = 0 ;
EFI_HANDLE ImageHandle = NULL ;
EFI_LOADED_IMAGE * LoadedImage = NULL ;
CONST CHAR8 * InstallerVersion ;
UINTN i ;
NSVGfont * font ; // , *nextFont;
DbgHeader ( " StartLoader11 " ) ;
2020-09-07 13:13:44 +02:00
if ( Settings . notEmpty ( ) ) {
DBG ( " Settings: %ls \n " , Settings . wc_str ( ) ) ;
TagDict * dict ;
Status = LoadUserSettings ( SelfRootDir , Settings , & dict ) ;
if ( ! EFI_ERROR ( Status ) ) {
DBG ( " - found custom settings for this entry: %ls \n " , Settings . wc_str ( ) ) ;
gBootChanged = TRUE ;
Status = GetUserSettings ( dict ) ;
if ( EFI_ERROR ( Status ) ) {
DBG ( " - ... but: %s \n " , efiStrError ( Status ) ) ;
} else {
if ( ( gSettings . CpuFreqMHz > 100 ) & & ( gSettings . CpuFreqMHz < 20000 ) ) {
gCPUStructure . MaxSpeed = gSettings . CpuFreqMHz ;
}
//CopyMem(KernelAndKextPatches,
// &gSettings.KernelAndKextPatches,
// sizeof(KERNEL_AND_KEXT_PATCHES));
//DBG("Custom KernelAndKextPatches copyed to started entry\n");
}
} else {
DBG ( " - [!] LoadUserSettings failed: %s \n " , efiStrError ( Status ) ) ;
}
}
2020-09-07 00:19:48 +02:00
2020-09-07 13:13:44 +02:00
DBG ( " Finally: ExternalClock=%lluMHz BusSpeed=%llukHz CPUFreq=%uMHz " ,
DivU64x32 ( gCPUStructure . ExternalClock + kilo - 1 , kilo ) ,
DivU64x32 ( gCPUStructure . FSBFrequency + kilo - 1 , kilo ) ,
gCPUStructure . MaxSpeed ) ;
if ( gSettings . QPI ) {
DBG ( " QPI: hw.busfrequency=%lluHz \n " , MultU64x32 ( gSettings . QPI , Mega ) ) ;
} else {
// to match the value of hw.busfrequency in the terminal
DBG ( " PIS: hw.busfrequency=%lluHz \n " , MultU64x32 ( LShiftU64 ( DivU64x32 ( gCPUStructure . ExternalClock + kilo - 1 , kilo ) , 2 ) , Mega ) ) ;
}
if ( OSVersion . notEmpty ( ) & & ( AsciiOSVersionToUint64 ( OSVersion ) > = AsciiOSVersionToUint64 ( " 10.11 " _XS8 ) ) ) {
if ( OSFLAG_ISSET ( Flags , OSFLAG_NOSIP ) ) {
gSettings . CsrActiveConfig = ( UINT32 ) 0xB7F ;
gSettings . BooterConfig = 0x28 ;
}
// ReadSIPCfg();
}
FilterKextPatches ( ) ;
FilterKernelPatches ( ) ;
FilterBootPatches ( ) ;
if ( LoadedImage & & ! BooterPatch ( ( UINT8 * ) LoadedImage - > ImageBase , LoadedImage - > ImageSize ) ) {
DBG ( " Will not patch boot.efi \n " ) ;
}
// Set boot argument for kernel if no caches, this should force kernel loading
if ( OSFLAG_ISSET ( Flags , OSFLAG_NOCACHES ) & & ! LoadOptions . containsStartWithIC ( " Kernel= " ) ) {
XString8 KernelLocation ;
if ( OSVersion . notEmpty ( ) & & AsciiOSVersionToUint64 ( OSVersion ) < = AsciiOSVersionToUint64 ( " 10.9 " _XS8 ) ) {
KernelLocation . S8Printf ( " \" Kernel=/mach_kernel \" " ) ;
} else {
// used for 10.10, 10.11, and new version.
KernelLocation . S8Printf ( " \" Kernel=/System/Library/Kernels/kernel \" " ) ;
}
LoadOptions . AddID ( KernelLocation ) ;
}
//we are booting OSX - restore emulation if it's not installed before g boot.efi
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > InstallEmulation ( gEmuVariableControl ) ;
}
// first patchACPI and find PCIROOT and RTC
// but before ACPI patch we need smbios patch
CheckEmptyFB ( ) ;
PatchSmbios ( ) ;
// DBG("PatchACPI\n");
PatchACPI ( Volume , OSVersion ) ;
// If KPDebug is true boot in verbose mode to see the debug messages
if ( KernelAndKextPatches . KPDebug ) {
LoadOptions . AddID ( " -v " _XS8 ) ;
}
DbgHeader ( " RestSetup macOS " ) ;
// DBG("SetDevices\n");
SetDevices ( this ) ;
// DBG("SetFSInjection\n");
SetFSInjection ( ) ;
//PauseForKey(L"SetFSInjection");
// DBG("SetVariablesForOSX\n");
SetVariablesForOSX ( this ) ;
// DBG("SetVariablesForOSX\n");
EventsInitialize ( this ) ;
// DBG("FinalizeSmbios\n");
FinalizeSmbios ( ) ;
SetCPUProperties ( ) ;
if ( OSFLAG_ISSET ( Flags , OSFLAG_HIBERNATED ) ) {
DoHibernateWake = PrepareHibernation ( Volume ) ;
}
SetupDataForOSX ( DoHibernateWake ) ;
if ( gDriversFlags . AptioFixLoaded & &
! DoHibernateWake & &
! LoadOptions . containsStartWithIC ( " slide= " ) ) {
// Add slide=0 argument for ML+ if not present
LoadOptions . AddID ( " slide=0 " _XS8 ) ;
}
2020-09-08 11:33:35 +02:00
if ( gSettings . LastBootedVolume ) {
if ( APFSTargetUUID . notEmpty ( ) ) {
// Jief : we need to LoaderPath. If not, GUI can't know which target was selected.
SetStartupDiskVolume ( Volume , LoaderPath ) ;
} else {
// Jief : I'm not sure why NullXStringW was given if LoaderType == OSTYPE_OSX.
// Let's do it like it was before when not in case of APFSTargetUUID
SetStartupDiskVolume ( Volume , LoaderType = = OSTYPE_OSX ? NullXStringW : LoaderPath ) ;
}
} else if ( gSettings . DefaultVolume . notEmpty ( ) ) {
// DefaultVolume specified in Config.plist or in Boot Option
// we'll remove macOS Startup Disk vars which may be present if it is used
// to reboot into another volume
RemoveStartupDiskVolume ( ) ;
}
2020-09-08 23:25:26 +02:00
{
EFI_HANDLE Interface = NULL ;
Status = gBS - > LocateProtocol ( & gAptioMemoryFixProtocolGuid , NULL , & Interface ) ;
if ( ! EFI_ERROR ( Status ) ) {
panic ( " Remove AptioMemoryFix.efi and OcQuirks.efi from your driver folder \n " ) ;
}
}
// Attempt to unload AptioMemoryFix. Something doesn't work well.
2020-09-07 13:13:44 +02:00
// UINTN HandleCount = 0;
// EFI_HANDLE* HandleBuffer = NULL;
2020-09-07 00:19:48 +02:00
//
2020-09-07 13:13:44 +02:00
// Status = gBS->LocateHandleBuffer (ByProtocol, &gAptioMemoryFixProtocolGuid, NULL, &HandleCount, &HandleBuffer);
// if ( !EFI_ERROR(Status) )
// {
// for (UINTN HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
// EFI_HANDLE Interface = NULL;
// Status = gBS->HandleProtocol(HandleBuffer[HandleIndex], &gAptioMemoryFixProtocolGuid, &Interface);
// if ( !EFI_ERROR(Status) ) {
// Status = gBS->UninstallProtocolInterface(HandleBuffer[HandleIndex], &gAptioMemoryFixProtocolGuid, Interface);
// if (EFI_ERROR(Status)) panic("Cannot uninstall AptioMemoryFix protocol. Status=%s\n", efiStrError(Status));
// }else{
// if ( Status != EFI_UNSUPPORTED ) DBG("HandleProtocol status=%s\n", efiStrError(Status));
// }
2020-09-07 00:19:48 +02:00
// }
2020-09-07 13:13:44 +02:00
// }else{
// DBG("LocateHandleBuffer status=%s\n", efiStrError(Status));
// // Assume no protocol AptioMemoryFix is installed.
2020-09-07 00:19:48 +02:00
// }
//
2020-09-07 16:44:24 +02:00
UINT64 CPUFrequencyFromART ;
InternalCalculateARTFrequencyIntel ( & CPUFrequencyFromART , NULL , 1 ) ;
2020-09-07 13:13:44 +02:00
EFI_LOADED_IMAGE * OcLoadedImage ;
Status = gBS - > HandleProtocol ( gImageHandle , & gEfiLoadedImageProtocolGuid , ( VOID * * ) & OcLoadedImage ) ;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * FileSystem = LocateFileSystem ( OcLoadedImage - > DeviceHandle , OcLoadedImage - > FilePath ) ;
Status = OcStorageInitFromFs ( & mOpenCoreStorage , FileSystem , L " EFI \\ CLOVER " , NULL ) ;
OcConfigureLogProtocol (
2020-09-07 16:44:24 +02:00
9 ,
2020-09-07 13:13:44 +02:00
0 ,
2151678018 ,
2147483648 ,
OPEN_CORE_LOG_PREFIX_PATH ,
mOpenCoreStorage . FileSystem
) ;
DEBUG ( ( DEBUG_INFO , " OC: Log initialized... \n " ) ) ;
OcAppleDebugLogInstallProtocol ( 0 ) ;
OcLoadBooterUefiSupport ( & mOpenCoreConfiguration ) ;
OcLoadKernelSupport ( & mOpenCoreStorage , & mOpenCoreConfiguration , & mOpenCoreCpuInfo ) ;
OcImageLoaderInit ( ) ;
2020-09-07 00:19:48 +02:00
XObjArray < SIDELOAD_KEXT > kextArray ;
if ( ! DoHibernateWake ) {
AddKextsInArray ( LStringW ( L " Kexts \\ 11 " ) , LStringW ( L " 11 " ) , CPU_TYPE_X86_64 , & kextArray ) ;
}
memset ( & mOpenCoreConfiguration , 0 , sizeof ( mOpenCoreConfiguration ) ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Scheme . KernelCache , " Auto " ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Misc . Security . SecureBootModel , " Default " ) ;
2020-09-07 19:33:38 +02:00
mOpenCoreConfiguration . Kernel . Scheme . FuzzyMatch = gSettings . KernelAndKextPatches . FuzzyMatch ;
memcpy ( & mOpenCoreConfiguration . Kernel . Quirks , & gSettings . KernelAndKextPatches . OcKernelQuirks , sizeof ( mOpenCoreConfiguration . Kernel . Quirks ) ) ;
2020-09-07 00:19:48 +02:00
mOpenCoreConfiguration . Kernel . Add . Count = kextArray . size ( ) ;
mOpenCoreConfiguration . Kernel . Add . AllocCount = mOpenCoreConfiguration . Kernel . Add . Count ;
2020-09-08 11:33:35 +02:00
mOpenCoreConfiguration . Kernel . Add . ValueSize = sizeof ( __typeof_am__ ( * * mOpenCoreConfiguration . Kernel . Add . Values ) ) ; // sizeof(OC_KERNEL_ADD_ENTRY) == 680
2020-09-07 00:19:48 +02:00
mOpenCoreConfiguration . Kernel . Add . Values = ( OC_KERNEL_ADD_ENTRY * * ) AllocatePool ( mOpenCoreConfiguration . Kernel . Add . AllocCount * sizeof ( * mOpenCoreConfiguration . Kernel . Add . Values ) ) ; // sizeof(OC_KERNEL_ADD_ENTRY) == 680
for ( size_t kextIdx = 0 ; kextIdx < kextArray . size ( ) ; kextIdx + + )
{
const SIDELOAD_KEXT & KextEntry = kextArray [ kextIdx ] ;
2020-09-07 19:33:38 +02:00
DBG ( " Bridge kext to OC : KextDirNameUnderOEMPath=%ls FileName=%ls \n " , KextEntry . KextDirNameUnderOEMPath . wc_str ( ) , KextEntry . FileName . wc_str ( ) ) ;
2020-09-08 11:33:35 +02:00
mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] = ( __typeof_am__ ( * mOpenCoreConfiguration . Kernel . Add . Values ) ) AllocatePool ( mOpenCoreConfiguration . Kernel . Add . ValueSize ) ;
2020-09-07 00:19:48 +02:00
mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > Enabled = 1 ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > Arch , " Any " ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > Comment , " " ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > MaxKernel , " " ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > MinKernel , " " ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > Identifier , " " ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > BundlePath , S8Printf ( " %ls/%ls " , KextEntry . KextDirNameUnderOEMPath . wc_str ( ) , KextEntry . FileName . wc_str ( ) ) . c_str ( ) ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > ExecutablePath , S8Printf ( " Contents/MacOS/%ls " , KextEntry . FileName . subString ( 0 , KextEntry . FileName . indexOf ( " . " ) ) . wc_str ( ) ) . c_str ( ) ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > PlistPath , " Contents/Info.plist " ) ; // TODO : is always Contents/Info.plist ?
mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > ImageData = NULL ;
mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > ImageDataSize = 0 ;
mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > PlistData = NULL ;
mOpenCoreConfiguration . Kernel . Add . Values [ kextIdx ] - > PlistDataSize = 0 ;
}
// Seems that Lilu must be first.
2020-09-08 23:25:26 +02:00
size_t pos = setKextAtPos ( & kextArray , " Lilu.kext " _XS8 , 0 ) ;
pos = setKextAtPos ( & kextArray , " VirtualSMC.kext " _XS8 , pos ) ;
pos = setKextAtPos ( & kextArray , " WhateverGreen.kext " _XS8 , pos ) ;
pos = setKextAtPos ( & kextArray , " AppleALC.kext " _XS8 , pos ) ;
pos = setKextAtPos ( & kextArray , " IntelMausi.kext " _XS8 , pos ) ;
pos = setKextAtPos ( & kextArray , " SMCProcessor.kext " _XS8 , pos ) ;
pos = setKextAtPos ( & kextArray , " SMCSuperIO.kext " _XS8 , pos ) ;
pos = setKextAtPos ( & kextArray , " USBPorts.kext " _XS8 , pos ) ;
2020-09-08 11:33:35 +02:00
XObjArray < KEXT_PATCH > selectedPathArray ;
2020-09-07 19:33:38 +02:00
for ( size_t kextPatchIdx = 0 ; kextPatchIdx < KernelAndKextPatches . KextPatches . size ( ) ; kextPatchIdx + + )
{
2020-09-08 11:33:35 +02:00
if ( KernelAndKextPatches . KextPatches [ kextPatchIdx ] . MenuItem . BValue ) selectedPathArray . AddReference ( & KernelAndKextPatches . KextPatches [ kextPatchIdx ] , false ) ;
}
mOpenCoreConfiguration . Kernel . Patch . Count = selectedPathArray . size ( ) ;
mOpenCoreConfiguration . Kernel . Patch . AllocCount = mOpenCoreConfiguration . Kernel . Patch . Count ;
mOpenCoreConfiguration . Kernel . Patch . ValueSize = sizeof ( __typeof_am__ ( * * mOpenCoreConfiguration . Kernel . Patch . Values ) ) ;
mOpenCoreConfiguration . Kernel . Patch . Values = ( __typeof_am__ ( * mOpenCoreConfiguration . Kernel . Patch . Values ) * ) AllocatePool ( mOpenCoreConfiguration . Kernel . Add . AllocCount * sizeof ( __typeof_am__ ( * mOpenCoreConfiguration . Kernel . Patch . Values ) ) ) ;
for ( size_t kextPatchIdx = 0 ; kextPatchIdx < selectedPathArray . size ( ) ; kextPatchIdx + + )
{
const KEXT_PATCH & kextPatch = selectedPathArray [ kextPatchIdx ] ;
DBG ( " Bridge kext patch to OC : %s \n " , kextPatch . Label . c_str ( ) ) ;
mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] = ( __typeof_am__ ( * mOpenCoreConfiguration . Kernel . Patch . Values ) ) AllocateZeroPool ( mOpenCoreConfiguration . Kernel . Patch . ValueSize ) ; // sizeof(OC_KERNEL_ADD_ENTRY) == 680
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Arch , " Any " ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Base , " " ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Comment , kextPatch . Label . c_str ( ) ) ;
mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Count = 0 ;
mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Enabled = 1 ;
OC_STRING_ASSIGN_N ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Find , kextPatch . Data . vdata ( ) , kextPatch . Data . size ( ) ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Identifier , " kernel " ) ;
mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Limit = kextPatch . Count ;
OC_STRING_ASSIGN_N ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Mask , kextPatch . MaskFind . vdata ( ) , kextPatch . MaskFind . size ( ) ) ;
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > MaxKernel , " " ) ; // it has been filtered, so we don't need to set Min and MaxKernel
OC_STRING_ASSIGN ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > MinKernel , " " ) ;
OC_STRING_ASSIGN_N ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Replace , kextPatch . Patch . vdata ( ) , kextPatch . Patch . size ( ) ) ;
OC_STRING_ASSIGN_N ( mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > ReplaceMask , kextPatch . MaskReplace . vdata ( ) , kextPatch . MaskReplace . size ( ) ) ;
mOpenCoreConfiguration . Kernel . Patch . Values [ kextPatchIdx ] - > Skip = 0 ;
2020-09-07 19:33:38 +02:00
}
for ( size_t forceKextIdx = 0 ; forceKextIdx < KernelAndKextPatches . ForceKexts . size ( ) ; forceKextIdx + + )
{
const XStringW & forceKext = KernelAndKextPatches . ForceKexts [ forceKextIdx ] ;
DBG ( " TODO !!!!!!!! Bridge force kext to OC : %ls \n " , forceKext . wc_str ( ) ) ;
}
2020-09-07 00:19:48 +02:00
EFI_HANDLE EntryHandle = NULL ;
Status = InternalEfiLoadImage (
FALSE ,
gImageHandle ,
DevicePath ,
NULL ,
0 ,
& EntryHandle
) ;
if ( EFI_ERROR ( Status ) ) return ; // TODO message ?
EFI_STATUS OptionalStatus = gBS - > HandleProtocol (
EntryHandle ,
& gEfiLoadedImageProtocolGuid ,
( VOID * * ) & LoadedImage
) ;
if ( EFI_ERROR ( OptionalStatus ) ) return ; // TODO message ?
2020-09-08 11:33:35 +02:00
// XStringW LoadOptionsAsXStringW = SWPrintf("%s ", LoadOptions.ConcatAll(" "_XS8).c_str());
XStringW LoadOptionsAsXStringW = SWPrintf ( " %ls %s " , Basename ( LoaderPath . wc_str ( ) ) , LoadOptions . ConcatAll ( " " _XS8 ) . c_str ( ) ) ;
LoadedImage - > LoadOptions = ( void * ) LoadOptionsAsXStringW . wc_str ( ) ;
LoadedImage - > LoadOptionsSize = ( UINT32 ) LoadOptionsAsXStringW . sizeInBytesIncludingTerminator ( ) ;
2020-09-07 00:19:48 +02:00
Status = OcStartImage ( EntryHandle , 0 , NULL ) ;
if ( EFI_ERROR ( Status ) ) return ; // TODO message ?
return ;
//Free memory
for ( i = 0 ; i < ConfigsNum ; i + + ) {
if ( ConfigsList [ i ] ) {
FreePool ( ConfigsList [ i ] ) ;
ConfigsList [ i ] = NULL ;
}
}
for ( i = 0 ; i < DsdtsNum ; i + + ) {
if ( DsdtsList [ i ] ) {
FreePool ( DsdtsList [ i ] ) ;
DsdtsList [ i ] = NULL ;
}
}
OptionMenu . FreeMenu ( ) ;
//there is a place to free memory
// GuiAnime
// mainParser
// BuiltinIcons
// OSIcons
NSVGfontChain * fontChain = fontsDB ;
while ( fontChain ) {
font = fontChain - > font ;
NSVGfontChain * nextChain = fontChain - > next ;
if ( font ) {
nsvg__deleteFont ( font ) ;
fontChain - > font = NULL ;
}
FreePool ( fontChain ) ;
fontChain = nextChain ;
}
fontsDB = NULL ;
// nsvg__deleteParser(mainParser); //temporary disabled
//destruct_globals_objects(NULL); //we can't destruct our globals here. We need, for example, Volumes.
//DumpKernelAndKextPatches(KernelAndKextPatches);
DBG ( " start loader \n " ) ;
XStringW devicePathString = DevicePathToXStringW ( DevicePath ) ;
// Load image into memory (will be started later)
Status = LoadEFIImage ( DevicePath , LoaderPath . basename ( ) , NULL , & ImageHandle ) ;
if ( EFI_ERROR ( Status ) ) {
DBG ( " Image is not loaded, status=%s \n " , efiStrError ( Status ) ) ;
return ; // no reason to continue if loading image failed
}
egClearScreen ( & BootBgColor ) ; //if not set then it is already MenuBackgroundPixel
// KillMouse();
// if (LoaderType == OSTYPE_OSX) {
if ( OSTYPE_IS_OSX ( LoaderType ) | |
OSTYPE_IS_OSX_RECOVERY ( LoaderType ) | |
OSTYPE_IS_OSX_INSTALLER ( LoaderType ) ) {
// To display progress bar properly (especially in FV2 mode) boot.efi needs to be in graphics mode.
// Unfortunately many UEFI implementations change the resolution when SetMode happens.
// This is not what boot.efi expects, and it freely calls SetMode at its will.
// As a result we see progress bar at improper resolution and the background is also missing (10.12.x+).
//
// libeg already has a workaround for SetMode behaviour, so we extend it for boot.efi support.
// The approach tries to be follows:
// 1. Ensure we have graphics mode set (since it is a must in the future).
// 2. Request text mode for boot.efi, which it expects by default (here a SetMode libeg hack will trigger
// on problematic UEFI implementations like AMI).
egSetGraphicsModeEnabled ( TRUE ) ;
egSetGraphicsModeEnabled ( FALSE ) ;
DBG ( " GetOSVersion: " ) ;
//needed for boot.efi patcher
Status = gBS - > HandleProtocol ( ImageHandle , & gEfiLoadedImageProtocolGuid , ( VOID * * ) & LoadedImage ) ;
// Correct OSVersion if it was not found
// This should happen only for 10.7-10.9 OSTYPE_OSX_INSTALLER
// For these cases, take OSVersion from loaded boot.efi image in memory
if ( /*LoaderType == OSTYPE_OSX_INSTALLER ||*/ OSVersion . isEmpty ( ) ) {
if ( ! EFI_ERROR ( Status ) ) {
// version in boot.efi appears as "Mac OS X 10.?"
/*
Start OSName Mac OS X 10.12 End OSName Start OSVendor Apple Inc . End
*/
// InstallerVersion = SearchString((CHAR8*)LoadedImage->ImageBase, LoadedImage->ImageSize, "Mac OS X ", 9);
InstallerVersion = AsciiStrStr ( ( CHAR8 * ) LoadedImage - > ImageBase , " Mac OS X " ) ;
if ( InstallerVersion ! = NULL ) { // string was found
InstallerVersion + = 9 ; // advance to version location
if ( strncmp ( InstallerVersion , " 10.7 " , 4 ) & &
strncmp ( InstallerVersion , " 10.8 " , 4 ) & &
strncmp ( InstallerVersion , " 10.9 " , 4 ) & &
strncmp ( InstallerVersion , " 10.10 " , 5 ) & &
strncmp ( InstallerVersion , " 10.11 " , 5 ) & &
strncmp ( InstallerVersion , " 10.12 " , 5 ) & &
strncmp ( InstallerVersion , " 10.13 " , 5 ) & &
strncmp ( InstallerVersion , " 10.14 " , 5 ) & &
strncmp ( InstallerVersion , " 10.15 " , 5 ) & &
strncmp ( InstallerVersion , " 10.16 " , 5 ) & &
strncmp ( InstallerVersion , " 11.0 " , 4 ) ) {
InstallerVersion = NULL ; // flag known version was not found
}
if ( InstallerVersion ! = NULL ) { // known version was found in image
OSVersion . takeValueFrom ( InstallerVersion ) ;
DBG ( " Corrected OSVersion: %s \n " , OSVersion . c_str ( ) ) ;
}
}
}
BuildVersion . setEmpty ( ) ;
}
if ( BuildVersion . notEmpty ( ) ) {
DBG ( " %s (%s) \n " , OSVersion . c_str ( ) , BuildVersion . c_str ( ) ) ;
} else {
DBG ( " %s \n " , OSVersion . c_str ( ) ) ;
}
if ( OSVersion . notEmpty ( ) & & ( AsciiOSVersionToUint64 ( OSVersion ) > = AsciiOSVersionToUint64 ( " 10.11 " _XS8 ) ) ) {
if ( OSFLAG_ISSET ( Flags , OSFLAG_NOSIP ) ) {
gSettings . CsrActiveConfig = ( UINT32 ) 0xB7F ;
gSettings . BooterConfig = 0x28 ;
}
// ReadSIPCfg();
}
FilterKextPatches ( ) ;
FilterKernelPatches ( ) ;
FilterBootPatches ( ) ;
if ( LoadedImage & & ! BooterPatch ( ( UINT8 * ) LoadedImage - > ImageBase , LoadedImage - > ImageSize ) ) {
DBG ( " Will not patch boot.efi \n " ) ;
}
// Set boot argument for kernel if no caches, this should force kernel loading
if ( OSFLAG_ISSET ( Flags , OSFLAG_NOCACHES ) & & ! LoadOptions . containsStartWithIC ( " Kernel= " ) ) {
XString8 KernelLocation ;
if ( OSVersion . notEmpty ( ) & & AsciiOSVersionToUint64 ( OSVersion ) < = AsciiOSVersionToUint64 ( " 10.9 " _XS8 ) ) {
KernelLocation . S8Printf ( " \" Kernel=/mach_kernel \" " ) ;
} else {
// used for 10.10, 10.11, and new version.
KernelLocation . S8Printf ( " \" Kernel=/System/Library/Kernels/kernel \" " ) ;
}
LoadOptions . AddID ( KernelLocation ) ;
}
//we are booting OSX - restore emulation if it's not installed before g boot.efi
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > InstallEmulation ( gEmuVariableControl ) ;
}
// first patchACPI and find PCIROOT and RTC
// but before ACPI patch we need smbios patch
CheckEmptyFB ( ) ;
PatchSmbios ( ) ;
// DBG("PatchACPI\n");
PatchACPI ( Volume , OSVersion ) ;
// If KPDebug is true boot in verbose mode to see the debug messages
if ( KernelAndKextPatches . KPDebug ) {
LoadOptions . AddID ( " -v " _XS8 ) ;
}
DbgHeader ( " RestSetup macOS " ) ;
// DBG("SetDevices\n");
SetDevices ( this ) ;
// DBG("SetFSInjection\n");
SetFSInjection ( ) ;
//PauseForKey(L"SetFSInjection");
// DBG("SetVariablesForOSX\n");
SetVariablesForOSX ( this ) ;
// DBG("SetVariablesForOSX\n");
EventsInitialize ( this ) ;
// DBG("FinalizeSmbios\n");
FinalizeSmbios ( ) ;
SetCPUProperties ( ) ;
if ( OSFLAG_ISSET ( Flags , OSFLAG_HIBERNATED ) ) {
DoHibernateWake = PrepareHibernation ( Volume ) ;
}
SetupDataForOSX ( DoHibernateWake ) ;
if ( gDriversFlags . AptioFixLoaded & &
! DoHibernateWake & &
! LoadOptions . containsStartWithIC ( " slide= " ) ) {
// Add slide=0 argument for ML+ if not present
LoadOptions . AddID ( " slide=0 " _XS8 ) ;
}
/**
* syscl - append " -xcpm " argument conditionally if set KernelXCPM on Intel Haswell + low - end CPUs
*/
if ( KernelAndKextPatches . KPKernelXCPM & &
gCPUStructure . Vendor = = CPU_VENDOR_INTEL & & gCPUStructure . Model > = CPU_MODEL_HASWELL & &
( AsciiStrStr ( gCPUStructure . BrandString , " Celeron " ) | | AsciiStrStr ( gCPUStructure . BrandString , " Pentium " ) ) & &
( AsciiOSVersionToUint64 ( OSVersion ) > = AsciiOSVersionToUint64 ( " 10.8.5 " _XS8 ) ) & &
( AsciiOSVersionToUint64 ( OSVersion ) < AsciiOSVersionToUint64 ( " 10.12 " _XS8 ) ) & &
( ! LoadOptions . containsIC ( " -xcpm " ) ) ) {
// add "-xcpm" argv if not present on Haswell+ Celeron/Pentium
LoadOptions . AddID ( " -xcpm " _XS8 ) ;
}
// add -xcpm on Ivy Bridge if set KernelXCPM and system version is 10.8.5 - 10.11.x
if ( KernelAndKextPatches . KPKernelXCPM & &
gCPUStructure . Model = = CPU_MODEL_IVY_BRIDGE & &
( AsciiOSVersionToUint64 ( OSVersion ) > = AsciiOSVersionToUint64 ( " 10.8.5 " _XS8 ) ) & &
( AsciiOSVersionToUint64 ( OSVersion ) < AsciiOSVersionToUint64 ( " 10.12 " _XS8 ) ) & &
( ! LoadOptions . containsIC ( " -xcpm " ) ) ) {
// add "-xcpm" argv if not present on Ivy Bridge
LoadOptions . AddID ( " -xcpm " _XS8 ) ;
}
if ( AudioIo ) {
AudioIo - > StopPlayback ( AudioIo ) ;
// CheckSyncSound(true);
EFI_DRIVER_BINDING_PROTOCOL * DriverBinding = NULL ;
Status = gBS - > HandleProtocol ( AudioDriverHandle , & gEfiDriverBindingProtocolGuid , ( VOID * * ) & DriverBinding ) ;
if ( DriverBinding ) {
DriverBinding - > Stop ( DriverBinding , AudioDriverHandle , 0 , NULL ) ;
}
}
// DBG("Set FakeCPUID: 0x%X\n", gSettings.FakeCPUID);
// DBG("LoadKexts\n");
// LoadKexts writes to DataHub, where large writes can prevent hibernate wake (happens when several kexts present in Clover's kexts dir)
if ( ! DoHibernateWake ) {
LoadKexts ( ) ;
}
// blocking boot.efi output if -v is not specified
// note: this blocks output even if -v is specified in
// /Library/Preferences/SystemConfiguration/com.apple.Boot.plist
// which is wrong
// apianti - only block console output if using graphics
// but don't block custom boot logo
if ( LoadOptions . containsIC ( " -v " ) ) {
Flags = OSFLAG_UNSET ( Flags , OSFLAG_USEGRAPHICS ) ;
}
}
else if ( OSTYPE_IS_WINDOWS ( LoaderType ) ) {
if ( AudioIo ) {
AudioIo - > StopPlayback ( AudioIo ) ;
}
DBG ( " Closing events for Windows \n " ) ;
gBS - > CloseEvent ( OnReadyToBootEvent ) ;
gBS - > CloseEvent ( ExitBootServiceEvent ) ;
gBS - > CloseEvent ( mSimpleFileSystemChangeEvent ) ;
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
PatchACPI_OtherOS ( L " Windows " , FALSE ) ;
//PauseForKey(L"continue");
}
else if ( OSTYPE_IS_LINUX ( LoaderType ) | | ( LoaderType = = OSTYPE_LINEFI ) ) {
DBG ( " Closing events for Linux \n " ) ;
gBS - > CloseEvent ( OnReadyToBootEvent ) ;
gBS - > CloseEvent ( ExitBootServiceEvent ) ;
gBS - > CloseEvent ( mSimpleFileSystemChangeEvent ) ;
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
//FinalizeSmbios();
PatchACPI_OtherOS ( L " Linux " , FALSE ) ;
//PauseForKey(L"continue");
}
if ( gSettings . LastBootedVolume ) {
if ( APFSTargetUUID . notEmpty ( ) ) {
// Jief : we need to LoaderPath. If not, GUI can't know which target was selected.
SetStartupDiskVolume ( Volume , LoaderPath ) ;
} else {
// Jief : I'm not sure why NullXStringW was given if LoaderType == OSTYPE_OSX.
// Let's do it like it was before when not in case of APFSTargetUUID
SetStartupDiskVolume ( Volume , LoaderType = = OSTYPE_OSX ? NullXStringW : LoaderPath ) ;
}
} else if ( gSettings . DefaultVolume . notEmpty ( ) ) {
// DefaultVolume specified in Config.plist or in Boot Option
// we'll remove macOS Startup Disk vars which may be present if it is used
// to reboot into another volume
RemoveStartupDiskVolume ( ) ;
}
/*
{
// UINT32 machineSignature = 0;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * FadtPointer = NULL ;
EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * Facs = NULL ;
// DBG("---dump hibernations data---\n");
FadtPointer = GetFadt ( ) ;
if ( FadtPointer ! = NULL ) {
Facs = ( EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * ) ( UINTN ) ( FadtPointer - > FirmwareCtrl ) ;
DBG ( " Firmware wake address=%08lx \n " , Facs - > FirmwareWakingVector ) ;
DBG ( " Firmware wake 64 addr=%16llx \n " , Facs - > XFirmwareWakingVector ) ;
DBG ( " Hardware signature =%08lx \n " , Facs - > HardwareSignature ) ;
DBG ( " GlobalLock =%08lx \n " , Facs - > GlobalLock ) ;
DBG ( " Flags =%08lx \n " , Facs - > Flags ) ;
DBG ( " HS at offset 0x%08X \n " , OFFSET_OF ( EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE , HardwareSignature ) ) ;
// machineSignature = Facs->HardwareSignature;
}
}
*/
// DBG("BeginExternalScreen\n");
BeginExternalScreen ( OSFLAG_ISSET ( Flags , OSFLAG_USEGRAPHICS ) /*, L"Booting OS"*/ ) ;
if ( ! OSTYPE_IS_WINDOWS ( LoaderType ) & & ! OSTYPE_IS_LINUX ( LoaderType ) ) {
if ( OSFLAG_ISSET ( Flags , OSFLAG_USEGRAPHICS ) ) {
// save orig OutputString and replace it with
// null implementation
ConOutOutputString = gST - > ConOut - > OutputString ;
gST - > ConOut - > OutputString = NullConOutOutputString ;
}
// Initialize the boot screen
if ( EFI_ERROR ( Status = InitBootScreen ( this ) ) ) {
if ( Status ! = EFI_ABORTED ) DBG ( " Failed to initialize custom boot screen: %s! \n " , efiStrError ( Status ) ) ;
}
else if ( EFI_ERROR ( Status = LockBootScreen ( ) ) ) {
DBG ( " Failed to lock custom boot screen: %s! \n " , efiStrError ( Status ) ) ;
}
} // !OSTYPE_IS_WINDOWS
if ( OSTYPE_IS_OSX ( LoaderType ) | |
OSTYPE_IS_OSX_RECOVERY ( LoaderType ) | |
OSTYPE_IS_OSX_INSTALLER ( LoaderType ) ) {
if ( DoHibernateWake ) {
DBG ( " Closing events for wake \n " ) ;
gBS - > CloseEvent ( OnReadyToBootEvent ) ;
gBS - > CloseEvent ( ExitBootServiceEvent ) ;
gBS - > CloseEvent ( mSimpleFileSystemChangeEvent ) ;
// gBS->CloseEvent (mVirtualAddressChangeEvent);
// When doing hibernate wake, save to DataHub only up to initial size of log
SavePreBootLog = FALSE ;
} else {
// delete boot-switch-vars if exists
Status = gRT - > SetVariable ( L " boot-switch-vars " , & gEfiAppleBootGuid ,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS ,
0 , NULL ) ;
DeleteNvramVariable ( L " IOHibernateRTCVariables " , & gEfiAppleBootGuid ) ;
DeleteNvramVariable ( L " boot-image " , & gEfiAppleBootGuid ) ;
}
SetupBooterLog ( ! DoHibernateWake ) ;
}
2020-02-15 15:51:18 +01:00
DBG ( " Closing log \n " ) ;
if ( SavePreBootLog ) {
Status = SaveBooterLog ( SelfRootDir , PREBOOT_LOG ) ;
if ( EFI_ERROR ( Status ) ) {
/*Status = */ SaveBooterLog ( NULL , PREBOOT_LOG ) ;
}
}
// DBG("StartEFIImage\n");
2020-05-01 18:26:28 +02:00
// StartEFIImage(DevicePath, LoadOptions,
// Basename(LoaderPath), Basename(LoaderPath), NULL, NULL);
2020-02-15 15:51:18 +01:00
// DBG("StartEFILoadedImage\n");
2020-05-01 18:26:28 +02:00
StartEFILoadedImage ( ImageHandle , LoadOptions , Basename ( LoaderPath . wc_str ( ) ) , LoaderPath . basename ( ) , NULL ) ;
2020-02-15 15:51:18 +01:00
// Unlock boot screen
if ( EFI_ERROR ( Status = UnlockBootScreen ( ) ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " Failed to unlock custom boot screen: %s! \n " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
2020-05-01 18:26:28 +02:00
if ( OSFLAG_ISSET ( Flags , OSFLAG_USEGRAPHICS ) ) {
2020-02-15 15:51:18 +01:00
// return back orig OutputString
gST - > ConOut - > OutputString = ConOutOutputString ;
}
// PauseForKey(L"FinishExternalScreen");
FinishExternalScreen ( ) ;
// PauseForKey(L"System started?!");
}
2020-02-18 19:49:54 +01:00
2020-02-15 15:51:18 +01:00
# define MAX_DISCOVERED_PATHS (16)
//#define PREBOOT_LOG L"EFI\\CLOVER\\misc\\preboot.log"
2020-05-01 18:26:28 +02:00
VOID LEGACY_ENTRY : : StartLegacy ( )
2020-02-15 15:51:18 +01:00
{
EFI_STATUS Status = EFI_UNSUPPORTED ;
// Unload EmuVariable before booting legacy.
// This is not needed in most cases, but it seems to interfere with legacy OS
// booted on some UEFI bioses, such as Phoenix UEFI 2.0
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
if ( gSettings . LastBootedVolume ) {
2020-05-01 18:26:28 +02:00
SetStartupDiskVolume ( Volume , NullXStringW ) ;
2020-08-15 15:47:56 +02:00
} else if ( gSettings . DefaultVolume . notEmpty ( ) ) {
2020-02-15 15:51:18 +01:00
// DefaultVolume specified in Config.plist:
// we'll remove macOS Startup Disk vars which may be present if it is used
// to reboot into another volume
RemoveStartupDiskVolume ( ) ;
}
2020-04-01 14:57:32 +02:00
egClearScreen ( & MenuBackgroundPixel ) ;
BeginExternalScreen ( TRUE /*, L"Booting Legacy OS"*/ ) ;
2020-03-30 10:34:16 +02:00
XImage BootLogoX ;
2020-05-01 18:26:28 +02:00
BootLogoX . LoadXImage ( ThemeX . ThemeDir , Volume - > LegacyOS - > IconName ) ;
2020-03-30 10:34:16 +02:00
BootLogoX . Draw ( ( UGAWidth - BootLogoX . GetWidth ( ) ) > > 1 ,
( UGAHeight - BootLogoX . GetHeight ( ) ) > > 1 ) ;
2020-02-15 15:51:18 +01:00
//try my LegacyBoot
2020-05-01 18:26:28 +02:00
switch ( Volume - > BootType ) {
2020-02-15 15:51:18 +01:00
case BOOTING_BY_CD :
2020-05-01 18:26:28 +02:00
Status = bootElTorito ( Volume ) ;
2020-02-15 15:51:18 +01:00
break ;
case BOOTING_BY_MBR :
2020-05-01 18:26:28 +02:00
Status = bootMBR ( Volume ) ;
2020-02-15 15:51:18 +01:00
break ;
case BOOTING_BY_PBR :
2020-08-15 15:47:56 +02:00
if ( gSettings . LegacyBoot = = " LegacyBiosDefault " _XS8 ) {
2020-02-15 15:51:18 +01:00
Status = bootLegacyBiosDefault ( gSettings . LegacyBiosDefaultEntry ) ;
2020-08-15 15:47:56 +02:00
} else if ( gSettings . LegacyBoot = = " PBRtest " _XS8 ) {
2020-05-01 18:26:28 +02:00
Status = bootPBRtest ( Volume ) ;
2020-08-15 15:47:56 +02:00
} else if ( gSettings . LegacyBoot = = " PBRsata " _XS8 ) {
2020-05-01 18:26:28 +02:00
Status = bootPBR ( Volume , TRUE ) ;
2020-02-15 15:51:18 +01:00
} else {
// default
2020-05-01 18:26:28 +02:00
Status = bootPBR ( Volume , FALSE ) ;
2020-02-15 15:51:18 +01:00
}
break ;
default :
break ;
}
CheckError ( Status , L " while LegacyBoot " ) ;
2020-02-18 19:49:54 +01:00
FinishExternalScreen ( ) ;
2020-02-15 15:51:18 +01:00
}
//
// pre-boot tool functions
//
2020-05-01 18:26:28 +02:00
VOID REFIT_MENU_ENTRY_LOADER_TOOL : : StartTool ( )
2020-02-15 15:51:18 +01:00
{
2020-05-01 18:26:28 +02:00
DBG ( " Start Tool: %ls \n " , LoaderPath . wc_str ( ) ) ;
2020-04-01 14:57:32 +02:00
egClearScreen ( & MenuBackgroundPixel ) ;
2020-02-15 15:51:18 +01:00
// assumes "Start <title>" as assigned below
2020-05-01 18:26:28 +02:00
BeginExternalScreen ( OSFLAG_ISSET ( Flags , OSFLAG_USEGRAPHICS ) /*, &Entry->Title[6]*/ ) ; // Shouldn't we check that length of Title is at least 6 ?
StartEFIImage ( DevicePath , LoadOptions , Basename ( LoaderPath . wc_str ( ) ) , LoaderPath . basename ( ) , NULL , NULL ) ;
2020-02-15 15:51:18 +01:00
FinishExternalScreen ( ) ;
//ReinitSelfLib();
}
//
// pre-boot driver functions
//
2020-02-17 21:41:09 +01:00
static VOID ScanDriverDir ( IN CONST CHAR16 * Path , OUT EFI_HANDLE * * DriversToConnect , OUT UINTN * DriversToConnectNum )
2020-02-15 15:51:18 +01:00
{
EFI_STATUS Status ;
REFIT_DIR_ITER DirIter ;
EFI_FILE_INFO * DirEntry ;
CHAR16 FileName [ 256 ] ;
EFI_HANDLE DriverHandle ;
EFI_DRIVER_BINDING_PROTOCOL * DriverBinding ;
UINTN DriversArrSize ;
UINTN DriversArrNum ;
EFI_HANDLE * DriversArr ;
BOOLEAN Skip ;
UINT8 AptioBlessed ;
STATIC CHAR16 CONST * CONST AptioNames [ ] = {
L " AptioMemoryFix " ,
L " AptioFix3Drv " ,
L " AptioFix2Drv " ,
L " AptioFixDrv " ,
L " LowMemFix "
} ;
STATIC UINT8 CONST AptioIndices [ ] = {
OFFSET_OF ( DRIVERS_FLAGS , AptioMemFixLoaded ) ,
OFFSET_OF ( DRIVERS_FLAGS , AptioFix3Loaded ) ,
OFFSET_OF ( DRIVERS_FLAGS , AptioFix2Loaded ) ,
OFFSET_OF ( DRIVERS_FLAGS , AptioFixLoaded ) ,
OFFSET_OF ( DRIVERS_FLAGS , MemFixLoaded )
} ;
DriversArrSize = 0 ;
DriversArrNum = 0 ;
DriversArr = NULL ;
//only one driver with highest priority will obtain status "Loaded"
DirIterOpen ( SelfRootDir , Path , & DirIter ) ;
# define BOOLEAN_AT_INDEX(k) (*(BOOLEAN*)((UINTN)&gDriversFlags + AptioIndices[(k)]))
2020-08-31 11:00:52 +02:00
for ( size_t i = 0 ; i ! = ARRAY_SIZE ( AptioIndices ) ; + + i )
2020-02-15 15:51:18 +01:00
BOOLEAN_AT_INDEX ( i ) = FALSE ;
AptioBlessed = ( UINT8 ) ARRAY_SIZE ( AptioNames ) ;
while ( DirIterNext ( & DirIter , 2 , L " *.efi " , & DirEntry ) ) {
2020-08-31 11:00:52 +02:00
size_t i ;
2020-02-15 15:51:18 +01:00
for ( i = 0 ; i ! = ARRAY_SIZE ( AptioNames ) ; + + i )
if ( StrStr ( DirEntry - > FileName , AptioNames [ i ] ) ! = NULL )
break ;
if ( ( ( UINT8 ) i ) > = AptioBlessed )
continue ;
AptioBlessed = ( UINT8 ) i ;
if ( ! i )
break ;
}
DirIterClose ( & DirIter ) ;
// look through contents of the directory
DirIterOpen ( SelfRootDir , Path , & DirIter ) ;
while ( DirIterNext ( & DirIter , 2 , L " *.efi " , & DirEntry ) ) {
Skip = ( DirEntry - > FileName [ 0 ] = = L ' . ' ) ;
2020-08-31 11:00:52 +02:00
for ( size_t i = 0 ; i < gSettings . DisabledDriverArray . size ( ) ; i + + ) {
if ( StrStr ( DirEntry - > FileName , gSettings . DisabledDriverArray [ i ] . wc_str ( ) ) ! = NULL ) {
2020-02-15 15:51:18 +01:00
Skip = TRUE ; // skip this
break ;
}
}
if ( Skip ) {
continue ;
}
2020-08-31 11:00:52 +02:00
{
size_t i ;
2020-08-31 14:24:00 +02:00
// either AptioMem, AptioFix* or LowMemFix exclusively
for ( i = 0 ; i ! = ARRAY_SIZE ( AptioNames ) ; + + i )
if ( StrStr ( DirEntry - > FileName , AptioNames [ i ] ) ! = NULL )
break ;
if ( i ! = ARRAY_SIZE ( AptioNames ) ) {
if ( ( ( UINT8 ) i ) ! = AptioBlessed )
continue ;
if ( AptioBlessed < ( UINT8 ) ARRAY_SIZE ( AptioIndices ) )
BOOLEAN_AT_INDEX ( AptioBlessed ) = TRUE ;
AptioBlessed = ( UINT8 ) ARRAY_SIZE ( AptioNames ) ;
}
2020-08-31 11:00:52 +02:00
}
2020-02-15 15:51:18 +01:00
# undef BOOLEAN_AT_INDEX
2020-04-04 15:50:13 +02:00
snwprintf ( FileName , 512 , " %ls \\ %ls " , Path , DirEntry - > FileName ) ;
2020-02-15 15:51:18 +01:00
Status = StartEFIImage ( FileDevicePath ( SelfLoadedImage - > DeviceHandle , FileName ) ,
2020-08-11 08:00:19 +02:00
NullXString8Array , DirEntry - > FileName , XStringW ( ) . takeValueFrom ( DirEntry - > FileName ) , NULL , & DriverHandle ) ;
2020-02-15 15:51:18 +01:00
if ( EFI_ERROR ( Status ) ) {
continue ;
}
2020-06-18 18:08:00 +02:00
if ( StrStr ( FileName , L " AudioDxe " ) ! = NULL ) {
AudioDriverHandle = DriverHandle ;
}
2020-02-15 15:51:18 +01:00
if ( StrStr ( FileName , L " EmuVariable " ) ! = NULL ) {
gDriversFlags . EmuVariableLoaded = TRUE ;
} else if ( StrStr ( FileName , L " Video " ) ! = NULL ) {
gDriversFlags . VideoLoaded = TRUE ;
} else if ( StrStr ( FileName , L " Partition " ) ! = NULL ) {
gDriversFlags . PartitionLoaded = TRUE ;
} else if ( StrStr ( FileName , L " HFS " ) ! = NULL ) {
gDriversFlags . HFSLoaded = TRUE ;
} else if ( StriStr ( FileName , L " apfs " ) ! = NULL ) {
gDriversFlags . APFSLoaded = TRUE ;
}
if ( DriverHandle ! = NULL & & DriversToConnectNum ! = NULL & & DriversToConnect ! = NULL ) {
// driver loaded - check for EFI_DRIVER_BINDING_PROTOCOL
Status = gBS - > HandleProtocol ( DriverHandle , & gEfiDriverBindingProtocolGuid , ( VOID * * ) & DriverBinding ) ;
if ( ! EFI_ERROR ( Status ) & & DriverBinding ! = NULL ) {
DBG ( " - driver needs connecting \n " ) ;
// standard UEFI driver - we would reconnect after loading - add to array
if ( DriversArrSize = = 0 ) {
// new array
DriversArrSize = 16 ;
2020-08-15 15:47:56 +02:00
DriversArr = ( __typeof__ ( DriversArr ) ) AllocateZeroPool ( sizeof ( EFI_HANDLE ) * DriversArrSize ) ;
2020-02-15 15:51:18 +01:00
} else if ( DriversArrNum + 1 = = DriversArrSize ) {
// extend array
DriversArr = ( __typeof__ ( DriversArr ) ) ReallocatePool ( DriversArrSize , DriversArrSize + 16 , DriversArr ) ;
DriversArrSize + = 16 ;
}
DriversArr [ DriversArrNum ] = DriverHandle ;
2020-03-25 19:32:44 +01:00
// DBG(" driver %ls included with Binding=%X\n", FileName, DriverBinding);
2020-02-15 15:51:18 +01:00
DriversArrNum + + ;
// we'll make array terminated
DriversArr [ DriversArrNum ] = NULL ;
}
}
}
Status = DirIterClose ( & DirIter ) ;
if ( Status ! = EFI_NOT_FOUND ) {
2020-04-04 15:50:13 +02:00
snwprintf ( FileName , 512 , " while scanning the %ls directory " , Path ) ;
2020-02-15 15:51:18 +01:00
CheckError ( Status , FileName ) ;
}
if ( DriversToConnectNum ! = NULL & & DriversToConnect ! = NULL ) {
* DriversToConnectNum = DriversArrNum ;
* DriversToConnect = DriversArr ;
}
}
/**
* Some UEFI ' s ( like HPQ EFI from HP notebooks ) have DiskIo protocols
* opened BY_DRIVER ( by Partition driver in HP case ) even when no file system
* is produced from this DiskIo . This then blocks our FS drivers from connecting
* and producing file systems .
* To fix it : we will disconnect drivers that connected to DiskIo BY_DRIVER
* if this is partition volume and if those drivers did not produce file system .
*/
VOID DisconnectInvalidDiskIoChildDrivers ( VOID )
{
EFI_STATUS Status ;
UINTN HandleCount = 0 ;
UINTN Index ;
UINTN OpenInfoIndex ;
EFI_HANDLE * Handles = NULL ;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * Fs ;
EFI_BLOCK_IO_PROTOCOL * BlockIo ;
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY * OpenInfo ;
UINTN OpenInfoCount ;
BOOLEAN Found ;
DBG ( " Searching for invalid DiskIo BY_DRIVER connects: " ) ;
//
// Get all DiskIo handles
//
Status = gBS - > LocateHandleBuffer ( ByProtocol , & gEfiDiskIoProtocolGuid , NULL , & HandleCount , & Handles ) ;
if ( EFI_ERROR ( Status ) | | HandleCount = = 0 ) {
DBG ( " no DiskIo handles \n " ) ;
return ;
}
//
// Check every DiskIo handle
//
Found = FALSE ;
for ( Index = 0 ; Index < HandleCount ; Index + + ) {
//DBG("\n");
//DBG(" - Handle %p:", Handles[Index]);
//
// If this is not partition - skip it.
// This is then whole disk and DiskIo
// should be opened here BY_DRIVER by Partition driver
// to produce partition volumes.
//
Status = gBS - > HandleProtocol (
Handles [ Index ] ,
& gEfiBlockIoProtocolGuid ,
( VOID * * ) & BlockIo
) ;
2020-04-23 11:08:10 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
//DBG(" BlockIo: %s - skipping\n", efiStrError(Status));
2020-02-15 15:51:18 +01:00
continue ;
}
if ( BlockIo - > Media = = NULL ) {
//DBG(" BlockIo: no media - skipping\n");
continue ;
}
if ( ! BlockIo - > Media - > LogicalPartition ) {
//DBG(" BlockIo: whole disk - skipping\n");
continue ;
}
//DBG(" BlockIo: partition");
//
// If SimpleFileSystem is already produced - skip it, this is ok
//
Status = gBS - > HandleProtocol (
Handles [ Index ] ,
& gEfiSimpleFileSystemProtocolGuid ,
( VOID * * ) & Fs
) ;
if ( Status = = EFI_SUCCESS ) {
//DBG(" FS: ok - skipping\n");
continue ;
}
//DBG(" FS: no");
//
// If no SimpleFileSystem on this handle but DiskIo is opened BY_DRIVER
// then disconnect this connection
//
Status = gBS - > OpenProtocolInformation (
Handles [ Index ] ,
& gEfiDiskIoProtocolGuid ,
& OpenInfo ,
& OpenInfoCount
) ;
2020-04-23 11:08:10 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-02-15 15:51:18 +01:00
//DBG(" OpenInfo: no - skipping\n");
continue ;
}
//DBG(" OpenInfo: %d", OpenInfoCount);
for ( OpenInfoIndex = 0 ; OpenInfoIndex < OpenInfoCount ; OpenInfoIndex + + ) {
if ( ( OpenInfo [ OpenInfoIndex ] . Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER ) = = EFI_OPEN_PROTOCOL_BY_DRIVER ) {
if ( ! Found ) {
DBG ( " \n " ) ;
}
Found = TRUE ;
Status = gBS - > DisconnectController ( Handles [ Index ] , OpenInfo [ OpenInfoIndex ] . AgentHandle , NULL ) ;
2020-08-25 17:35:19 +02:00
//DBG(" BY_DRIVER Agent: %p, Disconnect: %s", OpenInfo[OpenInfoIndex].AgentHandle, efiStrError(Status));
DBG ( " - Handle %p with DiskIo, is Partition, no Fs, BY_DRIVER Agent: %p, Disconnect: %s \n " , Handles [ Index ] , OpenInfo [ OpenInfoIndex ] . AgentHandle , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
}
2020-04-23 11:08:10 +02:00
FreePool ( OpenInfo ) ;
2020-02-15 15:51:18 +01:00
}
FreePool ( Handles ) ;
if ( ! Found ) {
DBG ( " not found, all ok \n " ) ;
}
}
VOID DisconnectSomeDevices ( VOID )
{
EFI_STATUS Status ;
UINTN HandleCount ;
UINTN Index , Index2 ;
EFI_HANDLE * Handles ;
EFI_HANDLE * ControllerHandles ;
UINTN ControllerHandleCount ;
EFI_BLOCK_IO_PROTOCOL * BlockIo = NULL ;
// EFI_DISK_IO_PROTOCOL *DiskIo = NULL;
EFI_PCI_IO_PROTOCOL * PciIo = NULL ;
// EFI_FILE_PROTOCOL *RootFP = NULL;
// EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *VolumeFS = NULL;
PCI_TYPE00 Pci ;
CHAR16 * DriverName ;
EFI_COMPONENT_NAME_PROTOCOL * CompName ;
if ( gDriversFlags . PartitionLoaded ) {
DBG ( " Partition driver loaded: " ) ;
// get all BlockIo handles
HandleCount = 0 ;
Handles = NULL ;
Status = gBS - > LocateHandleBuffer ( ByProtocol , & gEfiBlockIoProtocolGuid , NULL , & HandleCount , & Handles ) ;
if ( Status = = EFI_SUCCESS ) {
for ( Index = 0 ; Index < HandleCount ; Index + + ) {
Status = gBS - > HandleProtocol ( Handles [ Index ] , & gEfiBlockIoProtocolGuid , ( VOID * * ) & BlockIo ) ;
if ( EFI_ERROR ( Status ) ) {
continue ;
}
if ( BlockIo - > Media - > BlockSize = = 2048 ) {
// disconnect CD controller
Status = gBS - > DisconnectController ( Handles [ Index ] , NULL , NULL ) ;
2020-08-25 17:35:19 +02:00
DBG ( " CD disconnect %s " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
}
/* for (Index = 0; Index < HandleCount; Index++) {
Status = gBS - > DisconnectController ( Handles [ Index ] , NULL , NULL ) ;
} */
FreePool ( Handles ) ;
}
DBG ( " \n " ) ;
}
if ( ( gDriversFlags . HFSLoaded ) | | ( gDriversFlags . APFSLoaded ) ) {
2020-02-18 19:49:54 +01:00
if ( gDriversFlags . HFSLoaded ) {
DBG ( " HFS+ driver loaded \n " ) ;
2020-02-15 15:51:18 +01:00
}
if ( gDriversFlags . APFSLoaded ) {
DBG ( " APFS driver loaded \n " ) ;
}
// get all FileSystem handles
ControllerHandleCount = 0 ;
ControllerHandles = NULL ;
Status = gBS - > LocateHandleBuffer ( ByProtocol , & gEfiSimpleFileSystemProtocolGuid , NULL , & ControllerHandleCount , & ControllerHandles ) ;
2020-04-23 11:08:10 +02:00
/* if (!EFI_ERROR(Status)) {
2020-02-15 15:51:18 +01:00
for ( Index2 = 0 ; Index2 < ControllerHandleCount ; Index2 + + ) {
Status = gBS - > DisconnectController ( ControllerHandles [ Index2 ] ,
NULL , NULL ) ;
2020-08-25 17:35:19 +02:00
DBG ( " Driver [%d] disconnect %s \n " , Index2 , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
} */
HandleCount = 0 ;
Handles = NULL ;
Status = gBS - > LocateHandleBuffer ( ByProtocol , & gEfiComponentNameProtocolGuid , NULL , & HandleCount , & Handles ) ;
2020-04-23 11:08:10 +02:00
if ( ! EFI_ERROR ( Status ) ) {
2020-02-15 15:51:18 +01:00
for ( Index = 0 ; Index < HandleCount ; Index + + ) {
Status = gBS - > OpenProtocol (
Handles [ Index ] ,
& gEfiComponentNameProtocolGuid ,
( VOID * * ) & CompName ,
gImageHandle ,
NULL ,
EFI_OPEN_PROTOCOL_GET_PROTOCOL ) ;
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
// DBG("CompName %s\n", efiStrError(Status));
2020-02-15 15:51:18 +01:00
continue ;
}
Status = CompName - > GetDriverName ( CompName , " eng " , & DriverName ) ;
if ( EFI_ERROR ( Status ) ) {
continue ;
}
if ( ( StriStr ( DriverName , L " HFS " ) ) | | ( StriStr ( DriverName , L " apfs " ) ) ) {
for ( Index2 = 0 ; Index2 < ControllerHandleCount ; Index2 + + ) {
Status = gBS - > DisconnectController ( ControllerHandles [ Index2 ] ,
Handles [ Index ] , NULL ) ;
2020-08-25 17:35:19 +02:00
// DBG("Disconnect [%ls] from %X: %s\n", DriverName, ControllerHandles[Index2], efiStrError(Status));
2020-02-15 15:51:18 +01:00
}
}
}
FreePool ( Handles ) ;
}
// DBG("\n");
FreePool ( ControllerHandles ) ;
}
if ( gDriversFlags . VideoLoaded ) {
DBG ( " Video driver loaded: " ) ;
// get all PciIo handles
HandleCount = 0 ;
Handles = NULL ;
Status = gBS - > LocateHandleBuffer ( ByProtocol , & gEfiPciIoProtocolGuid , NULL , & HandleCount , & Handles ) ;
if ( Status = = EFI_SUCCESS ) {
for ( Index = 0 ; Index < HandleCount ; Index + + ) {
Status = gBS - > HandleProtocol ( Handles [ Index ] , & gEfiPciIoProtocolGuid , ( VOID * * ) & PciIo ) ;
if ( EFI_ERROR ( Status ) ) {
continue ;
}
Status = PciIo - > Pci . Read ( PciIo , EfiPciIoWidthUint32 , 0 , sizeof ( Pci ) / sizeof ( UINT32 ) , & Pci ) ;
2020-04-23 11:08:10 +02:00
if ( ! EFI_ERROR ( Status ) ) {
2020-02-15 15:51:18 +01:00
if ( IS_PCI_VGA ( & Pci ) = = TRUE ) {
// disconnect VGA
Status = gBS - > DisconnectController ( Handles [ Index ] , NULL , NULL ) ;
2020-08-25 17:35:19 +02:00
DBG ( " disconnect %s " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
}
}
FreePool ( Handles ) ;
}
DBG ( " \n " ) ;
}
if ( ! gFirmwareClover ) {
DisconnectInvalidDiskIoChildDrivers ( ) ;
}
}
VOID PatchVideoBios ( UINT8 * Edid )
{
if ( gSettings . PatchVBiosBytesCount > 0 & & gSettings . PatchVBiosBytes ! = NULL ) {
VideoBiosPatchBytes ( gSettings . PatchVBiosBytes , gSettings . PatchVBiosBytesCount ) ;
}
if ( gSettings . PatchVBios ) {
VideoBiosPatchNativeFromEdid ( Edid ) ;
}
}
static VOID LoadDrivers ( VOID )
{
EFI_STATUS Status ;
EFI_HANDLE * DriversToConnect = NULL ;
UINTN DriversToConnectNum = 0 ;
UINT8 * Edid ;
UINTN VarSize = 0 ;
BOOLEAN VBiosPatchNeeded ;
DbgHeader ( " LoadDrivers " ) ;
// load drivers from /efi/drivers
# if defined(MDE_CPU_X64)
if ( gFirmwareClover ) {
if ( FileExists ( SelfRootDir , L " \\ EFI \\ CLOVER \\ drivers \\ BIOS " ) ) {
ScanDriverDir ( L " \\ EFI \\ CLOVER \\ drivers \\ BIOS " , & DriversToConnect , & DriversToConnectNum ) ;
} else {
ScanDriverDir ( L " \\ EFI \\ CLOVER \\ drivers64 " , & DriversToConnect , & DriversToConnectNum ) ;
}
} else
if ( FileExists ( SelfRootDir , L " \\ EFI \\ CLOVER \\ drivers \\ UEFI " ) ) {
ScanDriverDir ( L " \\ EFI \\ CLOVER \\ drivers \\ UEFI " , & DriversToConnect , & DriversToConnectNum ) ;
} else {
ScanDriverDir ( L " \\ EFI \\ CLOVER \\ drivers64UEFI " , & DriversToConnect , & DriversToConnectNum ) ;
}
# else
ScanDriverDir ( L " \\ EFI \\ CLOVER \\ drivers32 " , & DriversToConnect , & DriversToConnectNum ) ;
# endif
VBiosPatchNeeded = gSettings . PatchVBios | | ( gSettings . PatchVBiosBytesCount > 0 & & gSettings . PatchVBiosBytes ! = NULL ) ;
if ( VBiosPatchNeeded ) {
// check if it is already done in CloverEFI BiosVideo
Status = gRT - > GetVariable (
L " CloverVBiosPatchDone " ,
& gEfiGlobalVariableGuid ,
NULL ,
& VarSize ,
NULL
) ;
if ( Status = = EFI_BUFFER_TOO_SMALL ) {
// var exists - it's done - let's not do it again
VBiosPatchNeeded = FALSE ;
}
}
if ( ( ( gSettings . CustomEDID ! = NULL ) & & gFirmwareClover ) | | ( VBiosPatchNeeded & & ! gDriversFlags . VideoLoaded ) ) {
// we have video bios patch - force video driver reconnect
DBG ( " Video bios patch requested or CustomEDID - forcing video reconnect \n " ) ;
gDriversFlags . VideoLoaded = TRUE ;
DriversToConnectNum + + ;
}
if ( DriversToConnectNum > 0 ) {
2020-03-25 19:32:44 +01:00
DBG ( " %llu drivers needs connecting ... \n " , DriversToConnectNum ) ;
2020-02-15 15:51:18 +01:00
// note: our platform driver protocol
// will use DriversToConnect - do not release it
RegisterDriversToHighestPriority ( DriversToConnect ) ;
if ( VBiosPatchNeeded ) {
if ( gSettings . CustomEDID ! = NULL ) {
Edid = gSettings . CustomEDID ;
} else {
Edid = getCurrentEdid ( ) ;
}
DisconnectSomeDevices ( ) ;
PatchVideoBios ( Edid ) ;
if ( gSettings . CustomEDID = = NULL ) {
FreePool ( Edid ) ;
}
} else {
DisconnectSomeDevices ( ) ;
}
BdsLibConnectAllDriversToAllControllers ( ) ;
// Boot speedup: remove temporary "BiosVideoBlockSwitchMode" RT var
// to unlock mode switching in CsmVideo
gRT - > SetVariable ( L " BiosVideoBlockSwitchMode " , & gEfiGlobalVariableGuid , EFI_VARIABLE_BOOTSERVICE_ACCESS , 0 , NULL ) ;
}
}
INTN FindDefaultEntry ( VOID )
{
INTN Index = - 1 ;
REFIT_VOLUME * Volume ;
BOOLEAN SearchForLoader ;
// DBG("FindDefaultEntry ...\n");
//DbgHeader("FindDefaultEntry");
//
// try to detect volume set by Startup Disk or previous Clover selection
// with broken nvram this requires emulation to be installed.
// enable emulation to determin efi-boot-device-data
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > InstallEmulation ( gEmuVariableControl ) ;
}
Index = FindStartupDiskVolume ( & MainMenu ) ;
if ( Index > = 0 ) {
2020-03-25 19:32:44 +01:00
DBG ( " Boot redirected to Entry %lld. '%ls' \n " , Index , MainMenu . Entries [ Index ] . Title . s ( ) ) ;
2020-02-15 15:51:18 +01:00
// we got boot-device-data, no need to keep emulating anymore
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
return Index ;
}
//
// if not found, then try DefaultVolume from config.plist
// if not null or empty, search volume that matches gSettings.DefaultVolume
//
2020-08-15 15:47:56 +02:00
if ( gSettings . DefaultVolume . notEmpty ( ) ) {
2020-02-15 15:51:18 +01:00
// if not null or empty, also search for loader that matches gSettings.DefaultLoader
2020-08-15 15:47:56 +02:00
SearchForLoader = gSettings . DefaultLoader . notEmpty ( ) ;
2020-02-15 15:51:18 +01:00
/*
if ( SearchForLoader ) {
2020-03-25 19:32:44 +01:00
DBG ( " Searching for DefaultVolume '%ls', DefaultLoader '%ls' ... \n " , gSettings . DefaultVolume , gSettings . DefaultLoader ) ;
2020-02-15 15:51:18 +01:00
} else {
2020-03-25 19:32:44 +01:00
DBG ( " Searching for DefaultVolume '%ls' ... \n " , gSettings . DefaultVolume ) ;
2020-02-15 15:51:18 +01:00
}
*/
2020-02-28 21:28:33 +01:00
for ( Index = 0 ; Index < ( INTN ) MainMenu . Entries . size ( ) & & MainMenu . Entries [ Index ] . getLOADER_ENTRY ( ) & & MainMenu . Entries [ Index ] . getLOADER_ENTRY ( ) - > Row = = 0 ; Index + + ) {
2020-02-15 15:51:18 +01:00
2020-02-28 21:28:33 +01:00
LOADER_ENTRY & Entry = * MainMenu . Entries [ Index ] . getLOADER_ENTRY ( ) ;
if ( ! Entry . Volume ) {
2020-02-15 15:51:18 +01:00
continue ;
}
2020-02-28 21:28:33 +01:00
Volume = Entry . Volume ;
2020-08-15 15:47:56 +02:00
if ( ( Volume - > VolName . isEmpty ( ) | | Volume - > VolName ! = gSettings . DefaultVolume ) & &
! Volume - > DevicePathString . contains ( gSettings . DefaultVolume ) ) {
2020-02-15 15:51:18 +01:00
continue ;
}
2020-02-28 21:28:33 +01:00
// we alreday know that Entry.isLoader
2020-04-27 11:50:49 +02:00
if ( SearchForLoader & & ( /*Entry.Tag != TAG_LOADER ||*/ ! Entry . LoaderPath . containsIC ( gSettings . DefaultLoader ) ) ) {
2020-02-15 15:51:18 +01:00
continue ;
}
2020-08-09 17:55:30 +02:00
DBG ( " - found entry %lld. '%ls', Volume '%ls', DevicePath '%ls' \n " , Index , Entry . Title . s ( ) , Volume - > VolName . wc_str ( ) , Entry . DevicePathString . wc_str ( ) ) ;
2020-02-15 15:51:18 +01:00
// if first method failed and second succeeded - uninstall emulation
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
return Index ;
}
}
DBG ( " Default boot entry not found \n " ) ;
// if both methods to determine default boot entry have failed - uninstall emulation before GUI
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
return - 1 ;
}
VOID SetVariablesFromNvram ( )
{
CHAR8 * tmpString ;
UINTN Size = 0 ;
2020-08-15 15:47:56 +02:00
UINTN index = 0 , index2 , i ;
2020-02-15 15:51:18 +01:00
CHAR8 * arg = NULL ;
// DbgHeader("SetVariablesFromNvram");
tmpString = ( __typeof__ ( tmpString ) ) GetNvramVariable ( L " boot-args " , & gEfiAppleBootGuid , NULL , & Size ) ;
if ( tmpString & & ( Size < = 0x1000 ) & & ( Size > 0 ) ) {
2020-03-25 19:32:44 +01:00
DBG ( " found boot-args in NVRAM:%s, size=%llu \n " , tmpString , Size ) ;
2020-02-15 15:51:18 +01:00
// use and forget old one
// DeleteNvramVariable(L"boot-args", &gEfiAppleBootGuid);
Size = AsciiStrLen ( tmpString ) ; // some EFI implementations include '\0' in Size, and others don't, so update Size to string length
arg = ( __typeof__ ( arg ) ) AllocatePool ( Size + 1 ) ;
/* if (AsciiStrStr(tmpString, "nvda_drv=1")) { //found substring
gSettings . NvidiaWeb = TRUE ;
} */
//first we will find new args that is not present in main args
index = 0 ;
while ( ( index < Size ) & & ( tmpString [ index ] ! = 0x0 ) ) {
ZeroMem ( arg , Size + 1 ) ;
index2 = 0 ;
if ( tmpString [ index ] ! = ' \" ' ) {
// DBG("search space index=%d\n", index);
while ( ( index < Size ) & & ( tmpString [ index ] ! = 0x20 ) & & ( tmpString [ index ] ! = 0x0 ) ) {
arg [ index2 + + ] = tmpString [ index + + ] ;
}
2020-03-25 19:32:44 +01:00
DBG ( " ...found arg:%s \n " , arg ) ;
2020-02-15 15:51:18 +01:00
} else {
index + + ;
// DBG("search quote index=%d\n", index);
while ( ( index < Size ) & & ( tmpString [ index ] ! = ' \" ' ) & & ( tmpString [ index ] ! = 0x0 ) ) {
arg [ index2 + + ] = tmpString [ index + + ] ;
}
if ( tmpString [ index ] = = ' \" ' ) {
index + + ;
}
2020-03-25 19:32:44 +01:00
DBG ( " ...found quoted arg: \n " /*, arg*/ ) ;
2020-02-15 15:51:18 +01:00
}
while ( tmpString [ index ] = = 0x20 ) {
index + + ;
}
// For the moment only arg -s must be ignored
if ( AsciiStrCmp ( arg , " -s " ) = = 0 ) {
2020-04-05 23:14:27 +02:00
DBG ( " ...ignoring arg:%s \n " , arg ) ;
2020-02-15 15:51:18 +01:00
continue ;
}
2020-08-15 15:47:56 +02:00
if ( ! gSettings . BootArgs . contains ( arg ) ) {
2020-02-15 15:51:18 +01:00
//this arg is not present will add
2020-03-25 19:32:44 +01:00
DBG ( " ...adding arg:%s \n " , arg ) ;
2020-08-15 15:47:56 +02:00
gSettings . BootArgs . trim ( ) ;
gSettings . BootArgs + = ' ' ;
2020-02-15 15:51:18 +01:00
for ( i = 0 ; i < index2 ; i + + ) {
2020-08-15 15:47:56 +02:00
gSettings . BootArgs + = arg [ i ] ;
2020-02-15 15:51:18 +01:00
}
2020-08-15 15:47:56 +02:00
gSettings . BootArgs + = ' ' ;
2020-02-15 15:51:18 +01:00
}
}
FreePool ( arg ) ;
}
if ( tmpString ) {
FreePool ( tmpString ) ;
}
tmpString = ( __typeof__ ( tmpString ) ) GetNvramVariable ( L " nvda_drv " , & gEfiAppleBootGuid , NULL , NULL ) ;
if ( tmpString & & AsciiStrCmp ( tmpString , " 1 " ) = = 0 ) {
gSettings . NvidiaWeb = TRUE ;
}
if ( tmpString ) {
FreePool ( tmpString ) ;
}
}
extern UINTN nLanCards ; // number of LAN cards
extern UINT16 gLanVendor [ 4 ] ; // their vendors
extern UINT8 * gLanMmio [ 4 ] ; // their MMIO regions
extern UINT8 gLanMac [ 4 ] [ 6 ] ; // their MAC addresses
extern UINTN nLanPaths ; // number of LAN pathes
2020-08-09 17:55:30 +02:00
BOOLEAN SetOEMPathIfExists ( IN EFI_FILE * Root , const XStringW & path , const XStringW & ConfName )
2020-02-15 15:51:18 +01:00
{
BOOLEAN res = FileExists ( Root , path ) ;
if ( res ) {
CHAR16 ConfigPath [ 1024 ] ;
2020-08-09 17:55:30 +02:00
snwprintf ( ConfigPath , sizeof ( ConfigPath ) , " %ls \\ %ls.plist " , path . wc_str ( ) , ConfName . wc_str ( ) ) ;
2020-02-15 15:51:18 +01:00
BOOLEAN res2 = FileExists ( Root , ConfigPath ) ;
if ( res2 ) {
2020-02-21 06:22:09 +01:00
OEMPath = path ;
2020-08-09 17:55:30 +02:00
DBG ( " CheckOEMPathExists: set OEMPath: %ls \n " , OEMPath . wc_str ( ) ) ;
2020-02-15 15:51:18 +01:00
return 1 ;
} else {
2020-08-09 17:55:30 +02:00
DBG ( " CheckOEMPathExists tried %ls. '%ls.plist' not exists in dir \n " , path . wc_str ( ) , ConfName . wc_str ( ) ) ;
2020-02-15 15:51:18 +01:00
}
} else {
2020-08-09 17:55:30 +02:00
DBG ( " CheckOEMPathExists tried %ls. Dir not exists \n " , path . wc_str ( ) ) ;
2020-02-15 15:51:18 +01:00
}
return 0 ;
}
2020-08-09 17:55:30 +02:00
VOID SetOEMPath ( const XStringW & ConfName )
2020-02-15 15:51:18 +01:00
{
2020-08-09 17:55:30 +02:00
OEMPath . takeValueFrom ( " EFI \\ CLOVER " ) ;
if ( ConfName . isEmpty ( ) ) {
DBG ( " set OEMPath (ConfName == NULL): %ls \n " , OEMPath . wc_str ( ) ) ;
2020-08-15 15:47:56 +02:00
} else if ( nLanCards > 0 & & SetOEMPathIfExists ( SelfRootDir , SWPrintf ( " EFI \\ CLOVER \\ OEM \\ %s--%02X-%02X-%02X-%02X-%02X-%02X " , gSettings . OEMProduct . c_str ( ) , gLanMac [ 0 ] [ 0 ] , gLanMac [ 0 ] [ 1 ] , gLanMac [ 0 ] [ 2 ] , gLanMac [ 0 ] [ 3 ] , gLanMac [ 0 ] [ 4 ] , gLanMac [ 0 ] [ 5 ] ) , ConfName ) ) {
} else if ( nLanCards > 1 & & SetOEMPathIfExists ( SelfRootDir , SWPrintf ( " EFI \\ CLOVER \\ OEM \\ %s--%02X-%02X-%02X-%02X-%02X-%02X " , gSettings . OEMProduct . c_str ( ) , gLanMac [ 1 ] [ 0 ] , gLanMac [ 1 ] [ 1 ] , gLanMac [ 1 ] [ 2 ] , gLanMac [ 1 ] [ 3 ] , gLanMac [ 1 ] [ 4 ] , gLanMac [ 1 ] [ 5 ] ) , ConfName ) ) {
} else if ( nLanCards > 2 & & SetOEMPathIfExists ( SelfRootDir , SWPrintf ( " EFI \\ CLOVER \\ OEM \\ %s--%02X-%02X-%02X-%02X-%02X-%02X " , gSettings . OEMProduct . c_str ( ) , gLanMac [ 2 ] [ 0 ] , gLanMac [ 2 ] [ 1 ] , gLanMac [ 2 ] [ 2 ] , gLanMac [ 2 ] [ 3 ] , gLanMac [ 2 ] [ 4 ] , gLanMac [ 2 ] [ 5 ] ) , ConfName ) ) {
} else if ( nLanCards > 3 & & SetOEMPathIfExists ( SelfRootDir , SWPrintf ( " EFI \\ CLOVER \\ OEM \\ %s--%02X-%02X-%02X-%02X-%02X-%02X " , gSettings . OEMProduct . c_str ( ) , gLanMac [ 3 ] [ 0 ] , gLanMac [ 3 ] [ 1 ] , gLanMac [ 3 ] [ 2 ] , gLanMac [ 3 ] [ 3 ] , gLanMac [ 3 ] [ 4 ] , gLanMac [ 3 ] [ 5 ] ) , ConfName ) ) {
} else if ( ! gFirmwareClover & & SetOEMPathIfExists ( SelfRootDir , SWPrintf ( " EFI \\ CLOVER \\ OEM \\ %s \\ UEFI " , gSettings . OEMBoard . c_str ( ) ) , ConfName ) ) {
} else if ( SetOEMPathIfExists ( SelfRootDir , SWPrintf ( " EFI \\ CLOVER \\ OEM \\ %s " , gSettings . OEMProduct . c_str ( ) ) , ConfName ) ) {
} else if ( SetOEMPathIfExists ( SelfRootDir , SWPrintf ( " EFI \\ CLOVER \\ OEM \\ %s-%d " , gSettings . OEMProduct . c_str ( ) , ( INT32 ) ( DivU64x32 ( gCPUStructure . CPUFrequency , Mega ) ) ) , ConfName ) ) {
} else if ( SetOEMPathIfExists ( SelfRootDir , SWPrintf ( " EFI \\ CLOVER \\ OEM \\ %s " , gSettings . OEMBoard . c_str ( ) ) , ConfName ) ) {
} else if ( SetOEMPathIfExists ( SelfRootDir , SWPrintf ( " EFI \\ CLOVER \\ OEM \\ %s-%d " , gSettings . OEMBoard . c_str ( ) , ( INT32 ) ( DivU64x32 ( gCPUStructure . CPUFrequency , Mega ) ) ) , ConfName ) ) {
2020-02-15 15:51:18 +01:00
} else {
2020-08-09 17:55:30 +02:00
DBG ( " set OEMPath by default: %ls \n " , OEMPath . wc_str ( ) ) ;
2020-02-15 15:51:18 +01:00
}
}
2020-02-18 19:49:54 +01:00
# ifdef DEBUG_CLOVER
2020-02-15 15:51:18 +01:00
XStringW g_str ( L " g_str:foobar " ) ;
XStringW g_str2 ( L " g_str:foobar2 " ) ;
//XStringW g_str3(L"g_str:foobar2");
//XStringW g_str4(L"g_str:foobar2");
//XStringW g_str5(L"g_str:foobar2");
//XStringW g_str6(L"g_str:foobar2");
//XStringW g_str7(L"g_str:foobar2");
//XStringW g_str8(L"g_str:foobar2");
//XStringW g_str9(L"g_str:foobar2");
//XStringW g_str10(L"g_str:foobar2");
//XStringW g_str11(L"g_str:foobar2");
//XStringW g_str12(L"g_str:foobar2");
2020-02-18 19:49:54 +01:00
# endif
2020-02-15 15:51:18 +01:00
//
// main entry point
//
EFI_STATUS
EFIAPI
RefitMain ( IN EFI_HANDLE ImageHandle ,
IN EFI_SYSTEM_TABLE * SystemTable )
{
EFI_STATUS Status ;
BOOLEAN MainLoopRunning = TRUE ;
BOOLEAN ReinitDesktop = TRUE ;
BOOLEAN AfterTool = FALSE ;
2020-02-28 21:28:33 +01:00
REFIT_ABSTRACT_MENU_ENTRY * ChosenEntry = NULL ;
REFIT_ABSTRACT_MENU_ENTRY * DefaultEntry = NULL ;
REFIT_ABSTRACT_MENU_ENTRY * OptionEntry = NULL ;
2020-02-15 15:51:18 +01:00
INTN DefaultIndex ;
UINTN MenuExit ;
2020-08-15 15:47:56 +02:00
UINTN i ;
2020-02-15 15:51:18 +01:00
//UINT64 TscDiv;
//UINT64 TscRemainder = 0;
2020-02-28 21:28:33 +01:00
// LOADER_ENTRY *LoaderEntry;
2020-08-09 17:55:30 +02:00
XStringW ConfName ;
2020-08-25 17:35:19 +02:00
TagDict * smbiosTags = NULL ;
2020-02-15 15:51:18 +01:00
BOOLEAN UniteConfigs = FALSE ;
EFI_TIME Now ;
BOOLEAN HaveDefaultVolume ;
2020-04-01 14:57:32 +02:00
REFIT_MENU_SCREEN BootScreen ;
BootScreen . isBootScreen = true ; //other screens will be constructed as false
2020-02-15 15:51:18 +01:00
// CHAR16 *InputBuffer; //, *Y;
// EFI_INPUT_KEY Key;
// Init assets dir: misc
/*Status = */ //egMkDir(SelfRootDir, L"EFI\\CLOVER\\misc");
//Should apply to: "ACPI/origin/" too
// get TSC freq and init MemLog if needed
gCPUStructure . TSCCalibr = GetMemLogTscTicksPerSecond ( ) ; //ticks for 1second
//GlobalConfig.TextOnly = TRUE;
// bootstrap
gST = SystemTable ;
gImageHandle = ImageHandle ;
gBS = SystemTable - > BootServices ;
2020-02-16 13:00:20 +01:00
gRT = SystemTable - > RuntimeServices ;
2020-02-15 15:51:18 +01:00
/*Status = */ EfiGetSystemConfigurationTable ( & gEfiDxeServicesTableGuid , ( VOID * * ) & gDS ) ;
ConsoleInHandle = SystemTable - > ConsoleInHandle ;
2020-09-07 16:44:24 +02:00
# ifdef DEBUG_ON_SERIAL_PORT
SerialPortInitialize ( ) ;
# endif
2020-08-09 17:55:30 +02:00
{
EFI_LOADED_IMAGE * LoadedImage ;
Status = gBS - > HandleProtocol ( gImageHandle , & gEfiLoadedImageProtocolGuid , ( VOID * * ) & LoadedImage ) ;
2020-08-26 20:49:49 +02:00
// if ( !EFI_ERROR(Status) ) {
// XString8 msg = S8Printf("Clover : Image base = 0x%llX\n", (uintptr_t)LoadedImage->ImageBase); // do not change, it's used by grep to feed the debugger
// SerialPortWrite((UINT8*)msg.c_str(), msg.length());
// }
2020-08-09 17:55:30 +02:00
if ( ! EFI_ERROR ( Status ) ) DBG ( " Clover : Image base = 0x%llX \n " , ( uintptr_t ) LoadedImage - > ImageBase ) ; // do not change, it's used by grep to feed the debugger
# ifdef JIEF_DEBUG
2020-09-07 13:13:44 +02:00
gBS - > Stall ( 3500000 ) ; // to give time to gdb to connect
2020-08-30 21:53:40 +02:00
// gBS->Stall(0500000); // to give time to gdb to connect
2020-08-09 17:55:30 +02:00
// PauseForKey(L"press\n");
# endif
}
2020-09-07 00:19:48 +02:00
2020-08-09 17:55:30 +02:00
construct_globals_objects ( gImageHandle ) ; // do this after SelfLoadedImage is initialized
2020-09-07 00:19:48 +02:00
2020-09-07 16:44:24 +02:00
// UINT64 CPUFrequencyFromART;
// InternalCalculateARTFrequencyIntel(&CPUFrequencyFromART, NULL, 1);
//
2020-09-07 13:13:44 +02:00
// EFI_LOADED_IMAGE* OcLoadedImage;
// Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &OcLoadedImage);
// EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileSystem = LocateFileSystem(OcLoadedImage->DeviceHandle, OcLoadedImage->FilePath);
// Status = OcStorageInitFromFs(&mOpenCoreStorage, FileSystem, L"EFI\\CLOVER", NULL);
//
// OcConfigureLogProtocol (
2020-09-07 16:44:24 +02:00
// 9,
2020-09-07 13:13:44 +02:00
// 0,
// 2151678018,
// 2147483648,
// OPEN_CORE_LOG_PREFIX_PATH,
// mOpenCoreStorage.FileSystem
// );
// DEBUG ((DEBUG_INFO, "OC: Log initialized...\n"));
// OcAppleDebugLogInstallProtocol(0);
2020-09-07 00:19:48 +02:00
2020-08-27 20:47:56 +02:00
# ifdef JIEF_DEBUG
// all_tests();
// PauseForKey(L"press\n");
# endif
2020-08-09 17:55:30 +02:00
2020-02-16 13:00:20 +01:00
gRT - > GetTime ( & Now , NULL ) ;
2020-02-15 15:51:18 +01:00
// firmware detection
gFirmwareClover = StrCmp ( gST - > FirmwareVendor , L " CLOVER " ) = = 0 ;
if ( ! gFirmwareRevision ) {
2020-08-09 17:55:30 +02:00
// gFirmwareRevision = P__oolPrint(L"%d", gST->FirmwareRevision);
2020-02-15 15:51:18 +01:00
}
InitializeConsoleSim ( ) ;
InitBooterLog ( ) ;
ZeroMem ( ( VOID * ) & gGraphics [ 0 ] , sizeof ( GFX_PROPERTIES ) * 4 ) ;
ZeroMem ( ( VOID * ) & gAudios [ 0 ] , sizeof ( HDA_PROPERTIES ) * 4 ) ;
DBG ( " \n " ) ;
if ( Now . TimeZone < - 1440 | | Now . TimeZone > 1440 ) {
MsgLog ( " Now is %02d.%02d.%d, %02d:%02d:%02d (GMT) \n " ,
Now . Day , Now . Month , Now . Year , Now . Hour , Now . Minute , Now . Second ) ;
} else {
MsgLog ( " Now is %02d.%02d.%d, %02d:%02d:%02d (GMT+%d) \n " ,
Now . Day , Now . Month , Now . Year , Now . Hour , Now . Minute , Now . Second , GlobalConfig . Timezone ) ;
}
2020-04-16 14:24:21 +02:00
//MsgLog("Starting Clover rev %ls on %ls EFI\n", gFirmwareRevision, gST->FirmwareVendor);
2020-04-16 13:19:37 +02:00
MsgLog ( " Starting %s on %ls EFI \n " , gRevisionStr , gST - > FirmwareVendor ) ;
2020-02-15 15:51:18 +01:00
2020-04-16 14:24:21 +02:00
if ( gBuildInfo ) DBG ( " Build with: [%s] \n " , gBuildInfo ) ;
2020-02-15 15:51:18 +01:00
Status = InitRefitLib ( gImageHandle ) ;
if ( EFI_ERROR ( Status ) )
return Status ;
//dumping SETTING structure
// if you change something in Platform.h, please uncomment and test that all offsets
// are natural aligned i.e. pointers are 8 bytes aligned
/*
DBG ( " Settings offsets: \n " ) ;
2020-03-25 19:32:44 +01:00
DBG ( " OEMProduct: %X \n " , OFFSET_OF ( SETTINGS_DATA , OEMProduct ) ) ;
DBG ( " DefaultVolume: %X \n " , OFFSET_OF ( SETTINGS_DATA , DefaultVolume ) ) ;
DBG ( " DefaultLoader: %X \n " , OFFSET_OF ( SETTINGS_DATA , DefaultLoader ) ) ;
DBG ( " ResetAddr: %X \n " , OFFSET_OF ( SETTINGS_DATA , ResetAddr ) ) ;
DBG ( " FixDsdt: %X \n " , OFFSET_OF ( SETTINGS_DATA , FixDsdt ) ) ;
DBG ( " FakeATI: %X \n " , OFFSET_OF ( SETTINGS_DATA , FakeATI ) ) ;
DBG ( " PatchVBiosBytes:%X \n " , OFFSET_OF ( SETTINGS_DATA , PatchVBiosBytes ) ) ;
DBG ( " VRAM: %X \n " , OFFSET_OF ( SETTINGS_DATA , VRAM ) ) ;
DBG ( " SecureBootWhiteListCount: %X \n " , OFFSET_OF ( SETTINGS_DATA , SecureBootWhiteListCount ) ) ;
DBG ( " LegacyBoot: %X \n " , OFFSET_OF ( SETTINGS_DATA , LegacyBoot ) ) ;
DBG ( " HVHideStrings: %X \n " , OFFSET_OF ( SETTINGS_DATA , HVHideStrings ) ) ;
DBG ( " PointerSpeed: %X \n " , OFFSET_OF ( SETTINGS_DATA , PointerSpeed ) ) ;
DBG ( " RtMLB: %X \n " , OFFSET_OF ( SETTINGS_DATA , RtMLB ) ) ;
DBG ( " ConfigName: %X \n " , OFFSET_OF ( SETTINGS_DATA , ConfigName ) ) ;
DBG ( " PointerSpeed: %X \n " , OFFSET_OF ( SETTINGS_DATA , PointerSpeed ) ) ;
DBG ( " PatchDsdtNum: %X \n " , OFFSET_OF ( SETTINGS_DATA , PatchDsdtNum ) ) ;
DBG ( " LenToReplace: %X \n " , OFFSET_OF ( SETTINGS_DATA , LenToReplace ) ) ;
DBG ( " ACPIDropTables: %X \n " , OFFSET_OF ( SETTINGS_DATA , ACPIDropTables ) ) ;
DBG ( " CustomEntries: %X \n " , OFFSET_OF ( SETTINGS_DATA , CustomEntries ) ) ;
DBG ( " CustomTool: %X \n " , OFFSET_OF ( SETTINGS_DATA , CustomTool ) ) ;
DBG ( " AddProperties: %X \n " , OFFSET_OF ( SETTINGS_DATA , AddProperties ) ) ;
DBG ( " BlockKexts: %X \n " , OFFSET_OF ( SETTINGS_DATA , BlockKexts ) ) ;
2020-02-15 15:51:18 +01:00
*/
// disable EFI watchdog timer
gBS - > SetWatchdogTimer ( 0x0000 , 0x0000 , 0x0000 , NULL ) ;
2020-08-11 14:43:53 +02:00
// ZeroMem((VOID*)&gSettings, sizeof(SETTINGS_DATA));
2020-02-15 15:51:18 +01:00
Status = InitializeUnicodeCollationProtocol ( ) ;
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " UnicodeCollation Status=%s \n " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
Status = gBS - > HandleProtocol ( ConsoleInHandle , & gEfiSimpleTextInputExProtocolGuid , ( VOID * * ) & SimpleTextEx ) ;
2020-04-23 11:08:10 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-02-15 15:51:18 +01:00
SimpleTextEx = NULL ;
}
2020-08-25 17:35:19 +02:00
DBG ( " SimpleTextEx Status=%s \n " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
PrepatchSmbios ( ) ;
//replace / with _
2020-08-15 15:47:56 +02:00
gSettings . OEMProduct . replaceAll ( U ' / ' , U ' _ ' ) ;
gSettings . OEMBoard . replaceAll ( U ' / ' , U ' _ ' ) ;
DBG ( " Running on: '%s' with board '%s' \n " , gSettings . OEMProduct . c_str ( ) , gSettings . OEMBoard . c_str ( ) ) ;
2020-02-15 15:51:18 +01:00
GetCPUProperties ( ) ;
GetDevices ( ) ;
GetDefaultSettings ( ) ;
// LoadOptions Parsing
DBG ( " Clover load options size = %d bytes \n " , SelfLoadedImage - > LoadOptionsSize ) ;
if ( ( SelfLoadedImage - > LoadOptions ! = NULL ) & &
( SelfLoadedImage - > LoadOptionsSize ! = 0 ) ) {
if ( * ( UINT32 * ) SelfLoadedImage - > LoadOptions = = CLOVER_SIGN ) {
GetBootFromOption ( ) ;
} else {
ParseLoadOptions ( & ConfName , & gConfigDict [ 1 ] ) ;
2020-08-19 21:29:26 +02:00
if ( ConfName . isEmpty ( ) ) {
gConfigDict [ 1 ] = NULL ;
} else {
SetOEMPath ( ConfName ) ;
Status = LoadUserSettings ( SelfRootDir , ConfName , & gConfigDict [ 1 ] ) ;
DBG ( " %ls \\ %ls.plist%ls loaded with name from LoadOptions: %s \n " ,
2020-08-25 17:35:19 +02:00
OEMPath . wc_str ( ) , ConfName . wc_str ( ) , EFI_ERROR ( Status ) ? L " not " : L " " , efiStrError ( Status ) ) ;
2020-08-19 21:29:26 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-02-15 15:51:18 +01:00
gConfigDict [ 1 ] = NULL ;
}
2020-08-19 21:29:26 +02:00
}
2020-02-15 15:51:18 +01:00
}
}
if ( gConfigDict [ 1 ] ) {
2020-08-25 17:35:19 +02:00
const TagStruct * UniteTag = gConfigDict [ 1 ] - > propertyForKey ( " Unite " ) ;
2020-02-15 15:51:18 +01:00
if ( UniteTag ) {
2020-08-18 18:45:44 +02:00
UniteConfigs = UniteTag - > isTrueOrYy ( ) ;
2020-03-25 19:32:44 +01:00
DBG ( " UniteConfigs = %ls " , UniteConfigs ? L " TRUE \n " : L " FALSE \n " ) ;
2020-02-15 15:51:18 +01:00
}
}
if ( ! gConfigDict [ 1 ] | | UniteConfigs ) {
2020-08-09 17:55:30 +02:00
SetOEMPath ( L " config " _XSW ) ;
Status = LoadUserSettings ( SelfRootDir , L " config " _XSW , & gConfigDict [ 0 ] ) ;
2020-08-25 17:35:19 +02:00
DBG ( " %ls \\ config.plist%ls loaded: %s \n " , OEMPath . wc_str ( ) , EFI_ERROR ( Status ) ? L " not " : L " " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
2020-04-04 15:50:13 +02:00
snwprintf ( gSettings . ConfigName , 64 , " %ls%ls%ls " ,
2020-02-15 15:51:18 +01:00
gConfigDict [ 0 ] ? L " config " : L " " ,
( gConfigDict [ 0 ] & & gConfigDict [ 1 ] ) ? L " + " : L " " ,
2020-08-09 17:55:30 +02:00
! gConfigDict [ 1 ] ? L " " : ( ConfName . notEmpty ( ) ? ConfName . wc_str ( ) : L " Load Options " ) ) ;
2020-08-13 14:57:05 +02:00
//gSettings.MainConfigName.takeValueFrom(gSettings.ConfigName);
2020-02-15 15:51:18 +01:00
gSettings . PointerEnabled = TRUE ;
gSettings . PointerSpeed = 2 ;
gSettings . DoubleClickTime = 500 ; //TODO - make it constant as nobody change it
# ifdef ENABLE_SECURE_BOOT
InitializeSecureBoot ( ) ;
# endif // ENABLE_SECURE_BOOT
{
// UINT32 machineSignature = 0;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * FadtPointer = NULL ;
EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * Facs = NULL ;
// DBG("---dump hibernations data---\n");
FadtPointer = GetFadt ( ) ;
if ( FadtPointer ! = NULL ) {
Facs = ( EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * ) ( UINTN ) ( FadtPointer - > FirmwareCtrl ) ;
/*
DBG ( " Firmware wake address=%08lx \n " , Facs - > FirmwareWakingVector ) ;
DBG ( " Firmware wake 64 addr=%16llx \n " , Facs - > XFirmwareWakingVector ) ;
DBG ( " Hardware signature =%08lx \n " , Facs - > HardwareSignature ) ;
DBG ( " GlobalLock =%08lx \n " , Facs - > GlobalLock ) ;
DBG ( " Flags =%08lx \n " , Facs - > Flags ) ;
*/
machineSignature = Facs - > HardwareSignature ;
}
# if HIBERNATE_DUMP_DATA
//------------------------------------------------------
DumpVariable ( L " Boot0082 " , & gEfiGlobalVariableGuid , 8 ) ;
DumpVariable ( L " boot-switch-vars " , & gEfiAppleBootGuid , - 1 ) ;
DumpVariable ( L " boot-signature " , & gEfiAppleBootGuid , - 1 ) ;
DumpVariable ( L " boot-image-key " , & gEfiAppleBootGuid , - 1 ) ;
DumpVariable ( L " boot-image " , & gEfiAppleBootGuid , 0 ) ;
//-----------------------------------------------------------
# endif //
}
#if 0
//testing place
{
2020-05-13 12:04:48 +02:00
const CHAR16 aaa [ ] = L " 12345 " ;
2020-04-13 10:43:18 +02:00
const CHAR8 * bbb = " 12345 " ;
DBG ( " string %ls, size=%lld, len=%lld sizeof=%ld iStrLen=%lld \n " , aaa , StrSize ( aaa ) , StrLen ( aaa ) , sizeof ( aaa ) , iStrLen ( bbb , 10 ) ) ;
2020-04-25 05:37:56 +02:00
const CHAR8 * ccc = " Выход " ;
DBG ( " string %s, size=%lld, len=%lld sizeof=%ld iStrLen=%lld \n " , ccc , AsciiStrSize ( ccc ) , AsciiStrLen ( ccc ) , sizeof ( ccc ) , iStrLen ( ccc , 10 ) ) ;
2020-04-30 08:22:26 +02:00
XString8 ddd = " Выход " _XS8 ;
2020-04-24 18:24:34 +02:00
// size_t sizex = ddd.allocatedSize();
2020-04-25 05:37:56 +02:00
DBG ( " xstring %s, asize=%ld, sizeinbyte=%ld sizeof=%ld lastcharat=%ld \n " , ddd . c_str ( ) , ddd . allocatedSize ( ) , ddd . sizeInBytes ( ) , sizeof ( ddd ) ,
2020-04-25 12:07:23 +02:00
ddd . indexOf ( ddd . lastChar ( ) ) ) ;
2020-04-13 10:43:18 +02:00
CHAR8 compatible [ 64 ] ;
UINT32 FakeLAN = 0x0030168c ;
UINT32 FakeID = FakeLAN > > 16 ;
2020-04-14 06:34:10 +02:00
UINT32 FakeVendor = FakeLAN & 0xFFFF ;
snprintf ( compatible , 64 , " pci%x,%x " , FakeVendor , FakeID ) ;
2020-04-13 10:43:18 +02:00
DBG ( " FakeLAN = 0x%x \n " , FakeLAN ) ;
DBG ( " Compatible=%s strlen=%ld sizeof=%ld iStrLen=%lld \n " , compatible ,
strlen ( compatible ) , sizeof ( compatible ) , iStrLen ( compatible , 64 ) ) ;
// LowCase(compatible);
// DBG(" Low Compatible=%s strlen=%ld sizeof=%ld iStrLen=%lld\n", compatible,
// strlen(compatible), sizeof(compatible), iStrLen(compatible, 64));
2020-04-19 20:48:00 +02:00
DBG ( " void*=%ld int=%ld long=%ld longlong=%ld enum=%ld \n " ,
sizeof ( void * ) , sizeof ( int ) , sizeof ( long int ) , sizeof ( long long ) , sizeof ( EFI_ALLOCATE_TYPE ) ) ;
2020-05-13 12:04:48 +02:00
/*
Results
41 : 381 0 : 000 string 12345 , size = 16 , len = 7 sizeof = 16 iStrLen = 5
41 : 381 0 : 000 string В ы х о д , size = 13 , len = 12 sizeof = 8 iStrLen = 10
41 : 381 0 : 000 xstring В ы х о д , asize = 0 , sizeinbyte = 11 sizeof = 16 lastcharat = 5
41 : 381 0 : 000 FakeLAN = 0x30168c
41 : 381 0 : 000 Compatible = pci168c , 30 strlen = 10 sizeof = 64 iStrLen = 10
*/
2020-02-15 15:51:18 +01:00
}
# endif
if ( ! GlobalConfig . FastBoot ) {
GetListOfThemes ( ) ;
GetListOfConfigs ( ) ;
}
2020-04-16 13:04:24 +02:00
// ThemeX.FillByEmbedded(); //init XTheme before EarlyUserSettings
2020-03-31 14:35:04 +02:00
2020-02-15 15:51:18 +01:00
for ( i = 0 ; i < 2 ; i + + ) {
if ( gConfigDict [ i ] ) {
2020-03-31 14:35:04 +02:00
GetEarlyUserSettings ( SelfRootDir , gConfigDict [ i ] ) ;
2020-02-15 15:51:18 +01:00
}
}
# ifdef ENABLE_SECURE_BOOT
// Install secure boot shim
if ( EFI_ERROR ( Status = InstallSecureBoot ( ) ) ) {
PauseForKey ( L " Secure boot failure! \n " ) ;
return Status ;
}
# endif // ENABLE_SECURE_BOOT
MainMenu . TimeoutSeconds = GlobalConfig . Timeout > = 0 ? GlobalConfig . Timeout : 0 ;
//DBG("LoadDrivers() start\n");
LoadDrivers ( ) ;
//DBG("LoadDrivers() end\n");
/* if (!gFirmwareClover &&
! gDriversFlags . EmuVariableLoaded ) {
GetSmcKeys ( FALSE ) ; // later we can get here SMC information
} */
Status = gBS - > LocateProtocol ( & gEmuVariableControlProtocolGuid , NULL , ( VOID * * ) & gEmuVariableControl ) ;
if ( EFI_ERROR ( Status ) ) {
gEmuVariableControl = NULL ;
}
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > InstallEmulation ( gEmuVariableControl ) ;
}
DbgHeader ( " InitScreen " ) ;
if ( ! GlobalConfig . FastBoot ) {
// init screen and dump video modes to log
if ( gDriversFlags . VideoLoaded ) {
InitScreen ( FALSE ) ;
} else {
InitScreen ( ! gFirmwareClover ) ; // ? FALSE : TRUE);
}
//DBG("DBG: setup screen\n");
SetupScreen ( ) ;
} else {
InitScreen ( FALSE ) ;
}
// DBG("DBG: ReinitSelfLib\n");
//Now we have to reinit handles
Status = ReinitSelfLib ( ) ;
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DebugLog ( 2 , " %s " , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
PauseForKey ( L " Error reinit refit \n " ) ;
# ifdef ENABLE_SECURE_BOOT
UninstallSecureBoot ( ) ;
# endif // ENABLE_SECURE_BOOT
return Status ;
}
// DBG("DBG: messages\n");
if ( ! GlobalConfig . NoEarlyProgress & & ! GlobalConfig . FastBoot & & GlobalConfig . Timeout > 0 ) {
2020-03-31 17:59:35 +02:00
XStringW Message = SWPrintf ( " Welcome to Clover %ls " , gFirmwareRevision ) ;
2020-04-01 14:57:32 +02:00
BootScreen . DrawTextXY ( Message , ( UGAWidth > > 1 ) , UGAHeight > > 1 , X_IS_CENTER ) ;
BootScreen . DrawTextXY ( L " ... testing hardware ... " _XSW , ( UGAWidth > > 1 ) , ( UGAHeight > > 1 ) + 20 , X_IS_CENTER ) ;
2020-02-15 15:51:18 +01:00
}
// DumpBiosMemoryMap();
GuiEventsInitialize ( ) ;
if ( ! gSettings . EnabledCores ) {
gSettings . EnabledCores = gCPUStructure . Cores ;
}
GetMacAddress ( ) ;
//DBG("ScanSPD() start\n");
ScanSPD ( ) ;
//DBG("ScanSPD() end\n");
SetPrivateVarProto ( ) ;
// GetDefaultSettings();
GetAcpiTablesList ( ) ;
2020-03-25 19:32:44 +01:00
DBG ( " Calibrated TSC Frequency = %llu = %lluMHz \n " , gCPUStructure . TSCCalibr , DivU64x32 ( gCPUStructure . TSCCalibr , Mega ) ) ;
2020-02-15 15:51:18 +01:00
if ( gCPUStructure . TSCCalibr > 200000000ULL ) { //200MHz
gCPUStructure . TSCFrequency = gCPUStructure . TSCCalibr ;
}
gCPUStructure . CPUFrequency = gCPUStructure . TSCFrequency ;
gCPUStructure . FSBFrequency = DivU64x32 ( MultU64x32 ( gCPUStructure . CPUFrequency , 10 ) ,
( gCPUStructure . MaxRatio = = 0 ) ? 1 : gCPUStructure . MaxRatio ) ;
gCPUStructure . MaxSpeed = ( UINT32 ) DivU64x32 ( gCPUStructure . TSCFrequency + ( Mega > > 1 ) , Mega ) ;
switch ( gCPUStructure . Model ) {
case CPU_MODEL_PENTIUM_M :
case CPU_MODEL_ATOM : // Atom
case CPU_MODEL_DOTHAN : // Pentium M, Dothan, 90nm
case CPU_MODEL_YONAH : // Core Duo/Solo, Pentium M DC
case CPU_MODEL_MEROM : // Core Xeon, Core 2 Duo, 65nm, Mobile
//case CPU_MODEL_CONROE:// Core Xeon, Core 2 Duo, 65nm, Desktop like Merom but not mobile
case CPU_MODEL_CELERON :
case CPU_MODEL_PENRYN : // Core 2 Duo/Extreme, Xeon, 45nm , Mobile
case CPU_MODEL_NEHALEM : // Core i7 LGA1366, Xeon 5500, "Bloomfield", "Gainstown", 45nm
case CPU_MODEL_FIELDS : // Core i7, i5 LGA1156, "Clarksfield", "Lynnfield", "Jasper", 45nm
case CPU_MODEL_DALES : // Core i7, i5, Nehalem
case CPU_MODEL_CLARKDALE : // Core i7, i5, i3 LGA1156, "Westmere", "Clarkdale", , 32nm
case CPU_MODEL_WESTMERE : // Core i7 LGA1366, Six-core, "Westmere", "Gulftown", 32nm
case CPU_MODEL_NEHALEM_EX : // Core i7, Nehalem-Ex Xeon, "Beckton"
case CPU_MODEL_WESTMERE_EX : // Core i7, Nehalem-Ex Xeon, "Eagleton"
gCPUStructure . ExternalClock = ( UINT32 ) DivU64x32 ( gCPUStructure . FSBFrequency + kilo - 1 , kilo ) ;
//DBG(" Read TSC ExternalClock: %d MHz\n", (INT32)(DivU64x32(gCPUStructure.ExternalClock, kilo)));
break ;
default :
//DBG(" Read TSC ExternalClock: %d MHz\n", (INT32)(DivU64x32(gCPUStructure.FSBFrequency, Mega)));
// for sandy bridge or newer
// to match ExternalClock 25 MHz like real mac, divide FSBFrequency by 4
gCPUStructure . ExternalClock = ( ( UINT32 ) DivU64x32 ( gCPUStructure . FSBFrequency + kilo - 1 , kilo ) + 3 ) / 4 ;
//DBG(" Corrected TSC ExternalClock: %d MHz\n", (INT32)(DivU64x32(gCPUStructure.ExternalClock, kilo)));
break ;
}
if ( ! GlobalConfig . NoEarlyProgress & & ! GlobalConfig . FastBoot & & GlobalConfig . Timeout > 0 ) {
2020-03-31 17:59:35 +02:00
XStringW Message = SWPrintf ( " ... user settings ... " ) ;
2020-04-01 14:57:32 +02:00
BootScreen . EraseTextXY ( ) ;
BootScreen . DrawTextXY ( Message , ( UGAWidth > > 1 ) , ( UGAHeight > > 1 ) + 20 , X_IS_CENTER ) ;
2020-02-15 15:51:18 +01:00
}
//Second step. Load config.plist into gSettings
for ( i = 0 ; i < 2 ; i + + ) {
if ( gConfigDict [ i ] ) {
2020-08-25 17:35:19 +02:00
Status = GetUserSettings ( gConfigDict [ i ] ) ;
2020-02-15 15:51:18 +01:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " Error in Second part of settings %llu: %s \n " , i , efiStrError ( Status ) ) ;
2020-02-15 15:51:18 +01:00
}
}
}
if ( gSettings . QEMU ) {
// UINT64 Msrflex = 0ULL;
if ( ! gSettings . UserChange ) {
gSettings . BusSpeed = 200000 ;
}
gCPUStructure . MaxRatio = ( UINT32 ) DivU64x32 ( gCPUStructure . TSCCalibr , gSettings . BusSpeed * kilo ) ;
DBG ( " Set MaxRatio for QEMU: %d \n " , gCPUStructure . MaxRatio ) ;
gCPUStructure . MaxRatio * = 10 ;
gCPUStructure . MinRatio = 60 ;
/* AsmWriteMsr64(MSR_FLEX_RATIO, ((6ULL << 40) + //(1ULL << 16) +
( gCPUStructure . MaxRatio < < 8 ) ) ) ;
DBG ( " check if flex is RW \n " ) ;
Msrflex = AsmReadMsr64 ( MSR_FLEX_RATIO ) ; //0 == not Rw :(
DBG ( " MSR_FLEX_RATIO = %lx \n " , Msrflex ) ;
*/
gCPUStructure . FSBFrequency = DivU64x32 ( MultU64x32 ( gCPUStructure . CPUFrequency , 10 ) ,
( gCPUStructure . MaxRatio = = 0 ) ? 1 : gCPUStructure . MaxRatio ) ;
gCPUStructure . ExternalClock = ( UINT32 ) DivU64x32 ( gCPUStructure . FSBFrequency + kilo - 1 , kilo ) ;
}
2020-05-09 11:15:03 +02:00
// dropDSM = 0xFFFF; //by default we drop all OEM _DSM. They have no sense for us.
// if (defDSM) {
// dropDSM = gSettings.DropOEM_DSM; //if set by user
// }
2020-02-15 15:51:18 +01:00
// Load any extra SMBIOS information
2020-08-09 17:55:30 +02:00
if ( ! EFI_ERROR ( LoadUserSettings ( SelfRootDir , L " smbios " _XSW , & smbiosTags ) ) & & ( smbiosTags ! = NULL ) ) {
2020-08-25 17:35:19 +02:00
const TagDict * dictPointer = smbiosTags - > dictPropertyForKey ( " SMBIOS " ) ;
2020-02-15 15:51:18 +01:00
if ( dictPointer ) {
ParseSMBIOSSettings ( dictPointer ) ;
} else {
DBG ( " Invalid smbios.plist, not overriding config.plist! \n " ) ;
}
}
/*
if ( gFirmwareClover | | gDriversFlags . EmuVariableLoaded ) {
if ( GlobalConfig . StrictHibernate ) {
DBG ( " Don't use StrictHibernate with emulated NVRAM! \n " ) ;
}
GlobalConfig . StrictHibernate = FALSE ;
}
*/
2020-08-15 15:47:56 +02:00
HaveDefaultVolume = gSettings . DefaultVolume . notEmpty ( ) ;
2020-02-15 15:51:18 +01:00
if ( ! gFirmwareClover & &
! gDriversFlags . EmuVariableLoaded & &
! HaveDefaultVolume & &
GlobalConfig . Timeout = = 0 & & ! ReadAllKeyStrokes ( ) ) {
// UEFI boot: get gEfiBootDeviceGuid from NVRAM.
// if present, ScanVolumes() will skip scanning other volumes
// in the first run.
// this speeds up loading of default macOS volume.
GetEfiBootDeviceFromNvram ( ) ;
}
if ( ! GlobalConfig . NoEarlyProgress & & ! GlobalConfig . FastBoot & & GlobalConfig . Timeout > 0 ) {
2020-03-31 17:59:35 +02:00
XStringW Message = SWPrintf ( " ... scan entries ... " ) ;
2020-04-01 14:57:32 +02:00
BootScreen . EraseTextXY ( ) ;
BootScreen . DrawTextXY ( Message , ( UGAWidth > > 1 ) , ( UGAHeight > > 1 ) + 20 , X_IS_CENTER ) ;
2020-02-15 15:51:18 +01:00
}
AfterTool = FALSE ;
gGuiIsReady = TRUE ;
2020-05-01 02:14:11 +02:00
gBootChanged = TRUE ;
gThemeChanged = TRUE ;
2020-02-15 15:51:18 +01:00
do {
2020-05-01 02:14:11 +02:00
if ( gBootChanged & & gThemeChanged ) { // config changed
GetListOfDsdts ( ) ; //only after GetUserSettings
GetListOfACPI ( ) ; //ssdt and other tables
}
gBootChanged = FALSE ;
2020-08-12 17:15:47 +02:00
MainMenu . Entries . setEmpty ( ) ;
OptionMenu . Entries . setEmpty ( ) ;
2020-02-15 15:51:18 +01:00
InitKextList ( ) ;
ScanVolumes ( ) ;
// as soon as we have Volumes, find latest nvram.plist and copy it to RT vars
if ( ! AfterTool ) {
if ( gFirmwareClover | | gDriversFlags . EmuVariableLoaded ) {
PutNvramPlistToRtVars ( ) ;
}
}
2020-06-05 11:43:12 +02:00
// log Audio devices in boot-log. This is for clients like Clover.app
2020-02-15 15:51:18 +01:00
GetOutputs ( ) ;
2020-08-31 09:07:36 +02:00
for ( i = 0 ; i < AudioList . size ( ) ; i + + ) {
if ( AudioList [ i ] . Name . notEmpty ( ) ) {
2020-02-15 15:51:18 +01:00
// Never change this log, otherwise clients will stop interprete the output.
2020-08-31 09:07:36 +02:00
MsgLog ( " Found Audio Device %ls (%s) at index %llu \n " , AudioList [ i ] . Name . wc_str ( ) , AudioOutputNames [ AudioList [ i ] . Device ] , i ) ;
2020-02-15 15:51:18 +01:00
}
}
if ( ! GlobalConfig . FastBoot ) {
2020-04-05 14:25:39 +02:00
// CHAR16 *TmpArgs;
2020-02-15 15:51:18 +01:00
if ( gThemeNeedInit ) {
2020-05-18 22:10:38 +02:00
InitTheme ( TRUE ) ;
2020-02-15 15:51:18 +01:00
gThemeNeedInit = FALSE ;
} else if ( gThemeChanged ) {
DBG ( " change theme \n " ) ;
2020-05-18 22:10:38 +02:00
InitTheme ( FALSE ) ;
2020-05-04 20:05:47 +02:00
//OptionMenu.FreeMenu(); // it is already freed at loop beginning
2020-08-12 17:15:47 +02:00
AboutMenu . Entries . setEmpty ( ) ;
HelpMenu . Entries . setEmpty ( ) ;
2020-02-15 15:51:18 +01:00
}
DBG ( " theme inited \n " ) ;
2020-03-29 18:17:27 +02:00
if ( ThemeX . embedded ) {
DBG ( " Chosen embedded theme \n " ) ;
} else {
2020-08-15 15:47:56 +02:00
DBG ( " Chosen theme %ls \n " , ThemeX . Theme . wc_str ( ) ) ;
2020-03-29 18:17:27 +02:00
}
2020-03-25 19:32:44 +01:00
// DBG("initial boot-args=%s\n", gSettings.BootArgs);
2020-02-15 15:51:18 +01:00
//now it is a time to set RtVariables
SetVariablesFromNvram ( ) ;
2020-08-11 08:00:19 +02:00
XString8Array TmpArgs = Split < XString8Array > ( gSettings . BootArgs , " " ) ;
2020-08-15 15:47:56 +02:00
DBG ( " after NVRAM boot-args=%s \n " , gSettings . BootArgs . c_str ( ) ) ;
2020-02-15 15:51:18 +01:00
gSettings . OptionsBits = EncodeOptions ( TmpArgs ) ;
2020-03-25 19:32:44 +01:00
// DBG("initial OptionsBits %X\n", gSettings.OptionsBits);
2020-02-15 15:51:18 +01:00
FillInputs ( TRUE ) ;
// scan for loaders and tools, add then to the menu
if ( GlobalConfig . LegacyFirst ) {
AddCustomLegacy ( ) ;
if ( ! GlobalConfig . NoLegacy ) {
ScanLegacy ( ) ;
}
}
}
GetSmcKeys ( TRUE ) ;
// Add custom entries
AddCustomEntries ( ) ;
if ( gSettings . DisableEntryScan ) {
DBG ( " Entry scan disabled \n " ) ;
} else {
ScanLoader ( ) ;
}
if ( ! GlobalConfig . FastBoot ) {
if ( ! GlobalConfig . LegacyFirst ) {
AddCustomLegacy ( ) ;
if ( ! GlobalConfig . NoLegacy ) {
ScanLegacy ( ) ;
}
}
// fixed other menu entries
2020-03-27 17:50:17 +01:00
if ( ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_TOOLS ) ) {
2020-02-15 15:51:18 +01:00
AddCustomTool ( ) ;
if ( ! gSettings . DisableToolScan ) {
ScanTool ( ) ;
# ifdef ENABLE_SECURE_BOOT
// Check for secure boot setup mode
AddSecureBootTool ( ) ;
# endif // ENABLE_SECURE_BOOT
}
}
2020-03-27 17:50:17 +01:00
MenuEntryOptions . Image = ThemeX . GetIcon ( BUILTIN_ICON_FUNC_OPTIONS ) ;
2020-05-18 22:10:38 +02:00
// DBG("Options: IconID=%lld name=%s empty=%s\n", MenuEntryOptions.Image.Id, MenuEntryOptions.Image.Name.c_str(),
// MenuEntryOptions.Image.isEmpty()?"пусто":"нет");
2020-02-15 15:51:18 +01:00
if ( gSettings . DisableCloverHotkeys )
MenuEntryOptions . ShortcutLetter = 0x00 ;
2020-03-03 21:44:07 +01:00
MainMenu . AddMenuEntry ( & MenuEntryOptions , false ) ;
2020-05-16 21:30:29 +02:00
2020-03-29 18:17:27 +02:00
MenuEntryAbout . Image = ThemeX . GetIcon ( ( INTN ) BUILTIN_ICON_FUNC_ABOUT ) ;
2020-05-18 22:10:38 +02:00
// DBG("About: IconID=%lld name=%s empty=%s\n", MenuEntryAbout.Image.Id, MenuEntryAbout.Image.Name.c_str(),
// MenuEntryAbout.Image.isEmpty()?"пусто":"нет");
2020-02-15 15:51:18 +01:00
if ( gSettings . DisableCloverHotkeys )
MenuEntryAbout . ShortcutLetter = 0x00 ;
2020-03-03 21:44:07 +01:00
MainMenu . AddMenuEntry ( & MenuEntryAbout , false ) ;
2020-02-15 15:51:18 +01:00
2020-03-29 18:17:27 +02:00
if ( ! ( ThemeX . HideUIFlags & HIDEUI_FLAG_FUNCS ) | | MainMenu . Entries . size ( ) = = 0 ) {
if ( gSettings . DisableCloverHotkeys )
MenuEntryReset . ShortcutLetter = 0x00 ;
MenuEntryReset . Image = ThemeX . GetIcon ( BUILTIN_ICON_FUNC_RESET ) ;
MainMenu . AddMenuEntry ( & MenuEntryReset , false ) ;
if ( gSettings . DisableCloverHotkeys )
MenuEntryShutdown . ShortcutLetter = 0x00 ;
MenuEntryShutdown . Image = ThemeX . GetIcon ( BUILTIN_ICON_FUNC_EXIT ) ;
MainMenu . AddMenuEntry ( & MenuEntryShutdown , false ) ;
}
2020-02-15 15:51:18 +01:00
// font already changed and this message very quirky, clear line here
2020-04-15 18:30:39 +02:00
// if (!GlobalConfig.NoEarlyProgress && !GlobalConfig.FastBoot && GlobalConfig.Timeout>0) {
2020-04-01 14:57:32 +02:00
// XStringW Message = L" "_XSW;
2020-04-15 18:30:39 +02:00
// BootScreen.EraseTextXY();
2020-04-01 14:57:32 +02:00
// DrawTextXY(Message, (UGAWidth >> 1), (UGAHeight >> 1) + 20, X_IS_CENTER);
2020-04-15 18:30:39 +02:00
// }
2020-02-15 15:51:18 +01:00
}
// wait for user ACK when there were errors
FinishTextScreen ( FALSE ) ;
# if CHECK_SMC
DumpSmcKeys ( ) ;
# endif
DefaultIndex = FindDefaultEntry ( ) ;
2020-04-01 14:57:32 +02:00
// DBG("DefaultIndex=%lld and MainMenu.Entries.size()=%llu\n", DefaultIndex, MainMenu.Entries.size());
2020-02-28 21:28:33 +01:00
if ( ( DefaultIndex > = 0 ) & & ( DefaultIndex < ( INTN ) MainMenu . Entries . size ( ) ) ) {
DefaultEntry = & MainMenu . Entries [ DefaultIndex ] ;
2020-02-15 15:51:18 +01:00
} else {
DefaultEntry = NULL ;
}
MainLoopRunning = TRUE ;
// MainMenu.TimeoutSeconds = GlobalConfig.Timeout >= 0 ? GlobalConfig.Timeout : 0;
if ( DefaultEntry & & ( GlobalConfig . FastBoot | |
( gSettings . SkipHibernateTimeout & &
2020-02-28 21:28:33 +01:00
DefaultEntry - > getLOADER_ENTRY ( )
& & OSFLAG_ISSET ( DefaultEntry - > getLOADER_ENTRY ( ) - > Flags , OSFLAG_HIBERNATED )
)
2020-04-15 18:30:39 +02:00
)
2020-02-28 21:28:33 +01:00
)
{
if ( DefaultEntry - > getLOADER_ENTRY ( ) ) {
2020-05-01 18:26:28 +02:00
DefaultEntry - > StartLoader ( ) ;
2020-02-28 21:28:33 +01:00
} else if ( DefaultEntry - > getLEGACY_ENTRY ( ) ) {
2020-05-01 18:26:28 +02:00
DefaultEntry - > StartLegacy ( ) ;
2020-02-15 15:51:18 +01:00
}
GlobalConfig . FastBoot = FALSE ; //Hmm... will never be here
}
2020-04-15 18:30:39 +02:00
// BOOLEAN MainAnime = MainMenu.GetAnime();
2020-02-15 15:51:18 +01:00
// DBG("MainAnime=%d\n", MainAnime);
AfterTool = FALSE ;
gEvent = 0 ; //clear to cancel loop
while ( MainLoopRunning ) {
2020-03-05 04:37:21 +01:00
// CHAR8 *LastChosenOS = NULL;
2020-02-15 15:51:18 +01:00
if ( GlobalConfig . Timeout = = 0 & & DefaultEntry ! = NULL & & ! ReadAllKeyStrokes ( ) ) {
// go strait to DefaultVolume loading
MenuExit = MENU_EXIT_TIMEOUT ;
} else {
2020-04-15 18:30:39 +02:00
MainMenu . GetAnime ( ) ;
2020-04-16 18:21:13 +02:00
if ( gThemeChanged ) {
gThemeChanged = FALSE ;
ThemeX . ClearScreen ( ) ;
}
2020-03-03 21:44:07 +01:00
MenuExit = MainMenu . RunMainMenu ( DefaultIndex , & ChosenEntry ) ;
2020-02-15 15:51:18 +01:00
}
2020-04-01 14:57:32 +02:00
// DBG("exit from MainMenu %llu\n", MenuExit); //MENU_EXIT_ENTER=(1) MENU_EXIT_DETAILS=3
2020-02-15 15:51:18 +01:00
// disable default boot - have sense only in the first run
GlobalConfig . Timeout = - 1 ;
if ( ( DefaultEntry ! = NULL ) & & ( MenuExit = = MENU_EXIT_TIMEOUT ) ) {
2020-02-28 21:28:33 +01:00
if ( DefaultEntry - > getLOADER_ENTRY ( ) ) {
2020-05-01 18:26:28 +02:00
DefaultEntry - > StartLoader ( ) ;
2020-02-28 21:28:33 +01:00
} else if ( DefaultEntry - > getLEGACY_ENTRY ( ) ) {
2020-05-01 18:26:28 +02:00
DefaultEntry - > StartLegacy ( ) ;
2020-02-15 15:51:18 +01:00
}
// if something goes wrong - break main loop to reinit volumes
break ;
}
if ( MenuExit = = MENU_EXIT_OPTIONS ) {
gBootChanged = FALSE ;
2020-03-05 04:37:21 +01:00
OptionsMenu ( & OptionEntry ) ;
2020-02-15 15:51:18 +01:00
if ( gBootChanged ) {
AfterTool = TRUE ;
MainLoopRunning = FALSE ;
break ;
}
continue ;
}
if ( MenuExit = = MENU_EXIT_HELP ) {
HelpRefit ( ) ;
continue ;
}
// EjectVolume
if ( MenuExit = = MENU_EXIT_EJECT ) {
2020-02-28 21:28:33 +01:00
Status = EFI_SUCCESS ;
if ( ChosenEntry - > getLOADER_ENTRY ( ) ) {
Status = EjectVolume ( ChosenEntry - > getLOADER_ENTRY ( ) - > Volume ) ;
}
if ( ChosenEntry - > getLEGACY_ENTRY ( ) ) {
Status = EjectVolume ( ChosenEntry - > getLEGACY_ENTRY ( ) - > Volume ) ;
}
if ( ! EFI_ERROR ( Status ) ) {
break ; //main loop is broken so Reinit all
2020-02-15 15:51:18 +01:00
}
continue ;
}
// Hide toggle
if ( MenuExit = = MENU_EXIT_HIDE_TOGGLE ) {
2020-08-15 22:39:25 +02:00
MainMenu . Entries . includeHidden = ! MainMenu . Entries . includeHidden ;
continue ;
2020-02-15 15:51:18 +01:00
}
// We don't allow exiting the main menu with the Escape key.
if ( MenuExit = = MENU_EXIT_ESCAPE ) {
break ; //refresh main menu
// continue;
}
2020-02-28 21:28:33 +01:00
if ( ChosenEntry - > getREFIT_MENU_ITEM_RESET ( ) ) { // Restart
if ( MenuExit = = MENU_EXIT_DETAILS ) {
2020-02-15 15:51:18 +01:00
// EFI_KEY_DATA KeyData;
// ZeroMem(&KeyData, sizeof KeyData);
// SimpleTextEx->ReadKeyStrokeEx (SimpleTextEx, &KeyData);
// if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
2020-02-28 21:28:33 +01:00
//do clear cmos as for AMI BIOS
// not sure for more robust method
IoWrite8 ( PCAT_RTC_ADDRESS_REGISTER , 0x10 ) ;
IoWrite8 ( PCAT_RTC_DATA_REGISTER , 0x0 ) ;
IoWrite8 ( PCAT_RTC_ADDRESS_REGISTER , 0x11 ) ;
IoWrite8 ( PCAT_RTC_DATA_REGISTER , 0x0 ) ;
2020-02-15 15:51:18 +01:00
// or may be
// IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, 0x17);
// IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x17);
// }
2020-02-28 21:28:33 +01:00
}
// Attempt warm reboot
gRT - > ResetSystem ( EfiResetWarm , EFI_SUCCESS , 0 , NULL ) ;
// Warm reboot may not be supported attempt cold reboot
gRT - > ResetSystem ( EfiResetCold , EFI_SUCCESS , 0 , NULL ) ;
// Terminate the screen and just exit
TerminateScreen ( ) ;
MainLoopRunning = FALSE ;
ReinitDesktop = FALSE ;
AfterTool = TRUE ;
}
2020-02-15 15:51:18 +01:00
2020-02-28 21:28:33 +01:00
if ( ChosenEntry - > getREFIT_MENU_ITEM_SHUTDOWN ( ) ) { // It is not Shut Down, it is Exit from Clover
TerminateScreen ( ) ;
// gRT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);
MainLoopRunning = FALSE ; // just in case we get this far
ReinitDesktop = FALSE ;
AfterTool = TRUE ;
}
if ( ChosenEntry - > getREFIT_MENU_ITEM_OPTIONS ( ) ) { // Options like KernelFlags, DSDTname etc.
gBootChanged = FALSE ;
2020-03-05 04:37:21 +01:00
OptionsMenu ( & OptionEntry ) ;
2020-02-28 21:28:33 +01:00
if ( gBootChanged )
2020-02-15 15:51:18 +01:00
AfterTool = TRUE ;
2020-02-28 21:28:33 +01:00
if ( gBootChanged | | gThemeChanged ) // If theme has changed reinit the desktop
MainLoopRunning = FALSE ;
}
if ( ChosenEntry - > getREFIT_MENU_ITEM_ABOUT ( ) ) { // About rEFIt
AboutRefit ( ) ;
}
2020-02-15 15:51:18 +01:00
2020-02-28 21:28:33 +01:00
/* -- not passed here
// case TAG_HELP:
HelpRefit ( ) ;
break ;
*/
if ( ChosenEntry - > getLOADER_ENTRY ( ) ) { // Boot OS via .EFI loader
SetBootCurrent ( ChosenEntry - > getLOADER_ENTRY ( ) ) ;
2020-05-01 18:26:28 +02:00
ChosenEntry - > StartLoader ( ) ;
2020-02-28 21:28:33 +01:00
//if boot.efi failed we should somehow exit from the loop
TerminateScreen ( ) ;
MainLoopRunning = FALSE ;
ReinitDesktop = FALSE ;
AfterTool = TRUE ;
}
if ( ChosenEntry - > getLEGACY_ENTRY ( ) ) { // Boot legacy OS
if ( StrCmp ( gST - > FirmwareVendor , L " Phoenix Technologies Ltd. " ) = = 0 & &
gST - > Hdr . Revision > > 16 = = 2 & & ( gST - > Hdr . Revision & ( ( 1 < < 16 ) - 1 ) ) = = 0 ) {
// Phoenix SecureCore Tiano 2.0 can't properly initiate LegacyBios protocol when called externally
// which results in "Operating System not found" message coming from BIOS
// in this case just quit Clover to enter BIOS again
2020-02-15 15:51:18 +01:00
TerminateScreen ( ) ;
MainLoopRunning = FALSE ;
ReinitDesktop = FALSE ;
AfterTool = TRUE ;
2020-02-28 21:28:33 +01:00
} else {
SetBootCurrent ( ChosenEntry - > getLEGACY_ENTRY ( ) ) ;
2020-05-01 18:26:28 +02:00
ChosenEntry - > StartLegacy ( ) ;
2020-02-28 21:28:33 +01:00
}
}
if ( ChosenEntry - > getREFIT_MENU_ENTRY_LOADER_TOOL ( ) ) { // Start a EFI tool
2020-05-01 18:26:28 +02:00
ChosenEntry - > StartTool ( ) ;
2020-02-28 21:28:33 +01:00
TerminateScreen ( ) ; //does not happen
// return EFI_SUCCESS;
// BdsLibConnectAllDriversToAllControllers();
// PauseForKey(L"Returned from StartTool\n");
MainLoopRunning = FALSE ;
AfterTool = TRUE ;
}
2020-02-15 15:51:18 +01:00
2020-02-28 21:28:33 +01:00
# ifdef ENABLE_SECURE_BOOT
if ( ChosenEntry - > getREFIT_MENU_ENTRY_SECURE_BOOT ( ) ) { // Try to enable secure boot
EnableSecureBoot ( ) ;
2020-02-15 15:51:18 +01:00
MainLoopRunning = FALSE ;
AfterTool = TRUE ;
2020-02-28 21:28:33 +01:00
}
2020-02-15 15:51:18 +01:00
2020-02-28 21:28:33 +01:00
if ( ChosenEntry - > getREFIT_MENU_ENTRY_SECURE_BOOT_CONFIG ( ) ) { // Configure secure boot
MainLoopRunning = ! ConfigureSecureBoot ( ) ;
AfterTool = TRUE ;
}
# endif // ENABLE_SECURE_BOOT
if ( ChosenEntry - > getREFIT_MENU_ENTRY_CLOVER ( ) ) { // Clover options
REFIT_MENU_ENTRY_CLOVER * LoaderEntry = ChosenEntry - > getREFIT_MENU_ENTRY_CLOVER ( ) ;
2020-04-05 14:25:39 +02:00
if ( LoaderEntry - > LoadOptions . notEmpty ( ) ) {
2020-02-28 21:28:33 +01:00
// we are uninstalling in case user selected Clover Options and EmuVar is installed
// because adding bios boot option requires access to real nvram
//Slice: sure?
/* if (gEmuVariableControl != NULL) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
*/
2020-04-23 22:43:35 +02:00
if ( LoaderEntry - > LoadOptions . contains ( " BO-ADD " ) ) {
2020-08-09 17:55:30 +02:00
XStringW Description ;
2020-02-28 21:28:33 +01:00
CONST CHAR16 * LoaderName ;
INTN EntryIndex , NameSize , Name2Size ;
LOADER_ENTRY * Entry ;
UINT8 * OptionalData ;
UINTN OptionalDataSize ;
UINTN BootNum ;
PrintBootOptions ( FALSE ) ;
for ( EntryIndex = 0 ; EntryIndex < ( INTN ) MainMenu . Entries . size ( ) ; EntryIndex + + ) {
if ( MainMenu . Entries [ EntryIndex ] . Row ! = 0 ) {
continue ;
}
if ( ! MainMenu . Entries [ EntryIndex ] . getLOADER_ENTRY ( ) ) {
continue ;
}
Entry = ( LOADER_ENTRY * ) MainMenu . Entries [ EntryIndex ] . getLOADER_ENTRY ( ) ;
2020-08-09 17:55:30 +02:00
XStringW & VolName = Entry - > Volume - > VolName ;
if ( VolName . isEmpty ( ) ) {
VolName = NullXStringW ;
2020-02-28 21:28:33 +01:00
}
2020-08-09 17:55:30 +02:00
NameSize = VolName . sizeInBytes ( ) ;
2020-02-28 21:28:33 +01:00
Name2Size = 0 ;
2020-04-27 11:50:49 +02:00
if ( Entry - > LoaderPath . notEmpty ( ) ) {
LoaderName = Basename ( Entry - > LoaderPath . wc_str ( ) ) ;
2020-02-28 21:28:33 +01:00
} else {
LoaderName = NULL ; //legacy boot
}
if ( LoaderName ! = NULL ) {
Name2Size = StrSize ( LoaderName ) ;
}
2020-08-09 17:55:30 +02:00
Description = SWPrintf ( " Clover start %ls at %ls " , ( LoaderName ! = NULL ) ? LoaderName : L " legacy " , VolName . wc_str ( ) ) ;
2020-02-28 21:28:33 +01:00
OptionalDataSize = NameSize + Name2Size + 4 + 2 ; //signature + VolNameSize
2020-08-15 15:47:56 +02:00
OptionalData = ( __typeof__ ( OptionalData ) ) AllocateZeroPool ( OptionalDataSize ) ;
2020-02-28 21:28:33 +01:00
if ( OptionalData = = NULL ) {
break ;
}
CopyMem ( OptionalData , " Clvr " , 4 ) ; //signature = 0x72766c43
CopyMem ( OptionalData + 4 , & NameSize , 2 ) ;
2020-08-09 17:55:30 +02:00
CopyMem ( OptionalData + 6 , VolName . wc_str ( ) , VolName . sizeInBytes ( ) ) ;
2020-02-28 21:28:33 +01:00
if ( Name2Size ! = 0 ) {
CopyMem ( OptionalData + 6 + NameSize , LoaderName , Name2Size ) ;
}
Status = AddBootOptionForFile (
LoaderEntry - > Volume - > DeviceHandle ,
LoaderEntry - > LoaderPath ,
TRUE ,
2020-08-09 17:55:30 +02:00
Description . wc_str ( ) ,
2020-02-28 21:28:33 +01:00
OptionalData ,
OptionalDataSize ,
EntryIndex ,
( UINT16 * ) & BootNum
) ;
if ( ! EFI_ERROR ( Status ) ) {
2020-03-25 19:32:44 +01:00
DBG ( " Entry %lld assigned option %04llX \n " , EntryIndex , BootNum ) ;
2020-02-28 21:28:33 +01:00
Entry - > BootNum = BootNum ;
}
FreePool ( OptionalData ) ;
} //for (EntryIndex
PrintBootOptions ( FALSE ) ;
2020-04-23 22:43:35 +02:00
} else if ( LoaderEntry - > LoadOptions . contains ( " BO-REMOVE " ) ) {
2020-02-28 21:28:33 +01:00
PrintBootOptions ( FALSE ) ;
Status = DeleteBootOptionForFile ( LoaderEntry - > Volume - > DeviceHandle ,
LoaderEntry - > LoaderPath
) ;
PrintBootOptions ( FALSE ) ;
2020-04-23 22:43:35 +02:00
} else if ( LoaderEntry - > LoadOptions . contains ( " BO-PRINT " ) ) {
2020-02-28 21:28:33 +01:00
PrintBootOptions ( TRUE ) ;
2020-02-15 15:51:18 +01:00
}
2020-02-28 21:28:33 +01:00
}
MainLoopRunning = FALSE ;
AfterTool = TRUE ;
}
2020-02-15 15:51:18 +01:00
} //MainLoopRunning
UninitRefitLib ( ) ;
if ( ! AfterTool ) {
// PauseForKey(L"After uninit");
//reconnectAll
if ( ! gFirmwareClover ) {
BdsLibConnectAllEfi ( ) ;
}
else {
DBG ( " ConnectAll after refresh menu \n " ) ;
BdsLibConnectAllDriversToAllControllers ( ) ;
}
// ReinitRefitLib();
// PauseForKey(L"After ReinitRefitLib");
}
if ( ReinitDesktop ) {
DBG ( " ReinitSelfLib after theme change \n " ) ;
ReinitSelfLib ( ) ;
}
// PauseForKey(L"After ReinitSelfLib");
} while ( ReinitDesktop ) ;
// If we end up here, things have gone wrong. Try to reboot, and if that
// fails, go into an endless loop.
//Slice - NO!!! Return to EFI GUI
2020-02-16 13:00:20 +01:00
// gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
2020-02-15 15:51:18 +01:00
// EndlessIdleLoop();
# ifdef ENABLE_SECURE_BOOT
UninstallSecureBoot ( ) ;
# endif // ENABLE_SECURE_BOOT
// Unload EmuVariable before returning to EFI GUI, as it should not be present when booting other Operating Systems.
// This seems critical in some UEFI implementations, such as Phoenix UEFI 2.0
if ( gEmuVariableControl ! = NULL ) {
gEmuVariableControl - > UninstallEmulation ( gEmuVariableControl ) ;
}
return EFI_SUCCESS ;
}
2020-02-16 13:00:20 +01:00