aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv/kernel/vmem.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2021-12-29 23:23:36 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2021-12-29 23:53:06 +0200
commit4f4d9fdc89c27aa3346467a24b621954f4564d3b (patch)
treec4ba4fb583a43b8fb27730b4cdb9b4b1395da91c /arch/riscv/kernel/vmem.c
parent4e5595a089c815febd7a0d42ab62940bf13f73ac (diff)
downloadkmi-4f4d9fdc89c27aa3346467a24b621954f4564d3b.tar.gz
kmi-4f4d9fdc89c27aa3346467a24b621954f4564d3b.zip
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
Diffstat (limited to 'arch/riscv/kernel/vmem.c')
-rw-r--r--arch/riscv/kernel/vmem.c92
1 files changed, 71 insertions, 21 deletions
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 <apos/vmem.h>
#include <apos/mem.h>
#include <apos/debug.h>
+#include <apos/cpu.h>
#include <pages.h>
#include <vmem.h>
+#include <csr.h>
#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