From 351f350fc4b5f3cc227e044bf43c2d9b959aafe4 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Wed, 8 Oct 2025 00:00:00 +0000 Subject: [PATCH 01/43] [MMU] preparing for multi-table --- kernel/memory/mmu.c | 58 ++++++++++++++++++++++++++------------------- kernel/memory/mmu.h | 2 +- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 0d411acd..a8865163 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -26,6 +26,8 @@ #define PAGE_TABLE_ENTRIES 512 +#define HIGH_VA 0xFFFF000000000000ULL + uint64_t *page_table_l0; static bool mmu_verbose; @@ -41,19 +43,19 @@ void mmu_enable_verbose(){ }\ }) -void mmu_map_2mb(uint64_t va, uint64_t pa, uint64_t attr_index) { +void mmu_map_2mb(uint64_t *table, uint64_t va, uint64_t pa, uint64_t attr_index) { uint64_t l0_index = (va >> 39) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; uint64_t l2_index = (va >> 21) & 0x1FF; kprintfv("[MMU] Mapping 2mb memory %x at [%i][%i][%i] for EL1", va, l0_index,l1_index,l2_index); - if (!(page_table_l0[l0_index] & 1)) { + if (!(table[l0_index] & 1)) { uint64_t* l1 = (uint64_t*)talloc(PAGE_SIZE); - page_table_l0[l0_index] = ((uint64_t)l1 & 0xFFFFFFFFF000ULL) | PD_TABLE; + table[l0_index] = ((uint64_t)l1 & 0xFFFFFFFFF000ULL) | PD_TABLE; } - uint64_t* l1 = (uint64_t*)(page_table_l0[l0_index] & 0xFFFFFFFFF000ULL); + uint64_t* l1 = (uint64_t*)(table[l0_index] & 0xFFFFFFFFF000ULL); if (!(l1[l1_index] & 1)) { uint64_t* l2 = (uint64_t*)talloc(PAGE_SIZE); @@ -68,18 +70,18 @@ void mmu_map_2mb(uint64_t va, uint64_t pa, uint64_t attr_index) { } //Level 0 = EL0, Level 1 = EL1, Level 2 = Shared -void mmu_map_4kb(uint64_t va, uint64_t pa, uint64_t attr_index, uint8_t mem_attributes, uint8_t level) { +void mmu_map_4kb(uint64_t *table, uint64_t va, uint64_t pa, uint64_t attr_index, uint8_t mem_attributes, uint8_t level) { uint64_t l0_index = (va >> 39) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; uint64_t l2_index = (va >> 21) & 0x1FF; uint64_t l3_index = (va >> 12) & 0x1FF; - if (!(page_table_l0[l0_index] & 1)) { + if (!(table[l0_index] & 1)) { uint64_t* l1 = (uint64_t*)talloc(PAGE_SIZE); - page_table_l0[l0_index] = ((uint64_t)l1 & 0xFFFFFFFFF000ULL) | PD_TABLE; + table[l0_index] = ((uint64_t)l1 & 0xFFFFFFFFF000ULL) | PD_TABLE; } - uint64_t* l1 = (uint64_t*)(page_table_l0[l0_index] & 0xFFFFFFFFF000ULL); + uint64_t* l1 = (uint64_t*)(table[l0_index] & 0xFFFFFFFFF000ULL); if (!(l1[l1_index] & 1)) { uint64_t* l2 = (uint64_t*)talloc(PAGE_SIZE); l1[l1_index] = ((uint64_t)l2 & 0xFFFFFFFFF000ULL) | PD_TABLE; @@ -142,6 +144,8 @@ static inline void mmu_flush_icache() { } void mmu_unmap(uint64_t va, uint64_t pa){ + + uint64_t *table = page_table_l0; uint64_t l0_index = (va >> 39) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; @@ -149,9 +153,9 @@ void mmu_unmap(uint64_t va, uint64_t pa){ uint64_t l3_index = (va >> 12) & 0x1FF; kprintfv("[MMU] Unmapping 4kb memory %x at [%i][%i][%i][%i] for EL1", va, l0_index,l1_index,l2_index, l3_index); - if (!(page_table_l0[l0_index] & 1)) return; + if (!(table[l0_index] & 1)) return; - uint64_t* l1 = (uint64_t*)(page_table_l0[l0_index] & 0xFFFFFFFFF000ULL); + uint64_t* l1 = (uint64_t*)(table[l0_index] & 0xFFFFFFFFF000ULL); if (!(l1[l1_index] & 1)) return; uint64_t* l2 = (uint64_t*)(l1[l1_index] & 0xFFFFFFFFF000ULL); @@ -170,8 +174,9 @@ void mmu_unmap(uint64_t va, uint64_t pa){ mmu_flush_icache(); } -void mmu_alloc(){ +uint64_t* mmu_alloc(){ page_table_l0 = (uint64_t*)talloc(PAGE_SIZE); + return page_table_l0; } extern uint64_t shared_start; @@ -185,32 +190,32 @@ void mmu_init() { uint64_t kend = mem_get_kmem_end(); for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB) - mmu_map_2mb(addr, addr, MAIR_IDX_NORMAL); + mmu_map_2mb(page_table_l0, addr, addr, MAIR_IDX_NORMAL); for (uint64_t addr = get_uart_base(); addr <= get_uart_base(); addr += GRANULE_4KB) - mmu_map_4kb(addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); for (uint64_t addr = GICD_BASE; addr <= GICC_BASE + 0x1000; addr += GRANULE_4KB) - mmu_map_4kb(addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); for (uint64_t addr = (uintptr_t)&shared_start; addr < (uintptr_t)&shared_code_end; addr += GRANULE_4KB) - mmu_map_4kb(addr, addr, MAIR_IDX_NORMAL, MEM_EXEC | MEM_RO, MEM_PRIV_SHARED); + mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_NORMAL, MEM_EXEC | MEM_RO, MEM_PRIV_SHARED); for (uint64_t addr = (uintptr_t)&shared_code_end; addr < (uintptr_t)&shared_ro_end; addr += GRANULE_4KB) - mmu_map_4kb(addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_SHARED); + mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_SHARED); for (uint64_t addr = (uintptr_t)&shared_ro_end; addr < (uintptr_t)&shared_end; addr += GRANULE_4KB) - mmu_map_4kb(addr, addr, MAIR_IDX_NORMAL, MEM_RW, MEM_PRIV_SHARED); + mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_NORMAL, MEM_RW, MEM_PRIV_SHARED); if (XHCI_BASE) - for (uint64_t addr = XHCI_BASE; addr <= XHCI_BASE + 0x1000; addr += GRANULE_4KB) - mmu_map_4kb(addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + for (uint64_t addr = XHCI_BASE; addr <= XHCI_BASE + 0x1000; addr += GRANULE_4KB) + mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); uint64_t dstart; uint64_t dsize; if (dtb_addresses(&dstart,&dsize)){ for (uint64_t addr = dstart; addr <= dstart + dsize; addr += GRANULE_4KB) - mmu_map_4kb(addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); + mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); } uint64_t mair = (MAIR_DEVICE_nGnRnE << (MAIR_IDX_DEVICE * 8)) | (MAIR_NORMAL_NOCACHE << (MAIR_IDX_NORMAL * 8)); @@ -238,24 +243,27 @@ void mmu_init() { } void register_device_memory(uint64_t va, uint64_t pa){ - mmu_map_4kb(va, pa, MAIR_IDX_DEVICE, MEM_RW, 1); + mmu_map_4kb(page_table_l0, va, pa, MAIR_IDX_DEVICE, MEM_RW, 1); mmu_flush_all(); mmu_flush_icache(); } void register_device_memory_2mb(uint64_t va, uint64_t pa){ - mmu_map_2mb(va, pa, MAIR_IDX_DEVICE); + mmu_map_2mb(page_table_l0, va, pa, MAIR_IDX_DEVICE); mmu_flush_all(); mmu_flush_icache(); } void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t level){ - mmu_map_4kb(va, pa, MAIR_IDX_NORMAL, attributes, level); + mmu_map_4kb(page_table_l0, va, pa, MAIR_IDX_NORMAL, attributes, level); mmu_flush_all(); mmu_flush_icache(); } void debug_mmu_address(uint64_t va){ + + uint64_t *table = page_table_l0; + uint64_t l0_index = (va >> 37) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; uint64_t l2_index = (va >> 21) & 0x1FF; @@ -263,11 +271,11 @@ void debug_mmu_address(uint64_t va){ kprintf("Address %x is meant to be mapped to [%i][%i][%i][%i]",va, l0_index,l1_index,l2_index,l3_index); - if (!(page_table_l0[l0_index] & 1)) { + if (!(table[l0_index] & 1)) { kprintf("L1 Table missing"); return; } - uint64_t* l1 = (uint64_t*)(page_table_l0[l0_index] & 0xFFFFFFFFF000ULL); + uint64_t* l1 = (uint64_t*)(table[l0_index] & 0xFFFFFFFFF000ULL); if (!(l1[l1_index] & 1)) { kprintf("L2 Table missing"); return; diff --git a/kernel/memory/mmu.h b/kernel/memory/mmu.h index 4995aedd..d7915f0a 100644 --- a/kernel/memory/mmu.h +++ b/kernel/memory/mmu.h @@ -5,7 +5,7 @@ #define GRANULE_4KB 0x1000 #define GRANULE_2MB 0x200000 -void mmu_alloc(); +uint64_t* mmu_alloc(); void mmu_init(); #ifdef __cplusplus extern "C" { From 552ede918417c0a67b26902e8da1b54e6b910dad Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Wed, 8 Oct 2025 00:00:00 +0000 Subject: [PATCH 02/43] [MMU] low&high kernel mapping --- kernel/kernel.c | 2 +- kernel/linker.ld | 5 +--- kernel/memory/mmu.c | 66 +++++++++++++++++++++++------------------- kernel/memory/mmu.h | 3 +- kernel/memory/talloc.c | 3 +- 5 files changed, 42 insertions(+), 37 deletions(-) diff --git a/kernel/kernel.c b/kernel/kernel.c index 9394bb2d..3b5a46e8 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -23,7 +23,7 @@ void kernel_main() { detect_hardware(); - mmu_alloc(); + mmu_init_kernel(); if (BOARD_TYPE == 2) mailbox_init(); diff --git a/kernel/linker.ld b/kernel/linker.ld index f5a56de5..77d94372 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -30,9 +30,6 @@ SECTIONS { .heap_fill : { FILL(0); . = . + 0xFF000; } heap_limit = .; - . = ALIGN(0x200000); - kcode_end = .; - .shared : ALIGN(0x1000) { shared_start = .; *libshared.a:*(.text*) @@ -49,5 +46,5 @@ SECTIONS { } . = ALIGN(0x200000); - kfull_end = .; + kcode_end = .; } \ No newline at end of file diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index a8865163..7d19bda7 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -27,8 +27,10 @@ #define PAGE_TABLE_ENTRIES 512 #define HIGH_VA 0xFFFF000000000000ULL +#define VIRT_TO_PHYS(x) ((VirtualAddr)x - HIGH_VA) +#define PHYS_TO_VIRT(x) ((PhysicalAddr)x + HIGH_VA) -uint64_t *page_table_l0; +uint64_t *kernel_lo_page, *kernel_hi_page; static bool mmu_verbose; @@ -145,7 +147,7 @@ static inline void mmu_flush_icache() { void mmu_unmap(uint64_t va, uint64_t pa){ - uint64_t *table = page_table_l0; + uint64_t *table = kernel_lo_page; uint64_t l0_index = (va >> 39) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; @@ -174,9 +176,13 @@ void mmu_unmap(uint64_t va, uint64_t pa){ mmu_flush_icache(); } -uint64_t* mmu_alloc(){ - page_table_l0 = (uint64_t*)talloc(PAGE_SIZE); - return page_table_l0; +void mmu_init_kernel(){ + kernel_lo_page = mmu_alloc(); + kernel_hi_page = mmu_alloc(); +} + +uint64_t *mmu_alloc(){ + return (uint64_t*)talloc(PAGE_SIZE); } extern uint64_t shared_start; @@ -189,33 +195,34 @@ void mmu_init() { uint64_t kstart = mem_get_kmem_start(); uint64_t kend = mem_get_kmem_end(); - for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB) - mmu_map_2mb(page_table_l0, addr, addr, MAIR_IDX_NORMAL); - - for (uint64_t addr = get_uart_base(); addr <= get_uart_base(); addr += GRANULE_4KB) - mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); - - for (uint64_t addr = GICD_BASE; addr <= GICC_BASE + 0x1000; addr += GRANULE_4KB) - mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); - - for (uint64_t addr = (uintptr_t)&shared_start; addr < (uintptr_t)&shared_code_end; addr += GRANULE_4KB) - mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_NORMAL, MEM_EXEC | MEM_RO, MEM_PRIV_SHARED); + for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB){ + mmu_map_2mb(kernel_lo_page, addr, addr, MAIR_IDX_NORMAL); + mmu_map_2mb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_NORMAL); + } - for (uint64_t addr = (uintptr_t)&shared_code_end; addr < (uintptr_t)&shared_ro_end; addr += GRANULE_4KB) - mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_SHARED); + for (uint64_t addr = get_uart_base(); addr <= get_uart_base(); addr += GRANULE_4KB){ + mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + } - for (uint64_t addr = (uintptr_t)&shared_ro_end; addr < (uintptr_t)&shared_end; addr += GRANULE_4KB) - mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_NORMAL, MEM_RW, MEM_PRIV_SHARED); + for (uint64_t addr = GICD_BASE; addr <= GICC_BASE + 0x1000; addr += GRANULE_4KB){ + mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + } if (XHCI_BASE) - for (uint64_t addr = XHCI_BASE; addr <= XHCI_BASE + 0x1000; addr += GRANULE_4KB) - mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + for (uint64_t addr = XHCI_BASE; addr <= XHCI_BASE + 0x1000; addr += GRANULE_4KB){ + mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + } uint64_t dstart; uint64_t dsize; if (dtb_addresses(&dstart,&dsize)){ - for (uint64_t addr = dstart; addr <= dstart + dsize; addr += GRANULE_4KB) - mmu_map_4kb(page_table_l0, addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); + for (uint64_t addr = dstart; addr <= dstart + dsize; addr += GRANULE_4KB){ + mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); + } } uint64_t mair = (MAIR_DEVICE_nGnRnE << (MAIR_IDX_DEVICE * 8)) | (MAIR_NORMAL_NOCACHE << (MAIR_IDX_NORMAL * 8)); @@ -228,7 +235,8 @@ void mmu_init() { asm volatile ("dsb ish"); asm volatile ("isb"); - asm volatile ("msr ttbr0_el1, %0" :: "r"(page_table_l0)); + asm volatile ("msr ttbr0_el1, %0" :: "r"(kernel_lo_page)); + asm volatile ("msr ttbr1_el1, %0" :: "r"(kernel_hi_page)); asm volatile ( "mrs x0, sctlr_el1\n" @@ -243,26 +251,26 @@ void mmu_init() { } void register_device_memory(uint64_t va, uint64_t pa){ - mmu_map_4kb(page_table_l0, va, pa, MAIR_IDX_DEVICE, MEM_RW, 1); + mmu_map_4kb(kernel_lo_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, 1); mmu_flush_all(); mmu_flush_icache(); } void register_device_memory_2mb(uint64_t va, uint64_t pa){ - mmu_map_2mb(page_table_l0, va, pa, MAIR_IDX_DEVICE); + mmu_map_2mb(kernel_lo_page, va, pa, MAIR_IDX_DEVICE); mmu_flush_all(); mmu_flush_icache(); } void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t level){ - mmu_map_4kb(page_table_l0, va, pa, MAIR_IDX_NORMAL, attributes, level); + mmu_map_4kb(kernel_lo_page, va, pa, MAIR_IDX_NORMAL, attributes, level); mmu_flush_all(); mmu_flush_icache(); } void debug_mmu_address(uint64_t va){ - uint64_t *table = page_table_l0; + uint64_t *table = kernel_lo_page; uint64_t l0_index = (va >> 37) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; diff --git a/kernel/memory/mmu.h b/kernel/memory/mmu.h index d7915f0a..ea505d08 100644 --- a/kernel/memory/mmu.h +++ b/kernel/memory/mmu.h @@ -19,4 +19,5 @@ void mmu_enable_verbose(); } #endif -void mmu_unmap(uint64_t va, uint64_t pa); \ No newline at end of file +void mmu_unmap(uint64_t va, uint64_t pa); +void mmu_init_kernel(); \ No newline at end of file diff --git a/kernel/memory/talloc.c b/kernel/memory/talloc.c index a63da829..27c80731 100644 --- a/kernel/memory/talloc.c +++ b/kernel/memory/talloc.c @@ -42,7 +42,6 @@ extern uint64_t kernel_start; extern uint64_t heap_bottom; extern uint64_t heap_limit; extern uint64_t kcode_end; -extern uint64_t kfull_end; static bool talloc_verbose = false; uint64_t next_free_temp_memory = (uint64_t)&heap_bottom; @@ -148,7 +147,7 @@ int get_memory_region(uint64_t *out_base, uint64_t *out_size) { void calc_ram(){ if (get_memory_region(&total_ram_start, &total_ram_size)) { calculated_ram_end = total_ram_start + total_ram_size; - calculated_ram_start = ((uint64_t)&kfull_end) + 0x1; + calculated_ram_start = ((uint64_t)&kcode_end) + 0x1; calculated_ram_start = ((calculated_ram_start) & ~((1ULL << 21) - 1)); calculated_ram_end = ((calculated_ram_end) & ~((1ULL << 21) - 1)); } else { From e06eb65b2310fe9947789bcb0717d7813e5afd6d Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Wed, 8 Oct 2025 00:00:00 +0000 Subject: [PATCH 03/43] [MMU] higher addresses (not using for kernel yet --- kernel/memory/mmu.c | 31 ++++--------------------------- kernel/memory/mmu_start.S | 27 +++++++++++++++++++++++++++ kernel/sysregs.h | 18 +++++++++++++++++- 3 files changed, 48 insertions(+), 28 deletions(-) create mode 100644 kernel/memory/mmu_start.S diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 7d19bda7..8c162fb3 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -8,11 +8,7 @@ #include "pci.h" #include "filesystem/disk.h" #include "memory/page_allocator.h" - -#define MAIR_DEVICE_nGnRnE 0b00000000 -#define MAIR_NORMAL_NOCACHE 0b01000100 -#define MAIR_IDX_DEVICE 0 -#define MAIR_IDX_NORMAL 1 +#include "sysregs.h" #define PD_TABLE 0b11 #define PD_BLOCK 0b01 @@ -26,7 +22,6 @@ #define PAGE_TABLE_ENTRIES 512 -#define HIGH_VA 0xFFFF000000000000ULL #define VIRT_TO_PHYS(x) ((VirtualAddr)x - HIGH_VA) #define PHYS_TO_VIRT(x) ((PhysicalAddr)x + HIGH_VA) @@ -190,6 +185,8 @@ extern uint64_t shared_code_end; extern uint64_t shared_ro_end; extern uint64_t shared_end; +extern void mmu_start(uint64_t *low, uint64_t *high); + void mmu_init() { //TODO: Move these hardcoded mappings to their own file uint64_t kstart = mem_get_kmem_start(); @@ -224,28 +221,8 @@ void mmu_init() { mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); } } - - uint64_t mair = (MAIR_DEVICE_nGnRnE << (MAIR_IDX_DEVICE * 8)) | (MAIR_NORMAL_NOCACHE << (MAIR_IDX_NORMAL * 8)); - asm volatile ("msr mair_el1, %0" :: "r"(mair)); - - //30 = Translation granule EL1. 10 = 4kb | 14 = TG EL0 00 = 4kb - uint64_t tcr = ((64 - 48) << 0) | ((64 - 48) << 16) | (0b00 << 14) | (0b10 << 30); - asm volatile ("msr tcr_el1, %0" :: "r"(tcr)); - - asm volatile ("dsb ish"); - asm volatile ("isb"); - - asm volatile ("msr ttbr0_el1, %0" :: "r"(kernel_lo_page)); - asm volatile ("msr ttbr1_el1, %0" :: "r"(kernel_hi_page)); - asm volatile ( - "mrs x0, sctlr_el1\n" - "orr x0, x0, #0x1\n" - "bic x0, x0, #(1 << 19)\n" - "msr sctlr_el1, x0\n" - "isb\n" - ::: "x0", "memory" - ); + mmu_start(kernel_lo_page, kernel_hi_page); kprintf("Finished MMU init"); } diff --git a/kernel/memory/mmu_start.S b/kernel/memory/mmu_start.S new file mode 100644 index 00000000..e26aad13 --- /dev/null +++ b/kernel/memory/mmu_start.S @@ -0,0 +1,27 @@ +#include "sysregs.h" + +.global mmu_start +mmu_start://(uint64_t *low x0, uint64_t *high x1) + ldr x3, =MAIR_VALUE + msr mair_el1, x3 + ldr x3, =TCR_VALUE + msr tcr_el1, x3 + dsb ish + isb + + msr ttbr0_el1, x0 + msr ttbr1_el1, x1 + + mrs x0, sctlr_el1 + orr x0, x0, #0x1 + bic x0, x0, #(1 << 19) + msr sctlr_el1, x0 + isb + + ldr x1, =HIGH_VA + + mrs x0, vbar_el1 + orr x0, x0, x1 + msr vbar_el1, x0 + + ret \ No newline at end of file diff --git a/kernel/sysregs.h b/kernel/sysregs.h index 72a98da7..4ff34046 100644 --- a/kernel/sysregs.h +++ b/kernel/sysregs.h @@ -46,4 +46,20 @@ #define TRAP_PHYS_TIMER_DISABLED (1 << 0) #define TRAV_VIRT_TIMER_DISABLED (1 << 1) //Disable trapping of timer calls on hypervisor level -#define CNTHCTL_VALUE (TRAP_PHYS_TIMER_DISABLED | TRAV_VIRT_TIMER_DISABLED) \ No newline at end of file +#define CNTHCTL_VALUE (TRAP_PHYS_TIMER_DISABLED | TRAV_VIRT_TIMER_DISABLED) + +// *************************************** +// MMU +// *************************************** + +//30 = Translation granule EL1. 10 = 4kb | 14 = TG EL0 00 = 4kb. 0xFFFFFFFF to translate to 64 +#define TCR_VALUE ((0xFFFFFFFF << 32) | ((64 - 48) << 0) | ((64 - 48) << 16) | (0b00 << 14) | (0b10 << 30)) + +#define MAIR_DEVICE_nGnRnE 0b00000000 +#define MAIR_NORMAL_NOCACHE 0b01000100 +#define MAIR_IDX_DEVICE 0 +#define MAIR_IDX_NORMAL 1 + +#define MAIR_VALUE ((MAIR_DEVICE_nGnRnE << (MAIR_IDX_DEVICE * 8)) | (MAIR_NORMAL_NOCACHE << (MAIR_IDX_NORMAL * 8))) + +#define HIGH_VA 0xFFFF000000000000ULL \ No newline at end of file From f244d23479e91bfeb46ee71e6064173e10ffebaf Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Thu, 9 Oct 2025 00:00:00 +0000 Subject: [PATCH 04/43] [FAT32] fixed filename match --- kernel/filesystem/fat32.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/filesystem/fat32.cpp b/kernel/filesystem/fat32.cpp index ff19daa7..053b8313 100644 --- a/kernel/filesystem/fat32.cpp +++ b/kernel/filesystem/fat32.cpp @@ -228,7 +228,7 @@ sizedptr FAT32FS::read_entry_handler(FAT32FS *instance, f32file_entry *entry, ch if (entry->flags.volume_id) return {0,0}; bool is_last = *seek_to(seek, '/') == '\0'; - if (!is_last && strstart(seek, filename, true) == 0) return {0, 0}; + if (!is_last && strstart(seek, filename, true) < (int)(strlen(filename, 0)-1)) return {0, 0}; if (is_last && strcmp(seek, filename, true) != 0) return {0, 0}; uint32_t filecluster = (entry->hi_first_cluster << 16) | entry->lo_first_cluster; @@ -265,7 +265,7 @@ size_t FAT32FS::read_file(file *descriptor, void* buf, size_t size){ sizedptr FAT32FS::list_entries_handler(FAT32FS *instance, f32file_entry *entry, char *filename, const char *seek) { if (entry->flags.volume_id) return { 0, 0 }; - if (strstart(seek, filename, true) == 0) return { 0, 0 }; + if (strstart(seek, filename, true) != (int)(strlen(filename, 0)-1)) return { 0, 0 }; bool is_last = *seek_to(seek, '/') == '\0'; From fcb7fc8895cbdab42608802c6ddf5e58e5c39ff8 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Thu, 9 Oct 2025 00:00:00 +0000 Subject: [PATCH 05/43] [MMU] use kernel on high address --- kernel/memory/mmu.c | 1 + kernel/memory/mmu_start.S | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 8c162fb3..ba5465b5 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -224,6 +224,7 @@ void mmu_init() { mmu_start(kernel_lo_page, kernel_hi_page); + asm volatile (".global mmu_finish\nmmu_finish:"); kprintf("Finished MMU init"); } diff --git a/kernel/memory/mmu_start.S b/kernel/memory/mmu_start.S index e26aad13..c5bd8b81 100644 --- a/kernel/memory/mmu_start.S +++ b/kernel/memory/mmu_start.S @@ -24,4 +24,6 @@ mmu_start://(uint64_t *low x0, uint64_t *high x1) orr x0, x0, x1 msr vbar_el1, x0 - ret \ No newline at end of file + ldr x0, =mmu_finish + orr x0, x0, x1 + br x0 \ No newline at end of file From 2b529bce9541e03e87e1eb63d4ac15905e607e66 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Thu, 9 Oct 2025 00:00:00 +0000 Subject: [PATCH 06/43] [MMU] Using exclusively HIGH VA for kernel code (not data) --- kernel/hw/hw.c | 13 +++++++++++++ kernel/hw/hw.h | 3 ++- kernel/kernel.c | 4 ++-- kernel/kernel_processes/kprocess_loader.c | 3 ++- kernel/memory/mmu.c | 9 +++++---- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/kernel/hw/hw.c b/kernel/hw/hw.c index 428d8e0d..91d86e6e 100644 --- a/kernel/hw/hw.c +++ b/kernel/hw/hw.c @@ -1,6 +1,7 @@ #include "hw.h" #include "console/kio.h" #include "gpio.h" +#include "sysregs.h" uint8_t BOARD_TYPE; uint8_t RPI_BOARD; @@ -82,6 +83,18 @@ void detect_hardware(){ } } +void hw_high_va(){ + UART0_BASE |= HIGH_VA; + MMIO_BASE |= HIGH_VA; + if (BOARD_TYPE != 1)//virt is probably doing some weird PCI address stuff already + PCI_BASE |= HIGH_VA; + GICD_BASE |= HIGH_VA; + GICC_BASE |= HIGH_VA; + MAILBOX_BASE |= HIGH_VA; + SDHCI_BASE |= HIGH_VA; + XHCI_BASE |= HIGH_VA; +} + void print_hardware(){ kprintf("Board type %i",BOARD_TYPE); } \ No newline at end of file diff --git a/kernel/hw/hw.h b/kernel/hw/hw.h index 33249462..3b03557a 100644 --- a/kernel/hw/hw.h +++ b/kernel/hw/hw.h @@ -38,4 +38,5 @@ extern uint32_t MSI_OFFSET; extern uintptr_t LOWEST_ADDR; void detect_hardware(); -void print_hardware(); \ No newline at end of file +void print_hardware(); +void hw_high_va(); \ No newline at end of file diff --git a/kernel/kernel.c b/kernel/kernel.c index 3b5a46e8..8d12decb 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -60,8 +60,6 @@ void kernel_main() { network_available = load_module(&net_module); load_module(&audio_module); - - init_audio_mixer(); } mmu_init(); @@ -69,6 +67,8 @@ void kernel_main() { kprint("Kernel initialization finished"); kprint("Starting processes"); + + if (BOARD_TYPE == 1) init_audio_mixer(); init_filesystem(); if (input_available) init_input_process(); diff --git a/kernel/kernel_processes/kprocess_loader.c b/kernel/kernel_processes/kprocess_loader.c index 4a446d06..11b778e8 100644 --- a/kernel/kernel_processes/kprocess_loader.c +++ b/kernel/kernel_processes/kprocess_loader.c @@ -3,6 +3,7 @@ #include "process/scheduler.h" #include "memory/page_allocator.h" #include "exceptions/irq.h" +#include "sysregs.h" process_t *create_kernel_process(const char *name, int (*func)(int argc, char* argv[]), int argc, const char* argv[]){ @@ -29,7 +30,7 @@ process_t *create_kernel_process(const char *name, int (*func)(int argc, char* a proc->sp = proc->stack; - proc->pc = (uintptr_t)func; + proc->pc = ((uintptr_t)func) | HIGH_VA; kprintf("Kernel process %s (%i) allocated with address at %x, stack at %x, heap at %x. %i argument(s)", (uintptr_t)name, proc->id, proc->pc, proc->sp, proc->heap, argc); proc->spsr = 0x205;//TODO: we can use 0x204 instead of 05 to use sp_el0 always maybe? proc->state = READY; diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index ba5465b5..8914508e 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -198,18 +198,15 @@ void mmu_init() { } for (uint64_t addr = get_uart_base(); addr <= get_uart_base(); addr += GRANULE_4KB){ - mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); } for (uint64_t addr = GICD_BASE; addr <= GICC_BASE + 0x1000; addr += GRANULE_4KB){ - mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); } if (XHCI_BASE) for (uint64_t addr = XHCI_BASE; addr <= XHCI_BASE + 0x1000; addr += GRANULE_4KB){ - mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); } @@ -217,13 +214,17 @@ void mmu_init() { uint64_t dsize; if (dtb_addresses(&dstart,&dsize)){ for (uint64_t addr = dstart; addr <= dstart + dsize; addr += GRANULE_4KB){ - mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); } } + + hw_high_va(); mmu_start(kernel_lo_page, kernel_hi_page); + for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB) + mmu_unmap(addr, addr); + asm volatile (".global mmu_finish\nmmu_finish:"); kprintf("Finished MMU init"); } From 9f70818fb569d6d4c030ea9b8be19575dca32138 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Fri, 10 Oct 2025 00:00:00 +0000 Subject: [PATCH 07/43] [MMU] disabling identity unmapping of kernel til its all mapped --- kernel/memory/mmu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 8914508e..39d138aa 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -194,27 +194,27 @@ void mmu_init() { for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB){ mmu_map_2mb(kernel_lo_page, addr, addr, MAIR_IDX_NORMAL); - mmu_map_2mb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_NORMAL); + mmu_map_2mb(kernel_hi_page, addr, addr, MAIR_IDX_NORMAL); } for (uint64_t addr = get_uart_base(); addr <= get_uart_base(); addr += GRANULE_4KB){ - mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_hi_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); } for (uint64_t addr = GICD_BASE; addr <= GICC_BASE + 0x1000; addr += GRANULE_4KB){ - mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_hi_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); } if (XHCI_BASE) for (uint64_t addr = XHCI_BASE; addr <= XHCI_BASE + 0x1000; addr += GRANULE_4KB){ - mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_hi_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); } uint64_t dstart; uint64_t dsize; if (dtb_addresses(&dstart,&dsize)){ for (uint64_t addr = dstart; addr <= dstart + dsize; addr += GRANULE_4KB){ - mmu_map_4kb(kernel_hi_page, HIGH_VA + addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_hi_page, addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); } } @@ -222,10 +222,10 @@ void mmu_init() { mmu_start(kernel_lo_page, kernel_hi_page); - for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB) - mmu_unmap(addr, addr); - asm volatile (".global mmu_finish\nmmu_finish:"); + // for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB) + // mmu_unmap(addr, addr); + kprintf("Finished MMU init"); } From 1829d88d84245f5189fde74930c94bbf29b7c005 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Fri, 10 Oct 2025 00:00:00 +0000 Subject: [PATCH 08/43] [MMU] kernel sp to high --- kernel/memory/mmu_start.S | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/kernel/memory/mmu_start.S b/kernel/memory/mmu_start.S index c5bd8b81..b2561cbb 100644 --- a/kernel/memory/mmu_start.S +++ b/kernel/memory/mmu_start.S @@ -20,6 +20,23 @@ mmu_start://(uint64_t *low x0, uint64_t *high x1) ldr x1, =HIGH_VA + ldr x0, =ksp + orr x0, x0, x1 + adrp x3, ksp + str x0, [x3] + + mov x0, sp + orr x0, x0, x1 + mov sp, x0 + + mov x0, x29 + orr x0, x0, x1 + mov x29, x0 + + mov x0, x30 + orr x0, x0, x1 + mov x30, x0 + mrs x0, vbar_el1 orr x0, x0, x1 msr vbar_el1, x0 From ce24fefc06857e560f5815b17fc6d0a039a5625f Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Tue, 11 Nov 2025 00:00:00 +0000 Subject: [PATCH 09/43] [FW_CFG] replaced infinite loop with wait --- kernel/fw/fw_cfg.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/fw/fw_cfg.c b/kernel/fw/fw_cfg.c index 2055545f..90dfc2d7 100644 --- a/kernel/fw/fw_cfg.c +++ b/kernel/fw/fw_cfg.c @@ -2,6 +2,7 @@ #include "console/kio.h" #include "std/memory_access.h" #include "memory/mmu.h" +#include "async.h" #define FW_CFG_DATA 0x09020000 #define FW_CFG_CTL (FW_CFG_DATA + 0x8) @@ -41,9 +42,11 @@ void fw_cfg_dma_operation(void* dest, uint32_t size, uint32_t ctrl) { write64(FW_CFG_DMA, __builtin_bswap64((uint64_t)&access)); - __asm__("ISB"); + __asm__("isb"); - while (__builtin_bswap32(access.control) & ~0x1) {} + if (!wait(&access.control, __builtin_bswap32(~0x1), false, 2000)){ + kprintf("[FW_CFG error] failed to communicate with fw_cfg"); + } } From e09ea6e782692c58ea514943197bbc5833fd6244 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Thu, 13 Nov 2025 00:00:00 +0000 Subject: [PATCH 10/43] [MMU, TMP] virtual addressing (with kernel in both low+high for all processes) --- kernel/memory/mmu.c | 26 ++++++++++++++++++--- kernel/memory/mmu.h | 7 ++++++ kernel/memory/mmu_start.S | 5 ++++ kernel/process/context_switch.S | 16 +++++++++++++ kernel/process/loading/process_loader.c | 31 ++++++++++++++----------- kernel/process/process.h | 1 + kernel/process/scheduler.c | 1 + kernel/process/syscall.c | 1 - 8 files changed, 70 insertions(+), 18 deletions(-) diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 39d138aa..c241c4d5 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -9,6 +9,7 @@ #include "filesystem/disk.h" #include "memory/page_allocator.h" #include "sysregs.h" +#include "std/memory.h" #define PD_TABLE 0b11 #define PD_BLOCK 0b01 @@ -185,6 +186,9 @@ extern uint64_t shared_code_end; extern uint64_t shared_ro_end; extern uint64_t shared_end; +extern uintptr_t cpec; +extern uintptr_t ksp; + extern void mmu_start(uint64_t *low, uint64_t *high); void mmu_init() { @@ -219,29 +223,37 @@ void mmu_init() { } hw_high_va(); - + mmu_start(kernel_lo_page, kernel_hi_page); asm volatile (".global mmu_finish\nmmu_finish:"); - // for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB) - // mmu_unmap(addr, addr); kprintf("Finished MMU init"); } +uintptr_t* mmu_new_ttrb(){ + uintptr_t *ttrb = (uintptr_t *)talloc(PAGE_SIZE); + memcpy(ttrb, kernel_lo_page, PAGE_SIZE); + return ttrb; +} + void register_device_memory(uint64_t va, uint64_t pa){ + mmu_map_4kb(kernel_hi_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, 1); mmu_map_4kb(kernel_lo_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, 1); mmu_flush_all(); mmu_flush_icache(); } void register_device_memory_2mb(uint64_t va, uint64_t pa){ + mmu_map_2mb(kernel_hi_page, va, pa, MAIR_IDX_DEVICE); mmu_map_2mb(kernel_lo_page, va, pa, MAIR_IDX_DEVICE); mmu_flush_all(); mmu_flush_icache(); } void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t level){ + if (level == MEM_PRIV_KERNEL) + mmu_map_4kb(kernel_hi_page, va, pa, MAIR_IDX_NORMAL, attributes, level); mmu_map_4kb(kernel_lo_page, va, pa, MAIR_IDX_NORMAL, attributes, level); mmu_flush_all(); mmu_flush_icache(); @@ -289,3 +301,11 @@ void debug_mmu_address(uint64_t va){ kprintf("Entry: %b", l4_val); return; } + +extern void mmu_swap(uintptr_t* ttbr); + +uintptr_t *pttrb; + +void mmu_swap_ttbr(uintptr_t* ttbr){ + pttrb = ttbr ? ttbr : kernel_lo_page; +} diff --git a/kernel/memory/mmu.h b/kernel/memory/mmu.h index ea505d08..c8028871 100644 --- a/kernel/memory/mmu.h +++ b/kernel/memory/mmu.h @@ -10,14 +10,21 @@ void mmu_init(); #ifdef __cplusplus extern "C" { #endif +void mmu_map_kernel(uintptr_t *ttrb); +uintptr_t* mmu_new_ttrb(); void register_device_memory(uint64_t va, uint64_t pa); void register_device_memory_2mb(uint64_t va, uint64_t pa); void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t level); +void mmu_map_4kb(uint64_t *table, uint64_t va, uint64_t pa, uint64_t attr_index, uint8_t mem_attributes, uint8_t level); void debug_mmu_address(uint64_t va); void mmu_enable_verbose(); +void mmu_swap_ttbr(uintptr_t* ttbr); +void mmu_default_ttbr(); #ifdef __cplusplus } #endif +extern uintptr_t *pttrb; + void mmu_unmap(uint64_t va, uint64_t pa); void mmu_init_kernel(); \ No newline at end of file diff --git a/kernel/memory/mmu_start.S b/kernel/memory/mmu_start.S index b2561cbb..e5737f6b 100644 --- a/kernel/memory/mmu_start.S +++ b/kernel/memory/mmu_start.S @@ -25,6 +25,11 @@ mmu_start://(uint64_t *low x0, uint64_t *high x1) adrp x3, ksp str x0, [x3] + ldr x0, =cpec + orr x0, x0, x1 + adrp x3, cpec + str x0, [x3] + mov x0, sp orr x0, x0, x1 mov sp, x0 diff --git a/kernel/process/context_switch.S b/kernel/process/context_switch.S index b5ee4469..e78c2115 100644 --- a/kernel/process/context_switch.S +++ b/kernel/process/context_switch.S @@ -1,3 +1,5 @@ +#include "sysregs.h" + .global save_pc_interrupt save_pc_interrupt: mrs x1, elr_el1 @@ -51,6 +53,20 @@ restore_context: msr elr_el1, x17 mov x17, #0 + + ldr x18, =pttrb + + cmp x18, #0 + b.eq 4f + + ldr x18, [x18] + + msr ttbr0_el1, x18 + + tlbi vmalle1is +4: dsb ish + isb + mov x18, #0 eret \ No newline at end of file diff --git a/kernel/process/loading/process_loader.c b/kernel/process/loading/process_loader.c index 8962cd5e..4eca49f6 100644 --- a/kernel/process/loading/process_loader.c +++ b/kernel/process/loading/process_loader.c @@ -6,6 +6,8 @@ #include "exceptions/exception_handler.h" #include "std/memory.h" #include "memory/mmu.h" +#include "memory/talloc.h" +#include "sysregs.h" typedef struct { uint64_t code_base_start; @@ -302,21 +304,14 @@ process_t* create_process(const char *name, const char *bundle, sizedptr text, u // kprintf("Allocated space for process between %x and %x",dest,dest+((code_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))); - if (!allow_va || text_va + code_size >= LOWEST_ADDR){ - if (!allow_va) - kprintf("[PROCESS_LOADING IMPLEMENTATION WARNING] virtual addressing currently not supported for this process. System is limited to one VA process at a time :("); - else - kprintf("[PROCESS_LOADING IMPLEMENTATION WARNING] virtual addressing currently not supported for this process. Would overwrite %x",LOWEST_ADDR); - entry += dest - min_addr; - proc->use_va = false; - } else { - //TODO: multiple TTBRs - for (uint32_t i = min_addr; i < max_addr; i += GRANULE_4KB){ - register_proc_memory( i, (uintptr_t)dest + (i - min_addr), MEM_EXEC | MEM_RO | MEM_NORM, MEM_PRIV_USER); - } - proc->use_va = true; - allow_va = false; + uintptr_t *ttbr = mmu_new_ttrb(); + + for (uintptr_t i = min_addr; i < max_addr; i += GRANULE_4KB){ + mmu_map_4kb(ttbr, i, (uintptr_t)dest + (i - min_addr), MAIR_IDX_NORMAL, MEM_EXEC | MEM_RO | MEM_NORM, MEM_PRIV_USER); + register_proc_memory(i, (uintptr_t)dest + (i - min_addr), MEM_EXEC | MEM_RO | MEM_NORM, MEM_PRIV_USER); } + proc->use_va = true; + allow_va = false; map_section(proc, dest, min_addr, text_va, text); map_section(proc, dest, min_addr, data_va, data); @@ -332,13 +327,21 @@ process_t* create_process(const char *name, const char *bundle, sizedptr text, u uintptr_t stack = (uintptr_t)palloc(stack_size, MEM_PRIV_USER, MEM_RW, true); if (!stack) return 0; + //TODO: use VA stack & heap. And expand heap's mapping as it grows + for (uintptr_t i = stack; i < stack + stack_size; i += GRANULE_4KB) + mmu_map_4kb(ttbr, i, i, MAIR_IDX_NORMAL, MEM_RO | MEM_NORM, MEM_PRIV_USER); + uintptr_t heap = (uintptr_t)palloc(PAGE_SIZE, MEM_PRIV_USER, MEM_RW, false); if (!heap) return 0; + mmu_map_4kb(ttbr, heap, heap, MAIR_IDX_NORMAL, MEM_RO | MEM_NORM, MEM_PRIV_USER); + proc->stack = (stack + stack_size); proc->stack_size = stack_size; proc->heap = heap; + proc->ttbr = ttbr; + proc->sp = proc->stack; proc->pc = (uintptr_t)(entry); diff --git a/kernel/process/process.h b/kernel/process/process.h index e499f7c9..f2d37f0e 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -51,6 +51,7 @@ typedef struct { void *code; size_t code_size; bool use_va; + uintptr_t *ttbr; uintptr_t va; enum process_state { STOPPED, READY, RUNNING, BLOCKED } state; __attribute__((aligned(16))) input_buffer_t input_buffer; diff --git a/kernel/process/scheduler.c b/kernel/process/scheduler.c index c0494cad..64259c31 100644 --- a/kernel/process/scheduler.c +++ b/kernel/process/scheduler.c @@ -64,6 +64,7 @@ void switch_proc(ProcSwitchReason reason) { current_proc = next_proc; cpec = (uintptr_t)&processes[current_proc]; timer_reset(processes[current_proc].priority); + mmu_swap_ttbr(processes[current_proc].ttbr); process_restore(); } diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index 147fe0ad..94f54851 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -376,7 +376,6 @@ void sync_el0_handler_c(){ } } } - //We could handle more exceptions now, such as x25 (unmasked x96) = data abort. 0x21 at end of 0x25 = alignment fault if (currentEL == 1){ kprintf("System has crashed. ESR: %x. ELR: %x. FAR: %x", esr, elr, far); coredump(esr, elr, far, proc->sp); From d25955b7dc8f558525c8da5f0117d11a1b182cbf Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Thu, 13 Nov 2025 00:00:00 +0000 Subject: [PATCH 11/43] [MMU] moved mmu init further back --- kernel/kernel.c | 2 +- kernel/memory/mmu.c | 5 +++-- kernel/pci.c | 6 +++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/kernel/kernel.c b/kernel/kernel.c index 7ef6977a..ce90c860 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -57,6 +57,7 @@ void kernel_main() { load_module(&disk_module); bool input_available = load_module(&input_module); + mmu_init(); bool network_available = false; if (BOARD_TYPE == 1){ if (system_config.use_net) @@ -65,7 +66,6 @@ void kernel_main() { load_module(&audio_module); } - mmu_init(); kprint("Kernel initialization finished"); diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index c241c4d5..83e363b8 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -211,6 +211,7 @@ void mmu_init() { if (XHCI_BASE) for (uint64_t addr = XHCI_BASE; addr <= XHCI_BASE + 0x1000; addr += GRANULE_4KB){ + mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); mmu_map_4kb(kernel_hi_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); } @@ -238,8 +239,8 @@ uintptr_t* mmu_new_ttrb(){ } void register_device_memory(uint64_t va, uint64_t pa){ - mmu_map_4kb(kernel_hi_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, 1); - mmu_map_4kb(kernel_lo_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, 1); + mmu_map_4kb(kernel_hi_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_lo_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); mmu_flush_all(); mmu_flush_icache(); } diff --git a/kernel/pci.c b/kernel/pci.c index b74d243c..6e256f61 100644 --- a/kernel/pci.c +++ b/kernel/pci.c @@ -442,8 +442,12 @@ bool pci_setup_msix(uint64_t pci_addr, msix_irq_line* irq_lines, uint8_t line_si if(!table_addr){ uint64_t bar_size = 0; pci_setup_bar(pci_addr, bir, &table_addr, &bar_size); + pci_register(table_addr, bar_size); kprintf("Setting up new bar for MSI-X %x + %x",table_addr, table_addr_offset); - } else kprintf("Bar %i setup at %x + %x",bir, table_addr, table_addr_offset); + } else { + kprintf("Bar %i setup at %x + %x",bir, table_addr, table_addr_offset); + pci_register(table_addr, GRANULE_4KB); + } volatile msix_table_entry *msix_start = (volatile msix_table_entry *)(uintptr_t)(table_addr + table_addr_offset); From 0c4a4864e0cc8397fa263d9221600bfa6f43cc88 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Thu, 13 Nov 2025 00:00:00 +0000 Subject: [PATCH 12/43] [MMU] moved hardcoded mmu mappings to own file --- kernel/console/serial/uart.c | 3 +++ kernel/exceptions/irq.c | 4 ++++ kernel/input/xhci.cpp | 2 ++ kernel/memory/mmu.c | 15 --------------- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/kernel/console/serial/uart.c b/kernel/console/serial/uart.c index a375b869..5d29c9cc 100644 --- a/kernel/console/serial/uart.c +++ b/kernel/console/serial/uart.c @@ -3,6 +3,7 @@ #include "gpio.h" #include "hw/hw.h" #include "mailbox/mailbox.h" +#include "memory/mmu.h" #define UART0_DR (UART0_BASE + 0x00) #define UART0_FR (UART0_BASE + 0x18) @@ -29,6 +30,8 @@ volatile uint32_t uart_mbox[9] __attribute__((aligned(16))) = { }; void enable_uart() { + register_device_memory(UART0_CR, UART0_CR); + write32(UART0_CR, 0x0); uint32_t ibrd = 1; diff --git a/kernel/exceptions/irq.c b/kernel/exceptions/irq.c index 6b9ad6f9..6518706a 100644 --- a/kernel/exceptions/irq.c +++ b/kernel/exceptions/irq.c @@ -11,6 +11,7 @@ #include "audio/audio.h" #include "networking/interface_manager.h" #include "process/syscall.h" +#include "memory/mmu.h" #define IRQ_TIMER 30 #define SLEEP_TIMER 27 @@ -40,6 +41,9 @@ static void gic_enable_irq(uint32_t irq, uint8_t priority, uint8_t cpu_target) { } void irq_init() { + register_device_memory(GICD_BASE, GICD_BASE); + register_device_memory(GICC_BASE, GICC_BASE); + if (RPI_BOARD != 3){ write32(GICD_BASE, 0); // Disable Distributor write32(GICC_BASE, 0); // Disable CPU Interface diff --git a/kernel/input/xhci.cpp b/kernel/input/xhci.cpp index 41085ee4..ba5c902e 100644 --- a/kernel/input/xhci.cpp +++ b/kernel/input/xhci.cpp @@ -9,6 +9,7 @@ #include "std/memory.h" #include "async.h" #include "memory/page_allocator.h" +#include "memory/mmu.h" uint64_t awaited_addr; uint32_t awaited_type; @@ -56,6 +57,7 @@ bool XHCIDriver::init(){ if (XHCI_BASE){ addr = XHCI_BASE; mmio = addr; + register_device_memory(mmio, mmio); if (BOARD_TYPE == 2 && RPI_BOARD >= 5) quirk_simulate_interrupts = !pci_setup_msi_rp1(36, true); } else if (PCI_BASE) { diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 83e363b8..c04d0bec 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -192,7 +192,6 @@ extern uintptr_t ksp; extern void mmu_start(uint64_t *low, uint64_t *high); void mmu_init() { - //TODO: Move these hardcoded mappings to their own file uint64_t kstart = mem_get_kmem_start(); uint64_t kend = mem_get_kmem_end(); @@ -201,20 +200,6 @@ void mmu_init() { mmu_map_2mb(kernel_hi_page, addr, addr, MAIR_IDX_NORMAL); } - for (uint64_t addr = get_uart_base(); addr <= get_uart_base(); addr += GRANULE_4KB){ - mmu_map_4kb(kernel_hi_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); - } - - for (uint64_t addr = GICD_BASE; addr <= GICC_BASE + 0x1000; addr += GRANULE_4KB){ - mmu_map_4kb(kernel_hi_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); - } - - if (XHCI_BASE) - for (uint64_t addr = XHCI_BASE; addr <= XHCI_BASE + 0x1000; addr += GRANULE_4KB){ - mmu_map_4kb(kernel_lo_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); - mmu_map_4kb(kernel_hi_page, addr, addr, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); - } - uint64_t dstart; uint64_t dsize; if (dtb_addresses(&dstart,&dsize)){ From 2126b65dc2b013aa0b06cdfa88da81e407d3566e Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Thu, 13 Nov 2025 00:00:00 +0000 Subject: [PATCH 13/43] [PI] fixed SDHCI for QEMU and boot partition --- kernel/bin/bin_mod.c | 2 +- kernel/hw/hw.c | 4 ++++ kernel/kernel_processes/windows/launcher.cpp | 4 ++-- run_raspi | 4 +--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/kernel/bin/bin_mod.c b/kernel/bin/bin_mod.c index 18015a26..644eee49 100644 --- a/kernel/bin/bin_mod.c +++ b/kernel/bin/bin_mod.c @@ -38,7 +38,7 @@ process_t* execute(const char* prog_name, int argc, const char* argv[]){ char *f = reader; if (*f){ if (strcmp(f, full_name, true) == 0){ - string path = string_format("/shared/redos/bin/%s",full_name); + string path = string_format("/boot/redos/bin/%s",full_name); file fd = {}; FS_RESULT op = fopen(path.data, &fd); if (op != FS_RESULT_SUCCESS){ diff --git a/kernel/hw/hw.c b/kernel/hw/hw.c index dbc44938..84c8c79e 100644 --- a/kernel/hw/hw.c +++ b/kernel/hw/hw.c @@ -44,7 +44,11 @@ void detect_hardware(){ MMIO_BASE = 0xFE000000; RPI_BOARD = 4; GPIO_PIN_BASE = 0x50; + #if QEMU + SDHCI_BASE = MMIO_BASE + 0x300000;//EMMC2 direct, no routing needed + #else SDHCI_BASE = MMIO_BASE + 0x340000;//EMMC2 direct, no routing needed + #endif GICD_BASE = MMIO_BASE + 0x1841000; GICC_BASE = MMIO_BASE + 0x1842000; PCI_BASE = 0xFD500000; diff --git a/kernel/kernel_processes/windows/launcher.cpp b/kernel/kernel_processes/windows/launcher.cpp index f028ba7c..cb6dd0d5 100644 --- a/kernel/kernel_processes/windows/launcher.cpp +++ b/kernel/kernel_processes/windows/launcher.cpp @@ -57,7 +57,7 @@ void Launcher::load_entries(){ entries.empty(); size_t listsize = 0x1000; void *listptr = malloc(listsize); - if (!list_directory_contents("/shared/redos/user/", listptr, listsize, 0)){ + if (!list_directory_contents("/boot/redos/user/", listptr, listsize, 0)){ kprintf("Failed to read contents of directory"); return; } @@ -67,7 +67,7 @@ void Launcher::load_entries(){ for (uint32_t i = 0; i < list->count; i++){ char *file = reader; if (*file){ - string fullpath = string_format("/shared/redos/user/%s",(uintptr_t)file); + string fullpath = string_format("/boot/redos/user/%s",(uintptr_t)file); string name = string_from_literal_length(file,find_extension(file)); string ext = string_from_literal(file + find_extension(file)); if (strcmp(ext.data,".red", true) == 0){ diff --git a/run_raspi b/run_raspi index 780aba83..8e2ec46b 100755 --- a/run_raspi +++ b/run_raspi @@ -12,8 +12,7 @@ OS_TYPE="$(uname)" DISPLAY_MODE="default" if [ "$OS_TYPE" = "Darwin" ]; then - NETARG="vmnet-bridged,id=net0,ifname=en0" - PRIVILEGE="sudo" + PRIVILEGE="" DISPLAY_MODE="cocoa" elif [ "$OS_TYPE" = "Linux" ]; then NETARG="user,id=net0" @@ -28,7 +27,6 @@ $PRIVILEGE qemu-system-aarch64 \ -kernel kernel.img \ -display $DISPLAY_MODE \ -device sd-card,drive=sd -drive id=sd,format=raw,file=disk.img,if=none \ --netdev $NETARG \ -serial mon:stdio \ -device usb-kbd \ -device usb-mouse \ From 0bb77db756f689b7391778f566fb48becfed9f4f Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Fri, 14 Nov 2025 00:00:00 +0000 Subject: [PATCH 14/43] [MMU] DWC2 mapping --- kernel/input/dwc2.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/input/dwc2.cpp b/kernel/input/dwc2.cpp index 85881ad4..57af1d2f 100644 --- a/kernel/input/dwc2.cpp +++ b/kernel/input/dwc2.cpp @@ -36,6 +36,8 @@ bool DWC2Driver::init() { use_interrupts = false; + register_device_memory(DWC2_BASE, DWC2_BASE); + dwc2 = (dwc2_regs*)DWC2_BASE; host = (dwc2_host*)(DWC2_BASE + 0x400); From 6ecc579a4e6b625d0d832790615ef5d3259fbc4f Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Fri, 14 Nov 2025 00:00:00 +0000 Subject: [PATCH 15/43] [MMU] switched to using single kernel map page --- kernel/kernel_processes/windows/launcher.cpp | 4 +- kernel/memory/mmu.c | 41 ++++++++------------ kernel/memory/mmu_start.S | 4 +- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/kernel/kernel_processes/windows/launcher.cpp b/kernel/kernel_processes/windows/launcher.cpp index cb6dd0d5..f028ba7c 100644 --- a/kernel/kernel_processes/windows/launcher.cpp +++ b/kernel/kernel_processes/windows/launcher.cpp @@ -57,7 +57,7 @@ void Launcher::load_entries(){ entries.empty(); size_t listsize = 0x1000; void *listptr = malloc(listsize); - if (!list_directory_contents("/boot/redos/user/", listptr, listsize, 0)){ + if (!list_directory_contents("/shared/redos/user/", listptr, listsize, 0)){ kprintf("Failed to read contents of directory"); return; } @@ -67,7 +67,7 @@ void Launcher::load_entries(){ for (uint32_t i = 0; i < list->count; i++){ char *file = reader; if (*file){ - string fullpath = string_format("/boot/redos/user/%s",(uintptr_t)file); + string fullpath = string_format("/shared/redos/user/%s",(uintptr_t)file); string name = string_from_literal_length(file,find_extension(file)); string ext = string_from_literal(file + find_extension(file)); if (strcmp(ext.data,".red", true) == 0){ diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index c04d0bec..fcb4d433 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -26,7 +26,7 @@ #define VIRT_TO_PHYS(x) ((VirtualAddr)x - HIGH_VA) #define PHYS_TO_VIRT(x) ((PhysicalAddr)x + HIGH_VA) -uint64_t *kernel_lo_page, *kernel_hi_page; +uint64_t *kernel_mmu_page; static bool mmu_verbose; @@ -143,7 +143,7 @@ static inline void mmu_flush_icache() { void mmu_unmap(uint64_t va, uint64_t pa){ - uint64_t *table = kernel_lo_page; + uint64_t *table = kernel_mmu_page; uint64_t l0_index = (va >> 39) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; @@ -173,8 +173,7 @@ void mmu_unmap(uint64_t va, uint64_t pa){ } void mmu_init_kernel(){ - kernel_lo_page = mmu_alloc(); - kernel_hi_page = mmu_alloc(); + kernel_mmu_page = mmu_alloc(); } uint64_t *mmu_alloc(){ @@ -189,28 +188,24 @@ extern uint64_t shared_end; extern uintptr_t cpec; extern uintptr_t ksp; -extern void mmu_start(uint64_t *low, uint64_t *high); +extern void mmu_start(uint64_t *mmu); void mmu_init() { uint64_t kstart = mem_get_kmem_start(); uint64_t kend = mem_get_kmem_end(); - for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB){ - mmu_map_2mb(kernel_lo_page, addr, addr, MAIR_IDX_NORMAL); - mmu_map_2mb(kernel_hi_page, addr, addr, MAIR_IDX_NORMAL); - } + for (uint64_t addr = kstart; addr < kend; addr += GRANULE_2MB) + mmu_map_2mb(kernel_mmu_page, addr, addr, MAIR_IDX_NORMAL); uint64_t dstart; uint64_t dsize; - if (dtb_addresses(&dstart,&dsize)){ - for (uint64_t addr = dstart; addr <= dstart + dsize; addr += GRANULE_4KB){ - mmu_map_4kb(kernel_hi_page, addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); - } - } + if (dtb_addresses(&dstart,&dsize)) + for (uint64_t addr = dstart; addr <= dstart + dsize; addr += GRANULE_4KB) + mmu_map_4kb(kernel_mmu_page, addr, addr, MAIR_IDX_NORMAL, MEM_RO, MEM_PRIV_KERNEL); hw_high_va(); - mmu_start(kernel_lo_page, kernel_hi_page); + mmu_start(kernel_mmu_page); asm volatile (".global mmu_finish\nmmu_finish:"); @@ -219,35 +214,31 @@ void mmu_init() { uintptr_t* mmu_new_ttrb(){ uintptr_t *ttrb = (uintptr_t *)talloc(PAGE_SIZE); - memcpy(ttrb, kernel_lo_page, PAGE_SIZE); + memcpy(ttrb, kernel_mmu_page, PAGE_SIZE); return ttrb; } void register_device_memory(uint64_t va, uint64_t pa){ - mmu_map_4kb(kernel_hi_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); - mmu_map_4kb(kernel_lo_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_4kb(kernel_mmu_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); mmu_flush_all(); mmu_flush_icache(); } void register_device_memory_2mb(uint64_t va, uint64_t pa){ - mmu_map_2mb(kernel_hi_page, va, pa, MAIR_IDX_DEVICE); - mmu_map_2mb(kernel_lo_page, va, pa, MAIR_IDX_DEVICE); + mmu_map_2mb(kernel_mmu_page, va, pa, MAIR_IDX_DEVICE); mmu_flush_all(); mmu_flush_icache(); } void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t level){ - if (level == MEM_PRIV_KERNEL) - mmu_map_4kb(kernel_hi_page, va, pa, MAIR_IDX_NORMAL, attributes, level); - mmu_map_4kb(kernel_lo_page, va, pa, MAIR_IDX_NORMAL, attributes, level); + mmu_map_4kb(kernel_mmu_page, va, pa, MAIR_IDX_NORMAL, attributes, level); mmu_flush_all(); mmu_flush_icache(); } void debug_mmu_address(uint64_t va){ - uint64_t *table = kernel_lo_page; + uint64_t *table = kernel_mmu_page; uint64_t l0_index = (va >> 37) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; @@ -293,5 +284,5 @@ extern void mmu_swap(uintptr_t* ttbr); uintptr_t *pttrb; void mmu_swap_ttbr(uintptr_t* ttbr){ - pttrb = ttbr ? ttbr : kernel_lo_page; + pttrb = ttbr ? ttbr : kernel_mmu_page; } diff --git a/kernel/memory/mmu_start.S b/kernel/memory/mmu_start.S index e5737f6b..ed953574 100644 --- a/kernel/memory/mmu_start.S +++ b/kernel/memory/mmu_start.S @@ -1,7 +1,7 @@ #include "sysregs.h" .global mmu_start -mmu_start://(uint64_t *low x0, uint64_t *high x1) +mmu_start://(uint64_t *page x0) ldr x3, =MAIR_VALUE msr mair_el1, x3 ldr x3, =TCR_VALUE @@ -10,7 +10,7 @@ mmu_start://(uint64_t *low x0, uint64_t *high x1) isb msr ttbr0_el1, x0 - msr ttbr1_el1, x1 + msr ttbr1_el1, x0 mrs x0, sctlr_el1 orr x0, x0, #0x1 From 7dd25aa0b7abf0d386b871750fc3847f9e23a3e2 Mon Sep 17 00:00:00 2001 From: dif Date: Fri, 14 Nov 2025 00:00:00 +0000 Subject: [PATCH 16/43] [MMU] removed double mapping --- kernel/process/loading/process_loader.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/process/loading/process_loader.c b/kernel/process/loading/process_loader.c index 4eca49f6..237b97a5 100644 --- a/kernel/process/loading/process_loader.c +++ b/kernel/process/loading/process_loader.c @@ -308,7 +308,6 @@ process_t* create_process(const char *name, const char *bundle, sizedptr text, u for (uintptr_t i = min_addr; i < max_addr; i += GRANULE_4KB){ mmu_map_4kb(ttbr, i, (uintptr_t)dest + (i - min_addr), MAIR_IDX_NORMAL, MEM_EXEC | MEM_RO | MEM_NORM, MEM_PRIV_USER); - register_proc_memory(i, (uintptr_t)dest + (i - min_addr), MEM_EXEC | MEM_RO | MEM_NORM, MEM_PRIV_USER); } proc->use_va = true; allow_va = false; From dd0abdfd18dc72e3cb266f889e33b2e34c6543a5 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sat, 15 Nov 2025 00:00:00 +0000 Subject: [PATCH 17/43] [LAUNCHER] reordered process alloc operations --- kernel/kernel_processes/windows/launcher.cpp | 4 ++-- kernel/process/loading/process_loader.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/kernel/kernel_processes/windows/launcher.cpp b/kernel/kernel_processes/windows/launcher.cpp index f028ba7c..126e27f2 100644 --- a/kernel/kernel_processes/windows/launcher.cpp +++ b/kernel/kernel_processes/windows/launcher.cpp @@ -188,11 +188,11 @@ void Launcher::activate_current(){ } active_proc->win_id = get_current_proc()->win_id; active_proc->priority = PROC_PRIORITY_FULL; - kprintf("[LAUNCHER] process launched"); - enable_interrupt(); process_active = true; sys_set_focus(active_proc->id); active_proc->state = process_t::process_state::READY; + kprintf("[LAUNCHER] process launched"); + enable_interrupt(); } } diff --git a/kernel/process/loading/process_loader.c b/kernel/process/loading/process_loader.c index 4eca49f6..1f24479a 100644 --- a/kernel/process/loading/process_loader.c +++ b/kernel/process/loading/process_loader.c @@ -344,12 +344,11 @@ process_t* create_process(const char *name, const char *bundle, sizedptr text, u proc->sp = proc->stack; + proc->output = (uintptr_t)palloc(0x1000, MEM_PRIV_USER, MEM_RW, true); proc->pc = (uintptr_t)(entry); kprintf("User process %s allocated with address at %x, stack at %x, heap at %x",(uintptr_t)name,proc->pc, proc->sp, proc->heap); proc->spsr = 0; proc->state = BLOCKED; - - proc->output = (uintptr_t)palloc(0x1000, MEM_PRIV_USER, MEM_RW, true); return proc; } \ No newline at end of file From 66c5b08b299de16a6403d66e810a2f5cf77fc60b Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sat, 15 Nov 2025 00:00:00 +0000 Subject: [PATCH 18/43] [MMU] copy current mappings to new ttbr --- kernel/memory/mmu.c | 35 ++++++++++++++++++++++++++++++++--- user/default_process.c | 3 --- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index fcb4d433..c9925a80 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -212,25 +212,54 @@ void mmu_init() { kprintf("Finished MMU init"); } +void mmu_copy(uintptr_t *new_ttrb, uintptr_t *old_ttrb, int level){ + for (int i = 0; i < PAGE_TABLE_ENTRIES; i++){ + if (old_ttrb[i] & 1){ + kprintf("TLE %b %x %i",old_ttrb[i] & 0b11,old_ttrb[i],level); + if (level == 3 || (old_ttrb[i] & 0b11) == PD_BLOCK){ + new_ttrb[i] = old_ttrb[i]; + } else { + kprintf("Old Entry %x",old_ttrb[i]); + uintptr_t *old_entry = (uintptr_t*)(old_ttrb[i] & 0xFFFFFFFFF000ULL); + uintptr_t *new_entry = mmu_alloc(); + if (!old_entry || !new_entry) continue; + kprintf("[%i] %x -> %x",level,old_entry, new_entry); + uint64_t entry = old_ttrb[i] & ~(0xFFFFFFFFF000ULL); + kprintf("Entry %x",entry); + new_ttrb[i] = entry | ((uintptr_t)new_entry & 0xFFFFFFFFF000ULL); + kprintf("Full entry %x",new_ttrb[i]); + if (level < 3) mmu_copy(new_entry, old_entry, level+1); + } + } + } +} + uintptr_t* mmu_new_ttrb(){ - uintptr_t *ttrb = (uintptr_t *)talloc(PAGE_SIZE); - memcpy(ttrb, kernel_mmu_page, PAGE_SIZE); + uintptr_t *ttrb = mmu_alloc(); + mmu_copy(ttrb, kernel_mmu_page,0); return ttrb; } void register_device_memory(uint64_t va, uint64_t pa){ + if (pttrb && pttrb != kernel_mmu_page)//TODO: This won't be necessary once kernel is exclusively in ttbr1 + mmu_map_4kb(pttrb, va, pa, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); mmu_map_4kb(kernel_mmu_page, va, pa, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); mmu_flush_all(); mmu_flush_icache(); } void register_device_memory_2mb(uint64_t va, uint64_t pa){ + if (pttrb && pttrb != kernel_mmu_page)//TODO: This won't be necessary once kernel is exclusively in ttbr1 + mmu_map_4kb(pttrb, va, pa, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); mmu_map_2mb(kernel_mmu_page, va, pa, MAIR_IDX_DEVICE); mmu_flush_all(); mmu_flush_icache(); } void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t level){ + if (pttrb && pttrb != kernel_mmu_page) + mmu_map_4kb(pttrb, va, pa, MAIR_IDX_NORMAL, attributes, level); + mmu_map_4kb(kernel_mmu_page, va, pa, MAIR_IDX_NORMAL, attributes, level); mmu_flush_all(); mmu_flush_icache(); @@ -238,7 +267,7 @@ void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t void debug_mmu_address(uint64_t va){ - uint64_t *table = kernel_mmu_page; + uint64_t *table = pttrb; uint64_t l0_index = (va >> 37) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; diff --git a/user/default_process.c b/user/default_process.c index f797aa92..1c9d9cd1 100644 --- a/user/default_process.c +++ b/user/default_process.c @@ -27,9 +27,6 @@ int img_example() { } resize_draw_ctx(&ctx, info.width+BORDER*2, info.height+BORDER*2); while (1) { - mouse_input mouse = {}; - get_mouse_status(&mouse); - // printf("Mouse %i",mouse.x); keypress kp = {}; // printf("Print console test %f", (get_time()/1000.f)); if (read_key(&kp)) From 6d55edb206e14d37d9ed65968ad3c224dbab6aad Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 19/43] [MMU] virt <-> phys memory translations --- kernel/sysregs.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/sysregs.h b/kernel/sysregs.h index 4ff34046..81791544 100644 --- a/kernel/sysregs.h +++ b/kernel/sysregs.h @@ -62,4 +62,8 @@ #define MAIR_VALUE ((MAIR_DEVICE_nGnRnE << (MAIR_IDX_DEVICE * 8)) | (MAIR_NORMAL_NOCACHE << (MAIR_IDX_NORMAL * 8))) -#define HIGH_VA 0xFFFF000000000000ULL \ No newline at end of file +#define HIGH_VA 0xFFFF000000000000ULL +#define VIRT_TO_PHYS(x) (x & ~HIGH_VA) +#define PHYS_TO_VIRT(x) (x | HIGH_VA) + +#define VIRT_TO_PHYS_P(x) ((void*)(((uintptr_t)x) & ~HIGH_VA)) \ No newline at end of file From b60c27990bed1a14bd894ae010245b7d3e72482f Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 20/43] [MMU] mappings for FW_CFG --- kernel/fw/fw_cfg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/fw/fw_cfg.c b/kernel/fw/fw_cfg.c index 90dfc2d7..a32deaea 100644 --- a/kernel/fw/fw_cfg.c +++ b/kernel/fw/fw_cfg.c @@ -3,6 +3,7 @@ #include "std/memory_access.h" #include "memory/mmu.h" #include "async.h" +#include "sysregs.h" #define FW_CFG_DATA 0x09020000 #define FW_CFG_CTL (FW_CFG_DATA + 0x8) @@ -26,21 +27,20 @@ struct fw_cfg_dma_access { bool fw_cfg_check(){ if (checked) return true; + register_device_memory(FW_CFG_DATA, FW_CFG_DATA); checked = read64(FW_CFG_DATA) == 0x554D4551; - if (checked){ - register_device_memory(FW_CFG_DATA, FW_CFG_DATA); - } + if (!checked) mmu_unmap(FW_CFG_DATA, FW_CFG_DATA); return checked; } void fw_cfg_dma_operation(void* dest, uint32_t size, uint32_t ctrl) { struct fw_cfg_dma_access access = { - .address = __builtin_bswap64((uint64_t)dest), + .address = __builtin_bswap64(VIRT_TO_PHYS((uint64_t)dest)), .length = __builtin_bswap32(size), .control = __builtin_bswap32(ctrl), }; - write64(FW_CFG_DMA, __builtin_bswap64((uint64_t)&access)); + write64(FW_CFG_DMA, __builtin_bswap64(VIRT_TO_PHYS((uint64_t)&access))); __asm__("isb"); @@ -70,7 +70,7 @@ bool fw_find_file(const char* search, struct fw_cfg_file *file) { return false; uint32_t count; - fw_cfg_dma_read(&count, sizeof(count), FW_LIST_DIRECTORY); + fw_cfg_dma_read(VIRT_TO_PHYS_P(&count), sizeof(count), FW_LIST_DIRECTORY); count = __builtin_bswap32(count); From 6bb91f6417fbcacfa3fd67e719c9455d83aeb94d Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 21/43] [MMU] removed double definition & fixed debug --- kernel/memory/mmu.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index c9925a80..67c572b1 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -23,9 +23,6 @@ #define PAGE_TABLE_ENTRIES 512 -#define VIRT_TO_PHYS(x) ((VirtualAddr)x - HIGH_VA) -#define PHYS_TO_VIRT(x) ((PhysicalAddr)x + HIGH_VA) - uint64_t *kernel_mmu_page; static bool mmu_verbose; @@ -267,7 +264,7 @@ void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t void debug_mmu_address(uint64_t va){ - uint64_t *table = pttrb; + uint64_t *table = pttrb ? pttrb : kernel_mmu_page; uint64_t l0_index = (va >> 37) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; From 3ca482157776b0a218d68395e8e735aa527c7556 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 22/43] [MMU] PCI mappings to phys --- kernel/pci.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/pci.c b/kernel/pci.c index 6e256f61..417a6a2c 100644 --- a/kernel/pci.c +++ b/kernel/pci.c @@ -5,6 +5,7 @@ #include "memory/mmu.h" #include "std/memory_access.h" #include "hw/hw.h" +#include "sysregs.h" #define PCI_BUS_MAX 256 #define PCI_SLOT_MAX 32 @@ -210,6 +211,8 @@ uint64_t pci_setup_bar(uint64_t pci_addr, uint32_t bar_index, uint64_t *mmio_sta *mmio_start = config_base; *mmio_size = size; + config_base = VIRT_TO_PHYS(config_base); + write32(bar_addr, config_base & 0xFFFFFFFF); write32(bar_addr_hi, config_base >> 32); @@ -231,6 +234,8 @@ uint64_t pci_setup_bar(uint64_t pci_addr, uint32_t bar_index, uint64_t *mmio_sta *mmio_start = config_base; *mmio_size = size32; + config_base = VIRT_TO_PHYS(config_base); + write32(bar_addr, config_base & 0xFFFFFFFF); } @@ -284,7 +289,7 @@ void pci_register(uint64_t mmio_addr, uint64_t mmio_size){ uint64_t start = mmio_addr & ~(GRANULE_4KB - 1); uint64_t end = (mmio_addr + mmio_size + GRANULE_4KB - 1) & ~(GRANULE_4KB - 1); for (uint64_t addr = start; addr < end; addr += GRANULE_4KB) - register_device_memory(addr,addr); + register_device_memory(PHYS_TO_VIRT(addr), VIRT_TO_PHYS(addr)); } #pragma region Interrupts From baafe48b7e5c818c2a30b907c70669aca016e032 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 23/43] [VIRTIO] used typedef and volatile for structs --- kernel/audio/virtio_audio_pci.cpp | 2 +- kernel/filesystem/virtio_blk_pci.c | 31 ++++++----------- .../drivers/virtio_net_pci/virtio_net_pci.cpp | 20 +++++------ kernel/virtio/virtio_pci.c | 34 +++++++++---------- kernel/virtio/virtio_pci.h | 18 +++++----- 5 files changed, 47 insertions(+), 58 deletions(-) diff --git a/kernel/audio/virtio_audio_pci.cpp b/kernel/audio/virtio_audio_pci.cpp index 81b7d23c..85ae09f0 100644 --- a/kernel/audio/virtio_audio_pci.cpp +++ b/kernel/audio/virtio_audio_pci.cpp @@ -206,7 +206,7 @@ bool VirtioAudioDriver::config_streams(uint32_t streams){ void VirtioAudioDriver::send_buffer(sizedptr buf){ virtio_add_buffer(&audio_dev, cmd_index % audio_dev.common_cfg->queue_size, buf.ptr, buf.size, true); - struct virtq_used* u = (struct virtq_used*)(uintptr_t)audio_dev.common_cfg->queue_device; + volatile virtq_used* u = (virtq_used*)audio_dev.common_cfg->queue_device; while (u->idx < cmd_index-2) ; // TODO: yield cpu cmd_index++; diff --git a/kernel/filesystem/virtio_blk_pci.c b/kernel/filesystem/virtio_blk_pci.c index 01a725bc..c0a2b7de 100644 --- a/kernel/filesystem/virtio_blk_pci.c +++ b/kernel/filesystem/virtio_blk_pci.c @@ -1,3 +1,4 @@ +#include "virtio_blk_pci.h" #include "disk.h" #include "std/string.h" #include "std/memory_access.h" @@ -6,28 +7,16 @@ #include "pci.h" #include "virtio/virtio_pci.h" #include "std/memory.h" -#include "virtio_blk_pci.h" +#include "sysregs.h" #define VIRTIO_BLK_T_IN 0 #define VIRTIO_BLK_T_OUT 1 -struct virtio_blk_req { +typedef struct { uint32_t type; uint32_t reserved; uint64_t sector; -} __attribute__((packed)); - -struct virtio_blk_config { - uint64_t capacity;//In number of sectors - uint32_t size_max; - uint32_t seg_max; - struct { - uint16_t cylinders; - uint8_t heads; - uint8_t sectors; - } geometry; - uint32_t blk_size; -} __attribute__((packed)); +} __attribute__((packed)) virtio_blk_req; #define VIRTIO_BLK_SUPPORTED_FEATURES \ ((1 << 0) | (1 << 1) | (1 << 4)) @@ -72,28 +61,28 @@ bool vblk_find_disk(){ void* disk_cmd; void vblk_write(const void *buffer, uint32_t sector, uint32_t count) { - if (!disk_cmd) disk_cmd = kalloc(blk_dev.memory_page, sizeof(struct virtio_blk_req), ALIGN_64B, MEM_PRIV_KERNEL); + if (!disk_cmd) disk_cmd = kalloc(blk_dev.memory_page, sizeof(virtio_blk_req), ALIGN_64B, MEM_PRIV_KERNEL); void* data = kalloc(blk_dev.memory_page, count * 512, ALIGN_64B, MEM_PRIV_KERNEL); memcpy(data, buffer, count * 512); - struct virtio_blk_req *req = (struct virtio_blk_req *)(uintptr_t)disk_cmd; + virtio_blk_req *req = (virtio_blk_req *)disk_cmd; req->type = VIRTIO_BLK_T_OUT; req->reserved = 0; req->sector = sector; - virtio_send_3d(&blk_dev, (uintptr_t)disk_cmd, sizeof(struct virtio_blk_req), (uintptr_t)data, count * 512, 0); + virtio_send_3d(&blk_dev, (uintptr_t)disk_cmd, sizeof(virtio_blk_req), (uintptr_t)data, count * 512, 0); kfree((void *)data,count * 512); } void vblk_read(void *buffer, uint32_t sector, uint32_t count) { - if (!disk_cmd) disk_cmd = kalloc(blk_dev.memory_page, sizeof(struct virtio_blk_req), ALIGN_64B, MEM_PRIV_KERNEL); + if (!disk_cmd) disk_cmd = kalloc(blk_dev.memory_page, sizeof(virtio_blk_req), ALIGN_64B, MEM_PRIV_KERNEL); - struct virtio_blk_req *req = (struct virtio_blk_req *)disk_cmd; + virtio_blk_req *req = (virtio_blk_req *)disk_cmd; req->type = VIRTIO_BLK_T_IN; req->reserved = 0; req->sector = sector; - virtio_send_3d(&blk_dev, (uintptr_t)disk_cmd, sizeof(struct virtio_blk_req), (uintptr_t)buffer, count * 512, VIRTQ_DESC_F_WRITE); + virtio_send_3d(&blk_dev, VIRT_TO_PHYS((uintptr_t)disk_cmd), sizeof(virtio_blk_req), VIRT_TO_PHYS((uintptr_t)buffer), count * 512, VIRTQ_DESC_F_WRITE); } \ No newline at end of file diff --git a/kernel/networking/drivers/virtio_net_pci/virtio_net_pci.cpp b/kernel/networking/drivers/virtio_net_pci/virtio_net_pci.cpp index 371cb58c..d5b5e478 100644 --- a/kernel/networking/drivers/virtio_net_pci/virtio_net_pci.cpp +++ b/kernel/networking/drivers/virtio_net_pci/virtio_net_pci.cpp @@ -158,9 +158,9 @@ sizedptr VirtioNetDriver::allocate_packet(size_t size){ sizedptr VirtioNetDriver::handle_receive_packet(){ select_queue(&vnp_net_dev, RECEIVE_QUEUE); - struct virtq_used* used = (struct virtq_used*)(uintptr_t)vnp_net_dev.common_cfg->queue_device; - struct virtq_desc* desc = (struct virtq_desc*)(uintptr_t)vnp_net_dev.common_cfg->queue_desc; - struct virtq_avail* avail = (struct virtq_avail*)(uintptr_t)vnp_net_dev.common_cfg->queue_driver; + volatile virtq_used* used = (virtq_used*)vnp_net_dev.common_cfg->queue_device; + volatile virtq_desc* desc = (virtq_desc*)vnp_net_dev.common_cfg->queue_desc; + volatile virtq_avail* avail = (virtq_avail*)vnp_net_dev.common_cfg->queue_driver; uint16_t qsz = vnp_net_dev.common_cfg->queue_size; uint16_t new_idx = used->idx; @@ -169,7 +169,7 @@ sizedptr VirtioNetDriver::handle_receive_packet(){ } uint16_t used_ring_index = (uint16_t)(last_used_receive_idx % qsz); - struct virtq_used_elem* e = &used->ring[used_ring_index]; + volatile virtq_used_elem* e = &used->ring[used_ring_index]; last_used_receive_idx++; uint32_t desc_index = e->id; @@ -178,7 +178,7 @@ sizedptr VirtioNetDriver::handle_receive_packet(){ { avail->ring[avail->idx % qsz] = (uint16_t)desc_index; avail->idx++; - *(volatile uint16_t*)(uintptr_t)(vnp_net_dev.notify_cfg + vnp_net_dev.notify_off_multiplier * RECEIVE_QUEUE) = 0; + *(volatile uint16_t*)(vnp_net_dev.notify_cfg + vnp_net_dev.notify_off_multiplier * RECEIVE_QUEUE) = 0; return (sizedptr){0,0}; } @@ -189,14 +189,14 @@ sizedptr VirtioNetDriver::handle_receive_packet(){ if (!out_buf){ avail->ring[avail->idx % qsz] = (uint16_t)desc_index; avail->idx++; - *(volatile uint16_t*)(uintptr_t)(vnp_net_dev.notify_cfg + vnp_net_dev.notify_off_multiplier * RECEIVE_QUEUE) = 0; + *(volatile uint16_t*)(vnp_net_dev.notify_cfg + vnp_net_dev.notify_off_multiplier * RECEIVE_QUEUE) = 0; return (sizedptr){0,0}; } memcpy(out_buf, (void*)(packet_addr + header_size), payload_len); avail->ring[avail->idx % qsz] = (uint16_t)desc_index; avail->idx++; - *(volatile uint16_t*)(uintptr_t)(vnp_net_dev.notify_cfg + vnp_net_dev.notify_off_multiplier * RECEIVE_QUEUE) = 0; + *(volatile uint16_t*)(vnp_net_dev.notify_cfg + vnp_net_dev.notify_off_multiplier * RECEIVE_QUEUE) = 0; return (sizedptr){ (uintptr_t)out_buf, payload_len }; } @@ -204,15 +204,15 @@ sizedptr VirtioNetDriver::handle_receive_packet(){ void VirtioNetDriver::handle_sent_packet(){ select_queue(&vnp_net_dev, TRANSMIT_QUEUE); - struct virtq_used* used = (struct virtq_used*)(uintptr_t)vnp_net_dev.common_cfg->queue_device; - struct virtq_desc* desc = (struct virtq_desc*)(uintptr_t)vnp_net_dev.common_cfg->queue_desc; + volatile virtq_used* used = (virtq_used*)vnp_net_dev.common_cfg->queue_device; + volatile virtq_desc* desc = (virtq_desc*)vnp_net_dev.common_cfg->queue_desc; uint16_t qsz = vnp_net_dev.common_cfg->queue_size; int cleaned = 0; while (last_used_sent_idx != used->idx && cleaned < 64) { uint16_t used_ring_index = (uint16_t)(last_used_sent_idx % qsz); last_used_sent_idx = (uint16_t)(last_used_sent_idx + 1); - struct virtq_used_elem* e = &used->ring[used_ring_index]; + volatile virtq_used_elem* e = &used->ring[used_ring_index]; uint32_t desc_index = e->id; if (desc_index < qsz) { diff --git a/kernel/virtio/virtio_pci.c b/kernel/virtio/virtio_pci.c index a0974578..2da4a525 100644 --- a/kernel/virtio/virtio_pci.c +++ b/kernel/virtio/virtio_pci.c @@ -150,11 +150,11 @@ bool virtio_init_device(virtio_device *dev) { dev->common_cfg->queue_driver = avail; dev->common_cfg->queue_device = used; - volatile struct virtq_avail* A = (volatile struct virtq_avail*)(uintptr_t)avail; + volatile virtq_avail* A = (volatile virtq_avail*)(uintptr_t)avail; A->flags = 0; A->idx = 0; - volatile struct virtq_used* U = (volatile struct virtq_used*)(uintptr_t)used; + volatile virtq_used* U = (volatile virtq_used*)(uintptr_t)used; U->flags = 0; U->idx = 0; @@ -177,9 +177,9 @@ uint32_t select_queue(virtio_device *dev, uint32_t index){ } bool virtio_send_3d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len, uint64_t resp, uint32_t resp_len, uint8_t flags) { - struct virtq_desc* d = (struct virtq_desc*)(uintptr_t)dev->common_cfg->queue_desc; - struct virtq_avail* a = (struct virtq_avail*)(uintptr_t)dev->common_cfg->queue_driver; - struct virtq_used* u = (struct virtq_used*)(uintptr_t)dev->common_cfg->queue_device; + volatile virtq_desc* d = (virtq_desc*)dev->common_cfg->queue_desc; + volatile virtq_avail* a = (virtq_avail*)dev->common_cfg->queue_driver; + volatile virtq_used* u = (virtq_used*)dev->common_cfg->queue_device; d[0].addr = cmd; d[0].len = cmd_len; @@ -201,7 +201,7 @@ bool virtio_send_3d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len, uint64_t a->ring[a->idx % dev->common_cfg->queue_size] = 0; a->idx++; - *(volatile uint16_t*)(uintptr_t)(dev->notify_cfg + dev->notify_off_multiplier * dev->common_cfg->queue_select) = 0; + *(volatile uint16_t*)(dev->notify_cfg + dev->notify_off_multiplier * dev->common_cfg->queue_select) = 0; while (last_used_idx == u->idx);//TODO: OPT @@ -214,9 +214,9 @@ bool virtio_send_3d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len, uint64_t bool virtio_send_2d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len, uint64_t resp, uint32_t resp_len, uint8_t flags) { - struct virtq_desc* d = (struct virtq_desc*)(uintptr_t)dev->common_cfg->queue_desc; - struct virtq_avail* a = (struct virtq_avail*)(uintptr_t)dev->common_cfg->queue_driver; - struct virtq_used* u = (struct virtq_used*)(uintptr_t)dev->common_cfg->queue_device; + volatile virtq_desc* d = (virtq_desc*)dev->common_cfg->queue_desc; + volatile virtq_avail* a = (virtq_avail*)dev->common_cfg->queue_driver; + volatile virtq_used* u = (virtq_used*)dev->common_cfg->queue_device; uint16_t last_used_idx = u->idx; d[0].addr = cmd; @@ -232,7 +232,7 @@ bool virtio_send_2d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len, uint64_t a->ring[a->idx % dev->common_cfg->queue_size] = 0; a->idx++; - *(volatile uint16_t*)(uintptr_t)(dev->notify_cfg + dev->notify_off_multiplier * dev->common_cfg->queue_select) = 0; + *(volatile uint16_t*)(dev->notify_cfg + dev->notify_off_multiplier * dev->common_cfg->queue_select) = 0; while (last_used_idx == u->idx);//TODO: OPT @@ -241,9 +241,9 @@ bool virtio_send_2d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len, uint64_t bool virtio_send_1d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len) { - struct virtq_desc* d = (struct virtq_desc*)(uintptr_t)dev->common_cfg->queue_desc; - struct virtq_avail* a = (struct virtq_avail*)(uintptr_t)dev->common_cfg->queue_driver; - struct virtq_used* u = (struct virtq_used*)(uintptr_t)dev->common_cfg->queue_device; + volatile virtq_desc* d = (virtq_desc*)dev->common_cfg->queue_desc; + volatile virtq_avail* a = (virtq_avail*)dev->common_cfg->queue_driver; + volatile virtq_used* u = (virtq_used*)dev->common_cfg->queue_device; uint16_t last_used_idx = u->idx; d[0].addr = cmd; @@ -255,7 +255,7 @@ bool virtio_send_1d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len) { a->idx++; - *(volatile uint16_t*)(uintptr_t)(dev->notify_cfg + dev->notify_off_multiplier * dev->common_cfg->queue_select) = 0; + *(volatile uint16_t*)(dev->notify_cfg + dev->notify_off_multiplier * dev->common_cfg->queue_select) = 0; while (last_used_idx == u->idx);//TODO: OPT @@ -264,8 +264,8 @@ bool virtio_send_1d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len) { void virtio_add_buffer(virtio_device *dev, uint16_t index, uint64_t buf, uint32_t buf_len, bool host_to_dev) { - struct virtq_desc* d = (struct virtq_desc*)(uintptr_t)dev->common_cfg->queue_desc; - struct virtq_avail* a = (struct virtq_avail*)(uintptr_t)dev->common_cfg->queue_driver; + volatile virtq_desc* d = (virtq_desc*)dev->common_cfg->queue_desc; + volatile virtq_avail* a = (virtq_avail*)dev->common_cfg->queue_driver; d[index].addr = buf; d[index].len = buf_len; @@ -275,5 +275,5 @@ void virtio_add_buffer(virtio_device *dev, uint16_t index, uint64_t buf, uint32_ a->ring[a->idx % dev->common_cfg->queue_size] = index; a->idx++; - *(volatile uint16_t*)(uintptr_t)(dev->notify_cfg + dev->notify_off_multiplier * dev->common_cfg->queue_select) = 0; + *(volatile uint16_t*)(dev->notify_cfg + dev->notify_off_multiplier * dev->common_cfg->queue_select) = 0; } \ No newline at end of file diff --git a/kernel/virtio/virtio_pci.h b/kernel/virtio/virtio_pci.h index 03e61d0a..9196fc69 100644 --- a/kernel/virtio/virtio_pci.h +++ b/kernel/virtio/virtio_pci.h @@ -32,29 +32,29 @@ typedef struct virtio_pci_common_cfg { uint16_t queue_reset; }__attribute__((packed)) virtio_pci_common_cfg; -struct virtq_desc { +typedef struct { uint64_t addr; uint32_t len; uint16_t flags; uint16_t next; -} __attribute__((packed)); +}__attribute__((packed)) virtq_desc; -struct virtq_avail { +typedef struct { uint16_t flags; uint16_t idx; uint16_t ring[]; -} __attribute__((packed)); +}__attribute__((packed)) virtq_avail; -struct virtq_used_elem { +typedef struct { uint32_t id; uint32_t len; -} __attribute__((packed)); +}__attribute__((packed)) virtq_used_elem; -struct virtq_used { +typedef struct { uint16_t flags; uint16_t idx; - struct virtq_used_elem ring[128]; -} __attribute__((packed)); + virtq_used_elem ring[128]; +}__attribute__((packed)) virtq_used; typedef struct virtio_device { struct virtio_pci_common_cfg* common_cfg; From 9e1cc0433b0413f15ccbae6a2aa5fcdf097b5734 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 24/43] [PROJ] qemu trace events file --- run_virt | 2 +- traceevents | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 traceevents diff --git a/run_virt b/run_virt index 4de9948f..0dceda02 100755 --- a/run_virt +++ b/run_virt @@ -88,7 +88,7 @@ $PRIVILEGE qemu-system-aarch64 \ -device usb-kbd,bus=usb.0 \ -device usb-mouse,bus=usb.0 \ -device virtio-sound-pci,audiodev=audio \ - -trace file=./trace \ + -trace events=./traceevents -trace file=./trace \ -audiodev ${AUDIO_BACKEND},id=audio \ -d guest_errors \ $ARGS diff --git a/traceevents b/traceevents new file mode 100644 index 00000000..e69de29b From 60c2b534ced1b2c4d1f3e8736b75dae03682ab20 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 25/43] [MMU] virtio virt to phys --- kernel/virtio/virtio_pci.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/kernel/virtio/virtio_pci.c b/kernel/virtio/virtio_pci.c index 2da4a525..fa470f13 100644 --- a/kernel/virtio/virtio_pci.c +++ b/kernel/virtio/virtio_pci.c @@ -4,6 +4,7 @@ #include "memory/page_allocator.h" #include "virtio_pci.h" #include "async.h" +#include "sysregs.h" #define VIRTIO_STATUS_RESET 0x0 #define VIRTIO_STATUS_ACKNOWLEDGE 0x1 @@ -73,21 +74,22 @@ void virtio_get_capabilities(virtio_device *dev, uint64_t pci_addr, uint64_t *mm if (cap->cfg_type < VIRTIO_PCI_CAP_PCI_CFG && bar_base == 0){ kprintfv("[VIRTIO] Setting up bar"); bar_base = pci_setup_bar(pci_addr, cap->bar, mmio_start, mmio_size); - kprintfv("[VIRTIO] Bar @ %llx", (unsigned long long)bar_base); + bar_base = VIRT_TO_PHYS(bar_base); + kprintfv("[VIRTIO] Bar @ %llx", bar_base); } if (cap->cfg_type == VIRTIO_PCI_CAP_COMMON_CFG){ - kprintfv("[VIRTIO] Common CFG @ %llx",(unsigned long long)(bar_base + cap->offset)); + kprintfv("[VIRTIO] Common CFG @ %llx",(unsigned long long)(bar_base + cap->offset) >> 32); dev->common_cfg = (struct virtio_pci_common_cfg*)(uintptr_t)(bar_base + cap->offset); } else if (cap->cfg_type == VIRTIO_PCI_CAP_NOTIFY_CFG) { - kprintfv("[VIRTIO] Notify CFG @ %llx",(unsigned long long)(bar_base + cap->offset)); + kprintfv("[VIRTIO] Notify CFG @ %llx",(unsigned long long)(bar_base + cap->offset) >> 32); dev->notify_cfg = (uint8_t*)(uintptr_t)(bar_base + cap->offset); dev->notify_off_multiplier = *(uint32_t*)(uintptr_t)(cap_addr + sizeof(struct virtio_pci_cap)); } else if (cap->cfg_type == VIRTIO_PCI_CAP_DEVICE_CFG){ - kprintfv("[VIRTIO] Device CFG @ %llx",(unsigned long long)(bar_base + cap->offset)); + kprintfv("[VIRTIO] Device CFG @ %llx",(unsigned long long)(bar_base + cap->offset) >> 32); dev->device_cfg = (uint8_t*)(uintptr_t)(bar_base + cap->offset); } else if (cap->cfg_type == VIRTIO_PCI_CAP_ISR_CFG){ - kprintfv("[VIRTIO] ISR CFG @ %llx",(unsigned long long)(bar_base + cap->offset)); + kprintfv("[VIRTIO] ISR CFG @ %llx",(unsigned long long)(bar_base + cap->offset) >> 32); dev->isr_cfg = (uint8_t*)(uintptr_t)(bar_base + cap->offset); } } @@ -146,9 +148,9 @@ bool virtio_init_device(virtio_device *dev) { uint64_t avail = (uintptr_t)kalloc(dev->memory_page, avail_sz, ALIGN_4KB, MEM_PRIV_KERNEL); uint64_t used = (uintptr_t)kalloc(dev->memory_page, used_sz, ALIGN_4KB, MEM_PRIV_KERNEL); - dev->common_cfg->queue_desc = base; - dev->common_cfg->queue_driver = avail; - dev->common_cfg->queue_device = used; + dev->common_cfg->queue_desc = VIRT_TO_PHYS(base); + dev->common_cfg->queue_driver = VIRT_TO_PHYS(avail); + dev->common_cfg->queue_device = VIRT_TO_PHYS(used); volatile virtq_avail* A = (volatile virtq_avail*)(uintptr_t)avail; A->flags = 0; @@ -181,18 +183,18 @@ bool virtio_send_3d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len, uint64_t volatile virtq_avail* a = (virtq_avail*)dev->common_cfg->queue_driver; volatile virtq_used* u = (virtq_used*)dev->common_cfg->queue_device; - d[0].addr = cmd; + d[0].addr = VIRT_TO_PHYS(cmd); d[0].len = cmd_len; d[0].flags = VIRTQ_DESC_F_NEXT; d[0].next = 1; - d[1].addr = resp; + d[1].addr = VIRT_TO_PHYS(resp); d[1].len = resp_len; d[1].flags = VIRTQ_DESC_F_NEXT | flags; d[1].next = 2; *dev->status_dma = 0; - d[2].addr = (uint64_t)dev->status_dma; + d[2].addr = VIRT_TO_PHYS((uint64_t)dev->status_dma); d[2].len = 1; d[2].flags = VIRTQ_DESC_F_WRITE; d[2].next = 0; @@ -219,12 +221,12 @@ bool virtio_send_2d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len, uint64_t volatile virtq_used* u = (virtq_used*)dev->common_cfg->queue_device; uint16_t last_used_idx = u->idx; - d[0].addr = cmd; + d[0].addr = VIRT_TO_PHYS(cmd); d[0].len = cmd_len; d[0].flags = flags; d[0].next = 1; - d[1].addr = resp; + d[1].addr = VIRT_TO_PHYS(resp); d[1].len = resp_len; d[1].flags = VIRTQ_DESC_F_WRITE; d[1].next = 0; @@ -246,7 +248,7 @@ bool virtio_send_1d(virtio_device *dev, uint64_t cmd, uint32_t cmd_len) { volatile virtq_used* u = (virtq_used*)dev->common_cfg->queue_device; uint16_t last_used_idx = u->idx; - d[0].addr = cmd; + d[0].addr = VIRT_TO_PHYS(cmd); d[0].len = cmd_len; d[0].flags = 0; d[0].next = 0; @@ -267,7 +269,7 @@ void virtio_add_buffer(virtio_device *dev, uint16_t index, uint64_t buf, uint32_ volatile virtq_desc* d = (virtq_desc*)dev->common_cfg->queue_desc; volatile virtq_avail* a = (virtq_avail*)dev->common_cfg->queue_driver; - d[index].addr = buf; + d[index].addr = VIRT_TO_PHYS(buf); d[index].len = buf_len; d[index].flags = host_to_dev ? 0 : VIRTQ_DESC_F_WRITE; d[index].next = 0; From 3c843166287c229b236c6a4c1efa428c3087e8f1 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 26/43] [FAT32] file list quick hack fix --- kernel/filesystem/fat32.cpp | 2 +- kernel/memory/page_allocator.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/filesystem/fat32.cpp b/kernel/filesystem/fat32.cpp index 55686b49..fa787341 100644 --- a/kernel/filesystem/fat32.cpp +++ b/kernel/filesystem/fat32.cpp @@ -50,7 +50,7 @@ bool FAT32FS::init(uint32_t partition_sector){ kprintf("Data start at %x",data_start_sector*512); read_FAT(mbs->reserved_sectors, mbs->sectors_per_fat, mbs->number_of_fats); - open_files = IndexMap(128); + open_files = IndexMap(512); return true; } diff --git a/kernel/memory/page_allocator.c b/kernel/memory/page_allocator.c index c95254d3..19135773 100644 --- a/kernel/memory/page_allocator.c +++ b/kernel/memory/page_allocator.c @@ -257,8 +257,10 @@ void* kalloc(void *page, uint64_t size, uint16_t alignment, uint8_t level){ kprintfv("[in_page_alloc] Aligned next pointer %x",info->next_free_mem_ptr); if (info->next_free_mem_ptr + size > (((uintptr_t)page) + PAGE_SIZE)) { - if (!info->next) + if (!info->next){ info->next = palloc(PAGE_SIZE, level, info->attributes, false); + kprintfv("[in_page_alloc] New page %x",info->next); + } kprintfv("[in_page_alloc] Page full. Moving to %x",(uintptr_t)info->next); return kalloc(info->next, size, alignment, level); } From b0dcf7639546937efd9f241b12b4ebde2ffa23fd Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 27/43] [MMU] only remap hw addresses that exist --- kernel/hw/hw.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/kernel/hw/hw.c b/kernel/hw/hw.c index 88172e7c..e48c8d6b 100644 --- a/kernel/hw/hw.c +++ b/kernel/hw/hw.c @@ -90,15 +90,15 @@ void detect_hardware(){ } void hw_high_va(){ - UART0_BASE |= HIGH_VA; - MMIO_BASE |= HIGH_VA; - if (BOARD_TYPE != 1)//virt is probably doing some weird PCI address stuff already + if (UART0_BASE) UART0_BASE |= HIGH_VA; + if (MMIO_BASE) MMIO_BASE |= HIGH_VA; + if (BOARD_TYPE != 1 && PCI_BASE)//virt is probably doing some weird PCI address stuff already PCI_BASE |= HIGH_VA; - GICD_BASE |= HIGH_VA; - GICC_BASE |= HIGH_VA; - MAILBOX_BASE |= HIGH_VA; - SDHCI_BASE |= HIGH_VA; - XHCI_BASE |= HIGH_VA; + if (GICD_BASE) GICD_BASE |= HIGH_VA; + if (GICC_BASE) GICC_BASE |= HIGH_VA; + if (MAILBOX_BASE) MAILBOX_BASE |= HIGH_VA; + if (SDHCI_BASE) SDHCI_BASE |= HIGH_VA; + if (XHCI_BASE) XHCI_BASE |= HIGH_VA; } void print_hardware(){ From 5624b7a014128c86deac17d68b502ab74ab613ca Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 28/43] [CONT_SWITCH] correct ttbr 0 check --- kernel/input/xhci.cpp | 80 ++++++++++++++++++--------------- kernel/process/context_switch.S | 3 ++ 2 files changed, 46 insertions(+), 37 deletions(-) diff --git a/kernel/input/xhci.cpp b/kernel/input/xhci.cpp index ba5c902e..f4443168 100644 --- a/kernel/input/xhci.cpp +++ b/kernel/input/xhci.cpp @@ -10,6 +10,7 @@ #include "async.h" #include "memory/page_allocator.h" #include "memory/mmu.h" +#include "sysregs.h" uint64_t awaited_addr; uint32_t awaited_type; @@ -34,13 +35,13 @@ uint32_t awaited_type; bool XHCIDriver::check_fatal_error() { uint32_t sts = op->usbsts; if (sts & (XHCI_USBSTS_HSE | XHCI_USBSTS_CE)) { - kprintf("[xHCI ERROR] Fatal condition: USBSTS = %x", sts); + kprintf("[xHCI ERROR] Fatal condition: USBSTS = %llx", sts); return true; } return false; } -#define CHECK_XHCI_FIELD(field) (op->field != 0 ? (kprintf("[xHCI Error] wrong " #field " %x", op->field), false) : (kprintfv("[xHCI] Correct " #field " value"), true)) +#define CHECK_XHCI_FIELD(field) (op->field != 0 ? (kprintf("[xHCI Error] wrong " #field " %llx", op->field), false) : (kprintfv("[xHCI] Correct " #field " value"), true)) #define XHCI_EP_TYPE_INT_IN 7 #define XHCI_EP_TYPE_INT_OUT 3 @@ -56,8 +57,8 @@ bool XHCIDriver::init(){ use_interrupts = true; if (XHCI_BASE){ addr = XHCI_BASE; - mmio = addr; - register_device_memory(mmio, mmio); + mmio = VIRT_TO_PHYS(addr); + register_device_memory(mmio, VIRT_TO_PHYS(mmio)); if (BOARD_TYPE == 2 && RPI_BOARD >= 5) quirk_simulate_interrupts = !pci_setup_msi_rp1(36, true); } else if (PCI_BASE) { @@ -69,7 +70,7 @@ bool XHCIDriver::init(){ return false; } - kprintfv("[xHCI] init %x",addr); + kprintfv("[xHCI] init %llx",addr); if (use_pci){ if (!(*(uint16_t*)(addr + 0x06) & (1 << 4))){ kprintf("[xHCI] Wrong capabilities list"); @@ -84,6 +85,8 @@ bool XHCIDriver::init(){ } pci_register(mmio, mmio_size); + + mmio = VIRT_TO_PHYS(mmio); uint8_t interrupts_ok = pci_setup_interrupts(addr, INPUT_IRQ, 1); switch(interrupts_ok){ @@ -99,18 +102,20 @@ bool XHCIDriver::init(){ break; } - kprintfv("[xHCI] BARs set up @ %x (%x)",mmio,mmio_size); + kprintfv("[xHCI] BARs set up @ %llx (%llx)",mmio,mmio_size); } + mmio = VIRT_TO_PHYS(mmio); + cap = (xhci_cap_regs*)mmio; - kprintfv("[xHCI] caplength %x",cap->caplength); + kprintfv("[xHCI] caplength %llx",cap->caplength); uintptr_t op_base = mmio + cap->caplength; op = (xhci_op_regs*)op_base; ports = (xhci_port_regs*)(op_base + 0x400); db_base = mmio + (cap->dboff & ~0x1F); rt_base = mmio + (cap->rtsoff & ~0x1F); - kprintfv("[xHCI] Resetting controller"); + kprintfv("[xHCI] Resetting controller %llx",&op->usbcmd); op->usbcmd &= ~1; wait(&op->usbcmd, 1, false, 16); kprintfv("[xHCI] Clear complete"); @@ -161,7 +166,7 @@ bool XHCIDriver::init(){ scratchpad_array[i] = (uint64_t)kalloc(mem_page, 0x1000, ALIGN_64B, MEM_PRIV_KERNEL); dcbaap[0] = (uint64_t)scratchpad_array; - kprintfv("[xHCI] dcbaap assigned at %x with %i scratchpads",dcbaap_addr,scratchpad_count); + kprintfv("[xHCI] dcbaap assigned at %llx with %i scratchpads",dcbaap_addr,scratchpad_count); command_ring.ring = (trb*)kalloc(mem_page, MAX_TRB_AMOUNT * sizeof(trb), ALIGN_64B, MEM_PRIV_KERNEL); @@ -169,7 +174,7 @@ bool XHCIDriver::init(){ make_ring_link(command_ring.ring, command_ring.cycle_bit); - kprintfv("[xHCI] command ring allocated at %x. crcr now %x",(uintptr_t)command_ring.ring, op->crcr); + kprintfv("[xHCI] command ring allocated at %llx. crcr now %llx",(uintptr_t)command_ring.ring, op->crcr); if (!enable_events()){ kprintf("[xHCI error] failed to enable events"); @@ -185,7 +190,7 @@ bool XHCIDriver::init(){ endpoint_map = IndexMap(255 * 5); context_map = IndexMap(255 * 5); - kprintfv("[xHCI] Init complete with usbcmd %x, usbsts %x",op->usbcmd, op->usbsts); + kprintfv("[xHCI] Init complete with usbcmd %llx, usbsts %llx",op->usbcmd, op->usbsts); if (check_fatal_error()) return false; @@ -207,7 +212,7 @@ bool XHCIDriver::port_reset(uint16_t port){ kprintf("[xHCI] port %i",port); - xhci_port_regs* port_info = &ports[port]; + xhci_port_regs* port_info = (xhci_port_regs*)VIRT_TO_PHYS_P(&ports[port]); if (port_info->portsc.pp == 0){ port_info->portsc.pp = 1; @@ -256,21 +261,21 @@ bool XHCIDriver::enable_events(){ erst->ring_base = ev_ring; erst->ring_size = MAX_TRB_AMOUNT; - kprintfv("[xHCI] ERST ring_base: %x", ev_ring); - kprintfv("[xHCI] ERST ring_size: %x", erst[0].ring_size); + kprintfv("[xHCI] ERST ring_base: %llx", ev_ring); + kprintfv("[xHCI] ERST ring_size: %llx", erst[0].ring_size); event_ring.ring = (trb*)ev_ring; event_ring.cycle_bit = 1; - kprintfv("[xHCI] Interrupter register @ %x", rt_base + 0x20); + kprintfv("[xHCI] Interrupter register @ %llx", rt_base + 0x20); interrupter->erstsz = 1; - kprintfv("[xHCI] ERSTSZ set to: %x", interrupter->erstsz); + kprintfv("[xHCI] ERSTSZ set to: %llx", (uintptr_t)interrupter->erstsz); interrupter->erdp = ev_ring; interrupter->erstba = erst_addr; - kprintfv("[xHCI] ERSTBA set to: %x", interrupter->erstba); + kprintfv("[xHCI] ERSTBA set to: %llx", (uintptr_t)interrupter->erstba); - kprintfv("[xHCI] ERDP set to: %x", interrupter->erdp); + kprintfv("[xHCI] ERDP set to: %llx", (uintptr_t)interrupter->erdp); interrupter->iman |= 1 << 1;//Enable interrupt @@ -295,26 +300,27 @@ void XHCIDriver::make_ring_link(trb* ring, bool cycle){ void XHCIDriver::ring_doorbell(uint32_t slot, uint32_t endpoint) { volatile uint32_t* db = (uint32_t*)(uintptr_t)(db_base + (slot << 2)); - kprintfv("[xHCI] Ringing doorbell at %x with value %x", db_base + (slot << 2),endpoint); + kprintfv("[xHCI] Ringing doorbell at %llx with value %llx", db_base + (slot << 2),endpoint); *db = endpoint; } bool XHCIDriver::await_response(uint64_t command, uint32_t type){ while (1){ if (check_fatal_error()){ - kprintf("[xHCI error] USBSTS value %x",op->usbsts); + kprintf("[xHCI error] USBSTS value %llx",op->usbsts); awaited_type = 0; return false; } for (; event_ring.index < MAX_TRB_AMOUNT; event_ring.index++){ last_event = &event_ring.ring[event_ring.index]; + kprintf("LAST EVENT %llx",last_event); if (!wait(&last_event->control, event_ring.cycle_bit, true, 2000)){ - kprintf("[xHCI error] Timeout awaiting response to %x command of type %x", command, type); + kprintf("[xHCI error] Timeout awaiting response to %llx command of type %llx", command, type); awaited_type = 0; return false; } - // kprintf("[xHCI] A response at %i of type %x as a response to %x",event_ring.index, (last_event->control & TRB_TYPE_MASK) >> 10, last_event->parameter); - // kprintf("[xHCI] %x vs %x = %i and %x vs %x = %i", (ev->control & TRB_TYPE_MASK) >> 10, type, (ev->control & TRB_TYPE_MASK) >> 10 == type, ev->parameter, command, command == 0 || ev->parameter == command); + // kprintf("[xHCI] A response at %i of type %llx as a response to %llx",event_ring.index, (last_event->control & TRB_TYPE_MASK) >> 10, last_event->parameter); + // kprintf("[xHCI] %llx vs %llx = %i and %llx vs %llx = %i", (ev->control & TRB_TYPE_MASK) >> 10, type, (ev->control & TRB_TYPE_MASK) >> 10 == type, ev->parameter, command, command == 0 || ev->parameter == command); if (event_ring.index == MAX_TRB_AMOUNT - 1){ event_ring.index = 0; event_ring.cycle_bit = !event_ring.cycle_bit; @@ -322,7 +328,7 @@ bool XHCIDriver::await_response(uint64_t command, uint32_t type){ if ((((last_event->control & TRB_TYPE_MASK) >> 10) == type) && (command == 0 || last_event->parameter == command)){ uint8_t completion_code = (last_event->status >> 24) & 0xFF; if (completion_code != 1) - kprintf("[xHCI error] wrong status %i on command type %x", completion_code, ((last_event->control & TRB_TYPE_MASK) >> 10) ); + kprintf("[xHCI error] wrong status %i on command type %llx", completion_code, ((last_event->control & TRB_TYPE_MASK) >> 10) ); interrupter->erdp = (uintptr_t)&event_ring.ring[event_ring.index+1] | (1 << 3);//Inform of latest processed event interrupter->iman |= 1;//Clear interrupts op->usbsts |= 1 << 3;//Clear interrupts @@ -343,7 +349,7 @@ bool XHCIDriver::issue_command(uint64_t param, uint32_t status, uint32_t control cmd->control = control | command_ring.cycle_bit; uint64_t cmd_addr = (uintptr_t)cmd; - kprintfv("[xHCI] issuing command with control: %x from %x", cmd->control, cmd_addr); + kprintfv("[xHCI] issuing command with control: %llx from %llx", cmd->control, cmd_addr); if (command_ring.index == MAX_TRB_AMOUNT - 1){ make_ring_link_control(command_ring.ring, command_ring.cycle_bit); command_ring.cycle_bit = !command_ring.cycle_bit; @@ -360,7 +366,7 @@ bool XHCIDriver::setup_device(uint8_t address, uint16_t port){ } address = (last_event->control >> 24) & 0xFF; - kprintfv("[xHCI] Slot id %x", address); + kprintfv("[xHCI] Slot id %llx", address); if (address == 0){ kprintf("[xHCI error]: Wrong slot id 0"); @@ -372,10 +378,10 @@ bool XHCIDriver::setup_device(uint8_t address, uint16_t port){ transfer_ring->cycle_bit = 1; xhci_input_context *ctx = (xhci_input_context*)kalloc(mem_page, sizeof(xhci_input_context), ALIGN_64B, MEM_PRIV_KERNEL); - kprintfv("[xHCI] Allocating input context at %x", (uintptr_t)ctx); + kprintfv("[xHCI] Allocating input context at %llx", (uintptr_t)ctx); context_map[address << 8] = ctx; void* output_ctx = (void*)kalloc(mem_page, 0x1000, ALIGN_64B, MEM_PRIV_KERNEL); - kprintfv("[xHCI] Allocating output for context at %x", (uintptr_t)output_ctx); + kprintfv("[xHCI] Allocating output for context at %llx", (uintptr_t)output_ctx); ctx->control_context.add_flags = 0b11; @@ -390,7 +396,7 @@ bool XHCIDriver::setup_device(uint8_t address, uint16_t port){ ctx->device_context.endpoints[0].endpoint_f1.max_packet_size = packet_size(ctx->device_context.slot_f0.speed); transfer_ring->ring = (trb*)kalloc(mem_page, MAX_TRB_AMOUNT * sizeof(trb), ALIGN_64B, MEM_PRIV_KERNEL); - kprintfv("Transfer ring at %x %i",(uintptr_t)transfer_ring->ring, address << 8); + kprintfv("Transfer ring at %llx %i",(uintptr_t)transfer_ring->ring, address << 8); make_ring_link(transfer_ring->ring, transfer_ring->cycle_bit); ctx->device_context.endpoints[0].endpoint_f23.dcs = transfer_ring->cycle_bit; @@ -411,7 +417,7 @@ bool XHCIDriver::request_sized_descriptor(uint8_t address, uint8_t endpoint, uin .wLength = descriptor_size }; - // kprintf("RT: %x R: %x V: %x I: %x L: %x",packet.bmRequestType,packet.bRequest,packet.wValue,packet.wIndex,packet.wLength); + // kprintf("RT: %llx R: %llx V: %llx I: %llx L: %llx",packet.bmRequestType,packet.bRequest,packet.wValue,packet.wIndex,packet.wLength); xhci_ring *transfer_ring = &endpoint_map[address << 8 | endpoint]; @@ -446,14 +452,14 @@ bool XHCIDriver::request_sized_descriptor(uint8_t address, uint8_t endpoint, uin uint8_t XHCIDriver::address_device(uint8_t address){ xhci_input_context* ctx = context_map[address << 8]; - kprintfv("Addressing device %i with context %x", address, (uintptr_t)ctx); + kprintfv("Addressing device %i with context %llx", address, (uintptr_t)ctx); if (!issue_command((uintptr_t)ctx, 0, (address << 24) | (TRB_TYPE_ADDRESS_DEV << 10))){ - kprintf("[xHCI error] failed addressing device at slot %x",address); + kprintf("[xHCI error] failed addressing device at slot %llx",address); return 0; } xhci_device_context* context = (xhci_device_context*)dcbaap[address]; - kprintfv("[xHCI] ADDRESS_DEVICE %i command issued. dcbaap %x Received packet size %i",address, (uintptr_t)dcbaap, context->endpoints[0].endpoint_f1.max_packet_size); + kprintfv("[xHCI] ADDRESS_DEVICE %i command issued. dcbaap %llx Received packet size %i",address, (uintptr_t)dcbaap, context->endpoints[0].endpoint_f1.max_packet_size); return address; } @@ -462,7 +468,7 @@ uint8_t XHCIDriver::get_ep_type(usb_endpoint_descriptor* descriptor) { } bool XHCIDriver::configure_endpoint(uint8_t address, usb_endpoint_descriptor *endpoint, uint8_t configuration_value, usb_device_types type){ - kprintfv("[xHCI] endpoint address %x",endpoint->bEndpointAddress); + kprintfv("[xHCI] endpoint address %llx",endpoint->bEndpointAddress); uint8_t ep_address = endpoint->bEndpointAddress; uint8_t ep_dir = (ep_address & 0x80) ? 1 : 0; // 1 IN, 0 OUT uint8_t ep_num = ((ep_address & 0x0F) * 2) + ep_dir; @@ -539,7 +545,7 @@ void XHCIDriver::handle_interrupt(){ uint64_t addr = ev->parameter; if (type == awaited_type && (awaited_addr == 0 || (awaited_addr & 0xFFFFFFFFFFFFFFFF) == addr)) return; - kprintfv("[xHCI] >>> Unhandled interrupt %i %x",event_ring.index,type); + kprintfv("[xHCI] >>> Unhandled interrupt %i %llx",event_ring.index,type); uint8_t completion_code = (ev->status >> 24) & 0xFF; if (completion_code == 1 || completion_code == 4){ switch (type){ @@ -560,14 +566,14 @@ void XHCIDriver::handle_interrupt(){ } } } else { - kprintf("[xHCI error] wrong status %i on command type %x", completion_code, ((ev->control & TRB_TYPE_MASK) >> 10)); + kprintf("[xHCI error] wrong status %i on command type %llx", completion_code, ((ev->control & TRB_TYPE_MASK) >> 10)); } if (event_ring.index == MAX_TRB_AMOUNT - 1){ event_ring.index = 0; event_ring.cycle_bit = !event_ring.cycle_bit; } else event_ring.index++; - interrupter->erdp = (uintptr_t)&event_ring.ring[event_ring.index] | (1 << 3);//Inform of latest processed event + interrupter->erdp = VIRT_TO_PHYS((uintptr_t)&event_ring.ring[event_ring.index]) | (1 << 3);//Inform of latest processed event interrupter->iman |= 1;//Clear interrupts op->usbsts |= 1 << 3;//Clear interrupts } diff --git a/kernel/process/context_switch.S b/kernel/process/context_switch.S index e78c2115..a0d031c3 100644 --- a/kernel/process/context_switch.S +++ b/kernel/process/context_switch.S @@ -61,6 +61,9 @@ restore_context: ldr x18, [x18] + cmp x18, #0 + b.eq 4f + msr ttbr0_el1, x18 tlbi vmalle1is From 6af3de24c4bacf86aac89c86afba78fe4caf2d08 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 29/43] [PROJ] rundebug separate windows for mac --- rundebug | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/rundebug b/rundebug index 4c1edd63..c007fc81 100755 --- a/rundebug +++ b/rundebug @@ -1,6 +1,6 @@ -#!/bin/bash +#!/bin/sh -MODE="raspi" +MODE="virt" ARGS=() for arg in "$@"; do @@ -10,11 +10,15 @@ for arg in "$@"; do esac done -# osascript < Date: Sun, 16 Nov 2025 00:00:00 +0000 Subject: [PATCH 30/43] [MMU] moved MMU init before peripherals --- kernel/kernel.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/kernel/kernel.c b/kernel/kernel.c index 6065027d..f39959cb 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -40,6 +40,7 @@ void kernel_main() { // if (BOARD_TYPE == 1) disable_visual(); load_module(&console_module); + mmu_init(); print_hardware(); @@ -52,13 +53,12 @@ void kernel_main() { load_module(&graphics_module); - // if (BOARD_TYPE == 2 && RPI_BOARD >= 5) - // pci_setup_rp1(); + if (BOARD_TYPE == 2 && RPI_BOARD >= 5) + pci_setup_rp1(); load_module(&disk_module); bool input_available = load_module(&input_module); - mmu_init(); bool network_available = false; if (BOARD_TYPE == 1){ if (system_config.use_net) @@ -66,7 +66,6 @@ void kernel_main() { load_module(&audio_module); } - kprint("Kernel initialization finished"); From 677363fe177c7bdffa2b98cda69d4fe9f7dc91ad Mon Sep 17 00:00:00 2001 From: dif Date: Mon, 17 Nov 2025 00:00:00 +0000 Subject: [PATCH 31/43] [MMU] return from mmu_init to high --- kernel/graph/tres.cpp | 1 + kernel/kernel_processes/kprocess_loader.c | 6 +++--- kernel/memory/mmu.c | 5 +---- kernel/memory/mmu_start.S | 11 +++++++---- kernel/process/syscall.c | 4 ++-- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/kernel/graph/tres.cpp b/kernel/graph/tres.cpp index a88f22c0..90bbc135 100644 --- a/kernel/graph/tres.cpp +++ b/kernel/graph/tres.cpp @@ -45,6 +45,7 @@ extern "C" void create_window(uint32_t x, uint32_t y, uint32_t width, uint32_t h } int find_window(void *node, void *key){ + if (!node || !key) return -1; window_frame* frame = (window_frame*)node; uint16_t wid = *(uint16_t*)key; if (frame->win_id == wid) return 0; diff --git a/kernel/kernel_processes/kprocess_loader.c b/kernel/kernel_processes/kprocess_loader.c index 30410820..17fe6438 100644 --- a/kernel/kernel_processes/kprocess_loader.c +++ b/kernel/kernel_processes/kprocess_loader.c @@ -16,11 +16,11 @@ process_t *create_kernel_process(const char *name, int (*func)(int argc, char* a uint64_t stack_size = 0x1000; uintptr_t stack = (uintptr_t)palloc(stack_size, MEM_PRIV_KERNEL, MEM_RW, false); - kprintf("Stack size %x. Start %x", stack_size,stack); + kprintf("Stack size %llx. Start %llx", stack_size,stack); if (!stack) return 0; uintptr_t heap = (uintptr_t)palloc(stack_size, MEM_PRIV_KERNEL, MEM_RW, false); - kprintf("Heap %x", heap); + kprintf("Heap %llx", heap); if (!heap) return 0; proc->stack = (stack + stack_size); @@ -31,7 +31,7 @@ process_t *create_kernel_process(const char *name, int (*func)(int argc, char* a proc->sp = proc->stack; proc->pc = ((uintptr_t)func) | HIGH_VA; - kprintf("Kernel process %s (%i) allocated with address at %x, stack at %x, heap at %x. %i argument(s)", (uintptr_t)name, proc->id, proc->pc, proc->sp, proc->heap, argc); + kprintf("Kernel process %s (%i) allocated with address at %llx, stack at %llx, heap at %llx. %i argument(s)", (uintptr_t)name, proc->id, proc->pc, proc->sp, proc->heap, argc); proc->spsr = 0x205; proc->state = READY; proc->PROC_X0 = argc; diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 67c572b1..38759053 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -204,15 +204,12 @@ void mmu_init() { mmu_start(kernel_mmu_page); - asm volatile (".global mmu_finish\nmmu_finish:"); - kprintf("Finished MMU init"); } void mmu_copy(uintptr_t *new_ttrb, uintptr_t *old_ttrb, int level){ for (int i = 0; i < PAGE_TABLE_ENTRIES; i++){ if (old_ttrb[i] & 1){ - kprintf("TLE %b %x %i",old_ttrb[i] & 0b11,old_ttrb[i],level); if (level == 3 || (old_ttrb[i] & 0b11) == PD_BLOCK){ new_ttrb[i] = old_ttrb[i]; } else { @@ -247,7 +244,7 @@ void register_device_memory(uint64_t va, uint64_t pa){ void register_device_memory_2mb(uint64_t va, uint64_t pa){ if (pttrb && pttrb != kernel_mmu_page)//TODO: This won't be necessary once kernel is exclusively in ttbr1 - mmu_map_4kb(pttrb, va, pa, MAIR_IDX_DEVICE, MEM_RW, MEM_PRIV_KERNEL); + mmu_map_2mb(pttrb, va, pa, MAIR_IDX_DEVICE); mmu_map_2mb(kernel_mmu_page, va, pa, MAIR_IDX_DEVICE); mmu_flush_all(); mmu_flush_icache(); diff --git a/kernel/memory/mmu_start.S b/kernel/memory/mmu_start.S index ed953574..a5899d95 100644 --- a/kernel/memory/mmu_start.S +++ b/kernel/memory/mmu_start.S @@ -2,6 +2,7 @@ .global mmu_start mmu_start://(uint64_t *page x0) +.type mmu_start, %function ldr x3, =MAIR_VALUE msr mair_el1, x3 ldr x3, =TCR_VALUE @@ -42,10 +43,12 @@ mmu_start://(uint64_t *page x0) orr x0, x0, x1 mov x30, x0 - mrs x0, vbar_el1 + ldr x0, [sp, #8] orr x0, x0, x1 - msr vbar_el1, x0 + str x0, [sp, #8] - ldr x0, =mmu_finish + mrs x0, vbar_el1 orr x0, x0, x1 - br x0 \ No newline at end of file + msr vbar_el1, x0 + + ret \ No newline at end of file diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index 94f54851..cc297e27 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -377,11 +377,11 @@ void sync_el0_handler_c(){ } } if (currentEL == 1){ - kprintf("System has crashed. ESR: %x. ELR: %x. FAR: %x", esr, elr, far); + kprintf("System has crashed. ESR: %llx. ELR: %llx. FAR: %llx", esr, elr, far); coredump(esr, elr, far, proc->sp); handle_exception("UNEXPECTED EXCEPTION",ec); } else { - kprintf("Process has crashed. ESR: %x. ELR: %x. FAR: %x", esr, elr, far); + kprintf("Process has crashed. ESR: %llx. ELR: %llx. FAR: %llx", esr, elr, far); coredump(esr, elr, far, proc->sp); syscall_depth--; stop_current_process(ec); From 43c7f7e6c58f0617a608ade77b95a7150e71f8b7 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Mon, 17 Nov 2025 00:00:00 +0000 Subject: [PATCH 32/43] [MMU] phys -> virt pointers --- kernel/sysregs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/sysregs.h b/kernel/sysregs.h index 81791544..6855cf20 100644 --- a/kernel/sysregs.h +++ b/kernel/sysregs.h @@ -66,4 +66,5 @@ #define VIRT_TO_PHYS(x) (x & ~HIGH_VA) #define PHYS_TO_VIRT(x) (x | HIGH_VA) -#define VIRT_TO_PHYS_P(x) ((void*)(((uintptr_t)x) & ~HIGH_VA)) \ No newline at end of file +#define VIRT_TO_PHYS_P(x) ((void*)(((uintptr_t)x) & ~HIGH_VA)) +#define PHYS_TO_VIRT_P(x) ((void*)(((uintptr_t)x) | HIGH_VA)) \ No newline at end of file From fa41091b62d215940ad29f491cabcdec832edf98 Mon Sep 17 00:00:00 2001 From: dif Date: Mon, 17 Nov 2025 00:00:00 +0000 Subject: [PATCH 33/43] [MMU] kalloc to VA in kernel --- .../framebuffer_gpus/ramfb_driver/ramfb.cpp | 3 ++- kernel/graph/tres.cpp | 11 +++++----- kernel/input/usb.cpp | 13 ++++++----- kernel/input/xhci.cpp | 22 +++++++++---------- kernel/memory/mmu.c | 1 - kernel/memory/page_allocator.c | 10 ++++++++- kernel/process/syscall.c | 6 ++--- 7 files changed, 38 insertions(+), 28 deletions(-) diff --git a/kernel/graph/drivers/framebuffer_gpus/ramfb_driver/ramfb.cpp b/kernel/graph/drivers/framebuffer_gpus/ramfb_driver/ramfb.cpp index c2e93df3..c59bb86e 100644 --- a/kernel/graph/drivers/framebuffer_gpus/ramfb_driver/ramfb.cpp +++ b/kernel/graph/drivers/framebuffer_gpus/ramfb_driver/ramfb.cpp @@ -6,6 +6,7 @@ #include "std/memory.h" #include "theme/theme.h" #include "memory/page_allocator.h" +#include "sysregs.h" typedef struct { uint64_t addr; @@ -71,7 +72,7 @@ bool RamFBGPUDriver::init(gpu_size preferred_screen_size){ void RamFBGPUDriver::update_gpu_fb(){ ramfb_structure fb = { - .addr = __builtin_bswap64((uintptr_t)framebuffer), + .addr = __builtin_bswap64(VIRT_TO_PHYS((uintptr_t)framebuffer)), .fourcc = __builtin_bswap32(RGB_FORMAT_ARGB8888), .flags = __builtin_bswap32(0), .width = __builtin_bswap32(screen_size.width), diff --git a/kernel/graph/tres.cpp b/kernel/graph/tres.cpp index 90bbc135..7aed5c89 100644 --- a/kernel/graph/tres.cpp +++ b/kernel/graph/tres.cpp @@ -6,6 +6,7 @@ #include "syscalls/syscalls.h" #include "kernel_processes/windows/launcher.h" #include "console/kio.h" +#include "sysregs.h" clinkedlist_t *window_list; window_frame *focused_window; @@ -36,7 +37,7 @@ extern "C" void create_window(uint32_t x, uint32_t y, uint32_t width, uint32_t h frame->height = height; frame->x = x; frame->y = y; - clinkedlist_push_front(window_list, frame); + clinkedlist_push_front(window_list, PHYS_TO_VIRT_P(frame)); main_gpu_driver->create_window(x,y, width, height, &frame->win_ctx); process_t *p = launch_launcher(); p->win_id = frame->win_id; @@ -54,7 +55,7 @@ int find_window(void *node, void *key){ void resize_window(uint32_t width, uint32_t height){ process_t *p = get_current_proc(); - clinkedlist_node_t *node = clinkedlist_find(window_list, &p->win_id, find_window); + clinkedlist_node_t *node = clinkedlist_find(window_list, PHYS_TO_VIRT_P(&p->win_id), (typeof(find_window)*)PHYS_TO_VIRT_P(find_window)); if (node && node->data){ window_frame* frame = (window_frame*)node->data; main_gpu_driver->resize_window(width, height, &frame->win_ctx); @@ -66,7 +67,7 @@ void resize_window(uint32_t width, uint32_t height){ void get_window_ctx(draw_ctx* out_ctx){ process_t *p = get_current_proc(); - clinkedlist_node_t *node = clinkedlist_find(window_list, &p->win_id, find_window); + clinkedlist_node_t *node = clinkedlist_find(window_list, PHYS_TO_VIRT_P(&p->win_id), (typeof(find_window)*)PHYS_TO_VIRT_P(find_window)); if (node && node->data){ window_frame* frame = (window_frame*)node->data; *out_ctx = frame->win_ctx; @@ -77,7 +78,7 @@ void get_window_ctx(draw_ctx* out_ctx){ void commit_frame(draw_ctx* frame_ctx, window_frame* frame){ if (!frame){ process_t *p = get_current_proc(); - clinkedlist_node_t *node = clinkedlist_find(window_list, &p->win_id, find_window); + clinkedlist_node_t *node = clinkedlist_find(window_list, PHYS_TO_VIRT_P(&p->win_id), (typeof(find_window)*)PHYS_TO_VIRT_P(find_window)); if (!node || !node->data) return; frame = (window_frame*)node->data; } @@ -121,7 +122,7 @@ void commit_frame(draw_ctx* frame_ctx, window_frame* frame){ } void set_window_focus(uint16_t win_id){ - clinkedlist_node_t *node = clinkedlist_find(window_list, &win_id, find_window); + clinkedlist_node_t *node = clinkedlist_find(window_list, PHYS_TO_VIRT_P(&win_id), (typeof(find_window)*)PHYS_TO_VIRT_P(find_window)); if (!node || !node->data) return; focused_window = (window_frame*)node->data; dirty_windows = true; diff --git a/kernel/input/usb.cpp b/kernel/input/usb.cpp index 3fa34b17..8562c6b5 100644 --- a/kernel/input/usb.cpp +++ b/kernel/input/usb.cpp @@ -4,6 +4,7 @@ #include "std/string.h" #include "memory/page_allocator.h" #include "usb_types.h" +#include "sysregs.h" uint16_t USBDriver::packet_size(uint16_t speed){ switch (speed) { @@ -25,7 +26,7 @@ bool USBDriver::setup_device(uint8_t address, uint16_t port){ } usb_device_descriptor* descriptor = (usb_device_descriptor*)kalloc(mem_page, sizeof(usb_device_descriptor), ALIGN_64B, MEM_PRIV_KERNEL); - if (!request_descriptor(address, 0, 0x80, 6, USB_DEVICE_DESCRIPTOR, 0, 0, descriptor)){ + if (!request_descriptor(address, 0, 0x80, 6, USB_DEVICE_DESCRIPTOR, 0, 0, VIRT_TO_PHYS_P(descriptor))){ kprintf("[USB error] failed to get device descriptor"); return false; } @@ -34,7 +35,7 @@ bool USBDriver::setup_device(uint8_t address, uint16_t port){ bool use_lang_desc = true; - if (!request_descriptor(address, 0, 0x80, 6, USB_STRING_DESCRIPTOR, 0, 0, lang_desc)){ + if (!request_descriptor(address, 0, 0x80, 6, USB_STRING_DESCRIPTOR, 0, 0, VIRT_TO_PHYS_P(lang_desc))){ kprintf("[USB warning] failed to get language descriptor"); use_lang_desc = false; } @@ -48,21 +49,21 @@ bool USBDriver::setup_device(uint8_t address, uint16_t port){ //TODO: we want to maintain the strings so we can have USB device information uint16_t langid = lang_desc->lang_ids[0]; usb_string_descriptor* prod_name = (usb_string_descriptor*)kalloc(mem_page, sizeof(usb_string_descriptor), ALIGN_64B, MEM_PRIV_KERNEL); - if (request_descriptor(address, 0, 0x80, 6, USB_STRING_DESCRIPTOR, descriptor->iProduct, langid, prod_name)){ + if (request_descriptor(address, 0, 0x80, 6, USB_STRING_DESCRIPTOR, descriptor->iProduct, langid, VIRT_TO_PHYS_P(prod_name))){ char name[128]; if (utf16tochar(prod_name->unicode_string, name, sizeof(name))) { kprintf("[USB device] Product name: %s", (uint64_t)name); } } usb_string_descriptor* man_name = (usb_string_descriptor*)kalloc(mem_page, sizeof(usb_string_descriptor), ALIGN_64B, MEM_PRIV_KERNEL); - if (request_descriptor(address, 0, 0x80, 6, USB_STRING_DESCRIPTOR, descriptor->iManufacturer, langid, man_name)){ + if (request_descriptor(address, 0, 0x80, 6, USB_STRING_DESCRIPTOR, descriptor->iManufacturer, langid, VIRT_TO_PHYS_P(man_name))){ char name[128]; if (utf16tochar(man_name->unicode_string, name, sizeof(name))) { kprintf("[USB device] Manufacturer name: %s", (uint64_t)name); } } usb_string_descriptor* ser_name = (usb_string_descriptor*)kalloc(mem_page, sizeof(usb_string_descriptor), ALIGN_64B, MEM_PRIV_KERNEL); - if (request_descriptor(address, 0, 0x80, 6, USB_STRING_DESCRIPTOR, descriptor->iSerialNumber, langid, ser_name)){ + if (request_descriptor(address, 0, 0x80, 6, USB_STRING_DESCRIPTOR, descriptor->iSerialNumber, langid, VIRT_TO_PHYS_P(ser_name))){ char name[128]; if (utf16tochar(ser_name->unicode_string, name, sizeof(name))) { kprintf("[USB device] Serial: %s", (uint64_t)name); @@ -77,7 +78,7 @@ bool USBDriver::get_configuration(uint8_t address){ usb_manager->register_device(address); - usb_configuration_descriptor* config = (usb_configuration_descriptor*)kalloc(mem_page, sizeof(usb_configuration_descriptor), ALIGN_64B, MEM_PRIV_KERNEL); + usb_configuration_descriptor* config = (usb_configuration_descriptor*)VIRT_TO_PHYS_P(kalloc(mem_page, sizeof(usb_configuration_descriptor), ALIGN_64B, MEM_PRIV_KERNEL)); if (!request_sized_descriptor(address, 0, 0x80, 6, USB_CONFIGURATION_DESCRIPTOR, 0, 0, 8, config)){ kprintf("[USB error] could not get config descriptor header"); return false; diff --git a/kernel/input/xhci.cpp b/kernel/input/xhci.cpp index f4443168..9ed46ef5 100644 --- a/kernel/input/xhci.cpp +++ b/kernel/input/xhci.cpp @@ -151,7 +151,7 @@ bool XHCIDriver::init(){ mem_page = palloc(0x1000, MEM_PRIV_KERNEL, MEM_RW | MEM_DEV, false); - uintptr_t dcbaap_addr = (uintptr_t)kalloc(mem_page, (max_device_slots + 1) * sizeof(uintptr_t), ALIGN_64B, MEM_PRIV_KERNEL); + uintptr_t dcbaap_addr = VIRT_TO_PHYS((uintptr_t)kalloc(mem_page, (max_device_slots + 1) * sizeof(uintptr_t), ALIGN_64B, MEM_PRIV_KERNEL)); op->dcbaap = dcbaap_addr; @@ -159,7 +159,7 @@ bool XHCIDriver::init(){ uint32_t scratchpad_count = ((cap->hcsparams2 >> 27) & 0x1F); - dcbaap = (uintptr_t*)dcbaap_addr; + dcbaap = (uintptr_t*)PHYS_TO_VIRT(dcbaap_addr); uint64_t* scratchpad_array = (uint64_t*)kalloc(mem_page, (scratchpad_count == 0 ? 1 : scratchpad_count) * sizeof(uintptr_t), ALIGN_64B, MEM_PRIV_KERNEL); for (uint32_t i = 0; i < scratchpad_count; i++) @@ -168,7 +168,7 @@ bool XHCIDriver::init(){ kprintfv("[xHCI] dcbaap assigned at %llx with %i scratchpads",dcbaap_addr,scratchpad_count); - command_ring.ring = (trb*)kalloc(mem_page, MAX_TRB_AMOUNT * sizeof(trb), ALIGN_64B, MEM_PRIV_KERNEL); + command_ring.ring = (trb*)VIRT_TO_PHYS_P(kalloc(mem_page, MAX_TRB_AMOUNT * sizeof(trb), ALIGN_64B, MEM_PRIV_KERNEL)); op->crcr = (uintptr_t)command_ring.ring | command_ring.cycle_bit; @@ -254,8 +254,8 @@ bool XHCIDriver::enable_events(){ kprintfv("[xHCI] Allocating ERST"); interrupter = (xhci_interrupter*)(rt_base + 0x20); - uint64_t ev_ring = (uintptr_t)kalloc(mem_page, MAX_TRB_AMOUNT * sizeof(trb), ALIGN_64B, MEM_PRIV_KERNEL); - uint64_t erst_addr = (uintptr_t)kalloc(mem_page, MAX_ERST_AMOUNT * sizeof(erst_entry), ALIGN_64B, MEM_PRIV_KERNEL); + uint64_t ev_ring = VIRT_TO_PHYS((uintptr_t)kalloc(mem_page, MAX_TRB_AMOUNT * sizeof(trb), ALIGN_64B, MEM_PRIV_KERNEL)); + uint64_t erst_addr = VIRT_TO_PHYS((uintptr_t)kalloc(mem_page, MAX_ERST_AMOUNT * sizeof(erst_entry), ALIGN_64B, MEM_PRIV_KERNEL)); erst_entry* erst = (erst_entry*)erst_addr; erst->ring_base = ev_ring; @@ -377,10 +377,10 @@ bool XHCIDriver::setup_device(uint8_t address, uint16_t port){ transfer_ring->cycle_bit = 1; - xhci_input_context *ctx = (xhci_input_context*)kalloc(mem_page, sizeof(xhci_input_context), ALIGN_64B, MEM_PRIV_KERNEL); + xhci_input_context *ctx = (xhci_input_context*)VIRT_TO_PHYS_P(kalloc(mem_page, sizeof(xhci_input_context), ALIGN_64B, MEM_PRIV_KERNEL)); kprintfv("[xHCI] Allocating input context at %llx", (uintptr_t)ctx); - context_map[address << 8] = ctx; - void* output_ctx = (void*)kalloc(mem_page, 0x1000, ALIGN_64B, MEM_PRIV_KERNEL); + context_map[address << 8] = (xhci_input_context *)ctx; + void* output_ctx = VIRT_TO_PHYS_P((void*)kalloc(mem_page, 0x1000, ALIGN_64B, MEM_PRIV_KERNEL)); kprintfv("[xHCI] Allocating output for context at %llx", (uintptr_t)output_ctx); ctx->control_context.add_flags = 0b11; @@ -400,10 +400,10 @@ bool XHCIDriver::setup_device(uint8_t address, uint16_t port){ make_ring_link(transfer_ring->ring, transfer_ring->cycle_bit); ctx->device_context.endpoints[0].endpoint_f23.dcs = transfer_ring->cycle_bit; - ctx->device_context.endpoints[0].endpoint_f23.ring_ptr = ((uintptr_t)transfer_ring->ring) >> 4; + ctx->device_context.endpoints[0].endpoint_f23.ring_ptr = VIRT_TO_PHYS((uintptr_t)transfer_ring->ring) >> 4; ctx->device_context.endpoints[0].endpoint_f4.average_trb_length = sizeof(trb); - dcbaap[address] = (uintptr_t)output_ctx; + dcbaap[address] = VIRT_TO_PHYS((uintptr_t)output_ctx); return USBDriver::setup_device(address, port); } @@ -501,7 +501,7 @@ bool XHCIDriver::configure_endpoint(uint8_t address, usb_endpoint_descriptor *en ep_ring->cycle_bit = 1; make_ring_link(ep_ring->ring, ep_ring->cycle_bit); ctx->device_context.endpoints[ep_num-1].endpoint_f23.dcs = ep_ring->cycle_bit; - ctx->device_context.endpoints[ep_num-1].endpoint_f23.ring_ptr = ((uintptr_t)ep_ring->ring) >> 4; + ctx->device_context.endpoints[ep_num-1].endpoint_f23.ring_ptr = VIRT_TO_PHYS((uintptr_t)ep_ring->ring) >> 4; ctx->device_context.endpoints[ep_num-1].endpoint_f4.average_trb_length = sizeof(trb); if (!issue_command((uintptr_t)ctx, 0, (address << 24) | (TRB_TYPE_CONFIG_EP << 10))){ diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 38759053..8e6d6091 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -253,7 +253,6 @@ void register_device_memory_2mb(uint64_t va, uint64_t pa){ void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t level){ if (pttrb && pttrb != kernel_mmu_page) mmu_map_4kb(pttrb, va, pa, MAIR_IDX_NORMAL, attributes, level); - mmu_map_4kb(kernel_mmu_page, va, pa, MAIR_IDX_NORMAL, attributes, level); mmu_flush_all(); mmu_flush_icache(); diff --git a/kernel/memory/page_allocator.c b/kernel/memory/page_allocator.c index 19135773..2734999d 100644 --- a/kernel/memory/page_allocator.c +++ b/kernel/memory/page_allocator.c @@ -7,6 +7,7 @@ #include "math/math.h" #include "console/kio.h" #include "process/scheduler.h" +#include "sysregs.h" #define PD_TABLE 0b11 #define PD_BLOCK 0b01 @@ -207,7 +208,7 @@ void mark_used(uintptr_t address, size_t pages) #define PAGE_INDEX_LIMIT (PAGE_SIZE-sizeof(page_index_hdr))/sizeof(page_index_entry) //TODO: maybe alloc to different base pages based on alignment? Then it's easier to keep track of full pages, freeing and sizes -void* kalloc(void *page, uint64_t size, uint16_t alignment, uint8_t level){ +void* kalloc_inner(void *page, uint64_t size, uint16_t alignment, uint8_t level){ //TODO: we're changing the size but not reporting it back, which means the free function does not fully free the allocd memory size = (size + alignment - 1) & ~(alignment - 1); @@ -275,6 +276,13 @@ void* kalloc(void *page, uint64_t size, uint16_t alignment, uint8_t level){ return (void*)result; } +//TODO: rather than kalloc, it should be palloc that does translations +void* kalloc(void *page, uint64_t size, uint16_t alignment, uint8_t level){ + void* ptr = kalloc_inner(page, size, alignment, level); + if (level == MEM_PRIV_KERNEL) ptr = PHYS_TO_VIRT_P(ptr); + return ptr; +} + void kfree(void* ptr, uint64_t size) { kprintfv("[page_alloc_free] Freeing block at %x size %x",(uintptr_t)ptr, size); diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index cc297e27..e509169b 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -284,7 +284,7 @@ void backtrace(uintptr_t fp, uintptr_t elr, sizedptr debug_line, sizedptr debug_ kprintf("%i: caller address: %x", depth, return_address, return_address); fp = *(uintptr_t*)fp; } else return; - + } } @@ -378,11 +378,11 @@ void sync_el0_handler_c(){ } if (currentEL == 1){ kprintf("System has crashed. ESR: %llx. ELR: %llx. FAR: %llx", esr, elr, far); - coredump(esr, elr, far, proc->sp); + if (syscall_depth < 2) coredump(esr, elr, far, proc->sp); handle_exception("UNEXPECTED EXCEPTION",ec); } else { kprintf("Process has crashed. ESR: %llx. ELR: %llx. FAR: %llx", esr, elr, far); - coredump(esr, elr, far, proc->sp); + if (syscall_depth < 2) coredump(esr, elr, far, proc->sp); syscall_depth--; stop_current_process(ec); } From 6a65c2cacd32f3552051bb1b291667e9bcf63ca3 Mon Sep 17 00:00:00 2001 From: dif Date: Mon, 17 Nov 2025 00:00:00 +0000 Subject: [PATCH 34/43] [MMU] fallback for crashes inside crash handler --- kernel/process/syscall.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index e509169b..591dec75 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -377,9 +377,12 @@ void sync_el0_handler_c(){ } } if (currentEL == 1){ - kprintf("System has crashed. ESR: %llx. ELR: %llx. FAR: %llx", esr, elr, far); - if (syscall_depth < 2) coredump(esr, elr, far, proc->sp); - handle_exception("UNEXPECTED EXCEPTION",ec); + if (syscall_depth < 3){ + if (syscall_depth == 1) kprintf("System has crashed. ESR: %llx. ELR: %llx. FAR: %llx", esr, elr, far); + if (syscall_depth < 2) coredump(esr, elr, far, proc->sp); + handle_exception("UNEXPECTED EXCEPTION",ec); + } + while (true); } else { kprintf("Process has crashed. ESR: %llx. ELR: %llx. FAR: %llx", esr, elr, far); if (syscall_depth < 2) coredump(esr, elr, far, proc->sp); From 31417b001e346fe571740a2744a374fd9a32e806 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Tue, 18 Nov 2025 00:00:00 +0000 Subject: [PATCH 35/43] [MMU VIRTIOGPU] fixed virtio gpu with new kalloc --- kernel/graph/drivers/virtio_gpu_pci/virtio_gpu_pci.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/graph/drivers/virtio_gpu_pci/virtio_gpu_pci.cpp b/kernel/graph/drivers/virtio_gpu_pci/virtio_gpu_pci.cpp index 7c3ce2b3..efefafc6 100644 --- a/kernel/graph/drivers/virtio_gpu_pci/virtio_gpu_pci.cpp +++ b/kernel/graph/drivers/virtio_gpu_pci/virtio_gpu_pci.cpp @@ -5,6 +5,7 @@ #include "std/std.h" #include "theme/theme.h" #include "memory/page_allocator.h" +#include "sysregs.h" #define VIRTIO_GPU_CMD_GET_DISPLAY_INFO 0x0100 #define VIRTIO_GPU_CMD_RESOURCE_CREATE_2D 0x0101 @@ -72,7 +73,7 @@ bool VirtioGPUDriver::init(gpu_size preferred_screen_size){ resource_id_counter = 0; framebuffer_size = screen_size.width * screen_size.height * BPP; - framebuffer = (uintptr_t)kalloc(gpu_dev.memory_page, framebuffer_size, ALIGN_4KB, MEM_PRIV_KERNEL); + framebuffer = VIRT_TO_PHYS((uintptr_t)kalloc(gpu_dev.memory_page, framebuffer_size, ALIGN_4KB, MEM_PRIV_KERNEL)); ctx = { .dirty_rects = {}, @@ -454,7 +455,7 @@ uint32_t VirtioGPUDriver::new_cursor(uint32_t color){ uint32_t *cursor = (uint32_t*)kalloc(gpu_dev.memory_page, cursor_size, ALIGN_4KB, MEM_PRIV_KERNEL); draw_ctx ctx = {{},cursor, 64 * BPP, 64, 64, 0,0}; fb_draw_cursor(&ctx, color); - attach_backing(id, (sizedptr){(uintptr_t)cursor, cursor_size}); + attach_backing(id, (sizedptr){VIRT_TO_PHYS((uintptr_t)cursor), cursor_size}); transfer_to_host(id, {{0,0},{64,64}}); return id; } From 38895b7d1e9cadfeec49955e6bf304c99ebd7705 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Tue, 18 Nov 2025 00:00:00 +0000 Subject: [PATCH 36/43] [MMU XHCI] fixed ring link pointer --- kernel/input/xhci.cpp | 2 +- kernel/memory/mmu.c | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/kernel/input/xhci.cpp b/kernel/input/xhci.cpp index 9ed46ef5..ade07048 100644 --- a/kernel/input/xhci.cpp +++ b/kernel/input/xhci.cpp @@ -293,7 +293,7 @@ void XHCIDriver::make_ring_link_control(trb* ring, bool cycle){ } void XHCIDriver::make_ring_link(trb* ring, bool cycle){ - ring[MAX_TRB_AMOUNT-1].parameter = (uintptr_t)ring; + ring[MAX_TRB_AMOUNT-1].parameter = VIRT_TO_PHYS((uintptr_t)ring); ring[MAX_TRB_AMOUNT-1].status = 0; make_ring_link_control(ring, cycle); } diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index 8e6d6091..f3e1de6b 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -213,15 +213,11 @@ void mmu_copy(uintptr_t *new_ttrb, uintptr_t *old_ttrb, int level){ if (level == 3 || (old_ttrb[i] & 0b11) == PD_BLOCK){ new_ttrb[i] = old_ttrb[i]; } else { - kprintf("Old Entry %x",old_ttrb[i]); uintptr_t *old_entry = (uintptr_t*)(old_ttrb[i] & 0xFFFFFFFFF000ULL); uintptr_t *new_entry = mmu_alloc(); if (!old_entry || !new_entry) continue; - kprintf("[%i] %x -> %x",level,old_entry, new_entry); uint64_t entry = old_ttrb[i] & ~(0xFFFFFFFFF000ULL); - kprintf("Entry %x",entry); new_ttrb[i] = entry | ((uintptr_t)new_entry & 0xFFFFFFFFF000ULL); - kprintf("Full entry %x",new_ttrb[i]); if (level < 3) mmu_copy(new_entry, old_entry, level+1); } } From c9538e630d86a985f07b6d160dec69c56dc2a47e Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Thu, 20 Nov 2025 00:00:00 +0000 Subject: [PATCH 37/43] [MMU] process output to high VA --- kernel/kernel_processes/kprocess_loader.c | 4 ++-- kernel/process/loading/process_loader.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/kernel_processes/kprocess_loader.c b/kernel/kernel_processes/kprocess_loader.c index 17fe6438..74268b56 100644 --- a/kernel/kernel_processes/kprocess_loader.c +++ b/kernel/kernel_processes/kprocess_loader.c @@ -30,14 +30,14 @@ process_t *create_kernel_process(const char *name, int (*func)(int argc, char* a proc->sp = proc->stack; - proc->pc = ((uintptr_t)func) | HIGH_VA; + proc->pc = PHYS_TO_VIRT(((uintptr_t)func)); kprintf("Kernel process %s (%i) allocated with address at %llx, stack at %llx, heap at %llx. %i argument(s)", (uintptr_t)name, proc->id, proc->pc, proc->sp, proc->heap, argc); proc->spsr = 0x205; proc->state = READY; proc->PROC_X0 = argc; proc->PROC_X1 = (uintptr_t)argv; - proc->output = (uintptr_t)palloc(0x1000, MEM_PRIV_KERNEL, MEM_RW, true); + proc->output = PHYS_TO_VIRT((uintptr_t)palloc(0x1000, MEM_PRIV_KERNEL, MEM_RW, true)); enable_interrupt(); diff --git a/kernel/process/loading/process_loader.c b/kernel/process/loading/process_loader.c index 694d4ec6..6c575515 100644 --- a/kernel/process/loading/process_loader.c +++ b/kernel/process/loading/process_loader.c @@ -343,7 +343,7 @@ process_t* create_process(const char *name, const char *bundle, sizedptr text, u proc->sp = proc->stack; - proc->output = (uintptr_t)palloc(0x1000, MEM_PRIV_USER, MEM_RW, true); + proc->output = PHYS_TO_VIRT((uintptr_t)palloc(0x1000, MEM_PRIV_USER, MEM_RW, true)); proc->pc = (uintptr_t)(entry); kprintf("User process %s allocated with address at %x, stack at %x, heap at %x",(uintptr_t)name,proc->pc, proc->sp, proc->heap); proc->spsr = 0; From d76139016ba16057387819f0174a71fcb5f11f25 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Fri, 21 Nov 2025 00:00:00 +0000 Subject: [PATCH 38/43] [PROC] fixed process output propagation logic --- kernel/input/xhci.cpp | 2 +- kernel/process/scheduler.c | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/kernel/input/xhci.cpp b/kernel/input/xhci.cpp index ade07048..aee8fa53 100644 --- a/kernel/input/xhci.cpp +++ b/kernel/input/xhci.cpp @@ -313,7 +313,7 @@ bool XHCIDriver::await_response(uint64_t command, uint32_t type){ } for (; event_ring.index < MAX_TRB_AMOUNT; event_ring.index++){ last_event = &event_ring.ring[event_ring.index]; - kprintf("LAST EVENT %llx",last_event); + // kprintf("LAST EVENT %llx",last_event); if (!wait(&last_event->control, event_ring.cycle_bit, true, 2000)){ kprintf("[xHCI error] Timeout awaiting response to %llx command of type %llx", command, type); awaited_type = 0; diff --git a/kernel/process/scheduler.c b/kernel/process/scheduler.c index d33d69fb..38cfdf7d 100644 --- a/kernel/process/scheduler.c +++ b/kernel/process/scheduler.c @@ -14,6 +14,7 @@ #include "math/math.h" #include "memory/mmu.h" #include "process/syscall.h" +#include "sysregs.h" extern void save_pc_interrupt(uintptr_t ptr); extern void restore_context(uintptr_t ptr); @@ -316,7 +317,7 @@ FS_RESULT open_proc(const char *path, file *descriptor){ file->buffer = proc->output; } else if (strcmp(path, "state", true) == 0){ descriptor->size = sizeof(int); - file->buffer = (uintptr_t)&proc->state; + file->buffer = PHYS_TO_VIRT((uintptr_t)&proc->state); file->ignore_cursor = true; file->read_only = true; } else return FS_RESULT_NOTFOUND; @@ -364,6 +365,10 @@ size_t write_proc(file* fd, const char *buf, size_t size, file_offset offset){ if (fd->id == FD_OUT){ process_t *proc = get_current_proc(); pbuf = proc->output; + if (size >= PROC_OUT_BUF){ + kprint("Output too large"); + return 0; + } } else { node = clinkedlist_find(proc_opened_files, (void*)&fd->id, find_open_proc_file); if (!node->data) return 0; @@ -372,10 +377,6 @@ size_t write_proc(file* fd, const char *buf, size_t size, file_offset offset){ pbuf = file->buffer; } - if (size >= PROC_OUT_BUF){ - kprint("Output too large"); - return 0; - } if (fd->cursor + size >= PROC_OUT_BUF){ fd->cursor = 0; memset((void*)pbuf, 0, PROC_OUT_BUF); @@ -383,8 +384,8 @@ size_t write_proc(file* fd, const char *buf, size_t size, file_offset offset){ memcpy((void*)(pbuf + fd->cursor), buf, size); fd->cursor += size; //TODO: Need a better way to handle opening a file multiple times - for (clinkedlist_node_t *start = proc_opened_files->head; start != proc_opened_files->tail; start = start->next){ - if (start != node){ + for (clinkedlist_node_t *start = proc_opened_files->head; start != 0; start = start->next){ + if (fd->id == FD_OUT || start != node){ proc_open_file *n_file = (proc_open_file*)start->data; if (n_file && n_file->buffer == pbuf){ n_file->file_size += size; From b20a5ecf585ce0b3f4a8efd613efbeca519bf51f Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Fri, 21 Nov 2025 00:00:00 +0000 Subject: [PATCH 39/43] [PROJ] added wheel of debt --- wheelofdebt | 1 + 1 file changed, 1 insertion(+) create mode 100755 wheelofdebt diff --git a/wheelofdebt b/wheelofdebt new file mode 100755 index 00000000..c1a7bae4 --- /dev/null +++ b/wheelofdebt @@ -0,0 +1 @@ +find . \( -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.hpp" -o -name "*.S" \) -print0 | xargs -0 cat | grep "TODO" | awk 'BEGIN{srand()} {print rand(), $0}' | sort -n | head -n 1 | cut -d' ' -f2- From 75345550163b28e90a49af1a13a2a3e10d09de80 Mon Sep 17 00:00:00 2001 From: Diego Ferrari Date: Fri, 21 Nov 2025 00:00:00 +0000 Subject: [PATCH 40/43] [CAT] made cat size argument optional --- bin/cat/cat.c | 6 +++--- kernel/process/scheduler.c | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/bin/cat/cat.c b/bin/cat/cat.c index 37b92269..841263a1 100644 --- a/bin/cat/cat.c +++ b/bin/cat/cat.c @@ -2,14 +2,14 @@ int main(int argc, const char* argv[]){ file fd2 = { .id = 2 }; - if (argc != 2){ - string err_msg = string_from_literal("Usage cat "); + if (argc < 1 || argc > 2){ + string err_msg = string_from_literal("Usage cat [size]"); fwrite(&fd2, err_msg.data, err_msg.length); free(err_msg.data, err_msg.mem_length); return 2; } const char* path = argv[0]; - size_t size = parse_int_u64(argv[1], UINT32_MAX); + size_t size = argc < 2 ? 0 : parse_int_u64(argv[1], UINT32_MAX); file fd = {}; fopen(path, &fd); if (fd.size == 0){ diff --git a/kernel/process/scheduler.c b/kernel/process/scheduler.c index 38cfdf7d..08e7169e 100644 --- a/kernel/process/scheduler.c +++ b/kernel/process/scheduler.c @@ -365,10 +365,8 @@ size_t write_proc(file* fd, const char *buf, size_t size, file_offset offset){ if (fd->id == FD_OUT){ process_t *proc = get_current_proc(); pbuf = proc->output; - if (size >= PROC_OUT_BUF){ - kprint("Output too large"); - return 0; - } + if (size > PROC_OUT_BUF) + size = PROC_OUT_BUF; } else { node = clinkedlist_find(proc_opened_files, (void*)&fd->id, find_open_proc_file); if (!node->data) return 0; From f350777cac2801b5154816e327c91f58af73994c Mon Sep 17 00:00:00 2001 From: dif Date: Sat, 22 Nov 2025 00:00:00 +0000 Subject: [PATCH 41/43] [MMU, PROC] mapping user process stack/heap to va --- kernel/bin/bin_mod.c | 27 +++++++++++----- kernel/memory/mmu.c | 41 ++++++++++++++++++++++++- kernel/memory/mmu.h | 1 + kernel/memory/page_allocator.c | 36 +++++++++++++++++----- kernel/memory/page_allocator.h | 1 + kernel/process/loading/process_loader.c | 31 +++++++++++++------ kernel/process/process.h | 3 ++ kernel/process/scheduler.c | 4 +-- kernel/process/syscall.c | 6 ++-- 9 files changed, 121 insertions(+), 29 deletions(-) diff --git a/kernel/bin/bin_mod.c b/kernel/bin/bin_mod.c index 644eee49..2e7ff0a6 100644 --- a/kernel/bin/bin_mod.c +++ b/kernel/bin/bin_mod.c @@ -51,17 +51,30 @@ process_t* execute(const char* prog_name, int argc, const char* argv[]){ } process_t *proc = load_elf_file(prog_name, 0, program, fd.size); string_free(path); - free(full_name,name_len); + free(full_name, name_len); if (!proc){ kprintf("Failed to create process for %s",prog_name); } proc->PROC_X0 = argc; - size_t total = 0; - for (int i = 0; i < argc; i++) - total += strlen(argv[i], 0); - char **nargv = (char **)kalloc((void*)proc->heap, total, ALIGN_16B, MEM_PRIV_USER); - memcpy(nargv, argv, total); - proc->PROC_X1 = (uintptr_t)nargv; + if (argc > 0){ + uintptr_t start = (uintptr_t)argv[0]; + uintptr_t end = (uintptr_t)argv; + size_t total = end-start; + size_t argvs = argc * sizeof(uintptr_t); + char *nargvals = (char*)(proc->stack_phys-total-argvs); + char *vnargvals = (char*)(proc->stack-total-argvs); + char** nargv = (char**)(proc->stack_phys-argvs); + uintptr_t strptr = 0; + for (int i = 0; i < argc; i++){ + size_t strsize = strlen(argv[i],0); + memcpy(nargvals + strptr, argv[i], strsize); + *(char*)(nargvals + strptr + strsize) = 0; + nargv[i] = vnargvals + strptr; + strptr += strsize; + } + proc->PROC_X1 = (uintptr_t)proc->stack-argvs; + proc->sp -= total+argvs; + } proc->state = READY; return proc; } diff --git a/kernel/memory/mmu.c b/kernel/memory/mmu.c index f3e1de6b..dcf1a238 100644 --- a/kernel/memory/mmu.c +++ b/kernel/memory/mmu.c @@ -254,11 +254,50 @@ void register_proc_memory(uint64_t va, uint64_t pa, uint8_t attributes, uint8_t mmu_flush_icache(); } +uintptr_t mmu_translate(uintptr_t va){ + uint64_t *table = pttrb && (va >> 48) == 0 ? pttrb : kernel_mmu_page; + + uint64_t l0_index = (va >> 39) & 0x1FF; + uint64_t l1_index = (va >> 30) & 0x1FF; + uint64_t l2_index = (va >> 21) & 0x1FF; + uint64_t l3_index = (va >> 12) & 0x1FF; + + if (!(table[l0_index] & 1)) { + kprintf("L1 Table missing"); + return 0; + } + uint64_t* l1 = (uint64_t*)(table[l0_index] & 0xFFFFFFFFF000ULL); + if (!(l1[l1_index] & 1)) { + kprintf("L2 Table missing"); + return 0; + } + uint64_t* l2 = (uint64_t*)(l1[l1_index] & 0xFFFFFFFFF000ULL); + uint64_t l3_val = l2[l2_index]; + if (!(l3_val & 1)) { + kprintf("L3 Table missing"); + return 0; + } + + if (!((l3_val >> 1) & 1)){ + kprintf("Mapped as 2MB memory in L3"); + kprintf("Entry: %b", l3_val); + return 0; + } + + uint64_t* l3 = (uint64_t*)(l2[l2_index] & 0xFFFFFFFFF000ULL); + uint64_t l4_val = l3[l3_index]; + if (!(l4_val & 1)){ + kprintf("L4 Table entry missing"); + return 0; + } + return l4_val & 0xFFFFFFFFF000ULL; +} + void debug_mmu_address(uint64_t va){ uint64_t *table = pttrb ? pttrb : kernel_mmu_page; - uint64_t l0_index = (va >> 37) & 0x1FF; + uint64_t l0_index = (va >> 39) & 0x1FF; uint64_t l1_index = (va >> 30) & 0x1FF; uint64_t l2_index = (va >> 21) & 0x1FF; uint64_t l3_index = (va >> 12) & 0x1FF; diff --git a/kernel/memory/mmu.h b/kernel/memory/mmu.h index c8028871..ce69294e 100644 --- a/kernel/memory/mmu.h +++ b/kernel/memory/mmu.h @@ -20,6 +20,7 @@ void debug_mmu_address(uint64_t va); void mmu_enable_verbose(); void mmu_swap_ttbr(uintptr_t* ttbr); void mmu_default_ttbr(); +uintptr_t mmu_translate(uintptr_t va); #ifdef __cplusplus } #endif diff --git a/kernel/memory/page_allocator.c b/kernel/memory/page_allocator.c index 2734999d..64d3f61f 100644 --- a/kernel/memory/page_allocator.c +++ b/kernel/memory/page_allocator.c @@ -208,7 +208,7 @@ void mark_used(uintptr_t address, size_t pages) #define PAGE_INDEX_LIMIT (PAGE_SIZE-sizeof(page_index_hdr))/sizeof(page_index_entry) //TODO: maybe alloc to different base pages based on alignment? Then it's easier to keep track of full pages, freeing and sizes -void* kalloc_inner(void *page, uint64_t size, uint16_t alignment, uint8_t level){ +void* kalloc_inner(void *page, uint64_t size, uint16_t alignment, uint8_t level, uintptr_t page_va, uintptr_t *next_va, uintptr_t *ttrb){ //TODO: we're changing the size but not reporting it back, which means the free function does not fully free the allocd memory size = (size + alignment - 1) & ~(alignment - 1); @@ -220,19 +220,27 @@ void* kalloc_inner(void *page, uint64_t size, uint16_t alignment, uint8_t level) if (size >= PAGE_SIZE){ void* ptr = palloc(size, level, info->attributes, true); page_index *index = info->page_alloc; - if (!info->page_alloc){ - info->page_alloc = palloc(PAGE_SIZE, level, info->attributes, true); + if (!index){ + info->page_alloc = palloc(PAGE_SIZE, level, info->attributes, true);//TODO: HIGH_VA index = info->page_alloc; } while (index->header.next) { index = index->header.next; } if (index->header.size >= PAGE_INDEX_LIMIT){ - index->header.next = palloc(PAGE_SIZE, level, info->attributes, true); + index->header.next = palloc(PAGE_SIZE, level, info->attributes, true);//TODO: HIGH_VA index = index->header.next; } index->ptrs[index->header.size].ptr = ptr; index->ptrs[index->header.size++].size = size; + if (page_va && next_va && ttrb){ + uintptr_t va = *next_va; + for (uintptr_t i = (uintptr_t)ptr; i < (uintptr_t)ptr + size; i+= GRANULE_4KB){ + mmu_map_4kb(ttrb, *next_va, (uintptr_t)i, (info->attributes & MEM_DEV) ? MAIR_IDX_DEVICE : MAIR_IDX_NORMAL, info->attributes, level); + *next_va += PAGE_SIZE; + } + return (void*)va; + } return ptr; } @@ -245,6 +253,9 @@ void* kalloc_inner(void *page, uint64_t size, uint16_t alignment, uint8_t level) *curr = (*curr)->next; memset((void*)result, 0, size); info->size += size; + if (page_va){ + return (void*)(page_va | (result & 0xFFF)); + } return (void*)result; } kprintfv("-> %x",(uintptr_t)&(*curr)->next); @@ -260,10 +271,14 @@ void* kalloc_inner(void *page, uint64_t size, uint16_t alignment, uint8_t level) if (info->next_free_mem_ptr + size > (((uintptr_t)page) + PAGE_SIZE)) { if (!info->next){ info->next = palloc(PAGE_SIZE, level, info->attributes, false); - kprintfv("[in_page_alloc] New page %x",info->next); + if (page_va && next_va && ttrb){ + mmu_map_4kb(ttrb, *next_va, (uintptr_t)info->next, (info->attributes & MEM_DEV) ? MAIR_IDX_DEVICE : MAIR_IDX_NORMAL, info->attributes, level); + *next_va += PAGE_SIZE; + } + kprintfv("[in_page_alloc] Page %llx points to new page %llx",page,info->next); } kprintfv("[in_page_alloc] Page full. Moving to %x",(uintptr_t)info->next); - return kalloc(info->next, size, alignment, level); + return kalloc_inner(info->next, size, alignment, level, page_va ? page_va + PAGE_SIZE : 0, next_va, ttrb); } uint64_t result = info->next_free_mem_ptr; @@ -273,12 +288,15 @@ void* kalloc_inner(void *page, uint64_t size, uint16_t alignment, uint8_t level) memset((void*)result, 0, size); info->size += size; + if (page_va){ + return (void*)(page_va | (result & 0xFFF)); + } return (void*)result; } //TODO: rather than kalloc, it should be palloc that does translations void* kalloc(void *page, uint64_t size, uint16_t alignment, uint8_t level){ - void* ptr = kalloc_inner(page, size, alignment, level); + void* ptr = kalloc_inner(page, size, alignment, level, 0, 0, 0); if (level == MEM_PRIV_KERNEL) ptr = PHYS_TO_VIRT_P(ptr); return ptr; } @@ -290,7 +308,9 @@ void kfree(void* ptr, uint64_t size) { mem_page *page = (mem_page *)(((uintptr_t)ptr) & ~0xFFF); - FreeBlock* block = (FreeBlock*)ptr; + uintptr_t phys_page = mmu_translate((uintptr_t)page); + + FreeBlock* block = (FreeBlock*)((uintptr_t)phys_page | ((uintptr_t)ptr & 0xFFF)); block->size = size; block->next = page->free_list; page->free_list = block; diff --git a/kernel/memory/page_allocator.h b/kernel/memory/page_allocator.h index 3fd97c49..9c95442b 100644 --- a/kernel/memory/page_allocator.h +++ b/kernel/memory/page_allocator.h @@ -31,6 +31,7 @@ void mark_used(uintptr_t address, size_t pages); bool page_used(uintptr_t ptr); +void* kalloc_inner(void *page, uint64_t size, uint16_t alignment, uint8_t level, uintptr_t page_va, uintptr_t *next_va, uintptr_t *ttrb); void* kalloc(void *page, uint64_t size, uint16_t alignment, uint8_t level); void kfree(void* ptr, uint64_t size); diff --git a/kernel/process/loading/process_loader.c b/kernel/process/loading/process_loader.c index 6c575515..9907790b 100644 --- a/kernel/process/loading/process_loader.c +++ b/kernel/process/loading/process_loader.c @@ -293,8 +293,6 @@ process_t* create_process(const char *name, const char *bundle, sizedptr text, u if (bss_va + bss.size > max_addr) max_addr = bss_va + bss.size; } - // max_addr = (max_addr + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - size_t code_size = max_addr-min_addr; // kprintf("Code takes %x from %x to %x",code_size, min_addr, max_addr); @@ -320,24 +318,39 @@ process_t* create_process(const char *name, const char *bundle, sizedptr text, u proc->va = min_addr; proc->code = (void*)dest; proc->code_size = (code_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + + max_addr = (max_addr + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + proc->last_va_mapping = max_addr; uint64_t stack_size = 0x1000; uintptr_t stack = (uintptr_t)palloc(stack_size, MEM_PRIV_USER, MEM_RW, true); if (!stack) return 0; + + proc->last_va_mapping += PAGE_SIZE;//Unmapped page to catch stack overflows + proc->stack = (proc->last_va_mapping + stack_size); + proc->stack_phys = (stack + stack_size); + + for (uintptr_t i = stack; i < stack + stack_size; i += GRANULE_4KB){ + mmu_map_4kb(ttbr, proc->last_va_mapping, i, MAIR_IDX_NORMAL, MEM_RW | MEM_NORM, MEM_PRIV_USER); + mmu_map_4kb(ttbr, i, i, MAIR_IDX_NORMAL, MEM_RW | MEM_NORM, MEM_PRIV_USER); + kprintf("Stack %llx -> %llx",proc->last_va_mapping, i); + proc->last_va_mapping += PAGE_SIZE; + } - //TODO: use VA stack & heap. And expand heap's mapping as it grows - for (uintptr_t i = stack; i < stack + stack_size; i += GRANULE_4KB) - mmu_map_4kb(ttbr, i, i, MAIR_IDX_NORMAL, MEM_RO | MEM_NORM, MEM_PRIV_USER); + proc->last_va_mapping += PAGE_SIZE;//Unmapped page to catch stack overflows uintptr_t heap = (uintptr_t)palloc(PAGE_SIZE, MEM_PRIV_USER, MEM_RW, false); if (!heap) return 0; - mmu_map_4kb(ttbr, heap, heap, MAIR_IDX_NORMAL, MEM_RO | MEM_NORM, MEM_PRIV_USER); + proc->heap = proc->last_va_mapping; + proc->heap_phys = heap; + mmu_map_4kb(ttbr, proc->last_va_mapping, heap, MAIR_IDX_NORMAL, MEM_RW | MEM_NORM, MEM_PRIV_USER); + mmu_map_4kb(ttbr, heap, heap, MAIR_IDX_NORMAL, MEM_RW | MEM_NORM, MEM_PRIV_USER); + + proc->last_va_mapping += PAGE_SIZE; - proc->stack = (stack + stack_size); proc->stack_size = stack_size; - proc->heap = heap; proc->ttbr = ttbr; @@ -345,7 +358,7 @@ process_t* create_process(const char *name, const char *bundle, sizedptr text, u proc->output = PHYS_TO_VIRT((uintptr_t)palloc(0x1000, MEM_PRIV_USER, MEM_RW, true)); proc->pc = (uintptr_t)(entry); - kprintf("User process %s allocated with address at %x, stack at %x, heap at %x",(uintptr_t)name,proc->pc, proc->sp, proc->heap); + kprintf("User process %s allocated with address at %llx, stack at %llx (%llx), heap at %llx (%llx)",(uintptr_t)name,proc->pc, proc->sp, proc->stack_phys, proc->heap, proc->heap_phys); proc->spsr = 0; proc->state = BLOCKED; diff --git a/kernel/process/process.h b/kernel/process/process.h index f2d37f0e..3b4ebdc6 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -42,9 +42,12 @@ typedef struct { //Not used in process saving uint16_t id; uintptr_t stack; + uintptr_t stack_phys; uint64_t stack_size; uintptr_t heap; + uintptr_t heap_phys; uintptr_t output; + uintptr_t last_va_mapping; file out_fd; uint64_t exit_code; bool focused; diff --git a/kernel/process/scheduler.c b/kernel/process/scheduler.c index 08e7169e..9d098d4f 100644 --- a/kernel/process/scheduler.c +++ b/kernel/process/scheduler.c @@ -114,8 +114,8 @@ void reset_process(process_t *proc){ bool just_finished = processes[current_proc].id == proc->id; proc->sp = 0; if (!just_finished || !(processes[current_proc].PROC_PRIV))//Privileged processes use their own stack even in an exception. We'll free it when we reuse it - if (proc->stack) pfree((void*)proc->stack-proc->stack_size,proc->stack_size); - if (proc->heap) free_managed_page((void*)proc->heap);//Sadly, full pages of alloc'd memory are not kept track and will not be freed + if (proc->stack_phys) pfree((void*)proc->stack_phys-proc->stack_size,proc->stack_size); + if (proc->heap_phys) free_managed_page((void*)proc->heap_phys); proc->pc = 0; proc->spsr = 0; proc->exit_code = 0; diff --git a/kernel/process/syscall.c b/kernel/process/syscall.c index 9fac2102..9ac33ef1 100644 --- a/kernel/process/syscall.c +++ b/kernel/process/syscall.c @@ -22,6 +22,7 @@ #include "bin/bin_mod.h" #include "net/transport_layer/csocket.h" #include "loading/dwarf.h" +#include "sysregs.h" int syscall_depth = 0; @@ -31,11 +32,12 @@ uintptr_t cpec; typedef uint64_t (*syscall_entry)(process_t *ctx); uint64_t syscall_malloc(process_t *ctx){ - void* page_ptr = syscall_depth > 1 ? (void*)get_proc_by_pid(1)->heap : (void*)get_current_heap(); + void* page_ptr = (void*)mmu_translate(syscall_depth > 1 ? get_proc_by_pid(1)->heap : ctx->heap); if ((uintptr_t)page_ptr == 0x0){ handle_exception("Wrong process heap state", 0); } - return (uintptr_t)kalloc(page_ptr, ctx->PROC_X0, ALIGN_16B, get_current_privilege()); + size_t size = ctx->PROC_X0; + return (uintptr_t)kalloc_inner(page_ptr, size, ALIGN_16B, get_current_privilege(), ctx->heap, &ctx->last_va_mapping, ctx->ttbr); } uint64_t syscall_free(process_t *ctx){ From d1e8a33f37afd879ba127b0ea996d68e85d32ad1 Mon Sep 17 00:00:00 2001 From: dif Date: Sat, 22 Nov 2025 00:00:00 +0000 Subject: [PATCH 42/43] [TERMINAL] reusing buffer --- utils/terminal/terminal.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/utils/terminal/terminal.cpp b/utils/terminal/terminal.cpp index b2c2c69d..840037dd 100644 --- a/utils/terminal/terminal.cpp +++ b/utils/terminal/terminal.cpp @@ -38,16 +38,15 @@ bool Terminal::exec_cmd(const char *cmd, int argc, const char *argv[]){ free(s1.data, s1.mem_length); fopen(s2.data, &state_fd); free(s2.data, s2.mem_length); - int state; - fread(&state_fd, (char*)&state, sizeof(int)); - while (state) { - fread(&state_fd, (char*)&state, sizeof(int)); - size_t amount = 0x100; - char *buf = (char*)malloc(amount); + int state = 1; + size_t amount = 0x100; + char *buf = (char*)malloc(amount); + do { fread(&out_fd, buf, amount); put_string(buf); - free(buf, amount); - } + fread(&state_fd, (char*)&state, sizeof(int)); + } while (state); + free(buf, amount); fclose(&out_fd); fclose(&state_fd); string exit_msg = string_format("\nProcess %i ended.",proc); From 6ea0eec978f56a2bf9c9abcab71343ffe613e00c Mon Sep 17 00:00:00 2001 From: dif Date: Sat, 22 Nov 2025 00:00:00 +0000 Subject: [PATCH 43/43] [PROC] keeping track of process output size --- kernel/process/process.h | 1 + kernel/process/scheduler.c | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/kernel/process/process.h b/kernel/process/process.h index 3b4ebdc6..62b56c7e 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -47,6 +47,7 @@ typedef struct { uintptr_t heap; uintptr_t heap_phys; uintptr_t output; + size_t output_size; uintptr_t last_va_mapping; file out_fd; uint64_t exit_code; diff --git a/kernel/process/scheduler.c b/kernel/process/scheduler.c index 9d098d4f..7b3332db 100644 --- a/kernel/process/scheduler.c +++ b/kernel/process/scheduler.c @@ -313,7 +313,7 @@ FS_RESULT open_proc(const char *path, file *descriptor){ file->pid = proc->id; if (strcmp(path, "out", true) == 0){ - descriptor->size = 0;//TODO: sizeof buffer, could already have data + descriptor->size = proc->output_size; file->buffer = proc->output; } else if (strcmp(path, "state", true) == 0){ descriptor->size = sizeof(int); @@ -381,13 +381,19 @@ size_t write_proc(file* fd, const char *buf, size_t size, file_offset offset){ } memcpy((void*)(pbuf + fd->cursor), buf, size); fd->cursor += size; - //TODO: Need a better way to handle opening a file multiple times - for (clinkedlist_node_t *start = proc_opened_files->head; start != 0; start = start->next){ - if (fd->id == FD_OUT || start != node){ - proc_open_file *n_file = (proc_open_file*)start->data; - if (n_file && n_file->buffer == pbuf){ - n_file->file_size += size; - } + if (fd->id == FD_OUT){ + process_t *proc = get_current_proc(); + proc->output_size += size; + } + if (proc_opened_files && proc_opened_files->head){ + //TODO: Need a better way to handle opening a file multiple times + for (clinkedlist_node_t *start = proc_opened_files->head; start != 0; start = start->next){ + if (fd->id == FD_OUT || start != node){ + proc_open_file *n_file = (proc_open_file*)start->data; + if (n_file && n_file->buffer == pbuf){ + n_file->file_size += size; + } + } } } return size;