diff --git a/bin/os b/bin/os index 2d0b0cf..66dc152 100755 Binary files a/bin/os and b/bin/os differ diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..5cb4ba2 --- /dev/null +++ b/flake.lock @@ -0,0 +1,26 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1771205900, + "narHash": "sha256-GDTqgUN8pI8lE55wTdaFOS+xwwOOz/w055SbCLLFTqA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "805ba342d424b11deabad6e1597372a3cfb39a59", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/image.hdd b/image.hdd index e9406da..d274f2e 100644 Binary files a/image.hdd and b/image.hdd differ diff --git a/obj/src/int.c.d b/obj/src/int.c.d index efb2f36..ef52c69 100644 --- a/obj/src/int.c.d +++ b/obj/src/int.c.d @@ -1,4 +1,5 @@ -obj/src/int.c.o: src/int.c src/apic.h src/common.h src/print.h +obj/src/int.c.o: src/int.c src/apic.h src/common.h src/print.h src/kbd.h src/apic.h: src/common.h: src/print.h: +src/kbd.h: diff --git a/obj/src/int.c.o b/obj/src/int.c.o index 0784825..3f0cfdc 100644 Binary files a/obj/src/int.c.o and b/obj/src/int.c.o differ diff --git a/obj/src/main.c.d b/obj/src/main.c.d index 927ac6e..d899aa2 100644 --- a/obj/src/main.c.d +++ b/obj/src/main.c.d @@ -1,9 +1,9 @@ obj/src/main.c.o: src/main.c src/../include/limine.h src/acpi.h \ - src/common.h src/apic.h src/alloc.h src/map.h src/print.h + src/common.h src/alloc.h src/apic.h src/map.h src/print.h src/../include/limine.h: src/acpi.h: src/common.h: -src/apic.h: src/alloc.h: +src/apic.h: src/map.h: src/print.h: diff --git a/obj/src/main.c.o b/obj/src/main.c.o index c6a62a6..bc71e48 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 06a0ffb..9b392c6 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -10,8 +10,6 @@ #define RSDT_SIGNATURE "RSDT" #define XSDT_SIGNATURE "XSDT" +static struct acpi_rsdt *rsdt; -static struct acpi_rsdt* rsdt; - -struct acpi_rsdp_header* rsdp; - +struct acpi_rsdp_header *rsdp; diff --git a/src/acpi.h b/src/acpi.h index 0941e9e..5a4df06 100644 --- a/src/acpi.h +++ b/src/acpi.h @@ -2,10 +2,8 @@ #include "common.h" - #define RSDP_SIGNATURE "RSDT PTR " - pstruct acpi_rsdp_header { u8 signature[8]; u8 checksum; @@ -41,4 +39,4 @@ struct acpi_rsdt { }; }; -extern struct acpi_rsdp_header* rsdp; +extern struct acpi_rsdp_header *rsdp; diff --git a/src/alloc.c b/src/alloc.c index 9a05ddd..9016c4f 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1,47 +1,39 @@ #include "alloc.h" +#include "../include/limine.h" #include "common.h" #include "print.h" -#include "../include/limine.h" - -__attribute__((used, section(".limine_requests"))) -static volatile struct limine_memmap_request mem_req = { - .id = LIMINE_MEMMAP_REQUEST_ID, - .revision = 0, +__attribute__(( + used, + section(".limine_requests"))) static volatile struct limine_memmap_request + mem_req = { + .id = LIMINE_MEMMAP_REQUEST_ID, + .revision = 0, }; extern u32 fg, bg; -static void print_memmap_entry(struct limine_memmap_entry* entry) { +static void print_memmap_entry(struct limine_memmap_entry *entry) { u32 savefg = fg; u32 savebg = bg; - static const char* type_strs[] = { - "Usable", - "Reserved", - "ACPI Reclaimable", - "ACPI NVS", - "BAD!!!", - "Bootloader Reclaimable", - "Executable and Modules", - "Framebuffer", - "ACPI Tables", + static const char *type_strs[] = { + "Usable", + "Reserved", + "ACPI Reclaimable", + "ACPI NVS", + "BAD!!!", + "Bootloader Reclaimable", + "Executable and Modules", + "Framebuffer", + "ACPI Tables", }; - static u32 type_colors[] = { - 0x00AF00, - 0xAF1F00, - 0x7f7f00, - 0x7f7f00, - 0xFF0000, - 0x007f7f, - 0x408000, - 0x0000FF, - 0x00FF00 - }; + static u32 type_colors[] = {0x00AF00, 0xAF1F00, 0x7f7f00, 0x7f7f00, 0xFF0000, + 0x007f7f, 0x408000, 0x0000FF, 0x00FF00}; bg = type_colors[entry->type]; fg = ~bg; - + u64 addr = entry->base; u64 end = addr + entry->length; print("["); @@ -55,31 +47,29 @@ static void print_memmap_entry(struct limine_memmap_entry* entry) { bg = savebg; } - - static size_t total_pages; -static u8* alloc_start; -static u8* alloc_end; -static u8* alloc_next; -static u64* alloc_bitmap; +static u8 *alloc_start; +static u8 *alloc_end; +static u8 *alloc_next; +static u64 *alloc_bitmap; void alloc_init() { print("Initializing Page Allocator\n"); - if(!mem_req.response) { + if (!mem_req.response) { print("Failed to get memory map :(\n)"); hang(); } - + u64 largest_base = 0; size_t largest_size = 0; - for(size_t i = 0; i < mem_req.response->entry_count; i++) { - struct limine_memmap_entry* entry = mem_req.response->entries[i]; + for (size_t i = 0; i < mem_req.response->entry_count; i++) { + struct limine_memmap_entry *entry = mem_req.response->entries[i]; print_memmap_entry(entry); - - if(entry->type == LIMINE_MEMMAP_USABLE) { - if(entry->length > largest_size) { + + if (entry->type == LIMINE_MEMMAP_USABLE) { + if (entry->length > largest_size) { largest_base = entry->base; largest_size = entry->length; print("\t\\LARGEST USABLE: "); @@ -89,50 +79,47 @@ void alloc_init() { } } - if(!largest_size) { + if (!largest_size) { print("Couldn't find a free page!!!\n"); hang(); } - total_pages = largest_size / PAGE_SIZE; size_t usage_bitmap_size = (total_pages + 7) / 8; - total_pages -= (usage_bitmap_size + PAGE_SIZE-1) / PAGE_SIZE; - alloc_bitmap = (u64*)(phys_to_virt(largest_base)); - alloc_start = (u8*)(phys_to_virt(largest_base + usage_bitmap_size)); + total_pages -= (usage_bitmap_size + PAGE_SIZE - 1) / PAGE_SIZE; + alloc_bitmap = (u64 *)(phys_to_virt(largest_base)); + alloc_start = (u8 *)(phys_to_virt(largest_base + usage_bitmap_size)); alloc_next = alloc_start; - alloc_end = (u8*)(phys_to_virt(largest_base + largest_size)); + alloc_end = (u8 *)(phys_to_virt(largest_base + largest_size)); } -static size_t page(void* addr) { - return ((u8*)addr - alloc_start) / PAGE_SIZE; +static size_t page(void *addr) { + return ((u8 *)addr - alloc_start) / PAGE_SIZE; } -static void* addr(size_t page) { - return alloc_start + page*PAGE_SIZE; -} +static void *addr(size_t page) { return alloc_start + page * PAGE_SIZE; } static void usepage(size_t page) { - size_t idx = page / 64; - size_t bit = page & 63; - alloc_bitmap[idx] |= (1 << bit); + size_t idx = page / 64; + size_t bit = page & 63; + alloc_bitmap[idx] |= (1 << bit); } static void usepagerange(size_t page, size_t len) { - for(size_t i = 0; i < len; len++) { + for (size_t i = 0; i < len; len++) { usepage(i + page); } } static void unusepage(size_t page) { - size_t idx = page / 64; - size_t bit = page & 63; - alloc_bitmap[idx] &= ~(1 << bit); + size_t idx = page / 64; + size_t bit = page & 63; + alloc_bitmap[idx] &= ~(1 << bit); } static void unusepagerange(size_t page, size_t len) { - for(size_t i = 0; i < len; len++) { - unusepage(i+page); + for (size_t i = 0; i < len; len++) { + unusepage(i + page); } } @@ -140,17 +127,17 @@ static u8 getpageusage(size_t page) { return (alloc_bitmap[page / 8] >> (page & 7)) & 1; } -void dealloc(void* addr, size_t size) { +void dealloc(void *addr, size_t size) { // adjust to page size - size_t pages = (size+PAGE_SIZE-1) / PAGE_SIZE; + size_t pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; unusepagerange(page(addr), pages); } -void* alloc(size_t size) { +void *alloc(size_t size) { size_t pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; size_t page = 0; - if(pages == 0 || pages >= total_pages) { + if (pages == 0 || pages >= total_pages) { print("Too many or too few pages: "); print8(pages); print("\n"); @@ -162,30 +149,30 @@ void* alloc(size_t size) { print(" consecutive pages\n"); size_t consecutive = 0; - for(size_t i = 0; i < total_pages/64; i++) { + for (size_t i = 0; i < total_pages / 64; i++) { u64 word = alloc_bitmap[i]; - if(word == 0) { - if(!consecutive) + if (word == 0) { + if (!consecutive) page = i * 64; consecutive += 64; - if(consecutive >= pages) { + if (consecutive >= pages) { usepagerange(page, pages); return addr(page); } continue; } - if(word == ~0ULL) { + if (word == ~0ULL) { consecutive = 0; page = -1; } - for(size_t bit = 0; bit < 64; bit++) { - if((word & (1ULL << bit)) == 0) { - if(!consecutive) + for (size_t bit = 0; bit < 64; bit++) { + if ((word & (1ULL << bit)) == 0) { + if (!consecutive) page = i * 64 + bit; - if(++consecutive >= pages) { + if (++consecutive >= pages) { usepagerange(page, pages); return addr(page); } @@ -198,4 +185,3 @@ void* alloc(size_t size) { return NULL; } - diff --git a/src/alloc.h b/src/alloc.h index 29d7a6e..b841650 100644 --- a/src/alloc.h +++ b/src/alloc.h @@ -3,14 +3,11 @@ static const size_t PAGE_SIZE = (1 << 12); void alloc_init(); -void* alloc(size_t size); -void dealloc(void* arg, size_t size); +void *alloc(size_t size); +void dealloc(void *arg, size_t size); -static inline u64 virt_to_phys(void* virt) { - return (u64)virt - hhdm_offset; +static inline u64 virt_to_phys(void *virt) { return (u64)virt - hhdm_offset; } + +static inline void *phys_to_virt(u64 phys) { + return (void *)(phys + hhdm_offset); } - -static inline void* phys_to_virt(u64 phys) { - return (void*)(phys + hhdm_offset); -} - diff --git a/src/apic.c b/src/apic.c index 0e9e38c..d00fdaa 100644 --- a/src/apic.c +++ b/src/apic.c @@ -1,6 +1,6 @@ #include "common.h" -#include "print.h" #include "map.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 @@ -11,7 +11,7 @@ enum { PIC_DATA_SLAVE = 0xA1, }; -#define IOAPIC_REG_REDIR(n) (0x10 + 2*(n)) +#define IOAPIC_REG_REDIR(n) (0x10 + 2 * (n)) enum { IOAPIC_REG_SELECT = 0x00, @@ -27,7 +27,6 @@ enum { #define IOAPIC_ACTIVE_LOW (1 << 13) #define IOAPIC_ACTIVE_HIGH (0 << 13) - static void pic_init() { // Start initialization sequence outb(PIC_COMM_MASTER, 0x11); // ICW1: Initialize in cascading mode @@ -35,10 +34,10 @@ static void pic_init() { outb(PIC_DATA_MASTER, 0x04); // ICW3: Slave PIC at IRQ2 outb(PIC_DATA_MASTER, 0x01); // ICW4: 8086/88 (MCS-80 compatible) - outb(PIC_COMM_SLAVE, 0x11); // ICW1: Initialize slave PIC - outb(PIC_DATA_SLAVE, 0x28); // ICW2: Slave PIC vector offset - outb(PIC_DATA_SLAVE, 0x02); // ICW3: It's connected to master PIC - outb(PIC_DATA_SLAVE, 0x01); // ICW4: 8086/88 mode + outb(PIC_COMM_SLAVE, 0x11); // ICW1: Initialize slave PIC + outb(PIC_DATA_SLAVE, 0x28); // ICW2: Slave PIC vector offset + outb(PIC_DATA_SLAVE, 0x02); // ICW3: It's connected to master PIC + outb(PIC_DATA_SLAVE, 0x01); // ICW4: 8086/88 mode // Mask all interrupts outb(PIC_DATA_MASTER, 0xFF); @@ -53,26 +52,17 @@ static void pic_disable() { static inline u64 rdmsr(u32 msr) { u32 hi, lo; - asm volatile ( - "rdmsr" - : "=a"(lo), "=d"(hi) - : "c"(msr) - ); + 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) - ); + 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() { @@ -96,12 +86,10 @@ static u64 apic_set_local_base(u64 base) { return base & 0xfffff000; } -u32* apic_reg(u32 reg) { - return (u32*) (hhdm_offset + apic_base + reg); -} +u32 *apic_reg(u32 reg) { return (u32 *)(hhdm_offset + apic_base + reg); } void send_eoi() { - volatile u32* reg= apic_reg(0xB0); + volatile u32 *reg = apic_reg(0xB0); *reg = 0; } @@ -111,14 +99,14 @@ void apic_enable() { apic_set_local_base(apic_get_local_base()); - if(!map_mmio((u64)apic_base, 1<<12)) { + if (!map_mmio((u64)apic_base, 1 << 12)) { print("Failed to map APIC registers!\n"); hang(); } - - volatile u32* spurious = apic_reg(0xF0); + + volatile u32 *spurious = apic_reg(0xF0); print("Reg 0xF0 at 0x"); - print64((u64) spurious); + print64((u64)spurious); print("\nSpurious: "); print32(*spurious); // set enable flag @@ -128,23 +116,23 @@ void apic_enable() { print("\n"); // TPR = 0 (accept all interrupts) - volatile u32* tpr = apic_reg(0x80); + volatile u32 *tpr = apic_reg(0x80); *tpr = 0; // Mask all LVT antries except LINT0 (0x21) - - volatile u32* timer = apic_reg(0x320); + + volatile u32 *timer = apic_reg(0x320); *timer = (1 << 16); - volatile u32* LINT0 = apic_reg(0x350); + volatile u32 *LINT0 = apic_reg(0x350); *LINT0 = (7 << 8); -// *LINT0 = (1 << 16); - volatile u32* LINT1 = apic_reg(0x360); + // *LINT0 = (1 << 16); + volatile u32 *LINT1 = apic_reg(0x360); *LINT1 = (1 << 16); - volatile u32* Error = apic_reg(0x370); + volatile u32 *Error = apic_reg(0x370); *Error = (1 << 16); } -static volatile u32* ioapic_base; +static volatile u32 *ioapic_base; void ioapic_write(u8 reg, u32 value) { ioapic_base[IOAPIC_REG_SELECT / 4] = reg; @@ -157,62 +145,62 @@ u32 ioapic_read(u8 reg) { } void ioapic_init() { - // simply assume it is at the default address - ioapic_base = map_mmio(0xFEC00000, 4096); - print("IOAPIC BASE: "); - print64((u64)ioapic_base); - print("\nIOAPIC Version:"); - ioapic_base[0] = 0x01; - print32(ioapic_base[4]); - print("\n"); + // simply assume it is at the default address + ioapic_base = map_mmio(0xFEC00000, 4096); + print("IOAPIC BASE: "); + print64((u64)ioapic_base); + print("\nIOAPIC Version:"); + ioapic_base[0] = 0x01; + print32(ioapic_base[4]); + print("\n"); - // mask all IRQs - for(size_t i = 0; i < 24; i++) { - u8 vect = 0x20 + i; - u32 low = vect | IOAPIC_MASKED | IOAPIC_DST_PHYS | IOAPIC_EDGE_TRIGG | IOAPIC_ACTIVE_HIGH; - u32 high = 0; - - ioapic_write(0x10 + i*2, low); - ioapic_write(0x10 + i*2 + 1, high); - } - - // setup keyboard by selecting IRQ1 - u8 irq = 1; - u8 vect = 0x21; - u8 cpu = 0; - - u32 low = ioapic_read(IOAPIC_REG_REDIR(irq)); - u32 high = ioapic_read(IOAPIC_REG_REDIR(irq)+1); + // mask all IRQs + for (size_t i = 0; i < 24; i++) { + u8 vect = 0x20 + i; + u32 low = vect | IOAPIC_MASKED | IOAPIC_DST_PHYS | IOAPIC_EDGE_TRIGG | + IOAPIC_ACTIVE_HIGH; + u32 high = 0; - - print("Current redirection for IRQ"); - print8(irq); - print(": "); - print32(low); - print(" "); - print32(high); - print("\n"); - - // Configure keyboard - UNMASKED (no IOAPIC_MASKED bit!) - low = vect | IOAPIC_DST_PHYS | IOAPIC_EDGE_TRIGG | IOAPIC_ACTIVE_HIGH; - high = (cpu << 24); - - ioapic_write(IOAPIC_REG_REDIR(irq), low); - ioapic_write(IOAPIC_REG_REDIR(irq)+1, high); - - low = ioapic_read(IOAPIC_REG_REDIR(irq)); - high = ioapic_read(IOAPIC_REG_REDIR(irq)+1); - // Verify it worked - print("Current redirection for IRQ"); - print8(irq); - print(": "); - print32(low); - print(" "); - print32(high); - print("\n"); - if (low & IOAPIC_MASKED) { - print(" [STILL MASKED (BAD)]\n"); - } else { - print(" [UNMASKED (GOOD)]\n"); - } + ioapic_write(0x10 + i * 2, low); + ioapic_write(0x10 + i * 2 + 1, high); + } + + // setup keyboard by selecting IRQ1 + u8 irq = 1; + u8 vect = 0x21; + u8 cpu = 0; + + u32 low = ioapic_read(IOAPIC_REG_REDIR(irq)); + u32 high = ioapic_read(IOAPIC_REG_REDIR(irq) + 1); + + print("Current redirection for IRQ"); + print8(irq); + print(": "); + print32(low); + print(" "); + print32(high); + print("\n"); + + // Configure keyboard - UNMASKED (no IOAPIC_MASKED bit!) + low = vect | IOAPIC_DST_PHYS | IOAPIC_EDGE_TRIGG | IOAPIC_ACTIVE_HIGH; + high = (cpu << 24); + + ioapic_write(IOAPIC_REG_REDIR(irq), low); + ioapic_write(IOAPIC_REG_REDIR(irq) + 1, high); + + low = ioapic_read(IOAPIC_REG_REDIR(irq)); + high = ioapic_read(IOAPIC_REG_REDIR(irq) + 1); + // Verify it worked + print("Current redirection for IRQ"); + print8(irq); + print(": "); + print32(low); + print(" "); + print32(high); + print("\n"); + if (low & IOAPIC_MASKED) { + print(" [STILL MASKED (BAD)]\n"); + } else { + print(" [UNMASKED (GOOD)]\n"); + } } diff --git a/src/apic.h b/src/apic.h index d9efe8c..2b671a1 100644 --- a/src/apic.h +++ b/src/apic.h @@ -8,4 +8,4 @@ void send_eoi(); void ioapic_write(u8 reg, u32 value); u32 ioapic_read(u8 reg); void ioapic_init(); -u32* apic_reg(u32 reg); +u32 *apic_reg(u32 reg); diff --git a/src/common.h b/src/common.h index 83977ab..829193e 100644 --- a/src/common.h +++ b/src/common.h @@ -6,54 +6,46 @@ #define pstruct struct __attribute__((packed)) -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef int8_t i8; -typedef int16_t i16; -typedef int32_t i32; -typedef int64_t i64; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; -static inline void INT(int n) { - asm volatile ( - "int %0" - : - : "i"(n) - ); -} +static inline void INT(int n) { asm volatile("int %0" : : "i"(n)); } static inline void outb(u16 port, u8 value) { - asm volatile ("outb %0, %1" : : "a"(value), "Nd"(port)); + 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)); + 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)); + asm volatile("outl %0, %1" : : "a"(value), "Nd"(port)); } static inline u8 inb(u16 port) { - u8 value; - asm volatile ("inb %w1, %b0" : "=a"(value) : "Nd"(port) : "memory"); - return value; + u8 value; + asm volatile("inb %w1, %b0" : "=a"(value) : "Nd"(port) : "memory"); + return value; } static inline u16 inw(u16 port) { - u16 value; - asm volatile ("inw %w1, %b0" : "=a"(value) : "Nd"(port) : "memory"); - return value; + u16 value; + asm volatile("inw %w1, %b0" : "=a"(value) : "Nd"(port) : "memory"); + return value; } static inline u32 ind(u16 port) { - u32 value; - asm volatile ("ind %w1, %b0" : "=a"(value) : "Nd"(port) : "memory"); - return value; + u32 value; + asm volatile("ind %w1, %b0" : "=a"(value) : "Nd"(port) : "memory"); + return value; } - - -void* memcpy(void* dst, const void* src, size_t n); -void* memset(void* s, int c, size_t n); -void* memmove(void* dst, const void* src, size_t n); -int memcmp(const void* s1, const void* s2, size_t n); +void *memcpy(void *dst, const void *src, size_t n); +void *memset(void *s, int c, size_t n); +void *memmove(void *dst, const void *src, size_t n); +int memcmp(const void *s1, const void *s2, size_t n); void hang(); extern u64 hhdm_offset; diff --git a/src/etc.h b/src/etc.h index 5eb4847..81d652f 100644 --- a/src/etc.h +++ b/src/etc.h @@ -2,11 +2,9 @@ #include "common.h" -void* memcpy(void* restrict dst, const void* src, size_t n); -void* memset(void* s, int c, size_t n); -void* memmove(void* dst, const void* src, size_t n); -int memcmp(const void* s1, const void* s2, size_t n); +void *memcpy(void *restrict dst, const void *src, size_t n); +void *memset(void *s, int c, size_t n); +void *memmove(void *dst, const void *src, size_t n); +int memcmp(const void *s1, const void *s2, size_t n); -static int isprint(int ch) { - return (u8)(ch-' ') <= ('~'-' '); -} +static int isprint(int ch) { return (u8)(ch - ' ') <= ('~' - ' '); } diff --git a/src/font.h b/src/font.h index 142a3fa..a4c3e9f 100644 --- a/src/font.h +++ b/src/font.h @@ -25,100 +25,20 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define FONT_HEIGHT 6 static u32 font[] = { - 0x0, - 0x8021084, - 0x294a, - 0x15f52bea, - 0x8fa38be, - 0x33a22e60, - 0x2e94d8a2, - 0x1084, - 0x10421088, - 0x4421082, - 0xa23880, - 0x471000, - 0x4420000, - 0x70000, - 0xc600000, - 0x2222200, - 0x1d3ad72e, - 0x3e4214c4, - 0x3e22222e, - 0x1d18320f, - 0x210fc888, - 0x1d183c3f, - 0x1d17844c, - 0x222221f, - 0x1d18ba2e, - 0x210f463e, - 0xc6018c0, - 0x4401000, - 0x10411100, - 0xe03800, - 0x4441040, - 0x802322e, - 0x3c1ef62e, - 0x231fc544, - 0x1f18be2f, - 0x3c10862e, - 0x1f18c62f, - 0x3e10bc3f, - 0x210bc3f, - 0x1d1c843e, - 0x2318fe31, - 0x3e42109f, - 0xc94211f, - 0x23149d31, - 0x3e108421, - 0x231ad6bb, - 0x239cd671, - 0x1d18c62e, - 0x217c62f, - 0x30eac62e, - 0x2297c62f, - 0x1d141a2e, - 0x842109f, - 0x1d18c631, - 0x8454631, - 0x375ad631, - 0x22a21151, - 0x8421151, - 0x3e22221f, - 0x1842108c, - 0x20820820, - 0xc421086, - 0x4544, - 0x3e000000, - 0x82, - 0x1c97b000, - 0xe949c21, - 0x1c10b800, - 0x1c94b908, - 0x1c549800, - 0x2211c4c, - 0xe87252e, - 0x12949c21, - 0xc210040, - 0x6210802, - 0x12519521, - 0xc210842, - 0x235aac00, - 0x12949c00, - 0xc949800, - 0x213a526, - 0x3087252e, - 0x2149800, - 0xe837000, - 0xc213c42, - 0xe94a400, - 0x464a400, - 0x155ac400, - 0x36426c00, - 0xe872529, - 0x1e223c00, - 0x1843188c, - 0x8421084, - 0xc463086, - 0x6d800, - 0x3fffffff, + 0x0, 0x8021084, 0x294a, 0x15f52bea, 0x8fa38be, 0x33a22e60, + 0x2e94d8a2, 0x1084, 0x10421088, 0x4421082, 0xa23880, 0x471000, + 0x4420000, 0x70000, 0xc600000, 0x2222200, 0x1d3ad72e, 0x3e4214c4, + 0x3e22222e, 0x1d18320f, 0x210fc888, 0x1d183c3f, 0x1d17844c, 0x222221f, + 0x1d18ba2e, 0x210f463e, 0xc6018c0, 0x4401000, 0x10411100, 0xe03800, + 0x4441040, 0x802322e, 0x3c1ef62e, 0x231fc544, 0x1f18be2f, 0x3c10862e, + 0x1f18c62f, 0x3e10bc3f, 0x210bc3f, 0x1d1c843e, 0x2318fe31, 0x3e42109f, + 0xc94211f, 0x23149d31, 0x3e108421, 0x231ad6bb, 0x239cd671, 0x1d18c62e, + 0x217c62f, 0x30eac62e, 0x2297c62f, 0x1d141a2e, 0x842109f, 0x1d18c631, + 0x8454631, 0x375ad631, 0x22a21151, 0x8421151, 0x3e22221f, 0x1842108c, + 0x20820820, 0xc421086, 0x4544, 0x3e000000, 0x82, 0x1c97b000, + 0xe949c21, 0x1c10b800, 0x1c94b908, 0x1c549800, 0x2211c4c, 0xe87252e, + 0x12949c21, 0xc210040, 0x6210802, 0x12519521, 0xc210842, 0x235aac00, + 0x12949c00, 0xc949800, 0x213a526, 0x3087252e, 0x2149800, 0xe837000, + 0xc213c42, 0xe94a400, 0x464a400, 0x155ac400, 0x36426c00, 0xe872529, + 0x1e223c00, 0x1843188c, 0x8421084, 0xc463086, 0x6d800, 0x3fffffff, }; diff --git a/src/int.c b/src/int.c index efee74f..2747b6f 100644 --- a/src/int.c +++ b/src/int.c @@ -3,10 +3,9 @@ #include "apic.h" // for debugging #include "print.h" - +#include "kbd.h" #include "common.h" - // for trap debugging u64 dbg_var = 0; @@ -21,26 +20,25 @@ pstruct int_desc { }; enum INT_DESC_FLAGS { - ID_GATE_INT = 0b00001110, + ID_GATE_INT = 0b00001110, ID_GATE_TRAP = 0b00001111, - ID_DPL = 0b00100000, - ID_PRESENT = 0b10000000, + ID_DPL = 0b00100000, + ID_PRESENT = 0b10000000, }; - #define CODE64_SELECTOR 0x28 struct int_desc idt[256]; -void set_idt(u8 vect, void* handler, u8 dpl) { - struct int_desc* ent = &idt[vect]; - u64 addr = (u64) handler; +void set_idt(u8 vect, void *handler, u8 dpl) { + struct int_desc *ent = &idt[vect]; + u64 addr = (u64)handler; ent->addr_low = addr & 0xFFFF; ent->addr_mid = (addr >> 16) & 0xFFFF; ent->addr_high = addr >> 32; ent->selector = CODE64_SELECTOR; - ent->flags = ID_GATE_INT | dpl*ID_DPL | ID_PRESENT; + ent->flags = ID_GATE_INT | dpl * ID_DPL | ID_PRESENT; ent->ist = 0; } @@ -49,15 +47,15 @@ pstruct idtr { u64 base; }; -#define IDTR_LIMIT (sizeof(struct int_desc)*256 - 1) +#define IDTR_LIMIT (sizeof(struct int_desc) * 256 - 1) -void load_idt(void* addr) { - struct idtr ir = (struct idtr) { - .limit = IDTR_LIMIT, - .base = (u64) addr, +void load_idt(void *addr) { + struct idtr ir = (struct idtr){ + .limit = IDTR_LIMIT, + .base = (u64)addr, }; - asm volatile("lidt %0" :: "m"(ir)); + asm volatile("lidt %0" ::"m"(ir)); } extern void draw(u8 vect); @@ -75,204 +73,226 @@ struct cpu_ctx { u64 iret_ss; }; -struct cpu_ctx* interrupt_dispatch(struct cpu_ctx* ctx) { +struct cpu_ctx *interrupt_dispatch(struct cpu_ctx *ctx) { print("\n[IRQ "); print8(ctx->vect); print("] with message: "); print64(dbg_var); print("\n"); - - send_eoi(); + if(ctx->vect == 0x21) { + kbd_handler(); + } return ctx; } -__attribute__((naked)) -void int_stub(void) { - __asm__ volatile ( - "push %%rax\n" - "push %%rbx\n" - "push %%rcx\n" - "push %%rdx\n" - "push %%rsi\n" - "push %%rdi\n" - "push %%r8\n" - "push %%r9\n" - "push %%r10\n" - "push %%r11\n" - "push %%r12\n" - "push %%r13\n" - "push %%r14\n" - "push %%r15\n" - "mov %%rsp, %%rdi\n" - "call interrupt_dispatch\n" - "mov %%rax, %%rsp\n" - "pop %%r15\n" - "pop %%r14\n" - "pop %%r13\n" - "pop %%r12\n" - "pop %%r11\n" - "pop %%r10\n" - "pop %%r9\n" - "pop %%r8\n" - "pop %%rdi\n" - "pop %%rsi\n" - "pop %%rdx\n" - "pop %%rcx\n" - "pop %%rbx\n" - "pop %%rax\n" - "add $16, %%rsp\n" - "iretq\n" - : - : - : "memory" - ); +__attribute__((naked)) void int_stub(void) { + __asm__ volatile("push %%rax\n" + "push %%rbx\n" + "push %%rcx\n" + "push %%rdx\n" + "push %%rsi\n" + "push %%rdi\n" + "push %%r8\n" + "push %%r9\n" + "push %%r10\n" + "push %%r11\n" + "push %%r12\n" + "push %%r13\n" + "push %%r14\n" + "push %%r15\n" + "mov %%rsp, %%rdi\n" + "call interrupt_dispatch\n" + "mov %%rax, %%rsp\n" + "pop %%r15\n" + "pop %%r14\n" + "pop %%r13\n" + "pop %%r12\n" + "pop %%r11\n" + "pop %%r10\n" + "pop %%r9\n" + "pop %%r8\n" + "pop %%rdi\n" + "pop %%rsi\n" + "pop %%rdx\n" + "pop %%rcx\n" + "pop %%rbx\n" + "pop %%rax\n" + "add $16, %%rsp\n" + "iretq\n" + : + : + : "memory"); } // Macro to generate interrupt stubs without error codes (push dummy 0) -#define ISR_NO_ERR(num) \ - __attribute__((naked)) void isr##num(void) { \ - asm volatile( \ - "push $0\n" \ - "push %0\n" \ - "jmp int_stub\n" \ - : : "i"(num)); \ +#define ISR_NO_ERR(num) \ + __attribute__((naked)) void isr##num(void) { \ + asm volatile("push $0\n" \ + "push %0\n" \ + "jmp int_stub\n" \ + : \ + : "i"(num)); \ } // Macro to generate interrupt stubs with error codes -#define ISR_ERR(num) \ - __attribute__((naked)) void isr##num(void) { \ - asm volatile( \ - "push %0\n" \ - "jmp int_stub\n" \ - : : "i"(num)); \ +#define ISR_ERR(num) \ + __attribute__((naked)) void isr##num(void) { \ + asm volatile("push %0\n" \ + "jmp int_stub\n" \ + : \ + : "i"(num)); \ } // CPU exceptions (0-31) -ISR_NO_ERR(0) // Divide by zero -ISR_NO_ERR(1) // Debug -ISR_NO_ERR(2) // NMI -ISR_NO_ERR(3) // Breakpoint -ISR_NO_ERR(4) // Overflow -ISR_NO_ERR(5) // Bound range exceeded -ISR_NO_ERR(6) // Invalid opcode -ISR_NO_ERR(7) // Device not available -ISR_ERR(8) // Double fault (pushes error code) -ISR_NO_ERR(9) // Coprocessor segment overrun -ISR_ERR(10) // Invalid TSS (pushes error code) -ISR_ERR(11) // Segment not present (pushes error code) -ISR_ERR(12) // Stack-segment fault (pushes error code) -ISR_ERR(13) // General protection fault (pushes error code) -ISR_ERR(14) // Page fault (pushes error code) -ISR_NO_ERR(15) // Reserved -ISR_NO_ERR(16) // x87 FPU error -ISR_ERR(17) // Alignment check (pushes error code) -ISR_NO_ERR(18) // Machine check -ISR_NO_ERR(19) // SIMD floating-point exception -ISR_NO_ERR(20) // Virtualization exception -ISR_ERR(21) // Control protection exception (pushes error code) -ISR_NO_ERR(22) // Reserved -ISR_NO_ERR(23) // Reserved -ISR_NO_ERR(24) // Reserved -ISR_NO_ERR(25) // Reserved -ISR_NO_ERR(26) // Reserved -ISR_NO_ERR(27) // Reserved -ISR_NO_ERR(28) // Reserved -ISR_NO_ERR(29) // Reserved -ISR_ERR(30) // Security exception (pushes error code) -ISR_NO_ERR(31) // Reserved +ISR_NO_ERR(0) // Divide by zero +ISR_NO_ERR(1) // Debug +ISR_NO_ERR(2) // NMI +ISR_NO_ERR(3) // Breakpoint +ISR_NO_ERR(4) // Overflow +ISR_NO_ERR(5) // Bound range exceeded +ISR_NO_ERR(6) // Invalid opcode +ISR_NO_ERR(7) // Device not available +ISR_ERR(8) // Double fault (pushes error code) +ISR_NO_ERR(9) // Coprocessor segment overrun +ISR_ERR(10) // Invalid TSS (pushes error code) +ISR_ERR(11) // Segment not present (pushes error code) +ISR_ERR(12) // Stack-segment fault (pushes error code) +ISR_ERR(13) // General protection fault (pushes error code) +ISR_ERR(14) // Page fault (pushes error code) +ISR_NO_ERR(15) // Reserved +ISR_NO_ERR(16) // x87 FPU error +ISR_ERR(17) // Alignment check (pushes error code) +ISR_NO_ERR(18) // Machine check +ISR_NO_ERR(19) // SIMD floating-point exception +ISR_NO_ERR(20) // Virtualization exception +ISR_ERR(21) // Control protection exception (pushes error code) +ISR_NO_ERR(22) // Reserved +ISR_NO_ERR(23) // Reserved +ISR_NO_ERR(24) // Reserved +ISR_NO_ERR(25) // Reserved +ISR_NO_ERR(26) // Reserved +ISR_NO_ERR(27) // Reserved +ISR_NO_ERR(28) // Reserved +ISR_NO_ERR(29) // Reserved +ISR_ERR(30) // Security exception (pushes error code) +ISR_NO_ERR(31) // Reserved // IRQs and user-defined interrupts (32-255) -ISR_NO_ERR(32) ISR_NO_ERR(33) ISR_NO_ERR(34) ISR_NO_ERR(35) -ISR_NO_ERR(36) ISR_NO_ERR(37) ISR_NO_ERR(38) ISR_NO_ERR(39) -ISR_NO_ERR(40) ISR_NO_ERR(41) ISR_NO_ERR(42) ISR_NO_ERR(43) -ISR_NO_ERR(44) ISR_NO_ERR(45) ISR_NO_ERR(46) ISR_NO_ERR(47) -ISR_NO_ERR(48) ISR_NO_ERR(49) ISR_NO_ERR(50) ISR_NO_ERR(51) -ISR_NO_ERR(52) ISR_NO_ERR(53) ISR_NO_ERR(54) ISR_NO_ERR(55) -ISR_NO_ERR(56) ISR_NO_ERR(57) ISR_NO_ERR(58) ISR_NO_ERR(59) -ISR_NO_ERR(60) ISR_NO_ERR(61) ISR_NO_ERR(62) ISR_NO_ERR(63) -ISR_NO_ERR(64) ISR_NO_ERR(65) ISR_NO_ERR(66) ISR_NO_ERR(67) -ISR_NO_ERR(68) ISR_NO_ERR(69) ISR_NO_ERR(70) ISR_NO_ERR(71) -ISR_NO_ERR(72) ISR_NO_ERR(73) ISR_NO_ERR(74) ISR_NO_ERR(75) -ISR_NO_ERR(76) ISR_NO_ERR(77) ISR_NO_ERR(78) ISR_NO_ERR(79) -ISR_NO_ERR(80) ISR_NO_ERR(81) ISR_NO_ERR(82) ISR_NO_ERR(83) -ISR_NO_ERR(84) ISR_NO_ERR(85) ISR_NO_ERR(86) ISR_NO_ERR(87) -ISR_NO_ERR(88) ISR_NO_ERR(89) ISR_NO_ERR(90) ISR_NO_ERR(91) -ISR_NO_ERR(92) ISR_NO_ERR(93) ISR_NO_ERR(94) ISR_NO_ERR(95) -ISR_NO_ERR(96) ISR_NO_ERR(97) ISR_NO_ERR(98) ISR_NO_ERR(99) -ISR_NO_ERR(100) ISR_NO_ERR(101) ISR_NO_ERR(102) ISR_NO_ERR(103) -ISR_NO_ERR(104) ISR_NO_ERR(105) ISR_NO_ERR(106) ISR_NO_ERR(107) -ISR_NO_ERR(108) ISR_NO_ERR(109) ISR_NO_ERR(110) ISR_NO_ERR(111) -ISR_NO_ERR(112) ISR_NO_ERR(113) ISR_NO_ERR(114) ISR_NO_ERR(115) -ISR_NO_ERR(116) ISR_NO_ERR(117) ISR_NO_ERR(118) ISR_NO_ERR(119) -ISR_NO_ERR(120) ISR_NO_ERR(121) ISR_NO_ERR(122) ISR_NO_ERR(123) -ISR_NO_ERR(124) ISR_NO_ERR(125) ISR_NO_ERR(126) ISR_NO_ERR(127) -ISR_NO_ERR(128) ISR_NO_ERR(129) ISR_NO_ERR(130) ISR_NO_ERR(131) -ISR_NO_ERR(132) ISR_NO_ERR(133) ISR_NO_ERR(134) ISR_NO_ERR(135) -ISR_NO_ERR(136) ISR_NO_ERR(137) ISR_NO_ERR(138) ISR_NO_ERR(139) -ISR_NO_ERR(140) ISR_NO_ERR(141) ISR_NO_ERR(142) ISR_NO_ERR(143) -ISR_NO_ERR(144) ISR_NO_ERR(145) ISR_NO_ERR(146) ISR_NO_ERR(147) -ISR_NO_ERR(148) ISR_NO_ERR(149) ISR_NO_ERR(150) ISR_NO_ERR(151) -ISR_NO_ERR(152) ISR_NO_ERR(153) ISR_NO_ERR(154) ISR_NO_ERR(155) -ISR_NO_ERR(156) ISR_NO_ERR(157) ISR_NO_ERR(158) ISR_NO_ERR(159) -ISR_NO_ERR(160) ISR_NO_ERR(161) ISR_NO_ERR(162) ISR_NO_ERR(163) -ISR_NO_ERR(164) ISR_NO_ERR(165) ISR_NO_ERR(166) ISR_NO_ERR(167) -ISR_NO_ERR(168) ISR_NO_ERR(169) ISR_NO_ERR(170) ISR_NO_ERR(171) -ISR_NO_ERR(172) ISR_NO_ERR(173) ISR_NO_ERR(174) ISR_NO_ERR(175) -ISR_NO_ERR(176) ISR_NO_ERR(177) ISR_NO_ERR(178) ISR_NO_ERR(179) -ISR_NO_ERR(180) ISR_NO_ERR(181) ISR_NO_ERR(182) ISR_NO_ERR(183) -ISR_NO_ERR(184) ISR_NO_ERR(185) ISR_NO_ERR(186) ISR_NO_ERR(187) -ISR_NO_ERR(188) ISR_NO_ERR(189) ISR_NO_ERR(190) ISR_NO_ERR(191) -ISR_NO_ERR(192) ISR_NO_ERR(193) ISR_NO_ERR(194) ISR_NO_ERR(195) -ISR_NO_ERR(196) ISR_NO_ERR(197) ISR_NO_ERR(198) ISR_NO_ERR(199) -ISR_NO_ERR(200) ISR_NO_ERR(201) ISR_NO_ERR(202) ISR_NO_ERR(203) -ISR_NO_ERR(204) ISR_NO_ERR(205) ISR_NO_ERR(206) ISR_NO_ERR(207) -ISR_NO_ERR(208) ISR_NO_ERR(209) ISR_NO_ERR(210) ISR_NO_ERR(211) -ISR_NO_ERR(212) ISR_NO_ERR(213) ISR_NO_ERR(214) ISR_NO_ERR(215) -ISR_NO_ERR(216) ISR_NO_ERR(217) ISR_NO_ERR(218) ISR_NO_ERR(219) -ISR_NO_ERR(220) ISR_NO_ERR(221) ISR_NO_ERR(222) ISR_NO_ERR(223) -ISR_NO_ERR(224) ISR_NO_ERR(225) ISR_NO_ERR(226) ISR_NO_ERR(227) -ISR_NO_ERR(228) ISR_NO_ERR(229) ISR_NO_ERR(230) ISR_NO_ERR(231) -ISR_NO_ERR(232) ISR_NO_ERR(233) ISR_NO_ERR(234) ISR_NO_ERR(235) -ISR_NO_ERR(236) ISR_NO_ERR(237) ISR_NO_ERR(238) ISR_NO_ERR(239) -ISR_NO_ERR(240) ISR_NO_ERR(241) ISR_NO_ERR(242) ISR_NO_ERR(243) -ISR_NO_ERR(244) ISR_NO_ERR(245) ISR_NO_ERR(246) ISR_NO_ERR(247) -ISR_NO_ERR(248) ISR_NO_ERR(249) ISR_NO_ERR(250) ISR_NO_ERR(251) -ISR_NO_ERR(252) ISR_NO_ERR(253) ISR_NO_ERR(254) ISR_NO_ERR(255) +ISR_NO_ERR(32) +ISR_NO_ERR(33) ISR_NO_ERR(34) ISR_NO_ERR(35) ISR_NO_ERR(36) ISR_NO_ERR(37) ISR_NO_ERR( + 38) ISR_NO_ERR(39) ISR_NO_ERR(40) ISR_NO_ERR(41) ISR_NO_ERR(42) ISR_NO_ERR(43) + ISR_NO_ERR(44) ISR_NO_ERR(45) ISR_NO_ERR(46) ISR_NO_ERR(47) ISR_NO_ERR( + 48) ISR_NO_ERR(49) ISR_NO_ERR(50) ISR_NO_ERR(51) ISR_NO_ERR(52) ISR_NO_ERR(53) + ISR_NO_ERR(54) ISR_NO_ERR(55) ISR_NO_ERR(56) ISR_NO_ERR(57) ISR_NO_ERR( + 58) ISR_NO_ERR(59) ISR_NO_ERR(60) ISR_NO_ERR(61) ISR_NO_ERR(62) + ISR_NO_ERR(63) ISR_NO_ERR(64) ISR_NO_ERR(65) ISR_NO_ERR(66) ISR_NO_ERR( + 67) ISR_NO_ERR(68) ISR_NO_ERR(69) ISR_NO_ERR(70) ISR_NO_ERR(71) + ISR_NO_ERR(72) ISR_NO_ERR(73) ISR_NO_ERR(74) ISR_NO_ERR(75) ISR_NO_ERR( + 76) ISR_NO_ERR(77) ISR_NO_ERR(78) ISR_NO_ERR(79) ISR_NO_ERR(80) + ISR_NO_ERR(81) ISR_NO_ERR(82) ISR_NO_ERR(83) ISR_NO_ERR( + 84) ISR_NO_ERR(85) ISR_NO_ERR(86) ISR_NO_ERR(87) + ISR_NO_ERR(88) ISR_NO_ERR(89) ISR_NO_ERR(90) ISR_NO_ERR( + 91) ISR_NO_ERR(92) ISR_NO_ERR(93) ISR_NO_ERR(94) + ISR_NO_ERR(95) ISR_NO_ERR(96) ISR_NO_ERR(97) ISR_NO_ERR( + 98) ISR_NO_ERR(99) ISR_NO_ERR(100) ISR_NO_ERR(101) + ISR_NO_ERR(102) ISR_NO_ERR(103) ISR_NO_ERR( + 104) ISR_NO_ERR(105) ISR_NO_ERR(106) + ISR_NO_ERR(107) ISR_NO_ERR(108) ISR_NO_ERR( + 109) ISR_NO_ERR(110) ISR_NO_ERR(111) + ISR_NO_ERR(112) ISR_NO_ERR(113) ISR_NO_ERR( + 114) ISR_NO_ERR(115) ISR_NO_ERR(116) + ISR_NO_ERR(117) ISR_NO_ERR(118) ISR_NO_ERR( + 119) ISR_NO_ERR(120) ISR_NO_ERR(121) + ISR_NO_ERR(122) ISR_NO_ERR( + 123) ISR_NO_ERR(124) + ISR_NO_ERR(125) ISR_NO_ERR( + 126) ISR_NO_ERR(127) + ISR_NO_ERR(128) ISR_NO_ERR( + 129) ISR_NO_ERR(130) + ISR_NO_ERR(131) ISR_NO_ERR( + 132) ISR_NO_ERR(133) + ISR_NO_ERR( + 134) ISR_NO_ERR(135) + ISR_NO_ERR(136) ISR_NO_ERR( + 137) ISR_NO_ERR(138) + ISR_NO_ERR(139) ISR_NO_ERR( + 140) ISR_NO_ERR(141) + ISR_NO_ERR(142) ISR_NO_ERR( + 143) + ISR_NO_ERR(144) ISR_NO_ERR(145) ISR_NO_ERR(146) ISR_NO_ERR(147) ISR_NO_ERR(148) ISR_NO_ERR(149) ISR_NO_ERR(150) ISR_NO_ERR(151) ISR_NO_ERR(152) ISR_NO_ERR(153) ISR_NO_ERR(154) ISR_NO_ERR(155) ISR_NO_ERR(156) ISR_NO_ERR(157) ISR_NO_ERR(158) ISR_NO_ERR(159) ISR_NO_ERR(160) ISR_NO_ERR(161) ISR_NO_ERR(162) ISR_NO_ERR(163) ISR_NO_ERR(164) ISR_NO_ERR(165) ISR_NO_ERR(166) ISR_NO_ERR(167) ISR_NO_ERR(168) ISR_NO_ERR(169) ISR_NO_ERR(170) ISR_NO_ERR(171) ISR_NO_ERR(172) ISR_NO_ERR(173) ISR_NO_ERR( + 174) ISR_NO_ERR(175) + ISR_NO_ERR( + 176) ISR_NO_ERR(177) + ISR_NO_ERR( + 178) ISR_NO_ERR(179) + ISR_NO_ERR( + 180) ISR_NO_ERR(181) + ISR_NO_ERR( + 182) ISR_NO_ERR(183) + ISR_NO_ERR( + 184) ISR_NO_ERR(185) + ISR_NO_ERR( + 186) + ISR_NO_ERR( + 187) + ISR_NO_ERR(188) ISR_NO_ERR(189) ISR_NO_ERR(190) ISR_NO_ERR(191) ISR_NO_ERR(192) ISR_NO_ERR(193) ISR_NO_ERR(194) ISR_NO_ERR(195) ISR_NO_ERR( + 196) ISR_NO_ERR(197) + ISR_NO_ERR(198) ISR_NO_ERR( + 199) + ISR_NO_ERR( + 200) ISR_NO_ERR(201) ISR_NO_ERR(202) ISR_NO_ERR(203) ISR_NO_ERR(204) ISR_NO_ERR(205) ISR_NO_ERR(206) ISR_NO_ERR(207) + ISR_NO_ERR(208) ISR_NO_ERR(209) ISR_NO_ERR(210) ISR_NO_ERR(211) ISR_NO_ERR(212) ISR_NO_ERR(213) ISR_NO_ERR(214) ISR_NO_ERR( + 215) ISR_NO_ERR(216) ISR_NO_ERR(217) ISR_NO_ERR(218) + ISR_NO_ERR(219) ISR_NO_ERR(220) ISR_NO_ERR(221) ISR_NO_ERR(222) ISR_NO_ERR(223) ISR_NO_ERR(224) ISR_NO_ERR(225) ISR_NO_ERR(226) ISR_NO_ERR(227) ISR_NO_ERR( + 228) ISR_NO_ERR(229) + ISR_NO_ERR(230) ISR_NO_ERR(231) ISR_NO_ERR(232) ISR_NO_ERR(233) ISR_NO_ERR(234) ISR_NO_ERR(235) ISR_NO_ERR( + 236) ISR_NO_ERR(237) + ISR_NO_ERR( + 238) ISR_NO_ERR(239) + ISR_NO_ERR(240) ISR_NO_ERR(241) ISR_NO_ERR(242) ISR_NO_ERR(243) ISR_NO_ERR(244) ISR_NO_ERR(245) ISR_NO_ERR( + 246) ISR_NO_ERR(247) + ISR_NO_ERR(248) ISR_NO_ERR( + 249) ISR_NO_ERR(250) + ISR_NO_ERR(251) ISR_NO_ERR( + 252) + ISR_NO_ERR( + 253) + ISR_NO_ERR( + 254) + ISR_NO_ERR( + 255) -// Array of all ISR handlers for easy initialization -void* isr_table[256] = { - isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, - isr8, isr9, isr10, isr11, isr12, isr13, isr14, isr15, - isr16, isr17, isr18, isr19, isr20, isr21, isr22, isr23, - isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31, - isr32, isr33, isr34, isr35, isr36, isr37, isr38, isr39, - isr40, isr41, isr42, isr43, isr44, isr45, isr46, isr47, - isr48, isr49, isr50, isr51, isr52, isr53, isr54, isr55, - isr56, isr57, isr58, isr59, isr60, isr61, isr62, isr63, - isr64, isr65, isr66, isr67, isr68, isr69, isr70, isr71, - isr72, isr73, isr74, isr75, isr76, isr77, isr78, isr79, - isr80, isr81, isr82, isr83, isr84, isr85, isr86, isr87, - isr88, isr89, isr90, isr91, isr92, isr93, isr94, isr95, - isr96, isr97, isr98, isr99, isr100, isr101, isr102, isr103, - isr104, isr105, isr106, isr107, isr108, isr109, isr110, isr111, - isr112, isr113, isr114, isr115, isr116, isr117, isr118, isr119, - isr120, isr121, isr122, isr123, isr124, isr125, isr126, isr127, - isr128, isr129, isr130, isr131, isr132, isr133, isr134, isr135, - isr136, isr137, isr138, isr139, isr140, isr141, isr142, isr143, - isr144, isr145, isr146, isr147, isr148, isr149, isr150, isr151, - isr152, isr153, isr154, isr155, isr156, isr157, isr158, isr159, - isr160, isr161, isr162, isr163, isr164, isr165, isr166, isr167, - isr168, isr169, isr170, isr171, isr172, isr173, isr174, isr175, - isr176, isr177, isr178, isr179, isr180, isr181, isr182, isr183, - isr184, isr185, isr186, isr187, isr188, isr189, isr190, isr191, - isr192, isr193, isr194, isr195, isr196, isr197, isr198, isr199, - isr200, isr201, isr202, isr203, isr204, isr205, isr206, isr207, - isr208, isr209, isr210, isr211, isr212, isr213, isr214, isr215, - isr216, isr217, isr218, isr219, isr220, isr221, isr222, isr223, - isr224, isr225, isr226, isr227, isr228, isr229, isr230, isr231, - isr232, isr233, isr234, isr235, isr236, isr237, isr238, isr239, - isr240, isr241, isr242, isr243, isr244, isr245, isr246, isr247, - isr248, isr249, isr250, isr251, isr252, isr253, isr254, isr255, + // Array of all ISR handlers for easy initialization + void *isr_table[256] = { + isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, + isr9, isr10, isr11, isr12, isr13, isr14, isr15, isr16, isr17, + isr18, isr19, isr20, isr21, isr22, isr23, isr24, isr25, isr26, + isr27, isr28, isr29, isr30, isr31, isr32, isr33, isr34, isr35, + isr36, isr37, isr38, isr39, isr40, isr41, isr42, isr43, isr44, + isr45, isr46, isr47, isr48, isr49, isr50, isr51, isr52, isr53, + isr54, isr55, isr56, isr57, isr58, isr59, isr60, isr61, isr62, + isr63, isr64, isr65, isr66, isr67, isr68, isr69, isr70, isr71, + isr72, isr73, isr74, isr75, isr76, isr77, isr78, isr79, isr80, + isr81, isr82, isr83, isr84, isr85, isr86, isr87, isr88, isr89, + isr90, isr91, isr92, isr93, isr94, isr95, isr96, isr97, isr98, + isr99, isr100, isr101, isr102, isr103, isr104, isr105, isr106, isr107, + isr108, isr109, isr110, isr111, isr112, isr113, isr114, isr115, isr116, + isr117, isr118, isr119, isr120, isr121, isr122, isr123, isr124, isr125, + isr126, isr127, isr128, isr129, isr130, isr131, isr132, isr133, isr134, + isr135, isr136, isr137, isr138, isr139, isr140, isr141, isr142, isr143, + isr144, isr145, isr146, isr147, isr148, isr149, isr150, isr151, isr152, + isr153, isr154, isr155, isr156, isr157, isr158, isr159, isr160, isr161, + isr162, isr163, isr164, isr165, isr166, isr167, isr168, isr169, isr170, + isr171, isr172, isr173, isr174, isr175, isr176, isr177, isr178, isr179, + isr180, isr181, isr182, isr183, isr184, isr185, isr186, isr187, isr188, + isr189, isr190, isr191, isr192, isr193, isr194, isr195, isr196, isr197, + isr198, isr199, isr200, isr201, isr202, isr203, isr204, isr205, isr206, + isr207, isr208, isr209, isr210, isr211, isr212, isr213, isr214, isr215, + isr216, isr217, isr218, isr219, isr220, isr221, isr222, isr223, isr224, + isr225, isr226, isr227, isr228, isr229, isr230, isr231, isr232, isr233, + isr234, isr235, isr236, isr237, isr238, isr239, isr240, isr241, isr242, + isr243, isr244, isr245, isr246, isr247, isr248, isr249, isr250, isr251, + isr252, isr253, isr254, isr255, }; // Initialize all IDT entries diff --git a/src/kbd.c b/src/kbd.c new file mode 100644 index 0000000..f469acb --- /dev/null +++ b/src/kbd.c @@ -0,0 +1,133 @@ +#include "apic.h" +#include "common.h" +#include "print.h" + +#include "kbd.h" + +#define PIC1_COMMAND 0x20 +#define PIC1_DATA 0x21 +#define PIC_EOI 0x20 + +#define PS2_DATA_PORT 0x60 +#define PS2_STATUS_PORT 0x64 + +// Scancode to ASCII mapping (US keyboard layout, simplified) +static const char scancode_to_ascii[] = { + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', '\n', + 0, // Control + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', + 0, // Left shift + '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', + 0, // Right shift + '*', + 0, // Alt + ' ' // Space +}; + +static const char scancode_to_ascii_shift[] = { + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', + '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', '\n', + 0, // Control + 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', + 0, // Left shift + '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', + 0, // Right shift + '*', + 0, // Alt + ' ' // Space +}; + +static struct { + bool shift; + bool ctrl; + bool alt; + bool caps; +} kbd_state; + +#define KBD_BUFFER_SIZE 1024 +static struct { + char buff[KBD_BUFFER_SIZE]; + volatile int read_pos; + volatile int write_pos; +} kbd_buff; + +static void kbd_buffer_putc(char c) { + int next_pos = (kbd_buff.write_pos + 1) % KBD_BUFFER_SIZE; + if (next_pos != kbd_buff.read_pos) { + kbd_buff.buff[kbd_buff.write_pos] = c; + kbd_buff.write_pos = next_pos; + } +} + +char kbd_buffer_getc() { + if (kbd_buff.read_pos == kbd_buff.write_pos) { + return 0; + } + + char c = kbd_buff.buff[kbd_buff.read_pos]; + kbd_buff.read_pos = (kbd_buff.read_pos + 1) % KBD_BUFFER_SIZE; + return c; +} + +void kbd_handler() { + print("KBD HANDLER CALLED: scancode: "); + + u8 scancode = inb(PS2_DATA_PORT); + + + print8(scancode); + print("\n"); + + bool released = (scancode & 0x80); + scancode &= 0x7F; + + + switch(scancode) { + case 0x2A: + case 0x36: + kbd_state.shift = !released; + break; + case 0x1D: + kbd_state.ctrl = !released; + break; + case 0x38: + kbd_state.alt = !released; + break; + case 0x3A: + if(!released) { + kbd_state.caps = !kbd_state.caps; + } + default: + break; + } + + if(!released && scancode < sizeof(scancode_to_ascii)) { + char c = 0; + + if(kbd_state.shift) { + c = scancode_to_ascii_shift[scancode]; + } else { + c = scancode_to_ascii[scancode]; + } + + + if(kbd_state.caps && c >= 'a' && c <= 'z') { + + } else if(kbd_state.caps && c >= 'A' && c <= 'Z') { + c = c - 'A' + 'a'; + } + + if(c != 0) { + kbd_buffer_putc(c); + } + printn(&c, 1); + print("\n"); + } + + + send_eoi(); +} + diff --git a/src/kbd.h b/src/kbd.h new file mode 100644 index 0000000..8f981e7 --- /dev/null +++ b/src/kbd.h @@ -0,0 +1,2 @@ +#pragma once +void kbd_handler(); diff --git a/src/main.c b/src/main.c index 4955666..92b0a80 100644 --- a/src/main.c +++ b/src/main.c @@ -1,92 +1,92 @@ -#include -#include #include +#include +#include #include "../include/limine.h" #include "acpi.h" -#include "apic.h" #include "alloc.h" +#include "apic.h" #include "common.h" #include "map.h" #include "print.h" -// credit owed to https://wiki.osdev.org/Limine_Bare_Bones for the limine setup code +// credit owed to https://wiki.osdev.org/Limine_Bare_Bones for the limine setup +// code -__attribute__((used, section(".limine_requests"))) -static volatile u64 limine_base_revision[] = LIMINE_BASE_REVISION(4); +__attribute__(( + used, + section(".limine_requests"))) static volatile u64 limine_base_revision[] = + LIMINE_BASE_REVISION(4); -__attribute__((used, section(".limine_requests"))) -static volatile struct limine_framebuffer_request fb_req = { - .id = LIMINE_FRAMEBUFFER_REQUEST_ID, - .revision = 0 -}; +__attribute__(( + used, + section( + ".limine_requests"))) static volatile struct limine_framebuffer_request + fb_req = {.id = LIMINE_FRAMEBUFFER_REQUEST_ID, .revision = 0}; +__attribute__(( + used, + section(".limine_requests"))) static volatile struct limine_hhdm_request + hhdm_req = {.id = LIMINE_HHDM_REQUEST_ID, .revision = 0}; -__attribute__((used, section(".limine_requests"))) -static volatile struct limine_hhdm_request hhdm_req = { - .id = LIMINE_HHDM_REQUEST_ID, - .revision = 0 -}; - -__attribute__((used, section(".limine_requests"))) -static volatile struct limine_rsdp_request rsdp_req = { - .id = LIMINE_RSDP_REQUEST_ID, - .revision = 0 -}; +__attribute__(( + used, + section(".limine_requests"))) static volatile struct limine_rsdp_request + rsdp_req = {.id = LIMINE_RSDP_REQUEST_ID, .revision = 0}; u64 hhdm_offset; -__attribute__((used, section(".limine_requests_start"))) -static volatile u64 limine_requests_start_marker[] = LIMINE_REQUESTS_START_MARKER; +__attribute__((used, section(".limine_requests_start"))) static volatile u64 + limine_requests_start_marker[] = LIMINE_REQUESTS_START_MARKER; -__attribute__((used, section(".limine_requests_end"))) -static volatile u64 limine_requests_end_marker[] = LIMINE_REQUESTS_END_MARKER; +__attribute__((used, section(".limine_requests_end"))) static volatile u64 + limine_requests_end_marker[] = LIMINE_REQUESTS_END_MARKER; -void* memcpy(void* restrict dst, const void* src, size_t n) { - u8* restrict pdst = (u8* restrict)dst; - const u8* restrict psrc = (const u8* restrict)src; +void *memcpy(void *restrict dst, const void *src, size_t n) { + u8 *restrict pdst = (u8 *restrict)dst; + const u8 *restrict psrc = (const u8 *restrict)src; - for(size_t i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { pdst[i] = psrc[i]; } return dst; } -void* memset(void* s, int c, size_t n) { - u8* p = (u8*) s; +void *memset(void *s, int c, size_t n) { + u8 *p = (u8 *)s; - for(size_t i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { p[i] = (u8)c; } return s; } -void* memmove(void* dst, const void* src, size_t n) { - u8* restrict pdst = (u8* restrict)dst; - const u8* restrict psrc = (const u8* restrict)src; +void *memmove(void *dst, const void *src, size_t n) { + u8 *restrict pdst = (u8 *restrict)dst; + const u8 *restrict psrc = (const u8 *restrict)src; - if(src > dst) { - for(size_t i = 0; i < n; i++) { + if (src > dst) { + for (size_t i = 0; i < n; i++) { pdst[i] = psrc[i]; - } - } else if(src < dst) { - for(size_t i = n; i > 0; i--) { - pdst[i-1] = psrc[i-1]; - } + } + } else if (src < dst) { + for (size_t i = n; i > 0; i--) { + pdst[i - 1] = psrc[i - 1]; + } } return dst; } -int memcmp(const void* s1, const void* s2, size_t n) { - const u8* p1 = (const u8* )s1; - const u8* p2 = (const u8* )s2; +int memcmp(const void *s1, const void *s2, size_t n) { + const u8 *p1 = (const u8 *)s1; + const u8 *p2 = (const u8 *)s2; - for(size_t i = 0; i < n; i++) { - if(p1[i] != p2[i]) { + for (size_t i = 0; i < n; i++) { + if (p1[i] != p2[i]) { return p1[i] < p2[i] ? -1 : 1; } } @@ -95,21 +95,18 @@ int memcmp(const void* s1, const void* s2, size_t n) { } void hang() { - for(;;) { - asm ("hlt"); + for (;;) { + asm("hlt"); } } - -struct limine_framebuffer* fb; +struct limine_framebuffer *fb; void draw(u8 vect) { - for(size_t y = 0; y < fb->height; y++) { - for(size_t x = 0; x < fb->width; x++) { - volatile u32* fb_ptr = fb->address; - fb_ptr[y * fb->width + x] = ( - ((x ^ y) & 0xff) * 0x0F0003 - )*vect; + for (size_t y = 0; y < fb->height; y++) { + for (size_t x = 0; x < fb->width; x++) { + volatile u32 *fb_ptr = fb->address; + fb_ptr[y * fb->width + x] = (((x ^ y) & 0xff) * 0x0F0003) * vect; } } } @@ -120,29 +117,30 @@ extern u32 fg; extern u32 bg; void enable_ps2_keyboard_interrupts(void) { - // Read PS/2 configuration byte - outb(0x64, 0x20); - while (!(inb(0x64) & 0x01)); // Wait for data - u8 config = inb(0x60); - - // Enable keyboard interrupt (bit 0) and clock (clear bit 4) - config |= 0x01; // Enable first port interrupt - config &= ~0x10; // Enable first port clock - - // Write config back - outb(0x64, 0x60); - outb(0x60, config); - - // Enable keyboard port - outb(0x64, 0xAE); + // Read PS/2 configuration byte + outb(0x64, 0x20); + while (!(inb(0x64) & 0x01)) + ; // Wait for data + u8 config = inb(0x60); + + // Enable keyboard interrupt (bit 0) and clock (clear bit 4) + config |= 0x01; // Enable first port interrupt + config &= ~0x10; // Enable first port clock + + // Write config back + outb(0x64, 0x60); + outb(0x60, config); + + // Enable keyboard port + outb(0x64, 0xAE); } void kmain() { - if(LIMINE_BASE_REVISION_SUPPORTED(limine_base_revision) == false) { + if (LIMINE_BASE_REVISION_SUPPORTED(limine_base_revision) == false) { hang(); } - if(fb_req.response == NULL || fb_req.response->framebuffer_count < 1) { + if (fb_req.response == NULL || fb_req.response->framebuffer_count < 1) { hang(); } @@ -154,43 +152,39 @@ void kmain() { bg = 0xFFFFFF; fg = 0x000000; - if(!hhdm_req.response) { + if (!hhdm_req.response) { print("Failed to get higher half direct mapping\n."); hang(); } hhdm_offset = hhdm_req.response->offset; - if(!rsdp_req.response) { - print ("Failed to find rsdp\n."); + if (!rsdp_req.response) { + print("Failed to find rsdp\n."); hang(); } alloc_init(); - - rsdp = (struct acpi_rsdp_header*)(rsdp_req.response->address); - + rsdp = (struct acpi_rsdp_header *)(rsdp_req.response->address); print("Found RSDP @ 0x"); print64((u64)rsdp); put('\n'); print("With signature: "); - printn((char*)rsdp->signature, sizeof(rsdp->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 - ); + 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)); + printn((const char *)rsdt->signature, sizeof(rsdt->signature)); print("\nAPIC Local Base: "); /* I should check cpuid to ensure its supported but it will @@ -200,7 +194,7 @@ void kmain() { print("APIC Enabled\n"); ioapic_init(); - if(!test_if_mapped((u64) apic_reg(0))) { + if (!test_if_mapped((u64)apic_reg(0))) { print("Mapping APIC registers failed :(\n"); hang(); } @@ -213,14 +207,15 @@ void kmain() { print("Enabling keyboard\n"); enable_ps2_keyboard_interrupts(); - outb(0x64, 0x20); // Read config - while (!(inb(0x64) & 0x01)); + outb(0x64, 0x20); // Read config + while (!(inb(0x64) & 0x01)) + ; u8 config = inb(0x60); asm volatile("sti"); - print("Press a key NOW...\n"); - - volatile u32* tpr = apic_reg(0x80); + print("Press a key NOW...\n"); + + volatile u32 *tpr = apic_reg(0x80); print("TPR: 0x"); print32(*tpr); print("\n"); @@ -228,30 +223,31 @@ void kmain() { print("PS/2 config: 0x"); print8(config); if (!(config & 0x01)) { - print("\nProblem: Bit 0 is 0 (interrupt disabled)\n"); + print("\nProblem: Bit 0 is 0 (interrupt disabled)\n"); } else { - print("\nOK: Bit 0 is 1 (interrupt enabled)\n"); + print("\nOK: Bit 0 is 1 (interrupt enabled)\n"); } print("Press keys (polling test)...\n"); while (1) { - if (inb(0x64) & 0x01) { // Data available - u8 code = inb(0x60); - print("Scan code: 0x"); - print8(code); - print("\n"); - volatile u32* irr = apic_reg(0x210); - print32(*irr); - irr = apic_reg(0x200); // IRR bits 31:0 - u32* isr = apic_reg(0x100); // ISR bits 31:0 + if (inb(0x64) & 0x01) { // Data available + u8 code = inb(0x60); + print("Scan code: 0x"); + print8(code); + print("\n"); + volatile u32 *irr = apic_reg(0x210); + print32(*irr); + irr = apic_reg(0x200); // IRR bits 31:0 + u32 *isr = apic_reg(0x100); // ISR bits 31:0 - print("IRR: "); print32(*irr); - print(" ISR: "); print32(*isr); - print("\n"); - if (code == 0x01) break; // ESC - } + print("IRR: "); + print32(*irr); + print(" ISR: "); + print32(*isr); + print("\n"); + if (code == 0x01) + break; // ESC + } } hang(); - } - diff --git a/src/map.c b/src/map.c index 5c89772..19f3440 100644 --- a/src/map.c +++ b/src/map.c @@ -3,7 +3,7 @@ #include "print.h" // MMIO (Memory-Mapped I/O) Mapping for ACPI and other hardware registers -// +// // CRITICAL: MMIO regions are NOT regular RAM! // - They're not in Limine's memory map as "usable" // - They're often above the RAM limit @@ -12,11 +12,173 @@ // Page table entry structure struct page_entry { + u64 present : 1; + u64 writable : 1; + u64 user : 1; + u64 write_through : 1; + u64 cache_disabled : 1; // IMPORTANT for MMIO! + u64 accessed : 1; + u64 dirty : 1; + u64 huge_page : 1; + u64 global : 1; + u64 unused : 3; + u64 frame : 40; + u64 reserved : 11; + u64 no_execute : 1; +}; + +extern u64 hhdm_offset; + +// Get current page tables +static u64 get_cr3() { + u64 cr3; + asm volatile("mov %%cr3, %0" : "=r"(cr3)); + return cr3 & ~0xFFF; +} + +static u64 alloc_page_table() { + void *a = alloc((1 << 12) / PAGE_SIZE); + if (!a) { + print("Failed to allocate page table\n"); + } + return a ? virt_to_phys(a) : 0; +} + +// Get or create a page table entry at any level +static struct page_entry *get_or_create_table(struct page_entry *table, + u64 index) { + if (!table[index].present) { + u64 new_table_phys = alloc_page_table(); + if (new_table_phys == 0) { + print("failed to alloc\n"); + return NULL; + } + + table[index].present = 1; + table[index].writable = 1; + table[index].user = 0; + table[index].frame = new_table_phys >> 12; + } + + u64 next_table_phys = (u64)table[index].frame << 12; + return (struct page_entry *)phys_to_virt(next_table_phys); +} + +// Map a MMIO page with proper cache settings +// physical_addr: Physical address of MMIO region +// size: Size in bytes (will be rounded up to 4KB pages) +// Returns: Virtual address to access the MMIO region +void *map_mmio(u64 physical_addr, u64 size) { + print("Mapping MMIO region:\n"); + print(" Physical: 0x"); + print64(physical_addr); + print("\n Size: 0x"); + print64(size); + print(" ("); + print64(size >> 20); + print(" MiB)\n"); + + // Align physical address down to page boundary + u64 phys_base = physical_addr & ~(PAGE_SIZE - 1); + u64 offset_in_page = physical_addr & (PAGE_SIZE - 1); + + // Calculate number of pages needed + u64 total_size = size + offset_in_page; + u64 num_pages = (total_size + PAGE_SIZE - 1) / PAGE_SIZE; + + print(" Aligned physical: 0x"); + print64(phys_base); + print("\n Offset in page: 0x"); + print64(offset_in_page); + print("\n Pages needed: "); + print64(num_pages); + print("\n"); + + // For MMIO, we typically map to the HHDM region + // Virtual address = Physical address + HHDM offset + u64 virt_base = phys_base + hhdm_offset; + + print(" Target virtual: 0x"); + print64(virt_base); + print("\n"); + + // Get current page tables + u64 pml4_phys = get_cr3(); + struct page_entry *pml4 = (struct page_entry *)phys_to_virt(pml4_phys); + + // Map each page + for (u64 i = 0; i < num_pages; i++) { + u64 current_phys = phys_base + (i * PAGE_SIZE); + u64 current_virt = virt_base + (i * PAGE_SIZE); + + // Extract indices + u64 pml4_index = (current_virt >> 39) & 0x1FF; + u64 pdpt_index = (current_virt >> 30) & 0x1FF; + u64 pd_index = (current_virt >> 21) & 0x1FF; + u64 pt_index = (current_virt >> 12) & 0x1FF; + + // Walk/create page table hierarchy + struct page_entry *pdpt = get_or_create_table(pml4, pml4_index); + if (!pdpt) { + print("ERROR: Failed to get/create PDPT\n"); + return NULL; + } + + struct page_entry *pd = get_or_create_table(pdpt, pdpt_index); + if (!pd) { + print("ERROR: Failed to get/create PD\n"); + return NULL; + } + + struct page_entry *pt = get_or_create_table(pd, pd_index); + if (!pt) { + print("ERROR: Failed to get/create PT\n"); + return NULL; + } + + // Map the page with MMIO-appropriate settings + pt[pt_index].present = 1; + pt[pt_index].writable = 1; + pt[pt_index].user = 0; + pt[pt_index].cache_disabled = 1; // CRITICAL: Disable caching for MMIO! + pt[pt_index].write_through = 0; + pt[pt_index].no_execute = 1; // Don't execute from MMIO + pt[pt_index].frame = current_phys >> 12; + + // Flush TLB for this page + asm volatile("invlpg (%0)" ::"r"(current_virt) : "memory"); + } + + print(" MMIO mapped successfully!\n"); + print(" Access at virtual: 0x"); + print64(virt_base + offset_in_page); + print("\n\n"); + + // Return virtual address (with original offset) + return (void *)(virt_base + offset_in_page); +} + +// Test correct mapping +int test_if_mapped(u64 virt_addr) { + // Try to read - if we get page fault, it's not mapped + // For now, just check the page tables manually + + u64 pml4_idx = (virt_addr >> 39) & 0x1FF; + u64 pdpt_idx = (virt_addr >> 30) & 0x1FF; + u64 pd_idx = (virt_addr >> 21) & 0x1FF; + u64 pt_idx = (virt_addr >> 12) & 0x1FF; + + // Get CR3 + u64 cr3; + asm volatile("mov %%cr3, %0" : "=r"(cr3)); + u64 pml4_phys = cr3 & ~0xFFF; + + struct page_entry { u64 present : 1; u64 writable : 1; u64 user : 1; u64 write_through : 1; - u64 cache_disabled : 1; // IMPORTANT for MMIO! + u64 cache_disabled : 1; u64 accessed : 1; u64 dirty : 1; u64 huge_page : 1; @@ -25,451 +187,298 @@ struct page_entry { u64 frame : 40; u64 reserved : 11; u64 no_execute : 1; -}; + }; -extern u64 hhdm_offset; + // Access PML4 + struct page_entry *pml4 = (struct page_entry *)(pml4_phys + hhdm_offset); + if (!pml4[pml4_idx].present) { + print(" PML4["); + print64(pml4_idx); + print("] NOT PRESENT\n"); + return 0; + } -// Get current page tables -static u64 get_cr3() { - u64 cr3; - asm volatile("mov %%cr3, %0" : "=r"(cr3)); - return cr3 & ~0xFFF; + // Access PDPT + struct page_entry *pdpt = + (struct page_entry *)(((u64)pml4[pml4_idx].frame << 12) + hhdm_offset); + + if (!pdpt[pdpt_idx].present) { + print(" PDPT["); + print64(pdpt_idx); + print("] NOT PRESENT\n"); + return 0; + } + + // Access PD + struct page_entry *pd = + (struct page_entry *)(((u64)pdpt[pdpt_idx].frame << 12) + hhdm_offset); + + if (!pd[pd_idx].present) { + print(" PD["); + print64(pd_idx); + print("] NOT PRESENT\n"); + return 0; + } + + // Access PT + struct page_entry *pt = + (struct page_entry *)(((u64)pd[pd_idx].frame << 12) + hhdm_offset); + + if (!pt[pt_idx].present) { + print(" PT["); + print64(pt_idx); + print("] NOT PRESENT\n"); + return 0; + } + + print(" All levels present\n"); + print(" Physical page: 0x"); + print64((u64)pt[pt_idx].frame << 12); + print("\n"); + print(" Cache disabled: "); + print8(pt[pt_idx].cache_disabled); + print("\n"); + + return 1; } -static u64 alloc_page_table() { - void* a = alloc((1<<12) / PAGE_SIZE); - if(!a) { - print("Failed to allocate page table\n"); - } - return a? virt_to_phys(a) : 0; -} - -// Get or create a page table entry at any level -static struct page_entry* get_or_create_table(struct page_entry *table, u64 index) { - if (!table[index].present) { - u64 new_table_phys = alloc_page_table(); - if (new_table_phys == 0) { - print("failed to alloc\n"); - return NULL; - } - - table[index].present = 1; - table[index].writable = 1; - table[index].user = 0; - table[index].frame = new_table_phys >> 12; - } - - u64 next_table_phys = (u64)table[index].frame << 12; - return (struct page_entry*)phys_to_virt(next_table_phys); -} - -// Map a MMIO page with proper cache settings -// physical_addr: Physical address of MMIO region -// size: Size in bytes (will be rounded up to 4KB pages) -// Returns: Virtual address to access the MMIO region -void* map_mmio(u64 physical_addr, u64 size) { - print("Mapping MMIO region:\n"); - print(" Physical: 0x"); - print64(physical_addr); - print("\n Size: 0x"); - print64(size); - print(" ("); - print64(size >> 20); - print(" MiB)\n"); - - // Align physical address down to page boundary - u64 phys_base = physical_addr & ~(PAGE_SIZE-1); - u64 offset_in_page = physical_addr & (PAGE_SIZE-1); - - // Calculate number of pages needed - u64 total_size = size + offset_in_page; - u64 num_pages = (total_size + PAGE_SIZE - 1) / PAGE_SIZE; - - print(" Aligned physical: 0x"); - print64(phys_base); - print("\n Offset in page: 0x"); - print64(offset_in_page); - print("\n Pages needed: "); - print64(num_pages); - print("\n"); - - // For MMIO, we typically map to the HHDM region - // Virtual address = Physical address + HHDM offset - u64 virt_base = phys_base + hhdm_offset; - - print(" Target virtual: 0x"); - print64(virt_base); - print("\n"); - - // Get current page tables - u64 pml4_phys = get_cr3(); - struct page_entry *pml4 = (struct page_entry*)phys_to_virt(pml4_phys); - - // Map each page - for (u64 i = 0; i < num_pages; i++) { - u64 current_phys = phys_base + (i * PAGE_SIZE); - u64 current_virt = virt_base + (i * PAGE_SIZE); - - // Extract indices - u64 pml4_index = (current_virt >> 39) & 0x1FF; - u64 pdpt_index = (current_virt >> 30) & 0x1FF; - u64 pd_index = (current_virt >> 21) & 0x1FF; - u64 pt_index = (current_virt >> 12) & 0x1FF; - - // Walk/create page table hierarchy - struct page_entry *pdpt = get_or_create_table(pml4, pml4_index); - if (!pdpt) { - print("ERROR: Failed to get/create PDPT\n"); - return NULL; - } - - struct page_entry *pd = get_or_create_table(pdpt, pdpt_index); - if (!pd) { - print("ERROR: Failed to get/create PD\n"); - return NULL; - } - - struct page_entry *pt = get_or_create_table(pd, pd_index); - if (!pt) { - print("ERROR: Failed to get/create PT\n"); - return NULL; - } - - // Map the page with MMIO-appropriate settings - pt[pt_index].present = 1; - pt[pt_index].writable = 1; - pt[pt_index].user = 0; - pt[pt_index].cache_disabled = 1; // CRITICAL: Disable caching for MMIO! - pt[pt_index].write_through = 0; - pt[pt_index].no_execute = 1; // Don't execute from MMIO - pt[pt_index].frame = current_phys >> 12; - - // Flush TLB for this page - asm volatile("invlpg (%0)" :: "r"(current_virt) : "memory"); - } - - print(" MMIO mapped successfully!\n"); - print(" Access at virtual: 0x"); - print64(virt_base + offset_in_page); - print("\n\n"); - - // Return virtual address (with original offset) - return (void*)(virt_base + offset_in_page); -} - -// Test correct mapping -int test_if_mapped(u64 virt_addr) { - // Try to read - if we get page fault, it's not mapped - // For now, just check the page tables manually - - u64 pml4_idx = (virt_addr >> 39) & 0x1FF; - u64 pdpt_idx = (virt_addr >> 30) & 0x1FF; - u64 pd_idx = (virt_addr >> 21) & 0x1FF; - u64 pt_idx = (virt_addr >> 12) & 0x1FF; - - // Get CR3 - u64 cr3; - asm volatile("mov %%cr3, %0" : "=r"(cr3)); - u64 pml4_phys = cr3 & ~0xFFF; - - struct page_entry { - u64 present : 1; - u64 writable : 1; - u64 user : 1; - u64 write_through : 1; - u64 cache_disabled : 1; - u64 accessed : 1; - u64 dirty : 1; - u64 huge_page : 1; - u64 global : 1; - u64 unused : 3; - u64 frame : 40; - u64 reserved : 11; - u64 no_execute : 1; - }; - - // Access PML4 - struct page_entry *pml4 = (struct page_entry*)(pml4_phys + hhdm_offset); - - if (!pml4[pml4_idx].present) { - print(" PML4["); - print64(pml4_idx); - print("] NOT PRESENT\n"); - return 0; - } - - // Access PDPT - struct page_entry *pdpt = (struct page_entry*)(((u64)pml4[pml4_idx].frame << 12) + hhdm_offset); - - if (!pdpt[pdpt_idx].present) { - print(" PDPT["); - print64(pdpt_idx); - print("] NOT PRESENT\n"); - return 0; - } - - // Access PD - struct page_entry *pd = (struct page_entry*)(((u64)pdpt[pdpt_idx].frame << 12) + hhdm_offset); - - if (!pd[pd_idx].present) { - print(" PD["); - print64(pd_idx); - print("] NOT PRESENT\n"); - return 0; - } - - // Access PT - struct page_entry *pt = (struct page_entry*)(((u64)pd[pd_idx].frame << 12) + hhdm_offset); - - if (!pt[pt_idx].present) { - print(" PT["); - print64(pt_idx); - print("] NOT PRESENT\n"); - return 0; - } - - print(" All levels present\n"); - print(" Physical page: 0x"); - print64((u64)pt[pt_idx].frame << 12); - print("\n"); - print(" Cache disabled: "); - print8(pt[pt_idx].cache_disabled); - print("\n"); - - return 1; -} - - // Unmap MMIO region void unmap_mmio(void *virtual_addr, u64 size) { - u64 virt_base = (u64)virtual_addr & ~0xFFF; - u64 num_pages = (size + ((u64)virtual_addr & 0xFFF) + 0xFFF) / 4096; - - u64 pml4_phys = get_cr3(); - struct page_entry *pml4 = (struct page_entry*)phys_to_virt(pml4_phys); - - for (u64 i = 0; i < num_pages; i++) { - u64 current_virt = virt_base + (i * 4096); - - u64 pml4_index = (current_virt >> 39) & 0x1FF; - u64 pdpt_index = (current_virt >> 30) & 0x1FF; - u64 pd_index = (current_virt >> 21) & 0x1FF; - u64 pt_index = (current_virt >> 12) & 0x1FF; - - if (!pml4[pml4_index].present) continue; - struct page_entry *pdpt = phys_to_virt((u64)pml4[pml4_index].frame << 12); - - if (!pdpt[pdpt_index].present) continue; - struct page_entry *pd = phys_to_virt((u64)pdpt[pdpt_index].frame << 12); - - if (!pd[pd_index].present) continue; - struct page_entry *pt = phys_to_virt((u64)pd[pd_index].frame << 12); - - if (!pt[pt_index].present) continue; - - // Clear the entry - *((u64*)&pt[pt_index]) = 0; - - // Flush TLB - asm volatile("invlpg (%0)" :: "r"(current_virt) : "memory"); - } + u64 virt_base = (u64)virtual_addr & ~0xFFF; + u64 num_pages = (size + ((u64)virtual_addr & 0xFFF) + 0xFFF) / 4096; + + u64 pml4_phys = get_cr3(); + struct page_entry *pml4 = (struct page_entry *)phys_to_virt(pml4_phys); + + for (u64 i = 0; i < num_pages; i++) { + u64 current_virt = virt_base + (i * 4096); + + u64 pml4_index = (current_virt >> 39) & 0x1FF; + u64 pdpt_index = (current_virt >> 30) & 0x1FF; + u64 pd_index = (current_virt >> 21) & 0x1FF; + u64 pt_index = (current_virt >> 12) & 0x1FF; + + if (!pml4[pml4_index].present) + continue; + struct page_entry *pdpt = phys_to_virt((u64)pml4[pml4_index].frame << 12); + + if (!pdpt[pdpt_index].present) + continue; + struct page_entry *pd = phys_to_virt((u64)pdpt[pdpt_index].frame << 12); + + if (!pd[pd_index].present) + continue; + struct page_entry *pt = phys_to_virt((u64)pd[pd_index].frame << 12); + + if (!pt[pt_index].present) + continue; + + // Clear the entry + *((u64 *)&pt[pt_index]) = 0; + + // Flush TLB + asm volatile("invlpg (%0)" ::"r"(current_virt) : "memory"); + } } // Check if a physical address is already mapped int is_mapped(u64 physical_addr) { - u64 virtual_addr = physical_addr + hhdm_offset; - - u64 pml4_phys = get_cr3(); - struct page_entry *pml4 = phys_to_virt(pml4_phys); - - u64 pml4_index = (virtual_addr >> 39) & 0x1FF; - u64 pdpt_index = (virtual_addr >> 30) & 0x1FF; - u64 pd_index = (virtual_addr >> 21) & 0x1FF; - u64 pt_index = (virtual_addr >> 12) & 0x1FF; - - if (!pml4[pml4_index].present) return 0; - struct page_entry *pdpt = phys_to_virt((u64)pml4[pml4_index].frame << 12); - - if (!pdpt[pdpt_index].present) return 0; - - // Check for 1GB huge page - if (pdpt[pdpt_index].huge_page) return 1; - - struct page_entry *pd = phys_to_virt((u64)pdpt[pdpt_index].frame << 12); - - if (!pd[pd_index].present) return 0; - - // Check for 2MB huge page - if (pd[pd_index].huge_page) return 1; - - struct page_entry *pt = phys_to_virt((u64)pd[pd_index].frame << 12); - - return pt[pt_index].present; -} + u64 virtual_addr = physical_addr + hhdm_offset; + u64 pml4_phys = get_cr3(); + struct page_entry *pml4 = phys_to_virt(pml4_phys); + + u64 pml4_index = (virtual_addr >> 39) & 0x1FF; + u64 pdpt_index = (virtual_addr >> 30) & 0x1FF; + u64 pd_index = (virtual_addr >> 21) & 0x1FF; + u64 pt_index = (virtual_addr >> 12) & 0x1FF; + + if (!pml4[pml4_index].present) + return 0; + struct page_entry *pdpt = phys_to_virt((u64)pml4[pml4_index].frame << 12); + + if (!pdpt[pdpt_index].present) + return 0; + + // Check for 1GB huge page + if (pdpt[pdpt_index].huge_page) + return 1; + + struct page_entry *pd = phys_to_virt((u64)pdpt[pdpt_index].frame << 12); + + if (!pd[pd_index].present) + return 0; + + // Check for 2MB huge page + if (pd[pd_index].huge_page) + return 1; + + struct page_entry *pt = phys_to_virt((u64)pd[pd_index].frame << 12); + + return pt[pt_index].present; +} // Read from ACPI register (8-bit) u8 acpi_read8(void *mmio_base, u64 offset) { - volatile u8 *addr = (volatile u8*)((u64)mmio_base + offset); - return *addr; + volatile u8 *addr = (volatile u8 *)((u64)mmio_base + offset); + return *addr; } // Read from ACPI register (16-bit) u16 acpi_read16(void *mmio_base, u64 offset) { - volatile u16 *addr = (volatile u16*)((u64)mmio_base + offset); - return *addr; + volatile u16 *addr = (volatile u16 *)((u64)mmio_base + offset); + return *addr; } // Read from ACPI register (32-bit) u32 acpi_read32(void *mmio_base, u64 offset) { - volatile u32 *addr = (volatile u32*)((u64)mmio_base + offset); - return *addr; + volatile u32 *addr = (volatile u32 *)((u64)mmio_base + offset); + return *addr; } // Read from ACPI register (64-bit) u64 acpi_read64(void *mmio_base, u64 offset) { - volatile u64 *addr = (volatile u64*)((u64)mmio_base + offset); - return *addr; + volatile u64 *addr = (volatile u64 *)((u64)mmio_base + offset); + return *addr; } // Write to ACPI register (8-bit) void acpi_write8(void *mmio_base, u64 offset, u8 value) { - volatile u8 *addr = (volatile u8*)((u64)mmio_base + offset); - *addr = value; + volatile u8 *addr = (volatile u8 *)((u64)mmio_base + offset); + *addr = value; } // Write to ACPI register (16-bit) void acpi_write16(void *mmio_base, u64 offset, u16 value) { - volatile u16 *addr = (volatile u16*)((u64)mmio_base + offset); - *addr = value; + volatile u16 *addr = (volatile u16 *)((u64)mmio_base + offset); + *addr = value; } // Write to ACPI register (32-bit) void acpi_write32(void *mmio_base, u64 offset, u32 value) { - volatile u32 *addr = (volatile u32*)((u64)mmio_base + offset); - *addr = value; + volatile u32 *addr = (volatile u32 *)((u64)mmio_base + offset); + *addr = value; } // Write to ACPI register (64-bit) void acpi_write64(void *mmio_base, u64 offset, u64 value) { - volatile u64 *addr = (volatile u64*)((u64)mmio_base + offset); - *addr = value; + volatile u64 *addr = (volatile u64 *)((u64)mmio_base + offset); + *addr = value; } // Example: Map and access ACPI PM1a Control Block -void* map_acpi_pm1a_control(u64 physical_addr) { - print("Mapping ACPI PM1a Control Block...\n"); - - // PM1a Control is typically 2 bytes, but map at least one page - void *mmio = map_mmio(physical_addr, 4096); - - if (mmio) { - print("PM1a Control Block mapped at virtual: 0x"); - print64((u64)mmio); - print("\n"); - } - - return mmio; +void *map_acpi_pm1a_control(u64 physical_addr) { + print("Mapping ACPI PM1a Control Block...\n"); + + // PM1a Control is typically 2 bytes, but map at least one page + void *mmio = map_mmio(physical_addr, 4096); + + if (mmio) { + print("PM1a Control Block mapped at virtual: 0x"); + print64((u64)mmio); + print("\n"); + } + + return mmio; } // Example: Map ACPI tables (FADT, MADT, etc.) -void* map_acpi_table(u64 physical_addr, u64 size) { - print("Mapping ACPI table...\n"); - print(" Physical: 0x"); - print64(physical_addr); - print("\n Size: "); - print64(size); - print(" bytes\n"); - - void *table = map_mmio(physical_addr, size); - - if (table) { - print("ACPI table mapped at virtual: 0x"); - print64((u64)table); - print("\n"); - } - - return table; -} +void *map_acpi_table(u64 physical_addr, u64 size) { + print("Mapping ACPI table...\n"); + print(" Physical: 0x"); + print64(physical_addr); + print("\n Size: "); + print64(size); + print(" bytes\n"); + void *table = map_mmio(physical_addr, size); + + if (table) { + print("ACPI table mapped at virtual: 0x"); + print64((u64)table); + print("\n"); + } + + return table; +} void print_page_mapping(u64 virtual_addr) { - print("Page mapping for virtual 0x"); - print64(virtual_addr); - print(":\n"); - - u64 pml4_phys = get_cr3(); - struct page_entry *pml4 = phys_to_virt(pml4_phys); - - u64 pml4_index = (virtual_addr >> 39) & 0x1FF; - u64 pdpt_index = (virtual_addr >> 30) & 0x1FF; - u64 pd_index = (virtual_addr >> 21) & 0x1FF; - u64 pt_index = (virtual_addr >> 12) & 0x1FF; - - print(" Indices: PML4["); - print64(pml4_index); - print("] PDPT["); - print64(pdpt_index); - print("] PD["); - print64(pd_index); - print("] PT["); - print64(pt_index); - print("]\n"); - - if (!pml4[pml4_index].present) { - print(" PML4 entry not present!\n"); - return; - } - print(" PML4 entry present, frame=0x"); - print64((u64)pml4[pml4_index].frame << 12); - print("\n"); - - struct page_entry *pdpt = phys_to_virt((u64)pml4[pml4_index].frame << 12); - - if (!pdpt[pdpt_index].present) { - print(" PDPT entry not present!\n"); - return; - } - print(" PDPT entry present, frame=0x"); - print64((u64)pdpt[pdpt_index].frame << 12); - print("\n"); - - if (pdpt[pdpt_index].huge_page) { - print(" 1GB huge page!\n"); - return; - } - - struct page_entry *pd = phys_to_virt((u64)pdpt[pdpt_index].frame << 12); - - if (!pd[pd_index].present) { - print(" PD entry not present!\n"); - return; - } - print(" PD entry present, frame=0x"); - print64((u64)pd[pd_index].frame << 12); - print("\n"); - - if (pd[pd_index].huge_page) { - print(" 2MB huge page!\n"); - return; - } - - struct page_entry *pt = phys_to_virt((u64)pd[pd_index].frame << 12); - - if (!pt[pt_index].present) { - print(" PT entry not present!\n"); - return; - } - - print(" PT entry present:\n"); - print(" Physical frame: 0x"); - print64((u64)pt[pt_index].frame << 12); - print("\n Writable: "); - print64(pt[pt_index].writable); - print("\n Cache disabled: "); - print64(pt[pt_index].cache_disabled); - print("\n No execute: "); - print64(pt[pt_index].no_execute); - print("\n"); + print("Page mapping for virtual 0x"); + print64(virtual_addr); + print(":\n"); + + u64 pml4_phys = get_cr3(); + struct page_entry *pml4 = phys_to_virt(pml4_phys); + + u64 pml4_index = (virtual_addr >> 39) & 0x1FF; + u64 pdpt_index = (virtual_addr >> 30) & 0x1FF; + u64 pd_index = (virtual_addr >> 21) & 0x1FF; + u64 pt_index = (virtual_addr >> 12) & 0x1FF; + + print(" Indices: PML4["); + print64(pml4_index); + print("] PDPT["); + print64(pdpt_index); + print("] PD["); + print64(pd_index); + print("] PT["); + print64(pt_index); + print("]\n"); + + if (!pml4[pml4_index].present) { + print(" PML4 entry not present!\n"); + return; + } + print(" PML4 entry present, frame=0x"); + print64((u64)pml4[pml4_index].frame << 12); + print("\n"); + + struct page_entry *pdpt = phys_to_virt((u64)pml4[pml4_index].frame << 12); + + if (!pdpt[pdpt_index].present) { + print(" PDPT entry not present!\n"); + return; + } + print(" PDPT entry present, frame=0x"); + print64((u64)pdpt[pdpt_index].frame << 12); + print("\n"); + + if (pdpt[pdpt_index].huge_page) { + print(" 1GB huge page!\n"); + return; + } + + struct page_entry *pd = phys_to_virt((u64)pdpt[pdpt_index].frame << 12); + + if (!pd[pd_index].present) { + print(" PD entry not present!\n"); + return; + } + print(" PD entry present, frame=0x"); + print64((u64)pd[pd_index].frame << 12); + print("\n"); + + if (pd[pd_index].huge_page) { + print(" 2MB huge page!\n"); + return; + } + + struct page_entry *pt = phys_to_virt((u64)pd[pd_index].frame << 12); + + if (!pt[pt_index].present) { + print(" PT entry not present!\n"); + return; + } + + print(" PT entry present:\n"); + print(" Physical frame: 0x"); + print64((u64)pt[pt_index].frame << 12); + print("\n Writable: "); + print64(pt[pt_index].writable); + print("\n Cache disabled: "); + print64(pt[pt_index].cache_disabled); + print("\n No execute: "); + print64(pt[pt_index].no_execute); + print("\n"); } diff --git a/src/map.h b/src/map.h index b3e50cf..45efde1 100644 --- a/src/map.h +++ b/src/map.h @@ -2,5 +2,5 @@ #include "common.h" -void* map_mmio(u64, u64); +void *map_mmio(u64, u64); int test_if_mapped(u64 virt_addr); diff --git a/src/print.c b/src/print.c index 4c9a70f..17ea5a6 100644 --- a/src/print.c +++ b/src/print.c @@ -9,17 +9,15 @@ static size_t row; static size_t col; static size_t term_width, term_height; static size_t fb_width, fb_height; -static volatile u32* fb_scr; - +static volatile u32 *fb_scr; #define TAB_STOP 4 // buffer at each edge for readability -#define TERM_WIDTH (FONT_WIDTH+2) -#define TERM_HEIGHT (FONT_HEIGHT+2) +#define TERM_WIDTH (FONT_WIDTH + 2) +#define TERM_HEIGHT (FONT_HEIGHT + 2) - -void print_init(struct limine_framebuffer* fb) { +void print_init(struct limine_framebuffer *fb) { term_width = fb->width / TERM_WIDTH; term_height = fb->height / TERM_HEIGHT; fb_width = fb->width; @@ -28,7 +26,8 @@ void print_init(struct limine_framebuffer* fb) { } static void scrollback() { - memmove((void*)fb_scr, (void*)(fb_scr + fb_width*TERM_HEIGHT), fb_width*(fb_height-1)*sizeof(u32)); + memmove((void *)fb_scr, (void *)(fb_scr + fb_width * TERM_HEIGHT), + fb_width * (fb_height - TERM_HEIGHT) * sizeof(u32)); } void put(int ch) { @@ -70,8 +69,9 @@ void put(int ch) { for (size_t y = 0; y < TERM_HEIGHT; y++) { for (size_t x = 0; x < TERM_WIDTH; x++) { size_t off = (py + y) * fb_width + (px + x); - bool padding = (y == 0 || y == TERM_HEIGHT-1 || x == 0 || x == TERM_WIDTH-1); - fb_scr[off] = ((~glyph & 1) | padding )? bg : fg; + bool padding = + (y == 0 || y == TERM_HEIGHT - 1 || x == 0 || x == TERM_WIDTH - 1); + fb_scr[off] = ((~glyph & 1) | padding) ? bg : fg; glyph >>= !padding; } } @@ -79,15 +79,14 @@ void put(int ch) { col++; } - -void print(const char* msg) { - while(*msg) { +void print(const char *msg) { + while (*msg) { put(*(msg++)); } } -void printn(const char* msg, size_t len) { - while(len-->0) { +void printn(const char *msg, size_t len) { + while (len-- > 0) { put(*(msg++)); } } @@ -95,8 +94,8 @@ void printn(const char* msg, size_t len) { static u8 digits[] = "0123456789ABCDEF"; void print8(u8 n) { - put(digits[n>>4]); - put(digits[n&0xf]); + put(digits[n >> 4]); + put(digits[n & 0xf]); } void print16(u16 n) { diff --git a/src/print.h b/src/print.h index eee3faf..7d4a6d4 100644 --- a/src/print.h +++ b/src/print.h @@ -1,16 +1,15 @@ #pragma once - #include "common.h" struct limine_framebuffer; void put(int ch); -void print(const char* msg); -void printn(const char* msg, size_t len); +void print(const char *msg); +void printn(const char *msg, size_t len); void print64(u64 n); void print32(u32 n); void print16(u16 n); void print8(u8 n); -void print_init(struct limine_framebuffer* fb); +void print_init(struct limine_framebuffer *fb);