diff --git a/bin/os b/bin/os index 580a4cf..13da876 100755 Binary files a/bin/os and b/bin/os differ diff --git a/image.hdd b/image.hdd index 05858a1..4ceb3f3 100644 Binary files a/image.hdd and b/image.hdd differ diff --git a/obj/src/int.c.o b/obj/src/int.c.o index 1c2c7ea..d33f5b5 100644 Binary files a/obj/src/int.c.o and b/obj/src/int.c.o differ diff --git a/obj/src/main.c.o b/obj/src/main.c.o index 24544ff..c7b2fdb 100644 Binary files a/obj/src/main.c.o and b/obj/src/main.c.o differ diff --git a/src/acpi.c b/src/acpi.c index 7cf267c..9578db8 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -4,38 +4,14 @@ #include "../include/limine.h" // credit to dreamportdev's OSDev-Notes and the OSDev Wiki for table layouts +// #include "acpi.h" #define RSDT_SIGNATURE "RSDT" #define XSDT_SIGNATURE "XSDT" -bool rsdp_validate(const u8* data) { - if(memcmp(data, (const u8*)RSDP_SIGNATURE, 8) != 0) { - /* to debug in memcmp is broken somehow */ - if(data[0] == 'R' && data[1] == 'S' && data[2] == 'D' && data[3] == 'T' && data[4] == ' ') { - printn((const char*)data, 8); - } - return false; - } - - struct acpi_rsdp_header* head = (struct acpi_rsdp_header*)data; - size_t len = sizeof(struct acpi_rsdp_header); - len -= (head->revision == 2) * sizeof(u32) + sizeof(u64) + sizeof(u8) + sizeof(u8[3]); - u32 sum_to_zero = 0; - for(size_t i = 0; i < len; i++) { - sum_to_zero += data[i]; - } - - return (sum_to_zero & 0xFF) == 0; -} - -static bool use_xsdt = false; static struct acpi_rsdt* rsdt; -static struct acpi_xsdt* xsdt; - -struct acpi_sdt_header* acpi_get_header(size_t n) { - return (struct acpi_sdt_header*) (use_xsdt? xsdt->addrs[n] : (u64)rsdt->addrs[n]); -} struct acpi_rsdp_header* rsdp; + diff --git a/src/acpi.h b/src/acpi.h index 5cb5127..0080d1d 100644 --- a/src/acpi.h +++ b/src/acpi.h @@ -11,15 +11,21 @@ pstruct acpi_rsdp_header { u8 checksum; u8 OEMID[6]; u8 revision; - u32 addr32_depr; + /* + union { + struct acpi_rsdt* rsdt :32; + struct acpi_xsdt* xsdt :32; + } ptr; + */ + u32 ptr32; // v2 u32 len; - u64 addr; + u64 ptr64; u8 extended_checksum; u8 resv[3]; }; -struct acpi_sdt_header { +struct acpi_rsdt { u8 signature[4]; u32 len; u8 revision; @@ -29,18 +35,10 @@ struct acpi_sdt_header { u32 OEM_revision; u32 creator_id; u32 creator_revision; -}; - -struct acpi_rsdt { - // signature == "RSDT" - struct acpi_sdt_header header; - u32 addrs[]; -}; - -struct acpi_xsdt { - // signature == "XSDT" - struct acpi_rsdp_header header; - u64 addrs[]; + union { + u32 addrs32[]; + u64 addrs64[]; + }; }; extern struct acpi_rsdp_header* rsdp; diff --git a/src/apic.c b/src/apic.c new file mode 100644 index 0000000..331288a --- /dev/null +++ b/src/apic.c @@ -0,0 +1,73 @@ +#include "common.h" +#include "print.h" + +// stub of a PIC layout, we don't need the whole thing +// as we only care about initializing it to disable it +enum { + PIC_COMM_MASTER = 0x20, + PIC_COMM_SLAVE = 0x21, + PIC_DATA_MASTER = 0xA0, + PIC_DATA_SLAVE = 0xA1, +}; + +static void pic_disable() { + outb(PIC_DATA_MASTER, ~0); + outb(PIC_DATA_SLAVE, ~0); +} + +static inline u64 rdmsr(u32 msr) { + u32 hi, lo; + asm volatile ( + "rdmsr" + : "=a"(lo), "=d"(hi) + : "c"(msr) + ); + + return (((u64)hi) << 32) | (u64)lo; +} + +static inline void wrmsr(u32 msr, u64 val) { + u32 eax = (u32) val; + u32 edx = (u32) (val >> 32); + asm volatile ( + "wrmsr" + : + : "c"(msr), "a" (eax), "d" (edx) + ); +} + + +static u64 apic_base; + +u64 apic_get_local_base() { + const u8 APIC_BASE_MSR = 0x1B; + + u64 msr = rdmsr(APIC_BASE_MSR); + + return (apic_base = (msr & 0xfffff000)); +} + +static u64 apic_set_local_base(u64 base) { + const u8 APIC_BASE_MSR = 0x1B; + + wrmsr(APIC_BASE_MSR, base & 0xfffff000); + + return base & 0xfffff000; +} + +static u32* apic_reg(u32 reg) { + return (u32*) (apic_base + reg); +} + +void apic_enable() { + pic_disable(); + print("\nPIC Disabled\n"); + apic_set_local_base(apic_get_local_base()); + volatile u32* reg = apic_reg(0xF0); + print("Local Base Set\nReg 0xF0 at 0x"); + print64((u64) reg); + // set enable flag + *reg = (*reg | 0x100); + print("\nReg written\n"); +} + diff --git a/src/common.h b/src/common.h index ec1c474..a6c9664 100644 --- a/src/common.h +++ b/src/common.h @@ -23,6 +23,16 @@ static inline void INT(int n) { ); } +static inline void outb(u16 port, u8 value) { + asm volatile ("outb %0, %1" : : "a"(value), "Nd"(port)); +} +static inline void outw(u16 port, u16 value) { + asm volatile ("outw %0, %1" : : "a"(value), "Nd"(port)); +} +static inline void outd(u16 port, u32 value) { + asm volatile ("outl %0, %1" : : "a"(value), "Nd"(port)); +} + void* memcpy(void* restrict dst, const void* src, size_t n); void* memset(void* s, int c, size_t n); diff --git a/src/int.c b/src/int.c index 5364253..e76b128 100644 --- a/src/int.c +++ b/src/int.c @@ -29,8 +29,6 @@ enum INT_DESC_FLAGS { #define CODE64_SELECTOR 0x28 -static int cnt = 0; - struct int_desc idt[256]; void set_idt(u8 vect, void* handler, u8 dpl) { diff --git a/src/main.c b/src/main.c index 88d3396..bc6174a 100644 --- a/src/main.c +++ b/src/main.c @@ -168,6 +168,9 @@ void print_memmap_entry(struct limine_memmap_entry* entry) { +u32 apic_get_local_base(); +void apic_enable(); + void kmain() { if(LIMINE_BASE_REVISION_SUPPORTED(limine_base_revision) == false) { hang(); @@ -211,6 +214,31 @@ void kmain() { print("With signature: "); printn((char*)rsdp->signature, sizeof(rsdp->signature)); + + print(" v"); + print8(rsdp->revision); + print("\nRSDT at 0x"); + struct acpi_rsdt* rsdt = + (struct acpi_rsdt*)( + (rsdp->revision? rsdp->ptr64:rsdp->ptr32) + hhdm_offset + ); + print64((u64)rsdt); + print("\nSDT Signature: "); + + + printn((const char*) rsdt->signature, sizeof(rsdt->signature)); + print("\nAPIC Local Base: "); + + /* I should check cpuid to ensure its supported but it will + * be for my machines ;^) */ + /* APIC stuff */ + u32 r = 0xDEADBEEF; + r = apic_get_local_base(); + print32(r); + + apic_enable(); + + print("\nAPIC Enabled"); hang();