diff --git a/libcpu/aarch64/common/mmu.h b/libcpu/aarch64/common/mmu.h index 875f925463..b58e58e929 100644 --- a/libcpu/aarch64/common/mmu.h +++ b/libcpu/aarch64/common/mmu.h @@ -30,14 +30,12 @@ struct mem_desc struct rt_varea varea; }; -enum rt_hw_mmu_prot_t { - RT_HW_MMU_PROT_READ, - RT_HW_MMU_PROT_WRITE, - RT_HW_MMU_PROT_EXECUTE, - RT_HW_MMU_PROT_KERNEL, - RT_HW_MMU_PROT_USER, - RT_HW_MMU_PROT_CACHE, -}; +#define RT_HW_MMU_PROT_READ 1 +#define RT_HW_MMU_PROT_WRITE 2 +#define RT_HW_MMU_PROT_EXECUTE 4 +#define RT_HW_MMU_PROT_KERNEL 8 +#define RT_HW_MMU_PROT_USER 16 +#define RT_HW_MMU_PROT_CACHE 32 #define MMU_AF_SHIFT 10 #define MMU_SHARED_SHIFT 8 @@ -142,7 +140,7 @@ static inline void *rt_hw_mmu_kernel_v2p(void *v_addr) * @param prot protect that will be added * @return size_t returned attribution */ -rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, rt_base_t prot) { switch (prot) { @@ -163,7 +161,7 @@ rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, enum rt_hw_mmu_prot_t prot * @param prot protect that will be removed * @return size_t returned attribution */ -rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, rt_base_t prot) { switch (prot) { @@ -185,7 +183,7 @@ rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, enum rt_hw_mmu_prot_t prot) * @param prot protect that will be test * @return rt_bool_t RT_TRUE if the prot is allowed, otherwise RT_FALSE */ -rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, rt_base_t prot) { rt_bool_t rc; switch (prot) diff --git a/libcpu/arm/cortex-a/mmu.h b/libcpu/arm/cortex-a/mmu.h index bd016b835d..8712a0f489 100644 --- a/libcpu/arm/cortex-a/mmu.h +++ b/libcpu/arm/cortex-a/mmu.h @@ -101,14 +101,12 @@ struct mem_desc */ #define ARCH_MAP_FAILED ((void *)-1) -enum rt_hw_mmu_prot_t { - RT_HW_MMU_PROT_READ, - RT_HW_MMU_PROT_WRITE, - RT_HW_MMU_PROT_EXECUTE, - RT_HW_MMU_PROT_KERNEL, - RT_HW_MMU_PROT_USER, - RT_HW_MMU_PROT_CACHE, -}; +#define RT_HW_MMU_PROT_READ 1 +#define RT_HW_MMU_PROT_WRITE 2 +#define RT_HW_MMU_PROT_EXECUTE 4 +#define RT_HW_MMU_PROT_KERNEL 8 +#define RT_HW_MMU_PROT_USER 16 +#define RT_HW_MMU_PROT_CACHE 32 int rt_hw_mmu_ioremap_init(struct rt_aspace *aspace, void *v_address, size_t size); void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size); @@ -142,7 +140,7 @@ void rt_hw_mmu_pgtbl_delete(void *pgtbl); * @param prot protect that will be removed * @return size_t returned attribution */ -rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, rt_base_t prot) { switch (prot) { @@ -176,7 +174,7 @@ rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, enum rt_hw_mmu_prot_t prot) * @param prot protect that will be added * @return size_t returned attribution */ -rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, rt_base_t prot) { switch (prot) { @@ -199,7 +197,7 @@ rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, enum rt_hw_mmu_prot_t prot * @param prot protect that will be test * @return rt_bool_t RT_TRUE if the prot is allowed, otherwise RT_FALSE */ -rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, rt_base_t prot) { rt_bool_t rc = 0; switch (prot) diff --git a/libcpu/risc-v/t-head/c906/riscv_mmu.h b/libcpu/risc-v/t-head/c906/riscv_mmu.h index dfb5a8ee48..406ed9a562 100644 --- a/libcpu/risc-v/t-head/c906/riscv_mmu.h +++ b/libcpu/risc-v/t-head/c906/riscv_mmu.h @@ -111,14 +111,12 @@ void mmu_set_pagetable(rt_ubase_t addr); void mmu_enable_user_page_access(); void mmu_disable_user_page_access(); -enum rt_hw_mmu_prot_t { - RT_HW_MMU_PROT_READ, - RT_HW_MMU_PROT_WRITE, - RT_HW_MMU_PROT_EXECUTE, - RT_HW_MMU_PROT_KERNEL, - RT_HW_MMU_PROT_USER, - RT_HW_MMU_PROT_CACHE, -}; +#define RT_HW_MMU_PROT_READ 1 +#define RT_HW_MMU_PROT_WRITE 2 +#define RT_HW_MMU_PROT_EXECUTE 4 +#define RT_HW_MMU_PROT_KERNEL 8 +#define RT_HW_MMU_PROT_USER 16 +#define RT_HW_MMU_PROT_CACHE 32 /** * @brief Remove permission from attribution @@ -127,7 +125,7 @@ enum rt_hw_mmu_prot_t { * @param prot protect that will be removed * @return size_t returned attribution */ -rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, rt_base_t prot) { switch (prot) { @@ -146,7 +144,7 @@ rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, enum rt_hw_mmu_prot_t prot) * @param prot protect that will be added * @return size_t returned attribution */ -rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, rt_base_t prot) { switch (prot) { @@ -165,7 +163,7 @@ rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, enum rt_hw_mmu_prot_t prot * @param prot protect that will be test * @return rt_bool_t RT_TRUE if the prot is allowed, otherwise RT_FALSE */ -rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, rt_base_t prot) { rt_bool_t rc = 0; switch (prot) diff --git a/libcpu/risc-v/t-head/c906/trap.c b/libcpu/risc-v/t-head/c906/trap.c index b0470dc6e8..ac04fdbfa4 100644 --- a/libcpu/risc-v/t-head/c906/trap.c +++ b/libcpu/risc-v/t-head/c906/trap.c @@ -204,6 +204,7 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw if (fault_op) { + rt_base_t saved_stat; lwp = lwp_self(); struct rt_aspace_fault_msg msg = { .fault_op = fault_op, @@ -211,10 +212,13 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw .fault_vaddr = (void *)stval, }; + __asm__ volatile ("csrrsi %0, sstatus, 2":"=r"(saved_stat)); if (lwp && rt_aspace_fault_try_fix(lwp->aspace, &msg)) { + __asm__ volatile ("csrw sstatus, %0"::"r"(saved_stat)); return; } + __asm__ volatile ("csrw sstatus, %0"::"r"(saved_stat)); } LOG_E("[FATAL ERROR] Exception %ld:%s\n", id, get_exception_msg(id)); LOG_E("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc); diff --git a/libcpu/risc-v/virt64/riscv_mmu.h b/libcpu/risc-v/virt64/riscv_mmu.h index a56492dcab..2d32ec0e48 100644 --- a/libcpu/risc-v/virt64/riscv_mmu.h +++ b/libcpu/risc-v/virt64/riscv_mmu.h @@ -94,14 +94,12 @@ void mmu_set_pagetable(rt_ubase_t addr); void mmu_enable_user_page_access(); void mmu_disable_user_page_access(); -enum rt_hw_mmu_prot_t { - RT_HW_MMU_PROT_READ, - RT_HW_MMU_PROT_WRITE, - RT_HW_MMU_PROT_EXECUTE, - RT_HW_MMU_PROT_KERNEL, - RT_HW_MMU_PROT_USER, - RT_HW_MMU_PROT_CACHE, -}; +#define RT_HW_MMU_PROT_READ 1 +#define RT_HW_MMU_PROT_WRITE 2 +#define RT_HW_MMU_PROT_EXECUTE 4 +#define RT_HW_MMU_PROT_KERNEL 8 +#define RT_HW_MMU_PROT_USER 16 +#define RT_HW_MMU_PROT_CACHE 32 /** * @brief Remove permission from attribution @@ -110,13 +108,14 @@ enum rt_hw_mmu_prot_t { * @param prot protect that will be removed * @return size_t returned attribution */ -rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, rt_base_t prot) { switch (prot) { /* remove write permission for user */ case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER: attr &= ~PTE_W; + break; default: RT_ASSERT(0); } @@ -130,13 +129,14 @@ rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, enum rt_hw_mmu_prot_t prot) * @param prot protect that will be added * @return size_t returned attribution */ -rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, rt_base_t prot) { switch (prot) { /* add write permission for user */ case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER: attr |= PTE_W; + break; default: RT_ASSERT(0); } @@ -150,7 +150,7 @@ rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, enum rt_hw_mmu_prot_t prot * @param prot protect that will be test * @return rt_bool_t RT_TRUE if the prot is allowed, otherwise RT_FALSE */ -rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, enum rt_hw_mmu_prot_t prot) +rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, rt_base_t prot) { rt_bool_t rc = 0; switch (prot) @@ -158,6 +158,7 @@ rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, enum rt_hw_mmu_prot_t /* test write permission for user */ case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER: rc = !!(attr & PTE_W); + break; default: RT_ASSERT(0); } diff --git a/libcpu/risc-v/virt64/trap.c b/libcpu/risc-v/virt64/trap.c index 51531d9ad0..5a7d2bc4c5 100644 --- a/libcpu/risc-v/virt64/trap.c +++ b/libcpu/risc-v/virt64/trap.c @@ -201,6 +201,7 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw if (fault_op) { + rt_base_t saved_stat; lwp = lwp_self(); struct rt_aspace_fault_msg msg = { .fault_op = fault_op, @@ -208,10 +209,13 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw .fault_vaddr = (void *)stval, }; + __asm__ volatile ("csrrsi %0, sstatus, 2":"=r"(saved_stat)); if (lwp && rt_aspace_fault_try_fix(lwp->aspace, &msg)) { + __asm__ volatile ("csrw sstatus, %0"::"r"(saved_stat)); return; } + __asm__ volatile ("csrw sstatus, %0"::"r"(saved_stat)); } LOG_E("[FATAL ERROR] Exception %ld:%s\n", id, get_exception_msg(id)); LOG_E("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc);