#include #include #include #include #include #include #include #include #include #include struct kernel_context { struct rsdp *rsdp; struct xsdp *xsdp; struct rsdt *rsdt; }; struct kernel_context ctx = {0}; struct idt_entry g_idt[256] = {0}; struct idtr g_idtr = {0}; extern void exception_handler(); extern void ps2_isr(); #define MAGIC_BREAKPOINT __asm__ volatile("xchgw %bx, %bx"); void kmain(struct multiboot_info *info) { clear_screen(); // Check if the bootloader gave us the upper and lower memory if (!(info->flags & 0x1)) goto halt; // Create and load an IDT for (int i = 0; i < 32; i++) { encode_idt_entry(g_idt, i, (uint32_t)&exception_handler, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, 0x00), TRAP_GATE_32 | INT_RING0 | INT_PRESENT); } g_idtr.size = (sizeof(struct idt_entry) * 256) - 1; g_idtr.base = (uint32_t) &g_idt; asm volatile ("lidt %0" :: "m"(g_idtr)); struct rsdp *found_rsdp = acpi_locate_rsdp(); if (!found_rsdp) { printf("Failed to find RSDP signature\n"); goto halt; } printf("RSDP detected at 0x%X\n", found_rsdp); if (found_rsdp->Revision == ACPI_VER_1) { if (!acpi_validate_rsdp_checksum(found_rsdp)) { printf("RSDP has an invalid checksum\n"); goto halt; } ctx.rsdp = found_rsdp; ctx.xsdp = 0; if (!acpi_validate_sdt_checksum((struct ACPISDTHeader *)found_rsdp->RsdtAddress)) { printf("RSDT has an invalid checksum\n"); goto halt; } ctx.rsdt = (struct rsdt*)found_rsdp->RsdtAddress; printf("RSDT detected at 0x%X\n", found_rsdp->RsdtAddress); } else if (found_rsdp->Revision == ACPI_VER_OTHER) { printf("ACPI versions higher than 1.0 are not supported\n"); goto halt; } else { printf("Invalid RSDP\n"); goto halt; } printf("Using ACPI v1.0\n"); struct fadt *fadt = acpi_locate_sdt(ctx.rsdt, "FACP"); if (!fadt) { printf("Failed to find FADT\n"); goto halt; } printf("Found FADT at 0x%x\n", fadt); if (fadt->Flags & 1) printf("Legacy devices are supported.\n"); else { printf("Legacy devices are not supported. I'm too lazy to support modern devices, bye bye.\n"); goto halt; } pic_remap(PIC_1_START, PIC_2_START); // ACPI version 1.0 is so old that we assume that our PC supports the 8042 ps/2 controller initialize_8042ps2(); encode_idt_entry(g_idt, 0x21, (uint32_t)&ps2_isr, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, 0x00), INT_GATE_32 | INT_RING0 | INT_PRESENT); asm volatile ("sti" ::); struct mcfg *mcfg = acpi_locate_sdt(ctx.rsdt, "MCFG"); if (!mcfg) { printf("failed to find mcfg\n"); } else { printf("Found MCFG at 0x%x\n", mcfg); struct pci_config_space *ide = pcie_find_device(mcfg, MASS_STORAGE_CONTROLLER, IDE_INTERFACE); if (ide) printf("IDE controller detected. Program Interface: %X\n", ide->program_interface); } halt: for (;;) {} }