Merge branch 'CloverHackyColor:master' into master

This commit is contained in:
LAbyOne 2021-10-03 13:39:17 +02:00 committed by GitHub
commit 5733bd9ff8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 642 additions and 388 deletions

View File

@ -12,7 +12,7 @@
#include "../../../PosixCompilation/xcode_utf_fixed.h" #include "../../../PosixCompilation/xcode_utf_fixed.h"
#include "../../../rEFIt_UEFI/cpp_unit_test/all_tests.h" #include "../../../rEFIt_UEFI/cpp_unit_test/all_tests.h"
#include "../../../rEFIt_UEFI/cpp_foundation/XToolsCommon.h"
//class Boolean //class Boolean
//{ //{
// bool flag; // bool flag;
@ -49,6 +49,8 @@ extern "C" int main(int argc, const char * argv[])
// b = (char*)NULL; // b = (char*)NULL;
// b = (float)1.0; // b = (float)1.0;
// b = i; // b = i;
printf("%d", numeric_limits<int>::min());
printf("%d", numeric_limits<int>::min());
return all_tests() ? 0 : -1 ; return all_tests() ? 0 : -1 ;
} }

View File

@ -2356,14 +2356,13 @@ printf("%s", "");
class RamSlotInfo { class RamSlotInfo {
public: public:
UINT64 Slot = UINT64(); UINT64 SlotIndex = UINT64();
UINT32 ModuleSize = UINT32(); UINT32 ModuleSize = UINT32();
UINT32 Frequency = UINT32(); UINT32 Frequency = UINT32();
XString8 Vendor = XString8(); XString8 Vendor = XString8();
XString8 PartNo = XString8(); XString8 PartNo = XString8();
XString8 SerialNo = XString8(); XString8 SerialNo = XString8();
UINT8 Type = UINT8(); UINT8 Type = UINT8();
XBool InUse = XBool();
RamSlotInfo() {} RamSlotInfo() {}
@ -2372,33 +2371,31 @@ printf("%s", "");
#endif #endif
XBool isEqual(const RamSlotInfo& other) const XBool isEqual(const RamSlotInfo& other) const
{ {
if ( !(Slot == other.Slot ) ) return false; if ( !(SlotIndex == other.SlotIndex ) ) return false;
if ( !(ModuleSize == other.ModuleSize ) ) return false; if ( !(ModuleSize == other.ModuleSize ) ) return false;
if ( !(Frequency == other.Frequency ) ) return false; if ( !(Frequency == other.Frequency ) ) return false;
if ( !(Vendor == other.Vendor ) ) return false; if ( !(Vendor == other.Vendor ) ) return false;
if ( !(PartNo == other.PartNo ) ) return false; if ( !(PartNo == other.PartNo ) ) return false;
if ( !(SerialNo == other.SerialNo ) ) return false; if ( !(SerialNo == other.SerialNo ) ) return false;
if ( !(Type == other.Type ) ) return false; if ( !(Type == other.Type ) ) return false;
if ( !(InUse == other.InUse ) ) return false;
return true; return true;
} }
XBool takeValueFrom(const SmbiosPlistClass::SmbiosDictClass::MemoryDictClass::ModuleDictClass& other) XBool takeValueFrom(const SmbiosPlistClass::SmbiosDictClass::MemoryDictClass::ModuleDictClass& other)
{ {
Slot = other.dgetSlotNo(); SlotIndex = other.dgetSlotIndex();
ModuleSize = other.dgetModuleSize(); ModuleSize = other.dgetModuleSize();
Frequency = other.dgetFrequency(); Frequency = other.dgetFrequency();
Vendor = other.dgetVendor(); Vendor = other.dgetVendor();
PartNo = other.dgetPartNo(); PartNo = other.dgetPartNo();
SerialNo = other.dgetSerialNo(); SerialNo = other.dgetSerialNo();
Type = other.dgetType(); Type = other.dgetType();
InUse = other.dgetInUse();
return true; return true;
} }
}; };
class RamSlotInfoArrayClass { class RamSlotInfoArrayClass {
public: public:
UINT8 SlotCounts = UINT8(); UINT8 SlotCount = UINT8();
UINT8 UserChannels = UINT8(); UINT8 UserChannels = UINT8();
XObjArrayWithTakeValueFromXmlArray<RamSlotInfo, SmbiosPlistClass::SmbiosDictClass::MemoryDictClass::ModuleDictClass> User = XObjArrayWithTakeValueFromXmlArray<RamSlotInfo, SmbiosPlistClass::SmbiosDictClass::MemoryDictClass::ModuleDictClass>(); XObjArrayWithTakeValueFromXmlArray<RamSlotInfo, SmbiosPlistClass::SmbiosDictClass::MemoryDictClass::ModuleDictClass> User = XObjArrayWithTakeValueFromXmlArray<RamSlotInfo, SmbiosPlistClass::SmbiosDictClass::MemoryDictClass::ModuleDictClass>();
@ -2409,14 +2406,14 @@ printf("%s", "");
#endif #endif
XBool isEqual(const RamSlotInfoArrayClass& other) const XBool isEqual(const RamSlotInfoArrayClass& other) const
{ {
if ( !(SlotCounts == other.SlotCounts) ) return false; if ( !(SlotCount == other.SlotCount) ) return false;
if ( !(UserChannels == other.UserChannels) ) return false; if ( !(UserChannels == other.UserChannels) ) return false;
if ( !(User.isEqual(other.User)) ) return false; if ( !(User.isEqual(other.User)) ) return false;
return true; return true;
} }
void takeValueFrom(const SmbiosPlistClass::SmbiosDictClass::MemoryDictClass& configPlist) void takeValueFrom(const SmbiosPlistClass::SmbiosDictClass::MemoryDictClass& configPlist)
{ {
SlotCounts = configPlist.dgetSlotCounts(); SlotCount = configPlist.dgetSlotCount();
UserChannels = configPlist.dgetUserChannels(); UserChannels = configPlist.dgetUserChannels();
User.takeValueFrom(configPlist.Modules); User.takeValueFrom(configPlist.Modules);
} }

View File

@ -39,14 +39,13 @@ static void SmbiosFillPatchingValues(const SETTINGS_DATA::SmbiosClass::RamSlotIn
{ {
RAM_SLOT_INFO& ramSlotInfo = *ramSlotInfoPtr; RAM_SLOT_INFO& ramSlotInfo = *ramSlotInfoPtr;
ramSlotInfo.Slot = other.Slot; ramSlotInfo.SlotIndex = other.SlotIndex;
ramSlotInfo.ModuleSize = other.ModuleSize; ramSlotInfo.ModuleSize = other.ModuleSize;
ramSlotInfo.Frequency = other.Frequency; ramSlotInfo.Frequency = other.Frequency;
ramSlotInfo.Vendor = other.Vendor; ramSlotInfo.Vendor = other.Vendor;
ramSlotInfo.PartNo = other.PartNo; ramSlotInfo.PartNo = other.PartNo;
ramSlotInfo.SerialNo = other.SerialNo; ramSlotInfo.SerialNo = other.SerialNo;
ramSlotInfo.Type = other.Type; ramSlotInfo.Type = other.Type;
ramSlotInfo.InUse = other.InUse;
} }
static void SmbiosFillPatchingValues(const XObjArray<SETTINGS_DATA::SmbiosClass::RamSlotInfo>& settingRamSlotInfoArray, XObjArray<RAM_SLOT_INFO>* ramSlotInfoArrayPtr) static void SmbiosFillPatchingValues(const XObjArray<SETTINGS_DATA::SmbiosClass::RamSlotInfo>& settingRamSlotInfoArray, XObjArray<RAM_SLOT_INFO>* ramSlotInfoArrayPtr)
@ -65,7 +64,7 @@ static void SmbiosFillPatchingValues(const SETTINGS_DATA::SmbiosClass::RamSlotIn
{ {
SmbiosMemoryConfigurationClass& Memory = *MemoryPtr; SmbiosMemoryConfigurationClass& Memory = *MemoryPtr;
Memory.SlotCounts = other.SlotCounts; Memory.SlotCount = other.SlotCount;
Memory.UserChannels = other.UserChannels; Memory.UserChannels = other.UserChannels;
SmbiosFillPatchingValues(other.User, &Memory._User); SmbiosFillPatchingValues(other.User, &Memory._User);
} }
@ -144,7 +143,12 @@ void SmbiosFillPatchingValues(XBool _SetTable132, uint8_t pEnabledCores, uint16_
smbiosInjectedSetting.SetTable132 = _SetTable132; smbiosInjectedSetting.SetTable132 = _SetTable132;
smbiosInjectedSetting.QPI = globalSettings.CPU.QPI; smbiosInjectedSetting.QPI = globalSettings.CPU.QPI;
smbiosInjectedSetting.RamSlotCount = pRamSlotCount; // If globalSettings.Smbios.RamSlotInfoArray.SlotCount is defined, the user wants to override
if ( globalSettings.Smbios.RamSlotInfoArray.SlotCount > 0 ) {
smbiosInjectedSetting.RamSlotCount = globalSettings.Smbios.RamSlotInfoArray.SlotCount;
}else{
smbiosInjectedSetting.RamSlotCount = pRamSlotCount;
}
} }

View File

@ -89,11 +89,10 @@ UINT32 mTotalSystemMemory;
UINT64 gTotalMemory; UINT64 gTotalMemory;
UINT16 mHandle3; UINT16 mHandle3;
UINT16 mHandle16 = 0x1000; UINT16 mHandle16 = 0x1000;
UINT16 mHandle17[MAX_RAM_SLOTS]; //UINT16 mHandle17[MAX_RAM_SLOTS];
UINT16 mHandle19; UINT16 mHandle19;
UINT16 mMemory17[MAX_RAM_SLOTS]; //UINT64 mInstalled[MAX_RAM_SLOTS];
UINT64 mInstalled[MAX_RAM_SLOTS]; //UINT64 mEnabled[MAX_RAM_SLOTS];
UINT64 mEnabled[MAX_RAM_SLOTS];
XBool gMobile; XBool gMobile;
UINT8 gBootStatus; UINT8 gBootStatus;
XBool Once; XBool Once;
@ -965,35 +964,35 @@ void PatchTableType4(const SmbiosInjectedSettings& smbiosSettings)
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type4->SerialNumber, BrandStr); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type4->SerialNumber, BrandStr);
} }
#ifdef JIEF_DEBUG //#ifdef JIEF_DEBUG
DBG("newSmbiosTable.Type4->AssetTag=%d\n", newSmbiosTable.Type4->AssetTag); //DBG("newSmbiosTable.Type4->AssetTag=%d\n", newSmbiosTable.Type4->AssetTag);
DBG("newSmbiosTable.Type4->CoreCount=%d\n", newSmbiosTable.Type4->CoreCount); //DBG("newSmbiosTable.Type4->CoreCount=%d\n", newSmbiosTable.Type4->CoreCount);
DBG("newSmbiosTable.Type4->CoreCount2=%d\n", newSmbiosTable.Type4->CoreCount2); //DBG("newSmbiosTable.Type4->CoreCount2=%d\n", newSmbiosTable.Type4->CoreCount2);
DBG("newSmbiosTable.Type4->CurrentSpeed=%d\n", newSmbiosTable.Type4->CurrentSpeed); //DBG("newSmbiosTable.Type4->CurrentSpeed=%d\n", newSmbiosTable.Type4->CurrentSpeed);
DBG("newSmbiosTable.Type4->EnabledCoreCount=%d\n", newSmbiosTable.Type4->EnabledCoreCount); //DBG("newSmbiosTable.Type4->EnabledCoreCount=%d\n", newSmbiosTable.Type4->EnabledCoreCount);
DBG("newSmbiosTable.Type4->EnabledCoreCount2=%d\n", newSmbiosTable.Type4->EnabledCoreCount2); //DBG("newSmbiosTable.Type4->EnabledCoreCount2=%d\n", newSmbiosTable.Type4->EnabledCoreCount2);
DBG("newSmbiosTable.Type4->ExternalClock=%d\n", newSmbiosTable.Type4->ExternalClock); //DBG("newSmbiosTable.Type4->ExternalClock=%d\n", newSmbiosTable.Type4->ExternalClock);
DBG("newSmbiosTable.Type4->L1CacheHandle=%d\n", newSmbiosTable.Type4->L1CacheHandle); //DBG("newSmbiosTable.Type4->L1CacheHandle=%d\n", newSmbiosTable.Type4->L1CacheHandle);
DBG("newSmbiosTable.Type4->L2CacheHandle=%d\n", newSmbiosTable.Type4->L2CacheHandle); //DBG("newSmbiosTable.Type4->L2CacheHandle=%d\n", newSmbiosTable.Type4->L2CacheHandle);
DBG("newSmbiosTable.Type4->L3CacheHandle=%d\n", newSmbiosTable.Type4->L3CacheHandle); //DBG("newSmbiosTable.Type4->L3CacheHandle=%d\n", newSmbiosTable.Type4->L3CacheHandle);
DBG("newSmbiosTable.Type4->MaxSpeed=%d\n", newSmbiosTable.Type4->MaxSpeed); //DBG("newSmbiosTable.Type4->MaxSpeed=%d\n", newSmbiosTable.Type4->MaxSpeed);
DBG("newSmbiosTable.Type4->PartNumber=%d\n", newSmbiosTable.Type4->PartNumber); //DBG("newSmbiosTable.Type4->PartNumber=%d\n", newSmbiosTable.Type4->PartNumber);
DBG("newSmbiosTable.Type4->ProcessorCharacteristics=%d\n", newSmbiosTable.Type4->ProcessorCharacteristics); //DBG("newSmbiosTable.Type4->ProcessorCharacteristics=%d\n", newSmbiosTable.Type4->ProcessorCharacteristics);
DBG("newSmbiosTable.Type4->ProcessorFamily=%d\n", newSmbiosTable.Type4->ProcessorFamily); //DBG("newSmbiosTable.Type4->ProcessorFamily=%d\n", newSmbiosTable.Type4->ProcessorFamily);
DBG("newSmbiosTable.Type4->ProcessorFamily2=%d\n", newSmbiosTable.Type4->ProcessorFamily2); //DBG("newSmbiosTable.Type4->ProcessorFamily2=%d\n", newSmbiosTable.Type4->ProcessorFamily2);
DBG("newSmbiosTable.Type4->ProcessorId.FeatureFlags=%d\n", *(UINT32*)&newSmbiosTable.Type4->ProcessorId.FeatureFlags); //DBG("newSmbiosTable.Type4->ProcessorId.FeatureFlags=%d\n", *(UINT32*)&newSmbiosTable.Type4->ProcessorId.FeatureFlags);
DBG("newSmbiosTable.Type4->ProcessorId.Signatur=%d\n", *(UINT32*)&newSmbiosTable.Type4->ProcessorId.Signature); //DBG("newSmbiosTable.Type4->ProcessorId.Signatur=%d\n", *(UINT32*)&newSmbiosTable.Type4->ProcessorId.Signature);
DBG("newSmbiosTable.Type4->ProcessorManufacturer=%d\n", newSmbiosTable.Type4->ProcessorManufacturer); //DBG("newSmbiosTable.Type4->ProcessorManufacturer=%d\n", newSmbiosTable.Type4->ProcessorManufacturer);
DBG("newSmbiosTable.Type4->ProcessorType=%d\n", newSmbiosTable.Type4->ProcessorType); //DBG("newSmbiosTable.Type4->ProcessorType=%d\n", newSmbiosTable.Type4->ProcessorType);
DBG("newSmbiosTable.Type4->ProcessorUpgrade=%d\n", newSmbiosTable.Type4->ProcessorUpgrade); //DBG("newSmbiosTable.Type4->ProcessorUpgrade=%d\n", newSmbiosTable.Type4->ProcessorUpgrade);
DBG("newSmbiosTable.Type4->ProcessorVersion=%d\n", newSmbiosTable.Type4->ProcessorVersion); //DBG("newSmbiosTable.Type4->ProcessorVersion=%d\n", newSmbiosTable.Type4->ProcessorVersion);
DBG("newSmbiosTable.Type4->SerialNumber=%d\n", newSmbiosTable.Type4->SerialNumber); //DBG("newSmbiosTable.Type4->SerialNumber=%d\n", newSmbiosTable.Type4->SerialNumber);
DBG("newSmbiosTable.Type4->Socket=%d\n", newSmbiosTable.Type4->Socket); //DBG("newSmbiosTable.Type4->Socket=%d\n", newSmbiosTable.Type4->Socket);
DBG("newSmbiosTable.Type4->Status=%d\n", newSmbiosTable.Type4->Status); //DBG("newSmbiosTable.Type4->Status=%d\n", newSmbiosTable.Type4->Status);
DBG("newSmbiosTable.Type4->ThreadCount=%d\n", newSmbiosTable.Type4->ThreadCount); //DBG("newSmbiosTable.Type4->ThreadCount=%d\n", newSmbiosTable.Type4->ThreadCount);
DBG("newSmbiosTable.Type4->ThreadCount2=%d\n", newSmbiosTable.Type4->ThreadCount2); //DBG("newSmbiosTable.Type4->ThreadCount2=%d\n", newSmbiosTable.Type4->ThreadCount2);
DBG("newSmbiosTable.Type4->Voltage=%d\n", *(UINT8*)&newSmbiosTable.Type4->Voltage); //DBG("newSmbiosTable.Type4->Voltage=%d\n", *(UINT8*)&newSmbiosTable.Type4->Voltage);
#endif //#endif
Handle = LogSmbiosTable(newSmbiosTable); Handle = LogSmbiosTable(newSmbiosTable);
} }
@ -1016,18 +1015,22 @@ void PatchTableType6(const SmbiosInjectedSettings& smbiosSettings)
continue; continue;
} }
SizeField = SmbiosTable.Type6->InstalledSize.InstalledOrEnabledSize & 0x7F; SizeField = SmbiosTable.Type6->InstalledSize.InstalledOrEnabledSize & 0x7F;
UINT64 mInstalled = 0;
if (SizeField < 0x7D) { if (SizeField < 0x7D) {
mInstalled[Index] = LShiftU64(1ULL, 20 + SizeField); mInstalled = LShiftU64(1ULL, 20 + SizeField);
} else if (SizeField == 0x7F) { } else if (SizeField == 0x7F) {
mInstalled[Index] = 0; mInstalled = 0;
} else } else {
mInstalled[Index] = 4096ULL * (1024ULL * 1024ULL); mInstalled = 4096ULL * (1024ULL * 1024ULL);
MsgLog("Table 6 MEMORY_MODULE %zu Installed %llX ", Index, mInstalled[Index]); }
MsgLog("Table 6 MEMORY_MODULE %zu Installed %llX ", Index, mInstalled);
UINT64 mEnabled = 0;
if (SizeField >= 0x7D) { if (SizeField >= 0x7D) {
mEnabled[Index] = 0; mEnabled = 0;
} else } else {
mEnabled[Index] = LShiftU64(1ULL, 20 + ((UINT8)SmbiosTable.Type6->EnabledSize.InstalledOrEnabledSize & 0x7F)); mEnabled = LShiftU64(1ULL, 20 + ((UINT8)SmbiosTable.Type6->EnabledSize.InstalledOrEnabledSize & 0x7F));
MsgLog("... enabled %llX \n", mEnabled[Index]); }
MsgLog("... enabled %llX \n", mEnabled);
LogSmbiosTable(SmbiosTable); LogSmbiosTable(SmbiosTable);
} }
@ -1115,17 +1118,17 @@ void PatchTableType9(const SmbiosInjectedSettings& smbiosSettings)
// SlotType = 32bit PCI/SlotTypePciExpressX1/x4/x16 // SlotType = 32bit PCI/SlotTypePciExpressX1/x4/x16
// real PC -> PCI, real Mac -> PCIe // real PC -> PCI, real Mac -> PCIe
#ifdef JIEF_DEBUG //#ifdef JIEF_DEBUG
for (uint8_t Index = 0; Index <= 15; Index++) { // for (uint8_t Index = 0; Index <= 15; Index++) {
DBG("SlotDevice[%hhu].BusNum = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).BusNum); // DBG("SlotDevice[%hhu].BusNum = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).BusNum);
DBG("SlotDevice[%hhu].DevFuncNum = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).DevFuncNum); // DBG("SlotDevice[%hhu].DevFuncNum = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).DevFuncNum);
DBG("SlotDevice[%hhu].SegmentGroupNum = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SegmentGroupNum); // DBG("SlotDevice[%hhu].SegmentGroupNum = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SegmentGroupNum);
DBG("SlotDevice[%hhu].SlotID = %hhd\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotID); // DBG("SlotDevice[%hhu].SlotID = %hhd\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotID);
DBG("SlotDevice[%hhu].SlotType = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotType); // DBG("SlotDevice[%hhu].SlotType = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotType);
DBG("SlotDevice[%hhu].SlotName = %s\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotName.c_str()); // DBG("SlotDevice[%hhu].SlotName = %s\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotName.c_str());
DBG("SlotDevice[%hhu].Valid = %d\n", Index, (bool)smbiosSettings.SlotDevices.isSlotForIndexValid(Index)); // DBG("SlotDevice[%hhu].Valid = %d\n", Index, (bool)smbiosSettings.SlotDevices.isSlotForIndexValid(Index));
} // }
#endif //#endif
for (uint8_t Index = 0; Index < 15; Index++) { for (uint8_t Index = 0; Index < 15; Index++) {
if (smbiosSettings.SlotDevices.isSlotForIndexValid(Index)) { if (smbiosSettings.SlotDevices.isSlotForIndexValid(Index)) {
@ -1228,6 +1231,17 @@ void GetTableType16(SmbiosDiscoveredSettings* smbiosSettings)
continue; continue;
} }
DBG("Type 16 Index = %zu\n", Index); DBG("Type 16 Index = %zu\n", Index);
if ( SmbiosTable.Type16->NumberOfMemoryDevices > numeric_limits<decltype(smbiosSettings->RamSlotCount)>::max() ) {
DBG("SmbiosTable.Type16->NumberOfMemoryDevices report too many devices (%d). Maxing out smbiosSettings->RamSlotCount to %d.\n", SmbiosTable.Type16->NumberOfMemoryDevices, MAX_RAM_SLOTS);
smbiosSettings->RamSlotCount = MAX_RAM_SLOTS;
break;
}
if ( SmbiosTable.Type16->NumberOfMemoryDevices > numeric_limits<decltype(smbiosSettings->RamSlotCount)>::max() - smbiosSettings->RamSlotCount ) {
DBG("smbiosSettings->RamSlotCount(%d) + SmbiosTable.Type16->NumberOfMemoryDevices(%d) is too many devices. Maxing out smbiosSettings->RamSlotCount to %d.\n", smbiosSettings->RamSlotCount, SmbiosTable.Type16->NumberOfMemoryDevices, MAX_RAM_SLOTS);
smbiosSettings->RamSlotCount = MAX_RAM_SLOTS;
break;
}
smbiosSettings->RamSlotCount += SmbiosTable.Type16->NumberOfMemoryDevices; smbiosSettings->RamSlotCount += SmbiosTable.Type16->NumberOfMemoryDevices;
} }
if ( smbiosSettings->RamSlotCount == 0 ) { if ( smbiosSettings->RamSlotCount == 0 ) {
@ -1266,16 +1280,47 @@ void PatchTableType16(const SmbiosInjectedSettings& smbiosSettings)
// newSmbiosTable.Type16->MemoryErrorCorrection = MemoryErrorCorrectionMultiBitEcc; // newSmbiosTable.Type16->MemoryErrorCorrection = MemoryErrorCorrectionMultiBitEcc;
// MemoryErrorInformationHandle // MemoryErrorInformationHandle
newSmbiosTable.Type16->MemoryErrorInformationHandle = 0xFFFF; newSmbiosTable.Type16->MemoryErrorInformationHandle = 0xFFFF;
newSmbiosTable.Type16->NumberOfMemoryDevices = MIN(smbiosSettings.RamSlotCount, MAX_RAM_SLOTS); newSmbiosTable.Type16->NumberOfMemoryDevices = smbiosSettings.RamSlotCount; // RamSlotCount is <= MAX_RAM_SLOTS), see GetTableType16()
DBG("NumberOfMemoryDevices = %d\n", MIN(smbiosSettings.RamSlotCount, MAX_RAM_SLOTS)); DBG("NumberOfMemoryDevices = %d\n", smbiosSettings.RamSlotCount);
LogSmbiosTable(newSmbiosTable); LogSmbiosTable(newSmbiosTable);
} }
void GetTableType17(SmbiosDiscoveredSettings* smbiosSettings) void GetTableType17(SmbiosDiscoveredSettings* smbiosSettings)
{ {
//#ifdef JIEF_DEBUG
//{
// RAM_SLOT_INFO* rsiPtr = NULL;
// rsiPtr = new RAM_SLOT_INFO;
// RAM_SLOT_INFO& rsi = *rsiPtr;
// rsi.Frequency = 2587;
// rsi.ModuleSize = 8192;
// rsi.PartNo.takeValueFrom("M393A1K43BB1-CTD");
// rsi.SerialNo.takeValueFrom("24B63C90");
// rsi.SlotIndex = 0;
// rsi.Type = 17;
// rsi.Vendor.takeValueFrom("Samsung");
// gRAM.SMBIOS.AddReference(rsiPtr, true);
//}
//{
// RAM_SLOT_INFO* rsiPtr = NULL;
// rsiPtr = new RAM_SLOT_INFO;
// RAM_SLOT_INFO& rsi = *rsiPtr;
// rsi.Frequency = 2587;
// rsi.ModuleSize = 8192;
// rsi.PartNo.takeValueFrom("M393A1K43BB1-CTD");
// rsi.SerialNo.takeValueFrom("24B63C91");
// rsi.SlotIndex = 1;
// rsi.Type = 17;
// rsi.Vendor.takeValueFrom("Samsung");
// gRAM.SMBIOS.AddReference(rsiPtr, true);
//}
// DBG("JIEF_DEBUG : force memory modules\n");
// return;
//#endif
// Memory Device // Memory Device
// //
XBool Found; XBool FoundOneTable;
// Get Table Type17 and count Size // Get Table Type17 and count Size
for (size_t Index = 0; Index < smbiosSettings->RamSlotCount; Index++) { //how many tables there may be? for (size_t Index = 0; Index < smbiosSettings->RamSlotCount; Index++) { //how many tables there may be?
@ -1284,9 +1329,10 @@ void GetTableType17(SmbiosDiscoveredSettings* smbiosSettings)
// DBG("SmbiosTable: Type 17 (Memory Device number %d) not found!\n", Index); // DBG("SmbiosTable: Type 17 (Memory Device number %d) not found!\n", Index);
continue; continue;
} }
#ifndef JIEF_DEBUG // it's all 0 in VMWare FoundOneTable = true;
//#ifndef JIEF_DEBUG // it's all 0 in VMWare
DBG("Type 17 Index = %zu\n", Index); DBG("Type 17 Index = %zu\n", Index);
#endif //#endif
//gDMI->CntMemorySlots++; //gDMI->CntMemorySlots++;
if (SmbiosTable.Type17->MemoryErrorInformationHandle < 0xFFFE) { if (SmbiosTable.Type17->MemoryErrorInformationHandle < 0xFFFE) {
DBG("Table has error information, checking\n"); //why skipping? DBG("Table has error information, checking\n"); //why skipping?
@ -1295,7 +1341,7 @@ void GetTableType17(SmbiosDiscoveredSettings* smbiosSettings)
// be skipped where others may not but it seems easier // be skipped where others may not but it seems easier
// to just skip all entries that have an error - apianti // to just skip all entries that have an error - apianti
// will try // will try
Found = false; XBool Found = false;
for (INTN Index2 = 0; Index2 < 24; Index2++) { for (INTN Index2 = 0; Index2 < 24; Index2++) {
newSmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_32BIT_MEMORY_ERROR_INFORMATION, Index2); newSmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_32BIT_MEMORY_ERROR_INFORMATION, Index2);
if (newSmbiosTable.Raw == NULL) { if (newSmbiosTable.Raw == NULL) {
@ -1332,18 +1378,23 @@ void GetTableType17(SmbiosDiscoveredSettings* smbiosSettings)
} }
} }
} }
RAM_SLOT_INFO* rsiPtr = NULL;
// Determine if slot has size // Determine if slot has size
if (SmbiosTable.Type17->Size > 0) { if (SmbiosTable.Type17->Size > 0) {
gRAM.SMBIOS[Index].InUse = true; rsiPtr = new RAM_SLOT_INFO;
gRAM.SMBIOS[Index].ModuleSize = SmbiosTable.Type17->Size; RAM_SLOT_INFO& rsi = *rsiPtr;
rsi.ModuleSize = SmbiosTable.Type17->Size;
if (SmbiosTable.Type17->Size == 0x7FFF) { if (SmbiosTable.Type17->Size == 0x7FFF) {
gRAM.SMBIOS[Index].ModuleSize = SmbiosTable.Type17->ExtendedSize; rsi.ModuleSize = SmbiosTable.Type17->ExtendedSize;
} }
} }
// Determine if module frequency is sane value // Determine if module frequency is sane value
if ((SmbiosTable.Type17->Speed > 0) && (SmbiosTable.Type17->Speed <= MAX_RAM_FREQUENCY)) { if ((SmbiosTable.Type17->Speed > 0) && (SmbiosTable.Type17->Speed <= MAX_RAM_FREQUENCY)) {
gRAM.SMBIOS[Index].InUse = true; if ( rsiPtr == NULL ) rsiPtr = new RAM_SLOT_INFO;
gRAM.SMBIOS[Index].Frequency = SmbiosTable.Type17->Speed; RAM_SLOT_INFO& rsi = *rsiPtr;
rsi.Frequency = SmbiosTable.Type17->Speed;
if (SmbiosTable.Type17->Speed > gRAM.Frequency) { if (SmbiosTable.Type17->Speed > gRAM.Frequency) {
gRAM.Frequency = SmbiosTable.Type17->Speed; gRAM.Frequency = SmbiosTable.Type17->Speed;
} }
@ -1353,56 +1404,66 @@ void GetTableType17(SmbiosDiscoveredSettings* smbiosSettings)
#endif #endif
} }
// Fill rest of information if in use // Fill rest of information if in use
if (gRAM.SMBIOS[Index].InUse) { if ( rsiPtr != NULL ) {
++(gRAM.SMBIOSInUse); //++(gRAM.SMBIOSInUse);
gRAM.SMBIOS[Index].Vendor.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->Manufacturer)); RAM_SLOT_INFO& rsi = *rsiPtr;
gRAM.SMBIOS[Index].Vendor.trim();
gRAM.SMBIOS[Index].SerialNo.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->SerialNumber)); rsi.SlotIndex = Index;
gRAM.SMBIOS[Index].SerialNo.trim(); rsi.Vendor.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->Manufacturer));
gRAM.SMBIOS[Index].PartNo.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->PartNumber)); rsi.Vendor.trim();
gRAM.SMBIOS[Index].PartNo.trim(); rsi.SerialNo.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->SerialNumber));
} rsi.SerialNo.trim();
// DBG("CntMemorySlots = %d\n", gDMI->CntMemorySlots) rsi.PartNo.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->PartNumber));
// DBG("gDMI->MemoryModules = %d\n", gDMI->MemoryModules) rsi.PartNo.trim();
if ((SmbiosTable.Type17->Speed > 0) && (SmbiosTable.Type17->Speed <= MAX_RAM_FREQUENCY)) {
DBG("SmbiosTable.Type17->Speed = %dMHz\n", gRAM.SMBIOS[Index].Frequency); gRAM.SMBIOS.AddReference(rsiPtr, true);
DBG("SmbiosTable.Type17->Size = %dMB\n", gRAM.SMBIOS[Index].ModuleSize);
DBG("SmbiosTable.Type17->SlotIndex = %d\n", rsi.SlotIndex);
DBG("SmbiosTable.Type17->ModuleSize = %dMB\n", rsi.ModuleSize);
DBG("SmbiosTable.Type17->Type = %d\n", rsi.Type);
DBG("SmbiosTable.Type17->Frequency = %dMHz\n", rsi.Frequency);
DBG("SmbiosTable.Type17->Bank/Device = %s %s\n", GetSmbiosString(SmbiosTable, SmbiosTable.Type17->BankLocator), GetSmbiosString(SmbiosTable, SmbiosTable.Type17->DeviceLocator)); DBG("SmbiosTable.Type17->Bank/Device = %s %s\n", GetSmbiosString(SmbiosTable, SmbiosTable.Type17->BankLocator), GetSmbiosString(SmbiosTable, SmbiosTable.Type17->DeviceLocator));
DBG("SmbiosTable.Type17->Vendor = %s\n", gRAM.SMBIOS[Index].Vendor.c_str()); DBG("SmbiosTable.Type17->Vendor = %s\n", rsi.Vendor.c_str());
DBG("SmbiosTable.Type17->SerialNumber = %s\n", gRAM.SMBIOS[Index].SerialNo.c_str()); DBG("SmbiosTable.Type17->SerialNo = %s\n", rsi.SerialNo.c_str());
DBG("SmbiosTable.Type17->PartNumber = %s\n", gRAM.SMBIOS[Index].PartNo.c_str()); DBG("SmbiosTable.Type17->PartNo = %s\n", rsi.PartNo.c_str());
} }
/* /*
if ((SmbiosTable.Type17->Size & 0x8000) == 0) { if ((SmbiosTable.Type17->Size & 0x8000) == 0) {
mTotalSystemMemory += SmbiosTable.Type17->Size; //Mb mTotalSystemMemory += SmbiosTable.Type17->Size; //Mb
mMemory17[Index] = (UINT16)(SmbiosTable.Type17->Size > 0 ? mTotalSystemMemory : 0); m Memory17[Index] = (UINT16)(SmbiosTable.Type17->Size > 0 ? mTotalSystemMemory : 0);
} }
DBG("mTotalSystemMemory = %d\n", mTotalSystemMemory); DBG("mTotalSystemMemory = %d\n", mTotalSystemMemory);
*/ */
} }
if ( !FoundOneTable ) {
DBG("No table 17 found\n");
}
} }
void PatchTableType17(const SmbiosInjectedSettings& smbiosSettings) void PatchTableType17(const SmbiosInjectedSettings& smbiosSettings, XArray<UINT16>* mMemory17Ptr, XArray<UINT16>* mHandle17Ptr)
{ {
XArray<UINT16>& mMemory17 = *mMemory17Ptr;
XArray<UINT16>& mHandle17 = *mHandle17Ptr;
XString8 deviceLocator; XString8 deviceLocator;
XString8 bankLocator; XString8 bankLocator;
UINT8 channelMap[MAX_RAM_SLOTS]; UINT8 channelMap[mMemory17.size()]; // mMemory17.size() == SlotCounts
UINT8 expectedCount = 0; UINT8 expectedCount = 0;
UINT8 channels = 2; UINT8 channels = 2;
XBool insertingEmpty = true; XBool insertingEmpty = true;
XBool trustSMBIOS = ((gRAM.SPDInUse == 0) || smbiosSettings.TrustSMBIOS); XBool trustSMBIOS = ( gRAM.SPD.size() == 0 || smbiosSettings.TrustSMBIOS);
XBool wrongSMBIOSBanks = false; XBool wrongSMBIOSBanks = false;
XBool isMacPro = false; XBool isMacPro = false;
MACHINE_TYPES Model = GetModelFromString(smbiosSettings.ProductName); MACHINE_TYPES Model = GetModelFromString(smbiosSettings.ProductName);
if ((Model == MacPro31) || (Model == MacPro41) || (Model == MacPro51) || (Model == MacPro61)) { if ((Model == MacPro31) || (Model == MacPro41) || (Model == MacPro51) || (Model == MacPro61) || (Model == MacPro71)) {
isMacPro = true; isMacPro = true;
} }
// Inject user memory tables // Inject user memory tables
if (smbiosSettings.InjectMemoryTables) if (smbiosSettings.InjectMemoryTables)
{ {
DBG("Injecting user memory modules to SMBIOS\n"); DBG("Injecting user memory modules to SMBIOS\n");
if (smbiosSettings.Memory.SlotCounts == 0) { if (smbiosSettings.Memory._User.size() == 0) {
DBG("User SMBIOS contains no memory modules\n"); DBG("User SMBIOS contains no memory modules\n");
return; return;
} }
@ -1411,46 +1472,46 @@ void PatchTableType17(const SmbiosInjectedSettings& smbiosSettings)
if ( UserChannels == 0 || UserChannels > 8 ) { if ( UserChannels == 0 || UserChannels > 8 ) {
UserChannels = 1; UserChannels = 1;
} }
auto SlotCounts = smbiosSettings.Memory.SlotCounts;
if ( SlotCounts >= MAX_RAM_SLOTS ) {
SlotCounts = MAX_RAM_SLOTS;
}
DBG("Channels: %d\n", UserChannels); DBG("Channels: %d\n", UserChannels);
// Setup interleaved channel map // Setup interleaved channel map
if (channels >= 2) { if (channels >= 2) {
UINT8 doubleChannels = (UINT8)UserChannels << 1; UINT8 doubleChannels = (UINT8)UserChannels << 1;
for (size_t Index = 0; Index < MAX_RAM_SLOTS; ++Index) { for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
channelMap[Index] = (UINT8)(((Index / doubleChannels) * doubleChannels) + channelMap[Index] = (UINT8)(((Index / doubleChannels) * doubleChannels) +
((Index / UserChannels) % 2) + ((Index % UserChannels) << 1)); ((Index / UserChannels) % 2) + ((Index % UserChannels) << 1));
} }
} else { } else {
for (size_t Index = 0; Index < MAX_RAM_SLOTS; ++Index) { for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
channelMap[Index] = (UINT8)Index; channelMap[Index] = (UINT8)Index;
} }
} }
DBG("Interleave:"); DBG("Interleave:");
for (size_t Index = 0; Index < MAX_RAM_SLOTS; ++Index) { for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
DBG(" %d", channelMap[Index]); DBG(" %d", channelMap[Index]);
} }
DBG("\n"); DBG("\n");
// Memory Device // Memory Device
// //
// Inject tables // Inject tables
#ifdef JIEF_DEBUG DBG("user SMBIOS data:\n");
DBG("gSettings.Smbios.Memory.SlotCounts=%d\n", smbiosSettings.Memory.SlotCounts); DBG(" smbiosSettings.RamSlotCount=%d\n", smbiosSettings.RamSlotCount);
DBG("gSettings.Smbios.Memory.UserChannels=%d\n", smbiosSettings.Memory.UserChannels); DBG(" smbiosSettings.Memory.SlotCounts=%d\n", smbiosSettings.Memory.SlotCount);
for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) { DBG(" smbiosSettings.Memory.UserChannels=%d\n", smbiosSettings.Memory.UserChannels);
DBG("gSettings.Smbios.Memory.User[%lld].Frequency=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Frequency); for (size_t Index = 0; Index < smbiosSettings.RamSlotCount; Index++) {
DBG("gSettings.Smbios.Memory.User[%lld].InUse=%d\n", Index, (bool)smbiosSettings.Memory.getSlotInfoForSlotID(Index).InUse); if ( smbiosSettings.Memory.doesSlotForIndexExist(Index) ) {
DBG("gSettings.Smbios.Memory.User[%lld].ModuleSize=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).ModuleSize); DBG(" smbiosSettings.Memory slot %zu\n", Index);
DBG("gSettings.Smbios.Memory.User[%lld].PartNo=%s\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).PartNo.c_str()); DBG(" smbiosSettings.Memory[%zu].ModuleSize=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).ModuleSize);
DBG("gSettings.Smbios.Memory.User[%lld].SerialNo=%s\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).SerialNo.c_str()); DBG(" smbiosSettings.Memory[%zu].Type=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Type);
DBG("gSettings.Smbios.Memory.User[%lld].Type=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Type); DBG(" smbiosSettings.Memory[%zu].Frequency=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Frequency);
DBG("gSettings.Smbios.Memory.User[%lld].Vendor=%s\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Vendor.c_str()); DBG(" smbiosSettings.Memory[%zu].Vendor=%s\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Vendor.c_str());
} DBG(" smbiosSettings.Memory[%zu].PartNo=%s\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).PartNo.c_str());
#endif DBG(" smbiosSettings.Memory[%zu].SerialNo=%s\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).SerialNo.c_str());
}else{
DBG(" smbiosSettings.Memory slot %zu is not defined\n", Index);
}
}
for (size_t Index = 0; Index < SlotCounts; Index++) { for (size_t Index = 0; Index < mMemory17.size(); Index++) {
UINTN UserIndex = channelMap[Index]; UINTN UserIndex = channelMap[Index];
UINT8 bank = (UINT8)(Index / UserChannels); UINT8 bank = (UINT8)(Index / UserChannels);
ZeroMem((void*)newSmbiosTable.Type17, MAX_TABLE_SIZE); ZeroMem((void*)newSmbiosTable.Type17, MAX_TABLE_SIZE);
@ -1471,12 +1532,8 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->BankLocator, bankLocator); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->BankLocator, bankLocator);
} }
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->DeviceLocator, deviceLocator); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->DeviceLocator, deviceLocator);
if ((smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).InUse) && (smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).ModuleSize > 0)) { if ( smbiosSettings.Memory.doesSlotForIndexExist(UserIndex) && smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).ModuleSize > 0 )
DBG("user SMBIOS data:\n"); {
DBG("SmbiosTable.Type17->Vendor = %s\n", smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).Vendor.c_str());
DBG("SmbiosTable.Type17->SerialNumber = %s\n", smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).SerialNo.c_str());
DBG("SmbiosTable.Type17->PartNumber = %s\n", smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).PartNo.c_str());
if (smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).Vendor.notEmpty()) { if (smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).Vendor.notEmpty()) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).Vendor); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).Vendor);
} else { } else {
@ -1522,34 +1579,36 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
DBG("mTotalSystemMemory = %d\n", mTotalSystemMemory); DBG("mTotalSystemMemory = %d\n", mTotalSystemMemory);
} }
return; return;
}else{
DBG("Do not inject memory table\n");
} }
// Prevent inserting empty tables // Prevent inserting empty tables
if ((gRAM.SPDInUse == 0) && (gRAM.SMBIOSInUse == 0)) { if ((gRAM.SPD.size() == 0) && (gRAM.SMBIOS.size() == 0)) {
DBG("SMBIOS and SPD contain no modules in use\n"); DBG("SMBIOS and SPD contain no modules in use\n");
return; return;
} }
// Detect whether the SMBIOS is trusted information // Detect whether the SMBIOS is trusted information
if (trustSMBIOS) { if (trustSMBIOS) {
if (gRAM.SMBIOSInUse != 0) { if (gRAM.SMBIOS.size() != 0) {
if (gRAM.SPDInUse != 0) { if (gRAM.SPD.size() != 0) {
if (gRAM.SPDInUse != gRAM.SMBIOSInUse) { if (gRAM.SPD.size() != gRAM.SMBIOS.size()) {
// Prefer the SPD information // Prefer the SPD information
if (gRAM.SPDInUse > gRAM.SMBIOSInUse) { if (gRAM.SPD.size() > gRAM.SMBIOS.size()) {
DBG("Not trusting SMBIOS because SPD reports more modules...\n"); DBG("Not trusting SMBIOS because SPD reports more modules...\n");
trustSMBIOS = false; trustSMBIOS = false;
} else if (gRAM.SPD[0].InUse || !gRAM.SMBIOS[0].InUse) { } else if (gRAM.SPD.doesSlotForIndexExist(0) || !gRAM.SMBIOS.doesSlotForIndexExist(0)) {
if (gRAM.SPDInUse > 1) { if (gRAM.SPD.size() > 1) {
DBG("Not trusting SMBIOS because SPD reports different modules...\n"); DBG("Not trusting SMBIOS because SPD reports different modules...\n");
trustSMBIOS = false; trustSMBIOS = false;
} else if (gRAM.SMBIOSInUse == 1) { } else if (gRAM.SMBIOS.size() == 1) {
channels = 1; channels = 1;
} }
} else if (gRAM.SPDInUse == 1) { } else if (gRAM.SPD.size() == 1) {
// The SMBIOS may contain table for built-in module // The SMBIOS may contain table for built-in module
if (gRAM.SMBIOSInUse <= 2) { if (gRAM.SMBIOS.size() <= 2) {
if (!gRAM.SMBIOS[0].InUse || !gRAM.SPD[2].InUse || if (!gRAM.SMBIOS.doesSlotForIndexExist(0) || !gRAM.SPD.doesSlotForIndexExist(2) ||
(gRAM.SMBIOS[0].Frequency != gRAM.SPD[2].Frequency) || (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).Frequency != gRAM.SPD.getSlotInfoForSlotIndex(2).Frequency) ||
(gRAM.SMBIOS[0].ModuleSize != gRAM.SPD[2].ModuleSize)) { (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize != gRAM.SPD.getSlotInfoForSlotIndex(2).ModuleSize)) {
channels = 1; channels = 1;
} }
} else { } else {
@ -1560,12 +1619,12 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
DBG("Not trusting SMBIOS because SPD reports less modules...\n"); DBG("Not trusting SMBIOS because SPD reports less modules...\n");
trustSMBIOS = false; trustSMBIOS = false;
} }
} else if (gRAM.SPD[0].InUse != gRAM.SMBIOS[0].InUse) { } else if (gRAM.SPD.doesSlotForIndexExist(0) != gRAM.SMBIOS.doesSlotForIndexExist(0)) {
// Never trust a sneaky SMBIOS! // Never trust a sneaky SMBIOS!
DBG("Not trusting SMBIOS because it's being sneaky...\n"); DBG("Not trusting SMBIOS because it's being sneaky...\n");
trustSMBIOS = false; trustSMBIOS = false;
} }
} else if (gRAM.SMBIOSInUse == 1) { } else if (gRAM.SMBIOS.size() == 1) {
channels = 1; channels = 1;
} }
} }
@ -1574,11 +1633,11 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
DBG("Trusting SMBIOS...\n"); DBG("Trusting SMBIOS...\n");
} }
// Determine expected slot count // Determine expected slot count
expectedCount = (smbiosSettings.Memory.SlotCounts != 0) ? smbiosSettings.Memory.SlotCounts : gRAM.SPDInUse; expectedCount = (smbiosSettings.RamSlotCount != 0) ? smbiosSettings.RamSlotCount : gRAM.SPD.getSlotCount();
if (trustSMBIOS) { if (trustSMBIOS) {
// Use the smbios in use count // Use the smbios in use count
if (expectedCount < gRAM.SMBIOSInUse) { if (expectedCount < gRAM.SMBIOS.getSlotCount()) {
expectedCount = gRAM.SMBIOSInUse; expectedCount = gRAM.SMBIOS.getSlotCount();
} }
// Check if smbios has a good total count // Check if smbios has a good total count
if ( (!gMobile || smbiosSettings.RamSlotCount == 2) && expectedCount < smbiosSettings.RamSlotCount ) { if ( (!gMobile || smbiosSettings.RamSlotCount == 2) && expectedCount < smbiosSettings.RamSlotCount ) {
@ -1601,8 +1660,8 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
} }
// Check for interleaved channels // Check for interleaved channels
if (channels >= 2) { if (channels >= 2) {
wrongSMBIOSBanks = ((gRAM.SMBIOS[1].InUse != gRAM.SPD[1].InUse) || wrongSMBIOSBanks = ((gRAM.SMBIOS.doesSlotForIndexExist(1) != gRAM.SPD.doesSlotForIndexExist(1)) ||
(gRAM.SMBIOS[1].ModuleSize != gRAM.SPD[1].ModuleSize)); (gRAM.SMBIOS.getSlotInfoForSlotIndex(1).ModuleSize != gRAM.SPD.getSlotInfoForSlotIndex(1).ModuleSize));
} }
if (wrongSMBIOSBanks) { if (wrongSMBIOSBanks) {
DBG("Detected alternating SMBIOS channel banks\n"); DBG("Detected alternating SMBIOS channel banks\n");
@ -1610,62 +1669,62 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
// Determine if using triple or quadruple channel // Determine if using triple or quadruple channel
if (smbiosSettings.Memory.UserChannels != 0) { if (smbiosSettings.Memory.UserChannels != 0) {
channels = smbiosSettings.Memory.UserChannels; channels = smbiosSettings.Memory.UserChannels;
} else if (gRAM.SPDInUse == 0) { } else if (gRAM.SPD.size() == 0) {
if (trustSMBIOS) { if (trustSMBIOS) {
if ((gRAM.SMBIOSInUse % 4) == 0) { if ((gRAM.SMBIOS.size() % 4) == 0) {
// Quadruple channel // Quadruple channel
if ((wrongSMBIOSBanks && if ((wrongSMBIOSBanks &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[1].InUse) && (gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(1)) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[2].InUse) && (gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(2)) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[3].InUse) && (gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(3)) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[1].ModuleSize) && (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(1).ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[2].ModuleSize) && (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[3].ModuleSize)) || (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(3).ModuleSize)) ||
((gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[2].InUse) && ((gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(2)) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[4].InUse) && (gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(4)) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[6].InUse) && (gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(6)) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[2].ModuleSize) && (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[4].ModuleSize) && (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(4).ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[6].ModuleSize))) { (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(6).ModuleSize))) {
channels = 4; channels = 4;
} }
} else if ((gRAM.SMBIOSInUse % 3) == 0) { } else if ((gRAM.SMBIOS.size() % 3) == 0) {
// Triple channel // Triple channel
if ((wrongSMBIOSBanks && if ((wrongSMBIOSBanks &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[1].InUse) && (gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(1)) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[2].InUse) && (gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(2)) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[1].ModuleSize) && (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(1).ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[2].ModuleSize)) || (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(2).ModuleSize)) ||
((gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[2].InUse) && ((gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(2)) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[4].InUse) && (gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(4)) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[2].ModuleSize) && (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[4].ModuleSize))) { (gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(4).ModuleSize))) {
channels = 3; channels = 3;
} }
} else if (!wrongSMBIOSBanks && ((gRAM.SMBIOSInUse % 2) != 0)) { } else if (!wrongSMBIOSBanks && ((gRAM.SMBIOS.size() % 2) != 0)) {
channels = 1; channels = 1;
} }
} }
} else if ((gRAM.SPDInUse % 4) == 0) { } else if ((gRAM.SPD.size() % 4) == 0) {
// Quadruple channel // Quadruple channel
if ((gRAM.SPD[0].InUse == gRAM.SPD[2].InUse) && if ((gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(2)) &&
(gRAM.SPD[0].InUse == gRAM.SPD[4].InUse) && (gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(4)) &&
(gRAM.SPD[0].InUse == gRAM.SPD[6].InUse) && (gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(6)) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[2].ModuleSize) && (gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[4].ModuleSize) && (gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(4).ModuleSize) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[6].ModuleSize)) { (gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(6).ModuleSize)) {
channels = 4; channels = 4;
} }
} else if ((gRAM.SPDInUse % 3) == 0) { } else if ((gRAM.SPD.size() % 3) == 0) {
// Triple channel // Triple channel
if ((gRAM.SPD[0].InUse == gRAM.SPD[2].InUse) && if ((gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(2)) &&
(gRAM.SPD[0].InUse == gRAM.SPD[4].InUse) && (gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(4)) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[2].ModuleSize) && (gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[4].ModuleSize)) { (gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(4).ModuleSize)) {
channels = 3; channels = 3;
} }
} else if ((gRAM.SPD[0].InUse != gRAM.SPD[2].InUse) || } else if ((gRAM.SPD.doesSlotForIndexExist(0) != gRAM.SPD.doesSlotForIndexExist(2)) ||
((gRAM.SPDInUse % 2) != 0)) { ((gRAM.SPD.size() % 2) != 0)) {
channels = 1; channels = 1;
} }
// Can't have less than the number of channels // Can't have less than the number of channels
@ -1679,64 +1738,67 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
// Setup interleaved channel map // Setup interleaved channel map
if (channels >= 2) { if (channels >= 2) {
UINT8 doubleChannels = (UINT8)channels << 1; UINT8 doubleChannels = (UINT8)channels << 1;
for (size_t Index = 0; Index < MAX_RAM_SLOTS; ++Index) { for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
channelMap[Index] = (UINT8)(((Index / doubleChannels) * doubleChannels) + channelMap[Index] = (UINT8)(((Index / doubleChannels) * doubleChannels) +
((Index / channels) % 2) + ((Index % channels) << 1)); ((Index / channels) % 2) + ((Index % channels) << 1));
} }
} else { } else {
for (size_t Index = 0; Index < MAX_RAM_SLOTS; ++Index) { for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
channelMap[Index] = (UINT8)Index; channelMap[Index] = (UINT8)Index;
} }
} }
DBG("Interleave:"); DBG("Interleave:");
for (size_t Index = 0; Index < MAX_RAM_SLOTS; ++Index) { for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
DBG(" %d", channelMap[Index]); DBG(" %d", channelMap[Index]);
} }
DBG("\n"); DBG("\n");
// Memory Device // Memory Device
// //
for (size_t Index = 0; Index < smbiosSettings.RamSlotCount; Index++) { for (size_t Index = 0; Index < mMemory17.size(); Index++) {
UINTN SMBIOSIndex = wrongSMBIOSBanks ? Index : channelMap[Index]; size_t SMBIOSIndex = wrongSMBIOSBanks ? Index : channelMap[Index];
UINTN SPDIndex = channelMap[Index]; size_t SPDIndex = channelMap[Index];
UINT8 bank = (UINT8)Index / channels; UINT8 bank = (UINT8)Index / channels;
if (!insertingEmpty && (Index > expectedCount) && if (!insertingEmpty && (Index > expectedCount) &&
!gRAM.SPD[SPDIndex].InUse && (!trustSMBIOS || !gRAM.SMBIOS[SMBIOSIndex].InUse)) { !gRAM.SPD.doesSlotForIndexExist(SPDIndex) && (!trustSMBIOS || !gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex))) {
continue; continue;
} }
SmbiosTable = GetSmbiosTableFromType(EntryPoint, EFI_SMBIOS_TYPE_MEMORY_DEVICE, SMBIOSIndex); SmbiosTable = GetSmbiosTableFromType(EntryPoint, EFI_SMBIOS_TYPE_MEMORY_DEVICE, SMBIOSIndex);
if (trustSMBIOS && gRAM.SMBIOS[SMBIOSIndex].InUse && (SmbiosTable.Raw != NULL)) { if (trustSMBIOS && gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex) && (SmbiosTable.Raw != NULL)) {
DBG("trusted SMBIOS data:\n"); DBG("trusted SMBIOS data, table index %zu:\n", SMBIOSIndex);
DBG("SmbiosTable.Type17->Vendor = %s\n", gRAM.SMBIOS[SMBIOSIndex].Vendor.c_str()); DBG(" gRAM.SMBIOS[%zu]->ModuleSize = %d\n", SMBIOSIndex, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).ModuleSize);
DBG("SmbiosTable.Type17->SerialNumber = %s\n", gRAM.SMBIOS[SMBIOSIndex].SerialNo.c_str()); DBG(" gRAM.SMBIOS[%zu]->Type = %d\n", SMBIOSIndex, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Type);
DBG("SmbiosTable.Type17->PartNumber = %s\n", gRAM.SMBIOS[SMBIOSIndex].PartNo.c_str()); DBG(" gRAM.SMBIOS[%zu]->Frequency = %d\n", SMBIOSIndex, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Frequency);
DBG(" gRAM.SMBIOS[%zu]->Vendor = %s\n", SMBIOSIndex, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor.c_str());
DBG(" gRAM.SMBIOS[%zu]->PartNo = %s\n", SMBIOSIndex, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).PartNo.c_str());
DBG(" gRAM.SMBIOS[%zu]->SerialNo = %s\n", SMBIOSIndex, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).SerialNo.c_str());
TableSize = SmbiosTableLength(SmbiosTable); TableSize = SmbiosTableLength(SmbiosTable);
CopyMem((void*)newSmbiosTable.Type17, (void *)SmbiosTable.Type17, TableSize); CopyMem((void*)newSmbiosTable.Type17, (void *)SmbiosTable.Type17, TableSize);
newSmbiosTable.Type17->AssetTag = 0; newSmbiosTable.Type17->AssetTag = 0;
if ( gRAM.SMBIOS[SMBIOSIndex].Vendor.notEmpty() ) { if ( gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SMBIOS[SMBIOSIndex].Vendor); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor);
// gSettings.MemoryManufacturer.takeValueFrom(gRAM.SMBIOS[SMBIOSIndex].Vendor);
} else { } else {
// newSmbiosTable.Type17->Manufacturer = 0;
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, unknown); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, unknown);
} }
if ( gRAM.SMBIOS[SMBIOSIndex].SerialNo.notEmpty() ) { if ( gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).SerialNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, gRAM.SMBIOS[SMBIOSIndex].SerialNo); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).SerialNo);
// gSettings.MemorySerialNumber.takeValueFrom(gRAM.SMBIOS[SMBIOSIndex].SerialNo);
} else { } else {
// newSmbiosTable.Type17->SerialNumber = 0;
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, unknown); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, unknown);
} }
if ( gRAM.SMBIOS[SMBIOSIndex].PartNo.notEmpty() ) { if ( gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).PartNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, gRAM.SMBIOS[SMBIOSIndex].PartNo); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).PartNo);
// gSettings.MemoryPartNumber.takeValueFrom(gRAM.SMBIOS[SMBIOSIndex].PartNo); //DBG(" Update PartNumber to %s\n", gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).PartNo.c_str());
DBG(" partNum=%s\n", gRAM.SMBIOS[SMBIOSIndex].PartNo.c_str());
} else { } else {
// newSmbiosTable.Type17->PartNumber = 0; // newSmbiosTable.Type17->PartNumber = 0;
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, unknown); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, unknown);
DBG(" partNum unknown\n"); //DBG(" Set PartNumber unknown\n");
} }
} else { } else {
DBG("!trusted SMBIOS data, Table index %zu:", SMBIOSIndex);
if ( !trustSMBIOS ) DBG("!trustSMBIOS ");
if ( !gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex) ) DBG("!gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex) ");
if ( SmbiosTable.Raw == NULL ) DBG("SmbiosTable.Raw == NULL ");
DBG("\n");
ZeroMem((void*)newSmbiosTable.Type17, MAX_TABLE_SIZE); ZeroMem((void*)newSmbiosTable.Type17, MAX_TABLE_SIZE);
newSmbiosTable.Type17->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE; newSmbiosTable.Type17->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
newSmbiosTable.Type17->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE17); newSmbiosTable.Type17->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE17);
@ -1750,54 +1812,54 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
newSmbiosTable.Type17->DeviceSet = bank + 1; newSmbiosTable.Type17->DeviceSet = bank + 1;
newSmbiosTable.Type17->MemoryArrayHandle = mHandle16; newSmbiosTable.Type17->MemoryArrayHandle = mHandle16;
if (gRAM.SPD[SPDIndex].InUse) { if (gRAM.SPD.doesSlotForIndexExist(SPDIndex)) {
DBG("SPD data in use:\n"); DBG("SPD data in use:\n");
DBG("SmbiosTable.Type17->Vendor = %s\n", gRAM.SPD[SPDIndex].Vendor.c_str()); DBG(" gRAM.SPD[%zu]->ModuleSize = %d\n", SPDIndex, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).ModuleSize);
DBG("SmbiosTable.Type17->SerialNumber = %s\n", gRAM.SPD[SPDIndex].SerialNo.c_str()); DBG(" gRAM.SPD[%zu]->Type = %d\n", SPDIndex, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Type);
DBG("SmbiosTable.Type17->PartNumber = %s\n", gRAM.SPD[SPDIndex].PartNo.c_str()); DBG(" gRAM.SPD[%zu]->Frequency = %d\n", SPDIndex, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Frequency);
DBG(" gRAM.SPD[%zu]->Vendor = %s\n", SPDIndex, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Vendor.c_str());
DBG(" gRAM.SPD[%zu]->SerialNo = %s\n", SPDIndex, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).SerialNo.c_str());
DBG(" gRAM.SPD[%zu]->PartNo = %s\n", SPDIndex, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).PartNo.c_str());
if ( gRAM.SPD[SPDIndex].Vendor.notEmpty() ) { if ( gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Vendor.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SPD[SPDIndex].Vendor); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Vendor);
// gSettings.MemoryManufacturer.takeValueFrom(gRAM.SPD[SPDIndex].Vendor);
} else { } else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, unknown); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, unknown);
} }
if ( gRAM.SPD[SPDIndex].SerialNo.notEmpty() ) { if ( gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).SerialNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, gRAM.SPD[SPDIndex].SerialNo); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).SerialNo);
// gSettings.MemorySerialNumber.takeValueFrom(gRAM.SPD[SPDIndex].SerialNo);
} else { } else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, unknown); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, unknown);
} }
if ( gRAM.SPD[SPDIndex].PartNo.notEmpty() ) { if ( gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).PartNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, gRAM.SPD[SPDIndex].PartNo); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).PartNo);
// gSettings.MemoryPartNumber.takeValueFrom(gRAM.SPD[SPDIndex].PartNo);
} else { } else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, unknown); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, unknown);
} }
if (gRAM.Frequency > gRAM.SPD[SPDIndex].Frequency) { if (gRAM.Frequency > gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Frequency) {
newSmbiosTable.Type17->Speed = (UINT16)gRAM.Frequency; newSmbiosTable.Type17->Speed = (UINT16)gRAM.Frequency; // unsafe cast
} else { } else {
newSmbiosTable.Type17->Speed = (UINT16)gRAM.SPD[SPDIndex].Frequency; newSmbiosTable.Type17->Speed = gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Frequency;
} }
if (gRAM.SPD[SPDIndex].ModuleSize > 0x7FFF) { if (gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).ModuleSize > 0x7FFF) {
newSmbiosTable.Type17->Size = 0x7FFF; newSmbiosTable.Type17->Size = 0x7FFF;
newSmbiosTable.Type17->ExtendedSize = gRAM.SPD[SPDIndex].ModuleSize; newSmbiosTable.Type17->ExtendedSize = gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).ModuleSize;
} else { } else {
newSmbiosTable.Type17->Size = (UINT16)gRAM.SPD[SPDIndex].ModuleSize; newSmbiosTable.Type17->Size = gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).ModuleSize;
} }
newSmbiosTable.Type17->MemoryType = gRAM.SPD[SPDIndex].Type; newSmbiosTable.Type17->MemoryType = gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Type;
} }
if (trustSMBIOS && gRAM.SMBIOS[SMBIOSIndex].InUse && if (trustSMBIOS && gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex) &&
(newSmbiosTable.Type17->Speed < (UINT16)gRAM.SMBIOS[SMBIOSIndex].Frequency)) { (newSmbiosTable.Type17->Speed < gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Frequency)) {
DBG("Type17->Speed corrected by SMBIOS from %dMHz to %dMHz\n", newSmbiosTable.Type17->Speed, gRAM.SMBIOS[SMBIOSIndex].Frequency); DBG(" Type17->Speed corrected by SMBIOS from %dMHz to %dMHz\n", newSmbiosTable.Type17->Speed, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Frequency);
newSmbiosTable.Type17->Speed = (UINT16)gRAM.SMBIOS[SMBIOSIndex].Frequency; newSmbiosTable.Type17->Speed = gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Frequency;
} }
if (trustSMBIOS && gRAM.SMBIOS[SMBIOSIndex].InUse && if (trustSMBIOS && gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex) &&
gRAM.SMBIOS[SMBIOSIndex].Vendor.notEmpty() && gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor.notEmpty() &&
( gRAM.SPD[SPDIndex].Vendor.isEmpty() || gRAM.SPD[SPDIndex].Vendor == "NoName"_XS8 ) ( gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Vendor.isEmpty() || gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Vendor == "NoName"_XS8 )
) { ) {
DBG("Type17->Manufacturer corrected by SMBIOS from NoName to %s\n", gRAM.SMBIOS[SMBIOSIndex].Vendor.c_str()); DBG(" Type17->Manufacturer corrected by SMBIOS from NoName to %s\n", gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor.c_str());
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SMBIOS[SMBIOSIndex].Vendor); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor);
} }
// gSettings.MemorySpeed.S8Printf("%d", newSmbiosTable.Type17->Speed); // gSettings.MemorySpeed.S8Printf("%d", newSmbiosTable.Type17->Speed);
@ -1823,7 +1885,7 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
} else { } else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->BankLocator, bankLocator); UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->BankLocator, bankLocator);
} }
DBG("SMBIOS Type 17 Index = %zd => %llu %llu:\n", Index, SMBIOSIndex, SPDIndex); DBG(" SMBIOS Type 17 Index = %zd => SMBIOSIndex=%zu SPDIndex=%zu:\n", Index, SMBIOSIndex, SPDIndex);
if (newSmbiosTable.Type17->Size == 0) { if (newSmbiosTable.Type17->Size == 0) {
DBG("%s %s EMPTY\n", bankLocator.c_str(), deviceLocator.c_str()); DBG("%s %s EMPTY\n", bankLocator.c_str(), deviceLocator.c_str());
newSmbiosTable.Type17->MemoryType = 0; //MemoryTypeUnknown; newSmbiosTable.Type17->MemoryType = 0; //MemoryTypeUnknown;
@ -1900,7 +1962,7 @@ PatchTableType19 (const SmbiosInjectedSettings& smbiosSettings)
return ; return ;
} }
void PatchTableType20 (const SmbiosInjectedSettings& smbiosSettings) void PatchTableType20 (const SmbiosInjectedSettings& smbiosSettings, const XArray<UINT16>& mMemory17, const XArray<UINT16>& mHandle17)
{ {
UINTN j = 0, k = 0, m = 0; UINTN j = 0, k = 0, m = 0;
// //
@ -1921,10 +1983,9 @@ void PatchTableType20 (const SmbiosInjectedSettings& smbiosSettings)
newSmbiosTable.Type20->MemoryDeviceHandle = mHandle17[j]; newSmbiosTable.Type20->MemoryDeviceHandle = mHandle17[j];
k = newSmbiosTable.Type20->EndingAddress; k = newSmbiosTable.Type20->EndingAddress;
m += mMemory17[j]; m += mMemory17[j];
DBG("Type20[%zu]->End = 0x%llX, Type17[%llu] = %llX\n", DBG("Type20[%zu]->End = 0x%llX, Type17[%llu] = %llX\n", Index, k, j, m);
Index, k, j, m);
// DBG(" MemoryDeviceHandle = 0x%X\n", newSmbiosTable.Type20->MemoryDeviceHandle); // DBG(" MemoryDeviceHandle = 0x%X\n", newSmbiosTable.Type20->MemoryDeviceHandle);
mMemory17[j] = 0; // used //mMemory17[j] = 0; // used
break; break;
} }
// DBG("\n"); // DBG("\n");
@ -2174,6 +2235,7 @@ EFI_STATUS PrepatchSmbios(SmbiosDiscoveredSettings* smbiosSettings)
GetTableType2(smbiosSettings); GetTableType2(smbiosSettings);
GetTableType3(smbiosSettings); GetTableType3(smbiosSettings);
GetTableType4(smbiosSettings); GetTableType4(smbiosSettings);
// GetTableType16() will initialize smbiosSettings->RamSlotCount. Could be MAX_RAM_SLOTS.
GetTableType16(smbiosSettings); GetTableType16(smbiosSettings);
GetTableType17(smbiosSettings); GetTableType17(smbiosSettings);
GetTableType32(smbiosSettings); //get BootStatus here to decide what to do GetTableType32(smbiosSettings); //get BootStatus here to decide what to do
@ -2201,10 +2263,20 @@ void PatchSmbios(const SmbiosInjectedSettings& smbiosSettings) //continue
PatchTableType11(smbiosSettings); PatchTableType11(smbiosSettings);
} }
PatchTableTypeSome(); PatchTableTypeSome();
PatchTableType17(smbiosSettings); auto SlotCounts = smbiosSettings.RamSlotCount;
if ( SlotCounts >= MAX_RAM_SLOTS ) {
log_technical_bug("GetTableType16() assign smbiosSettings.RamSlotCount a value bigger than MAX_RAM_SLOTS");
SlotCounts = MAX_RAM_SLOTS;
}
XArray<UINT16> mMemory17;
mMemory17.Add(0, SlotCounts);
XArray<UINT16> mHandle17;
mHandle17.Add(0, SlotCounts);
PatchTableType17(smbiosSettings, &mMemory17, &mHandle17);
PatchTableType16(smbiosSettings); PatchTableType16(smbiosSettings);
PatchTableType19(smbiosSettings); PatchTableType19(smbiosSettings);
PatchTableType20(smbiosSettings); PatchTableType20(smbiosSettings, mMemory17, mHandle17);
PatchTableType128(smbiosSettings); PatchTableType128(smbiosSettings);
PatchTableType130(smbiosSettings); PatchTableType130(smbiosSettings);
PatchTableType131(smbiosSettings); PatchTableType131(smbiosSettings);

View File

@ -17,22 +17,21 @@ extern "C" {
// The maximum number of RAM slots to detect // The maximum number of RAM slots to detect
// even for 3-channels chipset X58 there are no more then 8 slots // even for 3-channels chipset X58 there are no more then 8 slots
#define MAX_RAM_SLOTS 24 const uint8_t MAX_RAM_SLOTS = 24;
static_assert(MAX_RAM_SLOTS < UINT8_MAX, "MAX_RAM_SLOTS < UINT8_MAX"); // Important
// The maximum sane frequency for a RAM module // The maximum sane frequency for a RAM module
#define MAX_RAM_FREQUENCY 5000 #define MAX_RAM_FREQUENCY 5000
class RAM_SLOT_INFO { class RAM_SLOT_INFO {
public: public:
UINT64 Slot = UINT64(); UINT32 ModuleSize = 0;
UINT32 ModuleSize = UINT32(); UINT32 Frequency = 0;
UINT32 Frequency = UINT32(); XString8 Vendor = XString8();
XString8 Vendor = XString8(); XString8 PartNo = XString8();
XString8 PartNo = XString8(); XString8 SerialNo = XString8();
XString8 SerialNo = XString8(); UINT8 Type = 0;
UINT8 Type = UINT8(); UINT8 SlotIndex = 0;
XBool InUse = false; // XBool InUse = false;
RAM_SLOT_INFO() {} RAM_SLOT_INFO() {}
}; };
@ -40,21 +39,28 @@ extern const RAM_SLOT_INFO nullRAM_SLOT_INFO;
class SmbiosMemoryConfigurationClass { class SmbiosMemoryConfigurationClass {
public: public:
UINT8 SlotCounts = UINT8(); UINT8 SlotCount = UINT8();
UINT8 UserChannels = UINT8(); UINT8 UserChannels = UINT8();
XObjArray<RAM_SLOT_INFO> _User = XObjArray<RAM_SLOT_INFO>(); XObjArray<RAM_SLOT_INFO> _User = XObjArray<RAM_SLOT_INFO>();
SmbiosMemoryConfigurationClass() {} SmbiosMemoryConfigurationClass() {}
void setEmpty() { void setEmpty() {
SlotCounts = 0; SlotCount = 0;
UserChannels = 0; UserChannels = 0;
_User.setEmpty(); _User.setEmpty();
} }
XBool doesSlotForIndexExist(uint8_t idx2Look4) const {
for ( size_t idx = 0 ; idx < _User.size() ; ++idx ) {
if ( _User[idx].SlotIndex == idx2Look4 ) return true;
}
return false;
}
const RAM_SLOT_INFO& getSlotInfoForSlotID(UINT64 Slot) const { const RAM_SLOT_INFO& getSlotInfoForSlotID(UINT64 Slot) const {
for ( size_t idx = 0 ; idx < _User.size() ; ++idx ) { for ( size_t idx = 0 ; idx < _User.size() ; ++idx ) {
if ( _User[idx].Slot == Slot ) return _User[idx]; if ( _User[idx].SlotIndex == Slot ) return _User[idx];
} }
return nullRAM_SLOT_INFO; return nullRAM_SLOT_INFO;
} }
@ -86,14 +92,15 @@ class SmbiosDiscoveredSettings
XString8 OEMBoardFromSmbios = XString8(); XString8 OEMBoardFromSmbios = XString8();
XString8 OEMProductFromSmbios = XString8(); XString8 OEMProductFromSmbios = XString8();
XString8 OEMVendorFromSmbios = XString8(); XString8 OEMVendorFromSmbios = XString8();
uint8_t EnabledCores = 0; uint8_t EnabledCores = 0;
uint16_t RamSlotCount = 0; // this is maxed out to MAX_RAM_SLOTS remove_const(decltype(MAX_RAM_SLOTS)) RamSlotCount = 0; // this is discovered in GetTableType16(). Can be max out to MAX_RAM_SLOTS
static_assert(numeric_limits<decltype(MAX_RAM_SLOTS)>::max() <= numeric_limits<decltype(RamSlotCount)>::max(), "RamSlotCount wrong type");
// gCPUStructure // gCPUStructure
UINT64 ExternalClock = 0; UINT64 ExternalClock = 0;
UINT32 CurrentSpeed = 0; UINT32 CurrentSpeed = 0;
UINT32 MaxSpeed = 0; UINT32 MaxSpeed = 0;
SmbiosDiscoveredSettings() {} SmbiosDiscoveredSettings() {}
}; };
@ -102,13 +109,13 @@ class SmbiosDiscoveredSettings
* All settings that'll be injected goes into this struct. * All settings that'll be injected goes into this struct.
* Goal : No globals used by patchTablexxx functions * Goal : No globals used by patchTablexxx functions
* The method that initialises this is SmbiosFillPatchingValues() * The method that initialises this is SmbiosFillPatchingValues()
* Q: Why is this intersting ? Isn't it just copy and we should let smbios.cpp access globals, like gCPUStructure ? * Q: Why is this interesting ? Isn't it just copy and we should let smbios.cpp access globals, like gCPUStructure ?
* A: Problems with globals, is that don't control where they are accessed from. * A: Problems with globals, is that you don't know where they are accessed from.
* Imagine you have a wrong information sent to Smbios. * Imagine you have a wrong information sent to Smbios.
* Putting a breakpoint or a log in SmbiosInjectedSettings::takeValueFrom, you immediatley know if the problem is * Putting a breakpoint or a log in SmbiosInjectedSettings::takeValueFrom, you immediately know if the problem is
* on the Clover side (wrong info given by Clover) or on the Smbios patch side (Right info but wrong way of patching smbios table). * on the Clover side (wrong info given by Clover) or on the Smbios patch side (Right info but wrong way of patching smbios table).
* This way, Smbios is a layer (or toolbox) independent of Clover. * This way, Smbios is a layer (or toolbox) independent of Clover.
* SmbiosInjectedSettings is a "touch point" (some say "bridge") between layer. Of course it has to have only 1 or 2, easily identifiable. * SmbiosInjectedSettings is a "touch point" (some say "bridge") between layer. Of course there should only be 1 (or 2), easily identifiable "touch point".
* SmbiosFillPatchingValues() is THE place to make some checks, gather values and be sure of what to send to the patching functions. * SmbiosFillPatchingValues() is THE place to make some checks, gather values and be sure of what to send to the patching functions.
* *
* NOTE : I know it's tempting not to do it because it's a lot of copy/paste. But it's so much a time saver later to have better/simpler design... * NOTE : I know it's tempting not to do it because it's a lot of copy/paste. But it's so much a time saver later to have better/simpler design...
@ -218,22 +225,61 @@ class SmbiosInjectedSettings
SmbiosInjectedSettings() {} SmbiosInjectedSettings() {}
}; };
class RAM_SLOT_INFO_Array
{
XObjArray<RAM_SLOT_INFO> m_RAM_SLOT_INFO_Array = XObjArray<RAM_SLOT_INFO>();
public:
const XBool doesSlotForIndexExist(uint8_t idx2Look4) const {
for ( size_t idx = 0 ; idx < m_RAM_SLOT_INFO_Array.size() ; ++idx ) {
if ( m_RAM_SLOT_INFO_Array[idx].SlotIndex == idx2Look4 ) return true;
}
return false;
}
template<typename IntegralType, enable_if(is_integral(IntegralType))>
const RAM_SLOT_INFO& getSlotInfoForSlotIndex(IntegralType nIndex) {
//DebugLog(1, "SPDArray:[] : index = %lld, size=%zd\n", (uint64_t)nIndex, m_RAM_SLOT_INFO_Array.size());
if ( nIndex < 0 ) {
log_technical_bug("%s : nIndex < 0", __PRETTY_FUNCTION__);
return nullRAM_SLOT_INFO;
}
for ( size_t idx = 0 ; idx < m_RAM_SLOT_INFO_Array.size() ; ++idx ) {
if ( m_RAM_SLOT_INFO_Array[idx].SlotIndex == (unsigned_type(IntegralType))nIndex ) return m_RAM_SLOT_INFO_Array[idx];
}
return nullRAM_SLOT_INFO;
}
size_t getSlotCount() const
{
size_t max = 0;
for ( size_t idx = 0 ; idx < m_RAM_SLOT_INFO_Array.size() ; ++idx ) {
if ( m_RAM_SLOT_INFO_Array[idx].ModuleSize > 0 ) {
if ( m_RAM_SLOT_INFO_Array[idx].SlotIndex > max ) max = m_RAM_SLOT_INFO_Array[idx].SlotIndex;
}
}
return max+1;
};
size_t size() const { return m_RAM_SLOT_INFO_Array.size(); }
void AddReference(RAM_SLOT_INFO* rsiPtr, XBool freeIt) { m_RAM_SLOT_INFO_Array.AddReference(rsiPtr, freeIt); }
};
class MEM_STRUCTURE class MEM_STRUCTURE
{ {
public: public:
UINT32 Frequency = UINT32(); UINT32 Frequency = 0;
UINT32 Divider = UINT32(); UINT32 Divider = 0;
UINT8 TRC = UINT8(); UINT8 TRC = 0;
UINT8 TRP = UINT8(); UINT8 TRP = 0;
UINT8 RAS = UINT8(); UINT8 RAS = 0;
UINT8 Channels = UINT8(); UINT8 Channels = 0;
UINT8 Slots = UINT8(); UINT8 Slots = 0;
UINT8 Type = UINT8(); UINT8 Type = 0;
UINT8 SPDInUse = UINT8();
UINT8 SMBIOSInUse = UINT8();
RAM_SLOT_INFO SPD[MAX_RAM_SLOTS * 4]; RAM_SLOT_INFO_Array SPD = RAM_SLOT_INFO_Array();
RAM_SLOT_INFO SMBIOS[MAX_RAM_SLOTS * 4]; RAM_SLOT_INFO_Array SMBIOS = RAM_SLOT_INFO_Array();
}; };

View File

@ -694,43 +694,64 @@ STATIC void read_smb(EFI_PCI_IO_PROTOCOL *PciIo, UINT16 vid, UINT16 did)
// Copy spd data into buffer // Copy spd data into buffer
DBG("SPD[%d]: Type %d @0x%X\n", i, spdbuf[SPD_MEMORY_TYPE], 0x50 + i); DBG("SPD[%d]: Type %d @0x%X\n", i, spdbuf[SPD_MEMORY_TYPE], 0x50 + i);
RAM_SLOT_INFO* rsiPtr = NULL;
switch (spdbuf[SPD_MEMORY_TYPE]) { switch (spdbuf[SPD_MEMORY_TYPE]) {
case SPD_MEMORY_TYPE_SDRAM_DDR: case SPD_MEMORY_TYPE_SDRAM_DDR: {
init_spd(spd_indexes_ddr, spdbuf, base, i); init_spd(spd_indexes_ddr, spdbuf, base, i);
gRAM.SPD[i].Type = MemoryTypeDdr; rsiPtr = new RAM_SLOT_INFO;
gRAM.SPD[i].ModuleSize = (((1 << ((spdbuf[SPD_NUM_ROWS] & 0x0f) RAM_SLOT_INFO& rsi = *rsiPtr;
rsi.SlotIndex = i;
rsi.Type = MemoryTypeDdr;
rsi.ModuleSize = (((1 << ((spdbuf[SPD_NUM_ROWS] & 0x0f)
+ (spdbuf[SPD_NUM_COLUMNS] & 0x0f) - 17)) * + (spdbuf[SPD_NUM_COLUMNS] & 0x0f) - 17)) *
((spdbuf[SPD_NUM_DIMM_BANKS] & 0x7) + 1) * ((spdbuf[SPD_NUM_DIMM_BANKS] & 0x7) + 1) *
spdbuf[SPD_NUM_BANKS_PER_SDRAM])/3)*2; spdbuf[SPD_NUM_BANKS_PER_SDRAM])/3)*2;
break; break;
}
case SPD_MEMORY_TYPE_SDRAM_DDR2: case SPD_MEMORY_TYPE_SDRAM_DDR2: {
init_spd(spd_indexes_ddr, spdbuf, base, i); init_spd(spd_indexes_ddr, spdbuf, base, i);
gRAM.SPD[i].Type = MemoryTypeDdr2; rsiPtr = new RAM_SLOT_INFO;
gRAM.SPD[i].ModuleSize = ((1 << ((spdbuf[SPD_NUM_ROWS] & 0x0f) RAM_SLOT_INFO& rsi = *rsiPtr;
rsi.SlotIndex = i;
rsi.Type = MemoryTypeDdr2;
rsi.ModuleSize = ((1 << ((spdbuf[SPD_NUM_ROWS] & 0x0f)
+ (spdbuf[SPD_NUM_COLUMNS] & 0x0f) - 17)) * + (spdbuf[SPD_NUM_COLUMNS] & 0x0f) - 17)) *
((spdbuf[SPD_NUM_DIMM_BANKS] & 0x7) + 1) * ((spdbuf[SPD_NUM_DIMM_BANKS] & 0x7) + 1) *
spdbuf[SPD_NUM_BANKS_PER_SDRAM]); spdbuf[SPD_NUM_BANKS_PER_SDRAM]);
break; break;
}
case SPD_MEMORY_TYPE_SDRAM_DDR3: case SPD_MEMORY_TYPE_SDRAM_DDR3: {
init_spd(spd_indexes_ddr3, spdbuf, base, i); init_spd(spd_indexes_ddr3, spdbuf, base, i);
gRAM.SPD[i].Type = MemoryTypeDdr3; rsiPtr = new RAM_SLOT_INFO;
gRAM.SPD[i].ModuleSize = ((spdbuf[4] & 0x0f) + 28 ) + ((spdbuf[8] & 0x7) + 3 ); RAM_SLOT_INFO& rsi = *rsiPtr;
gRAM.SPD[i].ModuleSize -= (spdbuf[7] & 0x7) + 25;
gRAM.SPD[i].ModuleSize = ((1 << gRAM.SPD[i].ModuleSize) * (((spdbuf[7] >> 3) & 0x1f) + 1)); rsi.SlotIndex = i;
rsi.Type = MemoryTypeDdr3;
rsi.ModuleSize = ((spdbuf[4] & 0x0f) + 28 ) + ((spdbuf[8] & 0x7) + 3 );
rsi.ModuleSize -= (spdbuf[7] & 0x7) + 25;
rsi.ModuleSize = ((1 << rsi.ModuleSize) * (((spdbuf[7] >> 3) & 0x1f) + 1));
break; break;
}
case SPD_MEMORY_TYPE_SDRAM_DDR4: case SPD_MEMORY_TYPE_SDRAM_DDR4: {
init_spd(spd_indexes_ddr4, spdbuf, base, i); init_spd(spd_indexes_ddr4, spdbuf, base, i);
gRAM.SPD[i].Type = MemoryTypeDdr4; rsiPtr = new RAM_SLOT_INFO;
RAM_SLOT_INFO& rsi = *rsiPtr;
gRAM.SPD[i].ModuleSize rsi.SlotIndex = i;
rsi.Type = MemoryTypeDdr4;
rsi.ModuleSize
= (1 << ((spdbuf[4] & 0x0f) + 8 /* Mb */ - 3 /* MB */)) // SDRAM Capacity = (1 << ((spdbuf[4] & 0x0f) + 8 /* Mb */ - 3 /* MB */)) // SDRAM Capacity
* (1 << ((spdbuf[13] & 0x07) + 3)) // Primary Bus Width * (1 << ((spdbuf[13] & 0x07) + 3)) // Primary Bus Width
/ (1 << ((spdbuf[12] & 0x07) + 2)) // SDRAM Width / (1 << ((spdbuf[12] & 0x07) + 2)) // SDRAM Width
@ -795,26 +816,26 @@ STATIC void read_smb(EFI_PCI_IO_PROTOCOL *PciIo, UINT16 vid, UINT16 did)
111 = 8 die 111 = 8 die
*/ */
break; break;
}
default: default:
gRAM.SPD[i].ModuleSize = 0;
break; break;
} }
if (gRAM.SPD[i].ModuleSize == 0) continue; if (rsiPtr == NULL) continue;
RAM_SLOT_INFO& rsi = *rsiPtr;
//spd_type = (slot->spd[SPD_MEMORY_TYPE] < ((UINT8) 12) ? slot->spd[SPD_MEMORY_TYPE] : 0); //spd_type = (slot->spd[SPD_MEMORY_TYPE] < ((UINT8) 12) ? slot->spd[SPD_MEMORY_TYPE] : 0);
//gRAM Type = spd_mem_to_smbios[spd_type]; //gRAM Type = spd_mem_to_smbios[spd_type];
gRAM.SPD[i].PartNo.takeValueFrom(getDDRPartNum(spdbuf, base, i)); rsi.PartNo.takeValueFrom(getDDRPartNum(spdbuf, base, i));
gRAM.SPD[i].PartNo.trim(); rsi.PartNo.trim();
gRAM.SPD[i].Vendor.takeValueFrom(getVendorName(&(gRAM.SPD[i]), spdbuf, base, i)); rsi.Vendor.takeValueFrom(getVendorName(&(rsi), spdbuf, base, i));
gRAM.SPD[i].Vendor.trim(); rsi.Vendor.trim();
gRAM.SPD[i].SerialNo.takeValueFrom(getDDRSerial(spdbuf)); rsi.SerialNo.takeValueFrom(getDDRSerial(spdbuf));
gRAM.SPD[i].SerialNo.trim(); rsi.SerialNo.trim();
//XXX - when we can FreePool allocated for these buffers? No this is pointer copy //XXX - when we can FreePool allocated for these buffers? No this is pointer copy
// determine spd speed // determine spd speed
speed = getDDRspeedMhz(spdbuf); speed = getDDRspeedMhz(spdbuf);
DBG("DDR speed %dMHz\n", speed); DBG("DDR speed %dMHz\n", speed);
if (gRAM.SPD[i].Frequency<speed) gRAM.SPD[i].Frequency = speed; if (rsi.Frequency<speed) rsi.Frequency = speed;
#if 0 #if 0
// pci memory controller if available, is more reliable // pci memory controller if available, is more reliable
@ -829,22 +850,22 @@ STATIC void read_smb(EFI_PCI_IO_PROTOCOL *PciIo, UINT16 vid, UINT16 did)
case 98: freq+=2;break; case 98: freq+=2;break;
case 99: freq++; break; case 99: freq++; break;
} }
gRAM.SPD[i].Frequency = freq; rsi.Frequency = freq;
DBG("RAM speed %dMHz\n", freq); DBG("RAM speed %dMHz\n", freq);
} }
#endif #endif
MsgLog("Slot: %d Type %d %dMB %dMHz Vendor=%s PartNo=%s SerialNo=%s\n", MsgLog("Slot: %d Type %d %dMB %dMHz Vendor=%s PartNo=%s SerialNo=%s\n",
i, i,
(int)gRAM.SPD[i].Type, (int)rsi.Type,
gRAM.SPD[i].ModuleSize, rsi.ModuleSize,
gRAM.SPD[i].Frequency, rsi.Frequency,
gRAM.SPD[i].Vendor.c_str(), rsi.Vendor.c_str(),
gRAM.SPD[i].PartNo.c_str(), rsi.PartNo.c_str(),
gRAM.SPD[i].SerialNo.c_str()); rsi.SerialNo.c_str());
gRAM.SPD[i].InUse = true; // rsi.InUse = true;
++(gRAM.SPDInUse); gRAM.SPD.AddReference(rsiPtr, true);
//} //}
// laptops sometimes show slot 0 and 2 with slot 1 empty when only 2 slots are presents so: // laptops sometimes show slot 0 and 2 with slot 1 empty when only 2 slots are presents so:

View File

@ -4,26 +4,48 @@
// Currently only compiling 64 bits. // Currently only compiling 64 bits.
// If compiling for other size, #ifdef the static_assert depending of the platform and adjust constant (INT_MIN, INT_MAX) // If compiling for other size, #ifdef the static_assert depending of the platform and adjust constant (INT_MIN, INT_MAX)
#ifdef __cplusplus #ifdef __cplusplus
static_assert(sizeof(int) != 8, "sizeof(int) != 8"); static_assert(sizeof(char) == 1, "sizeof(char) != 1");
static_assert(sizeof(short) == 2, "sizeof(short) != 2");
static_assert(sizeof(int) == 4, "sizeof(int) != 4");
static_assert(sizeof(long) == 8, "sizeof(long) != 8"); // Jief : I think this break on Windows. Conditional compilation rquired to restore Windows compatibility
static_assert(sizeof(long long) == 8, "sizeof(long long) != 8");
static_assert(true, "true");
#endif #endif
#define INT8_MIN (-128) #define INT8_MIN (-128)
#define INT16_MIN (-32768) #define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1) #define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1) #define INT64_MIN (-9223372036854775807LL - 1)
#define INT_MIN INT64_MIN
#define INT8_MAX 127 #define INT8_MAX 127
#define INT16_MAX 32767 #define INT16_MAX 32767
#define INT32_MAX 2147483647 #define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL #define INT64_MAX 9223372036854775807LL
#define INT_MAX INT64_MAX
#define UINT8_MAX 0xff /* 255U */ #define UINT8_MAX 0xff /* 255U */
#define UINT16_MAX 0xffff /* 65535U */ #define UINT16_MAX 0xffff /* 65535U */
#define UINT32_MAX 0xffffffff /* 4294967295U */ #define UINT32_MAX 0xffffffff /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ #define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
#define CHAR_MIN (-128)
#define SCHAR_MIN (-128)
#define SHRT_MIN (-32768)
#define INT_MIN INT32_MIN
#define LONG_MIN INT64_MIN
#define LLONG_MIN INT64_MIN
#define CHAR_MAX 127
#define SCHAR_MAX 127
#define SHRT_MAX 32767
#define INT_MAX INT32_MAX
#define LONG_MAX INT64_MAX
#define LLONG_MAX INT64_MAX
#define UCHAR_MAX 255
#define USHRT_MAX 65535
#define UINT_MAX UINT32_MAX
#define ULONG_MAX UINT64_MAX
#define ULLONG_MAX UINT64_MAX
typedef UINT8 uint8_t; typedef UINT8 uint8_t;
typedef UINT16 uint16_t; typedef UINT16 uint16_t;

View File

@ -21,6 +21,7 @@
#include <IndustryStandard/SmBios.h> // for Smbios memory type #include <IndustryStandard/SmBios.h> // for Smbios memory type
#include "../../Platform/guid.h" #include "../../Platform/guid.h"
#include "../../Platform/platformdata.h" #include "../../Platform/platformdata.h"
#include "../../Platform/smbios.h"
//#include "../cpu.h" //#include "../cpu.h"
#include "../../cpp_lib/undefinable.h" #include "../../cpp_lib/undefinable.h"
@ -64,24 +65,15 @@ public:
public: public:
static ModuleDictClass NullValue; static ModuleDictClass NullValue;
class SlotClass : public XmlUInt64 class SlotIndexClass : public XmlUInt8
{ {
using super = XmlUInt64; using super = XmlUInt8;
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override { virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false; if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
if ( !isDefined() ) return xmlLiteParser->addWarning(generateErrors, S8Printf("Slot must be defined as a number between 0 and 15 inclusive at '%s:%d'", xmlPath.c_str(), keyPos.getLine())); 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()));
if ( value() < 0 ) return xmlLiteParser->addWarning(generateErrors, S8Printf("Slot cannot be negative. It must a number between 0 and 15 inclusive at '%s:%d'", xmlPath.c_str(), keyPos.getLine()));
if ( value() > 15 ) return xmlLiteParser->addWarning(generateErrors, S8Printf("Slot cannot > 15. It must a number between 0 and 15 inclusive at '%s:%d'", xmlPath.c_str(), keyPos.getLine()));
return true; return true;
} }
}; };
XmlUInt64 Slot = XmlUInt64();
XmlUInt32 Size = XmlUInt32();
XmlUInt32 Frequency = XmlUInt32();
XmlString8AllowEmpty Vendor = XmlString8AllowEmpty();
XmlString8AllowEmpty Part = XmlString8AllowEmpty();
XmlString8AllowEmpty Serial = XmlString8AllowEmpty();
class TypeClass: public XmlString8AllowEmpty { class TypeClass: public XmlString8AllowEmpty {
using super = XmlString8AllowEmpty; using super = XmlString8AllowEmpty;
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override { virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
@ -95,10 +87,18 @@ public:
return xmlLiteParser->addWarning(generateErrors, S8Printf("Type must be \"DDR\", \"DDR2\", \"DDR3\" or \"DDR4\" in dict '%s:%d'", xmlPath.c_str(), keyPos.getLine())); return xmlLiteParser->addWarning(generateErrors, S8Printf("Type must be \"DDR\", \"DDR2\", \"DDR3\" or \"DDR4\" in dict '%s:%d'", xmlPath.c_str(), keyPos.getLine()));
} }
public: public:
} Type = TypeClass(); };
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] = { XmlDictField m_fields[7] = {
{"Slot", Slot}, {"Slot", SlotIndex},
{"Size", Size}, {"Size", Size},
{"Frequency", Frequency}, {"Frequency", Frequency},
{"Vendor", Vendor}, {"Vendor", Vendor},
@ -110,12 +110,15 @@ public:
virtual void getFields(XmlDictField** fields, size_t* nb) override { *fields = m_fields; *nb = sizeof(m_fields)/sizeof(m_fields[0]); }; 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 { 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 ( !Slot.isDefined() ) return false; if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) b = false;
return true; 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;
} }
const decltype(Slot)::ValueType& dgetSlotNo() const { return Slot.isDefined() ? Slot.value() : Slot.nullValue; }; // 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(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(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(Vendor)::ValueType& dgetVendor() const { return Vendor.isDefined() ? Vendor.value() : Vendor.nullValue; };
@ -136,17 +139,50 @@ public:
// Cannot happen if validate has been done properly. // Cannot happen if validate has been done properly.
panic("invalid value"); panic("invalid value");
} }
XBool dgetInUse() const { return Size.isDefined() ? Size.value() > 0 : false; }; // XBool dgetInUse() const { return Size.isDefined() ? Size.value() > 0 : false; };
}; };
class ModuleArrayClass : public XmlArray<ModuleDictClass> class ModuleArrayClass : public XmlArray<ModuleDictClass>
{ {
using super = XmlArray<ModuleDictClass>;
public: public:
const ModuleDictClass& dgetSolt(size_t slotNo) const { 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 ) { for ( size_t idx = 0; idx < size(); ++idx ) {
if ( ElementAt(idx).dgetSlotNo() == slotNo ) if ( ElementAt(idx).dgetSlotIndex() == slotIndex )
return ElementAt(idx); return ElementAt(idx);
} }
return ModuleDictClass::NullValue; return ModuleDictClass::NullValue;
@ -171,28 +207,40 @@ public:
virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override { virtual XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false; if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
XBool b = true; XBool b = true;
for ( size_t i = 0 ; i < Modules.size() ; ) {
if ( Modules[i].SlotIndex.value() >= SlotCount.value() ) {
xmlLiteParser->addWarning(generateErrors, S8Printf("Ignore memory module with slot >= SlotCount at '%s:%d'", xmlPath.c_str(), keyPos.getLine()));
Modules.RemoveAtIndex(i);
}else{
i++;
}
}
if ( SlotCount.value() < Modules.dgetCalculatedSlotCount() ) {
log_technical_bug("SlotCount.value() < Modules.dgetCalculatedSlotCount()");
SlotCount.setUInt8Value(Modules.dgetCalculatedSlotCount());
}
return b; return b;
} }
decltype(SlotCount)::ValueType dgetSlotCountSetting() const { return SlotCount.isDefined() ? SlotCount.value() : 0; }; decltype(SlotCount)::ValueType dgetSlotCount() const { return SlotCount.isDefined() ? SlotCount.value() : 0; };
const decltype(Channels)::ValueType& dgetUserChannels() const { return Channels.isDefined() ? Channels.value() : Channels.nullValue; }; const decltype(Channels)::ValueType& dgetUserChannels() const { return Channels.isDefined() ? Channels.value() : Channels.nullValue; };
decltype(SlotCount)::ValueType dgetSlotMax() const { // decltype(SlotCount)::ValueType dgetSlotMax() const {
if ( !isDefined() || !Modules.isDefined() || Modules.size() == 0 ) return 0; // if ( !isDefined() || !Modules.isDefined() || Modules.size() == 0 ) return 0;
uint8_t max = 0; // uint8_t max = 0;
for ( size_t idx = 0 ; idx < Modules.size() ; ++idx ) { // for ( size_t idx = 0 ; idx < Modules.size() ; ++idx ) {
if ( Modules[idx].dgetModuleSize() > 0 ) { // if ( Modules[idx].dgetModuleSize() > 0 ) {
if ( Modules[idx].dgetSlotNo() > UINT8_MAX ) { // if ( Modules[idx].dgetSlotIndex() > UINT8_MAX ) {
log_technical_bug("Modules[idx].dgetSlotNo() > UINT8_MAX"); // log_technical_bug("Modules[idx].dgetSlotNo() > UINT8_MAX");
}else{ // }else{
if ( Modules[idx].dgetSlotNo() > max ) max = (uint8_t)Modules[idx].dgetSlotNo(); // safe cast Modules[idx].dgetSlotNo() is <= UINT8_MAX // if ( Modules[idx].dgetSlotIndex() > max ) max = (uint8_t)Modules[idx].dgetSlotIndex(); // safe cast Modules[idx].dgetSlotNo() is <= UINT8_MAX
} // }
} // }
} // }
return max+1; // return max+1;
}; // };
//
decltype(SlotCount)::ValueType dgetSlotCounts() const { return dgetSlotCountSetting() > dgetSlotMax() ? dgetSlotCountSetting() : dgetSlotMax(); }; // decltype(SlotCount)::ValueType dgetSlotCounts() const { return dgetSlotCountSetting() > dgetSlotMax() ? dgetSlotCountSetting() : dgetSlotMax(); };
}; };
@ -620,7 +668,7 @@ public:
decltype(SmbiosVersion)::ValueType dgetSmbiosVersion() const { return SmbiosVersion.isDefined() ? SmbiosVersion.value() : 0x204; }; decltype(SmbiosVersion)::ValueType dgetSmbiosVersion() const { return SmbiosVersion.isDefined() ? SmbiosVersion.value() : 0x204; };
decltype(MemoryRank)::ValueType dgetAttribute() const { return MemoryRank.isDefined() ? MemoryRank.value() : -1; }; decltype(MemoryRank)::ValueType dgetAttribute() const { return MemoryRank.isDefined() ? MemoryRank.value() : -1; };
decltype(Trust)::ValueType dgetTrustSMBIOS() const { return Trust.isDefined() ? Trust.value() : XBool(true); }; decltype(Trust)::ValueType dgetTrustSMBIOS() const { return Trust.isDefined() ? Trust.value() : XBool(true); };
XBool dgetInjectMemoryTables() const { return Memory.Modules.isDefined() && Memory.Modules.size() > 0 ? Memory.dgetSlotCounts() > 0 : false; }; XBool dgetInjectMemoryTables() const { return Memory.Modules.isDefined() && Memory.Modules.size() > 0 ? Memory.dgetSlotCount() > 0 : false; };
decltype(PlatformFeature)::ValueType dgetgPlatformFeature() const { decltype(PlatformFeature)::ValueType dgetgPlatformFeature() const {
if ( PlatformFeature.isDefined() ) return PlatformFeature.value(); if ( PlatformFeature.isDefined() ) return PlatformFeature.value();
return GetPlatformFeature(dgetModel()); return GetPlatformFeature(dgetModel());

View File

@ -12,6 +12,65 @@
#ifdef __cplusplus #ifdef __cplusplus
#include <stddef.h> // size_t #include <stddef.h> // size_t
#include <stdint.h> // CHAR_MIN etc.
template< class T > struct _xtools__remove_ref { typedef T type; };
template< class T > struct _xtools__remove_ref<T&> { typedef T type; };
template< class T > struct _xtools__remove_const { typedef T type; };
template< class T > struct _xtools__remove_const<const T> { typedef T type; };
template< class T > struct _xtools__remove_const<const T&> { typedef T& type; };
template< class T > struct _xtools__remove_const<const T*> { typedef T* type; };
template< class T > struct _xtools__remove_const_ptr { typedef T type; };
template< class T > struct _xtools__remove_const_ptr<const T> { typedef T type; };
template< class T > struct _xtools__remove_const_ptr<T*> { typedef T type; };
template< class T > struct _xtools__remove_const_ptr<const T*> { typedef T type; };
template< class T, int n > struct _xtools__remove_const_ptr<T[n]> { typedef T type; };
template< class T, int n > struct _xtools__remove_const_ptr<const T[n]> { typedef T type; };
template <class _Tp>
struct __numeric_limits {};
template <> struct __numeric_limits< char> {static constexpr char min() { return CHAR_MIN; }
static constexpr char max() { return CHAR_MAX; } };
template <> struct __numeric_limits< signed char> {static constexpr signed char min() { return SCHAR_MIN; }
static constexpr signed char max() { return SCHAR_MAX; } };
template <> struct __numeric_limits< unsigned char> {static constexpr unsigned char min() { return 0; }
static constexpr unsigned char max() { return UCHAR_MAX; } };
template <> struct __numeric_limits< char16_t> {static constexpr char16_t min() { return 0; }
static constexpr char16_t max() { return UINT16_MAX; } };
template <> struct __numeric_limits< char32_t> {static constexpr char32_t min() { return 0; }
static constexpr char32_t max() { return UINT32_MAX; } };
template <> struct __numeric_limits< wchar_t> {static constexpr wchar_t min() { return 0; }
static constexpr wchar_t max() { return __WCHAR_MAX__; } };
template <> struct __numeric_limits< short> {static constexpr short min() { return SHRT_MIN; }
static constexpr short max() { return SHRT_MAX; } };
template <> struct __numeric_limits< unsigned short> {static constexpr unsigned short min() { return 0; }
static constexpr unsigned short max() { return USHRT_MAX; } };
template <> struct __numeric_limits< int> {static constexpr int min() { return INT_MIN; }
static constexpr int max() { return INT_MAX; } };
template <> struct __numeric_limits< unsigned int> {static constexpr unsigned int min() { return 0; }
static constexpr unsigned int max() { return UINT_MAX; } };
template <> struct __numeric_limits< long> {static constexpr long min() { return LONG_MIN; }
static constexpr long max() { return LONG_MAX; } };
template <> struct __numeric_limits< unsigned long> {static constexpr unsigned long min() { return 0; }
static constexpr unsigned long max() { return ULONG_MAX; } };
template <> struct __numeric_limits< long long> {static constexpr long long min() { return LLONG_MIN; }
static constexpr long long max() { return LLONG_MAX; } };
template <> struct __numeric_limits<unsigned long long> {static constexpr unsigned long long min() { return 0; }
static constexpr unsigned long long max() { return ULLONG_MAX; } };
template <class _Tp>
class numeric_limits : public __numeric_limits<typename _xtools__remove_const<_Tp>::type>
{
};
struct _xtools__false_type { struct _xtools__false_type {
static constexpr bool value = false; static constexpr bool value = false;
@ -108,23 +167,6 @@ template <> struct _xtools__is_bool_st<bool> : public
// typedef _Ty type; // typedef _Ty type;
// }; // };
template< class T > struct _xtools__remove_ref { typedef T type; };
template< class T > struct _xtools__remove_ref<T&> { typedef T type; };
template< class T > struct _xtools__remove_const { typedef T type; };
template< class T > struct _xtools__remove_const<const T> { typedef T type; };
template< class T > struct _xtools__remove_const<const T&> { typedef T& type; };
template< class T > struct _xtools__remove_const<const T*> { typedef T* type; };
template< class T > struct _xtools__remove_const_ptr { typedef T type; };
template< class T > struct _xtools__remove_const_ptr<const T> { typedef T type; };
template< class T > struct _xtools__remove_const_ptr<T*> { typedef T type; };
template< class T > struct _xtools__remove_const_ptr<const T*> { typedef T type; };
template< class T, int n > struct _xtools__remove_const_ptr<T[n]> { typedef T type; };
template< class T, int n > struct _xtools__remove_const_ptr<const T[n]> { typedef T type; };
// is_char_ptr // is_char_ptr
template <class _Tp> struct _xtools__is_char_ptr_st : public _xtools__false_type {}; template <class _Tp> struct _xtools__is_char_ptr_st : public _xtools__false_type {};
template <> struct _xtools__is_char_ptr_st<char*> : public _xtools__true_type {}; template <> struct _xtools__is_char_ptr_st<char*> : public _xtools__true_type {};