CloverBootloader/rEFIt_UEFI/Platform/smbios.cpp

2419 lines
99 KiB
C++

/**
smbios.c
original idea of SMBIOS patching by mackerintel
implementation for UEFI smbios table patching
Slice 2011.
portion copyright Intel
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
SmbiosGen.c
**/
#define DONT_DEFINE_GLOBALS
#include <Platform.h> // Only use angled for Platform, else, xcode project won't compile
#include <Efi.h>
#include "smbios.h"
#include "platformdata.h"
#include "AcpiPatcher.h"
#include "guid.h"
#include "../Platform/CloverVersion.h"
#ifndef DEBUG_ALL
#define DEBUG_SMBIOS 1
#else
#define DEBUG_SMBIOS DEBUG_ALL
#endif
#if DEBUG_SMBIOS == 0
#define DBG(...)
#else
#define DBG(...) DebugLog(DEBUG_SMBIOS, __VA_ARGS__)
#endif
#define REMAP_SMBIOS_TABLE_GUID { 0xeb9d2d35, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
#define MAX_OEM_STRING 256
#define ROUND_PAGE(x) ((((unsigned)(x)) + EFI_PAGE_SIZE - 1) & ~(EFI_PAGE_SIZE - 1))
EFI_GUID gTableGuidArray[] = {gEfiSmbiosTableGuid, gEfiSmbios3TableGuid};
constexpr LString8 unknown = "unknown"_XS8;
SmbiosDiscoveredSettings g_SmbiosDiscoveredSettings;
SmbiosInjectedSettings g_SmbiosInjectedSettings;
const RAM_SLOT_INFO nullRAM_SLOT_INFO;
const SLOT_DEVICE nullSLOT_DEVICE;
//
// syscl: implement Dell truncate fix
// remap EFI_SMBIOS_TABLE_1 to new guid to fix Dell
// SMBIOS Table 1 truncate issue credit David Passmore
//
EFI_GUID gRemapEfiSmbiosTableGuid = REMAP_SMBIOS_TABLE_GUID;
//EFI_PHYSICAL_ADDRESS *smbiosTable;
void *Smbios; //pointer to SMBIOS data
SMBIOS_TABLE_ENTRY_POINT *EntryPoint; //SmbiosEps original
SMBIOS_TABLE_ENTRY_POINT *SmbiosEpsNew; //new SmbiosEps
//for patching
APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTable;
APPLE_SMBIOS_STRUCTURE_POINTER newSmbiosTable;
UINT16 NumberOfRecords;
UINT16 MaxStructureSize;
UINT8* Current; //pointer to the current end of tables
EFI_SMBIOS_TABLE_HEADER *Record;
EFI_SMBIOS_HANDLE Handle;
EFI_SMBIOS_TYPE Type;
UINTN stringNumber;
UINTN TableSize;
UINT16 CoreCache = 0;
UINT16 L1, L2, L3;
UINT32 MaxMemory = 0;
UINT32 mTotalSystemMemory;
UINT64 gTotalMemory;
UINT16 mHandle3;
UINT16 mHandle16 = 0x1000;
//UINT16 mHandle17[MAX_RAM_SLOTS];
UINT16 mHandle19;
//UINT64 mInstalled[MAX_RAM_SLOTS];
//UINT64 mEnabled[MAX_RAM_SLOTS];
XBool gMobile;
UINT8 gBootStatus;
XBool Once;
MEM_STRUCTURE gRAM;
#define MAX_HANDLE 0xFEFF
#define SMBIOS_PTR SIGNATURE_32('_','S','M','_')
#define MAX_TABLE_SIZE 512
//#define smbios_offsetof(s,m) ( (SMBIOS_TABLE_STRING) ((UINT8*)&((s*)0)->m - (UINT8*)0))
#ifndef smbios_offsetof
# define smbios_offsetof(TYPE, MEMBER) ((SMBIOS_TABLE_STRING)((size_t) &((TYPE *)0)->MEMBER))
#endif
SMBIOS_TABLE_STRING SMBIOS_TABLE_TYPE0_STR_IDX[] = {
smbios_offsetof(SMBIOS_TABLE_TYPE0, Vendor),
smbios_offsetof(SMBIOS_TABLE_TYPE0, BiosVersion),
smbios_offsetof(SMBIOS_TABLE_TYPE0, BiosReleaseDate),
0x00
}; // offsets of structures that values are strings for type 0 Bios
SMBIOS_TABLE_STRING SMBIOS_TABLE_TYPE1_STR_IDX[] = {
smbios_offsetof(SMBIOS_TABLE_TYPE1, Manufacturer),
smbios_offsetof(SMBIOS_TABLE_TYPE1, ProductName),
smbios_offsetof(SMBIOS_TABLE_TYPE1, Version),
smbios_offsetof(SMBIOS_TABLE_TYPE1, SerialNumber),
smbios_offsetof(SMBIOS_TABLE_TYPE1, SKUNumber),
smbios_offsetof(SMBIOS_TABLE_TYPE1, Family),
0x00
}; // offsets of structures that values are strings for type 1 System
SMBIOS_TABLE_STRING SMBIOS_TABLE_TYPE2_STR_IDX[] = {
smbios_offsetof(SMBIOS_TABLE_TYPE2, Manufacturer),
smbios_offsetof(SMBIOS_TABLE_TYPE2, ProductName),
smbios_offsetof(SMBIOS_TABLE_TYPE2, Version),
smbios_offsetof(SMBIOS_TABLE_TYPE2, SerialNumber),
smbios_offsetof(SMBIOS_TABLE_TYPE2, AssetTag),
smbios_offsetof(SMBIOS_TABLE_TYPE2, LocationInChassis),
0x00
}; // offsets of structures that values are strings for type 2 BaseBoard
SMBIOS_TABLE_STRING SMBIOS_TABLE_TYPE3_STR_IDX[] = {
smbios_offsetof(SMBIOS_TABLE_TYPE3, Manufacturer),
smbios_offsetof(SMBIOS_TABLE_TYPE3, Version),
smbios_offsetof(SMBIOS_TABLE_TYPE3, SerialNumber),
smbios_offsetof(SMBIOS_TABLE_TYPE3, AssetTag),
0x00
}; // offsets of structures that values are strings for type 3 Chassis
SMBIOS_TABLE_STRING SMBIOS_TABLE_TYPE4_STR_IDX[] = {
smbios_offsetof(SMBIOS_TABLE_TYPE4, Socket),
smbios_offsetof(SMBIOS_TABLE_TYPE4, ProcessorManufacturer),
smbios_offsetof(SMBIOS_TABLE_TYPE4, ProcessorVersion),
smbios_offsetof(SMBIOS_TABLE_TYPE4, SerialNumber),
smbios_offsetof(SMBIOS_TABLE_TYPE4, AssetTag),
smbios_offsetof(SMBIOS_TABLE_TYPE4, PartNumber),
0x00
}; // offsets of structures that values are strings for type 3 Chassis
/* Functions */
// validate the SMBIOS entry point structure
XBool IsEntryPointStructureValid (IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure)
{
UINT8 Length;
UINT8 Checksum = 0;
UINT8 *BytePtr;
if (!EntryPointStructure)
return false;
BytePtr = (UINT8*) EntryPointStructure;
Length = EntryPointStructure->EntryPointLength;
for (UINTN I = 0; I < Length; I++) {
Checksum = Checksum + (UINT8) BytePtr[I];
}
// a valid SMBIOS EPS must have checksum of 0
return (Checksum == 0);
}
void* FindOemSMBIOSPtr (void)
{
// Search 0x0f0000 - 0x0fffff for SMBIOS Ptr
for (UINTN Address = 0xf0000; Address < 0xfffff; Address += 0x10) {
if (*(UINT32 *)(Address) == SMBIOS_PTR && IsEntryPointStructureValid((SMBIOS_TABLE_ENTRY_POINT*)Address)) {
return (void *)Address;
}
}
return NULL;
}
void* GetSmbiosTablesFromHob (void)
{
EFI_PHYSICAL_ADDRESS *Table;
EFI_PEI_HOB_POINTERS GuidHob;
GuidHob.Raw = (__typeof_am__(GuidHob.Raw))GetFirstGuidHob(gEfiSmbiosTableGuid);
if (GuidHob.Raw != NULL) {
Table = (__typeof__(Table))GET_GUID_HOB_DATA (GuidHob.Guid);
if (Table != NULL) {
return (void *)(UINTN)*Table;
}
}
GuidHob.Raw = (__typeof_am__(GuidHob.Raw))GetFirstGuidHob(gEfiSmbios3TableGuid);
if (GuidHob.Raw != NULL) {
Table = (__typeof_am__(Table))GET_GUID_HOB_DATA (GuidHob.Guid);
if (Table != NULL) {
return (void *)(UINTN)*Table;
}
}
return NULL;
}
void* GetSmbiosTablesFromConfigTables (void)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS *Table = NULL;
Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (void **)&Table);
if (EFI_ERROR(Status) || Table == NULL) {
Table = NULL;
Status = EfiGetSystemConfigurationTable (&gEfiSmbios3TableGuid, (void **)&Table);
if (EFI_ERROR(Status)) {
Table = NULL;
}
}
return Table;
}
// This function determines ascii string length ending by space.
// search restricted to MaxLen, for example
// iStrLen("ABC ", 20) == 3
// if MaxLen=0 then as usual strlen but bugless
UINTN iStrLen(CONST CHAR8* String, UINTN MaxLen)
{
UINTN Len = 0;
CONST CHAR8* BA;
if(MaxLen > 0) {
for (Len=0; Len<MaxLen; Len++) {
if (String[Len] == 0) {
break;
}
}
BA = &String[Len - 1];
while ((Len != 0) && ((*BA == ' ') || (*BA == 0))) {
BA--; Len--;
}
} else {
BA = String;
while(*BA){BA++; Len++;}
}
return Len;
}
// Internal functions for flat SMBIOS
UINT16 SmbiosTableLength (APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTableN)
{
CHAR8 *AChar;
UINT16 Length;
AChar = (CHAR8 *)(SmbiosTableN.Raw + SmbiosTableN.Hdr->Length);
while ((*AChar != 0) || (*(AChar + 1) != 0)) {
AChar ++; //stop at 00 - first 0
}
Length = (UINT16)((UINTN)AChar - (UINTN)SmbiosTableN.Raw + 2); //length includes 00
return Length;
}
EFI_SMBIOS_HANDLE LogSmbiosTable (APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTableN)
{
UINT16 Length = SmbiosTableLength(SmbiosTableN);
if (Length > MaxStructureSize) {
MaxStructureSize = Length;
}
CopyMem(Current, SmbiosTableN.Raw, Length);
Current += Length;
NumberOfRecords++;
return SmbiosTableN.Hdr->Handle;
}
// the procedure insert Buffer into SmbiosTable by copy and update Field
// the Buffer restricted by zero or by space
EFI_STATUS UpdateSmbiosString(OUT APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTableN,
SMBIOS_TABLE_STRING* Field, const XString8& Buffer)
{
CHAR8* AString;
CHAR8* C1; //pointers for copy
CHAR8* C2;
UINTN Length = SmbiosTableLength(SmbiosTableN);
UINTN ALength, BLength;
UINT8 IndexStr = 1;
if ((SmbiosTableN.Raw == NULL) || Buffer.isEmpty() || !Field) {
return EFI_NOT_FOUND;
}
AString = (CHAR8*)(SmbiosTableN.Raw + SmbiosTableN.Hdr->Length); //first string
while (IndexStr != *Field) {
if (*AString) {
IndexStr++;
}
while (*AString != 0) AString++; //skip string at index
AString++; //next string
if (*AString == 0) {
//this is end of the table
if (*Field == 0) {
AString[1] = 0; //one more zero
}
*Field = IndexStr; //index of the next string that is empty
if (IndexStr == 1) {
AString--; //first string has no leading zero
}
break;
}
}
// AString is at place to copy
ALength = iStrLen(AString, 0);
BLength = iStrLen(Buffer.c_str(), MAX_OEM_STRING);
// DBG("Table type %d field %d\n", SmbiosTable.Hdr->Type, *Field);
// DBG("Old string length=%d new length=%d\n", ALength, BLength);
if (BLength > ALength) {
//Shift right
C1 = (CHAR8*)SmbiosTableN.Raw + Length; //old end
C2 = C1 + BLength - ALength; //new end
*C2 = 0;
while (C1 != AString) *(--C2) = *(--C1);
} else if (BLength < ALength) {
//Shift left
C1 = AString + ALength; //old start
C2 = AString + BLength; //new start
while (C1 != ((CHAR8*)SmbiosTableN.Raw + Length)) {
*C2++ = *C1++;
}
*C2 = 0;
*(--C2) = 0; //end of table
}
//DBG("UpdateSmbiosString() -> CopyMem %s %lld\n", Buffer.c_str(), BLength);
CopyMem(AString, Buffer.c_str(), BLength);
*(AString + BLength) = 0; // not sure there is 0
return EFI_SUCCESS;
}
APPLE_SMBIOS_STRUCTURE_POINTER GetSmbiosTableFromType (SMBIOS_TABLE_ENTRY_POINT *SmbiosPoint,
UINT8 SmbiosType, UINTN IndexTable)
{
APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTableN;
UINTN SmbiosTypeIndex;
SmbiosTypeIndex = 0;
SmbiosTableN.Raw = (UINT8 *)((UINTN)SmbiosPoint->TableAddress);
if (SmbiosTableN.Raw == NULL) {
return SmbiosTableN;
}
while ((SmbiosTypeIndex != IndexTable) || (SmbiosTableN.Hdr->Type != SmbiosType)) {
if (SmbiosTableN.Hdr->Type == SMBIOS_TYPE_END_OF_TABLE) {
SmbiosTableN.Raw = NULL;
return SmbiosTableN;
}
if (SmbiosTableN.Hdr->Type == SmbiosType) {
SmbiosTypeIndex++;
}
SmbiosTableN.Raw = (UINT8 *)(SmbiosTableN.Raw + SmbiosTableLength (SmbiosTableN));
}
return SmbiosTableN;
}
CHAR8* GetSmbiosString (APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTableN, SMBIOS_TABLE_STRING StringN)
{
CHAR8 *AString;
UINT8 Ind;
Ind = 1;
AString = (CHAR8 *)(SmbiosTableN.Raw + SmbiosTableN.Hdr->Length); //first string
while (Ind != StringN) {
while (*AString != 0) {
AString ++;
}
AString ++; //skip zero ending
if (*AString == 0) {
return AString; //this is end of the table
}
Ind++;
}
return AString; //return pointer to Ascii string
}
void AddSmbiosEndOfTable()
{
SMBIOS_STRUCTURE* StructurePtr = (SMBIOS_STRUCTURE*)Current;
StructurePtr->Type = SMBIOS_TYPE_END_OF_TABLE;
StructurePtr->Length = sizeof(SMBIOS_STRUCTURE);
StructurePtr->Handle = SMBIOS_TYPE_INACTIVE; //spec 2.7 p.120
Current += sizeof(SMBIOS_STRUCTURE);
*Current++ = 0;
*Current++ = 0; //double 0 at the end
NumberOfRecords++;
}
void UniquifySmbiosTableStr (APPLE_SMBIOS_STRUCTURE_POINTER SmbiosTableN, SMBIOS_TABLE_STRING* str_idx)
{
INTN i, j;
SMBIOS_TABLE_STRING cmp_idx;
SMBIOS_TABLE_STRING cmp_str;
SMBIOS_TABLE_STRING ref_str;
if (0 == str_idx[0]) return; // SMBIOS doesn't have string structures, just return;
for (i = 1; ;i++) {
cmp_idx = str_idx[i];
if (0 == cmp_idx) break;
cmp_str = SmbiosTableN.Raw[cmp_idx];
if (0 == cmp_str) continue; // if string is undefine, continue
for (j = 0; j < i; j++) {
ref_str = SmbiosTableN.Raw[str_idx[j]];
if (cmp_str == ref_str) {
SmbiosTableN.Raw[cmp_idx] = 0; // pretend the string doesn't exist
// UpdateSmbiosString(SmbiosTableN, &SmbiosTableN.Raw[cmp_idx], GetSmbiosString(SmbiosTableN, ref_str));
break;
}
}
}
}
/* Patching Functions */
void PatchTableType0(const SmbiosInjectedSettings& smbiosSettings)
{
// BIOS information
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_BIOS_INFORMATION, 0);
if (SmbiosTable.Raw == NULL) {
// DBG("SmbiosTable: Type 0 (Bios Information) not found!\n");
return;
}
TableSize = SmbiosTableLength(SmbiosTable);
ZeroMem((void*)newSmbiosTable.Type0, MAX_TABLE_SIZE);
CopyMem((void*)newSmbiosTable.Type0, (void*)SmbiosTable.Type0, TableSize); //can't point to union
/* Real Mac
BIOS Information (Type 0)
Raw Data:
Header and Data:
00 18 2E 00 01 02 00 00 03 7F 80 98 01 00 00 00
00 00 C1 02 00 01 FF FF
Strings:
Apple Inc.
MBP81.88Z.0047.B22.1109281426
09/28/11
*/
newSmbiosTable.Type0->BiosSegment = 0; //like in Mac
newSmbiosTable.Type0->SystemBiosMajorRelease = 0;
newSmbiosTable.Type0->SystemBiosMinorRelease = 1;
// newSmbiosTable.Type0->BiosCharacteristics.BiosCharacteristicsNotSupported = 0;
// newSmbiosTable.Type0->BIOSCharacteristicsExtensionBytes[1] |= 8; //UefiSpecificationSupported;
//Slice: ----------------------
//there is a bug in AppleSMBIOS-42 v1.7
//to eliminate this I have to zero first byte in the field
*(UINT8*)&newSmbiosTable.Type0->BiosCharacteristics = 0;
//dunno about latest version but there is a way to set good characteristics
//if use patched AppleSMBIOS
//----------------
Once = true;
UniquifySmbiosTableStr(newSmbiosTable, SMBIOS_TABLE_TYPE0_STR_IDX);
if ( smbiosSettings.BiosVendor.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type0->Vendor, smbiosSettings.BiosVendor);
}
if( smbiosSettings.BiosVersionUsed.notEmpty() ) {
if( smbiosSettings.EfiVersionUsed.notEmpty() ) {
DBG("UpdateSmbiosString : BiosVersion=EfiVersion=%s\n", smbiosSettings.EfiVersionUsed.c_str());
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type0->BiosVersion, smbiosSettings.EfiVersionUsed);
} else {
DBG("UpdateSmbiosString : BiosVersion=RomVersion=%s\n", smbiosSettings.BiosVersionUsed.c_str());
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type0->BiosVersion, smbiosSettings.BiosVersionUsed);
}
}else{
DBG("UpdateSmbiosString : BiosVersion no update\n");
}
if( smbiosSettings.ReleaseDateUsed.notEmpty() ) {
DBG("UpdateSmbiosString : ReleaseDate=%s\n", smbiosSettings.ReleaseDateUsed.c_str());
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type0->BiosReleaseDate, smbiosSettings.ReleaseDateUsed);
}else{
DBG("UpdateSmbiosString : ReleaseDate no update\n");
}
Handle = LogSmbiosTable(newSmbiosTable);
}
void GetTableType1(SmbiosDiscoveredSettings* smbiosSettings)
{
CHAR8* s;
// System Information
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_SYSTEM_INFORMATION, 0);
if (SmbiosTable.Raw == NULL) {
DBG("SmbiosTable: Type 1 (System Information) not found!\n");
return;
}
// smbiosSettings.SmUUID = GuidLEToXString8(SmbiosTable.Type1->Uuid); // is this is a bug, this uuid might be BE, not LE, or should we use the "variant" field
s = GetSmbiosString(SmbiosTable, SmbiosTable.Type1->ProductName);
smbiosSettings->OEMProductFromSmbios.strncpy(s, iStrLen(s, 64)); //strncpy take care of ending zero
return;
}
EFI_GUID getSmUUIDFromSmbios()
{
// System Information
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_SYSTEM_INFORMATION, 0);
if (SmbiosTable.Raw == NULL) {
DBG("SmbiosTable: Type 1 (System Information) not found!\n");
return nullGuid;
}
// EFI_GUID TmpGuid;
// XString8 g = GuidBeToXString8(SmbiosTable.Type1->Uuid); // should we use the "variant" field to know if it's LE or BE
XString8 guidBE = SmbiosTable.Type1->Uuid.toXString8(true); // This is the difference between PC and Mac. the UUID will be swapped (read as a LE, sent as a BE).
DBG("got BE smUUID as:%s\n", guidBE.c_str());
return GUID().takeValueFrom(guidBE);
}
void PatchTableType1(const SmbiosInjectedSettings& smbiosSettings)
{
// System Information
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_SYSTEM_INFORMATION, 0);
if (SmbiosTable.Raw == NULL) {
return;
}
//Increase table size
UINTN Size = SmbiosTable.Type1->Hdr.Length; //old size
TableSize = SmbiosTableLength(SmbiosTable); //including strings
UINTN NewSize = 27; //sizeof(SMBIOS_TABLE_TYPE1);
ZeroMem((void*)newSmbiosTable.Type1, MAX_TABLE_SIZE);
CopyMem((void*)newSmbiosTable.Type1, (void*)SmbiosTable.Type1, Size); //copy main table
CopyMem((CHAR8*)newSmbiosTable.Type1+NewSize, (CHAR8*)SmbiosTable.Type1+Size, TableSize - Size); //copy strings
newSmbiosTable.Type1->Hdr.Length = (UINT8)NewSize;
UniquifySmbiosTableStr(newSmbiosTable, SMBIOS_TABLE_TYPE1_STR_IDX);
newSmbiosTable.Type1->WakeUpType = SystemWakeupTypePowerSwitch;
Once = true;
// macOs take all guid as BE guid, irrespective to the variant.
if((smbiosSettings.SmUUID.Data3 & 0xF000) != 0) {
CopyMem((void*)&newSmbiosTable.Type1->Uuid, (void*)&smbiosSettings.SmUUID, sizeof(smbiosSettings.SmUUID));
}
if( smbiosSettings.ManufactureName.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type1->Manufacturer, smbiosSettings.ManufactureName);
}
if( smbiosSettings.ProductName.notEmpty() ){
DBG("%s : UpdateSmbiosString ProductName=%s\n", __PRETTY_FUNCTION__, smbiosSettings.ProductName.c_str());
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type1->ProductName, smbiosSettings.ProductName);
}
if( smbiosSettings.SystemVersion.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type1->Version, smbiosSettings.SystemVersion);
}
if( smbiosSettings.SerialNr.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type1->SerialNumber, smbiosSettings.SerialNr);
//DBG("%s : UpdateSmbiosString SerialNr=%s\n", __PRETTY_FUNCTION__, smbiosSettings.SerialNr.c_str());
}
if( smbiosSettings.BoardNumber.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type1->SKUNumber, smbiosSettings.BoardNumber); //iMac17,1 - there is nothing
}
if( smbiosSettings.FamilyName.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type1->Family, smbiosSettings.FamilyName);
}
Handle = LogSmbiosTable(newSmbiosTable);
return;
}
void GetTableType2(SmbiosDiscoveredSettings* smbiosSettings)
{
CHAR8* s;
// System Information
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION, 0);
if (SmbiosTable.Raw == NULL) {
return;
}
s = GetSmbiosString(SmbiosTable, SmbiosTable.Type2->ProductName);
smbiosSettings->OEMBoardFromSmbios.strncpy(s, iStrLen(s, 64) + 1);
s = GetSmbiosString(SmbiosTable, SmbiosTable.Type2->Manufacturer);
smbiosSettings->OEMVendorFromSmbios.strncpy(s, iStrLen(s, 64) + 1);
}
void PatchTableType2(const SmbiosInjectedSettings& smbiosSettings)
{
// BaseBoard Information
//
UINTN NewSize = 0x10; //sizeof(SMBIOS_TABLE_TYPE2);
ZeroMem((void*)newSmbiosTable.Type2, MAX_TABLE_SIZE);
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION, 0);
if (SmbiosTable.Raw == NULL) {
MsgLog("SmbiosTable: Type 2 (BaseBoard Information) not found, create new\n");
//Create new one
newSmbiosTable.Type2->Hdr.Type = 2;
newSmbiosTable.Type2->Hdr.Handle = 0x0200; //common rule
} else {
UINTN Size = SmbiosTable.Type2->Hdr.Length; //old size
TableSize = SmbiosTableLength(SmbiosTable); //including strings
if (NewSize > Size) {
CopyMem((void*)newSmbiosTable.Type2, (void*)SmbiosTable.Type2, Size); //copy main table
CopyMem((CHAR8*)newSmbiosTable.Type2 + NewSize, (CHAR8*)SmbiosTable.Type2 + Size, TableSize - Size); //copy strings
} else {
CopyMem((void*)newSmbiosTable.Type2, (void*)SmbiosTable.Type2, TableSize); //copy full table
}
}
newSmbiosTable.Type2->Hdr.Length = (UINT8)NewSize;
newSmbiosTable.Type2->ChassisHandle = mHandle3; //from GetTableType3
newSmbiosTable.Type2->BoardType = smbiosSettings.BoardType;
ZeroMem((void*)&newSmbiosTable.Type2->FeatureFlag, sizeof(BASE_BOARD_FEATURE_FLAGS));
newSmbiosTable.Type2->FeatureFlag.Motherboard = 1;
newSmbiosTable.Type2->FeatureFlag.Replaceable = 1;
if (smbiosSettings.BoardType == 11) {
newSmbiosTable.Type2->FeatureFlag.Removable = 1;
}
Once = true;
UniquifySmbiosTableStr(newSmbiosTable, SMBIOS_TABLE_TYPE2_STR_IDX);
if( smbiosSettings.BoardManufactureName.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type2->Manufacturer, smbiosSettings.BoardManufactureName);
}
if( smbiosSettings.BoardNumber.notEmpty() ){
DBG("%s : UpdateSmbiosString ProductName=BoardNumber=%s\n", __PRETTY_FUNCTION__, smbiosSettings.BoardNumber.c_str());
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type2->ProductName, smbiosSettings.BoardNumber);
}
if( smbiosSettings.BoardVersion.notEmpty() ){
DBG("%s : UpdateSmbiosString Version=BoardVersion=%s\n", __PRETTY_FUNCTION__, smbiosSettings.BoardVersion.c_str());
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type2->Version, smbiosSettings.BoardVersion); //iMac17,1 - there is ProductName
}
if( smbiosSettings.BoardSerialNumber.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type2->SerialNumber, smbiosSettings.BoardSerialNumber);
}
if( smbiosSettings.LocationInChassis.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type2->LocationInChassis, smbiosSettings.LocationInChassis);
}
//what about Asset Tag??? Not used in real mac. till now.
//Slice - for the table2 one patch more needed
/* spec
Field 0x0E - Identifies the number (0 to 255) of Contained Object Handles that follow
Field 0x0F - A list of handles of other structures (for example, Baseboard, Processor, Port, System Slots, Memory Device) that are contained by this baseboard
It may be good before our patching but changed after. We should at least check if all tables mentioned here are present in final structure
I just set 0 as in iMac11
*/
newSmbiosTable.Type2->NumberOfContainedObjectHandles = 0;
Handle = LogSmbiosTable(newSmbiosTable);
return;
}
XBool getMobileFromSmbios()
{
// System Chassis Information
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, 0);
if (SmbiosTable.Raw == NULL) {
//DBG("SmbiosTable: Type 3 (System Chassis Information) not found!\n");
return false;
}
mHandle3 = SmbiosTable.Type3->Hdr.Handle;
//DBG("getMobileFromSmbios (SmbiosTable.Type3->Type=%d) %d\n", SmbiosTable.Type3->Type, ((SmbiosTable.Type3->Type) >= 8) && (SmbiosTable.Type3->Type != 0x0D));
return ((SmbiosTable.Type3->Type) >= 8) && (SmbiosTable.Type3->Type != 0x0D); //iMac is desktop!
}
void GetTableType3(SmbiosDiscoveredSettings* smbiosSettings)
{
// System Chassis Information
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, 0);
if (SmbiosTable.Raw == NULL) {
DBG("SmbiosTable: Type 3 (System Chassis Information) not found!\n");
gMobile = false; //default value
return;
}
mHandle3 = SmbiosTable.Type3->Hdr.Handle;
gMobile = ((SmbiosTable.Type3->Type) >= 8) && (SmbiosTable.Type3->Type != 0x0D); //iMac is desktop!
return;
}
void PatchTableType3(const SmbiosInjectedSettings& smbiosSettings)
{
// System Chassis Information
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, 0);
if (SmbiosTable.Raw == NULL) {
// DBG("SmbiosTable: Type 3 (System Chassis Information) not found!\n");
return;
}
UINTN Size = SmbiosTable.Type3->Hdr.Length; //old size
TableSize = SmbiosTableLength(SmbiosTable); //including strings
UINTN NewSize = 0x15; //sizeof(SMBIOS_TABLE_TYPE3);
ZeroMem((void*)newSmbiosTable.Type3, MAX_TABLE_SIZE);
if (NewSize > Size) {
CopyMem((void*)newSmbiosTable.Type3, (void*)SmbiosTable.Type3, Size); //copy main table
CopyMem((CHAR8*)newSmbiosTable.Type3 + NewSize, (CHAR8*)SmbiosTable.Type3 + Size, TableSize - Size); //copy strings
newSmbiosTable.Type3->Hdr.Length = (UINT8)NewSize;
} else {
CopyMem((void*)newSmbiosTable.Type3, (void*)SmbiosTable.Type3, TableSize); //copy full table
}
newSmbiosTable.Type3->BootupState = ChassisStateSafe;
newSmbiosTable.Type3->PowerSupplyState = ChassisStateSafe;
newSmbiosTable.Type3->ThermalState = ChassisStateOther;
newSmbiosTable.Type3->SecurityStatus = ChassisSecurityStatusOther; //ChassisSecurityStatusNone;
newSmbiosTable.Type3->NumberofPowerCords = 1;
newSmbiosTable.Type3->ContainedElementCount = 0;
newSmbiosTable.Type3->ContainedElementRecordLength = 0;
Once = true;
UniquifySmbiosTableStr(newSmbiosTable, SMBIOS_TABLE_TYPE3_STR_IDX);
if (smbiosSettings.ChassisType != 0) {
newSmbiosTable.Type3->Type = smbiosSettings.ChassisType;
}
if( smbiosSettings.ChassisManufacturer.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type3->Manufacturer, smbiosSettings.ChassisManufacturer);
}
//SIC! According to iMac there must be the BoardNumber
if( smbiosSettings.BoardNumber.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type3->Version, smbiosSettings.BoardNumber);
}
if( smbiosSettings.SerialNr.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type3->SerialNumber, smbiosSettings.SerialNr);
//DBG("%s : UpdateSmbiosString SerialNr=%s\n", __PRETTY_FUNCTION__, smbiosSettings.SerialNr.c_str());
}
if( smbiosSettings.ChassisAssetTag.notEmpty() ){
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type3->AssetTag, smbiosSettings.ChassisAssetTag);
}
Handle = LogSmbiosTable(newSmbiosTable);
return;
}
void GetTableType4(SmbiosDiscoveredSettings* smbiosSettings)
{
// Processor Information
//
INTN res = 0;
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, 0);
if (SmbiosTable.Raw == NULL) {
DBG("SmbiosTable: Type 4 (Processor Information) not found!\n");
return;
}
res = (SmbiosTable.Type4->ExternalClock * 3 + 2) % 100;
if (res > 2) {
res = 0;
} else {
res = SmbiosTable.Type4->ExternalClock % 10;
}
smbiosSettings->ExternalClock = (UINT32)((SmbiosTable.Type4->ExternalClock * 1000) + (res * 110));//MHz->kHz
//snwprintf(gSettings.BusSpeed, 10, "%d", smbiosSettings.ExternalClock);
//gSettings.BusSpeed = smbiosSettings.ExternalClock; //why duplicate??
smbiosSettings->CurrentSpeed = SmbiosTable.Type4->CurrentSpeed;
smbiosSettings->MaxSpeed = SmbiosTable.Type4->MaxSpeed;
size_t off = OFFSET_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount);
if (SmbiosTable.Type4->Hdr.Length > off) { //Smbios >= 2.5
smbiosSettings->EnabledCores = SmbiosTable.Type4->EnabledCoreCount;
} else {
smbiosSettings->EnabledCores = 0; //to change later
}
//snwprintf(gSettings.CpuFreqMHz, 10, "%d", smbiosSettings.CurrentSpeed);
//gSettings.CpuFreqMHz = smbiosSettings.CurrentSpeed;
return;
}
void PatchTableType4(const SmbiosInjectedSettings& smbiosSettings)
{
// Processor Information
//
UINTN AddBrand = 0;
UINT16 ProcChar = 0;
//Note. iMac11,2 has four tables for CPU i3
UINTN CpuNumber;
// DBG("BrandString=%s\n", BrandStr);
for (CpuNumber = 0; CpuNumber < smbiosSettings.Cores; CpuNumber++) {
// Get Table Type4
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, CpuNumber);
if (SmbiosTable.Raw == NULL) {
break;
}
// we make SMBios v2.4 while it may be older so we have to increase size
UINTN Size = SmbiosTable.Type4->Hdr.Length; //old size
TableSize = SmbiosTableLength(SmbiosTable); //including strings
AddBrand = 0;
if (SmbiosTable.Type4->ProcessorVersion == 0) { //if no BrandString we can add
AddBrand = 48;
}
UINTN NewSize = sizeof(SMBIOS_TABLE_TYPE4);
ZeroMem((void*)newSmbiosTable.Type4, MAX_TABLE_SIZE);
CopyMem((void*)newSmbiosTable.Type4, (void*)SmbiosTable.Type4, Size); //copy main table
CopyMem((CHAR8*)newSmbiosTable.Type4+NewSize, (CHAR8*)SmbiosTable.Type4+Size, TableSize - Size); //copy strings
newSmbiosTable.Type4->Hdr.Length = (UINT8)NewSize;
newSmbiosTable.Type4->MaxSpeed = (UINT16)smbiosSettings.MaxSpeed;
//old version has no such fields. Fill now
if (Size <= 0x20){
//sanity check and clear
newSmbiosTable.Type4->SerialNumber = 0;
newSmbiosTable.Type4->AssetTag = 0;
newSmbiosTable.Type4->PartNumber = 0;
}
if (Size <= 0x23) { //Smbios <=2.3
newSmbiosTable.Type4->CoreCount = smbiosSettings.Cores;
newSmbiosTable.Type4->ThreadCount = smbiosSettings.Threads;
newSmbiosTable.Type4->ProcessorCharacteristics = (UINT16)smbiosSettings.Features;
} //else we propose DMI data is better then cpuid().
// if (newSmbiosTable.Type4->CoreCount < newSmbiosTable.Type4->EnabledCoreCount) {
// newSmbiosTable.Type4->EnabledCoreCount = smbiosSettings.Cores;
// }
//DBG("insert ExternalClock: %d MHz\n", (INT32)(DivU64x32(smbiosSettings.ExternalClock, Kilo)));
newSmbiosTable.Type4->ExternalClock = (UINT16)DivU64x32 (smbiosSettings.ExternalClock, Kilo);
newSmbiosTable.Type4->EnabledCoreCount = smbiosSettings.EnabledCores;
//some verifications
if ((newSmbiosTable.Type4->ThreadCount < newSmbiosTable.Type4->CoreCount) ||
newSmbiosTable.Type4->ThreadCount > newSmbiosTable.Type4->CoreCount * 2) {
newSmbiosTable.Type4->ThreadCount = smbiosSettings.Threads;
}
UniquifySmbiosTableStr(newSmbiosTable, SMBIOS_TABLE_TYPE4_STR_IDX);
// TODO: Set SmbiosTable.Type4->ProcessorFamily for all implemented CPU models
Once = true;
if (smbiosSettings.Model == CPU_MODEL_ATOM) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelAtom;
}
if ((smbiosSettings.Model == CPU_MODEL_DOTHAN) ||
(smbiosSettings.Model == CPU_MODEL_YONAH)) {
if (smbiosSettings.Mobile) {
newSmbiosTable.Type4->ProcessorUpgrade = ProcessorUpgradeSocket478;
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCoreSoloMobile;
if (smbiosSettings.Cores == 2) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCoreDuoMobile;
}
} else {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCoreSolo;
if (smbiosSettings.Cores == 2) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCoreDuo;
}
}
}
if (smbiosSettings.Model == CPU_MODEL_MEROM) {
if (smbiosSettings.Mobile) {
if (smbiosSettings.Cores==2) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2DuoMobile;
}
if (smbiosSettings.Cores==1) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2SoloMobile;
}
} else { // Conroe
newSmbiosTable.Type4->ProcessorUpgrade = ProcessorUpgradeSocketLGA775;
if (smbiosSettings.Cores>2) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2Quad;
} else
if (smbiosSettings.Cores==2) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2Extreme;
}
if (smbiosSettings.Cores==1) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2Solo;
}
}
}
if (smbiosSettings.Model == CPU_MODEL_PENRYN) {
if (smbiosSettings.Mobile) {
if (smbiosSettings.Cores>2) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2ExtremeMobile;
}
if (smbiosSettings.Cores==2) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2DuoMobile;
}
} else {
newSmbiosTable.Type4->ProcessorUpgrade = ProcessorUpgradeSocketLGA775;
if (smbiosSettings.Cores>2) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2Quad;
} else if (smbiosSettings.Cores==2) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2;
} else {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2Solo;
}
if ( smbiosSettings.BrandString.contains("Celeron") ) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyDualCoreIntelCeleron;
} else if ( smbiosSettings.BrandString.contains("Extreme") ) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2Extreme;
}
}
}
if (smbiosSettings.Model >= CPU_MODEL_NEHALEM) {
if ( smbiosSettings.BrandString.contains("i3") )
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCoreI3;
if ( smbiosSettings.BrandString.contains("i5") )
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCoreI5;
if ( smbiosSettings.BrandString.contains("i7") )
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCoreI7;
}
//spec 2.7 page 48 note 3
if ((newSmbiosTable.Type4->ProcessorFamily == ProcessorFamilyIntelCore2)
&& smbiosSettings.Mobile) {
newSmbiosTable.Type4->ProcessorFamily = ProcessorFamilyIntelCore2DuoMobile;
}
// Set CPU Attributes
newSmbiosTable.Type4->L1CacheHandle = L1;
newSmbiosTable.Type4->L2CacheHandle = L2;
newSmbiosTable.Type4->L3CacheHandle = L3;
newSmbiosTable.Type4->ProcessorType = CentralProcessor;
newSmbiosTable.Type4->ProcessorId.Signature.ProcessorSteppingId = smbiosSettings.Stepping;
newSmbiosTable.Type4->ProcessorId.Signature.ProcessorModel = (smbiosSettings.Model & 0xF);
newSmbiosTable.Type4->ProcessorId.Signature.ProcessorFamily = smbiosSettings.Family;
newSmbiosTable.Type4->ProcessorId.Signature.ProcessorType = smbiosSettings.Type;
newSmbiosTable.Type4->ProcessorId.Signature.ProcessorXModel = smbiosSettings.Extmodel;
newSmbiosTable.Type4->ProcessorId.Signature.ProcessorXFamily = smbiosSettings.Extfamily;
// CopyMem((void*)&newSmbiosTable.Type4->ProcessorId.FeatureFlags, (void*)&smbiosSettings.Features, 4);
// newSmbiosTable.Type4->ProcessorId.FeatureFlags = (PROCESSOR_FEATURE_FLAGS)(UINT32)smbiosSettings.Features;
if (Size <= 0x26) {
newSmbiosTable.Type4->ProcessorFamily2 = newSmbiosTable.Type4->ProcessorFamily;
ProcChar |= (smbiosSettings.ExtFeatures & CPUID_EXTFEATURE_EM64T)?0x04:0;
ProcChar |= (smbiosSettings.Cores > 1)?0x08:0;
ProcChar |= (smbiosSettings.Cores < smbiosSettings.Threads)?0x10:0;
ProcChar |= (smbiosSettings.ExtFeatures & CPUID_EXTFEATURE_XD)?0x20:0;
ProcChar |= (smbiosSettings.Features & CPUID_FEATURE_VMX)?0x40:0;
ProcChar |= (smbiosSettings.Features & CPUID_FEATURE_EST)?0x80:0;
newSmbiosTable.Type4->ProcessorCharacteristics = ProcChar;
}
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type4->Socket, "U2E1"_XS8);
XString8 BrandStr;
BrandStr.takeValueFrom(smbiosSettings.BrandString);
if (AddBrand) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type4->ProcessorVersion, BrandStr);
}
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type4->AssetTag, BrandStr); //like mac
// looks to be MicroCode revision
if(smbiosSettings.MicroCode > 0){
BrandStr.S8Printf("%llX", smbiosSettings.MicroCode);
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
Handle = LogSmbiosTable(newSmbiosTable);
}
return;
}
void PatchTableType6(const SmbiosInjectedSettings& smbiosSettings)
{
UINT8 SizeField = 0;
//
// MemoryModule (TYPE 6)
// This table is obsolete accoding to Spec but Apple still using it so
// copy existing table if found, no patches will be here
// we can have more then 1 module.
for (size_t Index = 0; Index < MAX_RAM_SLOTS; Index++) {
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_MEMORY_MODULE_INFORMATON,Index);
if (SmbiosTable.Raw == NULL) {
// MsgLog("SMBIOS Table 6 index %d not found\n", Index);
continue;
}
SizeField = SmbiosTable.Type6->InstalledSize.InstalledOrEnabledSize & 0x7F;
UINT64 mInstalled = 0;
if (SizeField < 0x7D) {
mInstalled = LShiftU64(1ULL, 20 + SizeField);
} else if (SizeField == 0x7F) {
mInstalled = 0;
} else {
mInstalled = 4096ULL * (1024ULL * 1024ULL);
}
MsgLog("Table 6 MEMORY_MODULE %zu Installed %llX ", Index, mInstalled);
UINT64 mEnabled = 0;
if (SizeField >= 0x7D) {
mEnabled = 0;
} else {
mEnabled = LShiftU64(1ULL, 20 + ((UINT8)SmbiosTable.Type6->EnabledSize.InstalledOrEnabledSize & 0x7F));
}
MsgLog("... enabled %llX \n", mEnabled);
LogSmbiosTable(SmbiosTable);
}
return;
}
void PatchTableType7(const SmbiosInjectedSettings& smbiosSettings)
{
// Cache Information
//
//TODO - should be separate table for each CPU core
//new handle for each core and attach Type4 tables for individual Type7
// Handle = 0x0700 + CoreN<<2 + CacheN (4-level cache is supported
// L1[CoreN] = Handle
XBool correctSD = false;
//according to spec for Smbios v2.0 max handle is 0xFFFE, for v>2.0 (we made 2.6) max handle=0xFEFF.
// Value 0xFFFF means no cache
L1 = 0xFFFF; // L1 Cache
L2 = 0xFFFF; // L2 Cache
L3 = 0xFFFF; // L3 Cache
// Get Table Type7 and set CPU Caches
for (size_t Index = 0; Index < MAX_CACHE_COUNT; Index++) {
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_CACHE_INFORMATION, Index);
if (SmbiosTable.Raw == NULL) {
break;
}
TableSize = SmbiosTableLength(SmbiosTable);
ZeroMem((void*)newSmbiosTable.Type7, MAX_TABLE_SIZE);
CopyMem((void*)newSmbiosTable.Type7, (void*)SmbiosTable.Type7, TableSize);
correctSD = (newSmbiosTable.Type7->SocketDesignation == 0);
CoreCache = newSmbiosTable.Type7->CacheConfiguration & 3;
Once = true;
//SSocketD = "L1-Cache";
if(correctSD) {
XString8 SSocketD = S8Printf("L%c-Cache", 0x31 + CoreCache);
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type7->SocketDesignation, SSocketD);
}
Handle = LogSmbiosTable(newSmbiosTable);
switch (CoreCache) {
case 0:
L1 = Handle;
break;
case 1:
L2 = Handle;
break;
case 2:
L3 = Handle;
break;
default:
break;
}
}
return;
}
void PatchTableType9(const SmbiosInjectedSettings& smbiosSettings)
{
//
// System Slots (Type 9)
/*
SlotDesignation: PCI1
System Slot Type: PCI
System Slot Data Bus Width: 32 bit
System Slot Current Usage: Available
System Slot Length: Short length
System Slot Type: PCI
Slot Id: the value present in the Slot Number field of the PCI Interrupt Routing table entry that is associated with this slot is: 1
Slot characteristics 1: Provides 3.3 Volts | Slot's opening is shared with another slot, e.g. PCI/EISA shared slot. |
Slot characteristics 2: PCI slot supports Power Management Enable (PME#) signal |
SegmentGroupNum: 0x4350
BusNum: 0x49
DevFuncNum: 0x31
Real Mac always contain Airport table 9 as
09 0D xx xx 01 A5 08 03 03 00 00 04 06 "AirPort"
*/
//usage in macOS:
// SlotID == value of Name(_SUN, SlotID) 8bit
// SlotDesignation == name to "AAPL,slot-name"
// 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
for (uint8_t Index = 0; Index < 15; Index++) {
if (smbiosSettings.SlotDevices.isSlotForIndexValid(Index)) {
INTN Dev, Func;
ZeroMem((void*)newSmbiosTable.Type9, MAX_TABLE_SIZE);
newSmbiosTable.Type9->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_SLOTS;
newSmbiosTable.Type9->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE9);
newSmbiosTable.Type9->Hdr.Handle = (UINT16)(0x0900 + Index);
newSmbiosTable.Type9->SlotDesignation = 1;
newSmbiosTable.Type9->SlotType = (uint8_t)smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotType;
newSmbiosTable.Type9->SlotDataBusWidth = SlotDataBusWidth1X;
newSmbiosTable.Type9->CurrentUsage = SlotUsageAvailable;
newSmbiosTable.Type9->SlotLength = SlotLengthShort;
newSmbiosTable.Type9->SlotID = smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotID;
newSmbiosTable.Type9->SlotCharacteristics1.Provides33Volts = 1;
newSmbiosTable.Type9->SlotCharacteristics2.HotPlugDevicesSupported = 1;
// take this from PCI bus for WiFi card
newSmbiosTable.Type9->SegmentGroupNum = smbiosSettings.SlotDevices.getSlotForIndex(Index).SegmentGroupNum;
newSmbiosTable.Type9->BusNum = smbiosSettings.SlotDevices.getSlotForIndex(Index).BusNum;
newSmbiosTable.Type9->DevFuncNum = smbiosSettings.SlotDevices.getSlotForIndex(Index).DevFuncNum;
//
Dev = smbiosSettings.SlotDevices.getSlotForIndex(Index).DevFuncNum >> 3;
Func = smbiosSettings.SlotDevices.getSlotForIndex(Index).DevFuncNum & 7;
DBG("insert table 9 for dev %llX:%llX\n", Dev, Func);
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type9->SlotDesignation, smbiosSettings.SlotDevices.getSlotForIndex(Index).SlotName);
LogSmbiosTable(newSmbiosTable);
}
}
return;
}
void PatchTableType11(const SmbiosInjectedSettings& smbiosSettings)
{
// CHAR8 *OEMString = "Apple inc. uses Clover"; //something else here?
// System Information
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_OEM_STRINGS, 0);
if (SmbiosTable.Raw != NULL) {
MsgLog("Table 11 present, but rewritten for us\n");
}
// TableSize = SmbiosTableLength(SmbiosTable);
ZeroMem((void*)newSmbiosTable.Type11, MAX_TABLE_SIZE);
// CopyMem((void*)newSmbiosTable.Type11, (void*)SmbiosTable.Type11, 5); //minimum, other bytes = 0
newSmbiosTable.Type11->Hdr.Type = EFI_SMBIOS_TYPE_OEM_STRINGS;
newSmbiosTable.Type11->Hdr.Length = 5;
newSmbiosTable.Type11->Hdr.Handle = 0x0B00; //common rule
newSmbiosTable.Type11->StringCount = 1;
//
// ZeroMem(OEMString, MAX_OEM_STRING);
// AsciiStrCatS(OEMString, MAX_OEM_STRING, "Apple ROM Version.\n");
// //AsciiStrCatS(OEMString, MAX_OEM_STRING, " BIOS ID:");
// //AsciiStrnCatS(OEMString, MAX_OEM_STRING, smbiosSettings.RomVersion, iStrLen(smbiosSettings.RomVersion, 64));
// // AsciiStrCatS(OEMString, MAX_OEM_STRING, "\n EFI Version:");
// // AsciiStrnCatS(OEMString, MAX_OEM_STRING, smbiosSettings.EfiVersion, iStrLen(smbiosSettings.EfiVersion, 64));
// AsciiStrCatS(OEMString, MAX_OEM_STRING, " Board-ID : ");
// AsciiStrnCatS(OEMString, MAX_OEM_STRING, smbiosSettings.BoardNumber, iStrLen(smbiosSettings.BoardNumber, 64));
// snprintf(TempRev, MAX_OEM_STRING, "\n⌘ Powered by %s\n", gRevisionStr);
// AsciiStrCatS(OEMString, MAX_OEM_STRING, TempRev);
#ifdef JIEF_DEBUG
XString8 OEMString = S8Printf("⌘ Powered by %s\n", gBuildId.c_str());
#else
XString8 OEMString = S8Printf("Apple ROM Version.\nBoard-ID : %s\n⌘ Powered by %s\n", smbiosSettings.BoardNumber.c_str(), gRevisionStr);
#endif
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type11->StringCount, OEMString);
LogSmbiosTable(newSmbiosTable);
return;
}
//some unused but interesting tables. Just log as is
#define NUM_OTHER_TYPES 14
const UINT8 tableTypes[] = {8, 10, 13, 18, 21, 22, 27, 28, 32, 33, 41, 129, 217, 219};
void PatchTableTypeSome()
{
for (UINTN IndexType = 0; IndexType < sizeof(tableTypes); IndexType++) {
for (size_t Index = 0; Index < 32; Index++) {
SmbiosTable = GetSmbiosTableFromType(EntryPoint, tableTypes[IndexType], Index);
if (SmbiosTable.Raw == NULL) {
continue;
}
LogSmbiosTable(SmbiosTable);
}
}
return;
}
void GetTableType16(SmbiosDiscoveredSettings* smbiosSettings)
{
// Physical Memory Array
//
mTotalSystemMemory = 0; //later we will add to the value, here initialize it
smbiosSettings->RamSlotCount = 0;
for (size_t Index = 0; Index < 8; Index++) { //how many tables there may be?
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, Index);
if (SmbiosTable.Raw == NULL) {
// DBG("SmbiosTable: Type 16 (Physical Memory Array) not found!\n");
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 ) {
DBG("Total Memory Slots Count is adjusted from 0 to %d\n", MAX_RAM_SLOTS);
smbiosSettings->RamSlotCount = MAX_RAM_SLOTS;
}else{
//Jief_Machak: VMWare report 64 memory slots !!! MAX_RAM_SLOTS is currently 24. Crash is PatchTable17.
if ( smbiosSettings->RamSlotCount > MAX_RAM_SLOTS ) {
DBG("Total Memory Slots Count is adjusted from %d to %d\n", smbiosSettings->RamSlotCount, MAX_RAM_SLOTS);
smbiosSettings->RamSlotCount = MAX_RAM_SLOTS;
}else{
DBG("Total Memory Slots Count = %d\n", smbiosSettings->RamSlotCount);
}
}
}
void PatchTableType16(const SmbiosInjectedSettings& smbiosSettings)
{
// Physical Memory Array
//
// Get Table Type16 and set Device Count
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, 0);
if (SmbiosTable.Raw == NULL) {
DBG("SmbiosTable: Type 16 (Physical Memory Array) not found!\n");
return;
}
TableSize = SmbiosTableLength(SmbiosTable);
ZeroMem((void*)newSmbiosTable.Type16, MAX_TABLE_SIZE);
CopyMem((void*)newSmbiosTable.Type16, (void*)SmbiosTable.Type16, TableSize);
newSmbiosTable.Type16->Hdr.Handle = mHandle16;
// Slice - I am not sure if I want these values
// newSmbiosTable.Type16->Location = MemoryArrayLocationProprietaryAddonCard;
// newSmbiosTable.Type16->Use = MemoryArrayUseSystemMemory;
// newSmbiosTable.Type16->MemoryErrorCorrection = MemoryErrorCorrectionMultiBitEcc;
// MemoryErrorInformationHandle
newSmbiosTable.Type16->MemoryErrorInformationHandle = 0xFFFF;
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 FoundOneTable;
// Get Table Type17 and count Size
for (size_t Index = 0; Index < smbiosSettings->RamSlotCount; Index++) { //how many tables there may be?
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_MEMORY_DEVICE, Index);
if (SmbiosTable.Raw == NULL) {
// DBG("SmbiosTable: Type 17 (Memory Device number %d) not found!\n", Index);
continue;
}
FoundOneTable = true;
//#ifndef JIEF_DEBUG // it's all 0 in VMWare
DBG("Type 17 Index = %zu\n", Index);
//#endif
//gDMI->CntMemorySlots++;
if (SmbiosTable.Type17->MemoryErrorInformationHandle < 0xFFFE) {
DBG("Table has error information, checking\n"); //why skipping?
// Why trust it if it has an error? I guess we could look
// up the error handle and determine certain errors may
// be skipped where others may not but it seems easier
// to just skip all entries that have an error - apianti
// will try
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) {
continue;
}
if (newSmbiosTable.Type18->Hdr.Handle == SmbiosTable.Type17->MemoryErrorInformationHandle) {
Found = true;
DBG("Found memory information in table 18/%lld, type=0x%X, operation=0x%X syndrome=0x%X\n", Index2,
newSmbiosTable.Type18->ErrorType,
newSmbiosTable.Type18->ErrorOperation,
newSmbiosTable.Type18->VendorSyndrome);
switch (newSmbiosTable.Type18->ErrorType) {
case MemoryErrorOk:
DBG("...memory OK\n");
break;
case MemoryErrorCorrected:
DBG("...memory errors corrected\n");
break;
case MemoryErrorChecksum:
DBG("...error type: Checksum\n");
break;
default:
DBG("...error type not shown\n");
break;
}
break;
}
}
if (Found) {
if ((newSmbiosTable.Type18->ErrorType != MemoryErrorOk) &&
(newSmbiosTable.Type18->ErrorType != MemoryErrorCorrected)) {
DBG("skipping wrong module\n");
continue;
}
}
}
RAM_SLOT_INFO* rsiPtr = NULL;
// Determine if slot has size
if (SmbiosTable.Type17->Size > 0) {
rsiPtr = new RAM_SLOT_INFO;
RAM_SLOT_INFO& rsi = *rsiPtr;
rsi.ModuleSize = SmbiosTable.Type17->Size;
if (SmbiosTable.Type17->Size == 0x7FFF) {
rsi.ModuleSize = SmbiosTable.Type17->ExtendedSize;
}
}
// Determine if module frequency is sane value
if ((SmbiosTable.Type17->Speed > 0) && (SmbiosTable.Type17->Speed <= MAX_RAM_FREQUENCY)) {
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;
}
} else {
#ifndef JIEF_DEBUG // always the case in VMWare
DBG("Ignoring insane frequency value %dMHz\n", SmbiosTable.Type17->Speed);
#endif
}
// Fill rest of information if in use
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 = %d\n", rsi.Type);
DBG("SmbiosTable.Type17->Frequency = %dMHz\n", rsi.Frequency);
DBG("SmbiosTable.Type17->Bank/Device = %s %s\n", GetSmbiosString(SmbiosTable, SmbiosTable.Type17->BankLocator), GetSmbiosString(SmbiosTable, SmbiosTable.Type17->DeviceLocator));
DBG("SmbiosTable.Type17->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
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, XArray<UINT16>* mMemory17Ptr, XArray<UINT16>* mHandle17Ptr)
{
XArray<UINT16>& mMemory17 = *mMemory17Ptr;
XArray<UINT16>& mHandle17 = *mHandle17Ptr;
XString8 deviceLocator;
XString8 bankLocator;
#if defined (__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wvla-extension"
#endif
UINT8 channelMap[mMemory17.size()]; // mMemory17.size() == SlotCounts
#if defined (__clang__)
#pragma clang diagnostic pop
#endif
UINT8 expectedCount = 0;
UINT8 channels = 2;
XBool insertingEmpty = true;
XBool trustSMBIOS = ( gRAM.SPD.size() == 0 || smbiosSettings.TrustSMBIOS);
XBool wrongSMBIOSBanks = false;
XBool isMacPro = false;
MacModel Model = GetModelFromString(smbiosSettings.ProductName);
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._User.size() == 0) {
DBG("User SMBIOS contains no memory modules\n");
return;
}
// Check channels
auto UserChannels = smbiosSettings.Memory.UserChannels;
if ( UserChannels == 0 || UserChannels > 8 ) {
UserChannels = 1;
}
DBG("Channels: %d\n", UserChannels);
// Setup interleaved channel map
if (channels >= 2) {
UINT8 doubleChannels = (UINT8)UserChannels << 1;
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 < mMemory17.size(); ++Index) {
channelMap[Index] = (UINT8)Index;
}
}
DBG("Interleave:");
for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
DBG(" %d", channelMap[Index]);
}
DBG("\n");
// Memory Device
//
// Inject tables
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 < mMemory17.size(); Index++) {
UINTN UserIndex = channelMap[Index];
UINT8 bank = (UINT8)(Index / UserChannels);
ZeroMem((void*)newSmbiosTable.Type17, MAX_TABLE_SIZE);
newSmbiosTable.Type17->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
newSmbiosTable.Type17->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE17);
newSmbiosTable.Type17->TotalWidth = 0xFFFF;
newSmbiosTable.Type17->DataWidth = 0xFFFF;
newSmbiosTable.Type17->Hdr.Handle = (UINT16)(0x1100 + UserIndex);
newSmbiosTable.Type17->FormFactor = (UINT8)(gMobile ? MemoryFormFactorSodimm : MemoryFormFactorDimm);
newSmbiosTable.Type17->TypeDetail.Synchronous = true;
newSmbiosTable.Type17->DeviceSet = bank + 1;
newSmbiosTable.Type17->MemoryArrayHandle = mHandle16;
if (isMacPro) {
deviceLocator.S8Printf("DIMM%zd", Index + 1);
} else {
deviceLocator.S8Printf("DIMM%d", bank);
bankLocator.S8Printf("BANK %zu", Index % channels);
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->BankLocator, bankLocator);
}
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->DeviceLocator, deviceLocator);
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 {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, unknown);
}
if (smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).SerialNo.notEmpty()) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).SerialNo);
} else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, unknown);
}
if (smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).PartNo.notEmpty()) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).PartNo);
} else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->PartNumber, unknown);
}
newSmbiosTable.Type17->Speed = (UINT16)smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).Frequency;
if (smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).ModuleSize > 0x7FFF) {
newSmbiosTable.Type17->Size = 0x7FFF;
newSmbiosTable.Type17->ExtendedSize = smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).ModuleSize;
mTotalSystemMemory += newSmbiosTable.Type17->ExtendedSize; //Mb
} else {
newSmbiosTable.Type17->Size = (UINT16)smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).ModuleSize;
mTotalSystemMemory += newSmbiosTable.Type17->Size; //Mb
}
newSmbiosTable.Type17->MemoryType = smbiosSettings.Memory.getSlotInfoForSlotID(UserIndex).Type;
if ((newSmbiosTable.Type17->MemoryType != MemoryTypeDdr2) &&
(newSmbiosTable.Type17->MemoryType != MemoryTypeDdr4) &&
(newSmbiosTable.Type17->MemoryType != MemoryTypeDdr)) {
newSmbiosTable.Type17->MemoryType = MemoryTypeDdr3;
}
DBG("%s %s %dMHz %dMB(Ext:%dMB)\n", bankLocator.c_str(), deviceLocator.c_str(), newSmbiosTable.Type17->Speed,
newSmbiosTable.Type17->Size, newSmbiosTable.Type17->ExtendedSize);
mMemory17[Index] = (UINT16)mTotalSystemMemory;
// DBG("mTotalSystemMemory = %d\n", mTotalSystemMemory);
} else {
DBG("%s %s EMPTY\n", bankLocator.c_str(), deviceLocator.c_str());
}
newSmbiosTable.Type17->MemoryErrorInformationHandle = 0xFFFF;
mHandle17[Index] = LogSmbiosTable(newSmbiosTable);
}
if (mTotalSystemMemory > 0) {
DBG("mTotalSystemMemory = %d\n", mTotalSystemMemory);
}
return;
}else{
DBG("Do not inject memory table\n");
}
// Prevent inserting empty tables
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.SMBIOS.size() != 0) {
// if (gRAM.SPD.size() != 0) {
// if (gRAM.SPD.size() != gRAM.SMBIOS.size()) {
// // Prefer the SPD information -- no, we trust SMBIOS!
// if (gRAM.SPD.size() > gRAM.SMBIOS.size()) {
// DBG("Not trusting SMBIOS because SPD reports more modules...\n");
// trustSMBIOS = false;
// } 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.SMBIOS.size() == 1) {
// channels = 1;
// }
// } else if (gRAM.SPD.size() == 1) {
// // The SMBIOS may contain table for built-in module
// 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 {
// DBG("Not trusting SMBIOS because SPD reports only one module...\n");
// trustSMBIOS = false;
// }
// } else {
// DBG("Not trusting SMBIOS because SPD reports less modules...\n");
// trustSMBIOS = false;
// }
// } 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.SMBIOS.size() == 1) {
channels = 1;
}
}
}
if (trustSMBIOS) {
DBG("Trusting SMBIOS...\n");
}
// Determine expected slot count
expectedCount = (smbiosSettings.RamSlotCount != 0) ? smbiosSettings.RamSlotCount : gRAM.SPD.getSlotCount();
if (trustSMBIOS) {
// Use the smbios in use count
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 ) {
if ( smbiosSettings.RamSlotCount > MAX_UINT8 ) {
// log_technical_bug("smbiosSettings.RamSlotCount > MAX_UINT8");
expectedCount = MAX_RAM_SLOTS;
}else{
expectedCount = (UINT8)smbiosSettings.RamSlotCount;
}
}
} else {
// Use default value of two for mobile or four for desktop
if (gMobile) {
if (expectedCount < 2) {
expectedCount = 2;
}
} else if (expectedCount < 4) {
expectedCount = 4;
}
}
// Check for interleaved channels
if (channels >= 2) {
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");
}
// Determine if using triple or quadruple channel
if (smbiosSettings.Memory.UserChannels != 0) {
channels = smbiosSettings.Memory.UserChannels;
} else if (gRAM.SPD.size() == 0) {
if (trustSMBIOS) {
if ((gRAM.SMBIOS.size() % 4) == 0) {
// Quadruple channel
if ((wrongSMBIOSBanks &&
(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.SMBIOS.size() % 3) == 0) {
// Triple channel
if ((wrongSMBIOSBanks &&
(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.SMBIOS.size() % 2) != 0)) {
channels = 1;
}
}
} else if ((gRAM.SPD.size() % 4) == 0) {
// Quadruple channel
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.SPD.size() % 3) == 0) {
// Triple channel
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.doesSlotForIndexExist(0) != gRAM.SPD.doesSlotForIndexExist(2)) ||
((gRAM.SPD.size() % 2) != 0)) {
channels = 1;
}
// Can't have less than the number of channels
if (expectedCount < channels) {
expectedCount = channels;
}
if (expectedCount > 0) {
--expectedCount;
}
DBG("Channels: %d\n", channels);
// Setup interleaved channel map
if (channels >= 2) {
UINT8 doubleChannels = (UINT8)channels << 1;
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 < mMemory17.size(); ++Index) {
channelMap[Index] = (UINT8)Index;
}
}
DBG("Interleave:");
for (size_t Index = 0; Index < mMemory17.size(); ++Index) {
DBG(" %d", channelMap[Index]);
}
DBG("\n");
// Memory Device
//
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.doesSlotForIndexExist(SPDIndex) && (!trustSMBIOS || !gRAM.SMBIOS.doesSlotForIndexExist(SMBIOSIndex))) {
continue;
}
SmbiosTable = GetSmbiosTableFromType(EntryPoint, EFI_SMBIOS_TYPE_MEMORY_DEVICE, SMBIOSIndex);
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.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor);
} else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, unknown);
}
if ( gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).SerialNo.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).SerialNo);
} else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->SerialNumber, unknown);
}
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(" 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);
newSmbiosTable.Type17->TotalWidth = 0xFFFF;
newSmbiosTable.Type17->DataWidth = 0xFFFF;
}
Once = true;
newSmbiosTable.Type17->Hdr.Handle = (UINT16)(0x1100 + Index);
newSmbiosTable.Type17->FormFactor = (UINT8)(gMobile ? MemoryFormFactorSodimm : MemoryFormFactorDimm);
newSmbiosTable.Type17->TypeDetail.Synchronous = true;
newSmbiosTable.Type17->DeviceSet = bank + 1;
newSmbiosTable.Type17->MemoryArrayHandle = mHandle16;
if (gRAM.SPD.doesSlotForIndexExist(SPDIndex)) {
DBG("SPD data in use:\n");
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.getSlotInfoForSlotIndex(SPDIndex).Vendor.notEmpty() ) {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Vendor);
} else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, unknown);
}
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.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.getSlotInfoForSlotIndex(SPDIndex).Frequency) {
newSmbiosTable.Type17->Speed = (UINT16)gRAM.Frequency; // unsafe cast
} else {
newSmbiosTable.Type17->Speed = gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Frequency;
}
if (gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).ModuleSize > 0x7FFF) {
newSmbiosTable.Type17->Size = 0x7FFF;
newSmbiosTable.Type17->ExtendedSize = gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).ModuleSize;
} else {
newSmbiosTable.Type17->Size = gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).ModuleSize;
}
newSmbiosTable.Type17->MemoryType = gRAM.SPD.getSlotInfoForSlotIndex(SPDIndex).Type;
}
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.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.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor.c_str());
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->Manufacturer, gRAM.SMBIOS.getSlotInfoForSlotIndex(SMBIOSIndex).Vendor);
}
// gSettings.MemorySpeed.S8Printf("%d", newSmbiosTable.Type17->Speed);
// Assume DDR3 unless explicitly set to DDR2/DDR/DDR4
if ((newSmbiosTable.Type17->MemoryType != MemoryTypeDdr2) &&
(newSmbiosTable.Type17->MemoryType != MemoryTypeDdr4) &&
(newSmbiosTable.Type17->MemoryType != MemoryTypeDdr)) {
newSmbiosTable.Type17->MemoryType = MemoryTypeDdr3;
}
//now I want to update deviceLocator and bankLocator
if (isMacPro) {
deviceLocator.S8Printf("DIMM%zd", Index + 1);
bankLocator.setEmpty();
} else {
deviceLocator.S8Printf("DIMM%d", bank);
bankLocator.S8Printf("BANK %zu", Index % channels);
}
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->DeviceLocator, deviceLocator);
if (isMacPro) {
newSmbiosTable.Type17->BankLocator = 0; //like in MacPro5,1
} else {
UpdateSmbiosString(newSmbiosTable, &newSmbiosTable.Type17->BankLocator, bankLocator);
}
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;
} else {
insertingEmpty = false;
DBG("%s %s %dMHz %dMB(Ext:%dMB)\n", bankLocator.c_str(), deviceLocator.c_str(), newSmbiosTable.Type17->Speed,
newSmbiosTable.Type17->Size, newSmbiosTable.Type17->ExtendedSize);
if (newSmbiosTable.Type17->Size == 0x7FFF) {
mTotalSystemMemory += newSmbiosTable.Type17->ExtendedSize; //Mb
} else {
mTotalSystemMemory += newSmbiosTable.Type17->Size; //Mb
}
mMemory17[Index] = (UINT16)mTotalSystemMemory;
// DBG("mTotalSystemMemory = %d\n", mTotalSystemMemory);
}
newSmbiosTable.Type17->MemoryErrorInformationHandle = 0xFFFF;
if (smbiosSettings.Attribute != -1) {
newSmbiosTable.Type17->Attributes = smbiosSettings.Attribute;
}
mHandle17[Index] = LogSmbiosTable(newSmbiosTable);
}
if (mTotalSystemMemory > 0) {
DBG("mTotalSystemMemory = %d\n", mTotalSystemMemory);
}
}
void
PatchTableType19 (const SmbiosInjectedSettings& smbiosSettings)
{
//
// Generate Memory Array Mapped Address info (TYPE 19)
//
/*
/// This structure provides the address mapping for a Physical Memory Array.
/// One structure is present for each contiguous address range described.
///
typedef struct {
SMBIOS_STRUCTURE Hdr;
UINT32 StartingAddress;
UINT32 EndingAddress;
UINT16 MemoryArrayHandle;
UINT8 PartitionWidth;
} SMBIOS_TABLE_TYPE19;
*/
//Slice - I created one table as a sum of all other. It is needed for SetupBrowser
UINT32 TotalEnd = 0;
UINT8 PartWidth = 1;
UINT16 SomeHandle = 0x1300; //as a common rule handle=(type<<8 + index)
for (size_t Index = 0; Index < smbiosSettings.RamSlotCount; Index++) {
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS, Index);
if (SmbiosTable.Raw == NULL) {
continue;
}
if (SmbiosTable.Type19->EndingAddress > TotalEnd) {
TotalEnd = SmbiosTable.Type19->EndingAddress;
}
PartWidth = SmbiosTable.Type19->PartitionWidth;
//SomeHandle = SmbiosTable.Type19->Hdr.Handle;
}
if (TotalEnd == 0) {
TotalEnd = (UINT32)(LShiftU64(mTotalSystemMemory, 10) - 1);
}
gTotalMemory = LShiftU64(mTotalSystemMemory, 20);
ZeroMem((void*)newSmbiosTable.Type19, MAX_TABLE_SIZE);
newSmbiosTable.Type19->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
newSmbiosTable.Type19->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
newSmbiosTable.Type19->Hdr.Handle = SomeHandle;
newSmbiosTable.Type19->MemoryArrayHandle = mHandle16;
newSmbiosTable.Type19->StartingAddress = 0;
newSmbiosTable.Type19->EndingAddress = TotalEnd;
newSmbiosTable.Type19->PartitionWidth = PartWidth;
mHandle19 = LogSmbiosTable(newSmbiosTable);
return ;
}
void PatchTableType20 (const SmbiosInjectedSettings& smbiosSettings, const XArray<UINT16>& mMemory17, const XArray<UINT16>& mHandle17)
{
UINTN j = 0, k = 0, m = 0;
//
// Generate Memory Array Mapped Address info (TYPE 20)
// not needed neither for Apple nor for EFI
m = 0;
for (size_t Index = 0; Index < smbiosSettings.RamSlotCount; Index++) {
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS, Index);
if (SmbiosTable.Raw == NULL) {
return ;
}
TableSize = SmbiosTableLength(SmbiosTable);
ZeroMem((void*)newSmbiosTable.Type20, MAX_TABLE_SIZE);
CopyMem((void*)newSmbiosTable.Type20, (void*)SmbiosTable.Type20, TableSize);
for (j=0; j < smbiosSettings.RamSlotCount; j++) {
//EndingAddress in kb while mMemory in Mb
if ((UINT32)(mMemory17[j] << 10) > newSmbiosTable.Type20->EndingAddress) {
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(" MemoryDeviceHandle = 0x%X\n", newSmbiosTable.Type20->MemoryDeviceHandle);
//mMemory17[j] = 0; // used
break;
}
// DBG("\n");
}
newSmbiosTable.Type20->MemoryArrayMappedAddressHandle = mHandle19;
//
// Record Smbios Type 20
//
LogSmbiosTable(newSmbiosTable);
}
return ;
}
void GetTableType32(SmbiosDiscoveredSettings* smbiosSettings)
{
SmbiosTable = GetSmbiosTableFromType (EntryPoint, EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, 0);
if (SmbiosTable.Raw == NULL) {
return;
}
gBootStatus = SmbiosTable.Type32->BootStatus;
}
/**
* Apple Specific Structures.
* Firmware Table, FirmwareVolume (TYPE 128).
*/
void PatchTableType128(const SmbiosInjectedSettings& smbiosSettings)
{
/**
* Useful information.
*
* FW_REGION_RESERVED = 0,
* FW_REGION_RECOVERY = 1,
* FW_REGION_MAIN = 2,
* gHob->MemoryAbove1MB.PhysicalStart + ResourceLength or fix as 0x200000 - 0x600000,
* FW_REGION_NVRAM = 3,
* FW_REGION_CONFIG = 4,
* FW_REGION_DIAGVAULT = 5.
*/
// Get the existing 128 table if exists.
//SmbiosTable = GetSmbiosTableFromType (EntryPoint, 128, 0);
// initialise new table
ZeroMem((void*)newSmbiosTable.Type128, MAX_TABLE_SIZE);
// common rules
newSmbiosTable.Type128->Hdr.Type = 128;
newSmbiosTable.Type128->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE128);
newSmbiosTable.Type128->Hdr.Handle = 0x8000;
// set firmware-features, example: 0x80001417, imac11,2 -> 0x1403.
newSmbiosTable.Type128->FirmwareFeatures = smbiosSettings.FirmwareFeatures;
// set firmware-features mask
newSmbiosTable.Type128->FirmwareFeaturesMask = smbiosSettings.FirmwareFeaturesMask;
newSmbiosTable.Type128->ExtendedFirmwareFeatures = (uint32_t)(smbiosSettings.ExtendedFirmwareFeatures >> 32);
newSmbiosTable.Type128->ExtendedFirmwareFeaturesMask = (uint32_t)(smbiosSettings.ExtendedFirmwareFeaturesMask >> 32);
/**
* TODO: I have an idea that region should be the same as Efivar.bin
* @author Slice
*/
newSmbiosTable.Type128->RegionCount = 1;
newSmbiosTable.Type128->RegionType[0] = FW_REGION_MAIN;
//UpAddress = mTotalSystemMemory << 20; //Mb -> b
//gHob->MemoryAbove1MB.PhysicalStart;
newSmbiosTable.Type128->FlashMap[0].StartAddress = 0xFFE00000; //0xF0000;
//gHob->MemoryAbove1MB.PhysicalStart + gHob->MemoryAbove1MB.ResourceLength - 1;
newSmbiosTable.Type128->FlashMap[0].EndAddress = 0xFFEFFFFF;
//newSmbiosTable.Type128->RegionType[1] = FW_REGION_NVRAM; //Efivar
//newSmbiosTable.Type128->FlashMap[1].StartAddress = 0x15000; //0xF0000;
//newSmbiosTable.Type128->FlashMap[1].EndAddress = 0x1FFFF;
//region type=1 also present in mac
// log the new, 128, sbmios table
LogSmbiosTable(newSmbiosTable);
return ;
}
void PatchTableType130(const SmbiosInjectedSettings& smbiosSettings)
{
//
// MemorySPD (TYPE 130)
// TODO: read SPD and place here. But for a what?
//
SmbiosTable = GetSmbiosTableFromType (EntryPoint, 130, 0);
if (SmbiosTable.Raw == NULL) {
return ;
}
//
// Log Smbios Record Type130
//
LogSmbiosTable(SmbiosTable);
return ;
}
void PatchTableType131(const SmbiosInjectedSettings& smbiosSettings)
{
// Get Table Type131
SmbiosTable = GetSmbiosTableFromType (EntryPoint, 131, 0);
if (SmbiosTable.Raw != NULL) {
MsgLog("Table 131 is present, CPUType=%hX\n", SmbiosTable.Type131->ProcessorType.Type);
MsgLog("Change to: %hX\n", smbiosSettings.CpuType);
}
ZeroMem((void*)newSmbiosTable.Type131, MAX_TABLE_SIZE);
newSmbiosTable.Type131->Hdr.Type = 131;
newSmbiosTable.Type131->Hdr.Length = sizeof(SMBIOS_STRUCTURE)+2;
newSmbiosTable.Type131->Hdr.Handle = 0x8300; //common rule
// Patch ProcessorType
newSmbiosTable.Type131->ProcessorType.Type = smbiosSettings.CpuType;
Handle = LogSmbiosTable(newSmbiosTable);
return;
}
void PatchTableType132(const SmbiosInjectedSettings& smbiosSettings)
{
if (!smbiosSettings.SetTable132) {
//DBG("disabled Table 132\n");
return;
}
// Get Table Type132
SmbiosTable = GetSmbiosTableFromType (EntryPoint, 132, 0);
if (SmbiosTable.Raw != NULL) {
MsgLog("Table 132 is present, QPI=%hX\n", SmbiosTable.Type132->ProcessorBusSpeed);
MsgLog("Change to: %hX\n", smbiosSettings.QPI);
}
ZeroMem((void*)newSmbiosTable.Type132, MAX_TABLE_SIZE);
newSmbiosTable.Type132->Hdr.Type = 132;
newSmbiosTable.Type132->Hdr.Length = sizeof(SMBIOS_STRUCTURE)+2;
newSmbiosTable.Type132->Hdr.Handle = 0x8400; //ugly
// Patch ProcessorBusSpeed
if(smbiosSettings.QPI){
newSmbiosTable.Type132->ProcessorBusSpeed = smbiosSettings.QPI;
} else {
newSmbiosTable.Type132->ProcessorBusSpeed = (UINT16)(LShiftU64(DivU64x32(smbiosSettings.ExternalClock, Kilo), 2));
}
Handle = LogSmbiosTable(newSmbiosTable);
return;
}
void PatchTableType133(const SmbiosInjectedSettings& smbiosSettings)
{
if (smbiosSettings.gPlatformFeature == 0xFFFF) {
return;
}
// Get Table Type133
SmbiosTable = GetSmbiosTableFromType (EntryPoint, 133, 0);
if (SmbiosTable.Raw != NULL) {
MsgLog("Table 133 is present, PlatformFeature=%llX\n", SmbiosTable.Type133->PlatformFeature);
MsgLog("Change to: %llX\n", smbiosSettings.gPlatformFeature);
}
ZeroMem((void*)newSmbiosTable.Type133, MAX_TABLE_SIZE);
newSmbiosTable.Type133->Hdr.Type = 133;
newSmbiosTable.Type133->Hdr.Length = sizeof(SMBIOS_STRUCTURE)+8;
newSmbiosTable.Type133->Hdr.Handle = 0x8500; //ugly
// newSmbiosTable.Type133->PlatformFeature = smbiosSettings.gPlatformFeature;
CopyMem((void*)&newSmbiosTable.Type133->PlatformFeature, (void*)&smbiosSettings.gPlatformFeature, 8);
Handle = LogSmbiosTable(newSmbiosTable);
return;
}
EFI_STATUS PrepatchSmbios(SmbiosDiscoveredSettings* smbiosSettings)
{
EFI_STATUS Status = EFI_SUCCESS;
UINTN BufferLen;
EFI_PHYSICAL_ADDRESS BufferPtr;
// UINTN Index;
DbgHeader("Get Smbios");
// Get SMBIOS Tables
Smbios = FindOemSMBIOSPtr();
// DBG("OEM SMBIOS EPS=%p\n", Smbios);
// DBG("OEM Tables = %X\n", ((SMBIOS_TABLE_ENTRY_POINT*)Smbios)->TableAddress);
if (!Smbios) {
// DBG("Original SMBIOS System Table not found! Getting from Hob...\n");
Smbios = GetSmbiosTablesFromHob();
// DBG("HOB SMBIOS EPS=%p\n", Smbios);
if (!Smbios) {
// DBG("And here SMBIOS System Table not found! Trying System table ...\n");
// this should work on any UEFI
Smbios = GetSmbiosTablesFromConfigTables();
// DBG("ConfigTables SMBIOS EPS=%p\n", Smbios);
if (!Smbios) {
// DBG("And here SMBIOS System Table not found! Exiting...\n");
return EFI_NOT_FOUND;
}
}
}
//original EPS and tables
EntryPoint = (SMBIOS_TABLE_ENTRY_POINT*)Smbios; //yes, it is old SmbiosEPS
// Smbios = (void*)(UINT32)EntryPoint->TableAddress; // here is flat Smbios database. Work with it
//how many we need to add for tables 128, 130, 131, 132 and for strings?
BufferLen = 0x20 + EntryPoint->TableLength + 64 * 10;
//new place for EPS and tables. Allocated once for both
BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;
Status = gBS->AllocatePages (AllocateMaxAddress, EfiACPIMemoryNVS, /*EfiACPIReclaimMemory, */
EFI_SIZE_TO_PAGES(BufferLen), &BufferPtr);
if (EFI_ERROR(Status)) {
// DBG("There is error allocating pages in EfiACPIMemoryNVS!\n");
Status = gBS->AllocatePages (AllocateMaxAddress, /*EfiACPIMemoryNVS, */EfiACPIReclaimMemory,
ROUND_PAGE(BufferLen)/EFI_PAGE_SIZE, &BufferPtr);
if (EFI_ERROR(Status)) {
// DBG("There is error allocating pages in EfiACPIReclaimMemory!\n");
}
}
// DBG("Buffer @ %p\n", BufferPtr);
if (BufferPtr) {
SmbiosEpsNew = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)BufferPtr; //this is new EPS
} else {
SmbiosEpsNew = EntryPoint; //is it possible?!
}
ZeroMem(SmbiosEpsNew, BufferLen);
// DBG("New EntryPoint = %p\n", SmbiosEpsNew);
NumberOfRecords = 0;
MaxStructureSize = 0;
//preliminary fill EntryPoint with some data
CopyMem((void *)SmbiosEpsNew, (void *)EntryPoint, sizeof(SMBIOS_TABLE_ENTRY_POINT));
Smbios = (void*)(SmbiosEpsNew + 1); //this is a C-language trick. I hate it but use. +1 means +sizeof(SMBIOS_TABLE_ENTRY_POINT)
Current = (UINT8*)Smbios; //begin fill tables from here
SmbiosEpsNew->TableAddress = (UINT32)(UINTN)Current;
SmbiosEpsNew->EntryPointLength = sizeof(SMBIOS_TABLE_ENTRY_POINT); // no matter on other versions
if (smbiosSettings->SmbiosVersion != 0) {
SmbiosEpsNew->MajorVersion = (UINT8)(smbiosSettings->SmbiosVersion >> 8);
SmbiosEpsNew->MinorVersion = (UINT8)(smbiosSettings->SmbiosVersion & 0xFF);
SmbiosEpsNew->SmbiosBcdRevision = (SmbiosEpsNew->MajorVersion << 4) + SmbiosEpsNew->MinorVersion;
}
else {
//old behavior
SmbiosEpsNew->MajorVersion = 2;
SmbiosEpsNew->MinorVersion = 4;
SmbiosEpsNew->SmbiosBcdRevision = 0x24; //Slice - we want to have v2.6 but Apple still uses 2.4, let it be default value
}
//Collect information for use in menu
GetTableType1(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
MsgLog("Boot status=%hhX\n", gBootStatus);
//for example the bootloader may go to Recovery is BootStatus is Fail
return Status;
}
void PatchSmbios(const SmbiosInjectedSettings& smbiosSettings) //continue
{
DbgHeader("PatchSmbios");
newSmbiosTable.Raw = (UINT8*)AllocateZeroPool(MAX_TABLE_SIZE);
//Slice - order of patching is significant
PatchTableType0(smbiosSettings);
PatchTableType1(smbiosSettings);
PatchTableType2(smbiosSettings);
PatchTableType3(smbiosSettings);
PatchTableType7(smbiosSettings); //we should know handles before patch Table4
PatchTableType4(smbiosSettings);
// PatchTableType6(smbiosSettings);
PatchTableType9(smbiosSettings);
if (!smbiosSettings.NoRomInfo) {
PatchTableType11(smbiosSettings);
}
PatchTableTypeSome();
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, mMemory17, mHandle17);
PatchTableType128(smbiosSettings);
PatchTableType130(smbiosSettings);
PatchTableType131(smbiosSettings);
PatchTableType132(smbiosSettings);
PatchTableType133(smbiosSettings);
AddSmbiosEndOfTable();
if(MaxStructureSize > MAX_TABLE_SIZE){
// DBG("Too long SMBIOS!\n");
}
FreePool((void*)newSmbiosTable.Raw);
// there is no need to keep all tables in numeric order. It is not needed
// neither by specs nor by AppleSmbios.kext
}
void FinalizeSmbios(const SmbiosInjectedSettings& smbiosSettings) //continue
{
EFI_PEI_HOB_POINTERS GuidHob;
EFI_PEI_HOB_POINTERS HobStart;
EFI_PHYSICAL_ADDRESS *Table = NULL;
//UINTN TableLength = 0;
// XBool FoundTable3 = false;
// Get Hob List
HobStart.Raw = (__typeof_am__(HobStart.Raw))GetHobList();
if (HobStart.Raw != NULL) {
// find SMBIOS in hob
for (size_t Index = 0; Index < sizeof (gTableGuidArray) / sizeof (*gTableGuidArray); ++Index) {
GuidHob.Raw = (__typeof_am__(HobStart.Raw))GetNextGuidHob (gTableGuidArray[Index], HobStart.Raw);
if (GuidHob.Raw != NULL) {
Table = (__typeof_am__(Table))GET_GUID_HOB_DATA (GuidHob.Guid);
//TableLength = GET_GUID_HOB_DATA_SIZE (GuidHob);
if (Table != NULL) {
if (Index != 0) {
// FoundTable3 = true; //don't know how to use it. Real Mac have table3 in the format of table2
DBG("Found SMBIOS3 Table\n");
}
break;
}
}
}
}
//
// Install SMBIOS in Config table
SmbiosEpsNew->TableLength = (UINT16)((UINT32)(UINTN)Current - (UINT32)(UINTN)Smbios);
SmbiosEpsNew->NumberOfSmbiosStructures = NumberOfRecords;
SmbiosEpsNew->MaxStructureSize = MaxStructureSize;
SmbiosEpsNew->IntermediateChecksum = 0;
SmbiosEpsNew->IntermediateChecksum = (UINT8)(256 - Checksum8((UINT8*)SmbiosEpsNew + 0x10, SmbiosEpsNew->EntryPointLength - 0x10));
SmbiosEpsNew->EntryPointStructureChecksum = 0;
SmbiosEpsNew->EntryPointStructureChecksum = (UINT8)(256 - Checksum8((UINT8*)SmbiosEpsNew, SmbiosEpsNew->EntryPointLength));
//DBG("SmbiosEpsNew->TableLength = %d\n", SmbiosEpsNew->TableLength);
//DBG("SmbiosEpsNew->EntryPointLength = %d\n", SmbiosEpsNew->EntryPointLength);
//DBG("SmbiosEpsNew->MaxStructureSize = %d\n", SmbiosEpsNew->MaxStructureSize);
//DBG("DMI checksum = %d\n", Checksum8((UINT8*)SmbiosEpsNew, SmbiosEpsNew->EntryPointLength));
//XString8 tmpDbg;
//XString8 tmptmpDbg;
//tmpDbg.dataSized(SmbiosEpsNew->TableLength*3+5*SmbiosEpsNew->TableLength/32+128);
//for ( size_t i = 0 ; i < SmbiosEpsNew->TableLength ; ) {
// size_t j;
// for ( j = 0 ; j < SmbiosEpsNew->TableLength && j < 32 ; j++ ) {
//// DBG("%02x ", ((UINT8*)(SmbiosEpsNew+1))[i+j] );
// tmptmpDbg.S8Printf("%02x ", ((UINT8*)(SmbiosEpsNew+1))[i+j] );
// tmpDbg.strcat(tmptmpDbg);
// }
//// DBG(" - ");
// tmptmpDbg.S8Printf(" - ");
// tmpDbg.strcat(tmptmpDbg);
// for ( j = 0 ; j < SmbiosEpsNew->TableLength && j < 32 ; j++ ) {
// UINT8 c = ((UINT8*)(SmbiosEpsNew+1))[i+j];
//// DBG("%c ", c > 32 ? c : '.');
// tmptmpDbg.S8Printf("%c", c > 32 ? c : '.');
// tmpDbg.strcat(tmptmpDbg);
// }
//// DBG("\n");
// tmptmpDbg.S8Printf("\n");
// tmpDbg.strcat(tmptmpDbg);
// i += j;
//}
//DBG("%s", tmpDbg.c_str());
//auto foo = SmbiosEpsNew;
//
// syscl: one more step: check if we need remap SMBIOS Table Type 1 Guid
//
// to fix Dell's SMBIOS truncate credit David Passmore
//
if (smbiosSettings.KPDELLSMBIOS)
{
//
// syscl: remap smbios table 1 guid
//
DBG("Remap smbios table type 1 guid.\n");
gBS->InstallConfigurationTable (&gRemapEfiSmbiosTableGuid, (void*)SmbiosEpsNew);
}
else
{
//
// use origin smbios guid table
//
DBG("Use origin smbios table type 1 guid.\n");
gBS->InstallConfigurationTable (&gEfiSmbiosTableGuid, (void*)SmbiosEpsNew);
}
gST->Hdr.CRC32 = 0;
gBS->CalculateCrc32 ((UINT8 *) &gST->Hdr, gST->Hdr.HeaderSize, &gST->Hdr.CRC32);
//
// Fix it in Hob list
//
// No smbios in Hob list on Aptio, so no need to update it there.
// But even if it would be there, loading of macOS would overwrite it
// since this list on my board is inside space needed for kernel
// (ha! like many other UEFI stuff).
// It's enough to add it to Conf.table.
//
if (Table != NULL) {
//PauseForKey(L"installing SMBIOS in Hob\n");
*Table = (UINT32)(UINTN)SmbiosEpsNew;
}
// egSaveFile(NULL, SWPrintf("%ls\\misc\\smbios.bin", self.getCloverDirFullPath().wc_str()).wc_str(), (UINT8*)(UINTN)SmbiosEpsNew, SmbiosEpsNew->TableLength);
return;
}