From fcf1e7528e232752698c39d306f8f85375121a03 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 7 Sep 2023 02:58:20 +0300 Subject: [PATCH] Search for SMBIOS & RSDP if the bootloader doesn't provide them --- Core/Memory/ReserveEssentials.cpp | 12 +--- Core/SystemManagementBIOS.cpp | 93 ++++++++++++++++--------------- Kernel.cpp | 56 +++++++++++++++++++ 3 files changed, 105 insertions(+), 56 deletions(-) diff --git a/Core/Memory/ReserveEssentials.cpp b/Core/Memory/ReserveEssentials.cpp index 5813147..0ce86d0 100644 --- a/Core/Memory/ReserveEssentials.cpp +++ b/Core/Memory/ReserveEssentials.cpp @@ -162,19 +162,11 @@ namespace Memory debug("Reserving RSDT..."); this->ReservePages((void *)bInfo.RSDP, TO_PAGES(sizeof(BootInfo::RSDPInfo))); -#if defined(a64) - if ((uintptr_t)ACPIPtr > 0x7FE00000) /* FIXME */ + if (!Memory::Virtual().Check(ACPIPtr)) { - error("ACPI table is located above 0x7FE00000, which is not mapped."); + error("ACPI table is located in an unmapped region."); return; } -#elif defined(a32) - if ((uintptr_t)ACPIPtr > 0x2800000) /* FIXME */ - { - error("ACPI table is located above 0x2800000, which is not mapped."); - return; - } -#endif size_t TableSize = ((ACPIPtr->Length - sizeof(ACPI::ACPI::ACPIHeader)) / (XSDT ? 8 : 4)); diff --git a/Core/SystemManagementBIOS.cpp b/Core/SystemManagementBIOS.cpp index c0ad12f..9d7159f 100644 --- a/Core/SystemManagementBIOS.cpp +++ b/Core/SystemManagementBIOS.cpp @@ -23,63 +23,64 @@ 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; - } + bool CheckSMBIOS() + { + if (bInfo.SMBIOSPtr != nullptr && bInfo.SMBIOSPtr < (void *)0xFFFFFFFFFFFF0000) + { + debug("SMBIOS is available (%#lx).", bInfo.SMBIOSPtr); + return true; + } - SMBIOSEntryPoint *GetSMBIOSEntryPoint() { return (SMBIOSEntryPoint *)bInfo.SMBIOSPtr; } + debug("SMBIOS is not available. (%#lx)", bInfo.SMBIOSPtr); + return false; + } - __no_sanitize("alignment") 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; - } + SMBIOSEntryPoint *GetSMBIOSEntryPoint() { return (SMBIOSEntryPoint *)bInfo.SMBIOSPtr; } - __no_sanitize("alignment") void *GetSMBIOSHeader(SMBIOSType Type) - { - if (!CheckSMBIOS()) - return nullptr; + __no_sanitize("alignment") 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; + } - SMBIOSEntryPoint *Header = (SMBIOSEntryPoint *)bInfo.SMBIOSPtr; - debug("Getting SMBIOS header for type %d", Type); + __no_sanitize("alignment") void *GetSMBIOSHeader(SMBIOSType Type) + { + if (!CheckSMBIOS()) + return nullptr; - struct SMBIOSHeader *hdr = (SMBIOSHeader *)(uintptr_t)Header->TableAddress; - for (int i = 0; i <= 11; i++) - { - if (hdr < (void *)(uintptr_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 *)((uintptr_t)hdr + SMBIOSTableLength(hdr)); - } - return nullptr; - } + SMBIOSEntryPoint *Header = (SMBIOSEntryPoint *)bInfo.SMBIOSPtr; + debug("Getting SMBIOS header for type %d", Type); - SMBIOSBIOSInformation *GetBIOSInformation() { return (SMBIOSBIOSInformation *)GetSMBIOSHeader(SMBIOSTypeBIOSInformation); } + struct SMBIOSHeader *hdr = (SMBIOSHeader *)(uintptr_t)Header->TableAddress; + for (int i = 0; i <= 11; i++) + { + if (hdr < (void *)(uintptr_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 *)((uintptr_t)hdr + SMBIOSTableLength(hdr)); + } + return nullptr; + } - SMBIOSSystemInformation *GetSystemInformation() { return (SMBIOSSystemInformation *)GetSMBIOSHeader(SMBIOSTypeSystemInformation); } + SMBIOSBIOSInformation *GetBIOSInformation() { return (SMBIOSBIOSInformation *)GetSMBIOSHeader(SMBIOSTypeBIOSInformation); } - SMBIOSBaseBoardInformation *GetBaseBoardInformation() { return (SMBIOSBaseBoardInformation *)GetSMBIOSHeader(SMBIOSTypeBaseBoardInformation); } + SMBIOSSystemInformation *GetSystemInformation() { return (SMBIOSSystemInformation *)GetSMBIOSHeader(SMBIOSTypeSystemInformation); } - SMBIOSProcessorInformation *GetProcessorInformation() { return (SMBIOSProcessorInformation *)GetSMBIOSHeader(SMBIOSTypeProcessorInformation); } + SMBIOSBaseBoardInformation *GetBaseBoardInformation() { return (SMBIOSBaseBoardInformation *)GetSMBIOSHeader(SMBIOSTypeBaseBoardInformation); } - SMBIOSMemoryArray *GetMemoryArray() { return (SMBIOSMemoryArray *)GetSMBIOSHeader(SMBIOSTypePhysicalMemoryArray); } + SMBIOSProcessorInformation *GetProcessorInformation() { return (SMBIOSProcessorInformation *)GetSMBIOSHeader(SMBIOSTypeProcessorInformation); } - SMBIOSMemoryDevice *GetMemoryDevice() { return (SMBIOSMemoryDevice *)GetSMBIOSHeader(SMBIOSTypeMemoryDevice); } + SMBIOSMemoryArray *GetMemoryArray() { return (SMBIOSMemoryArray *)GetSMBIOSHeader(SMBIOSTypePhysicalMemoryArray); } - SMBIOSMemoryArrayMappedAddress *GetMemoryArrayMappedAddress() { return (SMBIOSMemoryArrayMappedAddress *)GetSMBIOSHeader(SMBIOSTypeMemoryArrayMappedAddress); } + SMBIOSMemoryDevice *GetMemoryDevice() { return (SMBIOSMemoryDevice *)GetSMBIOSHeader(SMBIOSTypeMemoryDevice); } - SMBIOSMemoryDeviceMappedAddress *GetMemoryDeviceMappedAddress() { return (SMBIOSMemoryDeviceMappedAddress *)GetSMBIOSHeader(SMBIOSTypeMemoryDeviceMappedAddress); } + SMBIOSMemoryArrayMappedAddress *GetMemoryArrayMappedAddress() { return (SMBIOSMemoryArrayMappedAddress *)GetSMBIOSHeader(SMBIOSTypeMemoryArrayMappedAddress); } + + SMBIOSMemoryDeviceMappedAddress *GetMemoryDeviceMappedAddress() { return (SMBIOSMemoryDeviceMappedAddress *)GetSMBIOSHeader(SMBIOSTypeMemoryDeviceMappedAddress); } } diff --git a/Kernel.cpp b/Kernel.cpp index 21757ce..b0aea9e 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -155,6 +155,10 @@ bool DebuggerIsAttached = false; * - SMBIOS: * https://www.dmtf.org/dsp/DSP0134 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.6.0.pdf + * https://wiki.osdev.org/System_Management_BIOS + * + * - EDBA: + * https://wiki.osdev.org/Memory_Map_(x86) * * - UMIP, SMAP and SMEP: * https://en.wikipedia.org/wiki/Control_register @@ -599,6 +603,58 @@ EXTERNC __no_stack_protector NIF void Entry(BootInfo *Info) for (CallPtr *func = __init_array_start; func != __init_array_end; func++) (*func)(); +#ifdef a86 + if (!bInfo.SMBIOSPtr) + { + trace("SMBIOS was not provided by the bootloader. Trying to find it manually."); + for (uintptr_t i = 0xF0000; i < 0x100000; i += 16) + { + if (memcmp((void *)i, "_SM_", 4) == 0 || memcmp((void *)i, "_SM3_", 5) == 0) + { + bInfo.SMBIOSPtr = (void *)i; + trace("Found SMBIOS at %#lx", i); + } + } + } + + if (!bInfo.RSDP) + { + trace("RSDP was not provided by the bootloader. Trying to find it manually."); + /* FIXME: Not always shifting by 4 will work. */ + uintptr_t EBDABase = (uintptr_t)mminw((void *)0x40E) << 4; + + for (uintptr_t ptr = EBDABase; + ptr < 0x100000; /* 1MB */ + ptr += 16) + { + if (unlikely(ptr == EBDABase + 0x400)) + { + trace("EBDA is full. Trying to find RSDP in the BIOS area."); + break; + } + + BootInfo::RSDPInfo *rsdp = (BootInfo::RSDPInfo *)ptr; + if (memcmp(rsdp->Signature, "RSD PTR ", 8) == 0) + { + bInfo.RSDP = (BootInfo::RSDPInfo *)rsdp; + trace("Found RSDP at %#lx", rsdp); + } + } + + for (uintptr_t ptr = 0xE0000; + ptr < 0x100000; /* 1MB */ + ptr += 16) + { + BootInfo::RSDPInfo *rsdp = (BootInfo::RSDPInfo *)ptr; + if (memcmp(rsdp->Signature, "RSD PTR ", 8) == 0) + { + bInfo.RSDP = (BootInfo::RSDPInfo *)rsdp; + trace("Found RSDP at %#lx", rsdp); + } + } + } +#endif + InitializeMemoryManagement(); void *KernelStackAddress = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE));