Rework x86_64 paging and vmm
This commit is contained in:
@ -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) \
|
||||
|
6
kernel/atomic.h
Normal file
6
kernel/atomic.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef ATOMIC_H_
|
||||
#define ATOMIC_H_
|
||||
|
||||
#define ATOMIC(X) _Atomic(X)
|
||||
|
||||
#endif // ATOMIC_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
|
||||
|
@ -3,5 +3,6 @@
|
||||
|
||||
#define PACKED __attribute__((packed))
|
||||
#define ALIGNED(x) __attribute__((aligned((x))))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
|
||||
#endif // COMPILER_ATTR_H_
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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_
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#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);
|
||||
}
|
||||
|
@ -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_
|
||||
|
@ -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
|
||||
|
9
kernel/hal/x86_64/paging.S
Normal file
9
kernel/hal/x86_64/paging.S
Normal file
@ -0,0 +1,9 @@
|
||||
.global hal_loadpd
|
||||
hal_loadpd:
|
||||
mov %rdi, %cr3
|
||||
retq
|
||||
|
||||
.global hal_invalpg
|
||||
hal_invalpg:
|
||||
invlpg (%rdi)
|
||||
retq
|
65
kernel/hal/x86_64/vmm.c
Normal file
65
kernel/hal/x86_64/vmm.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#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();
|
||||
}
|
45
kernel/hal/x86_64/vmm.h
Normal file
45
kernel/hal/x86_64/vmm.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef HAL_VMM_H_
|
||||
#define HAL_VMM_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#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_
|
@ -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(;;);
|
||||
}
|
||||
|
@ -2,8 +2,21 @@
|
||||
#define KPRINTF_H_
|
||||
|
||||
#include <printf/printf.h>
|
||||
#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_
|
||||
|
@ -1,10 +0,0 @@
|
||||
#ifndef PAGING_PAGING_H_
|
||||
#define PAGING_PAGING_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void paging_init(void);
|
||||
size_t paging_virt2phys(size_t virtaddr);
|
||||
|
||||
#endif // PAGING_PAGING_H_
|
@ -1,124 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,10 @@
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
#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__)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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_
|
||||
|
@ -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_
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -2,18 +2,17 @@
|
||||
#define VMM_VMM_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#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_
|
||||
|
Reference in New Issue
Block a user