mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-11 14:28:08 +01:00
710b2dcee5
defaultMacModel member that has to be assigned before). Move BiosVersion, BiosReleaseDate and EfiVersion checks in SmbiosDictClass. Create warnings for incorrect values. Rename MaxMachineType to MaxMacModel. Remove GlobalConfig->BiosVersionUsed, ReleaseDateUsed and EfiVersionUsed.
777 lines
37 KiB
C++
Executable File
777 lines
37 KiB
C++
Executable File
/*
|
|
* ConfigPlist.h
|
|
*
|
|
* Created on: Oct 9, 2020
|
|
* Author: jief
|
|
*/
|
|
|
|
#ifndef _SMBIOSPLISTCLASS_H_
|
|
#define _SMBIOSPLISTCLASS_H_
|
|
|
|
#include "../../include/VolumeTypes.h"
|
|
#include "../../include/OSTypes.h"
|
|
#include "../../include/OSFlags.h"
|
|
#include "../../include/BootTypes.h"
|
|
#include "../../include/Languages.h"
|
|
#include "../../include/Devices.h"
|
|
#include "../../include/QuirksCodes.h"
|
|
#include "../../include/TagTypes.h"
|
|
#include "../../include/Pci.h"
|
|
#include "../../entry_scan/loader.h" // for KERNEL_SCAN_xxx constants
|
|
#include <IndustryStandard/SmBios.h> // for Smbios memory type
|
|
#include "../../Platform/guid.h"
|
|
#include "../../Platform/platformdata.h"
|
|
#include "../../Platform/smbios.h"
|
|
#include "../../Platform/VersionString.h" // for AsciiStrVersionToUint64
|
|
//#include "../cpu.h"
|
|
|
|
#include "../../cpp_lib/undefinable.h"
|
|
#include "../../cpp_lib/XmlLiteSimpleTypes.h"
|
|
#include "../../cpp_lib/XmlLiteCompositeTypes.h"
|
|
#include "../../cpp_lib/XmlLiteDictTypes.h"
|
|
#include "../../cpp_lib/XmlLiteArrayTypes.h"
|
|
#include "../../cpp_lib/XmlLiteUnionTypes.h"
|
|
#include "../../cpp_lib/XmlLiteParser.h"
|
|
|
|
#include "../../cpp_foundation/XString.h"
|
|
#include "../../cpp_foundation/XStringArray.h"
|
|
#include "../../cpp_foundation/XArray.h"
|
|
#include "../../cpp_foundation/XObjArray.h"
|
|
#include "../../Platform/Utils.h"
|
|
|
|
#include "ConfigPlistAbstract.h"
|
|
|
|
|
|
class SmbiosPlistClass : public ConfigPlistAbstractClass
|
|
{
|
|
using super = ConfigPlistAbstractClass;
|
|
public:
|
|
// #include "Config_SMBIOS.h"
|
|
|
|
|
|
class SmbiosDictClass : public XmlDict
|
|
{
|
|
using super = XmlDict;
|
|
public:
|
|
|
|
|
|
class MemoryDictClass : public XmlDict
|
|
{
|
|
using super = XmlDict;
|
|
public:
|
|
|
|
class ModuleDictClass : public XmlDict
|
|
{
|
|
using super = XmlDict;
|
|
public:
|
|
static ModuleDictClass NullValue;
|
|
|
|
class SlotIndexClass : public XmlUInt8
|
|
{
|
|
using super = XmlUInt8;
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
if ( value() >= MAX_RAM_SLOTS ) return xmlLiteParser->addWarning(generateErrors, S8Printf("Slot cannot >= MAX_RAM_SLOTS. It must a number between 0 and %d at '%s:%d'", MAX_RAM_SLOTS-1, xmlPath.c_str(), keyPos.getLine()));
|
|
return true;
|
|
}
|
|
};
|
|
class TypeClass: public XmlString8AllowEmpty {
|
|
using super = XmlString8AllowEmpty;
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
if ( isDefined() ) {
|
|
if ( xstring8.isEqualIC("DDR") ) return true;
|
|
if ( xstring8.isEqualIC("DDR2") ) return true;
|
|
if ( xstring8.isEqualIC("DDR3") ) return true;
|
|
if ( xstring8.isEqualIC("DDR4") ) return true;
|
|
}
|
|
return xmlLiteParser->addWarning(generateErrors, S8Printf("Type must be \"DDR\", \"DDR2\", \"DDR3\" or \"DDR4\" in dict '%s:%d'", xmlPath.c_str(), keyPos.getLine()));
|
|
}
|
|
public:
|
|
};
|
|
|
|
SlotIndexClass SlotIndex = SlotIndexClass();
|
|
XmlUInt32 Size = XmlUInt32();
|
|
XmlUInt32 Frequency = XmlUInt32();
|
|
XmlString8AllowEmpty Vendor = XmlString8AllowEmpty();
|
|
XmlString8AllowEmpty Part = XmlString8AllowEmpty();
|
|
XmlString8AllowEmpty Serial = XmlString8AllowEmpty();
|
|
TypeClass Type = TypeClass();
|
|
|
|
XmlDictField m_fields[7] = {
|
|
{"Slot", SlotIndex},
|
|
{"Size", Size},
|
|
{"Frequency", Frequency},
|
|
{"Vendor", Vendor},
|
|
{"Part", Part},
|
|
{"Serial", Serial},
|
|
{"Type", Type},
|
|
};
|
|
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
XBool b = true;
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) b = false;
|
|
if ( !SlotIndex.isDefined() ) b = xmlLiteParser->addWarning(generateErrors, S8Printf("Slot must be defined as a number between 0 and %d at '%s:%d'", MAX_RAM_SLOTS-1, xmlPath.c_str(), keyPos.getLine()));
|
|
if ( !Size.isDefined() ) b = xmlLiteParser->addWarning(generateErrors, S8Printf("Size must be defined at '%s:%d'", xmlPath.c_str(), keyPos.getLine()));
|
|
return b;
|
|
}
|
|
|
|
// Currently a UInt8, so value is 0..255. Careful if you change for a bigger uint type !
|
|
const decltype(SlotIndex)::ValueType& dgetSlotIndex() const { return SlotIndex.isDefined() ? SlotIndex.value() : SlotIndex.nullValue; };
|
|
const decltype(Size)::ValueType& dgetModuleSize() const { return Size.isDefined() ? Size.value() : Size.nullValue; };
|
|
const decltype(Frequency)::ValueType& dgetFrequency() const { return Frequency.isDefined() ? Frequency.value() : Frequency.nullValue; };
|
|
const decltype(Vendor)::ValueType& dgetVendor() const { return Vendor.isDefined() ? Vendor.value() : Vendor.nullValue; };
|
|
const decltype(Part)::ValueType& dgetPartNo() const { return Part.isDefined() ? Part.value() : Part.nullValue; };
|
|
const decltype(Serial)::ValueType& dgetSerialNo() const { return Serial.isDefined() ? Serial.value() : Serial.nullValue; };
|
|
UINT8 dgetType() const {
|
|
// if ( !Type.isDefined() ) return dgetModuleSize() > 0 ? MemoryTypeDdr3: 0;
|
|
if ( !Type.isDefined() ) return MemoryTypeDdr3;
|
|
if (Type.value().isEqualIC("DDR2")) {
|
|
return MemoryTypeDdr2;
|
|
} else if (Type.value().isEqualIC("DDR3")) {
|
|
return MemoryTypeDdr3;
|
|
} else if (Type.value().isEqualIC("DDR4")) {
|
|
return MemoryTypeDdr4;
|
|
} else if (Type.value().isEqualIC("DDR")) {
|
|
return MemoryTypeDdr;
|
|
}
|
|
// Cannot happen if validate has been done properly.
|
|
panic("invalid value");
|
|
}
|
|
// XBool dgetInUse() const { return Size.isDefined() ? Size.value() > 0 : false; };
|
|
|
|
};
|
|
|
|
class ModuleArrayClass : public XmlArray<ModuleDictClass>
|
|
{
|
|
using super = XmlArray<ModuleDictClass>;
|
|
public:
|
|
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
if ( size() > UINT8_MAX ) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("You cannot declare more then 256 memory modules in dict '%s:%d'", xmlPath.c_str(), keyPos.getLine()));
|
|
while ( size() > 256 ) RemoveAtIndex(size()-1);
|
|
}
|
|
|
|
for ( size_t i = 0 ; i < size() ; i++ ) {
|
|
for ( size_t j = i+1 ; j < size() ; ) {
|
|
if ( ElementAt(i).SlotIndex.value() >= ElementAt(j).SlotIndex.value() ) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("Ignore duplicate memory module for slot %d at '%s:%d'", ElementAt(i).SlotIndex.value(), xmlPath.c_str(), keyPos.getLine()));
|
|
RemoveAtIndex(j);
|
|
}else{
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
decltype(ModuleDictClass::SlotIndex)::ValueType dgetCalculatedSlotCount() const {
|
|
if ( !isDefined() ) return 0;
|
|
uint8_t max = 0;
|
|
for ( size_t idx = 0 ; idx < size() ; ++idx ) {
|
|
if ( ElementAt(idx).dgetModuleSize() > 0 ) {
|
|
if ( ElementAt(idx).dgetSlotIndex() > max ) max = ElementAt(idx).dgetSlotIndex();
|
|
}
|
|
}
|
|
return max+1;
|
|
};
|
|
|
|
const ModuleDictClass& dgetSoltAtIndex(size_t slotIndex) const {
|
|
for ( size_t idx = 0; idx < size(); ++idx ) {
|
|
if ( ElementAt(idx).dgetSlotIndex() == slotIndex )
|
|
return ElementAt(idx);
|
|
}
|
|
return ModuleDictClass::NullValue;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
XmlUInt8 SlotCount = XmlUInt8();
|
|
XmlUInt8 Channels = XmlUInt8();
|
|
ModuleArrayClass Modules = ModuleArrayClass();
|
|
|
|
XmlDictField m_fields[3] = {
|
|
{"SlotCount", SlotCount},
|
|
{"Channels", Channels},
|
|
{"Modules", Modules},
|
|
};
|
|
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
XBool b = true;
|
|
if ( Modules.size() == 0 ) {
|
|
// whatever if SlotCount is defined or not, and whatever value, it's ok.
|
|
return b;
|
|
}
|
|
if ( !SlotCount.isDefined() ) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("SlotCount is not defined in SMBIOS, but you defined memory modules. SlotCount adjusted to %d, which maybe wrong.", Modules.dgetCalculatedSlotCount())); // do not set b to false because value is auto-corrected, so it's now ok.
|
|
SlotCount.setUInt8Value(Modules.dgetCalculatedSlotCount());
|
|
}else{
|
|
for ( size_t i = 0 ; i < Modules.size() ; ) {
|
|
if ( Modules[i].SlotIndex.value() >= SlotCount.value() ) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("Ignored memory module with slot >= SlotCount at '%s:%d'", xmlPath.c_str(), keyPos.getLine())); // do not set b to false because value is auto-corrected, so it's now ok.
|
|
Modules.RemoveAtIndex(i);
|
|
}else{
|
|
i++;
|
|
}
|
|
}
|
|
if ( SlotCount.value() < Modules.dgetCalculatedSlotCount() ) {
|
|
log_technical_bug("SlotCount.value() < Modules.dgetCalculatedSlotCount()");
|
|
SlotCount.setUInt8Value(Modules.dgetCalculatedSlotCount());
|
|
}
|
|
}
|
|
return b;
|
|
}
|
|
|
|
decltype(SlotCount)::ValueType dgetSlotCount() const { return SlotCount.isDefined() ? SlotCount.value() : 0; };
|
|
const decltype(Channels)::ValueType& dgetUserChannels() const { return Channels.isDefined() ? Channels.value() : Channels.nullValue; };
|
|
|
|
// decltype(SlotCount)::ValueType dgetSlotMax() const {
|
|
// if ( !isDefined() || !Modules.isDefined() || Modules.size() == 0 ) return 0;
|
|
// uint8_t max = 0;
|
|
// for ( size_t idx = 0 ; idx < Modules.size() ; ++idx ) {
|
|
// if ( Modules[idx].dgetModuleSize() > 0 ) {
|
|
// if ( Modules[idx].dgetSlotIndex() > UINT8_MAX ) {
|
|
// log_technical_bug("Modules[idx].dgetSlotNo() > UINT8_MAX");
|
|
// }else{
|
|
// if ( Modules[idx].dgetSlotIndex() > max ) max = (uint8_t)Modules[idx].dgetSlotIndex(); // safe cast Modules[idx].dgetSlotNo() is <= UINT8_MAX
|
|
// }
|
|
// }
|
|
// }
|
|
// return max+1;
|
|
// };
|
|
//
|
|
// decltype(SlotCount)::ValueType dgetSlotCounts() const { return dgetSlotCountSetting() > dgetSlotMax() ? dgetSlotCountSetting() : dgetSlotMax(); };
|
|
|
|
};
|
|
|
|
class SlotDeviceDictClass : public XmlDict
|
|
{
|
|
using super = XmlDict;
|
|
public:
|
|
static SlotDeviceDictClass NullValue;
|
|
|
|
class DeviceClass: public XmlString8AllowEmpty {
|
|
using super = XmlString8AllowEmpty;
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
if ( isDefined() ) {
|
|
if ( xstring8.isEqualIC("ATI") ) return true;
|
|
if ( xstring8.isEqualIC("NVidia") ) return true;
|
|
if ( xstring8.isEqualIC("IntelGFX") ) return true;
|
|
if ( xstring8.isEqualIC("LAN") ) return true;
|
|
if ( xstring8.isEqualIC("WIFI") ) return true;
|
|
if ( xstring8.isEqualIC("Firewire") ) return true;
|
|
if ( xstring8.isEqualIC("HDMI") ) return true;
|
|
if ( xstring8.isEqualIC("USB") ) return true;
|
|
if ( xstring8.isEqualIC("NVME") ) return true;
|
|
}
|
|
return xmlLiteParser->addWarning(generateErrors, S8Printf("Type must be \"ATI\", \"NVidia\", \"IntelGFX\", \"LAN\", \"WIFI\", \"Firewire\", \"HDMI\", \"USB\" or \"NVME\" in dict '%s:%d'", xmlPath.c_str(), keyPos.getLine()));
|
|
}
|
|
} Device = DeviceClass();
|
|
XmlUInt8 ID = XmlUInt8();
|
|
XmlUInt8 Type = XmlUInt8();
|
|
XmlString8AllowEmpty Name = XmlString8AllowEmpty();
|
|
|
|
XmlDictField m_fields[4] = {
|
|
{"Device", Device},
|
|
{"ID", ID},
|
|
{"Type", Type},
|
|
{"Name", Name},
|
|
};
|
|
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
XBool b = true;
|
|
return b;
|
|
}
|
|
const decltype(Device)::ValueType& dgetDevice() const { return Device.isDefined() ? Device.value() : Device.nullValue; };
|
|
uint8_t dgetDeviceN() const {
|
|
// if ( !Device.isDefined() ) panic("%s: invalid value. Check validate method.", __PRETTY_FUNCTION__);
|
|
if ( !Device.isDefined() ) return 0;
|
|
if (Device.value().isEqualIC("ATI")) {
|
|
return 0;
|
|
} else if (Device.value().isEqualIC("NVidia")) {
|
|
return 1;
|
|
} else if (Device.value().isEqualIC("IntelGFX")) {
|
|
return 2;
|
|
} else if (Device.value().isEqualIC("LAN")) {
|
|
return 5;
|
|
} else if (Device.value().isEqualIC("WIFI")) {
|
|
return 6;
|
|
} else if (Device.value().isEqualIC("Firewire")) {
|
|
return 12;
|
|
} else if (Device.value().isEqualIC("HDMI")) {
|
|
return 4;
|
|
} else if (Device.value().isEqualIC("USB")) {
|
|
return 11;
|
|
} else if (Device.value().isEqualIC("NVME")) {
|
|
return 13;
|
|
} else {
|
|
panic("%s: invalid value. Check validate method.", __PRETTY_FUNCTION__);
|
|
}
|
|
}
|
|
|
|
decltype(ID)::ValueType dgetSlotID() const { return ID.isDefined() ? ID.value() : dgetDeviceN(); };
|
|
MISC_SLOT_TYPE dgetSlotType() const {
|
|
if ( !Type.isDefined() ) return Device.isDefined() ? SlotTypePci : MISC_SLOT_TYPE(0);
|
|
switch ( Type.value() ) {
|
|
case 0:
|
|
return SlotTypePci;
|
|
case 1:
|
|
return SlotTypePciExpressX1;
|
|
case 2:
|
|
return SlotTypePciExpressX2;
|
|
case 4:
|
|
return SlotTypePciExpressX4;
|
|
case 8:
|
|
return SlotTypePciExpressX8;
|
|
case 16:
|
|
return SlotTypePciExpressX16;
|
|
default:
|
|
return SlotTypePciExpress;
|
|
}
|
|
}
|
|
|
|
decltype(Name)::ValueType dgetSlotName() const { return Name.isDefined() ? Name.value() : Device.isDefined() ? S8Printf("PCI Slot %hhd", dgetDeviceN()) : NullXString8; };
|
|
|
|
};
|
|
|
|
|
|
class SlotDeviceArrayClass : public XmlArray<SlotDeviceDictClass>
|
|
{
|
|
public:
|
|
const SlotDeviceDictClass& dgetSoltDevice(INTN slotNo) const {
|
|
for ( size_t idx = 0; idx < size(); ++idx ) {
|
|
if ( ElementAt(idx).dgetDeviceN() == slotNo )
|
|
return ElementAt(idx);
|
|
}
|
|
return SlotDeviceDictClass::NullValue;
|
|
}
|
|
};
|
|
|
|
class SmUUIDClass : public XmlString8AllowEmpty
|
|
{
|
|
using super = XmlString8AllowEmpty;
|
|
protected:
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
if ( !isDefined() ) return true;
|
|
if ( !IsValidGuidString(xstring8) ) return xmlLiteParser->addWarning(generateErrors, S8Printf("Invalid SmUUID '%s' - should be in the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX in dict '%s:%d'", xstring8.c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class ProductNameClass : public XmlString8Trimed
|
|
{
|
|
using super = XmlString8Trimed;
|
|
public:
|
|
ProductNameClass() : super(true) {};
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
if ( !isDefined() ) {
|
|
xmlLiteParser->addError(generateErrors, S8Printf("You must define ProductName in SMBIOS dict, line %d", keyPos.getLine()));
|
|
return true;
|
|
}
|
|
MacModel Model;
|
|
Model = GetModelFromString(xstring8);
|
|
if ( Model == MaxMacModel ) return xmlLiteParser->addWarning(generateErrors, S8Printf("Invalid ProductName '%s' in dict '%s:%d'", xstring8.c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class BiosVersionClass : public XmlString8Trimed
|
|
{
|
|
using super = XmlString8Trimed;
|
|
public:
|
|
BiosVersionClass() : super(true) {};
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
if ( !value().contains(".") ) {
|
|
return xmlLiteParser->addWarning(generateErrors, S8Printf("BiosVersion '%s' doesn't contains a dot in dict '%s:%d'.", value().c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
}
|
|
size_t rindex = value().rindexOf(".");
|
|
if ( value().length() - rindex < 7 ) {
|
|
return xmlLiteParser->addWarning(generateErrors, S8Printf("Last part of BiosVersion '%s' must be at least 6 chars in dict '%s:%d'.", value().c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
}
|
|
// Should we check the format of these 6 last chars ?
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class BiosReleaseDateClass : public XmlString8Trimed
|
|
{
|
|
using super = XmlString8Trimed;
|
|
public:
|
|
BiosReleaseDateClass() : super(true) {};
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
if ( value().length() != 8 && value().length() != 10 ) {
|
|
return xmlLiteParser->addWarning(generateErrors, S8Printf("BiosReleaseDate '%s' must 8 or 10 chars in dict '%s:%d'.", value().c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
}
|
|
// Should we check the format of these 8 or 10 last chars ?
|
|
return true;
|
|
}
|
|
};
|
|
|
|
protected:
|
|
XmlString8Trimed BiosVendor = XmlString8Trimed(true); // true = allow empty
|
|
BiosVersionClass BiosVersion = BiosVersionClass(); // RomVersion
|
|
XmlString8AllowEmpty EfiVersion = XmlString8AllowEmpty();
|
|
BiosReleaseDateClass BiosReleaseDate = BiosReleaseDateClass();
|
|
|
|
XmlString8Trimed Manufacturer = XmlString8Trimed(true);
|
|
ProductNameClass ProductName = ProductNameClass();
|
|
XmlString8Trimed Version = XmlString8Trimed(true);
|
|
XmlString8Trimed SerialNumber = XmlString8Trimed(true);
|
|
SmUUIDClass SmUUID = SmUUIDClass();
|
|
XmlString8Trimed Family = XmlString8Trimed(true);
|
|
|
|
XmlString8Trimed BoardManufacturer = XmlString8Trimed();
|
|
XmlString8Trimed BoardSerialNumber = XmlString8Trimed();
|
|
XmlString8Trimed BoardID = XmlString8Trimed(true);
|
|
XmlString8Trimed LocationInChassis = XmlString8Trimed(true);
|
|
XmlString8Trimed BoardVersion = XmlString8Trimed(true);
|
|
XmlUInt8 BoardType = XmlUInt8();
|
|
|
|
XmlBool Mobile = XmlBool();
|
|
XmlUInt8 ChassisType = XmlUInt8();
|
|
XmlString8Trimed ChassisManufacturer = XmlString8Trimed(true);
|
|
XmlString8Trimed ChassisAssetTag = XmlString8Trimed(true);
|
|
|
|
XmlUInt16 SmbiosVersion = XmlUInt16();
|
|
XmlInt8 MemoryRank = XmlInt8(); // Attribute
|
|
|
|
XmlBool Trust = XmlBool();
|
|
XmlUInt64 PlatformFeature = XmlUInt64();
|
|
XmlBool NoRomInfo = XmlBool();
|
|
|
|
XmlUInt32 FirmwareFeatures = XmlUInt32(); // gFwFeatures
|
|
XmlUInt32 FirmwareFeaturesMask = XmlUInt32();
|
|
XmlUInt64 ExtendedFirmwareFeatures = XmlUInt64(); // gFwFeatures
|
|
XmlUInt64 ExtendedFirmwareFeaturesMask = XmlUInt64();
|
|
public:
|
|
MacModel defaultMacModel = MaxMacModel;
|
|
|
|
MemoryDictClass Memory = MemoryDictClass();
|
|
SlotDeviceArrayClass Slots = SlotDeviceArrayClass();
|
|
|
|
XmlDictField m_fields[31] = { //31
|
|
{"Trust", Trust},
|
|
{"MemoryRank", MemoryRank},
|
|
{"Memory", Memory},
|
|
{"Slots", Slots},
|
|
{"ProductName", ProductName},
|
|
{"SmbiosVersion", SmbiosVersion},
|
|
{"BiosVersion", BiosVersion},
|
|
{"BiosReleaseDate", BiosReleaseDate},
|
|
{"EfiVersion", EfiVersion},
|
|
{"FirmwareFeatures", FirmwareFeatures},
|
|
{"FirmwareFeaturesMask", FirmwareFeaturesMask},
|
|
{"ExtendedFirmwareFeatures", ExtendedFirmwareFeatures},
|
|
{"ExtendedFirmwareFeaturesMask", ExtendedFirmwareFeaturesMask},
|
|
{"PlatformFeature", PlatformFeature},
|
|
{"BiosVendor", BiosVendor},
|
|
{"Manufacturer", Manufacturer},
|
|
{"Version", Version},
|
|
{"Family", Family},
|
|
{"SerialNumber", SerialNumber},
|
|
{"SmUUID", SmUUID},
|
|
{"BoardManufacturer", BoardManufacturer},
|
|
{"BoardSerialNumber", BoardSerialNumber},
|
|
{"Board-ID", BoardID},
|
|
{"BoardVersion", BoardVersion},
|
|
{"BoardType", BoardType},
|
|
{"Mobile", Mobile},
|
|
{"LocationInChassis", LocationInChassis},
|
|
{"ChassisManufacturer", ChassisManufacturer},
|
|
{"ChassisAssetTag", ChassisAssetTag},
|
|
{"ChassisType", ChassisType},
|
|
{"NoRomInfo", NoRomInfo},
|
|
};
|
|
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
|
|
|
|
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
|
|
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
|
|
if ( !ProductName.isDefined() ) {
|
|
// return xmlLiteParser->addWarning(generateErrors, S8Printf("ProductName is not defined, the whole SMBIOS dict is ignored at line %d.", keyPos.getLine()));
|
|
if ( defaultMacModel < MaxMacModel ) {
|
|
ProductName.setStringValue(MachineModelName[defaultMacModel]);
|
|
}
|
|
}
|
|
if ( hasModel() ) {
|
|
if ( BiosVersion.isDefined() ) {
|
|
if ( !is2ndBiosVersionGreaterThan1st(ApplePlatformDataArray[getModel()].firmwareVersion, BiosVersion.value()) ) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("BiosVersion '%s' is before than default ('%s') -> ignored. Dict '%s:%d'.", BiosVersion.value().c_str(), ApplePlatformDataArray[getModel()].firmwareVersion.c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
BiosVersion.reset();
|
|
}
|
|
}
|
|
if ( BiosReleaseDate.isDefined() ) {
|
|
int compareReleaseDateResult = compareReleaseDate(GetReleaseDate(getModel()), BiosReleaseDate.value());
|
|
if ( compareReleaseDateResult == 0 ) {
|
|
// This is just 'info'. It's useless but fine to define the same as default.
|
|
xmlLiteParser->addInfo(generateErrors, S8Printf("BiosReleaseDate '%s' is the same as default ('%s') -> ignored. Dict '%s:%d'.", BiosReleaseDate.value().c_str(), GetReleaseDate(getModel()).c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
BiosReleaseDate.reset();
|
|
}else
|
|
if ( compareReleaseDateResult == 1 ) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("BiosReleaseDate '%s' is older than default ('%s') -> ignored. Dict '%s:%d'.", BiosReleaseDate.value().c_str(), GetReleaseDate(getModel()).c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
BiosReleaseDate.reset();
|
|
}
|
|
}
|
|
if ( EfiVersion.isDefined() ) {
|
|
if ( AsciiStrVersionToUint64(ApplePlatformDataArray[dgetModel()].efiversion, 4, 5) > AsciiStrVersionToUint64(EfiVersion.value(), 4, 5)) {
|
|
xmlLiteParser->addWarning(generateErrors, S8Printf("EfiVersion '%s' is older than default ('%s') -> ignored. Dict '%s:%d'.", EfiVersion.value().c_str(), ApplePlatformDataArray[dgetModel()].efiversion.c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
EfiVersion.reset();
|
|
} else if (AsciiStrVersionToUint64(ApplePlatformDataArray[dgetModel()].efiversion, 4, 5) == AsciiStrVersionToUint64(EfiVersion.value(), 4, 5)) {
|
|
xmlLiteParser->addInfo(generateErrors, S8Printf("EfiVersion '%s' is the same as default ('%s') -> ignored. Dict '%s:%d'.", EfiVersion.value().c_str(), ApplePlatformDataArray[dgetModel()].efiversion.c_str(), xmlPath.c_str(), keyPos.getLine()));
|
|
}
|
|
}
|
|
}else{
|
|
// This is supposed to never happen within Clover, because Clover initialise defaultMacModel.
|
|
// ccpv doesn't initialise defaultMacModel yet.
|
|
// If ccpv, let's say nothing at the moment
|
|
//xmlLiteParser->addInfo(generateErrors, S8Printf("Cannot check validity of BiosVersion because ProductName is not set. Dict '%s:%d'.", xmlPath.c_str(), keyPos.getLine()));
|
|
}
|
|
return true; // we don't want to invalidate the whole dict
|
|
}
|
|
|
|
|
|
|
|
const decltype(Trust)& getTrust() const { return Trust; }
|
|
const decltype(MemoryRank)& getMemoryRank() const { return MemoryRank; }
|
|
const decltype(Memory)& getMemory() const { return Memory; }
|
|
const decltype(Slots)& getSlots() const { return Slots; }
|
|
const decltype(ProductName)& getProductName() const { return ProductName; }
|
|
const decltype(SmbiosVersion)& getSmbiosVersion() const { return SmbiosVersion; }
|
|
const decltype(BiosVersion)& getBiosVersion() const { return BiosVersion; }
|
|
const decltype(BiosReleaseDate)& getBiosReleaseDate() const { return BiosReleaseDate; }
|
|
const decltype(EfiVersion)& getEfiVersion() const { return EfiVersion; }
|
|
const decltype(FirmwareFeatures)& getFirmwareFeatures() const { return FirmwareFeatures; }
|
|
const decltype(FirmwareFeaturesMask)& getFirmwareFeaturesMask() const { return FirmwareFeaturesMask; }
|
|
const decltype(ExtendedFirmwareFeatures)& getExtendedFirmwareFeatures() const { return ExtendedFirmwareFeatures; }
|
|
const decltype(ExtendedFirmwareFeaturesMask)& getExtendedFirmwareFeaturesMask() const { return ExtendedFirmwareFeaturesMask; }
|
|
const decltype(PlatformFeature)& getPlatformFeature() const { return PlatformFeature; }
|
|
const decltype(BiosVendor)& getBiosVendor() const { return BiosVendor; }
|
|
const decltype(Manufacturer)& getManufacturer() const { return Manufacturer; }
|
|
const decltype(Version)& getVersion() const { return Version; }
|
|
const decltype(Family)& getFamily() const { return Family; }
|
|
const decltype(SerialNumber)& getSerialNumber() const { return SerialNumber; }
|
|
const decltype(SmUUID)& getSmUUID() const { return SmUUID; }
|
|
const decltype(BoardManufacturer)& getBoardManufacturer() const { return BoardManufacturer; }
|
|
const decltype(BoardSerialNumber)& getBoardSerialNumber() const { return BoardSerialNumber; }
|
|
const decltype(BoardID)& getBoardID() const { return BoardID; }
|
|
const decltype(BoardVersion)& getBoardVersion() const { return BoardVersion; }
|
|
const decltype(BoardType)& getBoardType() const { return BoardType; }
|
|
const decltype(Mobile)& getMobile() const { return Mobile; }
|
|
const decltype(LocationInChassis)& getLocationInChassis() const { return LocationInChassis; }
|
|
const decltype(ChassisManufacturer)& getChassisManufacturer() const { return ChassisManufacturer; }
|
|
const decltype(ChassisAssetTag)& getChassisAssetTag() const { return ChassisAssetTag; }
|
|
const decltype(ChassisType)& getChassisType() const { return ChassisType; }
|
|
const decltype(NoRomInfo)& getNoRomInfo() const { return NoRomInfo; }
|
|
|
|
|
|
/*
|
|
* DO NOT call this if !ProductName.isDefined()
|
|
*/
|
|
MacModel getModel() const
|
|
{
|
|
if ( !ProductName.isDefined() ) {
|
|
// This must not happen in Clover because Clover set a defaultMacModel
|
|
// This must ot happen in ccpv because ccpv doesn't call dget... methods
|
|
log_technical_bug("%s : !ProductName.isDefined()", __PRETTY_FUNCTION__);
|
|
return iMac132; // cannot return GetDefaultModel() because we don't want to link runtime configuration to the xml reading layer.
|
|
}
|
|
return GetModelFromString(ProductName.value()); // ProductName has been validated, so Model CANNOT be MaxMacModel
|
|
}
|
|
XBool hasModel() const { return ProductName.isDefined(); }
|
|
|
|
MacModel dgetModel() const
|
|
{
|
|
if ( !hasModel() ) return MaxMacModel;
|
|
return getModel();
|
|
}
|
|
|
|
decltype(BiosVendor)::ValueType dgetBiosVendor() const {
|
|
if ( BiosVendor.isDefined() ) return BiosVendor.value();
|
|
return AppleBiosVendor;
|
|
};
|
|
|
|
decltype(BiosVersion)::ValueType dgetBiosVersion() const {
|
|
if ( BiosVersion.isDefined() ) return BiosVersion.value();
|
|
return ApplePlatformDataArray[dgetModel()].firmwareVersion;
|
|
};
|
|
|
|
decltype(EfiVersion)::ValueType dgetEfiVersion() const {
|
|
if ( !EfiVersion.isDefined() ) return ApplePlatformDataArray[dgetModel()].efiversion;
|
|
XString8 returnValue;
|
|
returnValue = EfiVersion.value();
|
|
returnValue.trim();
|
|
return returnValue;
|
|
}
|
|
|
|
decltype(BiosReleaseDate)::ValueType dgetBiosReleaseDate() const
|
|
{
|
|
if ( BiosReleaseDate.isDefined() ) return BiosReleaseDate.value();
|
|
XString8 dBiosVersion = dgetBiosVersion();
|
|
XString8 returnValue;
|
|
if ( dBiosVersion.notEmpty() ) {
|
|
if ( !dBiosVersion.contains(".") ) {
|
|
log_technical_bug("!dBiosVersion.contains(\".\")"); // Must not happen, BiosVersion has been validated to have a '.' followed by 6 chars.
|
|
return NullXString8;
|
|
}
|
|
const char* i = dBiosVersion.c_str();
|
|
i += AsciiStrLen(i);
|
|
while ( *i != '.' ) i--;
|
|
if ( strlen(i) < 7 ) {
|
|
log_technical_bug("strlen(i) < 7"); // Must not happen, BiosVersion has been validated to have a '.' followed by 6 chars.
|
|
return NullXString8;
|
|
}
|
|
if ( isReleaseDateWithYear20(dgetModel()) ) {
|
|
returnValue.S8Printf("%c%c/%c%c/20%c%c", i[3], i[4], i[5], i[6], i[1], i[2]);
|
|
}else{
|
|
returnValue.S8Printf("%c%c/%c%c/%c%c", i[3], i[4], i[5], i[6], i[1], i[2]);
|
|
}
|
|
}
|
|
return returnValue;
|
|
}
|
|
|
|
decltype(Manufacturer)::ValueType dgetManufactureName() const {
|
|
if ( Manufacturer.isDefined() ) return Manufacturer.value();
|
|
return AppleBiosVendor;
|
|
};
|
|
|
|
const decltype(ProductName)::ValueType& dgetProductName() const { return ProductName.isDefined() ? ProductName.value() : ProductName.nullValue; };
|
|
|
|
decltype(Version)::ValueType dgetSystemVersion() const {
|
|
if ( Version.isDefined() ) return Version.value();
|
|
return ApplePlatformDataArray[dgetModel()].systemVersion;
|
|
};
|
|
|
|
const decltype(SerialNumber)::ValueType dgetSerialNr() const {
|
|
if ( SerialNumber.isDefined() ) return SerialNumber.value();
|
|
return ApplePlatformDataArray[dgetModel()].serialNumber;
|
|
};
|
|
|
|
decltype(SmUUID)::ValueType dgetSmUUID() const { return SmUUID.isDefined() ? SmUUID.value() : nullGuidAsString; };
|
|
|
|
decltype(Family)::ValueType dgetFamilyName() const {
|
|
if ( Family.isDefined() ) return Family.value();
|
|
return ApplePlatformDataArray[dgetModel()].productFamily;
|
|
};
|
|
|
|
decltype(BoardManufacturer)::ValueType dgetBoardManufactureName() const {
|
|
if ( BoardManufacturer.isDefined() ) return BoardManufacturer.value();
|
|
return dgetBiosVendor();
|
|
|
|
};
|
|
|
|
decltype(BoardSerialNumber)::ValueType dgetBoardSerialNumber() const {
|
|
if ( BoardSerialNumber.isDefined() ) return BoardSerialNumber.value();
|
|
return AppleBoardSN;
|
|
};
|
|
|
|
decltype(BoardID)::ValueType dgetBoardNumber() const {
|
|
if ( BoardID.isDefined() ) return BoardID.value();
|
|
return ApplePlatformDataArray[dgetModel()].boardID;
|
|
};
|
|
|
|
decltype(LocationInChassis)::ValueType dgetLocationInChassis() const {
|
|
if ( LocationInChassis.isDefined() ) return LocationInChassis.value();
|
|
return AppleBoardLocation;
|
|
};
|
|
|
|
decltype(BoardVersion)::ValueType dgetBoardVersion() const {
|
|
return BoardVersion.isDefined() ? BoardVersion.value() : dgetProductName();
|
|
};
|
|
|
|
decltype(BoardType)::ValueType dgetBoardType() const {
|
|
if ( BoardType.isDefined() ) return BoardType.value();
|
|
MacModel Model = dgetModel();
|
|
if ((Model > MacPro31) && (Model < MacPro71)) {
|
|
return BaseBoardTypeProcessorMemoryModule; //0xB;
|
|
} else {
|
|
return BaseBoardTypeMotherBoard; //0xA;
|
|
}
|
|
};
|
|
|
|
decltype(Mobile)::ValueType dgetMobile() const {
|
|
if ( Mobile.isDefined() ) return Mobile.value();
|
|
return GetMobile(dgetModel());
|
|
};
|
|
|
|
decltype(ChassisType)::ValueType dgetChassisType() const {
|
|
if ( ChassisType.isDefined() ) return ChassisType.value();
|
|
return GetChassisTypeFromModel(dgetModel());
|
|
};
|
|
|
|
decltype(ChassisManufacturer)::ValueType dgetChassisManufacturer() const {
|
|
if ( ChassisManufacturer.isDefined() ) return ChassisManufacturer.value();
|
|
return dgetBiosVendor();
|
|
};
|
|
|
|
decltype(ChassisAssetTag)::ValueType dgetChassisAssetTag() const {
|
|
if ( ChassisAssetTag.isDefined() ) return ChassisAssetTag.value();
|
|
return ApplePlatformDataArray[dgetModel()].chassisAsset;
|
|
};
|
|
|
|
decltype(SmbiosVersion)::ValueType dgetSmbiosVersion() const { return SmbiosVersion.isDefined() ? SmbiosVersion.value() : 0x204; };
|
|
decltype(MemoryRank)::ValueType dgetAttribute() const { return MemoryRank.isDefined() ? MemoryRank.value() : -1; };
|
|
decltype(Trust)::ValueType dgetTrustSMBIOS() const { return Trust.isDefined() ? Trust.value() : XBool(true); };
|
|
XBool dgetInjectMemoryTables() const { return Memory.Modules.isDefined() && Memory.Modules.size() > 0 ? Memory.dgetSlotCount() > 0 : false; };
|
|
decltype(PlatformFeature)::ValueType dgetgPlatformFeature() const {
|
|
if ( PlatformFeature.isDefined() ) return PlatformFeature.value();
|
|
return GetPlatformFeature(dgetModel());
|
|
};
|
|
const decltype(NoRomInfo)::ValueType& dgetNoRomInfo() const { return NoRomInfo.isDefined() ? NoRomInfo.value() : NoRomInfo.nullValue; };
|
|
decltype(FirmwareFeatures)::ValueType dgetFirmwareFeatures() const {
|
|
if ( FirmwareFeatures.isDefined() ) return FirmwareFeatures.value();
|
|
return GetFwFeatures(dgetModel());
|
|
};
|
|
decltype(FirmwareFeaturesMask)::ValueType dgetFirmwareFeaturesMask() const {
|
|
if ( FirmwareFeaturesMask.isDefined() ) return FirmwareFeaturesMask.value();
|
|
return GetFwFeaturesMaskFromModel(dgetModel());
|
|
};
|
|
decltype(ExtendedFirmwareFeatures)::ValueType dgetExtendedFirmwareFeatures() const {
|
|
if ( ExtendedFirmwareFeatures.isDefined() ) return ExtendedFirmwareFeatures.value();
|
|
return GetExtFwFeatures(dgetModel());
|
|
};
|
|
decltype(ExtendedFirmwareFeaturesMask)::ValueType dgetExtendedFirmwareFeaturesMask() const {
|
|
if ( ExtendedFirmwareFeaturesMask.isDefined() ) return ExtendedFirmwareFeaturesMask.value();
|
|
return GetExtFwFeaturesMask(dgetModel());
|
|
}
|
|
|
|
};
|
|
|
|
SmbiosDictClass SMBIOS = SmbiosDictClass();
|
|
|
|
XmlDictField m_fields[1] = {
|
|
{"SMBIOS", SMBIOS},
|
|
};
|
|
|
|
public:
|
|
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); };
|
|
|
|
public:
|
|
SmbiosPlistClass() {};
|
|
|
|
};
|
|
|
|
|
|
//extern const ConfigPlist& configPlist;
|
|
//extern const ConfigPlist& getConfigPlist();
|
|
|
|
#endif /* _SMBIOSPLISTCLASS_H_ */
|