diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-01-07 17:33:55 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-01-07 17:33:55 +0200 |
| commit | ebe6fe5d44d58fcb1b9d0ac52fa98a0a3ff309a7 (patch) | |
| tree | 1273c7815d6790e746f6e7ecfcd464e5cab39f2e | |
| parent | be78fcb0acc665d4db8edb9cda53f6863d27dd85 (diff) | |
| download | kmi-ebe6fe5d44d58fcb1b9d0ac52fa98a0a3ff309a7.tar.gz kmi-ebe6fe5d44d58fcb1b9d0ac52fa98a0a3ff309a7.zip | |
Steps towards better status/debugging control
| -rw-r--r-- | TODO.txt | 1 | ||||
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 7 | ||||
| -rw-r--r-- | arch/riscv64/kernel/vmem.c | 30 | ||||
| -rw-r--r-- | common/dmem.c | 14 | ||||
| -rw-r--r-- | common/elf.c | 4 | ||||
| -rw-r--r-- | common/mem_regions.c | 7 | ||||
| -rw-r--r-- | common/proc.c | 23 | ||||
| -rw-r--r-- | common/tcb.c | 5 | ||||
| -rw-r--r-- | common/vmem.c | 22 | ||||
| -rw-r--r-- | include/apos/dmem.h | 6 | ||||
| -rw-r--r-- | include/apos/mem.h | 1 | ||||
| -rw-r--r-- | include/apos/mem_regions.h | 9 | ||||
| -rw-r--r-- | include/apos/proc.h | 4 | ||||
| -rw-r--r-- | include/apos/tcb.h | 2 | ||||
| -rw-r--r-- | include/apos/types.h | 4 | ||||
| -rw-r--r-- | include/apos/vmem.h | 14 | ||||
| -rw-r--r-- | include/arch/vmem.h | 17 |
17 files changed, 100 insertions, 70 deletions
@@ -45,3 +45,4 @@ under a common process ID. + When mapping some other address space into your own, I could keep a maximum used address of the guest address space and only map so many pages, which could be better for cache locality. ++ Assert? Not sure how to handle a kernel panic at the moment, I guess just die? diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c index b696912..e2cbcea 100644 --- a/arch/riscv64/kernel/proc.c +++ b/arch/riscv64/kernel/proc.c @@ -2,14 +2,17 @@ #include <apos/elf.h> #include <csr.h> -void jump_to_userspace(struct tcb *t, int argc, char **argv) +stat_t jump_to_userspace(struct tcb *t, int argc, char **argv) { csr_write(CSR_SEPC, t->entry); __asm__ volatile ("mv sp, %0\n" : "=r" (t->proc_stack) :: "memory"); __asm__ volatile ("sret\n" ::: "memory"); + /* we should never reach this */ + return ERR_ADDR; } -void return_to_userspace(struct tcb *t) +stat_t return_to_userspace(struct tcb *t) { /* lol */ + return ERR_ADDR; } diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index 146f30f..adde661 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -4,6 +4,7 @@ #include <apos/mem.h> #include <apos/debug.h> #include <arch/cpu.h> +#include <pages.h> #include <csr.h> #define pte_ppn(pte) (((pm_t)(pte)) >> 10) @@ -41,21 +42,21 @@ static pm_t *__find_vmem(struct vm_branch *b, vm_t v, enum mm_order *o) return 0; } -int mod_vmem(struct vm_branch *branch, vm_t vaddr, pm_t paddr, uint8_t flags) +stat_t mod_vpage(struct vm_branch *branch, vm_t vaddr, pm_t paddr, vmflags_t flags) { pm_t *pte = __find_vmem(branch, vaddr, 0); if(pte){ *pte = to_pte((pm_t)__pa(paddr), flags); - return 0; + return OK; } - return -1; + return ERR_NF; } /* huh, should probably add status flags etc. to all my API functions. Damn, I'm * lazy. */ -int stat_vmem(struct vm_branch *branch, vm_t vaddr, pm_t *paddr, - enum mm_order *order, uint8_t *flags) +stat_t stat_vpage(struct vm_branch *branch, vm_t vaddr, pm_t *paddr, + enum mm_order *order, vmflags_t *flags) { pm_t *pte = __find_vmem(branch, vaddr, order); if(pte){ @@ -65,10 +66,10 @@ int stat_vmem(struct vm_branch *branch, vm_t vaddr, pm_t *paddr, if(flags) *flags = pte_flags(*pte); - return 0; + return OK; } - return -1; + return ERR_NF; } static struct vm_branch *__create_leaf() @@ -91,8 +92,8 @@ static void __destroy_branch(struct vm_branch *b) } } -void map_vmem(struct vm_branch *branch, - pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order order) +stat_t map_vpage(struct vm_branch *branch, + pm_t paddr, vm_t vaddr, vmflags_t flags, enum mm_order order) { enum mm_order top = __mm_max_order; while (top != order) { @@ -107,18 +108,23 @@ void map_vmem(struct vm_branch *branch, } size_t idx = vm_to_index(vaddr, top); - if (is_branch(branch->leaf[idx])) /* something has gone terribly wrong */ + if (is_branch(branch->leaf[idx])) /* something has gone terribly wrong? */ __destroy_branch(branch->leaf[idx]); branch->leaf[idx] = (struct vm_branch *)to_pte((pm_t)__pa(paddr), flags); + return OK; } -void unmap_vmem(struct vm_branch *branch, vm_t vaddr) +stat_t unmap_vpage(struct vm_branch *branch, vm_t vaddr) { pm_t *pte = __find_vmem(branch, vaddr, 0); - if(pte) + if(pte){ *pte = 0; + return OK; + } + + return ERR_NF; } void flush_tlb() diff --git a/common/dmem.c b/common/dmem.c index 0cc96e1..1c49a83 100644 --- a/common/dmem.c +++ b/common/dmem.c @@ -26,27 +26,27 @@ stat_t init_devmem(pm_t ram_base, pm_t ram_top) return OK; } -stat_t dev_alloc_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, uint8_t flags, enum mm_order order) +stat_t dev_alloc_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order) { - map_vmem(b, *offset, vaddr, flags, order); + map_vpage(b, *offset, vaddr, flags, order); *offset += __o_size(order); return 0; } -stat_t dev_free_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, uint8_t flags, enum mm_order order) +stat_t dev_free_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order) { UNUSED(offset); UNUSED(flags); pm_t paddr = 0; enum mm_order v_order = 0; - stat_vmem(b, vaddr, &paddr, &v_order, 0); + stat_vpage(b, vaddr, &paddr, &v_order, 0); if(order != v_order) return -1; - unmap_vmem(b, vaddr); + unmap_vpage(b, vaddr); return 0; } -vm_t alloc_devmem(struct tcb *t, pm_t dev_start, size_t bytes, uint8_t flags) +vm_t alloc_devmem(struct tcb *t, pm_t dev_start, size_t bytes, vmflags_t flags) { vm_t region = 0; if(dev_start < __pre_top) @@ -64,7 +64,7 @@ vm_t alloc_devmem(struct tcb *t, pm_t dev_start, size_t bytes, uint8_t flags) stat_t free_devmem(struct tcb *t, vm_t dev_start) { pm_t dev_paddr = 0; - stat_vmem(t->b_r, dev_start, &dev_paddr, 0, 0); + stat_vpage(t->b_r, dev_start, &dev_paddr, 0, 0); if(dev_paddr >= __pre_top && dev_paddr <= __post_base) return ERR_ADDR; diff --git a/common/elf.c b/common/elf.c index 4378d52..6b7b6dd 100644 --- a/common/elf.c +++ b/common/elf.c @@ -54,8 +54,8 @@ static void __map_exec(struct tcb *t, vm_t bin, uint8_t ei_c, vm_t phstart, size * function? * pm_t paddr = 0; - stat_vmem(t->b_r, va, &paddr, 0, 0); - mod_vmem(t->b_r, va, paddr, uvflags); + stat_vpage(t->b_r, va, &paddr, 0, 0); + mod_vpage(t->b_r, va, paddr, uvflags); */ } } diff --git a/common/mem_regions.c b/common/mem_regions.c index ebcff50..c7abb19 100644 --- a/common/mem_regions.c +++ b/common/mem_regions.c @@ -420,9 +420,8 @@ size_t uvmem_size() * NOTE: not actually optimal, this doesn't bother to go through possible * permutations etc. which would be slow and I don't want to implement it. */ -vm_t map_fill_region(struct vm_branch *b, - stat_t (*vmem_handler)(struct vm_branch *, pm_t *, vm_t, uint8_t, enum mm_order), - pm_t offset, vm_t start, size_t bytes, uint8_t flags) +vm_t map_fill_region(struct vm_branch *b, mem_region_callback_t *mem_handler, + pm_t offset, vm_t start, size_t bytes, vmflags_t flags) { pm_t runner = __page(start); size_t pages = __pages(bytes); @@ -442,7 +441,7 @@ vm_t map_fill_region(struct vm_branch *b, continue; while(pages >= o_pages){ - int res = vmem_handler(b, &offset, __addr(runner), flags, top); + stat_t res = mem_handler(b, &offset, __addr(runner), flags, top); if(res > 0) break; diff --git a/common/proc.c b/common/proc.c index c272727..13d3750 100644 --- a/common/proc.c +++ b/common/proc.c @@ -1,8 +1,8 @@ -#include <apos/conf.h> #include <apos/elf.h> +#include <apos/proc.h> +#include <apos/conf.h> #include <apos/string.h> #include <apos/initrd.h> -#include <apos/proc.h> #include <arch/arch.h> /* TODO: add error checking */ @@ -10,11 +10,11 @@ static vm_t setup_call_stack(struct tcb *t, size_t bytes) { pm_t offset = 0; size_t pages = __pages(bytes); - uint8_t flags = VM_V | VM_R | VM_W | VM_U; + vmflags_t flags = VM_V | VM_R | VM_W | VM_U; for(size_t i = 1; i <= pages; ++i) { offset = alloc_page(BASE_PAGE, offset); - map_vmem(t->b_r, offset, PROC_STACK_TOP - BASE_PAGE_SIZE * i, flags, BASE_PAGE); + map_vpage(t->b_r, offset, PROC_STACK_TOP - BASE_PAGE_SIZE * i, flags, BASE_PAGE); } return PROC_STACK_TOP - BASE_PAGE_SIZE * pages; @@ -25,9 +25,13 @@ static vm_t setup_proc_stack(struct tcb *t, size_t bytes) return alloc_uvmem(t, bytes, VM_V | VM_R | VM_W | VM_U); } -void init_proc(void *fdt, struct vm_branch *b) +stat_t init_proc(void *fdt, struct vm_branch *b) { + /* todo: cleanup or something */ struct tcb *t = (struct tcb *)alloc_page(BASE_PAGE, 0); + if(!t) + return ERR_OOMEM; + memset(t, 0, sizeof(struct tcb)); t->b_r = b; t->pid = 0; @@ -39,13 +43,20 @@ void init_proc(void *fdt, struct vm_branch *b) /* the binary gets to choose first what memory regions it requires */ t->entry = load_elf(t, get_init_base(fdt)); + if(!t->entry) + return ERR_ADDR; t->proc_stack = setup_proc_stack(t, __proc_stack_size); + if(!t->proc_stack) + return ERR_ADDR; + t->call_stack = setup_call_stack(t, __call_stack_size); + if(!t->call_stack) + return ERR_ADDR; flush_tlb(); /* TODO: move fdt into process space */ - jump_to_userspace(t, 1, 0); + return jump_to_userspace(t, 1, 0); } diff --git a/common/tcb.c b/common/tcb.c index 7f3cf81..8fea188 100644 --- a/common/tcb.c +++ b/common/tcb.c @@ -9,11 +9,11 @@ static struct tcb *__tcb_cache[MAX_CPUS] = {0}; #define tcb_container(x) \ container_of(x, struct tcb, sp_n) -void threads_insert(struct tcb *t) +stat_t threads_insert(struct tcb *t) { if(!sp_root(t_root)){ sp_root(t_root) = &t->sp_n; - return; + return OK; } struct sp_node *n = sp_root(t_root), *p = NULL; @@ -35,6 +35,7 @@ void threads_insert(struct tcb *t) } sp_insert(&sp_root(t_root), p, &t->sp_n, d); + return OK; } struct tcb *threads_find(id_t tid) diff --git a/common/vmem.c b/common/vmem.c index bd0cc29..33c5dd3 100644 --- a/common/vmem.c +++ b/common/vmem.c @@ -1,19 +1,19 @@ #include <apos/mem_regions.h> #include <apos/vmem.h> - +#include <arch/vmem.h> stat_t init_uvmem(struct tcb *t, vm_t base, vm_t top) { return sp_mem_init(&t->sp_r, base, top); } -vm_t alloc_uvmem(struct tcb *t, size_t size, uint8_t flags) +vm_t alloc_uvmem(struct tcb *t, size_t size, vmflags_t flags) { vm_t v = alloc_region(&t->sp_r, size, &size); return map_allocd_region(t->b_r, v, size, flags); } -vm_t alloc_fixed_uvmem(struct tcb *t, vm_t start, size_t size, uint8_t flags) +vm_t alloc_fixed_uvmem(struct tcb *t, vm_t start, size_t size, vmflags_t flags) { vm_t v = alloc_fixed_region(&t->sp_r, start, size, &size); return map_allocd_region(t->b_r, v, size, flags); @@ -32,27 +32,27 @@ stat_t free_uvmem(struct tcb *t, vm_t va) return 0; } -stat_t alloc_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, uint8_t flags, enum mm_order order) +stat_t alloc_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order) { *offset = alloc_page(order, *offset); if(!*offset) - return 1; /* try again */ + return MEM_REGION_TRY_AGAIN; /* try again */ - map_vmem(b, *offset, vaddr, flags, order); - return 0; + map_vpage(b, *offset, vaddr, flags, order); + return OK; } -stat_t free_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, uint8_t flags, enum mm_order order) +stat_t free_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order) { UNUSED(flags); UNUSED(offset); pm_t paddr = 0; enum mm_order v_order = 0; - stat_vmem(b, vaddr, &paddr, &v_order, 0); + stat_vpage(b, vaddr, &paddr, &v_order, 0); if(order != v_order) - return -1; + return MEM_REGION_TRY_AGAIN; - unmap_vmem(b, vaddr); + unmap_vpage(b, vaddr); free_page(order, paddr); return 0; } diff --git a/include/apos/dmem.h b/include/apos/dmem.h index 936a902..811f56d 100644 --- a/include/apos/dmem.h +++ b/include/apos/dmem.h @@ -10,10 +10,10 @@ extern pm_t __post_base; extern pm_t __post_top; stat_t init_devmem(pm_t ram_base, pm_t ram_top); -vm_t alloc_devmem(struct tcb *t, pm_t dev_start, size_t bytes, uint8_t flags); +vm_t alloc_devmem(struct tcb *t, pm_t dev_start, size_t bytes, vmflags_t flags); stat_t free_devmem(struct tcb *t, vm_t dev_start); -stat_t dev_free_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, uint8_t flags, enum mm_order t); -stat_t dev_alloc_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, uint8_t flags, enum mm_order t); +stat_t dev_free_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order t); +stat_t dev_alloc_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order t); #endif /* APOS_DEV_H */ diff --git a/include/apos/mem.h b/include/apos/mem.h index 01edcf6..61528df 100644 --- a/include/apos/mem.h +++ b/include/apos/mem.h @@ -3,7 +3,6 @@ #include <apos/utils.h> #include <apos/types.h> -#include <pages.h> #define MM_OINFO_WIDTH (sizeof(mm_info_t) * 8) diff --git a/include/apos/mem_regions.h b/include/apos/mem_regions.h index eb81e63..35428e1 100644 --- a/include/apos/mem_regions.h +++ b/include/apos/mem_regions.h @@ -1,8 +1,10 @@ #ifndef APOS_MEM_REGIONS_H #define APOS_MEM_REGIONS_H +#include <apos/mem.h> #include <apos/types.h> #include <apos/sp_tree.h> +#include <arch/vmem.h> #define mem_container(ptr)\ container_of(ptr, struct sp_mem, sp_n) @@ -33,4 +35,11 @@ struct sp_mem *sp_used_find(struct sp_reg_root *r, vm_t start); struct sp_mem *sp_find_used_closest(struct sp_reg_root *r, vm_t start); struct sp_mem *sp_find_free(struct sp_reg_root *r, size_t size, size_t *align); +#define MEM_REGION_TRY_AGAIN 1 +typedef stat_t mem_region_callback_t(struct vm_branch *b, + pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order); + +vm_t map_fill_region(struct vm_branch *b, mem_region_callback_t *mem_handler, + pm_t offset, vm_t start, size_t bytes, vmflags_t flags); + #endif /* APOS_MEM_REGIONS_H */ diff --git a/include/apos/proc.h b/include/apos/proc.h index f835394..e1ea7b6 100644 --- a/include/apos/proc.h +++ b/include/apos/proc.h @@ -4,7 +4,7 @@ #include <apos/tcb.h> #include <apos/vmem.h> -void jump_to_userspace(struct tcb *t, int argc, char **argv); -void init_proc(void *fdt, struct vm_branch *b); +stat_t jump_to_userspace(struct tcb *t, int argc, char **argv); +stat_t init_proc(void *fdt, struct vm_branch *b); #endif /* APOS_PROC_H */ diff --git a/include/apos/tcb.h b/include/apos/tcb.h index 4872bd0..bd66aff 100644 --- a/include/apos/tcb.h +++ b/include/apos/tcb.h @@ -22,7 +22,7 @@ struct tcb { struct vm_branch *b_r; }; -void threads_insert(struct tcb *t); +stat_t threads_insert(struct tcb *t); struct tcb *cur_tcb(); struct tcb *get_tcb(id_t tid); diff --git a/include/apos/types.h b/include/apos/types.h index 7d690de..2d9bef1 100644 --- a/include/apos/types.h +++ b/include/apos/types.h @@ -178,12 +178,14 @@ typedef intmax_t ssize_t; /* some common types used throughout the kernel */ typedef int_fast8_t stat_t; typedef uint_fast32_t id_t; -typedef uint_fast8_t mflags_t; +typedef uint_fast8_t vmflags_t; /* error types (should this go somewhere else? */ /* negative error codes are reserved for general usage, positive error codes are * allowed to be function-specific. */ enum { + ERR_EXT = -5, /* already exists */ + ERR_OOMEM = -4, /* out of memory */ ERR_ADDR = -3, /* illegal address */ ERR_ALIGN = -2, /* wrong alignment */ ERR_NF = -1, /* not found */ diff --git a/include/apos/vmem.h b/include/apos/vmem.h index bd6b89e..083df87 100644 --- a/include/apos/vmem.h +++ b/include/apos/vmem.h @@ -2,22 +2,18 @@ #define APOS_VMEM_H #include <apos/tcb.h> +#include <apos/mem.h> #include <apos/pmem.h> #include <apos/sp_tree.h> -#include <arch/vmem.h> -vm_t alloc_uvmem(struct tcb *r, size_t size, uint8_t flags); -vm_t alloc_fixed_uvmem(struct tcb *r, vm_t start, size_t size, uint8_t flags); +vm_t alloc_uvmem(struct tcb *r, size_t size, vmflags_t flags); +vm_t alloc_fixed_uvmem(struct tcb *r, vm_t start, size_t size, vmflags_t flags); stat_t free_uvmem(struct tcb *r, vm_t a); stat_t init_uvmem(struct tcb *r, vm_t base, vm_t top); -vm_t map_fill_region(struct vm_branch *b, - int (*vmem_handler)(struct vm_branch *, pm_t *, vm_t, uint8_t, enum mm_order), - pm_t offset, vm_t start, size_t bytes, uint8_t flags); - -stat_t alloc_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, uint8_t flags, enum mm_order order); -stat_t free_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, uint8_t flags, enum mm_order order); +stat_t alloc_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order); +stat_t free_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order); #define map_allocd_region(b, start, bytes, flags)\ map_fill_region(b, &alloc_uvmem_wrapper, 0, start, bytes, flags) diff --git a/include/arch/vmem.h b/include/arch/vmem.h index 8aec154..17fa13d 100644 --- a/include/arch/vmem.h +++ b/include/arch/vmem.h @@ -3,20 +3,23 @@ #include <vmem.h> -void map_vmem(struct vm_branch *branch, - pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order order); +stat_t map_vpage(struct vm_branch *branch, + pm_t paddr, vm_t vaddr, vmflags_t flags, enum mm_order order); -void unmap_vmem(struct vm_branch *branch, vm_t vaddr); +stat_t unmap_vpage(struct vm_branch *branch, vm_t vaddr); -int mod_vmem(struct vm_branch *branch, vm_t vaddr, pm_t paddr, uint8_t flags); -int stat_vmem(struct vm_branch *branch, vm_t vaddr, pm_t *paddr, - enum mm_order *order, uint8_t *flags); +stat_t mod_vpage(struct vm_branch *branch, vm_t vaddr, pm_t paddr, vmflags_t flags); +stat_t stat_vpage(struct vm_branch *branch, vm_t vaddr, pm_t *paddr, + enum mm_order *order, vmflags_t *flags); void flush_tlb(); void flush_tlb_all(); void populate_root_branch(struct vm_branch *b); -int setup_kernel_io(struct vm_branch *b, vm_t paddr); struct vm_branch *init_vmem(void *fdt); +#ifdef DEBUG +stat_t setup_kernel_io(struct vm_branch *b, vm_t paddr); +#endif + #endif /* APOS_ARCH_PAGES_H */ |
