mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-29 12:35:53 +01:00
291 lines
15 KiB
C++
291 lines
15 KiB
C++
/*
|
|
* ConfigPlist.h
|
|
*
|
|
* Created on: Oct 9, 2020
|
|
* Author: jief
|
|
*/
|
|
|
|
#ifndef _CONFIGPLISTCLASS_GRAPHICS_H_
|
|
#define _CONFIGPLISTCLASS_GRAPHICS_H_
|
|
|
|
|
|
class Graphics_Class : public XmlDict
|
|
{
|
|
using super = XmlDict;
|
|
public:
|
|
const ConfigPlistClass& configPlist;
|
|
|
|
class Graphics_PatchVBiosBytes_Class : public XmlDict
|
|
{
|
|
protected:
|
|
XmlData Find = XmlData();
|
|
XmlData Replace = XmlData();
|
|
|
|
XmlDictField m_fields[2] = {
|
|
{"Find", Find},
|
|
{"Replace", Replace},
|
|
};
|
|
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
|
|
public:
|
|
const decltype(Find)::ValueType& dgetFind() const { return Find.isDefined() ? Find.value() : Find.nullValue; };
|
|
const decltype(Replace)::ValueType& dgetReplace() const { return Replace.isDefined() ? Replace.value() : Replace.nullValue; };
|
|
|
|
};
|
|
|
|
|
|
class Graphics_ATI_NVIDIA_Class : public XmlDict
|
|
{
|
|
using super = XmlDict;
|
|
protected:
|
|
XmlString8AllowEmpty Model = XmlString8AllowEmpty();
|
|
XmlUInt32 IOPCIPrimaryMatch = XmlUInt32(); // Id
|
|
XmlUInt32 IOPCISubDevId = XmlUInt32(); // SubId
|
|
XmlUInt64 VRAM = XmlUInt64(); // VideoRam
|
|
XmlUInt64 VideoPorts = decltype(VideoPorts)(); // VideoPorts
|
|
XmlBool LoadVBios = XmlBool(); // LoadVBios
|
|
|
|
XmlDictField m_fields[6] = {
|
|
{"Model", Model},
|
|
{"IOPCIPrimaryMatch", IOPCIPrimaryMatch},
|
|
{"IOPCISubDevId", IOPCISubDevId},
|
|
{"VRAM", VRAM},
|
|
{"VideoPorts", VideoPorts},
|
|
{"LoadVBios", LoadVBios},
|
|
};
|
|
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
public:
|
|
const decltype(Model)::ValueType& dgetModel() const { return Model.isDefined() ? Model.value() : Model.nullValue; };
|
|
const decltype(IOPCIPrimaryMatch)::ValueType& dgetId() const { return IOPCIPrimaryMatch.isDefined() ? IOPCIPrimaryMatch.value() : IOPCIPrimaryMatch.nullValue; };
|
|
const decltype(IOPCISubDevId)::ValueType& dgetSubId() const { return IOPCISubDevId.isDefined() ? IOPCISubDevId.value() : IOPCISubDevId.nullValue; };
|
|
decltype(VRAM)::ValueType dgetVideoRam() const { return VRAM.isDefined() ? LShiftU64(VRAM.value(), 20) : VRAM.nullValue; }; //Mb -> bytes
|
|
const decltype(VideoPorts)::ValueType& dgetVideoPorts() const { return VideoPorts.isDefined() ? VideoPorts.value() : VideoPorts.nullValue; };
|
|
const decltype(LoadVBios)::ValueType& dgetLoadVBios() const { return LoadVBios.isDefined() ? LoadVBios.value() : LoadVBios.nullValue; };
|
|
UINT32 dgetSignature() const { return SIGNATURE_32('C','A','R','D'); };
|
|
|
|
};
|
|
|
|
class Graphics_EDID_Class : public XmlDict
|
|
{
|
|
using super = XmlDict;
|
|
public:
|
|
XmlBool Inject = XmlBool();
|
|
XmlData Custom = XmlData();
|
|
XmlUInt16 VendorID = XmlUInt16();
|
|
XmlUInt16 ProductID = XmlUInt16();
|
|
XmlUInt16 HorizontalSyncPulseWidth = XmlUInt16();
|
|
XmlUInt8 VideoInputSignal = XmlUInt8();
|
|
|
|
XmlDictField m_fields[6] = {
|
|
{"Inject", Inject},
|
|
{"Custom", Custom},
|
|
{"VendorID", VendorID},
|
|
{"ProductID", ProductID},
|
|
{"HorizontalSyncPulseWidth", HorizontalSyncPulseWidth},
|
|
{"VideoInputSignal", VideoInputSignal},
|
|
};
|
|
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
virtual bool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, bool generateErrors) override {
|
|
RETURN_IF_FALSE( super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) );
|
|
if ( Inject.isDefined() ) {
|
|
if ( Inject.value() ) {
|
|
if ( !Custom.isDefined() ) {
|
|
// Each patch of VID/PID/HSPW/VIS can work independently without custom values.
|
|
// xmlLiteParser->addWarning(generateErrors, S8Printf("Custom has to be defined if Inject is defined in dict '%s:%d'.", xmlPath.c_str(), keyPos.getLine()));
|
|
// return false; // Allow this to be compatible with old way of reading settings. Can be put back when definitive switch is made
|
|
}else{
|
|
if ( Custom.value().size() % 128 != 0 ) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("Custom length must be modulo 128 in dict '%s:%d'.", xmlPath.c_str(), keyPos.getLine()));
|
|
Custom.reset();
|
|
return true; // that's what Clover is currently doing.
|
|
}
|
|
}
|
|
}else{
|
|
if ( Custom.isDefined() ) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("Custom is defined and will be ignored because Inject is false in dict '%s:%d'.", xmlPath.c_str(), keyPos.getLine()));
|
|
return false;
|
|
}
|
|
}
|
|
}else{
|
|
if ( Custom.isDefined() ) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("Custom is defined and will be ignored because Inject isn't defined '%s:%d'.", xmlPath.c_str(), keyPos.getLine()));
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
|
|
};
|
|
const decltype(Inject)::ValueType& dgetInjectEDID() const { return Inject.isDefined() ? Inject.value() : Inject.nullValue; };
|
|
const decltype(Custom)::ValueType& dgetCustomEDID() const { return dgetInjectEDID() && Custom.isDefined() ? Custom.value() : Custom.nullValue; };
|
|
const decltype(VendorID)::ValueType& dgetVendorEDID() const { return dgetInjectEDID() && VendorID.isDefined() ? VendorID.value() : VendorID.nullValue; };
|
|
const decltype(ProductID)::ValueType& dgetProductEDID() const { return dgetInjectEDID() && ProductID.isDefined() ? ProductID.value() : ProductID.nullValue; };
|
|
const decltype(HorizontalSyncPulseWidth)::ValueType& dgetEdidFixHorizontalSyncPulseWidth() const { return dgetInjectEDID() && HorizontalSyncPulseWidth.isDefined() ? HorizontalSyncPulseWidth.value() : HorizontalSyncPulseWidth.nullValue; };
|
|
const decltype(VideoInputSignal)::ValueType& dgetEdidFixVideoInputSignal() const { return dgetInjectEDID() && VideoInputSignal.isDefined() ? VideoInputSignal.value() : VideoInputSignal.nullValue; };
|
|
|
|
};
|
|
class XmlInjectUnion;
|
|
class Graphics_Inject_Class : public XmlDict
|
|
{
|
|
using super = XmlDict;
|
|
protected:
|
|
XmlBool Intel = XmlBool();
|
|
XmlBool ATI = XmlBool();
|
|
XmlBool NVidia = XmlBool();
|
|
|
|
XmlDictField m_fields[3] = {
|
|
{"Intel", Intel},
|
|
{"ATI", ATI},
|
|
{"NVidia", NVidia},
|
|
};
|
|
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
protected:
|
|
const decltype(Intel)::ValueType& dgetIntel() const { return Intel.isDefined() ? Intel.value() : Intel.nullValue; };
|
|
const decltype(ATI)::ValueType& dgetATI() const { return ATI.isDefined() ? ATI.value() : ATI.nullValue; };
|
|
const decltype(NVidia)::ValueType& dgetNVidia() const { return NVidia.isDefined() ? NVidia.value() : NVidia.nullValue; };
|
|
friend class XmlInjectUnion;
|
|
bool isInjectIntelDefined() const { return Intel.isDefined(); };
|
|
bool isInjectATIDefined() const { return ATI.isDefined(); };
|
|
bool isInjectNVidiaDefined() const { return NVidia.isDefined(); };
|
|
};
|
|
|
|
class XmlInjectUnion: public XmlUnion
|
|
{
|
|
protected:
|
|
XmlBool xmlBool = XmlBool();
|
|
Graphics_Inject_Class xmlDict = Graphics_Inject_Class();
|
|
XmlUnionField m_fields[2] = { xmlBool, xmlDict};
|
|
virtual void getFields(XmlUnionField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
public:
|
|
bool dgetGraphicsInjector() const {
|
|
if ( xmlBool.isDefined() ) return xmlBool.value();
|
|
return false;
|
|
}
|
|
const decltype(Graphics_Inject_Class::Intel)::ValueType& dgetInjectIntel() const { return xmlBool.isDefined() ? xmlBool.value() : xmlDict.isDefined() ? xmlDict.dgetIntel() : decltype(Graphics_Inject_Class::Intel)::nullValue; };
|
|
const decltype(Graphics_Inject_Class::ATI)::ValueType& dgetInjectATI() const { return xmlBool.isDefined() ? xmlBool.value() : xmlDict.isDefined() ? xmlDict.dgetATI() : decltype(Graphics_Inject_Class::ATI)::nullValue; };
|
|
const decltype(Graphics_Inject_Class::NVidia)::ValueType& dgetInjectNVidia() const { return xmlBool.isDefined() ? xmlBool.value() : xmlDict.isDefined() ? xmlDict.dgetNVidia() : decltype(Graphics_Inject_Class::NVidia)::nullValue; };
|
|
|
|
bool isInjectIntelDefined() const { return xmlBool.isDefined() || xmlDict.isInjectIntelDefined(); };
|
|
bool isInjectATIDefined() const { return xmlBool.isDefined() || xmlDict.isInjectATIDefined(); };
|
|
bool isInjectNVidiaDefined() const { return xmlBool.isDefined() || xmlDict.isInjectNVidiaDefined(); };
|
|
};
|
|
|
|
protected:
|
|
XmlBool PatchVBios = XmlBool();
|
|
XmlBool RadeonDeInit = XmlBool();
|
|
XmlUInt64 VRAM = XmlUInt64();
|
|
XmlUInt32 RefCLK = XmlUInt32();
|
|
XmlBool LoadVBios = XmlBool();
|
|
XmlUInt16 VideoPorts = XmlUInt16();
|
|
XmlInt8 BootDisplay = XmlInt8();
|
|
XmlString8AllowEmpty FBName = XmlString8AllowEmpty();
|
|
XmlString8AllowEmpty NVCAP = XmlString8AllowEmpty(); // It's currently an hex sequence without 0x. TODO validation. Only hex char, space and comma (see hex2bin), length < 20
|
|
XmlString8AllowEmpty displayCfg = XmlString8AllowEmpty(); // It's currently an hex sequence without 0x. TODO validation. Only hex char, space and comma, length < 8
|
|
XmlUInt32 DualLink = XmlUInt32();
|
|
XmlBool NvidiaGeneric = XmlBool();
|
|
XmlBool NvidiaNoEFI = XmlBool();
|
|
XmlBool NvidiaSingle = XmlBool();
|
|
XmlUInt32 igPlatformId = XmlUInt32();
|
|
XmlUInt32 snbPlatformId = XmlUInt32();
|
|
|
|
public:
|
|
XmlInjectUnion Inject = XmlInjectUnion();
|
|
Graphics_EDID_Class EDID = Graphics_EDID_Class();
|
|
XmlArray<Graphics_PatchVBiosBytes_Class> PatchVBiosBytesArray = XmlArray<Graphics_PatchVBiosBytes_Class>();
|
|
XmlArray<Graphics_ATI_NVIDIA_Class> ATI = XmlArray<Graphics_ATI_NVIDIA_Class>();
|
|
XmlArray<Graphics_ATI_NVIDIA_Class> NVIDIA = XmlArray<Graphics_ATI_NVIDIA_Class>();
|
|
|
|
XmlDictField m_fields[21] = {
|
|
{"PatchVBios", PatchVBios},
|
|
{"RadeonDeInit", RadeonDeInit},
|
|
{"VRAM", VRAM},
|
|
{"RefCLK", RefCLK},
|
|
{"LoadVBios", LoadVBios},
|
|
{"VideoPorts", VideoPorts},
|
|
{"BootDisplay", BootDisplay},
|
|
{"FBName", FBName},
|
|
{"NVCAP", NVCAP},
|
|
{"display-cfg", displayCfg},
|
|
{"DualLink", DualLink},
|
|
{"NvidiaGeneric", NvidiaGeneric},
|
|
{"NvidiaNoEFI", NvidiaNoEFI},
|
|
{"NvidiaSingle", NvidiaSingle},
|
|
{"ig-platform-id", igPlatformId},
|
|
{"snb-platform-id", snbPlatformId}, // TODO: validate : shpouldn't have both.
|
|
{"Inject", Inject},
|
|
{"EDID", EDID},
|
|
{"PatchVBiosBytes", PatchVBiosBytesArray},
|
|
{"ATI", ATI},
|
|
{"NVIDIA", NVIDIA},
|
|
};
|
|
|
|
Graphics_Class(const ConfigPlistClass& _configPlist) : configPlist(_configPlist) {}
|
|
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
|
|
const decltype(PatchVBios)::ValueType& dgetPatchVBios() const { return PatchVBios.isDefined() ? PatchVBios.value() : PatchVBios.nullValue; };
|
|
const decltype(PatchVBiosBytesArray)::ValueType& dgetPatchVBiosBytes() const { return PatchVBiosBytesArray.isDefined() ? PatchVBiosBytesArray.value() : PatchVBiosBytesArray.nullValue; };
|
|
const decltype(RadeonDeInit)::ValueType& dgetRadeonDeInit() const { return RadeonDeInit.isDefined() ? RadeonDeInit.value() : RadeonDeInit.nullValue; };
|
|
const decltype(VRAM)::ValueType& dgetVRAM() const { return VRAM.isDefined() ? VRAM.value() : VRAM.nullValue; };
|
|
const decltype(RefCLK)::ValueType& dgetRefCLK() const { return RefCLK.isDefined() ? RefCLK.value() : RefCLK.nullValue; };
|
|
const decltype(LoadVBios)::ValueType& dgetLoadVBios() const { return LoadVBios.isDefined() ? LoadVBios.value() : LoadVBios.nullValue; };
|
|
const decltype(VideoPorts)::ValueType& dgetVideoPorts() const { return VideoPorts.isDefined() ? VideoPorts.value() : VideoPorts.nullValue; };
|
|
int8_t dgetBootDisplay() const { return isDefined() ? BootDisplay.isDefined() ? BootDisplay.value() : -1 : 0; }; // TODO: different default value if section is not defined
|
|
const decltype(FBName)::ValueType& dgetFBName() const { return FBName.isDefined() ? FBName.value() : FBName.nullValue; };
|
|
// const decltype(displayCfg)::ValueType& dgetdisplayCfg() const { return displayCfg.isDefined() ? displayCfg.value() : displayCfg.nullValue; };
|
|
decltype(DualLink)::ValueType dgetDualLink() const { return DualLink.isDefined() ? DualLink.value() : 0xA; };
|
|
const decltype(NvidiaGeneric)::ValueType& dgetNvidiaGeneric() const { return NvidiaGeneric.isDefined() ? NvidiaGeneric.value() : NvidiaGeneric.nullValue; };
|
|
const decltype(NvidiaNoEFI)::ValueType& dgetNvidiaNoEFI() const { return NvidiaNoEFI.isDefined() ? NvidiaNoEFI.value() : NvidiaNoEFI.nullValue; };
|
|
const decltype(NvidiaSingle)::ValueType& dgetNvidiaSingle() const { return NvidiaSingle.isDefined() ? NvidiaSingle.value() : NvidiaSingle.nullValue; };
|
|
decltype(igPlatformId)::ValueType dget_IgPlatform() const {
|
|
for ( size_t idx = 0 ; idx < configPlist.Devices.Arbitrary.size() ; ++idx ) {
|
|
const ConfigPlistClass::DevicesClass::Devices_Arbitrary_Class& arbitraryProperty = configPlist.Devices.Arbitrary[idx];
|
|
for ( size_t jdx = 0 ; jdx < arbitraryProperty.CustomProperties.size() ; ++jdx ) {
|
|
const ConfigPlistClass::DevicesClass::SimplePropertyClass_Class& customProperty = arbitraryProperty.CustomProperties[jdx];
|
|
if ( customProperty.key.isDefined() && customProperty.key.value().contains("-platform-id") ) {
|
|
XBuffer<uint8_t> buf = customProperty.dgetValue();
|
|
if ( buf.size() == 0 ) return 0;
|
|
decltype(igPlatformId)::ValueType v = 0;
|
|
memcpy(&v, buf.data(), MIN(sizeof(decltype(igPlatformId)::ValueType), buf.size()));
|
|
return v;
|
|
}
|
|
}
|
|
}
|
|
if ( snbPlatformId.isDefined() ) return snbPlatformId.value();
|
|
return igPlatformId.isDefined() ? igPlatformId.value() : igPlatformId.nullValue;
|
|
};
|
|
// const decltype(snbPlatformId)::ValueType& dgetsnbPlatformId() const { return snbPlatformId.isDefined() ? snbPlatformId.value() : snbPlatformId.nullValue; };
|
|
|
|
// undefinable_bool dgetInjectAsBool() const { return Inject.isDefined() && Inject.xmlBool.isDefined() ? undefinable_bool(Inject.xmlBool.value()) : undefinable_bool(); };
|
|
const XArray<uint8_t> dgetDcfg() const {
|
|
XArray<uint8_t> xbuffer;
|
|
xbuffer.Add(0, 8);
|
|
if ( displayCfg.isDefined() ) {
|
|
hex2bin(displayCfg.value().c_str(), displayCfg.value().length(), xbuffer.data(), 8);
|
|
}else{
|
|
memcpy(xbuffer.data(), default_dcfg_0, 4);
|
|
memcpy(&xbuffer[4], default_dcfg_1, 4);
|
|
}
|
|
return xbuffer;
|
|
};
|
|
const XArray<uint8_t> dgetNVCAP() const {
|
|
XArray<uint8_t> xbuffer;
|
|
xbuffer.Add(0, 20);
|
|
if ( NVCAP.isDefined() ) {
|
|
hex2bin(NVCAP.value().c_str(), NVCAP.value().length(), xbuffer.data(), 20);
|
|
}else{
|
|
memcpy(xbuffer.data(), default_NVCAP, 20);
|
|
}
|
|
return xbuffer;
|
|
};
|
|
|
|
const decltype(NVIDIA)::ValueType& dgetNVIDIA() const { return NVIDIA.isDefined() ? NVIDIA.value() : NVIDIA.nullValue; };
|
|
|
|
};
|
|
|
|
|
|
#endif /* _CONFIGPLISTCLASS_GRAPHICS_H_ */
|