From 7a52f2f051d96813469db733cdcbd0e1a7be002d Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Sat, 30 Aug 2025 00:31:20 +0200 Subject: [PATCH] Rework x86_64 paging and vmm --- kernel/Makefile | 1 + kernel/atomic.h | 6 ++ kernel/bitmap/bitmap.h | 1 - kernel/compiler/attr.h | 1 + kernel/dlmalloc/malloc.c | 6 +- kernel/hal/hal.h | 1 + kernel/hal/x86_64/gdt.c | 2 +- kernel/hal/x86_64/hal.c | 2 +- kernel/hal/x86_64/intr.c | 79 ++++++--------------- kernel/hal/x86_64/intr.h | 29 ++++++++ kernel/hal/x86_64/intr0.S | 47 +++---------- kernel/hal/x86_64/paging.S | 9 +++ kernel/hal/x86_64/vmm.c | 65 +++++++++++++++++ kernel/hal/x86_64/vmm.h | 45 ++++++++++++ kernel/kmain.c | 11 ++- kernel/kprintf.h | 15 +++- kernel/paging/paging.h | 10 --- kernel/paging/x86_64/paging.c | 124 --------------------------------- kernel/pmm/pmm.c | 3 +- kernel/spinlock/spinlock.c | 7 +- kernel/spinlock/spinlock.h | 5 +- kernel/std/include/stdatomic.h | 5 +- kernel/term/term.c | 5 +- kernel/term/term.h | 2 + kernel/util/util.h | 12 ++++ kernel/vfs/vfs.c | 2 +- kernel/vmm/vmm.c | 51 +++++--------- kernel/vmm/vmm.h | 7 +- 28 files changed, 262 insertions(+), 291 deletions(-) create mode 100644 kernel/atomic.h create mode 100644 kernel/hal/x86_64/paging.S create mode 100644 kernel/hal/x86_64/vmm.c create mode 100644 kernel/hal/x86_64/vmm.h delete mode 100644 kernel/paging/paging.h delete mode 100644 kernel/paging/x86_64/paging.c diff --git a/kernel/Makefile b/kernel/Makefile index 060fbb9..8ad125b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -47,6 +47,7 @@ SRCFILES := $(wildcard *.c) \ $(wildcard fs/littlefs/*.c) \ $(wildcard fs/portlfs/*.c) \ $(wildcard baseimg/*.c) \ + $(wildcard task/*.c) \ $(wildcard hal/*.c) \ $(wildcard hal/$(ARCH)/*.c) \ $(wildcard hal/$(ARCH)/*.S) \ diff --git a/kernel/atomic.h b/kernel/atomic.h new file mode 100644 index 0000000..e4ed042 --- /dev/null +++ b/kernel/atomic.h @@ -0,0 +1,6 @@ +#ifndef ATOMIC_H_ +#define ATOMIC_H_ + +#define ATOMIC(X) _Atomic(X) + +#endif // ATOMIC_H_ diff --git a/kernel/bitmap/bitmap.h b/kernel/bitmap/bitmap.h index 0cd188e..5de35df 100644 --- a/kernel/bitmap/bitmap.h +++ b/kernel/bitmap/bitmap.h @@ -12,7 +12,6 @@ typedef struct { size_t alloc_blocks; size_t last_deep_frag; uintptr_t mem_start; - bool init; } BitMap; #define BITMAP_BLOCKS_PER_BYTE 8 diff --git a/kernel/compiler/attr.h b/kernel/compiler/attr.h index 2877b0b..b8ae016 100644 --- a/kernel/compiler/attr.h +++ b/kernel/compiler/attr.h @@ -3,5 +3,6 @@ #define PACKED __attribute__((packed)) #define ALIGNED(x) __attribute__((aligned((x)))) +#define NORETURN __attribute__((noreturn)) #endif // COMPILER_ATTR_H_ diff --git a/kernel/dlmalloc/malloc.c b/kernel/dlmalloc/malloc.c index 16740f2..c7dc843 100644 --- a/kernel/dlmalloc/malloc.c +++ b/kernel/dlmalloc/malloc.c @@ -7,6 +7,7 @@ #include "bitmap/bitmap.h" #include "util/util.h" #include "vmm/vmm.h" +#include "pmm/pmm.h" #include "malloc.h" #define USE_DL_PREFIX 1 @@ -64,10 +65,9 @@ void *sbrk(long inc) { } uint64_t blocks = _DIV_ROUNDUP(inc, BITMAP_BLOCK_SIZE); - void *virt = vmm_alloc(blocks); + uint8_t *virt = VIRT(pmm_alloc(blocks)); hal_memset(virt, 0, blocks * BITMAP_BLOCK_SIZE); - - _last = (void *)((size_t)virt + inc); + _last = (void *)(virt + inc); return virt; } diff --git a/kernel/hal/hal.h b/kernel/hal/hal.h index d6b4034..7dee641 100644 --- a/kernel/hal/hal.h +++ b/kernel/hal/hal.h @@ -22,6 +22,7 @@ void hal_init_withmalloc(void); #if defined(__x86_64__) # define HAL_PAGE_SIZE 0x1000 +# include "x86_64/vmm.h" #endif #endif // KERNEL_HAL_HAL_H_ diff --git a/kernel/hal/x86_64/gdt.c b/kernel/hal/x86_64/gdt.c index 61259db..fa79196 100644 --- a/kernel/hal/x86_64/gdt.c +++ b/kernel/hal/x86_64/gdt.c @@ -50,7 +50,7 @@ typedef struct { ALIGNED(16) static Tss tss = {0}; ALIGNED(16) static ExtendedGdt gdt = {0}; -void gdt_setentry(GdtEntry *ent, uint32_t base, uint32_t limit, uint32_t acc, uint8_t gran) { +void gdt_setentry(GdtEntry *ent, uint32_t base, uint32_t limit, uint8_t acc, uint8_t gran) { ent->baselow = base & 0xffff; ent->basemid = (base >> 16) & 0xff; ent->basehigh = (base >> 24) & 0xff; diff --git a/kernel/hal/x86_64/hal.c b/kernel/hal/x86_64/hal.c index 61cc077..fdbf571 100644 --- a/kernel/hal/x86_64/hal.c +++ b/kernel/hal/x86_64/hal.c @@ -31,6 +31,6 @@ void hal_init_withmalloc(void) { intr_init(); pit_init(); ioapic_setentry(IOAPIC, acpi_remapirq(0x00), INTR_TIMER); - hal_intr_enable(); + hal_intr_disable(); } diff --git a/kernel/hal/x86_64/intr.c b/kernel/hal/x86_64/intr.c index ffcfd71..3c645a9 100644 --- a/kernel/hal/x86_64/intr.c +++ b/kernel/hal/x86_64/intr.c @@ -1,5 +1,6 @@ #include #include +#include #include "intr.h" #include "io.h" #include "gdt.h" @@ -55,45 +56,6 @@ void idt_init(void) { LOG("hal", "idt init\n"); } -typedef struct { - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - uint64_t r11; - uint64_t r10; - uint64_t r9; - uint64_t r8; - uint64_t rsi; - uint64_t rdi; - uint64_t rbp; - uint64_t rdx; - uint64_t rcx; - uint64_t rbx; - uint64_t rax; -} PACKED CpuRegs; - -typedef struct { - uint64_t cr8; - uint64_t cr4; - uint64_t cr3; - uint64_t cr2; - uint64_t cr0; -} PACKED CpuCtrlRegs; - -typedef struct { - CpuCtrlRegs ctrl; - CpuRegs regs; - uint64_t trapnum; - uint64_t errnum; - - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; -} PACKED IntrStackFrame; - extern void *ISR_REDIRTABLE[]; static const char *exceptions[] = { @@ -164,36 +126,39 @@ void intr_init(void) { } void intr_dumpframe(IntrStackFrame *frame) { - kprintf("r15=%016lx r14=%016lx r13=%016lx r12=%016lx\n" - "r11=%016lx r10=%016lx r9 =%016lx r8 =%016lx\n" - "rsi=%016lx rdi=%016lx rbp=%016lx rdx=%016lx\n" - "rcx=%016lx rbx=%016lx rax=%016lx\n" - "cr8=%016lx cr4=%016lx cr3=%016lx cr2=%016lx\n" - "cr0=%016lx rip=%016lx cs =%016lx rfl=%016lx\n" - "rsp=%016lx ss =%016lx trp=%016lx err=%016lx\n", - frame->regs.r15, frame->regs.r14, frame->regs.r13, frame->regs.r12, - frame->regs.r11, frame->regs.r10, frame->regs.r9, frame->regs.r8, - frame->regs.rsi, frame->regs.rdi, frame->regs.rbp, frame->regs.rdx, - frame->regs.rcx, frame->regs.rbx, frame->regs.rax, - frame->ctrl.cr8, frame->ctrl.cr4, frame->ctrl.cr3, - frame->ctrl.cr2, frame->ctrl.cr0, frame->rip, frame->cs, frame->rflags, - frame->rsp, frame->ss, frame->trapnum, frame->errnum + uint64_t cr2; + asm volatile("mov %%cr2, %0" : "=r"(cr2)); + uint64_t cr3; + asm volatile("mov %%cr3, %0" : "=r"(cr3)); + uint64_t cr4; + asm volatile("mov %%cr4, %0" : "=r"(cr4)); + kprintf_unsafe("rax=%016lx rcx=%016lx rdx=%016lx\n" + "rsi=%016lx rdi=%016lx r8 =%016lx\n" + "r9 =%016lx r10=%016lx r11=%016lx\n" + "rip=%016lx rfl=%016lx rsp=%016lx\n" + "cs =%016lx ss =%016lx trp=%016lx\n" + "cr2=%016lx cr3=%016lx cr4=%016lx\n" + "\n\n", + frame->regs.rax, frame->regs.rcx, frame->regs.rdx, + frame->regs.rsi, frame->regs.rdi, frame->regs.r8, + frame->regs.r9, frame->regs.r10, frame->regs.r11, + frame->rip, frame->rflags, frame->rsp, + frame->cs, frame->ss, frame->trapnum, + cr2, cr3, cr4 ); } void intr_handleintr(IntrStackFrame *frame) { if (frame->trapnum >= 0 && frame->trapnum <= 31) { // EXCEPTION - ERR("ERROR", "%s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum); + kprintf_unsafe("ERROR", "%s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum); intr_dumpframe(frame); hal_hang(); } else if (frame->trapnum >= 32 && frame->trapnum <= 47) { if (frame->trapnum == INTR_TIMER) { - kprintf("ACK %d\n", PIT_TICKS); - PIT_TICKS++; io_out8(PIC2_CMD, 0x20); + PIT_TICKS++; } - io_out8(PIC1_CMD, 0x20); lapic_write(LAPIC_EOI, 0x00); } diff --git a/kernel/hal/x86_64/intr.h b/kernel/hal/x86_64/intr.h index f3795d0..5c7ca3c 100644 --- a/kernel/hal/x86_64/intr.h +++ b/kernel/hal/x86_64/intr.h @@ -6,6 +6,35 @@ #define INTR_TIMER 0x20 #define INTR_SPURIOUS 0xff +#include "compiler/attr.h" + +typedef struct { + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rdi; + uint64_t rsi; + uint64_t rdx; + uint64_t rcx; + uint64_t rax; +} PACKED SavedRegs; + +typedef struct { + SavedRegs regs; + uint64_t trapnum; + uint64_t errnum; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; +} PACKED IntrStackFrame; + void intr_init(void); #endif // HAL_INTR_H_ diff --git a/kernel/hal/x86_64/intr0.S b/kernel/hal/x86_64/intr0.S index 1e69a26..5547480 100644 --- a/kernel/hal/x86_64/intr0.S +++ b/kernel/hal/x86_64/intr0.S @@ -49,14 +49,12 @@ .global intr_vec46 .global intr_vec47 -.macro _PUSHAQ +.macro _push_regs push %rax - push %rbx push %rcx push %rdx - push %rbp - push %rdi push %rsi + push %rdi push %r8 push %r9 push %r10 @@ -67,7 +65,7 @@ push %r15 .endm -.macro _POPAQ +.macro _pop_regs pop %r15 pop %r14 pop %r13 @@ -76,58 +74,30 @@ pop %r10 pop %r9 pop %r8 - pop %rsi pop %rdi - pop %rbp + pop %rsi pop %rdx pop %rcx - pop %rbx pop %rax .endm -.macro _PUSHACR - mov %cr0, %rax - push %rax - - mov %cr2, %rax - push %rax - - mov %cr3, %rax - push %rax - - mov %cr4, %rax - push %rax - - mov %cr8, %rax - push %rax -.endm - -.macro _POPACR - add $0x28, %rsp -.endm - .macro _vecintr_errorcode_present_save num pushq $\num - _PUSHAQ - _PUSHACR .endm .macro _vecintr_plain_save num pushq $0x0 pushq $\num - _PUSHAQ - _PUSHACR .endm -siema: - jmp siema - .macro _vecintr_bodygen + _push_regs + cld mov %rsp, %rdi call intr_handleintr - _POPACR - _POPAQ + _pop_regs add $0x10, %rsp + iretq .endm @@ -227,7 +197,6 @@ intr_vec30: intr_vec31: _vecintr_plain_save 31 _vecintr_bodygen - intr_vec32: _vecintr_plain_save 32 _vecintr_bodygen diff --git a/kernel/hal/x86_64/paging.S b/kernel/hal/x86_64/paging.S new file mode 100644 index 0000000..e54570e --- /dev/null +++ b/kernel/hal/x86_64/paging.S @@ -0,0 +1,9 @@ +.global hal_loadpd +hal_loadpd: + mov %rdi, %cr3 + retq + +.global hal_invalpg +hal_invalpg: + invlpg (%rdi) + retq diff --git a/kernel/hal/x86_64/vmm.c b/kernel/hal/x86_64/vmm.c new file mode 100644 index 0000000..f242aa1 --- /dev/null +++ b/kernel/hal/x86_64/vmm.c @@ -0,0 +1,65 @@ +#include +#include +#include "vmm.h" +#include "hal/hal.h" +#include "bootinfo/bootinfo.h" +#include "pmm/pmm.h" + +PgTable *KERNEL_CR3 = NULL; + +PgTable *hal_vmm_current_cr3(void) { + PgTable *cr3; + asm volatile("mov %%cr3, %0" : "=r"(cr3)); + return cr3; +} + +PgIndex hal_vmm_pageindex(uint64_t vaddr) { + PgIndex ret; + + ret.pml4 = (vaddr & ((uint64_t)0x1ff < 39)) >> 39; + ret.pml3 = (vaddr & ((uint64_t)0x1ff < 30)) >> 30; + ret.pml2 = (vaddr & ((uint64_t)0x1ff < 21)) >> 21; + ret.pml1 = (vaddr & ((uint64_t)0x1ff < 12)) >> 12; + + return ret; +} + +uint64_t *hal_vmm_nexttable(uint64_t *table, uint64_t ent) { + uint8_t *addr; + + if (table[ent] & HAL_PG_PRESENT) { + addr = (uint8_t *)(table[ent] & ~((uint64_t)0xfff)); + } else { + addr = pmm_alloc(1); + hal_memset(BOOT_INFO.hhdm_off + addr, 0, HAL_PAGE_SIZE); + table[ent] = (uint64_t)addr | HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT; + } + + return (uint64_t *)(BOOT_INFO.hhdm_off + addr); +} + +void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags) { + PgIndex pi = hal_vmm_pageindex(virtaddr); + + uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4); + uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3); + uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2); + uint64_t *pte = &pml1[pi.pml1]; + + *pte = physaddr | (flags & 0x7); +} + +void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr) { + PgIndex pi = hal_vmm_pageindex(virtaddr); + + uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4); + uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3); + uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2); + uint64_t *pte = &pml1[pi.pml1]; + + *pte = physaddr & (~0x7); +} + +void hal_vmm_init(void) { + KERNEL_CR3 = hal_vmm_current_cr3(); +} diff --git a/kernel/hal/x86_64/vmm.h b/kernel/hal/x86_64/vmm.h new file mode 100644 index 0000000..7d60869 --- /dev/null +++ b/kernel/hal/x86_64/vmm.h @@ -0,0 +1,45 @@ +#ifndef HAL_VMM_H_ +#define HAL_VMM_H_ + +#include +#include +#include "compiler/attr.h" + +enum { + HAL_PG_PRESENT = 1<<0, + HAL_PG_RW = 1<<1, + HAL_PG_USER = 1<<2, +}; + +typedef struct { + uint64_t pml4; + uint64_t pml3; + uint64_t pml2; + uint64_t pml1; +} PACKED PgIndex; + +typedef struct { + bool present: 1; + bool rw: 1; + bool user: 1; + bool writethrough: 1; + bool cachedisabled: 1; + bool accessed: 1; + bool zero0: 1; + bool size: 1; + bool zero1: 1; + uint8_t avail: 3; + uint64_t addr: 52; +} PACKED Pte; + +typedef struct { + Pte ents[512]; +} PACKED PgTable; + +extern PgTable *KERNEL_CR3; + +void hal_vmm_init(void); +void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr); +void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags); + +#endif // HAL_VMM_H_ diff --git a/kernel/kmain.c b/kernel/kmain.c index 1f6620d..7d19279 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -4,8 +4,8 @@ #include "hal/hal.h" #include "bootinfo/bootinfo.h" #include "pmm/pmm.h" +#include "vmm/vmm.h" #include "term/term.h" -#include "paging/paging.h" #include "dlmalloc/malloc.h" #include "vfs/vfs.h" #include "baseimg/baseimg.h" @@ -60,16 +60,15 @@ void kmain(void) { log_bootinfo(); hal_init(); pmm_init(); - paging_init(); + vmm_init(); dlmalloc_check(); - hal_init_withmalloc(); - hal_intr_disable(); storedev_init(); baseimg_init(); vfs_init(); - hal_intr_enable(); + hal_init_withmalloc(); + /* hal_intr_enable(); */ /* kprintf(BANNER_TEXT "\n"); */ - hal_hang(); + for(;;); } diff --git a/kernel/kprintf.h b/kernel/kprintf.h index 002dd1b..551fa20 100644 --- a/kernel/kprintf.h +++ b/kernel/kprintf.h @@ -2,8 +2,21 @@ #define KPRINTF_H_ #include +#include "term/term.h" +#include "spinlock/spinlock.h" + +#define kprintf(fmt, ...) \ + do { \ + spinlock_acquire(&TERM.spinlock); \ + printf_(fmt, ##__VA_ARGS__); \ + spinlock_release(&TERM.spinlock); \ + } while(0) + +#define kprintf_unsafe(fmt, ...) \ + do { \ + printf_(fmt, ##__VA_ARGS__); \ + } while(0) -#define kprintf printf_ #define ksprintf sprintf_ #define kvsprintf vsprintf_ #define ksnprintf snprintf_ diff --git a/kernel/paging/paging.h b/kernel/paging/paging.h deleted file mode 100644 index ad05d65..0000000 --- a/kernel/paging/paging.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef PAGING_PAGING_H_ -#define PAGING_PAGING_H_ - -#include -#include - -void paging_init(void); -size_t paging_virt2phys(size_t virtaddr); - -#endif // PAGING_PAGING_H_ diff --git a/kernel/paging/x86_64/paging.c b/kernel/paging/x86_64/paging.c deleted file mode 100644 index ccbaf5a..0000000 --- a/kernel/paging/x86_64/paging.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include "paging/paging.h" -#include "hal/hal.h" -#include "bootinfo/bootinfo.h" -#include "util/util.h" -#include "kprintf.h" - -enum { - PF_PRESENT = 1<<0, - PF_READWRITE = 1<<1, - PF_USER = 1<<2, - PF_WRITETHROUGH = 1<<3, - PF_NOCACHE = 1<<4, - PF_ACCESS = 1<<5, - PF_DIRTY = 1<<6, - PF_PAGESIZE = 1<<7, - PF_ATTRTAB = 1<<7, - PF_GLOBAL = 1<<8, - PF_SHARED = 1<<9, - PF_CACHE_WC = PF_ATTRTAB | PF_WRITETHROUGH, -}; - -#define PGSHIFT_PML4E 39 -#define PGSHIFT_PDPTE 30 -#define PGSHIFT_PDE 21 -#define PGSHIFT_PTE 12 -#define PGMASK_ENTRY 0x1ff -#define PGMASK_OFFSET 0x3ff - -#define BITS_TO_VIRT_ADDR(pml4_index, pdpte_index, pd_index, pt_index) \ - (((uint64_t)pml4_index << PGSHIFT_PML4E) | \ - ((uint64_t)pdpte_index << PGSHIFT_PDPTE) | \ - ((uint64_t)pd_index << PGSHIFT_PDE) | ((uint64_t)pt_index << PGSHIFT_PTE)) - -// Workaround repeated characters -#define AMD64_MM_STRIPSX(a) ((uintptr_t)(a) & 0xFFFFFFFFFFFF) -#define AMD64_MM_ADDRSX(a) \ - (((uintptr_t)(a) & (1ULL << 47)) ? (0xFFFFFF0000000000 | ((uintptr_t)(a))) \ - : ((uintptr_t)(a))) - -// Virtual address' macros -#define PML4E(a) (((a) >> PGSHIFT_PML4E) & PGMASK_ENTRY) -#define PDPTE(a) (((a) >> PGSHIFT_PDPTE) & PGMASK_ENTRY) -#define PDE(a) (((a) >> PGSHIFT_PDE) & PGMASK_ENTRY) -#define PTE(a) (((a) >> PGSHIFT_PTE) & PGMASK_ENTRY) - -#define PTE_ADDR_MASK 0x000ffffffffff000 -#define PTE_GET_ADDR(VALUE) ((VALUE) & PTE_ADDR_MASK) -#define PTE_GET_FLAGS(VALUE) ((VALUE) & ~PTE_ADDR_MASK) - -#define PAGE_MASK(x) ((1 << (x)) - 1) - -#define USER_STACK_PAGES 2048 -#define PAGE_SIZE 0x1000 -#define PAGE_SIZE_LARGE 0x200000 -#define PAGE_SIZE_HUGE 0x40000000 - -#define P_PHYs_ADD(x) ((x) & ~0xfff) - -uint64_t *global_page_dir = NULL; - -void paging_init(void) { - uint64_t pdphys = 0; - asm volatile("movq %%cr3, %0" : "=r"(pdphys)); - if (!pdphys) { - ERR("paging", "could not get default page dir\n"); - hal_hang(); - } - - uint64_t pdvirt = pdphys + BOOT_INFO.hhdm_off; - global_page_dir = (uint64_t *)pdvirt; - - LOG("paging", "global_page_dir = %p\n", global_page_dir); -} - -size_t _paging_virt2phys(uint64_t *pgdir, size_t virtaddr) { - if (!pgdir) return 0; - - if (virtaddr >= BOOT_INFO.hhdm_off - && virtaddr <= (BOOT_INFO.hhdm_off + MAX(BOOT_INFO.memmap_total, UINT32_MAX))) { - return virtaddr - BOOT_INFO.hhdm_off; - } - - size_t virtaddr_init = virtaddr; - virtaddr &= ~0xfff; - - virtaddr = AMD64_MM_STRIPSX(virtaddr); - - uint32_t pml4idx = PML4E(virtaddr); - uint32_t pdpidx = PDPTE(virtaddr); - uint32_t pdidx = PDE(virtaddr); - uint32_t ptidx = PTE(virtaddr); - - if (!(pgdir[pml4idx] & PF_PRESENT)) { - return 0; - } - - size_t *pdp = (size_t *)(PTE_GET_ADDR(pgdir[pml4idx]) + BOOT_INFO.hhdm_off); - - if (!(pdp[pdpidx] & PF_PRESENT)) { - return 0; - } - - size_t *pd = (size_t *)(PTE_GET_ADDR(pdp[pdpidx]) + BOOT_INFO.hhdm_off); - - if (!(pd[pdidx] & PF_PRESENT)) { - return 0; - } - - size_t *pt = (size_t *)(PTE_GET_ADDR(pd[pdidx]) + BOOT_INFO.hhdm_off); - - if (pt[ptidx] & PF_PRESENT) { - return (size_t)(PTE_GET_ADDR(pt[ptidx]) + ((size_t)virtaddr_init & 0xfff)); - } - - return 0; -} - -size_t paging_virt2phys(size_t virtaddr) { - return _paging_virt2phys(global_page_dir, virtaddr); -} - diff --git a/kernel/pmm/pmm.c b/kernel/pmm/pmm.c index ef6a193..2e14710 100644 --- a/kernel/pmm/pmm.c +++ b/kernel/pmm/pmm.c @@ -6,6 +6,7 @@ #include "bootinfo/bootinfo.h" #include "spinlock/spinlock.h" #include "util/util.h" +#include "hal/hal.h" PhysMem PHYS_MEM; @@ -13,7 +14,6 @@ void pmm_init(void) { spinlock_init(&PHYS_MEM.spinlock); BitMap *bm = &PHYS_MEM.self; - bm->init = false; bm->nblocks = _DIV_ROUNDUP(BOOT_INFO.memmap_total, BITMAP_BLOCK_SIZE); bm->nbytes = _DIV_ROUNDUP(bm->nblocks, 8); @@ -48,7 +48,6 @@ void pmm_init(void) { bm->alloc_blocks = 0; LOG("pmm", "phys bitmap init 0x%lx, size = 0x%lx\n", physbegin, bm->nbytes); - bm->init = true; } void *pmm_alloc(size_t pages) { diff --git a/kernel/spinlock/spinlock.c b/kernel/spinlock/spinlock.c index fecc526..136ea9a 100644 --- a/kernel/spinlock/spinlock.c +++ b/kernel/spinlock/spinlock.c @@ -13,11 +13,12 @@ void spinlock_acquire(SpinLock *sl) { unlocked = false; SPINLOCK_HINT(); } - hal_intr_disable(); } void spinlock_release(SpinLock *sl) { - atomic_store(&sl->lock, false); - hal_intr_enable(); + bool locked = true; + if (atomic_compare_exchange_strong(&sl->lock, &locked, false)) { + atomic_store(&sl->lock, false); + } } diff --git a/kernel/spinlock/spinlock.h b/kernel/spinlock/spinlock.h index 9fc80c4..c31d748 100644 --- a/kernel/spinlock/spinlock.h +++ b/kernel/spinlock/spinlock.h @@ -3,9 +3,10 @@ #include #include -#include "hal/hal.h" -typedef struct { atomic_bool lock; } SpinLock; +typedef struct { + atomic_bool lock; +} SpinLock; // Spin more efficiently - cpu dependant #if defined(__x86_64__) diff --git a/kernel/std/include/stdatomic.h b/kernel/std/include/stdatomic.h index 32f21d3..2ee79a8 100644 --- a/kernel/std/include/stdatomic.h +++ b/kernel/std/include/stdatomic.h @@ -12,11 +12,14 @@ #define atomic_store_explicit __atomic_store_n #define atomic_store(p, v) atomic_store_explicit(p, v, memory_order_relaxed) -#define atomic_load(p, v) atomic_load_explicit(p, v, memory_order_relaxed) +#define atomic_load(p) atomic_load_explicit(p, memory_order_relaxed) #define atomic_compare_exchange_weak(p, old, new) \ __atomic_compare_exchange_n(p, old, new, true, memory_order_relaxed, memory_order_relaxed) +#define atomic_compare_exchange_strong(p, old, new) \ + __atomic_compare_exchange_n(p, old, new, false, memory_order_relaxed, memory_order_relaxed) + #define atomic_bool volatile bool #endif diff --git a/kernel/term/term.c b/kernel/term/term.c index 429134e..a118914 100644 --- a/kernel/term/term.c +++ b/kernel/term/term.c @@ -8,6 +8,7 @@ Term TERM; void term_init(void) { + spinlock_init(&TERM.spinlock); TERM.ftctx = flanterm_fb_init( NULL, NULL, BOOT_INFO.fb->address, @@ -30,13 +31,13 @@ void term_init(void) { ); } -void term_write(const char *s, size_t len) { +void term_write_unsafe(const char *s, size_t len) { flanterm_write(TERM.ftctx, s, len); } #if PUTCHAR_ == PUTCHAR_FB // For printf library void putchar_(char c) { - term_write(&c, 1); + term_write_unsafe(&c, 1); } #endif diff --git a/kernel/term/term.h b/kernel/term/term.h index 66c499f..d0367bf 100644 --- a/kernel/term/term.h +++ b/kernel/term/term.h @@ -7,10 +7,12 @@ typedef struct { struct flanterm_context *ftctx; + SpinLock spinlock; } Term; extern Term TERM; void term_init(void); +void term_write_unsafe(const char *s, size_t len); #endif // TERM_TERM_H_ diff --git a/kernel/util/util.h b/kernel/util/util.h index df1c43d..30c1044 100644 --- a/kernel/util/util.h +++ b/kernel/util/util.h @@ -35,6 +35,18 @@ } \ } while(0) +#define LL_FINDPROP(head, out, propname, propvalue) \ + do { \ + typeof((head)) __tmp = (head); \ + while (__tmp) { \ + if (__tmp->propname == (propvalue)) { \ + (out) = __tmp; \ + break; \ + } \ + __tmp = __tmp->next; \ + } \ + } while(0) + char *util_get_filename(char *path); #endif // UTIL_UTIL_H_ diff --git a/kernel/vfs/vfs.c b/kernel/vfs/vfs.c index f8b9d57..8c48489 100644 --- a/kernel/vfs/vfs.c +++ b/kernel/vfs/vfs.c @@ -190,7 +190,7 @@ void vfs_init(void) { tmpvars_init(); base_init(); - LOG("vfs", "init done\n"); + LOG("vfs", "init\n"); for (size_t i = 0; i < LEN(VFS_TABLE.mountpoints); i++) { if (!VFS_TABLE.mountpoints[i].taken) continue; diff --git a/kernel/vmm/vmm.c b/kernel/vmm/vmm.c index 9a79980..ba766d9 100644 --- a/kernel/vmm/vmm.c +++ b/kernel/vmm/vmm.c @@ -8,45 +8,30 @@ #include "util/util.h" #include "hal/hal.h" #include "pmm/pmm.h" -#include "paging/paging.h" - -#define POS_ENSURE 0x40000000 - -#define PAGE_SIZE 0x1000 VirtMem VIRT_MEM; +void vmm_map_kern_page(uint64_t virtaddr, uint64_t physaddr, uint32_t flags) { + #if defined(__x86_64__) + hal_vmm_map_page(KERNEL_CR3, virtaddr, physaddr, flags); + #else + # error "arch" + #endif +} + +void vmm_unmap_kern_page(uint64_t virtaddr, uint64_t physaddr) { + #if defined(__x86_64__) + hal_vmm_unmap_page(KERNEL_CR3, virtaddr, physaddr); + #else + # error "arch" + #endif +} + void vmm_init(void) { spinlock_init(&VIRT_MEM.spinlock); - BitMap *bm = &VIRT_MEM.self; - size_t targetpos = _DIV_ROUNDUP(BOOT_INFO.hhdm_off - BOOT_INFO.memmap_total - POS_ENSURE, PAGE_SIZE) * PAGE_SIZE; - bm->init = false; + hal_vmm_init(); - bm->mem_start = targetpos; - bm->nblocks = _DIV_ROUNDUP(BOOT_INFO.memmap_total, BITMAP_BLOCK_SIZE); - bm->nbytes = _DIV_ROUNDUP(bm->nblocks, 8); - - uint64_t pagesrequired = _DIV_ROUNDUP(bm->nbytes, BITMAP_BLOCK_SIZE); - bm->map = (uint8_t *)vmm_alloc(pagesrequired); - hal_memset(bm->map, 0, bm->nbytes); - - bm->init = true; -} - -void *vmm_alloc(size_t pages) { - size_t phys = (size_t)pmm_alloc(pages); - uint64_t out = phys + BOOT_INFO.hhdm_off; - return (void *)out; -} - - -void vmm_free(void *ptr, size_t pages) { - size_t phys = paging_virt2phys((size_t)ptr); - if (!phys) { - ERR("vmm", "could not find phys addr for %p\n", ptr); - hal_hang(); - } - pmm_free(phys, pages); + LOG("vmm", "init\n"); } diff --git a/kernel/vmm/vmm.h b/kernel/vmm/vmm.h index 5425224..b1a7de2 100644 --- a/kernel/vmm/vmm.h +++ b/kernel/vmm/vmm.h @@ -2,18 +2,17 @@ #define VMM_VMM_H_ #include -#include "bitmap/bitmap.h" #include "spinlock/spinlock.h" +#include "bootinfo/bootinfo.h" typedef struct { SpinLock spinlock; - BitMap self; } VirtMem; extern VirtMem VIRT_MEM; void vmm_init(void); -void *vmm_alloc(size_t pages); -void vmm_free(void *ptr, size_t pages); + +#define VIRT(X) ((void *)(BOOT_INFO.hhdm_off + (uint64_t)(X))) #endif // VMM_VMM_H_