diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2021-12-29 18:47:16 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2021-12-29 18:49:28 +0200 |
| commit | 4e5595a089c815febd7a0d42ab62940bf13f73ac (patch) | |
| tree | 322f35d9315e9966de8a66052811858df0144085 | |
| parent | a12e50e5a7dae52ed8bd5a24cc6576371e20985b (diff) | |
| download | kmi-4e5595a089c815febd7a0d42ab62940bf13f73ac.tar.gz kmi-4e5595a089c815febd7a0d42ab62940bf13f73ac.zip | |
Preparations for refactoring
| -rw-r--r-- | arch/riscv/init/init.c | 7 | ||||
| -rw-r--r-- | arch/riscv/ipc.txt | 7 | ||||
| -rw-r--r-- | arch/riscv/kernel/cpu.c | 2 | ||||
| -rw-r--r-- | arch/riscv/kernel/irq.c | 14 | ||||
| -rw-r--r-- | arch/riscv/kernel/main.c | 24 | ||||
| -rw-r--r-- | arch/riscv/kernel/proc.c | 2 | ||||
| -rw-r--r-- | arch/riscv/kernel/vmem.c | 10 | ||||
| -rw-r--r-- | arch/riscv/mm.txt | 6 | ||||
| -rw-r--r-- | backend_api.txt | 21 | ||||
| -rw-r--r-- | common/elf.c | 5 | ||||
| -rw-r--r-- | common/proc.c | 16 | ||||
| -rw-r--r-- | common/tcb.c | 4 | ||||
| -rw-r--r-- | include/apos/cpu.h | 4 | ||||
| -rw-r--r-- | include/apos/irq.h | 7 | ||||
| -rw-r--r-- | include/apos/lock.h | 3 | ||||
| -rw-r--r-- | include/apos/proc.h | 3 | ||||
| -rw-r--r-- | include/apos/tcb.h | 5 |
17 files changed, 122 insertions, 18 deletions
diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c index 029c855..dc9d7e9 100644 --- a/arch/riscv/init/init.c +++ b/arch/riscv/init/init.c @@ -30,9 +30,14 @@ void init_vmem() /* kernel (also sort of direct mapping) */ /* FIXME set up actually correct addressing retard */ flags |= VM_G; - for(size_t i = 256; i < 512; ++i) + for(size_t i = 256; i < 511; ++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); + csr_write(CSR_SATP, SATP_MODE_Sv39 | ((size_t)root_branch >> 12)); } diff --git a/arch/riscv/ipc.txt b/arch/riscv/ipc.txt new file mode 100644 index 0000000..21d758e --- /dev/null +++ b/arch/riscv/ipc.txt @@ -0,0 +1,7 @@ +Current idea: Have a bunch of servers that allow IPC requests. Each IPC request +to a server temporarily maps the server's address space etc. into the calling +functions address space, except for the callstack. Callstack should be a bunch +of 4K pages, so they can easily be mapped to be unreachable by deeper nested +server calls, whereas the normal stack can be mapped to higher order pages to +save a little bit of memory access latency when the client is operating +normally. diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index 34b7a32..6ae4ee7 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -1,6 +1,6 @@ #include <apos/cpu.h> -unsigned cpu_id() +id_t cpu_id() { return 0; /* VERY MUCH TEMP */ } diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c index f015411..113773a 100644 --- a/arch/riscv/kernel/irq.c +++ b/arch/riscv/kernel/irq.c @@ -1,4 +1,18 @@ +#include <apos/irq.h> +#include <csr.h> + void irq_handler() { } + +/* very simple for now */ +void enable_irq() +{ + csr_set(CSR_SSTATUS, CSR_SIE); +} + +void disable_irq() +{ + csr_clear(CSR_SSTATUS, CSR_SIE); +} diff --git a/arch/riscv/kernel/main.c b/arch/riscv/kernel/main.c index e519697..83270eb 100644 --- a/arch/riscv/kernel/main.c +++ b/arch/riscv/kernel/main.c @@ -30,7 +30,7 @@ struct pm_orders_t { static void init_dbg(void *fdt) { struct dbg_info_t dbg = dbg_from_fdt(fdt); - dbg_init(dbg.dbg_ptr, dbg.dev); + dbg_init(dbg.dbg_ptr + (-SZ_1G), dbg.dev); } #else @@ -201,8 +201,11 @@ static struct pm_orders_t init_pmem(void *fdt) 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 < 512; ++i) + 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) @@ -247,13 +250,16 @@ static void init_proc(void *fdt, struct vm_branch_t *b) t->pid = 0; t->tid = 0; threads_insert(t); - /* first page reserved to avoid issues with null pointers being legal*/ - sp_mem_init(&t->sp_r, SZ_4K, SZ_256G); + /* 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); - /* binary itself */ - size_t sz = get_init_size(fdt); - /* stack (?) */ - t->stack = alloc_uvmem(t, SZ_2M, VM_V | VM_R | VM_W | VM_U); + /* 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"); @@ -269,7 +275,7 @@ static void init_proc(void *fdt, struct vm_branch_t *b) __asm__("mv " QUOTE(reg) ", %0" :: "rK" (reg) : );\ } -void __main main(void *fdt) +void __main arch_main(void *fdt) { __va_reg(sp); __va_reg(fp); diff --git a/arch/riscv/kernel/proc.c b/arch/riscv/kernel/proc.c index 6d351bc..57ddc5b 100644 --- a/arch/riscv/kernel/proc.c +++ b/arch/riscv/kernel/proc.c @@ -5,7 +5,7 @@ void jump_to_userspace(struct tcb *t, vm_t bin, int argc, char **argv) { csr_write(CSR_SEPC, prepare_proc(t, bin)); - __asm__("mv sp, %0\n" : "=r" (t->stack) :: "memory"); + __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 e3680b3..45f6336 100644 --- a/arch/riscv/kernel/vmem.c +++ b/arch/riscv/kernel/vmem.c @@ -120,3 +120,13 @@ void unmap_vmem(struct vm_branch_t *branch, vm_t vaddr) if(pte) *pte = 0; } + +void flush_tlb(id_t cpu_id) +{ + __asm__("sfence.vma %0\n" :: "rk" (cpu_id) : "memory"); +} + +void flush_tlb_all() +{ + __asm__("sfence.vma\n" ::: "memory"); +} diff --git a/arch/riscv/mm.txt b/arch/riscv/mm.txt index 30ffc88..e5c52cb 100644 --- a/arch/riscv/mm.txt +++ b/arch/riscv/mm.txt @@ -18,6 +18,12 @@ Offset | Size | Purpose (first 256KiB page reserved for whatever, next 256KiB reserved for kernel vma, next 512KiB reserved for kernel pma?) +Sv39, final answer: + +First 255 pages are userspace (uvmem), page 255 is reserved for callstack. +Following 255 pages are reserved for kernel 'direct mapping', and the 512th page +is reserved for kernel IO. + Sv48: Offset | Size | Purpose diff --git a/backend_api.txt b/backend_api.txt new file mode 100644 index 0000000..f9bc93e --- /dev/null +++ b/backend_api.txt @@ -0,0 +1,21 @@ +Some functionality the different arch backends should support + ++ cpu_id() - return the ID of the current process executing the code, with +regular indexing (0 - MAX_CPUS), that is. + ++ map_vpage() - map one page according to the specs given. ++ stat_vpage() - get info about mapping at virtual address. ++ mod_vpage() - modify mapping at virtual address. ++ unmap_vpage() - unmap page at virtual address. + ++ flush_tlb() - flush TLB cache for running cpu. ++ flush_tlb_all() - flush all TLC caches. (note, flush_tlb is allowed to just + call flush_tlb_all if the arch doesn't support per-cpu + flushing.) ++ flush_tlb_region() - ??? maybe? + ++ enable_irq() - enable interrupts ++ disable_irq() - disable interrupts + ++ probably more stuff, just not entirely sure what parts should go where yet. ++ the backend also has to define a memory layout, of course. diff --git a/common/elf.c b/common/elf.c index c73d56c..fafef00 100644 --- a/common/elf.c +++ b/common/elf.c @@ -15,7 +15,7 @@ static void __map_exec(struct tcb *t, vm_t bin, uint8_t ei_c, vm_t phstart, size size_t vsz = program_header_prop(ei_c, runner, p_memsz); vm_t start = 0; - if(!(start = alloc_fixed_region(&t->sp_r, va, vsz, 0))) + if(!(start = alloc_fixed_region(&t->sp_r, va, vsz, &vsz))) return; /* out of memory or something */ uint8_t vflags = VM_V | VM_U; @@ -36,6 +36,9 @@ static void __map_exec(struct tcb *t, vm_t bin, uint8_t ei_c, vm_t phstart, size memcpy((void *)va, (void *)vo, vfz); /* skip while testing + * TODO: also fix, this fixes only the first region. Create new + * function? + * pm_t paddr = 0; stat_vmem(t->b_r, va, &paddr, 0, 0); mod_vmem(t->b_r, va, paddr, vflags); diff --git a/common/proc.c b/common/proc.c new file mode 100644 index 0000000..5fdf413 --- /dev/null +++ b/common/proc.c @@ -0,0 +1,16 @@ +#include <apos/proc.h> + +/* TODO: add error checking */ +vm_t setup_call_stack(struct tcb *t, vm_t start, 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) + { + offset = alloc_page(BASE_PAGE, offset); + map_vmem(t->b_r, offset, start + BASE_PAGE_SIZE * i, flags, BASE_PAGE); + } + + return start; +} diff --git a/common/tcb.c b/common/tcb.c index 8a1e95e..1547d49 100644 --- a/common/tcb.c +++ b/common/tcb.c @@ -1,4 +1,5 @@ #include <apos/tcb.h> +#include <apos/cpu.h> #include <apos/utils.h> #include <apos/sp_tree.h> @@ -64,8 +65,5 @@ struct tcb *get_tcb(id_t pid) struct tcb *cur_tcb() { - /* TODO: probably keep an array of processor ID's somewhere where each - * ID has a corresponding 'currently executing thread ID' field, and - * reutrn that. */ return __tcb_cache[cpu_id()]; } diff --git a/include/apos/cpu.h b/include/apos/cpu.h index a55fbad..81fb07e 100644 --- a/include/apos/cpu.h +++ b/include/apos/cpu.h @@ -1,7 +1,9 @@ #ifndef APOS_CPU_H #define APOS_CPU_H -unsigned cpu_id(); +#include <apos/tcb.h> + +id_t cpu_id(); /* TODO: add more cpu handling functions */ #endif /* APOS_CPU_H */ diff --git a/include/apos/irq.h b/include/apos/irq.h new file mode 100644 index 0000000..958b25f --- /dev/null +++ b/include/apos/irq.h @@ -0,0 +1,7 @@ +#ifndef APOS_IRQ_H +#define APOS_IRQ_H + +void enable_irq(); +void disable_irq(); + +#endif /* APOS_IRQ_H */ diff --git a/include/apos/lock.h b/include/apos/lock.h index b8983fa..178140b 100644 --- a/include/apos/lock.h +++ b/include/apos/lock.h @@ -2,12 +2,14 @@ #define LOCK_H #include <apos/atomic.h> +#include <apos/irq.h> typedef atomic_int spinlock_t; #include <lock.h> static inline void spin_lock(spinlock_t *lck) { + disable_irq(); do { while (atomic_load_explicit(lck, memory_order_acquire)) optional_pause(); @@ -18,6 +20,7 @@ static inline void spin_lock(spinlock_t *lck) static inline void spin_unlock(spinlock_t *lck) { atomic_store_explicit(lck, 0, memory_order_release); + enable_irq(); } #endif /* LOCK_H */ diff --git a/include/apos/proc.h b/include/apos/proc.h index 8071dda..6f272b1 100644 --- a/include/apos/proc.h +++ b/include/apos/proc.h @@ -2,6 +2,9 @@ #define APOS_PROC_H #include <apos/tcb.h> +#include <apos/vmem.h> + 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); #endif /* APOS_PROC_H */ diff --git a/include/apos/tcb.h b/include/apos/tcb.h index 714d750..1d85e8b 100644 --- a/include/apos/tcb.h +++ b/include/apos/tcb.h @@ -26,7 +26,10 @@ struct tcb { id_t tid; vm_t callback; - vm_t stack; + vm_t proc_stack; + vm_t call_stack; + + vm_t entry; struct vm_branch_t *b_r; }; |
