From 4f4d9fdc89c27aa3346467a24b621954f4564d3b Mon Sep 17 00:00:00 2001 From: Kimplul Date: Wed, 29 Dec 2021 23:23:36 +0200 Subject: Refactoring + Mainly just moving stuff out or arch/riscv/ that should be handled in common/ + Prepared separate process stack/call stack for server callbacks, rest to be implemeted soon ish --- arch/riscv/conf/init-link.S | 4 +- arch/riscv/config.h | 23 +++- arch/riscv/include/vmem.h | 6 +- arch/riscv/init/init.c | 33 +++-- arch/riscv/init/start.S | 5 + arch/riscv/kernel/irq.c | 6 +- arch/riscv/kernel/main.c | 295 +------------------------------------------- arch/riscv/kernel/pmem.c | 15 +++ arch/riscv/kernel/proc.c | 4 +- arch/riscv/kernel/vmem.c | 92 ++++++++++---- arch/riscv/source.mk | 2 +- common/debug.c | 16 +-- common/elf.c | 6 +- common/fdt.c | 8 +- common/initrd.c | 4 +- common/main.c | 52 ++++++++ common/mem.c | 22 ---- common/pmem.c | 179 +++++++++++++++++---------- common/proc.c | 42 ++++++- common/tcb.c | 5 + common/uapi/conf.c | 4 + common/vmem.c | 7 +- include/apos/arch.h | 6 + include/apos/conf.h | 9 ++ include/apos/debug.h | 14 ++- include/apos/elf.h | 2 +- include/apos/irq.h | 2 + include/apos/mem.h | 2 +- include/apos/pmem.h | 15 ++- include/apos/proc.h | 4 +- include/apos/tcb.h | 2 +- include/apos/vmem.h | 23 ++-- include/libfdt.h | 7 +- 33 files changed, 445 insertions(+), 471 deletions(-) create mode 100644 arch/riscv/init/start.S create mode 100644 arch/riscv/kernel/pmem.c create mode 100644 common/main.c create mode 100644 include/apos/arch.h create mode 100644 include/apos/conf.h diff --git a/arch/riscv/conf/init-link.S b/arch/riscv/conf/init-link.S index 53d24ab..ce53e5e 100644 --- a/arch/riscv/conf/init-link.S +++ b/arch/riscv/conf/init-link.S @@ -1,8 +1,8 @@ OUTPUT_ARCH(riscv) -ENTRY(init) +ENTRY(_start) SECTIONS { - . = ABSOLUTE(PM_KERN); + . = ABSOLUTE(PM_KERN_BASE); __init_start = .; /* objcopy only copies these three sections (as far as I'm aware) into the diff --git a/arch/riscv/config.h b/arch/riscv/config.h index fa6785e..0ef22fa 100644 --- a/arch/riscv/config.h +++ b/arch/riscv/config.h @@ -3,15 +3,32 @@ /* --- START ARCH USER CONFIG VALUES --- */ /* physical address to which the kernel will be loaded */ #define RAM_BASE 0x80000000 -#define PM_KERN (RAM_BASE + SZ_512K) +#define PM_KERN_BASE (RAM_BASE + SZ_512K) +#define PM_KERN_SIZE (SZ_256K) +#define PM_KERN_TOP (PM_KERN_BASE + PM_KERN_SIZE) /* --- END ARCH USER CONFIG VALUES --- */ /* don't touch >:( */ -#define PM_STACK_BASE (PM_KERN) -#define PM_STACK_TOP (RAM_BASE + SZ_1M) +#define PM_STACK_BASE (PM_KERN_BASE + SZ_256K) +#define PM_STACK_SIZE (SZ_256K) +#define PM_STACK_TOP (PM_STACK_BASE + PM_STACK_SIZE) + #define VM_DMAP (0xffffffc000000000) /* testing for now */ #define VM_KERN (VM_DMAP + SZ_256K) #define TMP_PTE (-SZ_2G) #define ROOT_PTE (0) #define ROOT_REGION (SZ_4K) + +#define IO_PAGE 511 +#define KSTART_PAGE 256 +#define CSTACK_PAGE 255 + +/* assume Sv39, probably wouldn't be too difficult to use runtime parameters + * instead. First 4K is reserved for NULL, but I suppose it could be mapped + * later if *absolutely* necessary. */ +#define UVMEM_START (SZ_4K) +#define UVMEM_END (SZ_256G - SZ_1G) + +#define PROC_STACK_TOP (SZ_256G) +#define PROC_STACK_BASE (SZ_256G - SZ_1G) diff --git a/arch/riscv/include/vmem.h b/arch/riscv/include/vmem.h index d17aaf1..228b24b 100644 --- a/arch/riscv/include/vmem.h +++ b/arch/riscv/include/vmem.h @@ -13,15 +13,15 @@ #define VM_A (1 << 6) #define VM_D (1 << 7) -enum mm_mode_t { +enum mm_mode { Sv48, Sv39, Sv32, }; typedef size_t vm_t; -struct __packed vm_branch_t { - struct vm_branch_t *leaf[512]; +struct __packed vm_branch { + struct vm_branch *leaf[512]; }; #endif /* APOS_RISCV_VMAP_H */ diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c index dc9d7e9..23dcadd 100644 --- a/arch/riscv/init/init.c +++ b/arch/riscv/init/init.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -14,29 +15,24 @@ struct init_vmem *root_branch; #define to_pte(a, f) (((a) >> 12) << 10 | (f)) /* assume Sv39 for now */ -void init_vmem() +void init_bootmem() { size_t flags = VM_V | VM_X | VM_R | VM_W; extern char *__init_start; root_branch = (struct init_vmem *)align_down((size_t)&__init_start - SZ_4K, SZ_4K); - for(size_t i = 0; i < 512; ++i) - root_branch->leaf[i] = 0; /* direct mapping (temp) */ - for(size_t i = 0; i < 256; ++i) + for(size_t i = 0; i < CSTACK_PAGE; ++i) root_branch->leaf[i] = (int*)to_pte(SZ_1G * i, flags); /* kernel (also sort of direct mapping) */ - /* FIXME set up actually correct addressing retard */ flags |= VM_G; - for(size_t i = 256; i < 511; ++i) + for(size_t i = KSTART_PAGE; i < IO_PAGE; ++i) root_branch->leaf[i] = (int *)to_pte(RAM_BASE + SZ_1G * (i - 256), flags); - /* kernel IO, map to 0 for now, should be made more robust in the future */ - /* same goes for the equivalent piece of code over in kernel/main.c, - * which btw should really get refactored, it's a mess */ - root_branch->leaf[511] = (int *)to_pte(0, flags); + /* kernel IO, map to 0 for now, will be updated in the future */ + root_branch->leaf[IO_PAGE] = (int *)to_pte(0, flags); csr_write(CSR_SATP, SATP_MODE_Sv39 | ((size_t)root_branch >> 12)); } @@ -53,11 +49,22 @@ void move_kernel() dst[i] = src[i]; } -void __init init(void *fdt) +#define __va_reg(reg)\ +{\ + vm_t reg = 0;\ + __asm__("mv %0, " QUOTE(reg) : "=r" (reg) :: );\ + reg = (vm_t)__va(reg);\ + __asm__("mv " QUOTE(reg) ", %0" :: "rK" (reg) : );\ +} + +void init(void *fdt) { extern char *__init_end; void (*kernel_main)(void *fdt) = (void (*)(void *))(VM_KERN); - init_vmem(); + init_bootmem(); move_kernel(); - kernel_main(fdt); + __va_reg(sp); + __va_reg(fp); + __va_reg(gp); + kernel_main(__va(fdt)); } diff --git a/arch/riscv/init/start.S b/arch/riscv/init/start.S new file mode 100644 index 0000000..f9bfb92 --- /dev/null +++ b/arch/riscv/init/start.S @@ -0,0 +1,5 @@ +.section .init.start +.global _start +_start: +li sp, PM_STACK_TOP +jal init diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c index 113773a..ed97c00 100644 --- a/arch/riscv/kernel/irq.c +++ b/arch/riscv/kernel/irq.c @@ -1,9 +1,13 @@ #include #include -void irq_handler() +void init_irq(void *fdt) { + UNUSED(fdt); +} +void handle_irq() +{ } /* very simple for now */ diff --git a/arch/riscv/kernel/main.c b/arch/riscv/kernel/main.c index 83270eb..9ce256e 100644 --- a/arch/riscv/kernel/main.c +++ b/arch/riscv/kernel/main.c @@ -1,298 +1,11 @@ -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -struct pm_layout_t { - pm_t base; - pm_t top; -}; - -struct pm_orders_t { - size_t max_order; - size_t bits[10]; - size_t page_shift; -}; - -#ifdef DEBUG - -static void init_dbg(void *fdt) -{ - struct dbg_info_t dbg = dbg_from_fdt(fdt); - dbg_init(dbg.dbg_ptr + (-SZ_1G), dbg.dev); -} - -#else -#define init_dbg(...) -#endif - -static struct pm_layout_t get_memlayout(void *fdt) -{ - struct cell_info_t ci = get_reginfo(fdt, "/memory"); - int mem_offset = fdt_path_offset(fdt, "/memory"); - uint8_t *mem_reg = - (uint8_t *) fdt_getprop(fdt, mem_offset, "reg", NULL); - - /* if riscv128 comes around we will probably see addr_cells == 4, but - * I'm not too concerned about it at the moment */ - pm_t base = (pm_t)fdt_load_int_ptr(ci.addr_cells, mem_reg); - - if(ci.addr_cells == 2) - mem_reg += sizeof(fdt64_t); - else - mem_reg += sizeof(fdt32_t); - - /* -1 because base is a legitimate memory address */ - pm_t top = (pm_t)fdt_load_int_ptr(ci.size_cells, mem_reg) + base - 1; - return (struct pm_layout_t){(size_t)__va(base), (size_t)__va(top)}; -} - -static pm_t get_kerneltop() -{ - /* interesting, for some reason if I define these to be just char - * pointers I get some wacky values. Not sure why that would be, but - * this works. */ - extern char __kernel_end; - return (pm_t)&__kernel_end; -} - -static pm_t get_fdttop(void *fdt) -{ - const char *b = (const char *)fdt; - return (pm_t)(b + fdt_totalsize(fdt)); -} - -static pm_t get_fdtbase(void *fdt) -{ - /* lol */ - return (pm_t)fdt; -} - - -static void mark_area_used(pm_t base, pm_t top) -{ - size_t area_left = top - base; - /* TODO: add in a method to make sure that we use as large mappings as - * possible. */ - while(area_left >= MM_KPAGE_SIZE){ - mark_used(base, MM_KPAGE); - area_left -= MM_KPAGE_SIZE; - base += MM_KPAGE_SIZE; - } - - if(area_left != 0) - mark_used(base, MM_KPAGE_SIZE); -} - -static void mark_reserved_mem(void *fdt) -{ - int rmem_offset = fdt_path_offset(fdt, "/reserved-memory/mmode_resv0"); - struct cell_info_t ci = get_reginfo(fdt, "/reserved-memory/mmode_resv0"); - uint8_t *rmem_reg = (uint8_t *)fdt_getprop(fdt, rmem_offset, "reg", NULL); - - pm_t base = (pm_t)fdt_load_int_ptr(ci.addr_cells, rmem_reg); - - if(ci.addr_cells == 2) - rmem_reg += sizeof(fdt64_t); - else - rmem_reg += sizeof(fdt32_t); - - pm_t top = (pm_t)fdt_load_int_ptr(ci.size_cells, rmem_reg) + base - 1; - mark_area_used(base, top); -} - -static struct pm_layout_t setup_pmem(void *fdt) -{ - struct pm_layout_t pmem = get_memlayout(fdt); - - pm_t initrd_top = get_initrdtop(fdt); - pm_t kernel_top = get_kerneltop(); - pm_t fdt_top = get_fdttop(fdt); - - pm_t top = MAX3(kernel_top, initrd_top, fdt_top); - dbg("initrd_top:\t%#lx\n", initrd_top); - dbg("kernel_top:\t%#lx\n", kernel_top); - dbg("fdt_top:\t%#lx\n", fdt_top); - - /* TODO: check that pmap placement doesn't overwrite anything, such as - * stack or go over top address of memory */ - size_t probe_size = probe_pmap(pmem.base, pmem.top - pmem.base); - /* riscv handles two byte boundaries better than one byte, so align - * upwards */ - pm_t pmap_base = align_up(top + 1, 2); - size_t actual_size = populate_pmap(pmem.base, pmem.top - pmem.base, - pmap_base); - - /* TODO: not entirely sure what to do about this, probably give up trying to - * boot? */ - if(probe_size != actual_size){ - dbg("BUG! probe_size (%#lx) != actual_size (%#lx)\n", - probe_size, actual_size); - } - - /* mark init stack, at the moment always mapped to 2M */ - mark_used(PM_STACK_BASE, MM_MPAGE); - - /* mark kernel, at the moment with a 2M partition */ - mark_used(PM_KERN, MM_MPAGE); - - /* mark fdt and initrd */ - mark_area_used(get_initrdbase(fdt), initrd_top); - mark_area_used(get_fdtbase(fdt), fdt_top); - - /* mark pmap */ - mark_area_used(pmap_base, pmap_base + actual_size); - - /* mark reserved mem */ - mark_reserved_mem(fdt); - - return (struct pm_layout_t){.base = pmap_base, .top = actual_size + pmap_base}; -} - -static struct pm_orders_t init_pmem(void *fdt) -{ - /* bad idea for now */ - /* enum mm_mode_t mmode = get_mmode(fdt); */ - - size_t max_order = 0; - size_t order_bits = 9; - enum mm_mode_t mmode = Sv39; - switch(mmode){ - case Sv32: - max_order = 1; - order_bits = 10; - break; - - case Sv39: - max_order = 2; - break; - - case Sv48: - max_order = 3; - break; - }; - - size_t bits[10] = {0}; - for(size_t i = 0; i <= max_order; ++i) - bits[i] = order_bits; - - init_mem(max_order, bits, 12); - - struct pm_orders_t ret = {max_order, {0}, 12}; - for(size_t i = 0; i <= __mm_max_order; ++i) - ret.bits[i] = bits[i]; - - return ret; -} - -/* assume Sv39 for now */ -#define to_pte(a, f) (((a) >> 12) << 10 | (f)) -static void populate_root_branch(struct vm_branch_t *b) -{ - size_t flags = VM_V | VM_R | VM_W | VM_X | VM_G; - for(size_t i = 256; i < 511; ++i) - b->leaf[i] = (struct vm_branch_t *)to_pte(RAM_BASE + SZ_1G * (i - 256), flags); - - /* very lazy, should be ashamed, yes */ - b->leaf[511] = (struct vm_branch_t *)to_pte(0, flags); -} - -static void start_vmem(struct vm_branch_t *branch, enum mm_mode_t m) -{ - /* TODO: get ASID from CPU id */ - - branch = (struct vm_branch_t *)__pa(branch); - - if(m == Sv32) - csr_write(CSR_SATP, SATP_MODE_Sv32 | pm_to_pnum((pm_t)(branch))); - else if (m == Sv39) - csr_write(CSR_SATP, SATP_MODE_Sv39 | pm_to_pnum((pm_t)(branch))); - else - csr_write(CSR_SATP, SATP_MODE_Sv48 | pm_to_pnum((pm_t)(branch))); - - __asm__ ("sfence.vma" : : : "memory"); - /* Sv57 && Sv64 in the future? */ -} - -static struct vm_branch_t *init_vmem(void *fdt) -{ - init_pmem(fdt); - setup_pmem(fdt); - - struct vm_branch_t *b = (struct vm_branch_t *)alloc_page(MM_KPAGE, 0); - memset(b, 0, sizeof(struct vm_branch_t)); - - populate_root_branch(b); - /* update which memory branch to use */ - start_vmem(b, Sv39); - return b; -} - -static void init_irq(void *fdt) -{ -} - -static void init_proc(void *fdt, struct vm_branch_t *b) +void arch_setup(void *fdt) { - struct tcb *t = (struct tcb *)alloc_page(MM_KPAGE, 0); - t->b_r = b; - t->pid = 0; - t->tid = 0; - threads_insert(t); - /* first page reserved to avoid issues with null pointers being legal */ - /* last gig page (assuming Sv39) reserved for call stack */ - sp_mem_init(&t->sp_r, SZ_4K, SZ_256G - SZ_1G); - - /* stack (should probably be set up to allow for configuration - * parameters to be passed) */ - t->proc_stack = alloc_uvmem(t, SZ_2M, VM_V | VM_R | VM_W | VM_U); - /* if need be, the call stack can later be expanded, but this init - * program uses it like this. */ - t->call_stack = setup_call_stack(t, SZ_256G - SZ_1G + SZ_2M, SZ_2M); - - /* should probably wrap this in like tlb_flush_all() or something */ - __asm__ ("sfence.vma" : : : "memory"); - - jump_to_userspace(t, get_init_base(fdt), 0, 0); -} - -#define __va_reg(reg)\ -{\ - vm_t reg = 0;\ - __asm__("mv %0, " QUOTE(reg) : "=r" (reg) :: );\ - reg = (vm_t)__va(reg);\ - __asm__("mv " QUOTE(reg) ", %0" :: "rK" (reg) : );\ -} - -void __main arch_main(void *fdt) -{ - __va_reg(sp); - __va_reg(fp); - __va_reg(gp); - - /* correct fdt pointer */ - fdt = (void *)__va(fdt); - init_dbg(fdt); - dbg_fdt(fdt); - - /* allow supervisor code to touch user data */ + UNUSED(fdt); + /* allow supervisor code to touch user pages */ csr_set(CSR_SSTATUS, SSTATUS_SUM); - /* maybe this is too early but mark that we want to jump to user mode - * eventually*/ + /* mark that we want to eventually jump to userspace */ csr_clear(CSR_SSTATUS, SSTATUS_SPP); - struct vm_branch_t *b = init_vmem(fdt); - init_mem_blocks(); - init_irq(fdt); - init_proc(fdt, b); } diff --git a/arch/riscv/kernel/pmem.c b/arch/riscv/kernel/pmem.c new file mode 100644 index 0000000..45b8eeb --- /dev/null +++ b/arch/riscv/kernel/pmem.c @@ -0,0 +1,15 @@ +#include + +int arch_pmem_conf(void *fdt, size_t *max_order, size_t *base_bits, size_t bits[ORDERS_NUM]) +{ + UNUSED(fdt); + + /* Sv39 for now */ + *max_order = 2; + *base_bits = 12; + /* we can assume bits[] is zeroed out beforehand */ + for(size_t i = 0; i <= *max_order; ++i) + bits[i] = 9; + + return 0; +} diff --git a/arch/riscv/kernel/proc.c b/arch/riscv/kernel/proc.c index 57ddc5b..6120c2d 100644 --- a/arch/riscv/kernel/proc.c +++ b/arch/riscv/kernel/proc.c @@ -2,9 +2,9 @@ #include #include -void jump_to_userspace(struct tcb *t, vm_t bin, int argc, char **argv) +void jump_to_userspace(struct tcb *t, int argc, char **argv) { - csr_write(CSR_SEPC, prepare_proc(t, bin)); + csr_write(CSR_SEPC, t->entry); __asm__("mv sp, %0\n" : "=r" (t->proc_stack) :: "memory"); __asm__("sret\n" ::: "memory"); } diff --git a/arch/riscv/kernel/vmem.c b/arch/riscv/kernel/vmem.c index 45f6336..c862cea 100644 --- a/arch/riscv/kernel/vmem.c +++ b/arch/riscv/kernel/vmem.c @@ -3,12 +3,14 @@ #include #include #include +#include #include #include +#include #define pte_ppn(pte) (((pm_t)(pte)) >> 10) #define pte_flags(pte) (((pm_t)(pte)) & 0xff) -#define to_pte(p, f) ((pm_to_pnum((pm_t)__pa(p)) << 10) | (f)) +#define to_pte(p, f) ((pm_to_pnum(p) << 10) | (f)) #define pte_addr(pte) __va(pnum_to_paddr(pte_ppn(pte))) #define pte_paddr(pte) (pnum_to_paddr(pte_ppn(pte))) #define vm_to_index(a, o) (pm_to_index(a, o)) @@ -16,9 +18,9 @@ #define is_leaf(pte) (is_active(pte) && (pte_flags(pte) & ~VM_V)) #define is_branch(pte) (is_active(pte) && !(pte_flags(pte) & ~VM_V)) -static pm_t *__find_vmem(struct vm_branch_t *b, vm_t v, enum mm_order_t *o) +static pm_t *__find_vmem(struct vm_branch *b, vm_t v, enum mm_order *o) { - enum mm_order_t top = __mm_max_order; + enum mm_order top = __mm_max_order; if(o) *o = MM_O0; do { @@ -35,17 +37,17 @@ static pm_t *__find_vmem(struct vm_branch_t *b, vm_t v, enum mm_order_t *o) return (pm_t *)&b->leaf[idx]; } - b = (struct vm_branch_t *)pte_addr(pte); + b = (struct vm_branch *)pte_addr(pte); } while (top--); return 0; } -int mod_vmem(struct vm_branch_t *branch, vm_t vaddr, pm_t paddr, uint8_t flags) +int mod_vmem(struct vm_branch *branch, vm_t vaddr, pm_t paddr, uint8_t flags) { pm_t *pte = __find_vmem(branch, vaddr, 0); if(pte){ - *pte = to_pte(paddr, flags); + *pte = to_pte((pm_t)__pa(paddr), flags); return 0; } @@ -54,8 +56,8 @@ int mod_vmem(struct vm_branch_t *branch, vm_t vaddr, pm_t paddr, uint8_t flags) /* huh, should probably add status flags etc. to all my API functions. Damn, I'm * lazy. */ -int stat_vmem(struct vm_branch_t *branch, vm_t vaddr, pm_t *paddr, - enum mm_order_t *order, uint8_t *flags) +int stat_vmem(struct vm_branch *branch, vm_t vaddr, pm_t *paddr, + enum mm_order *order, uint8_t *flags) { pm_t *pte = __find_vmem(branch, vaddr, order); if(pte){ @@ -71,30 +73,30 @@ int stat_vmem(struct vm_branch_t *branch, vm_t vaddr, pm_t *paddr, return -1; } -static struct vm_branch_t *__create_leaf() +static struct vm_branch *__create_leaf() { pm_t new_leaf = alloc_page(MM_KPAGE, 0); - memset((void *)new_leaf, 0, sizeof(struct vm_branch_t)); - return (struct vm_branch_t *)to_pte(new_leaf, VM_V); + memset((void *)new_leaf, 0, sizeof(struct vm_branch)); + return (struct vm_branch *)to_pte((pm_t)__pa(new_leaf), VM_V); } -static void __destroy_branch(struct vm_branch_t *b) +static void __destroy_branch(struct vm_branch *b) { if(!b) return; for(size_t i = 0; i < BASE_PAGE_SIZE / sizeof(pm_t); ++i){ if(is_branch(b->leaf[i])) - __destroy_branch((struct vm_branch_t *)pte_addr(b->leaf[i])); + __destroy_branch((struct vm_branch *)pte_addr(b->leaf[i])); free_page(MM_KPAGE, (pm_t)pte_addr(b->leaf[i])); } } -void map_vmem(struct vm_branch_t *branch, - pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order_t order) +void map_vmem(struct vm_branch *branch, + pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order order) { - enum mm_order_t top = __mm_max_order; + enum mm_order top = __mm_max_order; while (top != order) { size_t idx = vm_to_index(vaddr, top); @@ -102,7 +104,7 @@ void map_vmem(struct vm_branch_t *branch, branch->leaf[idx] = __create_leaf(); - branch = (struct vm_branch_t *)pte_addr(branch->leaf[idx]); + branch = (struct vm_branch *)pte_addr(branch->leaf[idx]); top--; } @@ -110,10 +112,10 @@ void map_vmem(struct vm_branch_t *branch, if (is_branch(branch->leaf[idx])) /* something has gone terribly wrong */ __destroy_branch(branch->leaf[idx]); - branch->leaf[idx] = (struct vm_branch_t *)to_pte(paddr, flags); + branch->leaf[idx] = (struct vm_branch *)to_pte((pm_t)__pa(paddr), flags); } -void unmap_vmem(struct vm_branch_t *branch, vm_t vaddr) +void unmap_vmem(struct vm_branch *branch, vm_t vaddr) { pm_t *pte = __find_vmem(branch, vaddr, 0); @@ -121,12 +123,60 @@ void unmap_vmem(struct vm_branch_t *branch, vm_t vaddr) *pte = 0; } -void flush_tlb(id_t cpu_id) +void flush_tlb() { - __asm__("sfence.vma %0\n" :: "rk" (cpu_id) : "memory"); + __asm__("sfence.vma %0\n" :: "rk" (cpu_id()) : "memory"); } void flush_tlb_all() { __asm__("sfence.vma\n" ::: "memory"); } + +static void start_vmem(struct vm_branch *branch, enum mm_mode m) +{ + branch = (struct vm_branch *)__pa(branch); + + if(m == Sv32) + csr_write(CSR_SATP, SATP_MODE_Sv32 | pm_to_pnum((pm_t)(branch))); + else if (m == Sv39) + csr_write(CSR_SATP, SATP_MODE_Sv39 | pm_to_pnum((pm_t)(branch))); + else + csr_write(CSR_SATP, SATP_MODE_Sv48 | pm_to_pnum((pm_t)(branch))); + + flush_tlb_all(); + /* Sv57 && Sv64 in the future? */ +} + +struct vm_branch *init_vmem(void *fdt) +{ + UNUSED(fdt); + struct vm_branch *b = (struct vm_branch *)alloc_page(MM_KPAGE, 0); + memset(b, 0, MM_KPAGE_SIZE); + + populate_root_branch(b); + /* update which memory branch to use */ + start_vmem(b, Sv39); + return b; +} + +void populate_root_branch(struct vm_branch *b) +{ + size_t flags = VM_V | VM_R | VM_W | VM_X | VM_G; + for(size_t i = KSTART_PAGE; i < IO_PAGE; ++i) + b->leaf[i] = (struct vm_branch *)to_pte(RAM_BASE + SZ_1G * (i - KSTART_PAGE), flags); + + /* map kernel IO to zero for now, this will be overridden later + * (if at all) */ + b->leaf[IO_PAGE] = (struct vm_branch *)to_pte(0, flags); +} + +#ifdef DEBUG +int setup_kernel_io(struct vm_branch *b, vm_t paddr) +{ + /* assume Sv39 for now */ + pm_t gigapage = paddr / MM_GPAGE_SIZE; + b->leaf[IO_PAGE] = (struct vm_branch *)to_pte(gigapage, VM_V | VM_R | VM_W); + return 0; +} +#endif diff --git a/arch/riscv/source.mk b/arch/riscv/source.mk index 0e9a5c3..e50880c 100644 --- a/arch/riscv/source.mk +++ b/arch/riscv/source.mk @@ -1,6 +1,6 @@ KERNEL_LOCAL != echo arch/riscv/kernel/*.[cS] KERNEL_SOURCES += $(KERNEL_LOCAL) -INIT_SOURCES += arch/riscv/init/init.c +INIT_SOURCES += arch/riscv/init/*.[cS] CLEANUP_CMD := ./arch/riscv/conf/rmimage.sh diff --git a/common/debug.c b/common/debug.c index 1800b1c..d34823a 100644 --- a/common/debug.c +++ b/common/debug.c @@ -59,7 +59,7 @@ static void __putchar(char c) port->data = c; } -static enum serial_dev_t serial_dev_enum(const char *dev_name) +static enum serial_dev serial_dev_enum(const char *dev_name) { if (strncmp("ns16550", dev_name, 7) == 0) return NS16550A; @@ -67,7 +67,7 @@ static enum serial_dev_t serial_dev_enum(const char *dev_name) return -1; } -struct dbg_info_t dbg_from_fdt(void *fdt) +struct dbg_info dbg_from_fdt(void *fdt) { int chosen_offset = fdt_path_offset(fdt, "/chosen"); const char *stdout = fdt_getprop(fdt, chosen_offset, "stdout-path", NULL); @@ -78,22 +78,22 @@ struct dbg_info_t dbg_from_fdt(void *fdt) const char *dev_name = (const char *)fdt_getprop(fdt, stdout_offset, "compatible", NULL); - enum serial_dev_t dev = serial_dev_enum(dev_name); + enum serial_dev dev = serial_dev_enum(dev_name); /* get serial device address */ - struct cell_info_t ci = get_reginfo(fdt, stdout); + struct cell_info ci = get_reginfo(fdt, stdout); void *reg_ptr = (void *)fdt_getprop(fdt, stdout_offset, "reg", NULL); - void *dbg_ptr = (void *)(pm_t)fdt_load_int_ptr(ci.addr_cells, reg_ptr); + pm_t dbg_ptr = (pm_t)fdt_load_int_ptr(ci.addr_cells, reg_ptr); - return (struct dbg_info_t){dbg_ptr, dev}; + return (struct dbg_info){dbg_ptr, dev}; } -void dbg_init(void *pt, enum serial_dev_t dev) +void setup_dbg(vm_t pt, enum serial_dev dev) { switch (dev) { case NS16550A: - port = pt; + port = (struct ns16550a *)pt; break; } diff --git a/common/elf.c b/common/elf.c index fafef00..aab00d1 100644 --- a/common/elf.c +++ b/common/elf.c @@ -72,9 +72,9 @@ static vm_t __prepare_proc(struct tcb *t, uint8_t ei_c, vm_t elf) } /* sets up all memory regions etc, returns the entry address */ -vm_t prepare_proc(struct tcb *t, vm_t p) +vm_t load_elf(struct tcb *t, vm_t b) { - struct elf_ident *i = (struct elf_ident *)p; + struct elf_ident *i = (struct elf_ident *)b; if(i->ei_magic != cpu_to_be32(EI_MAGIC)) return 0; @@ -82,5 +82,5 @@ vm_t prepare_proc(struct tcb *t, vm_t p) return 0; /* more sanity checks? */ - return __prepare_proc(t, i->ei_class, p); + return __prepare_proc(t, i->ei_class, b); } diff --git a/common/fdt.c b/common/fdt.c index c554b25..f76ad64 100644 --- a/common/fdt.c +++ b/common/fdt.c @@ -1,19 +1,19 @@ #include -struct cell_info_t get_cellinfo(void *fdt, int offset) +struct cell_info get_cellinfo(void *fdt, int offset) { - return (struct cell_info_t){ + return (struct cell_info){ fdt_size_cells(fdt, offset), fdt_address_cells(fdt, offset) }; } /* how "reg" is interpreted depends on the parent node */ -struct cell_info_t get_reginfo(void *fdt, const char *path) +struct cell_info get_reginfo(void *fdt, const char *path) { const char *i = strrchr(path, '/'); if(!i) - return (struct cell_info_t){0, 0}; + return (struct cell_info){0, 0}; size_t baselen = i - path; if(i == 0) diff --git a/common/initrd.c b/common/initrd.c index 18db836..afce2ec 100644 --- a/common/initrd.c +++ b/common/initrd.c @@ -56,7 +56,7 @@ static struct cpio_header *find_file(char *c, char* fname, size_t fname_len) pm_t get_initrdtop(void *fdt) { int chosen_offset = fdt_path_offset(fdt, "/chosen"); - struct cell_info_t ci = get_cellinfo(fdt, chosen_offset); + struct cell_info ci = get_cellinfo(fdt, chosen_offset); void *initrd_end_ptr = (void *)fdt_getprop(fdt, chosen_offset, "linux,initrd-end", NULL); @@ -68,7 +68,7 @@ pm_t get_initrdtop(void *fdt) pm_t get_initrdbase(void *fdt) { int chosen_offset = fdt_path_offset(fdt, "/chosen"); - struct cell_info_t ci = get_cellinfo(fdt, chosen_offset); + struct cell_info ci = get_cellinfo(fdt, chosen_offset); void *initrd_base_ptr = (void *)fdt_getprop(fdt, chosen_offset, "linux,initrd-start", NULL); diff --git a/common/main.c b/common/main.c new file mode 100644 index 0000000..f91fc22 --- /dev/null +++ b/common/main.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG +static struct dbg_info dbg_info = (struct dbg_info){0}; + +static void init_dbg(void *fdt) +{ + dbg_info = dbg_from_fdt(fdt); +} + +static void setup_dmap_dbg() +{ + setup_dbg(dbg_info.dbg_ptr, dbg_info.dev); +} + +static void setup_io_dbg(struct vm_branch *b) +{ + vm_t io_ptr = setup_kernel_io(b, dbg_info.dbg_ptr); + setup_dbg(io_ptr, dbg_info.dev); +} +#else +#define init_dbg(...) +#define setup_dmap_dbg(...) +#define setup_io_dbg(...) +#endif + +void __main main(void *fdt) +{ + /* dbg uses direct mapping at this point */ + init_dbg(fdt); + setup_dmap_dbg(); + dbg_fdt(fdt); + + arch_setup(fdt); + + init_pmem(fdt); + init_mem_blocks(); + struct vm_branch *b = init_vmem(fdt); + + /* start up debugging in kernel IO */ + setup_io_dbg(b); + + init_irq(fdt); + init_proc(fdt, b); +} diff --git a/common/mem.c b/common/mem.c index cff11b7..7a7eff6 100644 --- a/common/mem.c +++ b/common/mem.c @@ -24,25 +24,3 @@ void init_mem(size_t max_order, size_t bits[10], size_t page_shift) __mm_sizes[i] = 1UL << __mm_shifts[i] << __mm_page_shift; } } - -enum mm_mode_t get_mmode(void *fdt) -{ - int mmu_offset = fdt_path_offset(fdt, "/cpus/cpu"); - const char *mmu = fdt_getprop(fdt, mmu_offset, "mmu-type", NULL); - - if(strncmp("riscv,sv48", mmu, 10) == 0) - return Sv48; - - if(strncmp("riscv,sv39", mmu, 10) == 0) - return Sv39; - - if(strncmp("riscv,sv32", mmu, 10) == 0) - return Sv32; - - /* fdt is missing mmu-type for some reason, but we can probably use - * these values as fallback */ - if(__riscv_xlen == 32) - return Sv32; - else - return Sv39; -} diff --git a/common/pmem.c b/common/pmem.c index e40d160..d9cdd50 100644 --- a/common/pmem.c +++ b/common/pmem.c @@ -1,6 +1,9 @@ #include +#include +#include #include /* memset */ #include /* __is_nset etc */ +#include /* NOTE: these are all for pnum_t, i.e. O0_SHIFT is from 0 */ #define __foreach_page(var, start, end, attr, neg)\ @@ -41,7 +44,7 @@ struct mm_branch_t { struct mm_omap_t { pm_t base; mm_node_t **orders; - enum mm_order_t order; + enum mm_order order; }; struct mm_pmap_t { @@ -50,8 +53,8 @@ struct mm_pmap_t { static struct mm_pmap_t *pmap = 0; -static void __mark_free(mm_node_t * op, pnum_t pnum, enum mm_order_t tgt, - enum mm_order_t src, enum mm_order_t dst) +static void __mark_free(mm_node_t * op, pnum_t pnum, enum mm_order tgt, + enum mm_order src, enum mm_order dst) { size_t idx = pnum_to_index(pnum, src); @@ -69,7 +72,7 @@ static void __mark_free(mm_node_t * op, pnum_t pnum, enum mm_order_t tgt, __clear_nbit(o->full[__o_container(idx)], __o_bit(idx)); } -void free_page(enum mm_order_t order, pm_t paddr) +void free_page(enum mm_order order, pm_t paddr) { for (size_t i = MM_O0; i <= __mm_max_order; ++i) { if (!pmap->omap[i]) @@ -88,8 +91,8 @@ void free_page(enum mm_order_t order, pm_t paddr) } } -static bool __mark_used(mm_node_t * op, pnum_t pnum, enum mm_order_t tgt, - enum mm_order_t src, enum mm_order_t dst) +static bool __mark_used(mm_node_t * op, pnum_t pnum, enum mm_order tgt, + enum mm_order src, enum mm_order dst) { size_t idx = pnum_to_index(pnum, src); @@ -123,7 +126,7 @@ static bool __mark_used(mm_node_t * op, pnum_t pnum, enum mm_order_t tgt, return false; } -void mark_used(enum mm_order_t order, pm_t paddr) +void mark_used(enum mm_order order, pm_t paddr) { for (size_t i = MM_O0; i <= __mm_max_order; ++i) { if (!pmap->omap[i]) @@ -143,7 +146,7 @@ void mark_used(enum mm_order_t order, pm_t paddr) } static pnum_t __enum_order(mm_node_t * op, pnum_t offset, - enum mm_order_t src, enum mm_order_t dst) + enum mm_order src, enum mm_order dst) { size_t idx = pnum_to_index(offset, src); @@ -173,7 +176,7 @@ static pnum_t __enum_order(mm_node_t * op, pnum_t offset, return -1; } -pm_t alloc_page(enum mm_order_t order, pm_t offset) +pm_t alloc_page(enum mm_order order, pm_t offset) { if (order > __mm_max_order) return 0; @@ -204,57 +207,9 @@ pm_t alloc_page(enum mm_order_t order, pm_t offset) return paddr; } - - -static void __update_order(mm_node_t * op, pm_t base, pm_t offset, - enum mm_order_t src, enum mm_order_t dst) -{ - if (src == dst) { - struct mm_leaf_t *o = (struct mm_leaf_t *)op; - o->used = (mm_info_t *) move_paddr(o->used, base, offset); - return; - } - - struct mm_branch_t *o = (struct mm_branch_t *)op; - o->full = (mm_info_t *) move_paddr(o->full, base, offset); - for (size_t i = 0; i < o->entries; ++i) { - __update_order(o->next[i], base, offset, src - 1, dst); - o->next[i] = - (mm_node_t **) move_paddr(o->next[i], base, offset); - } - - o->next = (mm_node_t **) move_paddr(o->next, base, offset); -} - -static void __update_omap(struct mm_omap_t *omap, pm_t base, pm_t offset) -{ - for (size_t i = MM_O0; i <= omap->order; ++i) { - __update_order(omap->orders[i], base, offset, omap->order, i); - omap->orders[i] = - (mm_node_t *) move_paddr(omap->orders[i], base, offset); - } - - omap->orders = (mm_node_t **) move_paddr(omap->orders, base, offset); -} - -void update_pmap(pm_t offset) -{ - pm_t base = (pm_t) pmap; - for (size_t i = 0; i <= __mm_max_order; ++i) { - if (!pmap->omap[i]) - continue; - - __update_omap(pmap->omap[i], base, offset); - pmap->omap[i] = (struct mm_omap_t *)move_paddr(pmap->omap[i], - base, offset); - } - - pmap = (struct mm_pmap_t *)move_paddr(pmap, base, offset); -} - /* unfortunate that populating the mm info is so complicated */ static pm_t __populate_order(mm_node_t ** op, pm_t cont, - enum mm_order_t src, enum mm_order_t dst, size_t num) + enum mm_order src, enum mm_order dst, size_t num) { if (src == dst) { struct mm_leaf_t *o = (struct mm_leaf_t *) @@ -286,7 +241,7 @@ static pm_t __populate_order(mm_node_t ** op, pm_t cont, return cont; } -static pm_t __probe_order(pm_t cont, enum mm_order_t src, enum mm_order_t dst, +static pm_t __probe_order(pm_t cont, enum mm_order src, enum mm_order dst, size_t num) { if(src == dst){ @@ -306,7 +261,7 @@ static pm_t __probe_order(pm_t cont, enum mm_order_t src, enum mm_order_t dst, } static pm_t __populate_omap(struct mm_omap_t **omap, pm_t cont, - pm_t base, size_t entries, enum mm_order_t order) + pm_t base, size_t entries, enum mm_order order) { struct mm_omap_t *lomap = (struct mm_omap_t *) move_forward(cont, sizeof(struct mm_omap_t)); @@ -327,7 +282,7 @@ static pm_t __populate_omap(struct mm_omap_t **omap, pm_t cont, return cont; } -static pm_t __probe_omap(pm_t cont, size_t entries, enum mm_order_t order) +static pm_t __probe_omap(pm_t cont, size_t entries, enum mm_order order) { cont += sizeof(struct mm_omap_t); cont += (order + 1) * sizeof(mm_node_t **); @@ -388,8 +343,104 @@ pm_t probe_pmap(pm_t ram_base, size_t ram_size) return cont; } -/* only call from kernel */ -void init_pmap(void *p) +static void mark_area_used(pm_t base, pm_t top) { - pmap = (struct mm_pmap_t *)p; + size_t area_left = top - base; + pm_t runner = base; + while(area_left >= BASE_PAGE_SIZE){ + mark_used(BASE_PAGE, runner); + runner += BASE_PAGE_SIZE; + area_left -= BASE_PAGE_SIZE; + } + + if(area_left != 0) + mark_used(BASE_PAGE, runner); +} + +static void mark_reserved_mem(void *fdt) +{ + int rmem_offset = fdt_path_offset(fdt, "/reserved-memory/mmode_resv0"); + struct cell_info ci = get_reginfo(fdt, "/reserved-memory/mmode_resv0"); + uint8_t *rmem_reg = (uint8_t *)fdt_getprop(fdt, rmem_offset, "reg", NULL); + + pm_t base = (pm_t)fdt_load_int_ptr(ci.addr_cells, rmem_reg); + + if(ci.addr_cells == 2) + rmem_reg += sizeof(fdt64_t); + else + rmem_reg += sizeof(fdt32_t); + + pm_t top = (pm_t)fdt_load_int_ptr(ci.size_cells, rmem_reg) + base; + mark_area_used((pm_t)__va(base), (pm_t)__va(top)); +} + +static pm_t get_ramtop(void *fdt) +{ + struct cell_info ci = get_reginfo(fdt, "/memory"); + int mem_offset = fdt_path_offset(fdt, "/memory"); + uint8_t *mem_reg = (uint8_t *)fdt_getprop(fdt, mem_offset, "reg", NULL); + + pm_t base = (pm_t)fdt_load_int_ptr(ci.addr_cells, mem_reg); + + if(ci.addr_cells == 2) + mem_reg += sizeof(fdt64_t); + else + mem_reg += sizeof(fdt32_t); + + return (pm_t)fdt_load_int_ptr(ci.size_cells, mem_reg) + base; +} + +static pm_t get_fdttop(void *fdt) +{ + const char *b = (const char *)fdt; + return (pm_t)(b + fdt_totalsize(fdt)); +} + +static pm_t get_fdtbase(void *fdt) +{ + /* lol */ + return (pm_t)fdt; +} + +void init_pmem(void *fdt) +{ + size_t max_order = 0; + size_t base_bits = 0; + size_t bits[ORDERS_NUM] = {0}; + arch_pmem_conf(fdt, &max_order, &base_bits, bits); + init_mem(max_order, bits, base_bits); + + pm_t ram_size = get_ramtop(fdt) - RAM_BASE; + pm_t ram_base = (pm_t)__va(RAM_BASE); + + pm_t initrd_top = get_initrdtop(fdt); + pm_t fdt_top = get_fdttop(fdt); + + /* find probably most suitable contiguous region of ram for our physical + * ram map */ + pm_t pmap_base = align_up(MAX(initrd_top, fdt_top), sizeof(int)); + + size_t probe_size = probe_pmap(ram_base, ram_size); + size_t actual_size = populate_pmap(ram_base, ram_size, pmap_base); + + if(probe_size != actual_size) + dbg("BUG! probe_size (%#lx) != actual_size (%#lx)\n", + probe_size, actual_size); + + /* mark init stack, this should be unmapped once we get to executing + * processes */ + mark_area_used((pm_t)__va(PM_STACK_BASE), (pm_t)__va(PM_STACK_TOP)); + + /* mark kernel */ + mark_area_used((pm_t)__va(PM_KERN_BASE), (pm_t)__va(PM_KERN_TOP)); + + /* mark fdt and initrd */ + mark_area_used(get_initrdbase(fdt), initrd_top); + mark_area_used(get_fdtbase(fdt), fdt_top); + + /* mark pmap */ + mark_area_used(pmap_base, pmap_base + actual_size); + + /* mark reserved mem */ + mark_reserved_mem(fdt); } diff --git a/common/proc.c b/common/proc.c index 5fdf413..ccd60bd 100644 --- a/common/proc.c +++ b/common/proc.c @@ -1,16 +1,50 @@ +#include +#include +#include +#include #include /* TODO: add error checking */ -vm_t setup_call_stack(struct tcb *t, vm_t start, size_t bytes) +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; - for(size_t i = 0; i < pages; ++i) + for(size_t i = 1; i <= pages; ++i) { offset = alloc_page(BASE_PAGE, offset); - map_vmem(t->b_r, offset, start + BASE_PAGE_SIZE * i, flags, BASE_PAGE); + map_vmem(t->b_r, offset, PROC_STACK_TOP - BASE_PAGE_SIZE * i, flags, BASE_PAGE); } - return start; + return PROC_STACK_TOP - BASE_PAGE_SIZE * pages; +} + +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) +{ + struct tcb *t = (struct tcb *)alloc_page(BASE_PAGE, 0); + memset(t, 0, sizeof(struct tcb)); + t->b_r = b; + t->pid = 0; + t->tid = 0; + + threads_insert(t); + + sp_mem_init(&t->sp_r, UVMEM_START, UVMEM_END); + + /* the binary gets to choose first what memory regions it requires */ + t->entry = load_elf(t, get_init_base(fdt)); + + t->proc_stack = setup_proc_stack(t, __proc_stack_size); + t->call_stack = setup_call_stack(t, __call_stack_size); + + + flush_tlb(); + + /* TODO: move fdt into process space */ + jump_to_userspace(t, 1, 0); } diff --git a/common/tcb.c b/common/tcb.c index 1547d49..cbbfa47 100644 --- a/common/tcb.c +++ b/common/tcb.c @@ -67,3 +67,8 @@ struct tcb *cur_tcb() { return __tcb_cache[cpu_id()]; } + +void set_tcb(struct tcb *t) +{ + __tcb_cache[cpu_id()] = t; +} diff --git a/common/uapi/conf.c b/common/uapi/conf.c index 01c4ada..6f4faff 100644 --- a/common/uapi/conf.c +++ b/common/uapi/conf.c @@ -1,5 +1,9 @@ +#include #include +size_t __proc_stack_size = SZ_2M; +size_t __call_stack_size = SZ_2M; + vm_t sys_conf(vm_t param, vm_t val, vm_t u0, vm_t u1) { UNUSED(u0); UNUSED(u1); diff --git a/common/vmem.c b/common/vmem.c index ffe9b32..9ff3b96 100644 --- a/common/vmem.c +++ b/common/vmem.c @@ -182,6 +182,9 @@ static struct sp_mem *sp_find_used_closest(struct sp_reg_root *r, vm_t start) struct sp_mem *closest = 0; size_t md = (size_t)(-1); struct sp_node *n = sp_root(r->used_regions); + if(!n) + return mem_container(sp_root(r->free_regions)); + while(n){ struct sp_mem *t = mem_container(n); size_t d = ABS((ssize_t)start - (ssize_t)t->start); @@ -415,12 +418,12 @@ 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_t *b, vm_t start, size_t bytes, uint8_t flags) +vm_t map_fill_region(struct vm_branch *b, vm_t start, size_t bytes, uint8_t flags) { pm_t offset = 0; pm_t runner = __page(start); size_t pages = __pages(bytes); - enum mm_order_t top = __mm_max_order; + enum mm_order top = __mm_max_order; /* actual start might not be the same as the user specified start */ start = __addr(runner); diff --git a/include/apos/arch.h b/include/apos/arch.h new file mode 100644 index 0000000..b846876 --- /dev/null +++ b/include/apos/arch.h @@ -0,0 +1,6 @@ +#ifndef APOS_ARCH_H +#define APOS_ARCH_H + +void arch_setup(void *fdt); + +#endif /* APOS_ARCH_H */ diff --git a/include/apos/conf.h b/include/apos/conf.h new file mode 100644 index 0000000..844ce37 --- /dev/null +++ b/include/apos/conf.h @@ -0,0 +1,9 @@ +#ifndef APOS_CONF_H +#define APOS_CONF_H + +#include + +extern size_t __proc_stack_size; +extern size_t __call_stack_size; + +#endif /* APOS_CONF_H */ diff --git a/include/apos/debug.h b/include/apos/debug.h index 5830c45..1a3265f 100644 --- a/include/apos/debug.h +++ b/include/apos/debug.h @@ -2,26 +2,28 @@ #define APOS_DEBUG_H #include +#include #ifdef DEBUG -enum serial_dev_t { +enum serial_dev { /* only the NS16550A and compatible at the moment */ NS16550A, }; -struct dbg_info_t { - void *dbg_ptr; - enum serial_dev_t dev; +struct dbg_info { + pm_t dbg_ptr; + enum serial_dev dev; }; void __fmt(1, 2) dbg(const char *fmt, ...); -void dbg_init(void *pt, enum serial_dev_t dev); -struct dbg_info_t dbg_from_fdt(void *fdt); +void setup_dbg(pm_t pt, enum serial_dev dev); +struct dbg_info dbg_from_fdt(void *fdt); #else #define dbg(...) #define dbg_init(...) +#define dbg_from_fdt(...) #endif /* DEBUG */ diff --git a/include/apos/elf.h b/include/apos/elf.h index df07b7f..4fe74d1 100644 --- a/include/apos/elf.h +++ b/include/apos/elf.h @@ -184,6 +184,6 @@ __packed struct section64_header { #define program_header_prop(c, e, p) (c == ELFCLASS64 ? program64_header(e)->p : program32_header(e)->p) #define section_header_prop(c, e, p) (c == ELFCLASS64 ? section64_header(e)->p : section32_header(e)->p) -vm_t prepare_proc(struct tcb *t, vm_t p); +vm_t load_elf(struct tcb *t, vm_t b); #endif /* APOS_ELF_H */ diff --git a/include/apos/irq.h b/include/apos/irq.h index 958b25f..3ce6556 100644 --- a/include/apos/irq.h +++ b/include/apos/irq.h @@ -1,6 +1,8 @@ #ifndef APOS_IRQ_H #define APOS_IRQ_H +void init_irq(void *fdt); +void handle_irq(); void enable_irq(); void disable_irq(); diff --git a/include/apos/mem.h b/include/apos/mem.h index 0b3bffd..e935fe4 100644 --- a/include/apos/mem.h +++ b/include/apos/mem.h @@ -37,7 +37,7 @@ extern size_t __mm_page_shift; extern size_t __mm_max_order; void init_mem(size_t max_order, size_t shifts[10], size_t page_shift); -enum mm_mode_t get_mmode(void *fdt); +enum mm_mode get_mmode(void *fdt); #define BASE_PAGE_SIZE (__o_size(BASE_PAGE)) #define BASE_PAGE (MM_O0) diff --git a/include/apos/pmem.h b/include/apos/pmem.h index 01d89ce..2850f22 100644 --- a/include/apos/pmem.h +++ b/include/apos/pmem.h @@ -4,7 +4,8 @@ #include #include -enum mm_order_t { +#define ORDERS_NUM 10 +enum mm_order { MM_O0, MM_O1, MM_O2, @@ -20,12 +21,18 @@ enum mm_order_t { typedef size_t pm_t; typedef ssize_t pnum_t; +/* arch */ +int arch_pmem_conf(void *fdt, size_t *max_order, size_t *base_bits, size_t bits[ORDERS_NUM]); + +/* common */ void update_pmap(pm_t offset); -void free_page(enum mm_order_t order, pm_t paddr); -void mark_used(enum mm_order_t order, pm_t paddr); -pm_t alloc_page(enum mm_order_t order, pm_t offset); +void free_page(enum mm_order order, pm_t paddr); +void mark_used(enum mm_order order, pm_t paddr); +pm_t alloc_page(enum mm_order order, pm_t offset); pm_t populate_pmap(pm_t ram_base, size_t ram_size, pm_t cont); pm_t probe_pmap(pm_t ram_base, size_t ram_size); +void init_pmem(void *fdt); + #endif /* APOS_PMEM_H */ diff --git a/include/apos/proc.h b/include/apos/proc.h index 6f272b1..f835394 100644 --- a/include/apos/proc.h +++ b/include/apos/proc.h @@ -4,7 +4,7 @@ #include #include -void jump_to_userspace(struct tcb *t, vm_t bin, int argc, char **argv); -vm_t setup_call_stack(struct tcb *t, vm_t start, size_t bytes); +void jump_to_userspace(struct tcb *t, int argc, char **argv); +void 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 1d85e8b..0a07d7b 100644 --- a/include/apos/tcb.h +++ b/include/apos/tcb.h @@ -31,7 +31,7 @@ struct tcb { vm_t entry; - struct vm_branch_t *b_r; + struct vm_branch *b_r; }; void threads_insert(struct tcb *t); diff --git a/include/apos/vmem.h b/include/apos/vmem.h index 93d2ed7..87a3aa6 100644 --- a/include/apos/vmem.h +++ b/include/apos/vmem.h @@ -39,13 +39,22 @@ struct sp_mem { */ /* defined by arch */ -void map_vmem(struct vm_branch_t *branch, - pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order_t order); +void map_vmem(struct vm_branch *branch, + pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order order); -void unmap_vmem(struct vm_branch_t *branch, vm_t vaddr); -int mod_vmem(struct vm_branch_t *branch, vm_t vaddr, pm_t paddr, uint8_t flags); -int stat_vmem(struct vm_branch_t *branch, vm_t vaddr, pm_t *paddr, - enum mm_order_t *order, uint8_t *flags); +void unmap_vmem(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); + +int setup_kernel_io(struct vm_branch *b, vm_t paddr); +void populate_root_branch(struct vm_branch *b); +struct vm_branch *init_vmem(void *fdt); + +void flush_tlb(); +void flush_tlb_all(); + +/* defined in common */ int sp_mem_init(struct sp_reg_root *r, vm_t start, size_t nums); @@ -57,7 +66,7 @@ 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); void free_uvmem(struct tcb *r, vm_t a); -vm_t map_fill_region(struct vm_branch_t *b, vm_t start, size_t bytes, uint8_t flags); +vm_t map_fill_region(struct vm_branch *b, vm_t start, size_t bytes, uint8_t flags); size_t uvmem_size(); void set_uvmem_size(size_t s); diff --git a/include/libfdt.h b/include/libfdt.h index aa95bd3..304abb7 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -1,15 +1,16 @@ #ifndef APOS_LIBFDT_H #define APOS_LIBFDT_H #include "../dtc/libfdt/libfdt.h" +#include /* apos additions, implementation can be found in common/fdt.c */ -struct cell_info_t { +struct cell_info { uint32_t size_cells; uint32_t addr_cells; }; -struct cell_info_t get_cellinfo(void *fdt, int offset); -struct cell_info_t get_reginfo(void *fdt, const char *path); +struct cell_info get_cellinfo(void *fdt, int offset); +struct cell_info get_reginfo(void *fdt, const char *path); #if defined(DEBUG) void __dbg_fdt(void *fdt, int node_offset, int depth); -- cgit v1.3