From b8c77c57587116fe17029919505725e33e884a50 Mon Sep 17 00:00:00 2001 From: songyanguang <345810377@qq.com> Date: Thu, 16 Jan 2025 16:16:03 +0800 Subject: [PATCH] S-mode to access the memory of U-mode in the riscv --- .../hardkernel/intr/riscv/rv64gc/trampoline.S | 10 ++++++++ .../softkernel/memory/pagetable_riscv.c | 23 ++++++++++++++++++- .../XiZi_AIoT/softkernel/task/memspace.c | 4 ++++ Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 9 ++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/riscv/rv64gc/trampoline.S b/Ubiquitous/XiZi_AIoT/hardkernel/intr/riscv/rv64gc/trampoline.S index c8c2ce3fa..44fac5f1e 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/riscv/rv64gc/trampoline.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/riscv/rv64gc/trampoline.S @@ -168,6 +168,12 @@ handle_syscall: /* Slow paths for ptrace. */ handle_syscall_trace_enter: + csrr s0, satp + la a0, riscv_kernel_satp + ld a0, 0(a0) + csrw satp, a0 + sfence.vma + move a0, sp //call do_syscall_trace_enter call syscall_arch_handler @@ -185,6 +191,10 @@ handle_syscall_trace_enter: handle_syscall_trace_exit: move a0, sp //call do_syscall_trace_exit + + csrw satp, s0 + sfence.vma + j ret_from_exception diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c index f07a67660..bfc173b36 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable_riscv.c @@ -127,6 +127,8 @@ static bool _unmap_pages(uintptr_t* pgdir, uintptr_t vaddr, int len) /// @return static bool _map_user_pages(struct MemSpace* pmemspace, uintptr_t vaddr, uintptr_t paddr, int len, bool is_dev) { + bool ret; + if (len < 0) { return false; } @@ -143,7 +145,26 @@ static bool _map_user_pages(struct MemSpace* pmemspace, uintptr_t vaddr, uintptr _p_pgtbl_mmu_access->MmuUsrDevPteAttr(&mem_attr); } - return _map_pages(pmemspace->pgdir.pd_addr, vaddr, paddr, (intptr_t)len, mem_attr); + ret = _map_pages(pmemspace->pgdir.pd_addr, vaddr, paddr, (intptr_t)len, mem_attr); + if (ret == false) { + ERROR("mapping _map_pages fail.\n"); + return false; + } + + // In order for the S-mode to access the memory of the U-mode, in the riscv architecture. + if (LIKELY(!is_dev)) { + _p_pgtbl_mmu_access->MmuKernPteAttr(&mem_attr); + } else { + _p_pgtbl_mmu_access->MmuDevPteAttr(&mem_attr); + } + + ret = _map_pages(pmemspace->pgdir_riscv.pd_addr, vaddr, paddr, (intptr_t)len, mem_attr); + if (ret == false) { + ERROR("mapping _map_pages riscv fail.\n"); + return false; + } + + return true; } /// assume that a user pagedir is allocated from [0, size) diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/memspace.c b/Ubiquitous/XiZi_AIoT/softkernel/task/memspace.c index 3fce45d05..8c906d1bd 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/memspace.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/memspace.c @@ -120,6 +120,10 @@ uintptr_t* load_memspace(struct MemSpace* pmemspace, char* img_start) } /* copy kernel pagetable so that interrupt and syscall wont corrupt */ memcpy(pmemspace->pgdir.pd_addr, kern_pgdir.pd_addr, TOPLEVLE_PAGEDIR_SIZE); +#ifdef __riscv + xizi_pager.new_pgdir(&pmemspace->pgdir_riscv); + memcpy(pmemspace->pgdir_riscv.pd_addr, kern_pgdir.pd_addr, TOPLEVLE_PAGEDIR_SIZE); +#endif // read elf file by (header, section) uintptr_t load_size = 0; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 06354eb99..527752d00 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -288,6 +288,9 @@ static void task_state_set_running(struct Thread* task) doubleListAddOnHead(&task->node, &xizi_task_manager.task_running_list_head); } +#ifdef __riscv +uintptr_t riscv_kernel_satp = 0; +#endif struct Thread* next_task_emergency = NULL; extern void context_switch(struct context**, struct context*); static void _scheduler(struct SchedulerRightGroup right_group) @@ -318,8 +321,14 @@ static void _scheduler(struct SchedulerRightGroup right_group) /* run the chosen task */ task_state_set_running(next_task); cpu->task = next_task; + +#ifdef __riscv + riscv_kernel_satp = PFN_DOWN((uintptr_t)V2P(next_task->memspace->pgdir_riscv.pd_addr)) | SATP_MODE; +#endif + assert(next_task->memspace->pgdir.pd_addr != NULL); p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->memspace->pgdir.pd_addr)); + context_switch(&cpu->scheduler, next_task->thread_context.context); assert(next_task->state != RUNNING); }