LOTS MORE LOGGING. which is great, of course.

This commit is contained in:
apio 2022-09-07 19:41:08 +02:00
parent 0cc3900e88
commit b4484e951d
24 changed files with 251 additions and 207 deletions

View File

@ -15,7 +15,7 @@ ASFLAGS :=
LDFLAGS := -T$(MOON_DIR)/moon.ld -nostdlib -lgcc -Wl,--build-id=none -z max-page-size=0x1000 LDFLAGS := -T$(MOON_DIR)/moon.ld -nostdlib -lgcc -Wl,--build-id=none -z max-page-size=0x1000
ifneq ($(MOON_BUILD_STABLE), 1) 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 endif
ifeq ($(MOON_BUILD_DEBUG), 1) ifeq ($(MOON_BUILD_DEBUG), 1)

View File

@ -17,5 +17,9 @@ namespace ACPI
SDTHeader* GetRSDTOrXSDT(); SDTHeader* GetRSDTOrXSDT();
bool ValidateRSDTOrXSDT(SDTHeader* rootSDT);
bool IsXSDT(SDTHeader* rootSDT);
void* FindTable(SDTHeader* rootSDT, const char* signature); void* FindTable(SDTHeader* rootSDT, const char* signature);
} }

View File

@ -15,7 +15,7 @@
#endif #endif
#ifndef _MOON_SUFFIX #ifndef _MOON_SUFFIX
#define MOON_SUFFIX "stable" #define MOON_SUFFIX ""
#else #else
#define MOON_SUFFIX STRINGIZE_VALUE_OF(_MOON_SUFFIX) #define MOON_SUFFIX STRINGIZE_VALUE_OF(_MOON_SUFFIX)
#endif #endif

View File

@ -6,6 +6,7 @@ namespace CPU
{ {
const char* get_vendor_string(); const char* get_vendor_string();
const char* get_brand_string(); const char* get_brand_string();
void log_cpu_information();
uint64_t get_feature_bitmask(); uint64_t get_feature_bitmask();
uint64_t get_initial_apic_id(); uint64_t get_initial_apic_id();
bool has_feature(CPU::Features); bool has_feature(CPU::Features);

View File

@ -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;
};
}

View File

@ -7,7 +7,9 @@ namespace KernelMemoryManager
void release_mapping(void* mapping); void release_mapping(void* mapping);
void* get_unaligned_mapping(void* physicalAddress); void* get_unaligned_mapping(void* physicalAddress);
void* get_unaligned_mappings(void* physicalAddress, uint64_t count);
void release_unaligned_mapping(void* mapping); void release_unaligned_mapping(void* mapping);
void release_unaligned_mappings(void* mapping, uint64_t count);
void* get_page(); void* get_page();
void* get_pages(uint64_t count); void* get_pages(uint64_t count);

View File

@ -0,0 +1,6 @@
#pragma once
namespace Memory
{
void walk_memory_map();
}

View File

@ -1,6 +1,9 @@
#define MODULE "acpi/rsdt"
#include "acpi/RSDT.h" #include "acpi/RSDT.h"
#include "bootboot.h" #include "bootboot.h"
#include "log/Address.h" #include "log/Address.h"
#include "log/Log.h"
#include "memory/KernelMemoryManager.h" #include "memory/KernelMemoryManager.h"
#include "std/stdio.h" #include "std/stdio.h"
#include "std/string.h" #include "std/string.h"
@ -9,25 +12,93 @@ extern BOOTBOOT bootboot;
ACPI::SDTHeader* ACPI::GetRSDTOrXSDT() 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) void* ACPI::FindTable(ACPI::SDTHeader* rootSDT, const char* signature)
{ {
bool isXSDT = (strncmp(rootSDT->Signature, "XSDT", 4) == 0); bool isXSDT = (strncmp(rootSDT->Signature, "XSDT", 4) == 0);
int entries = (rootSDT->Length - sizeof(SDTHeader)) / (isXSDT ? 8 : 4); 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++) for (int i = 0; i < entries; i++)
{ {
kinfoln("Testing for table %s in entry %d", signature, i);
SDTHeader* h; 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 else
{ {
uint32_t entry = ((RSDT*)rootSDT)->PointerToOtherSDT[i]; uint32_t entry = ((RSDT*)rootSDT)->PointerToOtherSDT[i];
h = (SDTHeader*)(uint64_t)entry; 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); 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); KernelMemoryManager::release_unaligned_mapping(realHeader);
} }

View File

@ -1,4 +1,7 @@
#define MODULE "cpuid"
#include "cpu/CPU.h" #include "cpu/CPU.h"
#include "log/Log.h"
#include <cpuid.h> #include <cpuid.h>
#include <string.h> #include <string.h>
@ -80,3 +83,9 @@ uint64_t CPU::get_initial_apic_id()
__get_cpuid(1, &unused, &ebx, &unused, &unused); __get_cpuid(1, &unused, &ebx, &unused, &unused);
return ebx >> 24; return ebx >> 24;
} }
void CPU::log_cpu_information()
{
kinfoln("CPU vendor: %s", get_vendor_string());
kinfoln("CPU brand: %s", get_brand_string());
}

View File

@ -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

View File

@ -1,4 +1,7 @@
#define MODULE "gdt"
#include "gdt/GDT.h" #include "gdt/GDT.h"
#include "log/Log.h"
#include <stdint.h> #include <stdint.h>
struct GDTR struct GDTR
@ -39,5 +42,6 @@ void GDT::load()
static GDTR gdtr; static GDTR gdtr;
gdtr.offset = (uint64_t)&internal_gdt; gdtr.offset = (uint64_t)&internal_gdt;
gdtr.size = sizeof(InternalGDT); gdtr.size = sizeof(InternalGDT);
kinfoln("Loading GDT at offset %lx, size %d", gdtr.offset, gdtr.size);
load_gdt(&gdtr); load_gdt(&gdtr);
} }

View File

@ -1,4 +1,3 @@
#include "debug.h"
#include "interrupts/IRQ.h" #include "interrupts/IRQ.h"
#include "interrupts/SavedContext.h" #include "interrupts/SavedContext.h"
#include "panic/hang.h" #include "panic/hang.h"
@ -6,7 +5,6 @@
extern "C" void common_handler(SavedContext* context) extern "C" void common_handler(SavedContext* context)
{ {
if (context->number < 0x20) { Debug::DebugStatus::the()->ThrowException(context->number); }
if (context->number == 13) if (context->number == 13)
{ {
printf("General protection fault at %zx, %ld, %ld, %zx, %ld, %zx\n", context->rip, context->cs, context->ss, 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) 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(); hang();
} }
if (context->number >= 0x20 && context->number < 0x30) { IRQ::interrupt_handler(context); } if (context->number >= 0x20 && context->number < 0x30) { IRQ::interrupt_handler(context); }

View File

@ -1,5 +1,8 @@
#define MODULE "idt"
#include "interrupts/IDT.h" #include "interrupts/IDT.h"
#include "assert.h" #include "assert.h"
#include "log/Log.h"
struct IDTEntry struct IDTEntry
{ {
@ -47,5 +50,6 @@ void IDT::load()
{ {
idtr.limit = 0x0FFF; idtr.limit = 0x0FFF;
idtr.offset = (uint64_t)entries; idtr.offset = (uint64_t)entries;
kinfoln("Loading IDT at offset %lx, limit %d", idtr.offset, idtr.limit);
asm("lidt %0" : : "m"(idtr)); asm("lidt %0" : : "m"(idtr));
} }

View File

@ -1,5 +1,4 @@
#include "interrupts/IRQ.h" #include "interrupts/IRQ.h"
#include "debug.h"
#include "io/IO.h" #include "io/IO.h"
#include "io/PIC.h" #include "io/PIC.h"
#include "scheduling/PIT.h" #include "scheduling/PIT.h"
@ -9,13 +8,9 @@ void IRQ::interrupt_handler(SavedContext* context)
{ {
switch (context->irq_number) switch (context->irq_number)
{ {
case 0: case 0: PIT::tick(); break;
PIT::tick();
Debug::DebugStatus::the()->DebugTick();
break;
case 1: { case 1: {
volatile unsigned char scancode = IO::inb(0x60); [[maybe_unused]] volatile unsigned char scancode = IO::inb(0x60);
Debug::DebugStatus::the()->DebugKey(scancode);
printf("Keyboard key pressed, seconds since boot: %ld\n", PIT::ms_since_boot / 1000); printf("Keyboard key pressed, seconds since boot: %ld\n", PIT::ms_since_boot / 1000);
break; break;
} }

View File

@ -1,5 +1,6 @@
#include "interrupts/Install.h" #include "interrupts/Install.h"
#include "interrupts/IDT.h" #include "interrupts/IDT.h"
#include "log/Log.h"
extern "C" extern "C"
{ {
@ -53,6 +54,7 @@ extern "C"
void Interrupts::install() void Interrupts::install()
{ {
kinfoln("Installing handler stubs for exceptions (ISRs 0-31)");
INSTALL_TRAP(0); INSTALL_TRAP(0);
INSTALL_TRAP(1); INSTALL_TRAP(1);
INSTALL_TRAP(2); INSTALL_TRAP(2);
@ -85,6 +87,7 @@ void Interrupts::install()
INSTALL_TRAP(29); INSTALL_TRAP(29);
INSTALL_TRAP(30); INSTALL_TRAP(30);
INSTALL_UNUSED(31); INSTALL_UNUSED(31);
kinfoln("Installing handler stubs for IRQs (ISRs 32-47)");
INSTALL_ISR(32); INSTALL_ISR(32);
INSTALL_ISR(33); INSTALL_ISR(33);
INSTALL_ISR(34); INSTALL_ISR(34);
@ -101,6 +104,8 @@ void Interrupts::install()
INSTALL_ISR(45); INSTALL_ISR(45);
INSTALL_ISR(46); INSTALL_ISR(46);
INSTALL_ISR(47); INSTALL_ISR(47);
kinfoln("Installing handler stub for software interrupt 48");
INSTALL_ISR(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); } for (int i = 49; i < 256; i++) { INSTALL_UNUSED(i); }
} }

View File

@ -1,5 +1,8 @@
#define MODULE "pic"
#include "io/PIC.h" #include "io/PIC.h"
#include "io/IO.h" #include "io/IO.h"
#include "log/Log.h"
#define PIC1_COMMAND 0x20 #define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21 #define PIC1_DATA 0x21
@ -13,6 +16,7 @@
void PIC::remap() void PIC::remap()
{ {
kinfoln("Remapping PIC");
uint8_t a1, a2; uint8_t a1, a2;
a1 = IO::inb(PIC1_DATA); a1 = IO::inb(PIC1_DATA);
@ -25,8 +29,10 @@ void PIC::remap()
IO::outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); IO::outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
IO::delay(); IO::delay();
kinfoln("Remapping master PIC to ISRs 32-39");
IO::outb(PIC1_DATA, 0x20); IO::outb(PIC1_DATA, 0x20);
IO::delay(); IO::delay();
kinfoln("Remapping slave PIC to ISRs 40-47");
IO::outb(PIC2_DATA, 0x28); IO::outb(PIC2_DATA, 0x28);
IO::delay(); IO::delay();
@ -47,11 +53,13 @@ void PIC::remap()
void PIC::enable_master(uint8_t mask) void PIC::enable_master(uint8_t mask)
{ {
kinfoln("Setting mask of master PIC to 0x%x", mask);
IO::outb(PIC1_DATA, mask); IO::outb(PIC1_DATA, mask);
} }
void PIC::enable_slave(uint8_t mask) void PIC::enable_slave(uint8_t mask)
{ {
kinfoln("Setting mask of slave PIC to 0x%x", mask);
IO::outb(PIC2_DATA, mask); IO::outb(PIC2_DATA, mask);
} }

View File

@ -1,5 +1,6 @@
#include "log/Log.h" #include "log/Log.h"
#include "io/Serial.h" #include "io/Serial.h"
#include "scheduling/PIT.h"
#include "std/stdio.h" #include "std/stdio.h"
#include <stdarg.h> #include <stdarg.h>
@ -8,6 +9,7 @@ void KernelLog::log(const char* function, LogLevel level, const char* message, .
va_list ap; va_list ap;
va_start(ap, message); va_start(ap, message);
Serial::reset_color(); Serial::reset_color();
printf("[%ld.%ld] ", PIT::ms_since_boot / 1000, PIT::ms_since_boot % 1000);
Serial::print(function); Serial::print(function);
Serial::print(": "); Serial::print(": ");
switch (level) switch (level)
@ -26,6 +28,7 @@ void KernelLog::logln(const char* function, LogLevel level, const char* message,
va_list ap; va_list ap;
va_start(ap, message); va_start(ap, message);
Serial::reset_color(); Serial::reset_color();
printf("[%ld.%ld] ", PIT::ms_since_boot / 1000, PIT::ms_since_boot % 1000);
Serial::print(function); Serial::print(function);
Serial::print(": "); Serial::print(": ");
switch (level) switch (level)

View File

@ -5,7 +5,6 @@
#include "bootboot.h" #include "bootboot.h"
#include "config.h" #include "config.h"
#include "cpu/CPU.h" #include "cpu/CPU.h"
#include "debug.h"
#include "gdt/GDT.h" #include "gdt/GDT.h"
#include "init/Init.h" #include "init/Init.h"
#include "init/InitRD.h" #include "init/InitRD.h"
@ -19,9 +18,10 @@
#include "memory/KernelHeap.h" #include "memory/KernelHeap.h"
#include "memory/KernelMemoryManager.h" #include "memory/KernelMemoryManager.h"
#include "memory/Memory.h" #include "memory/Memory.h"
#include "memory/MemoryMap.h"
#include "memory/RangeAllocator.h" #include "memory/RangeAllocator.h"
#include "panic/hang.h" #include "panic/hang.h"
#include "power/shutdown.h" #include "power/reboot.h"
#include "render/BBRenderer.h" #include "render/BBRenderer.h"
#include "render/Draw.h" #include "render/Draw.h"
#include "render/TextRenderer.h" #include "render/TextRenderer.h"
@ -36,117 +36,44 @@ extern "C" void _start()
{ {
Init::check_magic(); Init::check_magic();
Init::disable_smp(); // Put all other cores except the bootstrap one in an infinite loop 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(); 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(); GDT::load();
Debug::DebugStatus::the()->PassBootStage(Color::Gray);
kinfoln("Loaded GDT"); kinfoln("Loaded GDT");
Debug::DebugStatus::the()->StartBootStage(Color::Cyan);
Interrupts::install(); Interrupts::install();
Debug::DebugStatus::the()->PassBootStage(Color::Cyan);
Debug::DebugStatus::the()->StartBootStage(Color::Blue);
IDT::load(); IDT::load();
Debug::DebugStatus::the()->PassBootStage(Color::Blue);
kinfoln("Loaded IDT"); kinfoln("Loaded IDT");
Debug::DebugStatus::the()->StartBootStage(Color::Green);
PIC::remap(); PIC::remap();
PIC::enable_master(0b11111100); // enable keyboard and PIT PIC::enable_master(0b11111100); // enable keyboard and PIT
PIC::enable_slave(0b11111111); PIC::enable_slave(0b11111111);
Debug::DebugStatus::the()->PassBootStage(Color::Green);
kinfoln("Prepared PIC"); kinfoln("Prepared PIC");
Debug::DebugStatus::the()->StartBootStage(Color::Magenta); PIT::initialize(1000); // 1000 times per second, 1 time per millisecond
PIT::initialize(100); // 100 times per second
Debug::DebugStatus::the()->PassBootStage(Color::Magenta);
kinfoln("Prepared PIT"); kinfoln("Prepared PIT");
Debug::DebugStatus::the()->StartBootStage(Color::Yellow);
Interrupts::enable(); Interrupts::enable();
Debug::DebugStatus::the()->PassBootStage(Color::Yellow);
kinfoln("Interrupts enabled"); kinfoln("Interrupts enabled");
Debug::DebugStatus::the()->StartBootStage(Color{0x33, 0x33, 0x00, 0xFF}); ACPI::SDTHeader* rootSDT = ACPI::GetRSDTOrXSDT();
ACPI::SDTHeader* rootSDT = (ACPI::SDTHeader*)KernelMemoryManager::get_unaligned_mapping(ACPI::GetRSDTOrXSDT()); bool isXSDT = ACPI::IsXSDT(rootSDT);
bool isXSDT = false; if (!ACPI::ValidateRSDTOrXSDT(rootSDT)) kerrorln("Invalid %s", isXSDT ? "XSDT" : "RSDT");
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);
sleep(2500); sleep(2500);
shutdown(); reboot();
while (1) halt(); while (1) halt();
loop:
goto loop;
} }

View File

@ -19,12 +19,29 @@ void* KernelMemoryManager::get_unaligned_mapping(void* physicalAddress)
return (void*)(virtualAddress + offset); 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) void KernelMemoryManager::release_unaligned_mapping(void* mapping)
{ {
uint64_t offset = (uint64_t)mapping % 4096; uint64_t offset = (uint64_t)mapping % 4096;
kernelVMM.unmap((uint64_t)mapping - offset); 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) void KernelMemoryManager::release_mapping(void* mapping)
{ {
kernelVMM.unmap((uint64_t)mapping); kernelVMM.unmap((uint64_t)mapping);

View File

@ -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++;
}
}

View File

@ -30,18 +30,22 @@ void RangeAllocator::init_from_mmap()
bitmap_addr = (char*)biggest_chunk; bitmap_addr = (char*)biggest_chunk;
ASSERT((total_mem / 4096 / 8) < biggest_chunk_size); ASSERT((total_mem / 4096 / 8) < biggest_chunk_size);
bitmap_size = total_mem / 4096 / 8 + 1; bitmap_size = total_mem / 4096 / 8 + 1;
memset(bitmap_addr, 0, bitmap_size); memset(bitmap_addr, 0xFF, bitmap_size);
free_mem = total_mem;
lock_pages(bitmap_addr, bitmap_size / 4096 + 1);
ptr = &bootboot.mmap; ptr = &bootboot.mmap;
for (uint64_t i = 0; i < mmap_entries; i++) 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++; ptr++;
} }
lock_pages(bitmap_addr, bitmap_size / 4096 + 1);
} }
bool RangeAllocator::bitmap_read(uint64_t index) bool RangeAllocator::bitmap_read(uint64_t index)

View File

@ -1,3 +1,5 @@
#define MODULE "power"
#include "power/reboot.h" #include "power/reboot.h"
#include "acpi/FADT.h" #include "acpi/FADT.h"
#include "acpi/RSDT.h" #include "acpi/RSDT.h"
@ -11,20 +13,53 @@
static void try_acpi_reboot() static void try_acpi_reboot()
{ {
kinfoln("Fetching pointer to RSDT/XSDT");
ACPI::SDTHeader* rootSDT = ACPI::GetRSDTOrXSDT(); ACPI::SDTHeader* rootSDT = ACPI::GetRSDTOrXSDT();
if (!rootSDT) return; if (!rootSDT)
if (!ACPI::ValidateSDTHeader(rootSDT)) return; {
if (strncmp(rootSDT->Signature, "RSDT", 4) != 0 && strncmp(rootSDT->Signature, "XSDT", 4) != 0) return; 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"); ACPI::FADT* fadt = (ACPI::FADT*)ACPI::FindTable(rootSDT, "FACP");
if (!fadt) return; if (!fadt)
if (!ACPI::ValidateSDTHeader(&fadt->header)) return; {
if (!(fadt->Flags & 1 << 10)) return; 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) switch (fadt->ResetReg.AddressSpace)
{ {
case ACPI::SystemIO: IO::outb(fadt->ResetReg.Address, fadt->ResetValue); break; case ACPI::SystemIO:
case ACPI::GeneralPurposeIO: IO::outb(fadt->ResetReg.Address, fadt->ResetValue); break; kinfoln("Attempting reboot via IO");
default: return; 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() static void try_kbd_reboot()

View File

@ -1,3 +1,5 @@
#define MODULE "power"
#include "power/shutdown.h" #include "power/shutdown.h"
#include "io/IO.h" #include "io/IO.h"
#include "log/Log.h" #include "log/Log.h"

View File

@ -1,5 +1,8 @@
#define MODULE "pit"
#include "scheduling/PIT.h" #include "scheduling/PIT.h"
#include "io/IO.h" #include "io/IO.h"
#include "log/Log.h"
#define PIT_CHANNEL_0_PORT 0x40 #define PIT_CHANNEL_0_PORT 0x40
@ -9,6 +12,7 @@ uint16_t divisor = 65535;
void PIT::initialize(uint64_t frequency) void PIT::initialize(uint64_t frequency)
{ {
divisor = base_frequency / 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; if (divisor < 100) divisor = 100;
IO::outb(PIT_CHANNEL_0_PORT, (uint8_t)(divisor & 0xFF)); IO::outb(PIT_CHANNEL_0_PORT, (uint8_t)(divisor & 0xFF));
IO::delay(); IO::delay();