aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2024-09-27 20:24:07 -0400
committerClyne Sullivan <clyne@bitgloo.com>2024-09-27 20:24:07 -0400
commit8f9329da623bf0812df44f60867180020283ff3f (patch)
tree08be9ccc06872609a7c0fba400c1adf414e86c60
parentbd0acf88361a4b73a49d11a45177e72bf32091bc (diff)
acpi detection
-rw-r--r--Makefile3
-rw-r--r--acpi.cpp51
-rw-r--r--acpi.hpp7
-rw-r--r--boot.cpp37
-rw-r--r--kernel.cpp2
-rw-r--r--multiboot.cpp51
6 files changed, 112 insertions, 39 deletions
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 <cstdint>
+
+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<XSDP *>(acpiRsdp);
+ } else if (acpiRsdpV2) {
+ term.write("ACPI v2 detected, treating as v1.\n");
+ rsdp = reinterpret_cast<XSDP *>(acpiRsdpV2);
+ }
+
+ //if (rsdp) {
+ // auto sdt = reinterpret_cast<SDTHeader *>(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<std::uint8_t, 16384> 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<std::uintptr_t>(ptr);