From 23dba51c0109c968a0172ada59ed4eed209e7e55 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 19 Nov 2022 11:32:46 +0200 Subject: [PATCH] SMBIOS support --- Core/SystemManagementBIOS.cpp | 70 +++++++ Core/smbios.hpp | 340 ++++++++++++++++++++++++++++++++++ KThread.cpp | 4 +- Kernel.cpp | 77 ++++++++ 4 files changed, 489 insertions(+), 2 deletions(-) create mode 100644 Core/SystemManagementBIOS.cpp create mode 100644 Core/smbios.hpp diff --git a/Core/SystemManagementBIOS.cpp b/Core/SystemManagementBIOS.cpp new file mode 100644 index 0000000..a6715eb --- /dev/null +++ b/Core/SystemManagementBIOS.cpp @@ -0,0 +1,70 @@ +#include "smbios.hpp" + +#include + +#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); } +} diff --git a/Core/smbios.hpp b/Core/smbios.hpp new file mode 100644 index 0000000..a95e708 --- /dev/null +++ b/Core/smbios.hpp @@ -0,0 +1,340 @@ +#ifndef __FENNIX_KERNEL_SMBIOS_H__ +#define __FENNIX_KERNEL_SMBIOS_H__ + +#include + +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__ diff --git a/KThread.cpp b/KThread.cpp index e699333..6df4fb5 100644 --- a/KThread.cpp +++ b/KThread.cpp @@ -56,7 +56,7 @@ void KernelMainThread() TaskManager->GetCurrentThread()->SetPriority(1); CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem, nullptr, nullptr, auxv); - CurrentWorker->Rename("Disk"); + CurrentWorker->Rename("Filesystems"); CurrentWorker->SetPriority(100); TaskManager->WaitForThread(CurrentWorker); @@ -66,7 +66,7 @@ void KernelMainThread() TaskManager->WaitForThread(CurrentWorker); CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)FetchDisks, nullptr, nullptr, auxv); - CurrentWorker->Rename("Fetch Disks"); + CurrentWorker->Rename("Disks"); CurrentWorker->SetPriority(100); TaskManager->WaitForThread(CurrentWorker); diff --git a/Kernel.cpp b/Kernel.cpp index 6bc4d46..9369485 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -10,6 +10,9 @@ #include #include #include +#include + +#include "Core/smbios.hpp" NewLock(KernelLock); @@ -97,6 +100,80 @@ EXTERNC void Entry(BootInfo *Info) Interrupts::InitializeTimer(0); KPrint("Initializing SMP"); 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); KPrint("\e058C19################################"); CPU::Halt(true);