aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-01-07 17:33:55 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2022-01-07 17:33:55 +0200
commitebe6fe5d44d58fcb1b9d0ac52fa98a0a3ff309a7 (patch)
tree1273c7815d6790e746f6e7ecfcd464e5cab39f2e
parentbe78fcb0acc665d4db8edb9cda53f6863d27dd85 (diff)
downloadkmi-ebe6fe5d44d58fcb1b9d0ac52fa98a0a3ff309a7.tar.gz
kmi-ebe6fe5d44d58fcb1b9d0ac52fa98a0a3ff309a7.zip
Steps towards better status/debugging control
-rw-r--r--TODO.txt1
-rw-r--r--arch/riscv64/kernel/proc.c7
-rw-r--r--arch/riscv64/kernel/vmem.c30
-rw-r--r--common/dmem.c14
-rw-r--r--common/elf.c4
-rw-r--r--common/mem_regions.c7
-rw-r--r--common/proc.c23
-rw-r--r--common/tcb.c5
-rw-r--r--common/vmem.c22
-rw-r--r--include/apos/dmem.h6
-rw-r--r--include/apos/mem.h1
-rw-r--r--include/apos/mem_regions.h9
-rw-r--r--include/apos/proc.h4
-rw-r--r--include/apos/tcb.h2
-rw-r--r--include/apos/types.h4
-rw-r--r--include/apos/vmem.h14
-rw-r--r--include/arch/vmem.h17
17 files changed, 100 insertions, 70 deletions
diff --git a/TODO.txt b/TODO.txt
index aee7b66..25e90d8 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -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 */