diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-06-11 19:08:18 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-06-11 19:08:18 +0300 |
| commit | 426da8be0db33405b0cfe53108b65040623972f0 (patch) | |
| tree | c1776cf14695d717a92d5d46d7a07c978a0e3618 | |
| parent | de99380f12f8e2fe4acf7734db0e1e37a356c45f (diff) | |
| download | kmi-426da8be0db33405b0cfe53108b65040623972f0.tar.gz kmi-426da8be0db33405b0cfe53108b65040623972f0.zip | |
continue documentation
| -rw-r--r-- | arch/riscv64/kernel/cpu.c | 10 | ||||
| -rw-r--r-- | arch/riscv64/kernel/entry.S | 11 | ||||
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 6 | ||||
| -rw-r--r-- | common/proc.c | 2 | ||||
| -rw-r--r-- | common/tcb.c | 7 | ||||
| -rw-r--r-- | common/uapi/dispatch.c | 1 | ||||
| -rw-r--r-- | include/apos/tcb.h | 2 | ||||
| -rw-r--r-- | include/apos/vmem.h | 14 | ||||
| -rw-r--r-- | include/arch/arch.h | 9 | ||||
| -rw-r--r-- | include/arch/proc.h | 39 | ||||
| -rw-r--r-- | include/arch/vmem.h | 107 | ||||
| -rw-r--r-- | lib/ubsan.c | 4 |
12 files changed, 185 insertions, 27 deletions
diff --git a/arch/riscv64/kernel/cpu.c b/arch/riscv64/kernel/cpu.c index 0558040..91b39b6 100644 --- a/arch/riscv64/kernel/cpu.c +++ b/arch/riscv64/kernel/cpu.c @@ -3,9 +3,17 @@ * riscv64 implementation of cpu handling. */ +#include <apos/tcb.h> #include <arch/cpu.h> id_t cpu_id() { - return 0; /* VERY MUCH TEMP */ + /* yes, slightly weird situation where cur_tcb() call cpu_id() which + * gets the current tcb and returns the cpu id in the tcb, so that that + * id can be used to get the tcb we want. I might try to work out + * something slightly smarter, although this is likely not going to have + * basically any kind of importance for perfomance. */ + struct tcb *t; + __asm__ volatile ("mv %0, tp\n" : "=r" (t) ::); + return t->cpu_id; } diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S index a5427a7..ee7b10f 100644 --- a/arch/riscv64/kernel/entry.S +++ b/arch/riscv64/kernel/entry.S @@ -25,8 +25,8 @@ _save_context: sr sp, offsetof_sp(tp) mv sp, tp - /* set scratch to 0 and move thread pointer back */ - csrrw tp, CSR_SSCRATCH, x0 + /* move thread pointer back */ + csrrw tp, CSR_SSCRATCH, tp /* save registers */ sr ra, offsetof_ra(sp) @@ -60,6 +60,10 @@ _save_context: sr t5, offsetof_t5(sp) sr t6, offsetof_t6(sp) + /* get current tcb into tp and set scratch to 0 so we can figure out if + * exception occured in kernel or userspace */ + csrrw tp, CSR_SSCRATCH, x0 + /* load supervisor cause */ csrr s4, CSR_SCAUSE /* interrupts fall through, exceptions jump */ @@ -85,9 +89,6 @@ handle_syscall: /* TODO: is a whole function call necessary? */ mv s0, a0 mv s1, a1 - /* get current tcb */ - call cur_tcb - mv tp, a0 /* get associated kernel stack */ mv sp, tp addi sp, sp, -sizeof_registers diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c index 09d694f..a85ae6f 100644 --- a/arch/riscv64/kernel/proc.c +++ b/arch/riscv64/kernel/proc.c @@ -33,15 +33,15 @@ stat_t set_ipc(struct tcb *t, id_t pid, id_t tid) return OK; } -stat_t set_thread(struct tcb *t, vm_t stack) +stat_t set_thread(struct tcb *t) { /* get location of registers in memory */ /** \todo check alignment, should be fine but just to be sure */ struct riscv_regs *r = (struct riscv_regs *)(--t); /* insert important values into register slots */ - r->sp = (long)stack; - r->tp = (long)t; + r->sp = (long)t->thread_stack_top; + r->tp = (long)t->thread_storage; return OK; } diff --git a/common/proc.c b/common/proc.c index 9d74a86..001e127 100644 --- a/common/proc.c +++ b/common/proc.c @@ -18,7 +18,7 @@ stat_t prepare_proc(struct tcb *t, vm_t bin, vm_t interp) return ERR_INVAL; alloc_stacks(t); - set_thread(t, t->thread_stack_top); + set_thread(t); set_return(entry); return OK; } diff --git a/common/tcb.c b/common/tcb.c index 3f644c1..a31ac87 100644 --- a/common/tcb.c +++ b/common/tcb.c @@ -129,9 +129,9 @@ struct tcb *create_thread(struct tcb *p) return t; } -static stat_t __clone_proc(struct tcb *p, struct tcb *n) +static stat_t __copy_proc(struct tcb *p, struct tcb *n) { - /** \todo clone memory regions, and mark them MR_COW, as well as copy + /** \todo Copy memory regions, and mark them MR_COW, as well as copy * bm_branch tree but with VM_W off, also at some point write COW * handler */ return OK; @@ -147,7 +147,7 @@ struct tcb *create_proc(struct tcb *p) return 0; if (likely(p)) - __clone_proc(p, n); /* we have a parent thread */ + __copy_proc(p, n); /* we have a parent thread */ return n; } @@ -239,6 +239,7 @@ struct tcb *cur_proc() void use_tcb(struct tcb *t) { + t->cpu_id = cpu_id(); cpu_tcb[cpu_id()] = t; } diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c index 35c39c9..848fc3f 100644 --- a/common/uapi/dispatch.c +++ b/common/uapi/dispatch.c @@ -48,6 +48,7 @@ SYSCALL_DEFINE0(noop)(){ struct sys_ret syscall_dispatch(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, sys_arg_t c, sys_arg_t d) { + /** \todo Add check that syscall is not larger than table */ sys_t call = syscall_table[syscall]; if (!call) diff --git a/include/apos/tcb.h b/include/apos/tcb.h index 18cf3ad..b43d5b4 100644 --- a/include/apos/tcb.h +++ b/include/apos/tcb.h @@ -252,6 +252,8 @@ struct tcb *cur_proc(); /** * Set \c t as current \ref tcb. * + * Also updates the current cpu id of the tcb. + * * @param t Thread to mark as current. */ void use_tcb(struct tcb *t); diff --git a/include/apos/vmem.h b/include/apos/vmem.h index c02d968..8388327 100644 --- a/include/apos/vmem.h +++ b/include/apos/vmem.h @@ -148,9 +148,9 @@ stat_t alloc_shared_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order, void *data); /** - * User virtual memory COW cloning worker callback for \ref map_fill_region(). + * User virtual memory COW copying worker callback for \ref map_fill_region(). * - * Currently unused, but intention is to set up COW clone of some other virtual + * Currently unused, but intention is to set up COW copy of some other virtual * memory region, likely passed through \c data? * * @param b Virtual memory to work in. @@ -164,8 +164,8 @@ stat_t alloc_shared_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, * \see alloc_uvmem_wraper(). * \todo Implement. */ -stat_t clone_allocd_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order order, void *data); +stat_t copy_allocd_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, + vmflags_t flags, enum mm_order order, void *data); /** * User virtual memory freeing worker callback for \ref map_fill_region(). @@ -211,7 +211,7 @@ stat_t free_uvmem_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, map_fill_region(b, &alloc_shared_wrapper, 0, start, bytes, flags, data) /** - * Convenience wrapper for \ref map_fill_region() when COW cloning a region. + * Convenience wrapper for \ref map_fill_region() when COW copying a region. * * @param b Virtual memory to work in. * @param start Start of virtual memory region to map. @@ -220,8 +220,8 @@ stat_t free_uvmem_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, * @param data Pointer to \c vmem to clone. * @return \see map_fill_region(). */ -#define clone_allocd_region(b, start, bytes, flags, data) \ - map_fill_region(b, &clone_allocd_wrapper, 0, start, bytes, flags, data) +#define copy_allocd_region(b, start, bytes, flags, data) \ + map_fill_region(b, ©_allocd_wrapper, 0, start, bytes, flags, data) /** * Convenience wrapper for \ref map_fill_region() when freeing region. diff --git a/include/arch/arch.h b/include/arch/arch.h index c19b039..c4f2d28 100644 --- a/include/arch/arch.h +++ b/include/arch/arch.h @@ -15,6 +15,15 @@ #include "../../arch/riscv32/include/arch.h" #endif +/** + * Setup arch specific stuff. + * + * See arch documentation if there is any. + * + * @param fdt Global FDT. + * @return \ref OK if boot can continue, error otherwise. + * \todo Check errors. + */ stat_t setup_arch(void *fdt); #endif /* APOS_ARCH_H */ diff --git a/include/arch/proc.h b/include/arch/proc.h index 7c6ad5b..e27fbf6 100644 --- a/include/arch/proc.h +++ b/include/arch/proc.h @@ -12,10 +12,45 @@ #include "../../arch/riscv32/include/proc.h" #endif +/** + * Set address to jump to when returning to userspace. + * + * @param r Address to jump to. + * @return \ref OK. + */ stat_t set_return(vm_t r); + +/** + * Attach IPC data to load into argument registers when returning to userspace. + * + * @param t Thread that will run after return. + * @param pid Process ID. + * @param tid Thread ID. + * @return \ref OK. + */ stat_t set_ipc(struct tcb *t, id_t pid, id_t tid); -/*\todo: should this be in arch/tcb.h or something? */ -stat_t set_thread(struct tcb *t, vm_t stack); + +/** \todo Should these be in arch/tcb.h or something? */ +/** \todo Should these be void? */ + +/** + * Attach thread stack and thread local storage when returning to userspace. + * + * Their info should already be stored in \c t, and this function just + * actualizes the information. + * + * @param t Thread that will run after return. + * @return \ref OK. + */ +stat_t set_thread(struct tcb *t); + +/** + * Run \c init program. + * + * @param t Thread that \c init is attached to. + * @param fdt Pointer to FDT that is passed to \c init. + * @return \ref ERR_ADDR, as it shouldn't return- + */ stat_t run_init(struct tcb *t, void *fdt); #endif /* APOS_ARCH_PROC_H */ diff --git a/include/arch/vmem.h b/include/arch/vmem.h index b39d905..dcfe7fd 100644 --- a/include/arch/vmem.h +++ b/include/arch/vmem.h @@ -13,28 +13,129 @@ #include "../../arch/riscv32/include/vmem.h" #endif +/** + * Map one virtual page to physical page. + * + * If \ref INFO_SEFF is returned, the caller is responsible for synchronizing + * all other threads that are in the same virtual address space. + * + * The caller is responsible for checking that both virtual and physical page of + * the correct order are available. + * + * @param branch Virtual memory to work in. + * @param paddr Physical address of page. + * @param vaddr Virtual address to map page to. + * @param flags Page flags. + * @param order Order of page. + * @return \ref INFO_SEFF when top level table modified, \ref OK otherwise. + */ stat_t map_vpage(struct vmem *branch, pm_t paddr, vm_t vaddr, vmflags_t flags, enum mm_order order); +/** + * Unmap one page. + * + * @param branch Virtual memory to work in. + * @param vaddr Virtual address of page to unmap. + * @return \ref OK when succesful, \ref ERR_NF if no page at \c vaddr could be + * found. + */ stat_t unmap_vpage(struct vmem *branch, vm_t vaddr); +/** + * Modify page mapping physical address and flags. + * + * Note that changing the order of a page is not supported, to do that unmap and + * remap a page. + * + * @param branch Virtual memory to work in. + * @param vaddr Virtual address of map to modify. + * @param paddr Physical address to map to. + * @param flags Flags to set. + * @return \ref ERR_NF if no virtual page is found at \c vaddr. + * \ref INFO_SEFF if modding takes place in top page table but otherwise + * succesful, \ref OK otherwise. + */ stat_t mod_vpage(struct vmem *branch, vm_t vaddr, pm_t paddr, vmflags_t flags); + +/** + * Get information about physical page. + * + * @param branch Virtual memory to work in. + * @param vaddr Virtual address of map to get parameters of. + * @param paddr Where to write physical address of the page. + * @param order Where to write the order of the page. + * @param flags Where to write the physical mapping flags of the page. + * @return \ref ERR_NF when no page is found at \c vaddr, \ref OK otherwise. + */ stat_t stat_vpage(struct vmem *branch, vm_t vaddr, pm_t *paddr, enum mm_order *order, vmflags_t *flags); +/** Flush tlb of current processor. */ void flush_tlb(); + +/** Flush tlbs of all processors. */ void flush_tlb_all(); +/** \todo Add flushing of only some region in memory? */ + +/** + * Populate virtual memory with kernel virtual address info. + * + * @param b Virtual memory to work in. + * @return \ref OK. + */ stat_t populate_kvmem(struct vmem *b); + +/** + * Initialize arch virtual memory and return boot virtual memory. + * + * @param fdt Global FDT pointer. + * @return Pointer to new boot virtual memory when succesful, \c NULL otherwise. + */ struct vmem *init_vmem(void *fdt); #if defined(DEBUG) +/** + * Map and setup serial port. + * + * @param b Virtual memory to work in. + * @param paddr Physical address of serial port. + * @return Virtual address of serial port. + */ vm_t setup_kernel_io(struct vmem *b, vm_t paddr); #endif +/** + * Create new virtual memory space. + * + * @return Pointer to virtual memory root when succesful, \c NULL otherwise. + */ struct vmem *create_vmem(); -stat_t use_vmem(struct vmem *); -stat_t destroy_vmem(struct vmem *); -stat_t clone_uvmem(struct vmem *, struct vmem *); + +/** + * Jump into virtual memory context. + * + * @param b Virtual memory to jump into. + * @return \ref OK. + */ +stat_t use_vmem(struct vmem *b); + +/** + * Destroy virtual memory space. + * + * @param b Virtual memory to destroy. + * @return \ref OK. + */ +stat_t destroy_vmem(struct vmem *b); + +/** + * Raw clone user virtual memory. + * + * @param r Source virtual memory of clone. + * @param b Destination virtual memory of clone. + * @return \ref OK. + */ +stat_t clone_uvmem(struct vmem *r, struct vmem *b); #endif /* APOS_ARCH_PAGES_H */ diff --git a/lib/ubsan.c b/lib/ubsan.c index bbefdad..f296b7a 100644 --- a/lib/ubsan.c +++ b/lib/ubsan.c @@ -151,8 +151,8 @@ struct invalid_builtin_data { * @param message Message to be printed. * @param loc Location information. */ -static void print_location(const char *message, - struct source_location loc) +inline static void print_location(const char *message, + const struct source_location loc) { bug("ubsan: %s at file %s, line %ju, column %ju\n", message, loc.file, (uintmax_t)loc.line, (uintmax_t)loc.column); |
