aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2021-12-29 18:47:16 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2021-12-29 18:49:28 +0200
commit4e5595a089c815febd7a0d42ab62940bf13f73ac (patch)
tree322f35d9315e9966de8a66052811858df0144085
parenta12e50e5a7dae52ed8bd5a24cc6576371e20985b (diff)
downloadkmi-4e5595a089c815febd7a0d42ab62940bf13f73ac.tar.gz
kmi-4e5595a089c815febd7a0d42ab62940bf13f73ac.zip
Preparations for refactoring
-rw-r--r--arch/riscv/init/init.c7
-rw-r--r--arch/riscv/ipc.txt7
-rw-r--r--arch/riscv/kernel/cpu.c2
-rw-r--r--arch/riscv/kernel/irq.c14
-rw-r--r--arch/riscv/kernel/main.c24
-rw-r--r--arch/riscv/kernel/proc.c2
-rw-r--r--arch/riscv/kernel/vmem.c10
-rw-r--r--arch/riscv/mm.txt6
-rw-r--r--backend_api.txt21
-rw-r--r--common/elf.c5
-rw-r--r--common/proc.c16
-rw-r--r--common/tcb.c4
-rw-r--r--include/apos/cpu.h4
-rw-r--r--include/apos/irq.h7
-rw-r--r--include/apos/lock.h3
-rw-r--r--include/apos/proc.h3
-rw-r--r--include/apos/tcb.h5
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;
};