mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-23 11:35:19 +01:00
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:
parent
83b93234be
commit
542b812276
@ -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);
|
||||
}
|
||||
|
@ -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,8 +143,13 @@ void SmbiosFillPatchingValues(XBool _SetTable132, uint8_t pEnabledCores, uint16_
|
||||
smbiosInjectedSetting.SetTable132 = _SetTable132;
|
||||
smbiosInjectedSetting.QPI = globalSettings.CPU.QPI;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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,24 +1404,28 @@ 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());
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1381,28 +1436,34 @@ void GetTableType17(SmbiosDiscoveredSettings* smbiosSettings)
|
||||
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());
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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");
|
||||
//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);
|
||||
|
@ -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();
|
||||
UINT32 ModuleSize = 0;
|
||||
UINT32 Frequency = 0;
|
||||
XString8 Vendor = XString8();
|
||||
XString8 PartNo = XString8();
|
||||
XString8 SerialNo = XString8();
|
||||
UINT8 Type = UINT8();
|
||||
XBool InUse = false;
|
||||
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;
|
||||
}
|
||||
@ -88,7 +94,8 @@ class SmbiosDiscoveredSettings
|
||||
XString8 OEMVendorFromSmbios = XString8();
|
||||
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;
|
||||
@ -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();
|
||||
|
||||
};
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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_MAX 127
|
||||
#define INT16_MAX 32767
|
||||
#define INT32_MAX 2147483647
|
||||
#define INT64_MAX 9223372036854775807LL
|
||||
#define INT_MAX INT64_MAX
|
||||
|
||||
#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;
|
||||
|
@ -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).dgetSlotNo() == slotNo )
|
||||
if ( ElementAt(idx).dgetModuleSize() > 0 ) {
|
||||
if ( ElementAt(idx).dgetSlotIndex() > max ) max = ElementAt(idx).dgetSlotIndex();
|
||||
}
|
||||
}
|
||||
return max+1;
|
||||
};
|
||||
|
||||
const ModuleDictClass& dgetSoltAtIndex(size_t slotIndex) const {
|
||||
for ( size_t idx = 0; idx < size(); ++idx ) {
|
||||
if ( ElementAt(idx).dgetSlotIndex() == slotIndex )
|
||||
return ElementAt(idx);
|
||||
}
|
||||
return ModuleDictClass::NullValue;
|
||||
@ -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());
|
||||
|
@ -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 {};
|
||||
|
Loading…
Reference in New Issue
Block a user