Refactor array of RamSlotInfo and RAM_SLOT_INFO to avoid allocating

empty slots.
Remove the InUse member.
Remove mHandle17, mInstalled, mEnabled global.
Create numeric_limits.
This commit is contained in:
jief666 2021-10-02 20:44:16 +03:00
parent 83b93234be
commit 542b812276
8 changed files with 638 additions and 386 deletions

View File

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

View File

@ -39,14 +39,13 @@ static void SmbiosFillPatchingValues(const SETTINGS_DATA::SmbiosClass::RamSlotIn
{
RAM_SLOT_INFO& ramSlotInfo = *ramSlotInfoPtr;
ramSlotInfo.Slot = other.Slot;
ramSlotInfo.SlotIndex = other.SlotIndex;
ramSlotInfo.ModuleSize = other.ModuleSize;
ramSlotInfo.Frequency = other.Frequency;
ramSlotInfo.Vendor = other.Vendor;
ramSlotInfo.PartNo = other.PartNo;
ramSlotInfo.SerialNo = other.SerialNo;
ramSlotInfo.Type = other.Type;
ramSlotInfo.InUse = other.InUse;
}
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;
Memory.SlotCounts = other.SlotCounts;
Memory.SlotCount = other.SlotCount;
Memory.UserChannels = other.UserChannels;
SmbiosFillPatchingValues(other.User, &Memory._User);
}
@ -144,7 +143,12 @@ void SmbiosFillPatchingValues(XBool _SetTable132, uint8_t pEnabledCores, uint16_
smbiosInjectedSetting.SetTable132 = _SetTable132;
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;
UINT16 mHandle3;
UINT16 mHandle16 = 0x1000;
UINT16 mHandle17[MAX_RAM_SLOTS];
//UINT16 mHandle17[MAX_RAM_SLOTS];
UINT16 mHandle19;
UINT16 mMemory17[MAX_RAM_SLOTS];
UINT64 mInstalled[MAX_RAM_SLOTS];
UINT64 mEnabled[MAX_RAM_SLOTS];
//UINT64 mInstalled[MAX_RAM_SLOTS];
//UINT64 mEnabled[MAX_RAM_SLOTS];
XBool gMobile;
UINT8 gBootStatus;
XBool Once;
@ -965,35 +964,35 @@ void PatchTableType4(const SmbiosInjectedSettings& smbiosSettings)
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type4->SerialNumber, BrandStr);
}
#ifdef JIEF_DEBUG
DBG("newSmbiosTable.Type4->AssetTag=%d\n", newSmbiosTable.Type4->AssetTag);
DBG("newSmbiosTable.Type4->CoreCount=%d\n", newSmbiosTable.Type4->CoreCount);
DBG("newSmbiosTable.Type4->CoreCount2=%d\n", newSmbiosTable.Type4->CoreCount2);
DBG("newSmbiosTable.Type4->CurrentSpeed=%d\n", newSmbiosTable.Type4->CurrentSpeed);
DBG("newSmbiosTable.Type4->EnabledCoreCount=%d\n", newSmbiosTable.Type4->EnabledCoreCount);
DBG("newSmbiosTable.Type4->EnabledCoreCount2=%d\n", newSmbiosTable.Type4->EnabledCoreCount2);
DBG("newSmbiosTable.Type4->ExternalClock=%d\n", newSmbiosTable.Type4->ExternalClock);
DBG("newSmbiosTable.Type4->L1CacheHandle=%d\n", newSmbiosTable.Type4->L1CacheHandle);
DBG("newSmbiosTable.Type4->L2CacheHandle=%d\n", newSmbiosTable.Type4->L2CacheHandle);
DBG("newSmbiosTable.Type4->L3CacheHandle=%d\n", newSmbiosTable.Type4->L3CacheHandle);
DBG("newSmbiosTable.Type4->MaxSpeed=%d\n", newSmbiosTable.Type4->MaxSpeed);
DBG("newSmbiosTable.Type4->PartNumber=%d\n", newSmbiosTable.Type4->PartNumber);
DBG("newSmbiosTable.Type4->ProcessorCharacteristics=%d\n", newSmbiosTable.Type4->ProcessorCharacteristics);
DBG("newSmbiosTable.Type4->ProcessorFamily=%d\n", newSmbiosTable.Type4->ProcessorFamily);
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.Signatur=%d\n", *(UINT32*)&newSmbiosTable.Type4->ProcessorId.Signature);
DBG("newSmbiosTable.Type4->ProcessorManufacturer=%d\n", newSmbiosTable.Type4->ProcessorManufacturer);
DBG("newSmbiosTable.Type4->ProcessorType=%d\n", newSmbiosTable.Type4->ProcessorType);
DBG("newSmbiosTable.Type4->ProcessorUpgrade=%d\n", newSmbiosTable.Type4->ProcessorUpgrade);
DBG("newSmbiosTable.Type4->ProcessorVersion=%d\n", newSmbiosTable.Type4->ProcessorVersion);
DBG("newSmbiosTable.Type4->SerialNumber=%d\n", newSmbiosTable.Type4->SerialNumber);
DBG("newSmbiosTable.Type4->Socket=%d\n", newSmbiosTable.Type4->Socket);
DBG("newSmbiosTable.Type4->Status=%d\n", newSmbiosTable.Type4->Status);
DBG("newSmbiosTable.Type4->ThreadCount=%d\n", newSmbiosTable.Type4->ThreadCount);
DBG("newSmbiosTable.Type4->ThreadCount2=%d\n", newSmbiosTable.Type4->ThreadCount2);
DBG("newSmbiosTable.Type4->Voltage=%d\n", *(UINT8*)&newSmbiosTable.Type4->Voltage);
#endif
//#ifdef JIEF_DEBUG
//DBG("newSmbiosTable.Type4->AssetTag=%d\n", newSmbiosTable.Type4->AssetTag);
//DBG("newSmbiosTable.Type4->CoreCount=%d\n", newSmbiosTable.Type4->CoreCount);
//DBG("newSmbiosTable.Type4->CoreCount2=%d\n", newSmbiosTable.Type4->CoreCount2);
//DBG("newSmbiosTable.Type4->CurrentSpeed=%d\n", newSmbiosTable.Type4->CurrentSpeed);
//DBG("newSmbiosTable.Type4->EnabledCoreCount=%d\n", newSmbiosTable.Type4->EnabledCoreCount);
//DBG("newSmbiosTable.Type4->EnabledCoreCount2=%d\n", newSmbiosTable.Type4->EnabledCoreCount2);
//DBG("newSmbiosTable.Type4->ExternalClock=%d\n", newSmbiosTable.Type4->ExternalClock);
//DBG("newSmbiosTable.Type4->L1CacheHandle=%d\n", newSmbiosTable.Type4->L1CacheHandle);
//DBG("newSmbiosTable.Type4->L2CacheHandle=%d\n", newSmbiosTable.Type4->L2CacheHandle);
//DBG("newSmbiosTable.Type4->L3CacheHandle=%d\n", newSmbiosTable.Type4->L3CacheHandle);
//DBG("newSmbiosTable.Type4->MaxSpeed=%d\n", newSmbiosTable.Type4->MaxSpeed);
//DBG("newSmbiosTable.Type4->PartNumber=%d\n", newSmbiosTable.Type4->PartNumber);
//DBG("newSmbiosTable.Type4->ProcessorCharacteristics=%d\n", newSmbiosTable.Type4->ProcessorCharacteristics);
//DBG("newSmbiosTable.Type4->ProcessorFamily=%d\n", newSmbiosTable.Type4->ProcessorFamily);
//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.Signatur=%d\n", *(UINT32*)&newSmbiosTable.Type4->ProcessorId.Signature);
//DBG("newSmbiosTable.Type4->ProcessorManufacturer=%d\n", newSmbiosTable.Type4->ProcessorManufacturer);
//DBG("newSmbiosTable.Type4->ProcessorType=%d\n", newSmbiosTable.Type4->ProcessorType);
//DBG("newSmbiosTable.Type4->ProcessorUpgrade=%d\n", newSmbiosTable.Type4->ProcessorUpgrade);
//DBG("newSmbiosTable.Type4->ProcessorVersion=%d\n", newSmbiosTable.Type4->ProcessorVersion);
//DBG("newSmbiosTable.Type4->SerialNumber=%d\n", newSmbiosTable.Type4->SerialNumber);
//DBG("newSmbiosTable.Type4->Socket=%d\n", newSmbiosTable.Type4->Socket);
//DBG("newSmbiosTable.Type4->Status=%d\n", newSmbiosTable.Type4->Status);
//DBG("newSmbiosTable.Type4->ThreadCount=%d\n", newSmbiosTable.Type4->ThreadCount);
//DBG("newSmbiosTable.Type4->ThreadCount2=%d\n", newSmbiosTable.Type4->ThreadCount2);
//DBG("newSmbiosTable.Type4->Voltage=%d\n", *(UINT8*)&newSmbiosTable.Type4->Voltage);
//#endif
Handle = LogSmbiosTable(newSmbiosTable);
}
@ -1016,18 +1015,22 @@ void PatchTableType6(const SmbiosInjectedSettings& smbiosSettings)
continue;
}
SizeField = SmbiosTable.Type6->InstalledSize.InstalledOrEnabledSize & 0x7F;
UINT64 mInstalled = 0;
if (SizeField < 0x7D) {
mInstalled[Index] = LShiftU64(1ULL, 20 + SizeField);
mInstalled = LShiftU64(1ULL, 20 + SizeField);
} else if (SizeField == 0x7F) {
mInstalled[Index] = 0;
} else
mInstalled[Index] = 4096ULL * (1024ULL * 1024ULL);
MsgLog("Table 6 MEMORY_MODULE %zu Installed %llX ", Index, mInstalled[Index]);
mInstalled = 0;
} else {
mInstalled = 4096ULL * (1024ULL * 1024ULL);
}
MsgLog("Table 6 MEMORY_MODULE %zu Installed %llX ", Index, mInstalled);
UINT64 mEnabled = 0;
if (SizeField >= 0x7D) {
mEnabled[Index] = 0;
} else
mEnabled[Index] = LShiftU64(1ULL, 20 + ((UINT8)SmbiosTable.Type6->EnabledSize.InstalledOrEnabledSize & 0x7F));
MsgLog("... enabled %llX \n", mEnabled[Index]);
mEnabled = 0;
} else {
mEnabled = LShiftU64(1ULL, 20 + ((UINT8)SmbiosTable.Type6->EnabledSize.InstalledOrEnabledSize & 0x7F));
}
MsgLog("... enabled %llX \n", mEnabled);
LogSmbiosTable(SmbiosTable);
}
@ -1115,17 +1118,17 @@ void PatchTableType9(const SmbiosInjectedSettings& smbiosSettings)
// SlotType = 32bit PCI/SlotTypePciExpressX1/x4/x16
// real PC -> PCI, real Mac -> PCIe
#ifdef JIEF_DEBUG
for (uint8_t Index = 0; Index <= 15; Index++) {
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].SegmentGroupNum = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SegmentGroupNum);
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].SlotName = %s\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotName.c_str());
DBG("SlotDevice[%hhu].Valid = %d\n", Index, (bool)smbiosSettings.SlotDevices.isSlotForIndexValid(Index));
}
#endif
//#ifdef JIEF_DEBUG
// for (uint8_t Index = 0; Index <= 15; Index++) {
// 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].SegmentGroupNum = %d\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SegmentGroupNum);
// 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].SlotName = %s\n", Index, smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotName.c_str());
// DBG("SlotDevice[%hhu].Valid = %d\n", Index, (bool)smbiosSettings.SlotDevices.isSlotForIndexValid(Index));
// }
//#endif
for (uint8_t Index = 0; Index < 15; Index++) {
if (smbiosSettings.SlotDevices.isSlotForIndexValid(Index)) {
@ -1228,6 +1231,17 @@ void GetTableType16(SmbiosDiscoveredSettings* smbiosSettings)
continue;
}
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;
}
if ( smbiosSettings->RamSlotCount == 0 ) {
@ -1266,16 +1280,47 @@ void PatchTableType16(const SmbiosInjectedSettings& smbiosSettings)
// newSmbiosTable.Type16->MemoryErrorCorrection = MemoryErrorCorrectionMultiBitEcc;
// MemoryErrorInformationHandle
newSmbiosTable.Type16->MemoryErrorInformationHandle = 0xFFFF;
newSmbiosTable.Type16->NumberOfMemoryDevices = MIN(smbiosSettings.RamSlotCount, MAX_RAM_SLOTS);
DBG("NumberOfMemoryDevices = %d\n", MIN(smbiosSettings.RamSlotCount, MAX_RAM_SLOTS));
newSmbiosTable.Type16->NumberOfMemoryDevices = smbiosSettings.RamSlotCount; // RamSlotCount is <= MAX_RAM_SLOTS), see GetTableType16()
DBG("NumberOfMemoryDevices = %d\n", smbiosSettings.RamSlotCount);
LogSmbiosTable(newSmbiosTable);
}
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
//
XBool Found;
XBool FoundOneTable;
// Get Table Type17 and count Size
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);
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);
#endif
//#endif
//gDMI->CntMemorySlots++;
if (SmbiosTable.Type17->MemoryErrorInformationHandle < 0xFFFE) {
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
// to just skip all entries that have an error - apianti
// will try
Found = false;
XBool Found = false;
for (INTN Index2 = 0; Index2 < 24; Index2++) {
newSmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_32BIT_MEMORY_ERROR_INFORMATION, Index2);
if (newSmbiosTable.Raw == NULL) {
@ -1332,18 +1378,23 @@ void GetTableType17(SmbiosDiscoveredSettings* smbiosSettings)
}
}
}
RAM_SLOT_INFO* rsiPtr = NULL;
// Determine if slot has size
if (SmbiosTable.Type17->Size > 0) {
gRAM.SMBIOS[Index].InUse = true;
gRAM.SMBIOS[Index].ModuleSize = SmbiosTable.Type17->Size;
rsiPtr = new RAM_SLOT_INFO;
RAM_SLOT_INFO& rsi = *rsiPtr;
rsi.ModuleSize = SmbiosTable.Type17->Size;
if (SmbiosTable.Type17->Size == 0x7FFF) {
gRAM.SMBIOS[Index].ModuleSize = SmbiosTable.Type17->ExtendedSize;
rsi.ModuleSize = SmbiosTable.Type17->ExtendedSize;
}
}
// Determine if module frequency is sane value
if ((SmbiosTable.Type17->Speed > 0) && (SmbiosTable.Type17->Speed <= MAX_RAM_FREQUENCY)) {
gRAM.SMBIOS[Index].InUse = true;
gRAM.SMBIOS[Index].Frequency = SmbiosTable.Type17->Speed;
if ( rsiPtr == NULL ) rsiPtr = new RAM_SLOT_INFO;
RAM_SLOT_INFO& rsi = *rsiPtr;
rsi.Frequency = SmbiosTable.Type17->Speed;
if (SmbiosTable.Type17->Speed > gRAM.Frequency) {
gRAM.Frequency = SmbiosTable.Type17->Speed;
}
@ -1353,56 +1404,66 @@ void GetTableType17(SmbiosDiscoveredSettings* smbiosSettings)
#endif
}
// Fill rest of information if in use
if (gRAM.SMBIOS[Index].InUse) {
++(gRAM.SMBIOSInUse);
gRAM.SMBIOS[Index].Vendor.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->Manufacturer));
gRAM.SMBIOS[Index].Vendor.trim();
gRAM.SMBIOS[Index].SerialNo.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->SerialNumber));
gRAM.SMBIOS[Index].SerialNo.trim();
gRAM.SMBIOS[Index].PartNo.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->PartNumber));
gRAM.SMBIOS[Index].PartNo.trim();
}
// DBG("CntMemorySlots = %d\n", gDMI->CntMemorySlots)
// DBG("gDMI->MemoryModules = %d\n", gDMI->MemoryModules)
if ((SmbiosTable.Type17->Speed > 0) && (SmbiosTable.Type17->Speed <= MAX_RAM_FREQUENCY)) {
DBG("SmbiosTable.Type17->Speed = %dMHz\n", gRAM.SMBIOS[Index].Frequency);
DBG("SmbiosTable.Type17->Size = %dMB\n", gRAM.SMBIOS[Index].ModuleSize);
if ( rsiPtr != NULL ) {
//++(gRAM.SMBIOSInUse);
RAM_SLOT_INFO& rsi = *rsiPtr;
rsi.SlotIndex = Index;
rsi.Vendor.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->Manufacturer));
rsi.Vendor.trim();
rsi.SerialNo.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->SerialNumber));
rsi.SerialNo.trim();
rsi.PartNo.takeValueFrom(GetSmbiosString(SmbiosTable, SmbiosTable.Type17->PartNumber));
rsi.PartNo.trim();
gRAM.SMBIOS.AddReference(rsiPtr, true);
DBG("SmbiosTable.Type17->SlotIndex = %d\n", rsi.SlotIndex);
DBG("SmbiosTable.Type17->ModuleSize = %dMB\n", rsi.ModuleSize);
DBG("SmbiosTable.Type17->Type = %dMB\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->Vendor = %s\n", gRAM.SMBIOS[Index].Vendor.c_str());
DBG("SmbiosTable.Type17->SerialNumber = %s\n", gRAM.SMBIOS[Index].SerialNo.c_str());
DBG("SmbiosTable.Type17->PartNumber = %s\n", gRAM.SMBIOS[Index].PartNo.c_str());
DBG("SmbiosTable.Type17->Vendor = %s\n", rsi.Vendor.c_str());
DBG("SmbiosTable.Type17->SerialNo = %s\n", rsi.SerialNo.c_str());
DBG("SmbiosTable.Type17->PartNo = %s\n", rsi.PartNo.c_str());
}
/*
if ((SmbiosTable.Type17->Size & 0x8000) == 0) {
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);
*/
}
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 bankLocator;
UINT8 channelMap[MAX_RAM_SLOTS];
UINT8 channelMap[mMemory17.size()]; // mMemory17.size() == SlotCounts
UINT8 expectedCount = 0;
UINT8 channels = 2;
XBool insertingEmpty = true;
XBool trustSMBIOS = ((gRAM.SPDInUse == 0) || smbiosSettings.TrustSMBIOS);
XBool trustSMBIOS = ( gRAM.SPD.size() == 0 || smbiosSettings.TrustSMBIOS);
XBool wrongSMBIOSBanks = false;
XBool isMacPro = false;
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;
}
// Inject user memory tables
if (smbiosSettings.InjectMemoryTables)
{
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");
return;
}
@ -1411,46 +1472,46 @@ void PatchTableType17(const SmbiosInjectedSettings& smbiosSettings)
if ( UserChannels == 0 || UserChannels > 8 ) {
UserChannels = 1;
}
auto SlotCounts = smbiosSettings.Memory.SlotCounts;
if ( SlotCounts >= MAX_RAM_SLOTS ) {
SlotCounts = MAX_RAM_SLOTS;
}
DBG("Channels: %d\n", UserChannels);
// Setup interleaved channel map
if (channels >= 2) {
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) +
((Index / UserChannels) % 2) + ((Index % UserChannels) << 1));
}
} else {
for (size_t Index = 0; Index < MAX_RAM_SLOTS; ++Index) {
for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
channelMap[Index] = (UINT8)Index;
}
}
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("\n");
// Memory Device
//
// Inject tables
#ifdef JIEF_DEBUG
DBG("gSettings.Smbios.Memory.SlotCounts=%d\n", smbiosSettings.Memory.SlotCounts);
DBG("gSettings.Smbios.Memory.UserChannels=%d\n", smbiosSettings.Memory.UserChannels);
for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
DBG("gSettings.Smbios.Memory.User[%lld].Frequency=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Frequency);
DBG("gSettings.Smbios.Memory.User[%lld].InUse=%d\n", Index, (bool)smbiosSettings.Memory.getSlotInfoForSlotID(Index).InUse);
DBG("gSettings.Smbios.Memory.User[%lld].ModuleSize=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).ModuleSize);
DBG("gSettings.Smbios.Memory.User[%lld].PartNo=%s\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).PartNo.c_str());
DBG("gSettings.Smbios.Memory.User[%lld].SerialNo=%s\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).SerialNo.c_str());
DBG("gSettings.Smbios.Memory.User[%lld].Type=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Type);
DBG("gSettings.Smbios.Memory.User[%lld].Vendor=%s\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Vendor.c_str());
}
#endif
DBG("user SMBIOS data:\n");
DBG(" smbiosSettings.RamSlotCount=%d\n", smbiosSettings.RamSlotCount);
DBG(" smbiosSettings.Memory.SlotCounts=%d\n", smbiosSettings.Memory.SlotCount);
DBG(" smbiosSettings.Memory.UserChannels=%d\n", smbiosSettings.Memory.UserChannels);
for (size_t Index = 0; Index < smbiosSettings.RamSlotCount; Index++) {
if ( smbiosSettings.Memory.doesSlotForIndexExist(Index) ) {
DBG(" smbiosSettings.Memory slot %zu\n", Index);
DBG(" smbiosSettings.Memory[%zu].ModuleSize=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).ModuleSize);
DBG(" smbiosSettings.Memory[%zu].Type=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Type);
DBG(" smbiosSettings.Memory[%zu].Frequency=%d\n", Index, smbiosSettings.Memory.getSlotInfoForSlotID(Index).Frequency);
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());
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];
UINT8 bank = (UINT8)(Index / UserChannels);
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->DeviceLocator, deviceLocator);
if ((smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).InUse) && (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.doesSlotForIndexExist(UserIndex) && smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).ModuleSize > 0 )
{
if (smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).Vendor.notEmpty()) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).Vendor);
} else {
@ -1522,34 +1579,36 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
DBG("mTotalSystemMemory = %d\n", mTotalSystemMemory);
}
return;
}else{
DBG("Do not inject memory table\n");
}
// 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");
return;
}
// Detect whether the SMBIOS is trusted information
if (trustSMBIOS) {
if (gRAM.SMBIOSInUse != 0) {
if (gRAM.SPDInUse != 0) {
if (gRAM.SPDInUse != gRAM.SMBIOSInUse) {
if (gRAM.SMBIOS.size() != 0) {
if (gRAM.SPD.size() != 0) {
if (gRAM.SPD.size() != gRAM.SMBIOS.size()) {
// 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");
trustSMBIOS = false;
} else if (gRAM.SPD[0].InUse || !gRAM.SMBIOS[0].InUse) {
if (gRAM.SPDInUse > 1) {
} else if (gRAM.SPD.doesSlotForIndexExist(0) || !gRAM.SMBIOS.doesSlotForIndexExist(0)) {
if (gRAM.SPD.size() > 1) {
DBG("Not trusting SMBIOS because SPD reports different modules...\n");
trustSMBIOS = false;
} else if (gRAM.SMBIOSInUse == 1) {
} else if (gRAM.SMBIOS.size() == 1) {
channels = 1;
}
} else if (gRAM.SPDInUse == 1) {
} else if (gRAM.SPD.size() == 1) {
// The SMBIOS may contain table for built-in module
if (gRAM.SMBIOSInUse <= 2) {
if (!gRAM.SMBIOS[0].InUse || !gRAM.SPD[2].InUse ||
(gRAM.SMBIOS[0].Frequency != gRAM.SPD[2].Frequency) ||
(gRAM.SMBIOS[0].ModuleSize != gRAM.SPD[2].ModuleSize)) {
if (gRAM.SMBIOS.size() <= 2) {
if (!gRAM.SMBIOS.doesSlotForIndexExist(0) || !gRAM.SPD.doesSlotForIndexExist(2) ||
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).Frequency != gRAM.SPD.getSlotInfoForSlotIndex(2).Frequency) ||
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize != gRAM.SPD.getSlotInfoForSlotIndex(2).ModuleSize)) {
channels = 1;
}
} 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");
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!
DBG("Not trusting SMBIOS because it's being sneaky...\n");
trustSMBIOS = false;
}
} else if (gRAM.SMBIOSInUse == 1) {
} else if (gRAM.SMBIOS.size() == 1) {
channels = 1;
}
}
@ -1574,11 +1633,11 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
DBG("Trusting SMBIOS...\n");
}
// 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) {
// Use the smbios in use count
if (expectedCount < gRAM.SMBIOSInUse) {
expectedCount = gRAM.SMBIOSInUse;
if (expectedCount < gRAM.SMBIOS.getSlotCount()) {
expectedCount = gRAM.SMBIOS.getSlotCount();
}
// Check if smbios has a good total count
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
if (channels >= 2) {
wrongSMBIOSBanks = ((gRAM.SMBIOS[1].InUse != gRAM.SPD[1].InUse) ||
(gRAM.SMBIOS[1].ModuleSize != gRAM.SPD[1].ModuleSize));
wrongSMBIOSBanks = ((gRAM.SMBIOS.doesSlotForIndexExist(1) != gRAM.SPD.doesSlotForIndexExist(1)) ||
(gRAM.SMBIOS.getSlotInfoForSlotIndex(1).ModuleSize != gRAM.SPD.getSlotInfoForSlotIndex(1).ModuleSize));
}
if (wrongSMBIOSBanks) {
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
if (smbiosSettings.Memory.UserChannels != 0) {
channels = smbiosSettings.Memory.UserChannels;
} else if (gRAM.SPDInUse == 0) {
} else if (gRAM.SPD.size() == 0) {
if (trustSMBIOS) {
if ((gRAM.SMBIOSInUse % 4) == 0) {
if ((gRAM.SMBIOS.size() % 4) == 0) {
// Quadruple channel
if ((wrongSMBIOSBanks &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[1].InUse) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[2].InUse) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[3].InUse) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[1].ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[2].ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[3].ModuleSize)) ||
((gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[2].InUse) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[4].InUse) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[6].InUse) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[2].ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[4].ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[6].ModuleSize))) {
(gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(1)) &&
(gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(2)) &&
(gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(3)) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(1).ModuleSize) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(3).ModuleSize)) ||
((gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(2)) &&
(gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(4)) &&
(gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(6)) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(4).ModuleSize) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(6).ModuleSize))) {
channels = 4;
}
} else if ((gRAM.SMBIOSInUse % 3) == 0) {
} else if ((gRAM.SMBIOS.size() % 3) == 0) {
// Triple channel
if ((wrongSMBIOSBanks &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[1].InUse) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[2].InUse) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[1].ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[2].ModuleSize)) ||
((gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[2].InUse) &&
(gRAM.SMBIOS[0].InUse == gRAM.SMBIOS[4].InUse) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[2].ModuleSize) &&
(gRAM.SMBIOS[0].ModuleSize == gRAM.SMBIOS[4].ModuleSize))) {
(gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(1)) &&
(gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(2)) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(1).ModuleSize) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(2).ModuleSize)) ||
((gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(2)) &&
(gRAM.SMBIOS.doesSlotForIndexExist(0) == gRAM.SMBIOS.doesSlotForIndexExist(4)) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SMBIOS.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SMBIOS.getSlotInfoForSlotIndex(4).ModuleSize))) {
channels = 3;
}
} else if (!wrongSMBIOSBanks && ((gRAM.SMBIOSInUse % 2) != 0)) {
} else if (!wrongSMBIOSBanks && ((gRAM.SMBIOS.size() % 2) != 0)) {
channels = 1;
}
}
} else if ((gRAM.SPDInUse % 4) == 0) {
} else if ((gRAM.SPD.size() % 4) == 0) {
// Quadruple channel
if ((gRAM.SPD[0].InUse == gRAM.SPD[2].InUse) &&
(gRAM.SPD[0].InUse == gRAM.SPD[4].InUse) &&
(gRAM.SPD[0].InUse == gRAM.SPD[6].InUse) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[2].ModuleSize) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[4].ModuleSize) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[6].ModuleSize)) {
if ((gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(2)) &&
(gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(4)) &&
(gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(6)) &&
(gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(4).ModuleSize) &&
(gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(6).ModuleSize)) {
channels = 4;
}
} else if ((gRAM.SPDInUse % 3) == 0) {
} else if ((gRAM.SPD.size() % 3) == 0) {
// Triple channel
if ((gRAM.SPD[0].InUse == gRAM.SPD[2].InUse) &&
(gRAM.SPD[0].InUse == gRAM.SPD[4].InUse) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[2].ModuleSize) &&
(gRAM.SPD[0].ModuleSize == gRAM.SPD[4].ModuleSize)) {
if ((gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(2)) &&
(gRAM.SPD.doesSlotForIndexExist(0) == gRAM.SPD.doesSlotForIndexExist(4)) &&
(gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(2).ModuleSize) &&
(gRAM.SPD.getSlotInfoForSlotIndex(0).ModuleSize == gRAM.SPD.getSlotInfoForSlotIndex(4).ModuleSize)) {
channels = 3;
}
} else if ((gRAM.SPD[0].InUse != gRAM.SPD[2].InUse) ||
((gRAM.SPDInUse % 2) != 0)) {
} else if ((gRAM.SPD.doesSlotForIndexExist(0) != gRAM.SPD.doesSlotForIndexExist(2)) ||
((gRAM.SPD.size() % 2) != 0)) {
channels = 1;
}
// 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
if (channels >= 2) {
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) +
((Index / channels) % 2) + ((Index % channels) << 1));
}
} else {
for (size_t Index = 0; Index < MAX_RAM_SLOTS; ++Index) {
for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
channelMap[Index] = (UINT8)Index;
}
}
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("\n");
// Memory Device
//
for (size_t Index = 0; Index < smbiosSettings.RamSlotCount; Index++) {
UINTN SMBIOSIndex = wrongSMBIOSBanks ? Index : channelMap[Index];
UINTN SPDIndex = channelMap[Index];
for (size_t Index = 0; Index < mMemory17.size(); Index++) {
size_t SMBIOSIndex = wrongSMBIOSBanks ? Index : channelMap[Index];
size_t SPDIndex = channelMap[Index];
UINT8 bank = (UINT8)Index / channels;
if (!insertingEmpty && (Index > expectedCount) &&
!gRAM.SPD[SPDIndex].InUse && (!trustSMBIOS || !gRAM.SMBIOS[SMBIOSIndex].InUse)) {
!gRAM.SPD.doesSlotForIndexExist(SPDIndex) && (!trustSMBIOS || !gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex))) {
continue;
}
SmbiosTable = GetSmbiosTableFromType(EntryPoint, EFI_SMBIOS_TYPE_MEMORY_DEVICE, SMBIOSIndex);
if (trustSMBIOS && gRAM.SMBIOS[SMBIOSIndex].InUse && (SmbiosTable.Raw != NULL)) {
DBG("trusted SMBIOS data:\n");
DBG("SmbiosTable.Type17->Vendor = %s\n", gRAM.SMBIOS[SMBIOSIndex].Vendor.c_str());
DBG("SmbiosTable.Type17->SerialNumber = %s\n", gRAM.SMBIOS[SMBIOSIndex].SerialNo.c_str());
DBG("SmbiosTable.Type17->PartNumber = %s\n", gRAM.SMBIOS[SMBIOSIndex].PartNo.c_str());
if (trustSMBIOS && gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex) && (SmbiosTable.Raw != NULL)) {
DBG("trusted SMBIOS data, table index %zu:\n", SMBIOSIndex);
DBG(" gRAM.SMBIOS[%zu]->ModuleSize = %d\n", SMBIOSIndex, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).ModuleSize);
DBG(" gRAM.SMBIOS[%zu]->Type = %d\n", SMBIOSIndex, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Type);
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);
CopyMem((void*)newSmbiosTable.Type17, (void *)SmbiosTable.Type17, TableSize);
newSmbiosTable.Type17->AssetTag = 0;
if ( gRAM.SMBIOS[SMBIOSIndex].Vendor.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SMBIOS[SMBIOSIndex].Vendor);
// gSettings.MemoryManufacturer.takeValueFrom(gRAM.SMBIOS[SMBIOSIndex].Vendor);
if ( gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor);
} else {
// newSmbiosTable.Type17->Manufacturer = 0;
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, unknown);
}
if ( gRAM.SMBIOS[SMBIOSIndex].SerialNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, gRAM.SMBIOS[SMBIOSIndex].SerialNo);
// gSettings.MemorySerialNumber.takeValueFrom(gRAM.SMBIOS[SMBIOSIndex].SerialNo);
if ( gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).SerialNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).SerialNo);
} else {
// newSmbiosTable.Type17->SerialNumber = 0;
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, unknown);
}
if ( gRAM.SMBIOS[SMBIOSIndex].PartNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, gRAM.SMBIOS[SMBIOSIndex].PartNo);
// gSettings.MemoryPartNumber.takeValueFrom(gRAM.SMBIOS[SMBIOSIndex].PartNo);
DBG(" partNum=%s\n", gRAM.SMBIOS[SMBIOSIndex].PartNo.c_str());
if ( gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).PartNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).PartNo);
//DBG(" Update PartNumber to %s\n", gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).PartNo.c_str());
} else {
// newSmbiosTable.Type17->PartNumber = 0;
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, unknown);
DBG(" partNum unknown\n");
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, unknown);
//DBG(" Set PartNumber unknown\n");
}
} 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);
newSmbiosTable.Type17->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
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->MemoryArrayHandle = mHandle16;
if (gRAM.SPD[SPDIndex].InUse) {
if (gRAM.SPD.doesSlotForIndexExist(SPDIndex)) {
DBG("SPD data in use:\n");
DBG("SmbiosTable.Type17->Vendor = %s\n", gRAM.SPD[SPDIndex].Vendor.c_str());
DBG("SmbiosTable.Type17->SerialNumber = %s\n", gRAM.SPD[SPDIndex].SerialNo.c_str());
DBG("SmbiosTable.Type17->PartNumber = %s\n", gRAM.SPD[SPDIndex].PartNo.c_str());
DBG(" gRAM.SPD[%zu]->ModuleSize = %d\n", SPDIndex, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).ModuleSize);
DBG(" gRAM.SPD[%zu]->Type = %d\n", SPDIndex, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Type);
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() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SPD[SPDIndex].Vendor);
// gSettings.MemoryManufacturer.takeValueFrom(gRAM.SPD[SPDIndex].Vendor);
if ( gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Vendor.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Vendor);
} else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, unknown);
}
if ( gRAM.SPD[SPDIndex].SerialNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, gRAM.SPD[SPDIndex].SerialNo);
// gSettings.MemorySerialNumber.takeValueFrom(gRAM.SPD[SPDIndex].SerialNo);
if ( gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).SerialNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).SerialNo);
} else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, unknown);
}
if ( gRAM.SPD[SPDIndex].PartNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, gRAM.SPD[SPDIndex].PartNo);
// gSettings.MemoryPartNumber.takeValueFrom(gRAM.SPD[SPDIndex].PartNo);
if ( gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).PartNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).PartNo);
} else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, unknown);
}
if (gRAM.Frequency > gRAM.SPD[SPDIndex].Frequency) {
newSmbiosTable.Type17->Speed = (UINT16)gRAM.Frequency;
if (gRAM.Frequency > gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Frequency) {
newSmbiosTable.Type17->Speed = (UINT16)gRAM.Frequency; // unsafe cast
} 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->ExtendedSize = gRAM.SPD[SPDIndex].ModuleSize;
newSmbiosTable.Type17->ExtendedSize = gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).ModuleSize;
} 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 &&
(newSmbiosTable.Type17->Speed < (UINT16)gRAM.SMBIOS[SMBIOSIndex].Frequency)) {
DBG("Type17->Speed corrected by SMBIOS from %dMHz to %dMHz\n", newSmbiosTable.Type17->Speed, gRAM.SMBIOS[SMBIOSIndex].Frequency);
newSmbiosTable.Type17->Speed = (UINT16)gRAM.SMBIOS[SMBIOSIndex].Frequency;
if (trustSMBIOS && gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex) &&
(newSmbiosTable.Type17->Speed < gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Frequency)) {
DBG(" Type17->Speed corrected by SMBIOS from %dMHz to %dMHz\n", newSmbiosTable.Type17->Speed, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Frequency);
newSmbiosTable.Type17->Speed = gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Frequency;
}
if (trustSMBIOS && gRAM.SMBIOS[SMBIOSIndex].InUse &&
gRAM.SMBIOS[SMBIOSIndex].Vendor.notEmpty() &&
( gRAM.SPD[SPDIndex].Vendor.isEmpty() || gRAM.SPD[SPDIndex].Vendor == "NoName"_XS8 )
if (trustSMBIOS && gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex) &&
gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor.notEmpty() &&
( 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());
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SMBIOS[SMBIOSIndex].Vendor);
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.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor);
}
// gSettings.MemorySpeed.S8Printf("%d", newSmbiosTable.Type17->Speed);
@ -1823,7 +1885,7 @@ for (uint64_t Index = 0; Index < smbiosSettings.Memory.SlotCounts; Index++) {
} else {
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) {
DBG("%s %s EMPTY\n", bankLocator.c_str(), deviceLocator.c_str());
newSmbiosTable.Type17->MemoryType = 0; //MemoryTypeUnknown;
@ -1900,7 +1962,7 @@ PatchTableType19 (const SmbiosInjectedSettings& smbiosSettings)
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;
//
@ -1921,10 +1983,9 @@ void PatchTableType20 (const SmbiosInjectedSettings& smbiosSettings)
newSmbiosTable.Type20->MemoryDeviceHandle = mHandle17[j];
k = newSmbiosTable.Type20->EndingAddress;
m += mMemory17[j];
DBG("Type20[%zu]->End = 0x%llX, Type17[%llu] = %llX\n",
Index, k, j, m);
DBG("Type20[%zu]->End = 0x%llX, Type17[%llu] = %llX\n", Index, k, j, m);
// DBG(" MemoryDeviceHandle = 0x%X\n", newSmbiosTable.Type20->MemoryDeviceHandle);
mMemory17[j] = 0; // used
//mMemory17[j] = 0; // used
break;
}
// DBG("\n");
@ -2174,6 +2235,7 @@ EFI_STATUS PrepatchSmbios(SmbiosDiscoveredSettings* smbiosSettings)
GetTableType2(smbiosSettings);
GetTableType3(smbiosSettings);
GetTableType4(smbiosSettings);
// GetTableType16() will initialize smbiosSettings->RamSlotCount. Could be MAX_RAM_SLOTS.
GetTableType16(smbiosSettings);
GetTableType17(smbiosSettings);
GetTableType32(smbiosSettings); //get BootStatus here to decide what to do
@ -2201,10 +2263,20 @@ void PatchSmbios(const SmbiosInjectedSettings& smbiosSettings) //continue
PatchTableType11(smbiosSettings);
}
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);
PatchTableType19(smbiosSettings);
PatchTableType20(smbiosSettings);
PatchTableType20(smbiosSettings, mMemory17, mHandle17);
PatchTableType128(smbiosSettings);
PatchTableType130(smbiosSettings);
PatchTableType131(smbiosSettings);

View File

@ -17,22 +17,21 @@ extern "C" {
// The maximum number of RAM slots to detect
// even for 3-channels chipset X58 there are no more then 8 slots
#define MAX_RAM_SLOTS 24
static_assert(MAX_RAM_SLOTS < UINT8_MAX, "MAX_RAM_SLOTS < UINT8_MAX"); // Important
const uint8_t MAX_RAM_SLOTS = 24;
// The maximum sane frequency for a RAM module
#define MAX_RAM_FREQUENCY 5000
class RAM_SLOT_INFO {
public:
UINT64 Slot = UINT64();
UINT32 ModuleSize = UINT32();
UINT32 Frequency = UINT32();
XString8 Vendor = XString8();
XString8 PartNo = XString8();
XString8 SerialNo = XString8();
UINT8 Type = UINT8();
XBool InUse = false;
UINT32 ModuleSize = 0;
UINT32 Frequency = 0;
XString8 Vendor = XString8();
XString8 PartNo = XString8();
XString8 SerialNo = XString8();
UINT8 Type = 0;
UINT8 SlotIndex = 0;
// XBool InUse = false;
RAM_SLOT_INFO() {}
};
@ -40,21 +39,28 @@ extern const RAM_SLOT_INFO nullRAM_SLOT_INFO;
class SmbiosMemoryConfigurationClass {
public:
UINT8 SlotCounts = UINT8();
UINT8 SlotCount = UINT8();
UINT8 UserChannels = UINT8();
XObjArray<RAM_SLOT_INFO> _User = XObjArray<RAM_SLOT_INFO>();
SmbiosMemoryConfigurationClass() {}
void setEmpty() {
SlotCounts = 0;
SlotCount = 0;
UserChannels = 0;
_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 {
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;
}
@ -86,14 +92,15 @@ class SmbiosDiscoveredSettings
XString8 OEMBoardFromSmbios = XString8();
XString8 OEMProductFromSmbios = 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
UINT64 ExternalClock = 0;
UINT32 CurrentSpeed = 0;
UINT32 MaxSpeed = 0;
UINT32 CurrentSpeed = 0;
UINT32 MaxSpeed = 0;
SmbiosDiscoveredSettings() {}
};
@ -102,13 +109,13 @@ class SmbiosDiscoveredSettings
* All settings that'll be injected goes into this struct.
* Goal : No globals used by patchTablexxx functions
* 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 ?
* A: Problems with globals, is that don't control where they are accessed from.
* 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 you don't know where they are accessed from.
* 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).
* 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.
*
* 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() {}
};
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
{
public:
UINT32 Frequency = UINT32();
UINT32 Divider = UINT32();
UINT8 TRC = UINT8();
UINT8 TRP = UINT8();
UINT8 RAS = UINT8();
UINT8 Channels = UINT8();
UINT8 Slots = UINT8();
UINT8 Type = UINT8();
UINT8 SPDInUse = UINT8();
UINT8 SMBIOSInUse = UINT8();
UINT32 Frequency = 0;
UINT32 Divider = 0;
UINT8 TRC = 0;
UINT8 TRP = 0;
UINT8 RAS = 0;
UINT8 Channels = 0;
UINT8 Slots = 0;
UINT8 Type = 0;
RAM_SLOT_INFO SPD[MAX_RAM_SLOTS * 4];
RAM_SLOT_INFO SMBIOS[MAX_RAM_SLOTS * 4];
RAM_SLOT_INFO_Array SPD = RAM_SLOT_INFO_Array();
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
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]) {
case SPD_MEMORY_TYPE_SDRAM_DDR:
case SPD_MEMORY_TYPE_SDRAM_DDR: {
init_spd(spd_indexes_ddr, spdbuf, base, i);
gRAM.SPD[i].Type = MemoryTypeDdr;
gRAM.SPD[i].ModuleSize = (((1 << ((spdbuf[SPD_NUM_ROWS] & 0x0f)
rsiPtr = new RAM_SLOT_INFO;
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_DIMM_BANKS] & 0x7) + 1) *
spdbuf[SPD_NUM_BANKS_PER_SDRAM])/3)*2;
break;
case SPD_MEMORY_TYPE_SDRAM_DDR2:
}
case SPD_MEMORY_TYPE_SDRAM_DDR2: {
init_spd(spd_indexes_ddr, spdbuf, base, i);
gRAM.SPD[i].Type = MemoryTypeDdr2;
gRAM.SPD[i].ModuleSize = ((1 << ((spdbuf[SPD_NUM_ROWS] & 0x0f)
rsiPtr = new RAM_SLOT_INFO;
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_DIMM_BANKS] & 0x7) + 1) *
spdbuf[SPD_NUM_BANKS_PER_SDRAM]);
break;
case SPD_MEMORY_TYPE_SDRAM_DDR3:
}
case SPD_MEMORY_TYPE_SDRAM_DDR3: {
init_spd(spd_indexes_ddr3, spdbuf, base, i);
gRAM.SPD[i].Type = MemoryTypeDdr3;
gRAM.SPD[i].ModuleSize = ((spdbuf[4] & 0x0f) + 28 ) + ((spdbuf[8] & 0x7) + 3 );
gRAM.SPD[i].ModuleSize -= (spdbuf[7] & 0x7) + 25;
gRAM.SPD[i].ModuleSize = ((1 << gRAM.SPD[i].ModuleSize) * (((spdbuf[7] >> 3) & 0x1f) + 1));
rsiPtr = new RAM_SLOT_INFO;
RAM_SLOT_INFO& rsi = *rsiPtr;
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;
case SPD_MEMORY_TYPE_SDRAM_DDR4:
}
case SPD_MEMORY_TYPE_SDRAM_DDR4: {
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[13] & 0x07) + 3)) // Primary Bus 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
*/
break;
}
default:
gRAM.SPD[i].ModuleSize = 0;
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);
//gRAM Type = spd_mem_to_smbios[spd_type];
gRAM.SPD[i].PartNo.takeValueFrom(getDDRPartNum(spdbuf, base, i));
gRAM.SPD[i].PartNo.trim();
gRAM.SPD[i].Vendor.takeValueFrom(getVendorName(&(gRAM.SPD[i]), spdbuf, base, i));
gRAM.SPD[i].Vendor.trim();
gRAM.SPD[i].SerialNo.takeValueFrom(getDDRSerial(spdbuf));
gRAM.SPD[i].SerialNo.trim();
rsi.PartNo.takeValueFrom(getDDRPartNum(spdbuf, base, i));
rsi.PartNo.trim();
rsi.Vendor.takeValueFrom(getVendorName(&(rsi), spdbuf, base, i));
rsi.Vendor.trim();
rsi.SerialNo.takeValueFrom(getDDRSerial(spdbuf));
rsi.SerialNo.trim();
//XXX - when we can FreePool allocated for these buffers? No this is pointer copy
// determine spd speed
speed = getDDRspeedMhz(spdbuf);
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
// 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 99: freq++; break;
}
gRAM.SPD[i].Frequency = freq;
rsi.Frequency = freq;
DBG("RAM speed %dMHz\n", freq);
}
#endif
MsgLog("Slot: %d Type %d %dMB %dMHz Vendor=%s PartNo=%s SerialNo=%s\n",
i,
(int)gRAM.SPD[i].Type,
gRAM.SPD[i].ModuleSize,
gRAM.SPD[i].Frequency,
gRAM.SPD[i].Vendor.c_str(),
gRAM.SPD[i].PartNo.c_str(),
gRAM.SPD[i].SerialNo.c_str());
(int)rsi.Type,
rsi.ModuleSize,
rsi.Frequency,
rsi.Vendor.c_str(),
rsi.PartNo.c_str(),
rsi.SerialNo.c_str());
gRAM.SPD[i].InUse = true;
++(gRAM.SPDInUse);
// rsi.InUse = true;
gRAM.SPD.AddReference(rsiPtr, true);
//}
// 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.
// If compiling for other size, #ifdef the static_assert depending of the platform and adjust constant (INT_MIN, INT_MAX)
#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
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1)
#define INT_MIN INT64_MIN
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1)
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define INT_MAX INT64_MAX
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define UINT8_MAX 0xff /* 255U */
#define UINT8_MAX 0xff /* 255U */
#define UINT16_MAX 0xffff /* 65535U */
#define UINT32_MAX 0xffffffff /* 4294967295U */
#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 UINT16 uint16_t;

View File

@ -21,6 +21,7 @@
#include <IndustryStandard/SmBios.h> // for Smbios memory type
#include "../../Platform/guid.h"
#include "../../Platform/platformdata.h"
#include "../../Platform/smbios.h"
//#include "../cpu.h"
#include "../../cpp_lib/undefinable.h"
@ -64,24 +65,15 @@ public:
public:
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 {
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() < 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()));
if ( value() >= MAX_RAM_SLOTS ) return xmlLiteParser->addWarning(generateErrors, S8Printf("Slot cannot >= MAX_RAM_SLOTS. It must a number between 0 and %d at '%s:%d'", MAX_RAM_SLOTS-1, xmlPath.c_str(), keyPos.getLine()));
return true;
}
};
XmlUInt64 Slot = XmlUInt64();
XmlUInt32 Size = XmlUInt32();
XmlUInt32 Frequency = XmlUInt32();
XmlString8AllowEmpty Vendor = XmlString8AllowEmpty();
XmlString8AllowEmpty Part = XmlString8AllowEmpty();
XmlString8AllowEmpty Serial = XmlString8AllowEmpty();
class TypeClass: public XmlString8AllowEmpty {
using super = XmlString8AllowEmpty;
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()));
}
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] = {
{"Slot", Slot},
{"Slot", SlotIndex},
{"Size", Size},
{"Frequency", Frequency},
{"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 XBool validate(XmlLiteParser* xmlLiteParser, const XString8& xmlPath, const XmlParserPosition& keyPos, XBool generateErrors) override {
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) return false;
if ( !Slot.isDefined() ) return false;
return true;
XBool b = true;
if ( !super::validate(xmlLiteParser, xmlPath, keyPos, generateErrors) ) b = false;
if ( !SlotIndex.isDefined() ) b = xmlLiteParser->addWarning(generateErrors, S8Printf("Slot must be defined as a number between 0 and %d at '%s:%d'", MAX_RAM_SLOTS-1, xmlPath.c_str(), keyPos.getLine()));
if ( !Size.isDefined() ) b = xmlLiteParser->addWarning(generateErrors, S8Printf("Size must be defined at '%s:%d'", xmlPath.c_str(), keyPos.getLine()));
return b;
}
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(Frequency)::ValueType& dgetFrequency() const { return Frequency.isDefined() ? Frequency.value() : Frequency.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.
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>
{
using super = XmlArray<ModuleDictClass>;
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 ) {
if ( ElementAt(idx).dgetSlotNo() == slotNo )
if ( ElementAt(idx).dgetSlotIndex() == slotIndex )
return ElementAt(idx);
}
return ModuleDictClass::NullValue;
@ -171,28 +207,40 @@ public:
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;
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;
}
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; };
decltype(SlotCount)::ValueType dgetSlotMax() const {
if ( !isDefined() || !Modules.isDefined() || Modules.size() == 0 ) return 0;
uint8_t max = 0;
for ( size_t idx = 0 ; idx < Modules.size() ; ++idx ) {
if ( Modules[idx].dgetModuleSize() > 0 ) {
if ( Modules[idx].dgetSlotNo() > UINT8_MAX ) {
log_technical_bug("Modules[idx].dgetSlotNo() > UINT8_MAX");
}else{
if ( Modules[idx].dgetSlotNo() > max ) max = (uint8_t)Modules[idx].dgetSlotNo(); // safe cast Modules[idx].dgetSlotNo() is <= UINT8_MAX
}
}
}
return max+1;
};
decltype(SlotCount)::ValueType dgetSlotCounts() const { return dgetSlotCountSetting() > dgetSlotMax() ? dgetSlotCountSetting() : dgetSlotMax(); };
// decltype(SlotCount)::ValueType dgetSlotMax() const {
// if ( !isDefined() || !Modules.isDefined() || Modules.size() == 0 ) return 0;
// uint8_t max = 0;
// for ( size_t idx = 0 ; idx < Modules.size() ; ++idx ) {
// if ( Modules[idx].dgetModuleSize() > 0 ) {
// if ( Modules[idx].dgetSlotIndex() > UINT8_MAX ) {
// log_technical_bug("Modules[idx].dgetSlotNo() > UINT8_MAX");
// }else{
// if ( Modules[idx].dgetSlotIndex() > max ) max = (uint8_t)Modules[idx].dgetSlotIndex(); // safe cast Modules[idx].dgetSlotNo() is <= UINT8_MAX
// }
// }
// }
// return max+1;
// };
//
// decltype(SlotCount)::ValueType dgetSlotCounts() const { return dgetSlotCountSetting() > dgetSlotMax() ? dgetSlotCountSetting() : dgetSlotMax(); };
};
@ -620,7 +668,7 @@ public:
decltype(SmbiosVersion)::ValueType dgetSmbiosVersion() const { return SmbiosVersion.isDefined() ? SmbiosVersion.value() : 0x204; };
decltype(MemoryRank)::ValueType dgetAttribute() const { return MemoryRank.isDefined() ? MemoryRank.value() : -1; };
decltype(Trust)::ValueType dgetTrustSMBIOS() const { return Trust.isDefined() ? Trust.value() : XBool(true); };
XBool dgetInjectMemoryTables() const { return Memory.Modules.isDefined() && Memory.Modules.size() > 0 ? Memory.dgetSlotCounts() > 0 : false; };
XBool dgetInjectMemoryTables() const { return Memory.Modules.isDefined() && Memory.Modules.size() > 0 ? Memory.dgetSlotCount() > 0 : false; };
decltype(PlatformFeature)::ValueType dgetgPlatformFeature() const {
if ( PlatformFeature.isDefined() ) return PlatformFeature.value();
return GetPlatformFeature(dgetModel());

View File

@ -12,6 +12,65 @@
#ifdef __cplusplus
#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 {
static constexpr bool value = false;
@ -108,23 +167,6 @@ template <> struct _xtools__is_bool_st<bool> : public
// 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
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 {};