diff --git a/Makefile b/Makefile index 652f617..deb1bac 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ CXXFLAGS := -m32 -ggdb -g3 -O0 -fno-pic -ffreestanding -fno-rtti -fno-exceptions -std=c++23 LDFLAGS := -m32 -static -T link.ld -ffreestanding -nostdlib -CXXFILES := boot.cpp \ +CXXFILES := acpi.cpp \ + boot.cpp \ gdt.cpp \ idt.cpp \ memory.cpp \ diff --git a/acpi.cpp b/acpi.cpp new file mode 100644 index 0000000..b74a7dc --- /dev/null +++ b/acpi.cpp @@ -0,0 +1,51 @@ +#include "textoutput.hpp" + +#include + +extern TextOutput& term; +extern std::uint32_t *acpiRsdp; +extern std::uint32_t *acpiRsdpV2; + +struct XSDP { + char Signature[8]; + std::uint8_t Checksum; + char OEMID[6]; + std::uint8_t Revision; + std::uint32_t RsdtAddress; // deprecated since version 2.0 + + // v2 only! + std::uint32_t Length; + std::uint64_t XsdtAddress; + std::uint8_t ExtendedChecksum; + std::uint8_t reserved[3]; +} __attribute__ ((packed)); + +struct SDTHeader { + char Signature[4]; + std::uint32_t Length; + std::uint8_t Revision; + std::uint8_t Checksum; + char OEMID[6]; + char OEMTableID[8]; + std::uint32_t OEMRevision; + std::uint32_t CreatorID; + std::uint32_t CreatorRevision; +}; + +static XSDP *rsdp = nullptr; + +void acpi_initialize() +{ + if (acpiRsdp) { + term.write("ACPI v1 detected.\n"); + rsdp = reinterpret_cast(acpiRsdp); + } else if (acpiRsdpV2) { + term.write("ACPI v2 detected, treating as v1.\n"); + rsdp = reinterpret_cast(acpiRsdpV2); + } + + //if (rsdp) { + // auto sdt = reinterpret_cast(rsdp->RsdtAddress); + //} +} + diff --git a/acpi.hpp b/acpi.hpp new file mode 100644 index 0000000..8154b81 --- /dev/null +++ b/acpi.hpp @@ -0,0 +1,7 @@ +#ifndef ACPI_HPP +#define ACPI_HPP + +void acpi_initialize(); + +#endif // ACPI_HPP + diff --git a/boot.cpp b/boot.cpp index 0b003fd..1c46b63 100644 --- a/boot.cpp +++ b/boot.cpp @@ -3,43 +3,6 @@ extern void kernel_main(); -struct multiboot2 -{ - static constexpr std::uint32_t MAGIC = 0xE85250D6; - static constexpr std::uint32_t FLAGS = 0; - static constexpr std::uint32_t LENGTH = 16; - static constexpr std::uint32_t CHECKSUM = -(MAGIC + FLAGS + LENGTH); - - alignas(8) - std::uint32_t magic = MAGIC; - std::uint32_t flags = FLAGS; - std::uint32_t length = LENGTH; - std::uint32_t checksum = CHECKSUM; -} __attribute__((packed)); - -struct multiboot2_tag -{ - alignas(8) - std::uint16_t id; - std::uint16_t flags; - std::uint32_t length; - std::uint32_t data[]; -} __attribute__((packed)); - -__attribute__((section(".multiboot2"))) -multiboot2 multibootHeader; - -__attribute__((section(".multiboot2"))) -multiboot2_tag multibootTagInfoRequest = { - 1, 0, sizeof(multiboot2_tag) + sizeof(std::uint32_t), - {4} -}; - -__attribute__((section(".multiboot2"))) -multiboot2_tag multibootTagEnd = { - 0, 0, sizeof(multiboot2_tag), {} -}; - alignas(16) std::array stack; diff --git a/kernel.cpp b/kernel.cpp index f16faa8..4d00e07 100644 --- a/kernel.cpp +++ b/kernel.cpp @@ -1,3 +1,4 @@ +#include "acpi.hpp" #include "gdt.hpp" #include "idt.hpp" #include "memory.hpp" @@ -26,6 +27,7 @@ void kernel_main(void) for (;;); }); + acpi_initialize(); memory_initialize(); gdt_initialize(); pic_initialize(); diff --git a/multiboot.cpp b/multiboot.cpp index 0c34984..0a30938 100644 --- a/multiboot.cpp +++ b/multiboot.cpp @@ -4,11 +4,50 @@ extern TextOutput& term; +struct multiboot2 +{ + static constexpr std::uint32_t MAGIC = 0xE85250D6; + static constexpr std::uint32_t FLAGS = 0; + static constexpr std::uint32_t LENGTH = 16; + static constexpr std::uint32_t CHECKSUM = -(MAGIC + FLAGS + LENGTH); + + alignas(8) + std::uint32_t magic = MAGIC; + std::uint32_t flags = FLAGS; + std::uint32_t length = LENGTH; + std::uint32_t checksum = CHECKSUM; +} __attribute__((packed)); + +struct multiboot2_tag +{ + alignas(8) + std::uint16_t id; + std::uint16_t flags; + std::uint32_t length; + std::uint32_t data[]; +} __attribute__((packed)); + +__attribute__((section(".multiboot2"))) +multiboot2 multibootHeader; + +__attribute__((section(".multiboot2"))) +multiboot2_tag multibootTagInfoRequest = { + 1, 0, sizeof(multiboot2_tag) + sizeof(std::uint32_t), + {4} +}; + +__attribute__((section(".multiboot2"))) +multiboot2_tag multibootTagEnd = { + 0, 0, sizeof(multiboot2_tag), {} +}; + std::uint32_t multiboot_magic; std::uint32_t *multiboot_ptr; std::uint32_t lowerMem = 0; std::uint32_t upperMem = 0; +std::uint32_t *acpiRsdp = nullptr; +std::uint32_t *acpiRsdpV2 = nullptr; bool multiboot_initialize() { @@ -24,9 +63,19 @@ bool multiboot_initialize() term.write(ptr[0]); term.write(", "); - if (ptr[0] == 4) { + switch (ptr[0]) { + case 4: lowerMem = ptr[2] * 1024; upperMem = ptr[3] * 1024; + break; + case 14: + acpiRsdp = ptr + 2; + break; + case 15: + acpiRsdpV2 = ptr + 2; + break; + default: + break; } auto next = reinterpret_cast(ptr);