CloverBootloader/rEFIt_UEFI/Platform/Settings.cpp

1514 lines
63 KiB
C++

/*
Slice 2012
*/
#include <Platform.h>
#include "Settings.h"
#include "FixBiosDsdt.h"
#include "../include/VolumeTypes.h"
#include "../include/OSFlags.h"
#include "../include/OSTypes.h"
#include "../include/BootTypes.h"
#include "../include/QuirksCodes.h"
#include "../entry_scan/loader.h"
#include "../Platform/BootLog.h"
#include "../entry_scan/secureboot.h"
#include "../libeg/XTheme.h"
#include "cpu.h"
#include "VersionString.h"
#include "card_vlist.h"
#include "Injectors.h"
#include "../include/Pci.h"
#include "../include/Devices.h"
#include "smbios.h"
#include "Net.h"
#include "Nvram.h"
#include "BootOptions.h"
#include "../Settings/SelfOem.h"
#include "ati_reg.h"
#include "ati.h"
#include "nvidia.h"
#include "gma.h"
#include "Edid.h"
#include "hda.h"
#include "../entry_scan/bootscreen.h"
#include "../Settings/ConfigPlist/ConfigPlistClass.h"
#include "../Settings/ConfigManager.h"
#ifndef DEBUG_ALL
#define DEBUG_SET 1
#else
#define DEBUG_SET DEBUG_ALL
#endif
#if DEBUG_SET == 0
#define DBG(...)
#else
#define DBG(...) DebugLog (DEBUG_SET, __VA_ARGS__)
#endif
//#define DUMP_KERNEL_KEXT_PATCHES 1
#define GEN_PMCON_1 0xA0
INTN OldChosenTheme;
INTN OldChosenSmbios;
INTN OldChosenConfig;
INTN OldChosenDsdt;
UINTN OldChosenAudio;
XBool SavePreBootLog;
UINT8 DefaultAudioVolume;
INTN LayoutBannerOffset = 64;
INTN LayoutTextOffset = 0;
INTN LayoutButtonOffset = 0;
XObjArray<ACPI_PATCHED_AML> ACPIPatchedAML;
CHAR16 *IconFormat = NULL;
SETTINGS_DATA gSettings;
UINT32 gFakeCPUID;
EFI_EDID_DISCOVERED_PROTOCOL *EdidDiscovered;
XStringWArray ThemeNameArray;
XStringWArray ConfigsList;
XStringWArray DsdtsList;
XObjArray<HDA_OUTPUTS> AudioList;
XStringWArray SmbiosList;
// firmware
XBool gFirmwareClover = false;
UINTN gEvent;
UINT16 gBacklightLevel;
XBool ResumeFromCoreStorage = false;
//EG_PIXEL SelectionBackgroundPixel = { 0xef, 0xef, 0xef, 0xff }; //define in lib.h
const INTN BCSMargin = 11;
//
DRIVERS_FLAGS gDriversFlags; //the initializer is not needed for global variables
EMU_VARIABLE_CONTROL_PROTOCOL *gEmuVariableControl = NULL;
// global configuration with default values
REFIT_CONFIG GlobalConfig;
CONST CHAR8* AudioOutputNames[] = {
"LineOut",
"Speaker",
"Headphones",
"SPDIF",
"Garniture",
"HDMI",
"Other"
};
const XString8 defaultInstallTitle = "Install macOS"_XS8;
const XString8 defaultRecoveryTitle = "Recovery"_XS8;
const XStringW defaultRecoveryImagePath = L"mac"_XSW;
const XStringW defaultRecoveryDriveImagePath = L"mac"_XSW;
const SETTINGS_DATA::SmbiosClass::SlotDeviceClass SETTINGS_DATA::SmbiosClass::SlotDeviceClass::NullSlotDevice;
CUSTOM_LOADER_ENTRY::CUSTOM_LOADER_ENTRY(const CUSTOM_LOADER_ENTRY_SETTINGS& _settings) : settings(_settings)
{
if ( settings.ImageData.notEmpty() ) {
Image.Image.FromPNG(settings.ImageData.data(), settings.ImageData.size());
}
if ( settings.DriveImageData.notEmpty() ) {
DriveImage.Image.FromPNG(settings.DriveImageData.data(), settings.DriveImageData.size());
}
if ( settings.CustomLogoTypeSettings == CUSTOM_BOOT_USER && settings.CustomLogoAsXString8.notEmpty() ) {
CustomLogoImage.LoadXImage(&self.getSelfVolumeRootDir(), settings.CustomLogoAsXString8);
if (CustomLogoImage.isEmpty()) {
DBG("Custom boot logo not found at path '%s'!\n", settings.CustomLogoAsXString8.c_str());
CustomLogoType = CUSTOM_BOOT_DISABLED;
}
} else if ( settings.CustomLogoTypeSettings == CUSTOM_BOOT_USER && settings.CustomLogoAsData.notEmpty() ) {
CustomLogoImage.FromPNG(settings.CustomLogoAsData.data(), settings.CustomLogoAsData.size());
if (CustomLogoImage.isEmpty()) {
DBG("Custom boot logo not decoded from data!\n");
CustomLogoType = CUSTOM_BOOT_DISABLED;
}
}
DBG("Sub entry custom boot %s (0x%llX)\n", CustomBootModeToStr(settings.CustomLogoTypeSettings), (uintptr_t)&CustomLogoImage);
for ( size_t idx = 0 ; idx < settings.SubEntriesSettings.size() ; ++idx ) {
const CUSTOM_LOADER_SUBENTRY_SETTINGS& CustomEntrySettings = settings.SubEntriesSettings[idx];
CUSTOM_LOADER_SUBENTRY* entry = new CUSTOM_LOADER_SUBENTRY(*this, CustomEntrySettings);
SubEntries.AddReference(entry, true);
}
KernelAndKextPatches = gSettings.KernelAndKextPatches; // Jief : why do we have a duplicated KernelAndKextPatches var inside CUSTOM_LOADER_ENTRY ?
}
XString8Array CUSTOM_LOADER_SUBENTRY::getLoadOptions() const
{
if ( settings._Arguments.isDefined() ) return Split<XString8Array>(settings._Arguments.value(), " ");
XString8Array LoadOptions = parent.getLoadOptions();
LoadOptions.import(Split<XString8Array>(settings._AddArguments, " "));
if (LoadOptions.isEmpty() && OSTYPE_IS_WINDOWS(parent.settings.Type)) {
LoadOptions.Add("-s");
LoadOptions.Add("-h");
}
return LoadOptions;
}
UINT8 CUSTOM_LOADER_SUBENTRY::getFlags(XBool NoCachesDefault) const
{
UINT8 Flags = parent.getFlags(NoCachesDefault);
if ( settings._Arguments.isDefined() ) Flags = OSFLAG_SET(Flags, OSFLAG_NODEFAULTARGS);
if ( settings._NoCaches.isDefined() ) {
if ( settings._NoCaches.value() ) {
Flags = OSFLAG_SET(Flags, OSFLAG_NOCACHES);
} else {
if (NoCachesDefault) {
Flags = OSFLAG_SET(Flags, OSFLAG_NOCACHES);
}
}
}
return Flags;
}
XString8Array CUSTOM_LOADER_ENTRY::getLoadOptions() const
{
if ( settings.Arguments.isDefined() ) return Split<XString8Array>(settings.Arguments.value(), " ");
XString8Array LoadOptions;
LoadOptions.import(Split<XString8Array>(settings.AddArguments, " "));
if (LoadOptions.isEmpty() && OSTYPE_IS_WINDOWS(settings.Type)) {
LoadOptions.Add("-s");
LoadOptions.Add("-h");
}
return LoadOptions;
}
const XString8& CUSTOM_LOADER_SUBENTRY::getTitle() const {
if ( settings._Title.isDefined() ) return settings._Title.value();
if ( settings._FullTitle.isDefined() ) return NullXString8;
return parent.settings.dgetTitle();
};
const XString8& CUSTOM_LOADER_SUBENTRY::getFullTitle() const {
if ( settings._FullTitle.isDefined() ) return settings._FullTitle.value();
if ( settings._Title.isDefined() ) return NullXString8;
return parent.settings.FullTitle;
};
XBool SETTINGS_DATA::GUIClass::getDarkEmbedded(XBool isDaylight) const {
if ( EmbeddedThemeType.isEqualIC("Dark") ) return true;
if ( EmbeddedThemeType.isEqualIC("Daytime") ) return !isDaylight;
return false;
}
//
// check if this entry corresponds to Boot# variable and then set BootCurrent
//
void
SetBootCurrent(REFIT_MENU_ITEM_BOOTNUM *Entry)
{
EFI_STATUS Status;
BO_BOOT_OPTION BootOption;
XStringW VarName;
UINTN VarSize = 0;
UINT8 *BootVariable;
UINTN NameSize;
UINT8 *Data;
UINT16 *BootOrder;
UINT16 *BootOrderNew;
UINT16 *Ptr;
UINTN BootOrderSize;
INTN BootIndex = 0, Index;
VarName = SWPrintf("Boot%04llX", Entry->BootNum);
BootVariable = (UINT8*)GetNvramVariable(VarName.wc_str(), gEfiGlobalVariableGuid, NULL, &VarSize);
if ((BootVariable == NULL) || (VarSize == 0)) {
DBG("Boot option %ls not found\n", VarName.wc_str());
return;
}
//decode the variable
BootOption.Variable = BootVariable;
BootOption.VariableSize = VarSize;
ParseBootOption (&BootOption);
if ((BootOption.OptionalDataSize == 0) ||
(BootOption.OptionalData == NULL) ||
(*(UINT32*)BootOption.OptionalData != CLOVER_SIGN)) {
DBG("BootVariable of the entry is empty\n");
FreePool(BootVariable);
return;
}
Data = BootOption.OptionalData + 4;
NameSize = *(UINT16*)Data;
Data += 2;
if (StriCmp((CHAR16*)Data, Entry->Volume->VolName.wc_str()) != 0) {
DBG("Boot option %llu has other volume name %ls\n", Entry->BootNum, (CHAR16*)Data);
FreePool(BootVariable);
return;
}
if (VarSize > NameSize + 6) {
Data += NameSize;
if (StriCmp((CHAR16*)Data, Basename(Entry->LoaderPath.wc_str())) != 0) {
DBG("Boot option %llu has other loader name %ls\n", Entry->BootNum, (CHAR16*)Data);
FreePool(BootVariable);
return;
}
}
FreePool(BootVariable);
//all check passed, save the number
Status = SetNvramVariable (L"BootCurrent",
gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(UINT16),
&Entry->BootNum);
if (EFI_ERROR(Status)) {
DBG("Can't save BootCurrent, status=%s\n", efiStrError(Status));
}
//Next step is rotate BootOrder to set BootNum to first place
BootOrder = (__typeof__(BootOrder))GetNvramVariable(L"BootOrder", gEfiGlobalVariableGuid, NULL, &BootOrderSize);
if (BootOrder == NULL) {
return;
}
VarSize = (INTN)BootOrderSize / sizeof(UINT16); //reuse variable
for (Index = 0; Index < (INTN)VarSize; Index++) {
if (BootOrder[Index] == Entry->BootNum) {
BootIndex = Index;
break;
}
}
if (BootIndex != 0) {
BootOrderNew = (__typeof__(BootOrderNew))AllocatePool(BootOrderSize);
Ptr = BootOrderNew;
for (Index = 0; Index < (INTN)VarSize - BootIndex; Index++) {
*Ptr++ = BootOrder[Index + BootIndex];
}
for (Index = 0; Index < BootIndex; Index++) {
*Ptr++ = BootOrder[Index];
}
Status = gRT->SetVariable (L"BootOrder",
gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS,
BootOrderSize,
BootOrderNew
);
if (EFI_ERROR(Status)) {
DBG("Can't save BootOrder, status=%s\n", efiStrError(Status));
}
DBG("Set new BootOrder\n");
PrintBootOrder(BootOrderNew, VarSize);
FreePool(BootOrderNew);
}
FreePool(BootOrder);
}
void afterGetUserSettings(SETTINGS_DATA& settingsData)
{
// Secure boot
/* this parameter, which should be called SecureBootSetupMode, is ignored if :
* it is true
* SecureBoot is already true.
*/
if ( settingsData.Boot.SecureSetting == 0 ) {
// Only disable setup mode, we want always secure boot
GlobalConfig.SecureBootSetupMode = 0;
} else if ( settingsData.Boot.SecureSetting == 1 && !GlobalConfig.SecureBoot ) {
// This mode will force boot policy even when no secure boot or it is disabled
GlobalConfig.SecureBootSetupMode = 1;
GlobalConfig.SecureBoot = 1;
}
//set to drop
GlobalConfig.DropSSDT = settingsData.ACPI.SSDT.DropSSDTSetting;
if (GlobalConfig.ACPIDropTables.notEmpty()) {
for ( size_t idx = 0 ; idx < settingsData.ACPI.ACPIDropTablesArray.size() ; ++idx)
{
DBG(" - [%02zd]: Drop table : %.4s, %16llx : ", idx, (const char*)&settingsData.ACPI.ACPIDropTablesArray[idx].Signature, settingsData.ACPI.ACPIDropTablesArray[idx].TableId);
XBool Dropped = false;
for ( size_t idx2 = 0 ; idx2 < GlobalConfig.ACPIDropTables.length() ; ++idx2 ) {
ACPI_DROP_TABLE& DropTable = GlobalConfig.ACPIDropTables[idx2];
if (((settingsData.ACPI.ACPIDropTablesArray[idx].Signature == DropTable.Signature) &&
(!settingsData.ACPI.ACPIDropTablesArray[idx].TableId || (DropTable.TableId == settingsData.ACPI.ACPIDropTablesArray[idx].TableId)) &&
(!settingsData.ACPI.ACPIDropTablesArray[idx].TabLength || (DropTable.Length == settingsData.ACPI.ACPIDropTablesArray[idx].TabLength))) ||
(!settingsData.ACPI.ACPIDropTablesArray[idx].Signature && (DropTable.TableId == settingsData.ACPI.ACPIDropTablesArray[idx].TableId))) {
DropTable.MenuItem.BValue = true;
DropTable.OtherOS = settingsData.ACPI.ACPIDropTablesArray[idx].OtherOS;
GlobalConfig.DropSSDT = false; // if one item=true then dropAll=false by default
//DBG(" true");
Dropped = true;
}
}
DBG(" %s\n", Dropped ? "yes" : "no");
}
}
// Whether or not to draw boot screen
GlobalConfig.CustomLogoType = settingsData.Boot.CustomLogoType;
if ( settingsData.Boot.CustomLogoType == CUSTOM_BOOT_USER && settingsData.Boot.CustomLogoAsXString8.notEmpty() ) {
if (GlobalConfig.CustomLogo != NULL) {
delete GlobalConfig.CustomLogo;
}
GlobalConfig.CustomLogo = new XImage;
GlobalConfig.CustomLogo->LoadXImage(&self.getSelfVolumeRootDir(), settingsData.Boot.CustomLogoAsXString8);
if (GlobalConfig.CustomLogo->isEmpty()) {
DBG("Custom boot logo not found at path '%s'!\n", settingsData.Boot.CustomLogoAsXString8.c_str());
GlobalConfig.CustomLogoType = CUSTOM_BOOT_DISABLED;
}
} else if ( settingsData.Boot.CustomLogoType == CUSTOM_BOOT_USER && settingsData.Boot.CustomLogoAsData.notEmpty() ) {
if (GlobalConfig.CustomLogo != NULL) {
delete GlobalConfig.CustomLogo;
}
GlobalConfig.CustomLogo = new XImage;
GlobalConfig.CustomLogo->FromPNG(settingsData.Boot.CustomLogoAsData.data(), settingsData.Boot.CustomLogoAsData.size());
if (GlobalConfig.CustomLogo->isEmpty()) {
DBG("Custom boot logo not decoded from data!\n"/*, Prop->getString()->stringValue().c_str()*/);
GlobalConfig.CustomLogoType = CUSTOM_BOOT_DISABLED;
}
}
DBG("Custom boot %s (0x%llX)\n", CustomBootModeToStr(GlobalConfig.CustomLogoType), (uintptr_t)GlobalConfig.CustomLogo);
GlobalConfig.EnableC6 = settingsData.getEnableC6();
GlobalConfig.EnableC4 = settingsData.getEnableC4();
GlobalConfig.EnableC2 = settingsData.getEnableC2();
// GlobalConfig.C3Latency = settingsData.getC3Latency();
// DBG("4: GlobalConfig.C3Latency=%x\n", GlobalConfig.C3Latency);
if (settingsData.CPU.HWPEnable && (gCPUStructure.Model >= CPU_MODEL_SKYLAKE_U)) {
GlobalConfig.HWP = true;
AsmWriteMsr64 (MSR_IA32_PM_ENABLE, 1);
if ( settingsData.CPU.HWPValue.isDefined() ) {
AsmWriteMsr64 (MSR_IA32_HWP_REQUEST, settingsData.CPU.HWPValue.value());
}
}
for ( size_t idx = 0 ; idx < settingsData.GUI.CustomEntriesSettings.size() ; ++idx ) {
const CUSTOM_LOADER_ENTRY_SETTINGS& CustomEntrySettings = settingsData.GUI.CustomEntriesSettings[idx];
CUSTOM_LOADER_ENTRY* entry = new CUSTOM_LOADER_ENTRY(CustomEntrySettings);
GlobalConfig.CustomEntries.AddReference(entry, true);
}
for ( size_t idx = 0 ; idx < settingsData.GUI.CustomLegacySettings.size() ; ++idx ) {
const CUSTOM_LEGACY_ENTRY_SETTINGS& CustomLegacySettings = settingsData.GUI.CustomLegacySettings[idx];
CUSTOM_LEGACY_ENTRY* entry = new CUSTOM_LEGACY_ENTRY(CustomLegacySettings, ThemeX->getThemeDir());
GlobalConfig.CustomLegacyEntries.AddReference(entry, true);
}
for ( size_t idx = 0 ; idx < settingsData.GUI.CustomToolSettings.size() ; ++idx ) {
const CUSTOM_TOOL_ENTRY_SETTINGS& CustomToolSettings = settingsData.GUI.CustomToolSettings[idx];
CUSTOM_TOOL_ENTRY* entry = new CUSTOM_TOOL_ENTRY(CustomToolSettings, ThemeX->getThemeDir());
GlobalConfig.CustomToolsEntries.AddReference(entry, true);
}
if ( settingsData.GUI.Theme.notEmpty() )
{
ThemeX->Theme.takeValueFrom(settingsData.GUI.Theme);
DBG("Default theme: %ls\n", settingsData.GUI.Theme.wc_str());
OldChosenTheme = 0xFFFF; //default for embedded
for (UINTN i = 0; i < ThemeNameArray.size(); i++) {
//now comparison is case sensitive
if ( settingsData.GUI.Theme.isEqualIC(ThemeNameArray[i]) ) {
OldChosenTheme = i;
break;
}
}
}
EFI_TIME Now;
gRT->GetTime(&Now, NULL);
if (settingsData.GUI.Timezone != 0xFF) {
INT32 NowHour = Now.Hour + settingsData.GUI.Timezone;
if (NowHour < 0 ) NowHour += 24;
if (NowHour >= 24 ) NowHour -= 24;
ThemeX->Daylight = (NowHour > 8) && (NowHour < 20);
} else {
ThemeX->Daylight = true;
}
ThemeX->DarkEmbedded = settingsData.GUI.getDarkEmbedded(ThemeX->Daylight);
if ( settingsData.GUI.languageCode == english ) {
GlobalConfig.Codepage = 0xC0;
GlobalConfig.CodepageSize = 0;
} else if ( settingsData.GUI.languageCode == russian ) {
GlobalConfig.Codepage = 0x410;
GlobalConfig.CodepageSize = 0x40;
} else if ( settingsData.GUI.languageCode == ukrainian ) {
GlobalConfig.Codepage = 0x400;
GlobalConfig.CodepageSize = 0x60;
} else if ( settingsData.GUI.languageCode == chinese ) {
GlobalConfig.Codepage = 0x3400;
GlobalConfig.CodepageSize = 0x19C0;
} else if ( settingsData.GUI.languageCode == korean ) {
GlobalConfig.Codepage = 0x1100;
GlobalConfig.CodepageSize = 0x100;
}
if (settingsData.Graphics.EDID.InjectEDID){
//DBG("Inject EDID\n");
if ( settingsData.Graphics.EDID.CustomEDID.size() > 0 && settingsData.Graphics.EDID.CustomEDID.size() % 128 == 0 ) {
InitializeEdidOverride();
}
}
GlobalConfig.KPKernelPm = settingsData.KernelAndKextPatches._KPKernelPm || GlobalConfig.NeedPMfix;
GlobalConfig.KPAppleIntelCPUPM = settingsData.KernelAndKextPatches._KPAppleIntelCPUPM || GlobalConfig.NeedPMfix;
if ( settingsData.RtVariables.RtROMAsString.isEqualIC("UseMacAddr0") ) {
if ( gConf.LanCardArray.size() > 0 ) GlobalConfig.RtROM.ncpy(&gConf.LanCardArray[0].MacAddress[0], 6);
else GlobalConfig.RtROM.memset(0, 6);
} else if ( settingsData.RtVariables.RtROMAsString.isEqualIC("UseMacAddr1") ) {
if ( gConf.LanCardArray.size() > 1 ) GlobalConfig.RtROM.ncpy(&gConf.LanCardArray[1].MacAddress[0], 6);
else GlobalConfig.RtROM.memset(0, 6);
}else{
GlobalConfig.RtROM = settingsData.RtVariables.RtROMAsData;
}
if ( GlobalConfig.RtROM.isEmpty() ) {
GlobalConfig.RtROM.ncpy(&settingsData.Smbios.SmUUID.Data4[2], 6);
}
GlobalConfig.RtMLB = settingsData.RtVariables.RtMLBSetting;
if ( GlobalConfig.RtMLB.isEmpty() ) {
GlobalConfig.RtMLB = settingsData.Smbios.BoardSerialNumber;
}
for (size_t idx = 0 ; idx < gConf.GfxPropertiesArrayNonConst.size() ; idx++ ) {
gConf.GfxPropertiesArrayNonConst[idx].LoadVBios = settingsData.Graphics.LoadVBios; //default
}
if ( settingsData.CPU.TurboDisabled ) {
GlobalConfig.Turbo = false;
}else{
GlobalConfig.Turbo = gCPUStructure.Turbo;
}
// Jief : Shouldn't this injection made at StartLoader only ? And only for macOS ?
if ( settingsData.Devices.Properties.propertiesAsString.notEmpty() )
{
size_t binaryPropSize = hex2bin(settingsData.Devices.Properties.propertiesAsString, NULL, 0); // check of correct length is supposed to have been done when reading settings.
UINTN nbPages = EFI_SIZE_TO_PAGES(binaryPropSize);
EFI_PHYSICAL_ADDRESS BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS; //0xFE000000;
EFI_STATUS Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiACPIReclaimMemory,
nbPages,
&BufferPtr
);
if (!EFI_ERROR(Status)) {
cProperties = (UINT8*)(UINTN)BufferPtr;
cPropSize = (UINT32)hex2bin(settingsData.Devices.Properties.propertiesAsString, cProperties, EFI_PAGES_TO_SIZE(nbPages)); // cast should be safe hex2bin return < MAX_UINT32
DBG("Injected EFIString of length %d\n", cPropSize);
}else{
MsgLog("AllocatePages failed (%s), Properties not injected", efiStrError(Status));
}
}
//---------
GlobalConfig.IgPlatform = settingsData.Graphics._IgPlatform;
for ( size_t idx = 0 ; idx < settingsData.Devices.ArbitraryArray.size() ; ++idx ) {
const SETTINGS_DATA::DevicesClass::ArbitraryPropertyClass& arbitraryProperty = settingsData.Devices.ArbitraryArray[idx];
for ( size_t jdx = 0 ; jdx < arbitraryProperty.CustomPropertyArray.size() ; ++jdx ) {
const SETTINGS_DATA::DevicesClass::SimplePropertyClass& customProperty = arbitraryProperty.CustomPropertyArray[jdx];
if ( customProperty.Key.contains("-platform-id") ) {
memcpy(&GlobalConfig.IgPlatform, customProperty.Key.data(), 4);
}
}
}
}
void
SetDevices (LOADER_ENTRY *Entry)
{
// EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *modeInfo;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
UINTN HandleCount;
UINTN i, j;
EFI_HANDLE *HandleBuffer;
pci_dt_t PCIdevice;
UINTN Segment;
UINTN Bus;
UINTN Device;
UINTN Function;
XBool StringDirty = false;
XBool TmpDirty = false;
UINT32 Rcba;
UINT32 Hptc;
DevPropDevice *device = NULL;
GetEdidDiscovered ();
//First make string from Device->Properties
device = NULL;
if (!device_inject_string) {
device_inject_string = devprop_create_string();
}
for ( size_t idx = 0 ; idx < gSettings.Devices.Properties.PropertyArray.size() ; ++idx ) {
const SETTINGS_DATA::DevicesClass::PropertiesClass::PropertyClass& Prop = gSettings.Devices.Properties.PropertyArray[idx];
// if (Prop->Device != 0) {
// Prop = Prop->Next; //skip CustomProperties
// continue;
// }
EFI_DEVICE_PATH_PROTOCOL* DevicePath = Prop.getDevicePath();
if ( DevicePath == NULL ) {
MsgLog("Properties with Label=%ls ignored because getDevicePath() return NULL\n", Prop.DevicePathAsString.wc_str());
continue;
}
device = devprop_add_device_pci(device_inject_string, NULL, DevicePath);
DBG("add device: %ls\n", Prop.DevicePathAsString.wc_str());
for ( size_t jdx = 0 ; jdx < Prop.propertiesArray.size() ; ++jdx ) {
const SETTINGS_DATA::DevicesClass::SimplePropertyClass& Prop2 = Prop.propertiesArray[jdx];
if (Prop2.MenuItem.BValue) {
if ( Prop2.Key.contains("-platform-id") ) {
if ( GlobalConfig.IgPlatform == 0 && Prop2.Value.size() == sizeof(GlobalConfig.IgPlatform) ) {
CopyMem((UINT8*)&GlobalConfig.IgPlatform, Prop2.Value.data(), sizeof(GlobalConfig.IgPlatform));
}
devprop_add_value(device, Prop2.Key.c_str(), (UINT8*)&GlobalConfig.IgPlatform, 4);
DBG(" Add key=%s valuelen=%zu\n", Prop2.Key.c_str(), Prop2.Value.size());
} else if ( (Prop2.Key.contains("override-no-edid") || Prop2.Key.contains("override-no-connect"))
&& gSettings.Graphics.EDID.InjectEDID && gSettings.Graphics.EDID.CustomEDID.notEmpty()) {
// special case for EDID properties
devprop_add_value(device, Prop2.Key.c_str(), gSettings.Graphics.EDID.CustomEDID.data(), 128);
DBG(" Add key=%s from custom EDID\n", Prop2.Key.c_str());
} else {
devprop_add_value(device, Prop2.Key.c_str(), Prop2.Value.data(), Prop2.Value.size());
DBG(" Add key=%s valuelen=%zu\n", Prop2.Key.c_str(), Prop2.Value.size());
}
}else{
DBG("Skip disabled properties with Path=%ls, Key=%s\n", Prop.DevicePathAsString.wc_str(), Prop2.Key.c_str());
}
StringDirty = true;
}
}
devices_number = 1; //should initialize for reentering GUI
// Scan PCI handles
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiPciIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (!EFI_ERROR(Status)) {
for (i = 0; i < HandleCount; i++) {
Status = gBS->HandleProtocol (HandleBuffer[i], &gEfiPciIoProtocolGuid, (void **)&PciIo);
if (!EFI_ERROR(Status)) {
// Read PCI BUS
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci);
if (EFI_ERROR(Status)) {
continue;
}
Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
PCIdevice.DeviceHandle = HandleBuffer[i];
PCIdevice.dev.addr = (UINT32)PCIADDR(Bus, Device, Function);
PCIdevice.vendor_id = Pci.Hdr.VendorId;
PCIdevice.device_id = Pci.Hdr.DeviceId;
PCIdevice.revision = Pci.Hdr.RevisionID;
PCIdevice.subclass = Pci.Hdr.ClassCode[0];
PCIdevice.class_id = *((UINT16*)(Pci.Hdr.ClassCode+1));
PCIdevice.subsys_id_union.subsys.vendor_id = Pci.Device.SubsystemVendorID;
PCIdevice.subsys_id_union.subsys.device_id = Pci.Device.SubsystemID;
PCIdevice.used = false;
//------------------
device = NULL;
for ( size_t idx = 0 ; idx < gSettings.Devices.ArbitraryArray.size() ; ++idx ) {
const SETTINGS_DATA::DevicesClass::ArbitraryPropertyClass& Prop = gSettings.Devices.ArbitraryArray[idx];
if (Prop.Device != PCIdevice.dev.addr) {
continue;
}
if (!PCIdevice.used) {
device = devprop_add_device_pci(device_inject_string, &PCIdevice, NULL);
PCIdevice.used = true;
}
for ( size_t jdx = 0 ; jdx < Prop.CustomPropertyArray.size() ; ++jdx ) {
const SETTINGS_DATA::DevicesClass::SimplePropertyClass& Prop2 = Prop.CustomPropertyArray[jdx];
//special corrections
if (Prop2.MenuItem.BValue) {
if ( Prop2.Key.contains("-platform-id") ) {
devprop_add_value(device, Prop2.Key.c_str(), (UINT8*)&GlobalConfig.IgPlatform, sizeof(GlobalConfig.IgPlatform));
} else {
devprop_add_value(device, Prop2.Key, Prop2.Value);
}
}
StringDirty = true;
}
}
//------------------
if (PCIdevice.used) {
DBG("custom properties for device %02llX:%02llX.%02llX injected\n", Bus, Device, Function);
}
//}
// GFX
if (
(Pci.Hdr.ClassCode[2] == PCI_CLASS_DISPLAY) &&
((Pci.Hdr.ClassCode[1] == PCI_CLASS_DISPLAY_VGA) ||
(Pci.Hdr.ClassCode[1] == PCI_CLASS_DISPLAY_OTHER))) {
switch (Pci.Hdr.VendorId) {
case 0x1002:
if (gSettings.Graphics.InjectAsDict.InjectATI) {
//can't do this in one step because of C-conventions
TmpDirty = setup_ati_devprop(Entry, &PCIdevice);
StringDirty |= TmpDirty;
} else {
MsgLog ("ATI injection not set\n");
}
for (j = 0; j < gConf.GfxPropertiesArrayNonConst.size(); j++) {
if (gConf.GfxPropertiesArrayNonConst[j].Handle == PCIdevice.DeviceHandle) {
if (gConf.GfxPropertiesArrayNonConst[j].ConnChanged) {
*(UINT32*)(gConf.GfxPropertiesArrayNonConst[j].Mmio + RADEON_BIOS_0_SCRATCH) = gConf.GfxPropertiesArrayNonConst[j].Connectors;
}
break;
}
}
if (gSettings.Graphics.RadeonDeInit) {
for (j = 0; j < gConf.GfxPropertiesArrayNonConst.size(); j++) {
if (gConf.GfxPropertiesArrayNonConst[j].Handle == PCIdevice.DeviceHandle) {
SetMem((void*)(gConf.GfxPropertiesArrayNonConst[j].Mmio + 0x6800), 0x800, 0);
*(UINT32*)(gConf.GfxPropertiesArrayNonConst[j].Mmio + 0x6848) = 0; //EVERGREEN_GRPH_FLIP_CONTROL, 1<<0 SURFACE_UPDATE_H_RETRACE_EN
*(UINT32*)(gConf.GfxPropertiesArrayNonConst[j].Mmio + 0x681C) = 0; //EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH
*(UINT32*)(gConf.GfxPropertiesArrayNonConst[j].Mmio + 0x6820) = 0; //EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH
*(UINT32*)(gConf.GfxPropertiesArrayNonConst[j].Mmio + 0x6808) = 0; //EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL, EVERGREEN_LUT_10BIT_BYPASS_EN (1 << 8)
*(UINT32*)(gConf.GfxPropertiesArrayNonConst[j].Mmio + 0x6800) = 1; //EVERGREEN_GRPH_ENABLE
*(UINT32*)(gConf.GfxPropertiesArrayNonConst[j].Mmio + 0x6EF8) = 0; //EVERGREEN_MASTER_UPDATE_MODE
//*(UINT32*)(gConf.GfxPropertiesArrayNonConst[j].Mmio + R600_BIOS_0_SCRATCH) = 0x00810000;
DBG("Device %llu deinited\n", j);
}
}
}
break;
case 0x8086:
if (gSettings.Graphics.InjectAsDict.InjectIntel) {
TmpDirty = setup_gma_devprop(Entry->macOSVersion, Entry->BuildVersion, Entry->Volume->RootDir, &PCIdevice);
StringDirty |= TmpDirty;
MsgLog ("Intel GFX revision = 0x%hhX\n", PCIdevice.revision);
} else {
MsgLog ("Intel GFX injection not set\n");
}
// IntelBacklight reworked by Sherlocks. 2018.10.07
if (gSettings.Devices.IntelBacklight || gSettings.Devices.IntelMaxBacklight) {
UINT32 LEV2 = 0, LEVL = 0, P0BL = 0, GRAN = 0;
UINT32 LEVW = 0, LEVX = 0, LEVD = 0, PCHL = 0;
UINT32 ShiftLEVX = 0, FBLEVX = 0;
UINT32 SYSLEVW = 0x80000000;
UINT32 MACLEVW = 0xC0000000;
MsgLog ("Intel GFX IntelBacklight\n");
// Read LEV2
/*Status = */PciIo->Mem.Read(
PciIo,
EfiPciIoWidthUint32,
0,
0x48250,
1,
&LEV2
);
// Read LEVL
/*Status = */PciIo->Mem.Read(
PciIo,
EfiPciIoWidthUint32,
0,
0x48254,
1,
&LEVL
);
// Read P0BL -- what is the sense to read if not used?
/*Status = */PciIo->Mem.Read(
PciIo,
EfiPciIoWidthUint32,
0,
0x70040,
1,
&P0BL
);
// Read GRAN
/*Status = */PciIo->Mem.Read(
PciIo,
EfiPciIoWidthUint32,
0,
0xC2000,
1,
&GRAN
);
// Read LEVW
/*Status = */PciIo->Mem.Read(
PciIo,
EfiPciIoWidthUint32,
0,
0xC8250,
1,
&LEVW
);
// Read LEVX
/*Status = */PciIo->Mem.Read(
PciIo,
EfiPciIoWidthUint32,
0,
0xC8254,
1,
&LEVX
);
ShiftLEVX = LEVX >> 16;
// Read LEVD
/*Status = */PciIo->Mem.Read(
PciIo,
EfiPciIoWidthUint32,
0,
0xC8258,
1,
&LEVD
);
// Read PCHL
/*Status = */PciIo->Mem.Read(
PciIo,
EfiPciIoWidthUint32,
0,
0xE1180,
1,
&PCHL
);
MsgLog (" LEV2 = 0x%X, LEVL = 0x%X, P0BL = 0x%X, GRAN = 0x%X\n", LEV2, LEVL, P0BL, GRAN);
MsgLog (" LEVW = 0x%X, LEVX = 0x%X, LEVD = 0x%X, PCHL = 0x%X\n", LEVW, LEVX, LEVD, PCHL);
// Maximum brightness level of each framebuffers
// Sandy Bridge/Ivy Bridge: 0x0710
// Haswell/Broadwell: 0x056C/0x07A1/0x0AD9/0x1499
// Skylake/KabyLake: 0x056C
// Coffee Lake: 0xFFFF
switch (Pci.Hdr.DeviceId) {
case 0x0102: // "Intel HD Graphics 2000"
case 0x0106: // "Intel HD Graphics 2000"
case 0x010A: // "Intel HD Graphics P3000"
case 0x0112: // "Intel HD Graphics 3000"
case 0x0116: // "Intel HD Graphics 3000"
case 0x0122: // "Intel HD Graphics 3000"
case 0x0126: // "Intel HD Graphics 3000"
if (GlobalConfig.IgPlatform) {
switch (GlobalConfig.IgPlatform) {
case (UINT32)0x00030010:
case (UINT32)0x00050000:
FBLEVX = 0xFFFF;
break;
default:
FBLEVX = 0x0710;
break;
}
} else {
FBLEVX = 0x0710;
}
break;
case 0x0152: // "Intel HD Graphics 2500"
case 0x0156: // "Intel HD Graphics 2500"
case 0x015A: // "Intel HD Graphics 2500"
case 0x0162: // "Intel HD Graphics 4000"
case 0x0166: // "Intel HD Graphics 4000"
case 0x016A: // "Intel HD Graphics P4000"
FBLEVX = 0x0710;
break;
case 0x0412: // "Intel HD Graphics 4600"
case 0x0416: // "Intel HD Graphics 4600"
case 0x041A: // "Intel HD Graphics P4600"
case 0x041E: // "Intel HD Graphics 4400"
case 0x0422: // "Intel HD Graphics 5000"
case 0x0426: // "Intel HD Graphics 5000"
case 0x042A: // "Intel HD Graphics 5000"
case 0x0A06: // "Intel HD Graphics"
case 0x0A16: // "Intel HD Graphics 4400"
case 0x0A1E: // "Intel HD Graphics 4200"
case 0x0A22: // "Intel Iris Graphics 5100"
case 0x0A26: // "Intel HD Graphics 5000"
case 0x0A2A: // "Intel Iris Graphics 5100"
case 0x0A2B: // "Intel Iris Graphics 5100"
case 0x0A2E: // "Intel Iris Graphics 5100"
case 0x0D12: // "Intel HD Graphics 4600"
case 0x0D16: // "Intel HD Graphics 4600"
case 0x0D22: // "Intel Iris Pro Graphics 5200"
case 0x0D26: // "Intel Iris Pro Graphics 5200"
case 0x0D2A: // "Intel Iris Pro Graphics 5200"
case 0x0D2B: // "Intel Iris Pro Graphics 5200"
case 0x0D2E: // "Intel Iris Pro Graphics 5200"
if (GlobalConfig.IgPlatform) {
switch (GlobalConfig.IgPlatform) {
case (UINT32)0x04060000:
case (UINT32)0x0c060000:
case (UINT32)0x04160000:
case (UINT32)0x0c160000:
case (UINT32)0x04260000:
case (UINT32)0x0c260000:
case (UINT32)0x0d260000:
case (UINT32)0x0d220003:
FBLEVX = 0x1499;
break;
case (UINT32)0x0a160000:
case (UINT32)0x0a260000:
case (UINT32)0x0a260005:
case (UINT32)0x0a260006:
FBLEVX = 0x0AD9;
break;
case (UINT32)0x0d260007:
FBLEVX = 0x07A1;
break;
case (UINT32)0x04120004:
case (UINT32)0x0412000b:
break;
default:
FBLEVX = 0x056C;
break;
}
} else {
switch (Pci.Hdr.DeviceId) {
case 0x0406:
case 0x0C06:
case 0x0416:
case 0x0C16:
case 0x0426:
case 0x0C26:
case 0x0D22:
FBLEVX = 0x1499;
break;
case 0x0A16:
case 0x0A26:
FBLEVX = 0x0AD9;
break;
case 0x0D26:
FBLEVX = 0x07A1;
break;
default:
FBLEVX = 0x056C;
break;
}
}
break;
case 0x1612: // "Intel HD Graphics 5600"
case 0x1616: // "Intel HD Graphics 5500"
case 0x161E: // "Intel HD Graphics 5300"
case 0x1626: // "Intel HD Graphics 6000"
case 0x162B: // "Intel Iris Graphics 6100"
case 0x162D: // "Intel Iris Pro Graphics P6300"
case 0x1622: // "Intel Iris Pro Graphics 6200"
case 0x162A: // "Intel Iris Pro Graphics P6300"
if (GlobalConfig.IgPlatform) {
switch (GlobalConfig.IgPlatform) {
case (UINT32)0x16060000:
case (UINT32)0x160e0000:
case (UINT32)0x16160000:
case (UINT32)0x161e0000:
case (UINT32)0x16220000:
case (UINT32)0x16260000:
case (UINT32)0x162b0000:
case (UINT32)0x16260004:
case (UINT32)0x162b0004:
case (UINT32)0x16220007:
case (UINT32)0x16260008:
case (UINT32)0x162b0008:
FBLEVX = 0x1499;
break;
case (UINT32)0x16260005:
case (UINT32)0x16260006:
FBLEVX = 0x0AD9;
break;
case (UINT32)0x16120003:
FBLEVX = 0x07A1;
break;
default:
FBLEVX = 0x056C;
break;
}
} else {
switch (Pci.Hdr.DeviceId) {
case 0x1606:
case 0x160E:
case 0x1616:
case 0x161E:
case 0x1622:
FBLEVX = 0x1499;
break;
case 0x1626:
FBLEVX = 0x0AD9;
break;
case 0x1612:
FBLEVX = 0x07A1;
break;
default:
FBLEVX = 0x056C;
break;
}
}
break;
case 0x1902: // "Intel HD Graphics 510"
case 0x1906: // "Intel HD Graphics 510"
case 0x190B: // "Intel HD Graphics 510"
case 0x1912: // "Intel HD Graphics 530"
case 0x1916: // "Intel HD Graphics 520"
case 0x191B: // "Intel HD Graphics 530"
case 0x191D: // "Intel HD Graphics P530"
case 0x191E: // "Intel HD Graphics 515"
case 0x1921: // "Intel HD Graphics 520"
case 0x1923: // "Intel HD Graphics 535"
case 0x1926: // "Intel Iris Graphics 540"
case 0x1927: // "Intel Iris Graphics 550"
case 0x192B: // "Intel Iris Graphics 555"
case 0x192D: // "Intel Iris Graphics P555"
case 0x1932: // "Intel Iris Pro Graphics 580"
case 0x193A: // "Intel Iris Pro Graphics P580"
case 0x193B: // "Intel Iris Pro Graphics 580"
case 0x193D: // "Intel Iris Pro Graphics P580"
if (GlobalConfig.IgPlatform) {
switch (GlobalConfig.IgPlatform) {
case (UINT32)0x19120001:
FBLEVX = 0xFFFF;
break;
default:
FBLEVX = 0x056C;
break;
}
} else {
FBLEVX = 0x056C;
}
break;
case 0x5902: // "Intel HD Graphics 610"
case 0x5906: // "Intel HD Graphics 610"
case 0x5912: // "Intel HD Graphics 630"
case 0x5916: // "Intel HD Graphics 620"
case 0x591A: // "Intel HD Graphics P630"
case 0x591B: // "Intel HD Graphics 630"
case 0x591D: // "Intel HD Graphics P630"
case 0x591E: // "Intel HD Graphics 615"
case 0x5923: // "Intel HD Graphics 635"
case 0x5926: // "Intel Iris Plus Graphics 640"
case 0x5927: // "Intel Iris Plus Graphics 650"
case 0x5917: // "Intel UHD Graphics 620"
case 0x591C: // "Intel UHD Graphics 615"
case 0x87C0: // "Intel UHD Graphics 617"
case 0x87CA: // "Intel UHD Graphics 615"
FBLEVX = 0x056C;
break;
case 0x3E90: // "Intel UHD Graphics 610"
case 0x3E93: // "Intel UHD Graphics 610"
case 0x3E91: // "Intel UHD Graphics 630"
case 0x3E92: // "Intel UHD Graphics 630"
case 0x3E98: // "Intel UHD Graphics 630"
case 0x3E9B: // "Intel UHD Graphics 630"
case 0x3EA5: // "Intel Iris Plus Graphics 655"
case 0x3EA0: // "Intel UHD Graphics 620"
case 0x9B41: // "Intel UHD Graphics 620"
case 0x9BCA: // "Intel UHD Graphics 620"
FBLEVX = 0xFFFF;
break;
default:
FBLEVX = 0xFFFF;
break;
}
// Write LEVW
if (LEVW != SYSLEVW) {
MsgLog (" Found invalid LEVW, set System LEVW: 0x%X\n", SYSLEVW);
/*Status = */PciIo->Mem.Write(
PciIo,
EfiPciIoWidthUint32,
0,
0xC8250,
1,
&SYSLEVW
);
}
switch (gCPUStructure.Model) {
case CPU_MODEL_SANDY_BRIDGE:
case CPU_MODEL_IVY_BRIDGE:
case CPU_MODEL_IVY_BRIDGE_E5:
// if change SYS LEVW to macOS LEVW, the brightness of the pop-up may decrease or increase.
// but the brightness of the monitor will not actually change. so we should not use this.
MsgLog (" Skip writing macOS LEVW: 0x%X\n", MACLEVW);
break;
case CPU_MODEL_HASWELL:
case CPU_MODEL_HASWELL_ULT:
case CPU_MODEL_HASWELL_U5: // Broadwell
case CPU_MODEL_BROADWELL_HQ:
case CPU_MODEL_BROADWELL_E5:
case CPU_MODEL_BROADWELL_DE:
// if not change SYS LEVW to macOS LEVW, backlight will be dark and don't work keys for backlight.
// so we should use this.
MsgLog (" Write macOS LEVW: 0x%X\n", MACLEVW);
/*Status = */PciIo->Mem.Write(
PciIo,
EfiPciIoWidthUint32,
0,
0xC8250,
1,
&MACLEVW
);
break;
default:
if (gSettings.Devices.IntelBacklight) {
MsgLog (" Write macOS LEVW: 0x%X\n", MACLEVW);
/*Status = */PciIo->Mem.Write(
PciIo,
EfiPciIoWidthUint32,
0,
0xC8250,
1,
&MACLEVW
);
}
break;
}
switch (Pci.Hdr.DeviceId) {
case 0x0042: // "Intel HD Graphics"
case 0x0046: // "Intel HD Graphics"
case 0x0102: // "Intel HD Graphics 2000"
case 0x0106: // "Intel HD Graphics 2000"
case 0x010A: // "Intel HD Graphics P3000"
case 0x0112: // "Intel HD Graphics 3000"
case 0x0116: // "Intel HD Graphics 3000"
case 0x0122: // "Intel HD Graphics 3000"
case 0x0126: // "Intel HD Graphics 3000"
case 0x0152: // "Intel HD Graphics 2500"
case 0x0156: // "Intel HD Graphics 2500"
case 0x015A: // "Intel HD Graphics 2500"
case 0x0162: // "Intel HD Graphics 4000"
case 0x0166: // "Intel HD Graphics 4000"
case 0x016A: // "Intel HD Graphics P4000"
// Write LEVL/LEVX
if (gSettings.Devices.IntelMaxBacklight) {
if (!LEVL) {
LEVL = FBLEVX;
MsgLog (" Found invalid LEVL, set LEVL: 0x%X\n", LEVL);
}
if (!LEVX) {
ShiftLEVX = FBLEVX;
MsgLog (" Found invalid LEVX, set LEVX: 0x%X\n", ShiftLEVX);
}
if (gSettings.Devices.IntelMaxValue) {
FBLEVX = gSettings.Devices.IntelMaxValue;
MsgLog (" Read IntelMaxValue: 0x%X\n", FBLEVX);
} else {
MsgLog (" Read default Framebuffer LEVX: 0x%X\n", FBLEVX);
}
LEVL = (LEVL * FBLEVX) / ShiftLEVX;
MsgLog (" Write new LEVL: 0x%X\n", LEVL);
/*Status = */PciIo->Mem.Write(
PciIo,
EfiPciIoWidthUint32,
0,
0x48254,
1,
&LEVL
);
LEVX = FBLEVX | FBLEVX << 16;
MsgLog (" Write new LEVX: 0x%X\n", LEVX);
/*Status = */PciIo->Mem.Write(
PciIo,
EfiPciIoWidthUint32,
0,
0xC8254,
1,
&LEVX
);
}
break;
case 0x3E90: // "Intel UHD Graphics 610"
case 0x3E93: // "Intel UHD Graphics 610"
case 0x3E91: // "Intel UHD Graphics 630"
case 0x3E92: // "Intel UHD Graphics 630"
case 0x3E98: // "Intel UHD Graphics 630"
case 0x3E9B: // "Intel UHD Graphics 630"
case 0x3EA5: // "Intel Iris Plus Graphics 655"
case 0x3EA0: // "Intel UHD Graphics 620"
case 0x9B41: // "Intel UHD Graphics 620"
case 0x9BCA: // "Intel UHD Graphics 620"
// Write LEVD
if (gSettings.Devices.IntelMaxBacklight) {
if (gSettings.Devices.IntelMaxValue) {
FBLEVX = gSettings.Devices.IntelMaxValue;
MsgLog (" Read IntelMaxValue: 0x%X\n", FBLEVX);
} else {
MsgLog (" Read default Framebuffer LEVX: 0x%X\n", FBLEVX);
}
LEVD = (UINT32)DivU64x32(MultU64x32(FBLEVX, LEVX), 0xFFFF);
MsgLog (" Write new LEVD: 0x%X\n", LEVD);
/*Status = */PciIo->Mem.Write(
PciIo,
EfiPciIoWidthUint32,
0,
0xC8258,
1,
&LEVD
);
}
break;
default:
// Write LEVX
if (gSettings.Devices.IntelMaxBacklight) {
if (gSettings.Devices.IntelMaxValue) {
FBLEVX = gSettings.Devices.IntelMaxValue;
MsgLog (" Read IntelMaxValue: 0x%X\n", FBLEVX);
LEVX = FBLEVX | FBLEVX << 16;
} else if (!LEVX) {
MsgLog (" Found invalid LEVX, set LEVX: 0x%X\n", FBLEVX);
LEVX = FBLEVX | FBLEVX << 16;
} else if (ShiftLEVX != FBLEVX) {
MsgLog (" Read default Framebuffer LEVX: 0x%X\n", FBLEVX);
LEVX = (((LEVX & 0xFFFF) * FBLEVX / ShiftLEVX) | FBLEVX << 16);
}
MsgLog (" Write new LEVX: 0x%X\n", LEVX);
/*Status = */PciIo->Mem.Write(
PciIo,
EfiPciIoWidthUint32,
0,
0xC8254,
1,
&LEVX
);
}
break;
}
if (gSettings.Devices.FakeID.FakeIntel == 0x00008086) {
UINT32 IntelDisable = 0x03;
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x50, 1, &IntelDisable);
}
}
break;
case 0x10de:
if (gSettings.Graphics.InjectAsDict.InjectNVidia) {
TmpDirty = setup_nvidia_devprop(&PCIdevice);
StringDirty |= TmpDirty;
} else {
MsgLog ("NVidia GFX injection not set\n");
}
break;
default:
break;
}
}
//LAN
else if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_NETWORK) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_NETWORK_ETHERNET)) {
//MsgLog ("Ethernet device found\n");
TmpDirty = set_eth_props (&PCIdevice);
StringDirty |= TmpDirty;
}
//USB
else if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_SERIAL) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_SERIAL_USB)) {
if (gSettings.Devices.USB.USBInjection) {
TmpDirty = set_usb_props (&PCIdevice);
StringDirty |= TmpDirty;
}
}
// HDA
else if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_MEDIA) &&
((Pci.Hdr.ClassCode[1] == PCI_CLASS_MEDIA_HDA) ||
(Pci.Hdr.ClassCode[1] == PCI_CLASS_MEDIA_AUDIO))) {
// HDMI injection inside
if (gSettings.Devices.Audio.HDAInjection ) {
TmpDirty = setup_hda_devprop (PciIo, &PCIdevice, Entry->macOSVersion);
StringDirty |= TmpDirty;
}
if (gSettings.Devices.Audio.ResetHDA) {
//PCI_HDA_TCSEL_OFFSET = 0x44
UINT8 Value = 0;
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x44, 1, &Value);
if (EFI_ERROR(Status)) {
continue;
}
Value &= 0xf8;
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x44, 1, &Value);
}
}
//LPC
else if ((Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) &&
(Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA))
{
// 2021-04 Jief : LpcTune doesn't exist in Settings.cpp. Never set to true.
// if (gSettings.LpcTune) {
// UINT16 PmCon;
// Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, GEN_PMCON_1, 1, &PmCon);
// MsgLog ("Initial PmCon value=%hX\n", PmCon);
//
// if (GlobalConfig.EnableC6) {
// PmCon |= 1 << 11;
// DBG("C6 enabled\n");
// } else {
// PmCon &= ~(1 << 11);
// DBG("C6 disabled\n");
// }
// /*
// if (GlobalConfig.EnableC2) {
// PmCon |= 1 << 10;
// DBG("BIOS_PCIE enabled\n");
// } else {
// PmCon &= ~(1 << 10);
// DBG("BIOS_PCIE disabled\n");
// }
// */
// if (GlobalConfig.EnableC4) {
// PmCon |= 1 << 7;
// DBG("C4 enabled\n");
// } else {
// PmCon &= ~(1 << 7);
// DBG("C4 disabled\n");
// }
//
// if (gSettings.ACPI.SSDT.EnableISS) {
// PmCon |= 1 << 3;
// DBG("SpeedStep enabled\n");
// } else {
// PmCon &= ~(1 << 3);
// DBG("SpeedStep disabled\n");
// }
//
// PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, GEN_PMCON_1, 1, &PmCon);
//
// Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,GEN_PMCON_1, 1, &PmCon);
// MsgLog ("Set PmCon value=%hX\n", PmCon);
//
// }
Rcba = 0;
/* Scan Port */
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0xF0, 1, &Rcba);
if (EFI_ERROR(Status)) continue;
// Rcba &= 0xFFFFC000;
if ((Rcba & 0xFFFFC000) == 0) {
MsgLog (" RCBA disabled; cannot use it\n");
continue;
}
if ((Rcba & 1) == 0) {
MsgLog (" RCBA access disabled; trying to enable\n");
Rcba |= 1;
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0xF0, 1, &Rcba);
}
Rcba &= 0xFFFFC000;
if (gSettings.Devices.ForceHPET) {
Hptc = REG32 ((UINTN)Rcba, 0x3404);
if ((Hptc & 0x80) != 0) {
DBG("HPET is already enabled\n");
} else {
DBG("HPET is disabled, trying to enable...\n");
REG32 ((UINTN)Rcba, 0x3404) = Hptc | 0x80;
}
// Re-Check if HPET is enabled.
Hptc = REG32 ((UINTN)Rcba, 0x3404);
if ((Hptc & 0x80) == 0) {
DBG("HPET is disabled in HPTC. Cannot enable!\n");
} else {
DBG("HPET is enabled\n");
}
}
if (gSettings.Devices.DisableFunctions){
UINT32 FD = REG32 ((UINTN)Rcba, 0x3418);
DBG("Initial value of FD register 0x%X\n", FD);
FD |= gSettings.Devices.DisableFunctions;
REG32 ((UINTN)Rcba, 0x3418) = FD;
FD = REG32 ((UINTN)Rcba, 0x3418);
DBG(" recheck value after patch 0x%X\n", FD);
}
}
}
}
}
if (StringDirty) {
EFI_PHYSICAL_ADDRESS BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS; //0xFE000000;
XBuffer<char> newDeviceProperties = devprop_generate_string(device_inject_string);
size_t binaryPropSize = hex2bin(newDeviceProperties, NULL, 0);
if ( binaryPropSize > MAX_UINT32 ) {
MsgLog("devprop_generate_string(device_inject_string) is too big");
newDeviceProperties.setEmpty();
}else{
DBG("stringlength = %zu\n", newDeviceProperties.size());
UINTN nbPages = EFI_SIZE_TO_PAGES(binaryPropSize);
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiACPIReclaimMemory,
nbPages,
&BufferPtr
);
if (!EFI_ERROR(Status)) {
mProperties = (UINT8*)(UINTN)BufferPtr;
// DBG(gDeviceProperties);
// DBG("\n");
// StringDirty = false;
//-------
mPropSize = (UINT32)hex2bin(newDeviceProperties, mProperties, EFI_PAGES_TO_SIZE(nbPages)); // cast should be safe as hex2bin return <= MAXUINT32
// gDeviceProperties is not used
gDeviceProperties = newDeviceProperties.forgetDataWithoutFreeing(); // do this AFTER hex2bin
// DBG("Final size of mProperties=%d\n", mPropSize);
//---------
// Status = egSaveFile(&self.getSelfRootDir(), SWPrintf("%ls\\misc\\devprop.bin", self.getCloverDirFullPath().wc_str()).wc_str() , (UINT8*)mProperties, mPropSize);
}else{
MsgLog("AllocatePages failed (%s), device_inject_string not injected\n", efiStrError(Status));
}
}
}
MsgLog ("CurrentMode: Width=%lld Height=%lld\n", UGAWidth, UGAHeight);
}
EFI_STATUS
ApplySettings()
{
// TODO: SetVariable()..
// here we can apply user settings instead of default one
gMobile = gSettings.Smbios.Mobile;
if ((gSettings.CPU.BusSpeed != 0) && (gSettings.CPU.BusSpeed > 10 * Kilo) && (gSettings.CPU.BusSpeed < 500 * Kilo)) {
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 = gSettings.CPU.BusSpeed;
//DBG("Read ExternalClock: %d MHz\n", (INT32)(DivU64x32(gCPUStructure.ExternalClock, Kilo)));
break;
default:
//DBG("Read ExternalClock: %d MHz\n", (INT32)(DivU64x32(gSettings.BusSpeed, Kilo)));
// for sandy bridge or newer
// to match ExternalClock 25 MHz like real mac, divide BusSpeed by 4
gCPUStructure.ExternalClock = (gSettings.CPU.BusSpeed + 3) / 4;
//DBG("Corrected ExternalClock: %d MHz\n", (INT32)(DivU64x32(gCPUStructure.ExternalClock, Kilo)));
break;
}
gCPUStructure.FSBFrequency = MultU64x64 (gSettings.CPU.BusSpeed, Kilo); //kHz -> Hz
gCPUStructure.MaxSpeed = (UINT32)(DivU64x32 ((UINT64)gSettings.CPU.BusSpeed * gCPUStructure.MaxRatio, 10000)); //kHz->MHz
}
if ((gSettings.CPU.CpuFreqMHz > 100) && (gSettings.CPU.CpuFreqMHz < 20000)) {
gCPUStructure.MaxSpeed = gSettings.CPU.CpuFreqMHz;
}
// to determine the use of Table 132
if (gSettings.CPU.QPI) {
GlobalConfig.SetTable132 = true;
//DBG("QPI: use Table 132\n");
}
else {
switch (gCPUStructure.Model) {
case CPU_MODEL_NEHALEM:// Core i7 LGA1366, Xeon 5500, "Bloomfield", "Gainstown", 45nm
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"
GlobalConfig.SetTable132 = true;
DBG("QPI: use Table 132\n");
break;
default:
//DBG("QPI: disable Table 132\n");
break;
}
}
gCPUStructure.CPUFrequency = MultU64x64 (gCPUStructure.MaxSpeed, Mega);
return EFI_SUCCESS;
}
XStringW GetOtherKextsDir (XBool On)
{
if ( !selfOem.isKextsDirFound() ) return NullXStringW;
if ( FileExists(&selfOem.getKextsDir(), On ? L"Other" : L"Off") ) {
return On ? L"Other"_XSW : L"Off"_XSW;
}
return NullXStringW;
}
//dmazar
// Jief 2020-10: this is only called by SetFSInjection(). SetFSInjection() doesn't check for return value emptiness.
XStringW GetOSVersionKextsDir(const MacOsVersion& OSVersion)
{
if ( !selfOem.isKextsDirFound() ) return NullXStringW;
XStringW SrcDir = SWPrintf("%ls\\%s", selfOem.getKextsFullPath().wc_str(), OSVersion.asString(2).c_str());
if (FileExists (&self.getSelfVolumeRootDir(), SrcDir)) return SrcDir;
return NullXStringW;
}
const EFI_GUID& SETTINGS_DATA::getUUID()
{
if ( SystemParameters.CustomUuid.notNull() ) return SystemParameters.CustomUuid;
return Smbios.SmUUID;
}