aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/riscv/kernel/main.c6
-rw-r--r--common/vmem.c45
-rw-r--r--include/apos/tcb.h1
-rw-r--r--include/apos/vmem.h11
4 files changed, 29 insertions, 34 deletions
diff --git a/arch/riscv/kernel/main.c b/arch/riscv/kernel/main.c
index 794b71b..914dcba 100644
--- a/arch/riscv/kernel/main.c
+++ b/arch/riscv/kernel/main.c
@@ -251,12 +251,14 @@ static void init_proc(void *fdt, struct vm_branch_t *b)
sp_mem_init(&t->sp_r, SZ_4K, SZ_256G);
/* binary itself */
- size_t sz = align_up(get_init_size(fdt), BASE_PAGE_SIZE);
+ size_t sz = get_init_size(fdt);
+ /* these need to be fixed and actually map the addresses that the ELF
+ * binary wants, instead of willy nilly */
t->bin = alloc_uvmem(t, sz, VM_V | VM_X | VM_R | VM_W | VM_U);
/* stack */
t->stack = alloc_uvmem(t, SZ_2M, VM_V | VM_R | VM_W | VM_U);
- /* if it needs heap, it'll ask for it */
+ /* should probably wrap this in like tlb_flush_all() or something */
__asm__ ("sfence.vma" : : : "memory");
move_init(fdt, (void *)t->bin);
diff --git a/common/vmem.c b/common/vmem.c
index 6d2b7dc..c6a4706 100644
--- a/common/vmem.c
+++ b/common/vmem.c
@@ -103,6 +103,9 @@ static struct sp_mem *sp_used_insert_region(struct sp_reg_root *r, struct sp_mem
int sp_mem_init(struct sp_reg_root *r, vm_t start, size_t arena_size)
{
+ /* convert bytes to pages */
+ start = __page(start);
+ arena_size = __page(arena_size);
struct sp_mem *m = get_mem_node();
m->start = start;
m->end = start + arena_size;
@@ -162,12 +165,12 @@ static struct sp_mem *sp_mem_create_region(vm_t start, vm_t end,
return m;
}
-static struct sp_mem *sp_free_find_first(struct sp_reg_root *r, size_t size, size_t alignment)
+static struct sp_mem *sp_free_find_first(struct sp_reg_root *r, size_t size)
{
struct sp_node *n = sp_root(r->free_regions);
while(n){
struct sp_mem *t = mem_container(n);
- size_t nsize = t->end - align_up(t->start, alignment);
+ size_t nsize = t->end - t->start;
if(size <= nsize)
return t;
@@ -182,34 +185,23 @@ static struct sp_mem *sp_free_find_first(struct sp_reg_root *r, size_t size, siz
* just ignore them for now. Note that alloc_region should only be used when
* mmap is called with MAP_ANON, all other situations should be handled in some
* fs server */
-vm_t alloc_region(struct sp_reg_root *r, size_t size, size_t alignment)
+vm_t alloc_region(struct sp_reg_root *r,
+ size_t size, size_t *actual_size)
{
- struct sp_mem *m = sp_free_find_first(r, size, alignment);
+ *actual_size = align_up(size, BASE_PAGE_SIZE);
+ size_t pages = __page(*actual_size);
+ struct sp_mem *m = sp_free_find_first(r, pages);
if(!m)
return 0;
sp_remove(&sp_root(r->free_regions), &m->sp_n);
- vm_t aligned_start = align_up(m->start, alignment);
-
- vm_t pre_start = m->start;
- vm_t pre_end = aligned_start;
-
- vm_t start = pre_end;
- vm_t end = aligned_start + size;
+ vm_t start = m->start;
+ vm_t end = m->start + pages;
vm_t post_start = end;
vm_t post_end = m->end;
- if(pre_start != pre_end){
- struct sp_mem *n = sp_mem_create_region(pre_start, pre_end, m->prev, m);
- m->prev = n;
- if(n->prev)
- n->prev->next = n;
-
- sp_free_insert_region(r, n);
- }
-
if(post_start != post_end){
struct sp_mem *n = sp_mem_create_region(post_start, post_end, m, m->next);
m->next = n;
@@ -223,7 +215,7 @@ vm_t alloc_region(struct sp_reg_root *r, size_t size, size_t alignment)
m->start = start;
mark_region_used(m->flags);
sp_used_insert_region(r, m);
- return start;
+ return __addr(start);
}
static void __sp_try_coalesce_prev(struct sp_reg_root *r, struct sp_mem *m)
@@ -280,7 +272,11 @@ static void sp_mem_try_coalesce(struct sp_reg_root *r, struct sp_mem *m)
void free_region(struct sp_reg_root *r, vm_t start)
{
- struct sp_mem *m = sp_used_find(r, start);
+ /* addr not aligned to page boundary, corrupted or incorrect pointer */
+ if(start != __addr(__page(start)))
+ return;
+
+ struct sp_mem *m = sp_used_find(r, __page(start));
if(!m)
return;
@@ -315,9 +311,8 @@ vm_t map_fill_region(struct vm_branch_t *b, vm_t start, size_t bytes, uint8_t fl
vm_t alloc_uvmem(struct tcb *t, size_t s, uint8_t flags)
{
- size_t sa = align_up(s, BASE_PAGE_SIZE);
- vm_t v = alloc_region(&t->sp_r, sa, 0);
- return map_fill_region(t->b_r, v, sa, flags);
+ vm_t v = alloc_region(&t->sp_r, s, &s);
+ return map_fill_region(t->b_r, v, s, flags);
}
void free_uvmem(struct tcb *t, vm_t a)
diff --git a/include/apos/tcb.h b/include/apos/tcb.h
index 9cef386..f987b43 100644
--- a/include/apos/tcb.h
+++ b/include/apos/tcb.h
@@ -23,6 +23,7 @@ struct tcb {
id_t tid;
vm_t stack;
+ vm_t heap;
vm_t bin;
struct vm_branch_t *b_r;
diff --git a/include/apos/vmem.h b/include/apos/vmem.h
index 2f6b10c..6918ba4 100644
--- a/include/apos/vmem.h
+++ b/include/apos/vmem.h
@@ -28,15 +28,12 @@ struct sp_mem {
#define __va(x) (((char *)(x)) + VM_DMAP - RAM_BASE)
#define __pa(x) (((char *)(x)) + RAM_BASE - VM_DMAP)
+#define __page(x) ((x) / BASE_PAGE_SIZE)
+#define __addr(x) ((x) * BASE_PAGE_SIZE)
/* general overview of the different functions:
- * (un)map_vmem: map one known page of physical memory to one known page of
- * virtual memory
- *
- * (un)map_vregion: map known physical region to unknown virtual region within
- * start and end
- *
- * (un)map_vsize: map unknown physical region to unknown virtual region
+ * internally they all work with pages, but they are called and return usable
+ * addresses, though within page bounds of course.
*/
/* defined by arch */