110 lines
3.1 KiB
C
110 lines
3.1 KiB
C
#include <multiboot.h>
|
|
#include <acpi.h>
|
|
#include <vga.h>
|
|
#include <pci.h>
|
|
#include <printf.h>
|
|
#include <strcmp.h>
|
|
#include <gdt.h>
|
|
#include <idt.h>
|
|
#include <pic8259.h>
|
|
#include <ps2.h>
|
|
|
|
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 (;;) {}
|
|
}
|