aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-06-11 19:08:18 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-06-11 19:08:18 +0300
commit426da8be0db33405b0cfe53108b65040623972f0 (patch)
treec1776cf14695d717a92d5d46d7a07c978a0e3618
parentde99380f12f8e2fe4acf7734db0e1e37a356c45f (diff)
downloadkmi-426da8be0db33405b0cfe53108b65040623972f0.tar.gz
kmi-426da8be0db33405b0cfe53108b65040623972f0.zip
continue documentation
-rw-r--r--arch/riscv64/kernel/cpu.c10
-rw-r--r--arch/riscv64/kernel/entry.S11
-rw-r--r--arch/riscv64/kernel/proc.c6
-rw-r--r--common/proc.c2
-rw-r--r--common/tcb.c7
-rw-r--r--common/uapi/dispatch.c1
-rw-r--r--include/apos/tcb.h2
-rw-r--r--include/apos/vmem.h14
-rw-r--r--include/arch/arch.h9
-rw-r--r--include/arch/proc.h39
-rw-r--r--include/arch/vmem.h107
-rw-r--r--lib/ubsan.c4
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, &copy_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);