SMBIOS support

This commit is contained in:
Alex 2022-11-19 11:32:46 +02:00
parent eb980a95d9
commit 23dba51c01
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
4 changed files with 489 additions and 2 deletions

View File

@ -0,0 +1,70 @@
#include "smbios.hpp"
#include <debug.h>
#include "../kernel.h"
/* https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.2.0.pdf */
namespace SMBIOS
{
bool CheckSMBIOS()
{
if (bInfo->SMBIOSPtr != nullptr && bInfo->SMBIOSPtr < (void *)0xffffffffffff0000)
{
debug("SMBIOS is available (%#lx).", bInfo->SMBIOSPtr);
return true;
}
debug("SMBIOS is not available. (%#lx)", bInfo->SMBIOSPtr);
return false;
}
SMBIOSEntryPoint *GetSMBIOSEntryPoint() { return (SMBIOSEntryPoint *)bInfo->SMBIOSPtr; }
static inline int SMBIOSTableLength(SMBIOSHeader *Hdr)
{
int i;
const char *strtab = (char *)Hdr + Hdr->Length;
for (i = 1; strtab[i - 1] != '\0' || strtab[i] != '\0'; i++)
;
return Hdr->Length + i + 1;
}
void *GetSMBIOSHeader(SMBIOSType Type)
{
if (!CheckSMBIOS())
return nullptr;
SMBIOSEntryPoint *Header = (SMBIOSEntryPoint *)bInfo->SMBIOSPtr;
debug("Getting SMBIOS header for type %d", Type);
struct SMBIOSHeader *hdr = (SMBIOSHeader *)(uint64_t)Header->TableAddress;
for (int i = 0; i <= 11; i++)
{
if (hdr < (void *)(uint64_t)(Header->TableAddress + Header->TableLength))
if (hdr->Type == Type)
{
debug("Found SMBIOS header for type %d at %#lx", Type, hdr);
return hdr;
}
hdr = (struct SMBIOSHeader *)((uint64_t)hdr + SMBIOSTableLength(hdr));
}
return nullptr;
}
SMBIOSBIOSInformation *GetBIOSInformation() { return (SMBIOSBIOSInformation *)GetSMBIOSHeader(SMBIOSTypeBIOSInformation); }
SMBIOSSystemInformation *GetSystemInformation() { return (SMBIOSSystemInformation *)GetSMBIOSHeader(SMBIOSTypeSystemInformation); }
SMBIOSBaseBoardInformation *GetBaseBoardInformation() { return (SMBIOSBaseBoardInformation *)GetSMBIOSHeader(SMBIOSTypeBaseBoardInformation); }
SMBIOSProcessorInformation *GetProcessorInformation() { return (SMBIOSProcessorInformation *)GetSMBIOSHeader(SMBIOSTypeProcessorInformation); }
SMBIOSMemoryArray *GetMemoryArray() { return (SMBIOSMemoryArray *)GetSMBIOSHeader(SMBIOSTypePhysicalMemoryArray); }
SMBIOSMemoryDevice *GetMemoryDevice() { return (SMBIOSMemoryDevice *)GetSMBIOSHeader(SMBIOSTypeMemoryDevice); }
SMBIOSMemoryArrayMappedAddress *GetMemoryArrayMappedAddress() { return (SMBIOSMemoryArrayMappedAddress *)GetSMBIOSHeader(SMBIOSTypeMemoryArrayMappedAddress); }
SMBIOSMemoryDeviceMappedAddress *GetMemoryDeviceMappedAddress() { return (SMBIOSMemoryDeviceMappedAddress *)GetSMBIOSHeader(SMBIOSTypeMemoryDeviceMappedAddress); }
}

340
Core/smbios.hpp Normal file
View File

@ -0,0 +1,340 @@
#ifndef __FENNIX_KERNEL_SMBIOS_H__
#define __FENNIX_KERNEL_SMBIOS_H__
#include <types.h>
namespace SMBIOS
{
enum SMBIOSType
{
SMBIOSTypeBIOSInformation = 0,
SMBIOSTypeSystemInformation = 1,
SMBIOSTypeBaseBoardInformation = 2,
SMBIOSTypeSystemEnclosure = 3,
SMBIOSTypeProcessorInformation = 4,
SMBIOSTypeMemoryControllerInformation = 5,
SMBIOSTypeMemoryModuleInformation = 6,
SMBIOSTypeCacheInformation = 7,
SMBIOSTypePortConnectorInformation = 8,
SMBIOSTypeSystemSlots = 9,
SMBIOSTypeOnBoardDevicesInformation = 10,
SMBIOSTypeOEMStrings = 11,
SMBIOSTypeSystemConfigurationOptions = 12,
SMBIOSTypeBIOSLanguageInformation = 13,
SMBIOSTypeGroupAssociations = 14,
SMBIOSTypeSystemEventLog = 15,
SMBIOSTypePhysicalMemoryArray = 16,
SMBIOSTypeMemoryDevice = 17,
SMBIOSType32BitMemoryErrorInformation = 18,
SMBIOSTypeMemoryArrayMappedAddress = 19,
SMBIOSTypeMemoryDeviceMappedAddress = 20,
SMBIOSTypeBuiltInPointingDevice = 21,
SMBIOSTypePortableBattery = 22,
SMBIOSTypeSystemReset = 23,
SMBIOSTypeHardwareSecurity = 24,
SMBIOSTypeSystemPowerControls = 25,
SMBIOSTypeVoltageProbe = 26,
SMBIOSTypeCoolingDevice = 27,
SMBIOSTypeTemperatureProbe = 28,
SMBIOSTypeElectricalCurrentProbe = 29,
SMBIOSTypeOutofBandRemoteAccess = 30,
SMBIOSTypeBootIntegrityServices = 31,
SMBIOSTypeSystemBoot = 32,
SMBIOSType64BitMemoryErrorInformation = 33,
SMBIOSTypeManagementDevice = 34,
SMBIOSTypeManagementDeviceComponent = 35,
SMBIOSTypeManagementDeviceThresholdData = 36,
SMBIOSTypeMemoryChannel = 37,
SMBIOSTypeIPMIDevice = 38,
SMBIOSTypePowerSupply = 39,
SMBIOSTypeAdditionalInformation = 40,
SMBIOSTypeOnboardDevicesExtendedInformation = 41,
SMBIOSTypeManagementControllerHostInterface = 42,
SMBIOSTypeTPMDevice = 43,
SMBIOSTypeProcessorAdditionalInformation = 44,
SMBIOSTypeInactive = 126,
SMBIOSTypeEndOfTable = 127
};
struct SMBIOSHeader
{
unsigned char Type;
unsigned char Length;
unsigned short Handle;
};
struct SMBIOSEntryPoint
{
char EntryPointString[4];
unsigned char Checksum;
unsigned char Length;
unsigned char MajorVersion;
unsigned char MinorVersion;
unsigned short MaxStructureSize;
unsigned char EntryPointRevision;
char FormattedArea[5];
char EntryPointString2[5];
unsigned char Checksum2;
unsigned short TableLength;
unsigned int TableAddress;
unsigned short NumberOfStructures;
unsigned char BCDRevision;
};
static inline char *SMBIOSNextString(char *Str)
{
while (*Str != '\0')
Str++;
return Str + 1;
}
struct SMBIOSBIOSInformation
{
SMBIOSHeader Header;
unsigned char Vendor;
unsigned char Version;
unsigned short StartingAddressSegment;
unsigned char ReleaseDate;
unsigned char ROMSize;
unsigned long Characteristics;
unsigned char CharacteristicsExtensionBytes[2];
unsigned char SystemBIOSMajorRelease;
unsigned char SystemBIOSMinorRelease;
unsigned char EmbeddedControllerFirmwareMajorRelease;
unsigned char EmbeddedControllerFirmwareMinorRelease;
const char *GetString(unsigned char Index)
{
char *Str = (char *)((unsigned long)this + this->Header.Length);
Index--;
if (Index == 0 || Index > 10)
return Str;
for (unsigned char i = 0; i < Index; i++)
Str = SMBIOSNextString(Str);
return Str;
}
};
struct SMBIOSSystemInformation
{
SMBIOSHeader Header;
unsigned char Manufacturer;
unsigned char ProductName;
unsigned char Version;
unsigned char SerialNumber;
unsigned char UUID[16];
unsigned char WakeUpType;
unsigned char SKU;
unsigned char Family;
const char *GetString(unsigned char Index)
{
char *Str = (char *)((unsigned long)this + this->Header.Length);
Index--;
if (Index == 0 || Index > 10)
return Str;
for (unsigned char i = 0; i < Index; i++)
Str = SMBIOSNextString(Str);
return Str;
}
};
struct SMBIOSBaseBoardInformation
{
SMBIOSHeader Header;
unsigned char Manufacturer;
unsigned char Product;
unsigned char Version;
unsigned char SerialNumber;
unsigned char AssetTag;
unsigned char FeatureFlags;
unsigned char LocationInChassis;
unsigned short ChassisHandle;
unsigned char BoardType;
unsigned char NumberOfContainedObjectHandles;
unsigned short ContainedObjectHandles[0];
const char *GetString(unsigned char Index)
{
char *Str = (char *)((unsigned long)this + this->Header.Length);
Index--;
if (Index == 0 || Index > 10)
return Str;
for (unsigned char i = 0; i < Index; i++)
Str = SMBIOSNextString(Str);
return Str;
}
};
struct SMBIOSProcessorInformation
{
SMBIOSHeader Header;
unsigned char SocketDesignation;
unsigned char ProcessorType;
unsigned char ProcessorFamily;
unsigned char ProcessorManufacturer;
unsigned long ProcessorID[2];
unsigned char ProcessorVersion;
unsigned char Voltage;
unsigned short ExternalClock;
unsigned short MaxSpeed;
unsigned short CurrentSpeed;
unsigned char Status;
unsigned char ProcessorUpgrade;
unsigned short L1CacheHandle;
unsigned short L2CacheHandle;
unsigned short L3CacheHandle;
unsigned char SerialNumber;
unsigned char AssetTag;
unsigned char PartNumber;
unsigned char CoreCount;
unsigned char CoreEnabled;
unsigned char ThreadCount;
unsigned short ProcessorCharacteristics;
unsigned short ProcessorFamily2;
unsigned short CoreCount2;
unsigned short CoreEnabled2;
unsigned short ThreadCount2;
const char *GetString(unsigned char Index)
{
char *Str = (char *)((unsigned long)this + this->Header.Length);
Index--;
if (Index == 0 || Index > 10)
return Str;
for (unsigned char i = 0; i < Index; i++)
Str = SMBIOSNextString(Str);
return Str;
}
};
struct SMBIOSMemoryDevice
{
SMBIOSHeader Header;
unsigned char PhysicalMemoryArrayHandle;
unsigned char MemoryErrorInformationHandle;
unsigned short TotalWidth;
unsigned short DataWidth;
unsigned short Size;
unsigned char FormFactor;
unsigned char DeviceSet;
unsigned char DeviceLocator;
unsigned char BankLocator;
unsigned char MemoryType;
unsigned short TypeDetail;
unsigned short Speed;
unsigned char Manufacturer;
unsigned char SerialNumber;
unsigned char AssetTag;
unsigned char PartNumber;
unsigned char Attributes;
unsigned short ExtendedSize;
unsigned short ConfiguredMemoryClockSpeed;
unsigned short MinimumVoltage;
unsigned short MaximumVoltage;
unsigned short ConfiguredVoltage;
unsigned char MemoryTechnology;
unsigned char OperatingModeCapability;
unsigned char FirmwareVersion;
unsigned char ModuleManufacturerID;
unsigned char ModuleProductID;
unsigned char MemorySubsystemControllerManufacturerID;
unsigned char MemorySubsystemControllerProductID;
unsigned short NonVolatileSize;
unsigned short VolatileSize;
unsigned short CacheSize;
unsigned short LogicalSize;
unsigned char ExtendedSpeed;
unsigned char ExtendedConfiguredMemorySpeed;
const char *GetString(unsigned char Index)
{
char *Str = (char *)((unsigned long)this + this->Header.Length);
Index--;
if (Index == 0 || Index > 10)
return Str;
for (unsigned char i = 0; i < Index; i++)
Str = SMBIOSNextString(Str);
return Str;
}
};
struct SMBIOSMemoryArrayMappedAddress
{
SMBIOSHeader Header;
unsigned int StartingAddress;
unsigned int EndingAddress;
unsigned short MemoryArrayHandle;
unsigned char PartitionWidth;
const char *GetString(unsigned char Index)
{
char *Str = (char *)((unsigned long)this + this->Header.Length);
Index--;
if (Index == 0 || Index > 10)
return Str;
for (unsigned char i = 0; i < Index; i++)
Str = SMBIOSNextString(Str);
return Str;
}
};
struct SMBIOSMemoryDeviceMappedAddress
{
SMBIOSHeader Header;
unsigned int StartingAddress;
unsigned int EndingAddress;
unsigned short MemoryDeviceHandle;
unsigned short MemoryArrayMappedAddressHandle;
unsigned char PartitionRowPosition;
unsigned char InterleavePosition;
unsigned char InterleavedDataDepth;
const char *GetString(unsigned char Index)
{
char *Str = (char *)((unsigned long)this + this->Header.Length);
Index--;
if (Index == 0 || Index > 10)
return Str;
for (unsigned char i = 0; i < Index; i++)
Str = SMBIOSNextString(Str);
return Str;
}
};
struct SMBIOSMemoryArray
{
SMBIOSHeader Header;
unsigned char Location;
unsigned char Use;
unsigned char MemoryErrorCorrection;
unsigned int MaximumCapacity;
unsigned short MemoryErrorInformationHandle;
unsigned short NumberOfMemoryDevices;
const char *GetString(unsigned char Index)
{
char *Str = (char *)((unsigned long)this + this->Header.Length);
Index--;
if (Index == 0 || Index > 10)
return Str;
for (unsigned char i = 0; i < Index; i++)
Str = SMBIOSNextString(Str);
return Str;
}
};
bool CheckSMBIOS();
SMBIOSEntryPoint *GetSMBIOSEntryPoint();
void *GetSMBIOSHeader(SMBIOSType Type);
SMBIOSBIOSInformation *GetBIOSInformation();
SMBIOSSystemInformation *GetSystemInformation();
SMBIOSBaseBoardInformation *GetBaseBoardInformation();
SMBIOSProcessorInformation *GetProcessorInformation();
SMBIOSMemoryArray *GetMemoryArray();
SMBIOSMemoryDevice *GetMemoryDevice();
SMBIOSMemoryArrayMappedAddress *GetMemoryArrayMappedAddress();
SMBIOSMemoryDeviceMappedAddress *GetMemoryDeviceMappedAddress();
}
#endif // !__FENNIX_KERNEL_SMBIOS_H__

View File

@ -56,7 +56,7 @@ void KernelMainThread()
TaskManager->GetCurrentThread()->SetPriority(1); TaskManager->GetCurrentThread()->SetPriority(1);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem, nullptr, nullptr, auxv); CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem, nullptr, nullptr, auxv);
CurrentWorker->Rename("Disk"); CurrentWorker->Rename("Filesystems");
CurrentWorker->SetPriority(100); CurrentWorker->SetPriority(100);
TaskManager->WaitForThread(CurrentWorker); TaskManager->WaitForThread(CurrentWorker);
@ -66,7 +66,7 @@ void KernelMainThread()
TaskManager->WaitForThread(CurrentWorker); TaskManager->WaitForThread(CurrentWorker);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)FetchDisks, nullptr, nullptr, auxv); CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)FetchDisks, nullptr, nullptr, auxv);
CurrentWorker->Rename("Fetch Disks"); CurrentWorker->Rename("Disks");
CurrentWorker->SetPriority(100); CurrentWorker->SetPriority(100);
TaskManager->WaitForThread(CurrentWorker); TaskManager->WaitForThread(CurrentWorker);

View File

@ -10,6 +10,9 @@
#include <smp.hpp> #include <smp.hpp>
#include <cargs.h> #include <cargs.h>
#include <io.h> #include <io.h>
#include <dumper.hpp>
#include "Core/smbios.hpp"
NewLock(KernelLock); NewLock(KernelLock);
@ -97,6 +100,80 @@ EXTERNC void Entry(BootInfo *Info)
Interrupts::InitializeTimer(0); Interrupts::InitializeTimer(0);
KPrint("Initializing SMP"); KPrint("Initializing SMP");
SMP::Initialize(PowerManager->GetMADT()); SMP::Initialize(PowerManager->GetMADT());
if (SMBIOS::CheckSMBIOS())
{
SMBIOS::SMBIOSEntryPoint *smbios = SMBIOS::GetSMBIOSEntryPoint();
SMBIOS::SMBIOSBIOSInformation *bios = SMBIOS::GetBIOSInformation();
SMBIOS::SMBIOSSystemInformation *system = SMBIOS::GetSystemInformation();
SMBIOS::SMBIOSBaseBoardInformation *baseboard = SMBIOS::GetBaseBoardInformation();
debug("SMBIOS: %p", smbios);
debug("BIOS: %p", bios);
debug("System: %p", system);
debug("Baseboard: %p", baseboard);
DumpData("SMBIOS ALL DUMP", (void *)(uint64_t)smbios->TableAddress, smbios->TableLength);
if (smbios)
DumpData("SMBIOS", smbios, sizeof(SMBIOS::SMBIOSEntryPoint));
if (bios)
DumpData("BIOS", bios, sizeof(SMBIOS::SMBIOSBIOSInformation));
if (system)
DumpData("System", system, sizeof(SMBIOS::SMBIOSSystemInformation));
if (baseboard)
DumpData("Baseboard", baseboard, sizeof(SMBIOS::SMBIOSBaseBoardInformation));
if (smbios)
KPrint("SMBIOS: \eCCCCCCString:\e8888FF%.4s \eCCCCCCVersion (Major Minor):\e8888FF%d %d \eCCCCCCTable:\e8888FF%#x \eCCCCCCLength:\e8888FF%d",
smbios->EntryPointString, smbios->MajorVersion, smbios->MinorVersion,
smbios->TableAddress, smbios->TableLength);
else
KPrint("SMBIOS: \e8888FFSMBIOS found but not supported?");
if (bios)
{
const char *BIOSVendor = bios->GetString(bios->Vendor);
const char *BIOSVersion = bios->GetString(bios->Version);
const char *BIOSReleaseDate = bios->GetString(bios->ReleaseDate);
debug("%d %d %d", bios->Vendor, bios->Version, bios->ReleaseDate);
KPrint("BIOS: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s",
BIOSVendor, BIOSVersion, BIOSReleaseDate);
}
if (system)
{
const char *SystemManufacturer = system->GetString(system->Manufacturer);
const char *SystemProductName = system->GetString(system->ProductName);
const char *SystemVersion = system->GetString(system->Version);
const char *SystemSerialNumber = system->GetString(system->SerialNumber);
const char *SystemSKU = system->GetString(system->SKU);
const char *SystemFamily = system->GetString(system->Family);
debug("%d %d %d %d %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c %d %d", system->Manufacturer, system->ProductName, system->Version,
system->SerialNumber,
system->UUID[0], system->UUID[1], system->UUID[2], system->UUID[3],
system->UUID[4], system->UUID[5], system->UUID[6], system->UUID[7],
system->UUID[8], system->UUID[9], system->UUID[10], system->UUID[11],
system->UUID[12], system->UUID[13], system->UUID[14], system->UUID[15],
system->SKU, system->Family);
KPrint("System: \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s",
SystemManufacturer, SystemProductName, SystemVersion, SystemSerialNumber, SystemSKU, SystemFamily);
}
if (baseboard)
{
const char *Manufacturer = baseboard->GetString(baseboard->Manufacturer);
const char *Product = baseboard->GetString(baseboard->Product);
const char *Version = baseboard->GetString(baseboard->Version);
const char *SerialNumber = baseboard->GetString(baseboard->SerialNumber);
debug("%d %d %d %d", baseboard->Manufacturer, baseboard->Product, baseboard->Version, baseboard->SerialNumber);
KPrint("Baseboard: \eCCCCCC\e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s \eCCCCCC/ \e8888FF%s",
Manufacturer, Product, Version, SerialNumber);
}
}
else
KPrint("SMBIOS: \eFF0000Not Found");
CPU::Halt(true);
TaskManager = new Tasking::Task((Tasking::IP)KernelMainThread); TaskManager = new Tasking::Task((Tasking::IP)KernelMainThread);
KPrint("\e058C19################################"); KPrint("\e058C19################################");
CPU::Halt(true); CPU::Halt(true);