From b4484e951da3288dd3ff670d94987fd695c7e914 Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 7 Sep 2022 19:41:08 +0200 Subject: [PATCH] LOTS MORE LOGGING. which is great, of course. --- kernel/Makefile | 2 +- kernel/include/acpi/RSDT.h | 4 + kernel/include/config.h | 2 +- kernel/include/cpu/CPU.h | 1 + kernel/include/debug.h | 31 ------- kernel/include/memory/KernelMemoryManager.h | 2 + kernel/include/memory/MemoryMap.h | 6 ++ kernel/src/acpi/RSDT.cpp | 77 +++++++++++++++- kernel/src/cpu/CPU.cpp | 9 ++ kernel/src/debug.cpp | 61 ------------- kernel/src/gdt/GDT.cpp | 4 + kernel/src/interrupts/Entry.cpp | 4 +- kernel/src/interrupts/IDT.cpp | 4 + kernel/src/interrupts/IRQ.cpp | 9 +- kernel/src/interrupts/Install.cpp | 5 ++ kernel/src/io/PIC.cpp | 8 ++ kernel/src/log/Log.cpp | 3 + kernel/src/main.cpp | 97 +++------------------ kernel/src/memory/KernelMemoryManager.cpp | 17 ++++ kernel/src/memory/MemoryMap.cpp | 37 ++++++++ kernel/src/memory/RangeAllocator.cpp | 16 ++-- kernel/src/power/reboot.cpp | 53 +++++++++-- kernel/src/power/shutdown.cpp | 2 + kernel/src/scheduling/PIT.cpp | 4 + 24 files changed, 251 insertions(+), 207 deletions(-) delete mode 100644 kernel/include/debug.h create mode 100644 kernel/include/memory/MemoryMap.h delete mode 100644 kernel/src/debug.cpp create mode 100644 kernel/src/memory/MemoryMap.cpp diff --git a/kernel/Makefile b/kernel/Makefile index ea544c30..baa6f8d1 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -15,7 +15,7 @@ ASFLAGS := LDFLAGS := -T$(MOON_DIR)/moon.ld -nostdlib -lgcc -Wl,--build-id=none -z max-page-size=0x1000 ifneq ($(MOON_BUILD_STABLE), 1) -CFLAGS := ${CFLAGS} -D_MOON_SUFFIX="$(shell git rev-parse --short HEAD)" +CFLAGS := ${CFLAGS} -D_MOON_SUFFIX=-$(shell git rev-parse --short HEAD) endif ifeq ($(MOON_BUILD_DEBUG), 1) diff --git a/kernel/include/acpi/RSDT.h b/kernel/include/acpi/RSDT.h index a4d634a4..2ccd5af2 100644 --- a/kernel/include/acpi/RSDT.h +++ b/kernel/include/acpi/RSDT.h @@ -17,5 +17,9 @@ namespace ACPI SDTHeader* GetRSDTOrXSDT(); + bool ValidateRSDTOrXSDT(SDTHeader* rootSDT); + + bool IsXSDT(SDTHeader* rootSDT); + void* FindTable(SDTHeader* rootSDT, const char* signature); } \ No newline at end of file diff --git a/kernel/include/config.h b/kernel/include/config.h index 6a0a4d62..9747cabb 100644 --- a/kernel/include/config.h +++ b/kernel/include/config.h @@ -15,7 +15,7 @@ #endif #ifndef _MOON_SUFFIX -#define MOON_SUFFIX "stable" +#define MOON_SUFFIX "" #else #define MOON_SUFFIX STRINGIZE_VALUE_OF(_MOON_SUFFIX) #endif \ No newline at end of file diff --git a/kernel/include/cpu/CPU.h b/kernel/include/cpu/CPU.h index 56813d00..3b8359b3 100644 --- a/kernel/include/cpu/CPU.h +++ b/kernel/include/cpu/CPU.h @@ -6,6 +6,7 @@ namespace CPU { const char* get_vendor_string(); const char* get_brand_string(); + void log_cpu_information(); uint64_t get_feature_bitmask(); uint64_t get_initial_apic_id(); bool has_feature(CPU::Features); diff --git a/kernel/include/debug.h b/kernel/include/debug.h deleted file mode 100644 index 71dc39a9..00000000 --- a/kernel/include/debug.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include "render/BBRenderer.h" -#include "render/Color.h" - -namespace Debug -{ - - struct DebugStatus - { - static DebugStatus* the(); - - void Init(); - void ThrowException(int exception); - void StartBootStage(Color stage); - void PassBootStage(Color stage); - void FailBootStage(); - void DebugTick(); - void DebugKey(char key); - - private: - int x = 0; - int y = 0; - - int errx = 0; - int erry = 30; - - BBRenderer renderer; - - static DebugStatus s_main; - }; -} \ No newline at end of file diff --git a/kernel/include/memory/KernelMemoryManager.h b/kernel/include/memory/KernelMemoryManager.h index d6ef0450..8fe80b94 100644 --- a/kernel/include/memory/KernelMemoryManager.h +++ b/kernel/include/memory/KernelMemoryManager.h @@ -7,7 +7,9 @@ namespace KernelMemoryManager void release_mapping(void* mapping); void* get_unaligned_mapping(void* physicalAddress); + void* get_unaligned_mappings(void* physicalAddress, uint64_t count); void release_unaligned_mapping(void* mapping); + void release_unaligned_mappings(void* mapping, uint64_t count); void* get_page(); void* get_pages(uint64_t count); diff --git a/kernel/include/memory/MemoryMap.h b/kernel/include/memory/MemoryMap.h new file mode 100644 index 00000000..c2714dc1 --- /dev/null +++ b/kernel/include/memory/MemoryMap.h @@ -0,0 +1,6 @@ +#pragma once + +namespace Memory +{ + void walk_memory_map(); +} \ No newline at end of file diff --git a/kernel/src/acpi/RSDT.cpp b/kernel/src/acpi/RSDT.cpp index 07e25435..ba2c8f84 100644 --- a/kernel/src/acpi/RSDT.cpp +++ b/kernel/src/acpi/RSDT.cpp @@ -1,6 +1,9 @@ +#define MODULE "acpi/rsdt" + #include "acpi/RSDT.h" #include "bootboot.h" #include "log/Address.h" +#include "log/Log.h" #include "memory/KernelMemoryManager.h" #include "std/stdio.h" #include "std/string.h" @@ -9,25 +12,93 @@ extern BOOTBOOT bootboot; ACPI::SDTHeader* ACPI::GetRSDTOrXSDT() { - return (SDTHeader*)bootboot.arch.x86_64.acpi_ptr; + static void* cache = nullptr; + if (cache) return (SDTHeader*)cache; + kinfoln("First time accessing the RSDT/XSDT, mapping it into memory"); + void* physical = (void*)bootboot.arch.x86_64.acpi_ptr; + uint64_t offset = (uint64_t)physical % 4096; + kinfoln("RSDT/XSDT physical address: %lx", (uint64_t)physical); + cache = KernelMemoryManager::get_unaligned_mapping(physical); + uint64_t numPages = 1; + while ((offset + ((SDTHeader*)cache)->Length) > (numPages * 4096)) + { + kinfoln("RSDT/XSDT extends beyond the mapped page, mapping one more page"); + KernelMemoryManager::release_unaligned_mappings(cache, numPages); + numPages++; + cache = KernelMemoryManager::get_unaligned_mappings(cache, numPages); + } + kinfoln("Mapped RSDT/XSDT to virtual address %lx, uses %ld pages", (uint64_t)cache, numPages); + SDTHeader* result = (SDTHeader*)cache; + char OEMID[7]; + memcpy(OEMID, result->OEMID, 6); + OEMID[6] = 0; + kinfoln("OEMID: %s", OEMID); + char OEMTableID[9]; + memcpy(OEMTableID, result->OEMTableID, 8); + OEMTableID[8] = 0; + kinfoln("OEMTableID: %s", OEMTableID); + return result; +} + +bool ACPI::ValidateRSDTOrXSDT(ACPI::SDTHeader* rootSDT) +{ + if (!ValidateSDTHeader(rootSDT)) return false; + if (strncmp(rootSDT->Signature, "XSDT", 4) == 0) return true; + if (strncmp(rootSDT->Signature, "RSDT", 4) == 0) return true; + return false; +} + +bool ACPI::IsXSDT(ACPI::SDTHeader* rootSDT) +{ + return strncmp(rootSDT->Signature, "XSDT", 4) == 0; } void* ACPI::FindTable(ACPI::SDTHeader* rootSDT, const char* signature) { bool isXSDT = (strncmp(rootSDT->Signature, "XSDT", 4) == 0); int entries = (rootSDT->Length - sizeof(SDTHeader)) / (isXSDT ? 8 : 4); + kinfoln("Searching for table %s in the %s at %lx (table contains %d entries)", signature, isXSDT ? "XSDT" : "RSDT", + (uint64_t)rootSDT, entries); for (int i = 0; i < entries; i++) { + kinfoln("Testing for table %s in entry %d", signature, i); SDTHeader* h; - if (isXSDT) h = (SDTHeader*)((XSDT*)rootSDT)->PointerToOtherSDT[i]; + if (isXSDT) + { + uint64_t reversedAddress = (uint64_t)((XSDT*)rootSDT)->PointerToOtherSDT[i]; + uint64_t correctAddress = reversedAddress >> 32 | reversedAddress << 32; + h = (SDTHeader*)correctAddress; + } else { uint32_t entry = ((RSDT*)rootSDT)->PointerToOtherSDT[i]; h = (SDTHeader*)(uint64_t)entry; } + if (!h) + { + kinfoln("Entry points to null"); + continue; + } + kinfoln("Physical address of entry: %lx", (uint64_t)h); SDTHeader* realHeader = (SDTHeader*)KernelMemoryManager::get_unaligned_mapping(h); - if (strncmp(h->Signature, signature, 4) == 0) return (void*)h; + kinfoln("Mapped entry to virtual address %lx", (uint64_t)realHeader); + if (!ValidateSDTHeader(realHeader)) + { + kinfoln("Header is not valid, skipping this entry"); + KernelMemoryManager::release_unaligned_mapping(realHeader); + continue; + } + char tableSignature[5]; + memcpy(tableSignature, h->Signature, 4); + tableSignature[4] = 0; + kinfoln("Comparing target signature (%s) to signature of entry (%s)", signature, tableSignature); + if (strncmp(h->Signature, signature, 4) == 0) + { + kinfoln("Found table %s", signature); + return (void*)realHeader; + } + kinfoln("Signatures do not match, unmapping entry and continuing"); KernelMemoryManager::release_unaligned_mapping(realHeader); } diff --git a/kernel/src/cpu/CPU.cpp b/kernel/src/cpu/CPU.cpp index f98b6051..173951f4 100644 --- a/kernel/src/cpu/CPU.cpp +++ b/kernel/src/cpu/CPU.cpp @@ -1,4 +1,7 @@ +#define MODULE "cpuid" + #include "cpu/CPU.h" +#include "log/Log.h" #include #include @@ -80,3 +83,9 @@ uint64_t CPU::get_initial_apic_id() __get_cpuid(1, &unused, &ebx, &unused, &unused); return ebx >> 24; } + +void CPU::log_cpu_information() +{ + kinfoln("CPU vendor: %s", get_vendor_string()); + kinfoln("CPU brand: %s", get_brand_string()); +} diff --git a/kernel/src/debug.cpp b/kernel/src/debug.cpp deleted file mode 100644 index 4a240e40..00000000 --- a/kernel/src/debug.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "debug.h" -#include "assert.h" -#include "scheduling/PIT.h" - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstrict-aliasing" - -namespace Debug -{ - DebugStatus DebugStatus::s_main; - - void DebugStatus::Init() - { - ASSERT(renderer.init()); - } - - void DebugStatus::StartBootStage(Color stage) - { - renderer.paint_rect(x, y, 10, 10, stage); - y += 11; - } - - void DebugStatus::PassBootStage(Color stage) - { - renderer.paint_rect(x, y, 10, 10, stage); - y -= 11; - x += 11; - } - - void DebugStatus::FailBootStage() - { - renderer.paint_rect(x, y, 10, 10, Color::Red); - y -= 11; - x += 11; - } - - void DebugStatus::DebugTick() - { - uint8_t blue = (PIT::ms_since_boot / 10) % 255; - renderer.paint_rect(0, 200, 10, 10, Color{blue, 0x00, 0x00, 0xFF}); - } - - void DebugStatus::DebugKey(char key) - { - renderer.paint_rect(0, 215, 10, 10, Color{0x00, (uint8_t)key, 0x00, 0xFF}); - } - - void DebugStatus::ThrowException(int exception) - { - uint8_t red = (uint8_t)(exception * 8); - renderer.paint_rect(errx, erry, 10, 10, Color{0x00, 0x00, red, 0xFF}); - errx += 11; - } - - DebugStatus* DebugStatus::the() - { - return &s_main; - } -} - -#pragma GCC diagnostic pop \ No newline at end of file diff --git a/kernel/src/gdt/GDT.cpp b/kernel/src/gdt/GDT.cpp index 745cc05b..cdba2665 100644 --- a/kernel/src/gdt/GDT.cpp +++ b/kernel/src/gdt/GDT.cpp @@ -1,4 +1,7 @@ +#define MODULE "gdt" + #include "gdt/GDT.h" +#include "log/Log.h" #include struct GDTR @@ -39,5 +42,6 @@ void GDT::load() static GDTR gdtr; gdtr.offset = (uint64_t)&internal_gdt; gdtr.size = sizeof(InternalGDT); + kinfoln("Loading GDT at offset %lx, size %d", gdtr.offset, gdtr.size); load_gdt(&gdtr); } \ No newline at end of file diff --git a/kernel/src/interrupts/Entry.cpp b/kernel/src/interrupts/Entry.cpp index 5914b20d..c44b78a3 100644 --- a/kernel/src/interrupts/Entry.cpp +++ b/kernel/src/interrupts/Entry.cpp @@ -1,4 +1,3 @@ -#include "debug.h" #include "interrupts/IRQ.h" #include "interrupts/SavedContext.h" #include "panic/hang.h" @@ -6,7 +5,6 @@ extern "C" void common_handler(SavedContext* context) { - if (context->number < 0x20) { Debug::DebugStatus::the()->ThrowException(context->number); } if (context->number == 13) { printf("General protection fault at %zx, %ld, %ld, %zx, %ld, %zx\n", context->rip, context->cs, context->ss, @@ -15,7 +13,7 @@ extern "C" void common_handler(SavedContext* context) } if (context->number == 14) { - printf("Page fault at 0x%zx\n", context->rip); + printf("Page fault (RIP 0x%lx), while trying to access %lx\n", context->rip, context->cr2); hang(); } if (context->number >= 0x20 && context->number < 0x30) { IRQ::interrupt_handler(context); } diff --git a/kernel/src/interrupts/IDT.cpp b/kernel/src/interrupts/IDT.cpp index bb32e9b5..5010f2d9 100644 --- a/kernel/src/interrupts/IDT.cpp +++ b/kernel/src/interrupts/IDT.cpp @@ -1,5 +1,8 @@ +#define MODULE "idt" + #include "interrupts/IDT.h" #include "assert.h" +#include "log/Log.h" struct IDTEntry { @@ -47,5 +50,6 @@ void IDT::load() { idtr.limit = 0x0FFF; idtr.offset = (uint64_t)entries; + kinfoln("Loading IDT at offset %lx, limit %d", idtr.offset, idtr.limit); asm("lidt %0" : : "m"(idtr)); } \ No newline at end of file diff --git a/kernel/src/interrupts/IRQ.cpp b/kernel/src/interrupts/IRQ.cpp index 7afd3e76..e80a7ac9 100644 --- a/kernel/src/interrupts/IRQ.cpp +++ b/kernel/src/interrupts/IRQ.cpp @@ -1,5 +1,4 @@ #include "interrupts/IRQ.h" -#include "debug.h" #include "io/IO.h" #include "io/PIC.h" #include "scheduling/PIT.h" @@ -9,13 +8,9 @@ void IRQ::interrupt_handler(SavedContext* context) { switch (context->irq_number) { - case 0: - PIT::tick(); - Debug::DebugStatus::the()->DebugTick(); - break; + case 0: PIT::tick(); break; case 1: { - volatile unsigned char scancode = IO::inb(0x60); - Debug::DebugStatus::the()->DebugKey(scancode); + [[maybe_unused]] volatile unsigned char scancode = IO::inb(0x60); printf("Keyboard key pressed, seconds since boot: %ld\n", PIT::ms_since_boot / 1000); break; } diff --git a/kernel/src/interrupts/Install.cpp b/kernel/src/interrupts/Install.cpp index 163141d2..287fefd3 100644 --- a/kernel/src/interrupts/Install.cpp +++ b/kernel/src/interrupts/Install.cpp @@ -1,5 +1,6 @@ #include "interrupts/Install.h" #include "interrupts/IDT.h" +#include "log/Log.h" extern "C" { @@ -53,6 +54,7 @@ extern "C" void Interrupts::install() { + kinfoln("Installing handler stubs for exceptions (ISRs 0-31)"); INSTALL_TRAP(0); INSTALL_TRAP(1); INSTALL_TRAP(2); @@ -85,6 +87,7 @@ void Interrupts::install() INSTALL_TRAP(29); INSTALL_TRAP(30); INSTALL_UNUSED(31); + kinfoln("Installing handler stubs for IRQs (ISRs 32-47)"); INSTALL_ISR(32); INSTALL_ISR(33); INSTALL_ISR(34); @@ -101,6 +104,8 @@ void Interrupts::install() INSTALL_ISR(45); INSTALL_ISR(46); INSTALL_ISR(47); + kinfoln("Installing handler stub for software interrupt 48"); INSTALL_ISR(48); + kinfoln("Installing unused handler stubs for the rest of the IDT"); for (int i = 49; i < 256; i++) { INSTALL_UNUSED(i); } } \ No newline at end of file diff --git a/kernel/src/io/PIC.cpp b/kernel/src/io/PIC.cpp index d0e1ed75..f01524af 100644 --- a/kernel/src/io/PIC.cpp +++ b/kernel/src/io/PIC.cpp @@ -1,5 +1,8 @@ +#define MODULE "pic" + #include "io/PIC.h" #include "io/IO.h" +#include "log/Log.h" #define PIC1_COMMAND 0x20 #define PIC1_DATA 0x21 @@ -13,6 +16,7 @@ void PIC::remap() { + kinfoln("Remapping PIC"); uint8_t a1, a2; a1 = IO::inb(PIC1_DATA); @@ -25,8 +29,10 @@ void PIC::remap() IO::outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); IO::delay(); + kinfoln("Remapping master PIC to ISRs 32-39"); IO::outb(PIC1_DATA, 0x20); IO::delay(); + kinfoln("Remapping slave PIC to ISRs 40-47"); IO::outb(PIC2_DATA, 0x28); IO::delay(); @@ -47,11 +53,13 @@ void PIC::remap() void PIC::enable_master(uint8_t mask) { + kinfoln("Setting mask of master PIC to 0x%x", mask); IO::outb(PIC1_DATA, mask); } void PIC::enable_slave(uint8_t mask) { + kinfoln("Setting mask of slave PIC to 0x%x", mask); IO::outb(PIC2_DATA, mask); } diff --git a/kernel/src/log/Log.cpp b/kernel/src/log/Log.cpp index 86772169..53eb16d6 100644 --- a/kernel/src/log/Log.cpp +++ b/kernel/src/log/Log.cpp @@ -1,5 +1,6 @@ #include "log/Log.h" #include "io/Serial.h" +#include "scheduling/PIT.h" #include "std/stdio.h" #include @@ -8,6 +9,7 @@ void KernelLog::log(const char* function, LogLevel level, const char* message, . va_list ap; va_start(ap, message); Serial::reset_color(); + printf("[%ld.%ld] ", PIT::ms_since_boot / 1000, PIT::ms_since_boot % 1000); Serial::print(function); Serial::print(": "); switch (level) @@ -26,6 +28,7 @@ void KernelLog::logln(const char* function, LogLevel level, const char* message, va_list ap; va_start(ap, message); Serial::reset_color(); + printf("[%ld.%ld] ", PIT::ms_since_boot / 1000, PIT::ms_since_boot % 1000); Serial::print(function); Serial::print(": "); switch (level) diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 18a90e7f..7297b3fa 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -5,7 +5,6 @@ #include "bootboot.h" #include "config.h" #include "cpu/CPU.h" -#include "debug.h" #include "gdt/GDT.h" #include "init/Init.h" #include "init/InitRD.h" @@ -19,9 +18,10 @@ #include "memory/KernelHeap.h" #include "memory/KernelMemoryManager.h" #include "memory/Memory.h" +#include "memory/MemoryMap.h" #include "memory/RangeAllocator.h" #include "panic/hang.h" -#include "power/shutdown.h" +#include "power/reboot.h" #include "render/BBRenderer.h" #include "render/Draw.h" #include "render/TextRenderer.h" @@ -36,117 +36,44 @@ extern "C" void _start() { Init::check_magic(); Init::disable_smp(); // Put all other cores except the bootstrap one in an infinite loop - Debug::DebugStatus::the()->Init(); - Debug::DebugStatus::the()->StartBootStage(Color::White); Init::early_init(); - Debug::DebugStatus::the()->PassBootStage(Color::White); - kinfoln("Starting Moon %d.%d-%s", MOON_MAJOR, MOON_MINOR, MOON_SUFFIX); + kinfoln("Starting Moon %d.%d%s", MOON_MAJOR, MOON_MINOR, MOON_SUFFIX); + + CPU::log_cpu_information(); + + Memory::walk_memory_map(); - Debug::DebugStatus::the()->StartBootStage(Color::Gray); GDT::load(); - Debug::DebugStatus::the()->PassBootStage(Color::Gray); kinfoln("Loaded GDT"); - Debug::DebugStatus::the()->StartBootStage(Color::Cyan); Interrupts::install(); - Debug::DebugStatus::the()->PassBootStage(Color::Cyan); - Debug::DebugStatus::the()->StartBootStage(Color::Blue); IDT::load(); - Debug::DebugStatus::the()->PassBootStage(Color::Blue); kinfoln("Loaded IDT"); - Debug::DebugStatus::the()->StartBootStage(Color::Green); PIC::remap(); PIC::enable_master(0b11111100); // enable keyboard and PIT PIC::enable_slave(0b11111111); - Debug::DebugStatus::the()->PassBootStage(Color::Green); kinfoln("Prepared PIC"); - Debug::DebugStatus::the()->StartBootStage(Color::Magenta); - PIT::initialize(100); // 100 times per second - Debug::DebugStatus::the()->PassBootStage(Color::Magenta); + PIT::initialize(1000); // 1000 times per second, 1 time per millisecond kinfoln("Prepared PIT"); - Debug::DebugStatus::the()->StartBootStage(Color::Yellow); Interrupts::enable(); - Debug::DebugStatus::the()->PassBootStage(Color::Yellow); kinfoln("Interrupts enabled"); - Debug::DebugStatus::the()->StartBootStage(Color{0x33, 0x33, 0x00, 0xFF}); - ACPI::SDTHeader* rootSDT = (ACPI::SDTHeader*)KernelMemoryManager::get_unaligned_mapping(ACPI::GetRSDTOrXSDT()); - bool isXSDT = false; - if (strncmp(rootSDT->Signature, "XSDT", 4) != 0) - { - if (strncmp(rootSDT->Signature, "RSDT", 4) != 0) - { - kerrorln("Invalid RootSDT signature"); - Debug::DebugStatus::the()->FailBootStage(); - while (1) halt(); - } - } - else - isXSDT = true; - if (ACPI::ValidateSDTHeader(rootSDT)) - { - kinfoln("%s: 0x%lx", isXSDT ? "XSDT is valid" : "RSDT is valid", (uint64_t)rootSDT); - Debug::DebugStatus::the()->PassBootStage(Color{0x33, 0x33, 0x00, 0xFF}); - } - else - { - kinfoln(isXSDT ? "Invalid XSDT :(" : "Invalid RSDT :("); - Debug::DebugStatus::the()->FailBootStage(); - while (1) halt(); - } - - Debug::DebugStatus::the()->StartBootStage(Color{0x00, 0x66, 0xCC, 0xFF}); - ACPI::SDTHeader* fadt = (ACPI::SDTHeader*)ACPI::FindTable(rootSDT, "FACP"); - if (!fadt) - { - kerrorln("FADT not found"); - Debug::DebugStatus::the()->FailBootStage(); - while (1) halt(); - } - if (strncmp(fadt->Signature, "FACP", 4) != 0) - { - kerrorln("Invalid FADT signature"); - Debug::DebugStatus::the()->FailBootStage(); - while (1) halt(); - } - else - { - if (ACPI::ValidateSDTHeader(fadt)) - { - kinfoln("FADT is valid"); - Debug::DebugStatus::the()->PassBootStage(Color{0x00, 0x66, 0xCC, 0xFF}); - } - else - { - kinfoln("Invalid FADT :("); - Debug::DebugStatus::the()->FailBootStage(); - while (1) halt(); - } - } - - ACPI::SDTHeader* madt = (ACPI::SDTHeader*)ACPI::FindTable(rootSDT, "APIC"); - if (!madt) - { - kerrorln("MADT not found"); - while (1) halt(); - } - - KernelMemoryManager::release_unaligned_mapping(rootSDT); + ACPI::SDTHeader* rootSDT = ACPI::GetRSDTOrXSDT(); + bool isXSDT = ACPI::IsXSDT(rootSDT); + if (!ACPI::ValidateRSDTOrXSDT(rootSDT)) kerrorln("Invalid %s", isXSDT ? "XSDT" : "RSDT"); sleep(2500); - shutdown(); + reboot(); while (1) halt(); -loop: - goto loop; } \ No newline at end of file diff --git a/kernel/src/memory/KernelMemoryManager.cpp b/kernel/src/memory/KernelMemoryManager.cpp index a1cf8ae1..ed93f4e1 100644 --- a/kernel/src/memory/KernelMemoryManager.cpp +++ b/kernel/src/memory/KernelMemoryManager.cpp @@ -19,12 +19,29 @@ void* KernelMemoryManager::get_unaligned_mapping(void* physicalAddress) return (void*)(virtualAddress + offset); } +void* KernelMemoryManager::get_unaligned_mappings(void* physicalAddress, uint64_t count) +{ + uint64_t offset = (uint64_t)physicalAddress % 4096; + uint64_t virtualAddress = KernelHeap::request_virtual_pages(count); + for (uint64_t i = 0; i < count; i++) + { + kernelVMM.map(virtualAddress + (i * 4096), ((uint64_t)physicalAddress - offset) + (i * 4096)); + } + return (void*)(virtualAddress + offset); +} + void KernelMemoryManager::release_unaligned_mapping(void* mapping) { uint64_t offset = (uint64_t)mapping % 4096; kernelVMM.unmap((uint64_t)mapping - offset); } +void KernelMemoryManager::release_unaligned_mappings(void* mapping, uint64_t count) +{ + uint64_t offset = (uint64_t)mapping % 4096; + for (uint64_t i = 0; i < count; i++) { kernelVMM.unmap(((uint64_t)mapping - offset) + (i * 4096)); } +} + void KernelMemoryManager::release_mapping(void* mapping) { kernelVMM.unmap((uint64_t)mapping); diff --git a/kernel/src/memory/MemoryMap.cpp b/kernel/src/memory/MemoryMap.cpp new file mode 100644 index 00000000..9ae89bbe --- /dev/null +++ b/kernel/src/memory/MemoryMap.cpp @@ -0,0 +1,37 @@ +#define MODULE "mmap" + +#include "memory/MemoryMap.h" +#include "bootboot.h" +#include "log/Log.h" + +extern BOOTBOOT bootboot; + +void Memory::walk_memory_map() +{ + MMapEnt* ptr = &bootboot.mmap; + uint64_t mmap_entries = (bootboot.size - 128) / 16; + for (uint64_t i = 0; i < mmap_entries; i++) + { + switch (MMapEnt_Type(ptr)) + { + case MMAP_USED: + kinfoln("Used memory region starting at %lx, ends at %lx, size %lx", MMapEnt_Ptr(ptr), + MMapEnt_Ptr(ptr) + MMapEnt_Size(ptr) - 1, MMapEnt_Size(ptr)); + break; + case MMAP_ACPI: + kinfoln("ACPI memory region starting at %lx, ends at %lx, size %lx", MMapEnt_Ptr(ptr), + MMapEnt_Ptr(ptr) + MMapEnt_Size(ptr) - 1, MMapEnt_Size(ptr)); + break; + case MMAP_MMIO: + kinfoln("MMIO memory region starting at %lx, ends at %lx, size %lx", MMapEnt_Ptr(ptr), + MMapEnt_Ptr(ptr) + MMapEnt_Size(ptr) - 1, MMapEnt_Size(ptr)); + break; + case MMAP_FREE: + kinfoln("Free memory region starting at %lx, ends at %lx, size %lx", MMapEnt_Ptr(ptr), + MMapEnt_Ptr(ptr) + MMapEnt_Size(ptr) - 1, MMapEnt_Size(ptr)); + break; + default: kinfoln("Invalid memory map entry"); break; + } + ptr++; + } +} \ No newline at end of file diff --git a/kernel/src/memory/RangeAllocator.cpp b/kernel/src/memory/RangeAllocator.cpp index 65a42cdf..e76c1ba9 100644 --- a/kernel/src/memory/RangeAllocator.cpp +++ b/kernel/src/memory/RangeAllocator.cpp @@ -30,18 +30,22 @@ void RangeAllocator::init_from_mmap() bitmap_addr = (char*)biggest_chunk; ASSERT((total_mem / 4096 / 8) < biggest_chunk_size); bitmap_size = total_mem / 4096 / 8 + 1; - memset(bitmap_addr, 0, bitmap_size); - - free_mem = total_mem; - - lock_pages(bitmap_addr, bitmap_size / 4096 + 1); + memset(bitmap_addr, 0xFF, bitmap_size); ptr = &bootboot.mmap; for (uint64_t i = 0; i < mmap_entries; i++) { - if (!MMapEnt_IsFree(ptr)) { reserve_pages((void*)MMapEnt_Ptr(ptr), MMapEnt_Size(ptr) / 4096); } + uint64_t index = MMapEnt_Ptr(ptr) / 4096; + if (!MMapEnt_IsFree(ptr)) { reserved_mem += 4096; } + else + { + free_mem += 4096; + bitmap_set(index, false); + } ptr++; } + + lock_pages(bitmap_addr, bitmap_size / 4096 + 1); } bool RangeAllocator::bitmap_read(uint64_t index) diff --git a/kernel/src/power/reboot.cpp b/kernel/src/power/reboot.cpp index caeaf4ad..a03920ad 100644 --- a/kernel/src/power/reboot.cpp +++ b/kernel/src/power/reboot.cpp @@ -1,3 +1,5 @@ +#define MODULE "power" + #include "power/reboot.h" #include "acpi/FADT.h" #include "acpi/RSDT.h" @@ -11,20 +13,53 @@ static void try_acpi_reboot() { + kinfoln("Fetching pointer to RSDT/XSDT"); ACPI::SDTHeader* rootSDT = ACPI::GetRSDTOrXSDT(); - if (!rootSDT) return; - if (!ACPI::ValidateSDTHeader(rootSDT)) return; - if (strncmp(rootSDT->Signature, "RSDT", 4) != 0 && strncmp(rootSDT->Signature, "XSDT", 4) != 0) return; + if (!rootSDT) + { + kinfoln("The pointer to the RSDT/XSDT is null"); + return; + } + if (!ACPI::ValidateSDTHeader(rootSDT)) + { + kinfoln("The RSDT/XSDT has an invalid header"); + return; + } + if (strncmp(rootSDT->Signature, "RSDT", 4) != 0 && strncmp(rootSDT->Signature, "XSDT", 4) != 0) + { + kinfoln("The RSDT/XSDT's signature is not RSDT or XSDT"); + return; + } + kinfoln("Searching for FACP"); ACPI::FADT* fadt = (ACPI::FADT*)ACPI::FindTable(rootSDT, "FACP"); - if (!fadt) return; - if (!ACPI::ValidateSDTHeader(&fadt->header)) return; - if (!(fadt->Flags & 1 << 10)) return; + if (!fadt) + { + kinfoln("Unable to find the FADT"); + return; + } + if (fadt->header.Revision < 2) + { + kinfoln("ACPI revision is too low (%d), ACPI Reset is only implemented in ACPI 2.0+", fadt->header.Revision); + return; + } + if (!(fadt->Flags & 1 << 10)) + { + kinfoln("This system does not support ACPI Reset"); + return; + } switch (fadt->ResetReg.AddressSpace) { - case ACPI::SystemIO: IO::outb(fadt->ResetReg.Address, fadt->ResetValue); break; - case ACPI::GeneralPurposeIO: IO::outb(fadt->ResetReg.Address, fadt->ResetValue); break; - default: return; + case ACPI::SystemIO: + kinfoln("Attempting reboot via IO"); + IO::outb(fadt->ResetReg.Address, fadt->ResetValue); + break; + case ACPI::GeneralPurposeIO: + kinfoln("Attempting reboot via IO"); + IO::outb(fadt->ResetReg.Address, fadt->ResetValue); + break; + default: kinfoln("This method of rebooting via ACPI is not yet implemented"); return; } + kinfoln("Tried to reboot, but apparently did nothing"); } static void try_kbd_reboot() diff --git a/kernel/src/power/shutdown.cpp b/kernel/src/power/shutdown.cpp index 52e225b5..3d365dee 100644 --- a/kernel/src/power/shutdown.cpp +++ b/kernel/src/power/shutdown.cpp @@ -1,3 +1,5 @@ +#define MODULE "power" + #include "power/shutdown.h" #include "io/IO.h" #include "log/Log.h" diff --git a/kernel/src/scheduling/PIT.cpp b/kernel/src/scheduling/PIT.cpp index 657eeaa8..60478c7d 100644 --- a/kernel/src/scheduling/PIT.cpp +++ b/kernel/src/scheduling/PIT.cpp @@ -1,5 +1,8 @@ +#define MODULE "pit" + #include "scheduling/PIT.h" #include "io/IO.h" +#include "log/Log.h" #define PIT_CHANNEL_0_PORT 0x40 @@ -9,6 +12,7 @@ uint16_t divisor = 65535; void PIT::initialize(uint64_t frequency) { divisor = base_frequency / frequency; + kinfoln("Configuring PIT to use divisor %d (will tick %lu times per second)", divisor, frequency); if (divisor < 100) divisor = 100; IO::outb(PIT_CHANNEL_0_PORT, (uint8_t)(divisor & 0xFF)); IO::delay();