mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-21 18:57:16 +08:00
Sync dfs lwp (#8123)
This commit is contained in:
@@ -13,10 +13,6 @@
|
||||
#include <rtthread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef RT_CPUS_NR
|
||||
#define RT_CPUS_NR 1
|
||||
#endif /* RT_CPUS_NR */
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
struct cpu_ops_t
|
||||
{
|
||||
|
||||
@@ -54,6 +54,10 @@ static void data_abort(unsigned long far, unsigned long iss)
|
||||
rt_kprintf("Translation fault, third level\n");
|
||||
break;
|
||||
|
||||
case 0b001000:
|
||||
rt_kprintf("Access flag fault, zeroth level\n");
|
||||
break;
|
||||
|
||||
case 0b001001:
|
||||
rt_kprintf("Access flag fault, first level\n");
|
||||
break;
|
||||
@@ -66,6 +70,10 @@ static void data_abort(unsigned long far, unsigned long iss)
|
||||
rt_kprintf("Access flag fault, third level\n");
|
||||
break;
|
||||
|
||||
case 0b001100:
|
||||
rt_kprintf("Permission fault, zeroth level\n");
|
||||
break;
|
||||
|
||||
case 0b001101:
|
||||
rt_kprintf("Permission fault, first level\n");
|
||||
break;
|
||||
@@ -148,7 +156,7 @@ static void data_abort(unsigned long far, unsigned long iss)
|
||||
}
|
||||
}
|
||||
|
||||
void process_exception(unsigned long esr, unsigned long epc)
|
||||
void print_exception(unsigned long esr, unsigned long epc)
|
||||
{
|
||||
rt_uint8_t ec;
|
||||
rt_uint32_t iss;
|
||||
|
||||
@@ -204,7 +204,7 @@ static int _kernel_map_2M(unsigned long *lv0_tbl, void *vaddr, void *paddr, unsi
|
||||
{
|
||||
return MMU_MAP_ERROR_VANOTALIGN;
|
||||
}
|
||||
if (pa & ARCH_SECTION_MASK)
|
||||
if (pa & ARCH_PAGE_MASK)
|
||||
{
|
||||
return MMU_MAP_ERROR_PANOTALIGN;
|
||||
}
|
||||
@@ -556,7 +556,7 @@ static int _map_single_page_2M(unsigned long *lv0_tbl, unsigned long va,
|
||||
{
|
||||
return MMU_MAP_ERROR_VANOTALIGN;
|
||||
}
|
||||
if (pa & ARCH_SECTION_MASK)
|
||||
if (pa & ARCH_PAGE_MASK)
|
||||
{
|
||||
return MMU_MAP_ERROR_PANOTALIGN;
|
||||
}
|
||||
@@ -803,8 +803,8 @@ void rt_hw_mem_setup_early(unsigned long *tbl0, unsigned long *tbl1,
|
||||
#ifdef RT_USING_SMART
|
||||
unsigned long va = KERNEL_VADDR_START;
|
||||
#else
|
||||
extern unsigned char _start;
|
||||
unsigned long va = (unsigned long) &_start;
|
||||
extern unsigned char __start;
|
||||
unsigned long va = (unsigned long) &__start;
|
||||
va = RT_ALIGN_DOWN(va, 0x200000);
|
||||
#endif
|
||||
|
||||
@@ -826,3 +826,22 @@ void rt_hw_mem_setup_early(unsigned long *tbl0, unsigned long *tbl1,
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
void *rt_hw_mmu_pgtbl_create(void)
|
||||
{
|
||||
size_t *mmu_table;
|
||||
mmu_table = (size_t *)rt_pages_alloc_ext(0, PAGE_ANY_AVAILABLE);
|
||||
if (!mmu_table)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
memset(mmu_table, 0, ARCH_PAGE_SIZE);
|
||||
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, ARCH_PAGE_SIZE);
|
||||
return mmu_table;
|
||||
}
|
||||
|
||||
void rt_hw_mmu_pgtbl_delete(void *pgtbl)
|
||||
{
|
||||
rt_pages_free(pgtbl, 0);
|
||||
}
|
||||
|
||||
+96
-12
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-05-12 RT-Thread the first version
|
||||
* 2023-08-15 Shell Support more mapping attribution
|
||||
*/
|
||||
#ifndef __MMU_H_
|
||||
#define __MMU_H_
|
||||
@@ -29,27 +30,42 @@ 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 MMU_AF_SHIFT 10
|
||||
#define MMU_SHARED_SHIFT 8
|
||||
#define MMU_AP_SHIFT 6
|
||||
#define MMU_MA_SHIFT 2
|
||||
#define MMU_AP_MASK (0x3 << MMU_AP_SHIFT)
|
||||
|
||||
#define MMU_AP_KAUN 0UL /* kernel r/w, user none */
|
||||
#define MMU_AP_KAUA 1UL /* kernel r/w, user r/w */
|
||||
#define MMU_AP_KRUN 2UL /* kernel r, user none */
|
||||
#define MMU_AP_KRUR 3UL /* kernel r, user r */
|
||||
#define MMU_ATTR_AF (1ul << MMU_AF_SHIFT) /* the access flag */
|
||||
#define MMU_ATTR_DBM (1ul << 51) /* the dirty bit modifier */
|
||||
|
||||
#define MMU_MAP_CUSTOM(ap, mtype) \
|
||||
((0x1UL << MMU_AF_SHIFT) | (0x2UL << MMU_SHARED_SHIFT) | \
|
||||
((ap) << MMU_AP_SHIFT) | ((mtype) << MMU_MA_SHIFT))
|
||||
#define MMU_MAP_K_RO MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_MEM)
|
||||
#define MMU_MAP_K_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM)
|
||||
#define MMU_MAP_K_RW MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_NOCACHE_MEM)
|
||||
#define MMU_MAP_K_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUN, DEVICE_MEM)
|
||||
#define MMU_MAP_U_RO MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_NOCACHE_MEM)
|
||||
#define MMU_MAP_U_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_MEM)
|
||||
#define MMU_MAP_U_RW MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_NOCACHE_MEM)
|
||||
#define MMU_MAP_U_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUA, DEVICE_MEM)
|
||||
#define MMU_MAP_K_ROCB MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_MEM)
|
||||
#define MMU_MAP_K_RO MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_NOCACHE_MEM)
|
||||
#define MMU_MAP_K_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM)
|
||||
#define MMU_MAP_K_RW MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_NOCACHE_MEM)
|
||||
#define MMU_MAP_K_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUN, DEVICE_MEM)
|
||||
#define MMU_MAP_U_ROCB MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_MEM)
|
||||
#define MMU_MAP_U_RO MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_NOCACHE_MEM)
|
||||
#define MMU_MAP_U_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_MEM)
|
||||
#define MMU_MAP_U_RW MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_NOCACHE_MEM)
|
||||
#define MMU_MAP_U_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUA, DEVICE_MEM)
|
||||
#define MMU_MAP_TRACE(attr) ((attr) & ~(MMU_ATTR_AF | MMU_ATTR_DBM))
|
||||
|
||||
#define ARCH_SECTION_SHIFT 21
|
||||
#define ARCH_SECTION_SIZE (1 << ARCH_SECTION_SHIFT)
|
||||
@@ -88,7 +104,8 @@ void rt_hw_aspace_switch(struct rt_aspace *aspace);
|
||||
void *rt_hw_mmu_v2p(struct rt_aspace *aspace, void *vaddr);
|
||||
void rt_hw_mmu_kernel_map_init(struct rt_aspace *aspace, rt_size_t vaddr_start,
|
||||
rt_size_t size);
|
||||
void rt_hw_mmu_ktbl_set(unsigned long tbl);
|
||||
void *rt_hw_mmu_pgtbl_create(void);
|
||||
void rt_hw_mmu_pgtbl_delete(void *pgtbl);
|
||||
|
||||
static inline void *rt_hw_mmu_tbl_get()
|
||||
{
|
||||
@@ -101,8 +118,8 @@ static inline void *rt_hw_mmu_kernel_v2p(void *v_addr)
|
||||
{
|
||||
rt_ubase_t par;
|
||||
void *paddr;
|
||||
asm volatile("at s1e1w, %0"::"r"(v_addr):"memory");
|
||||
asm volatile("mrs %0, par_el1":"=r"(par)::"memory");
|
||||
__asm__ volatile("at s1e1w, %0"::"r"(v_addr):"memory");
|
||||
__asm__ volatile("mrs %0, par_el1":"=r"(par)::"memory");
|
||||
|
||||
if (par & 0x1)
|
||||
{
|
||||
@@ -118,6 +135,73 @@ static inline void *rt_hw_mmu_kernel_v2p(void *v_addr)
|
||||
|
||||
return paddr;
|
||||
}
|
||||
/**
|
||||
* @brief Add permission from attribution
|
||||
*
|
||||
* @param attr architecture specified mmu attribution
|
||||
* @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)
|
||||
{
|
||||
switch (prot)
|
||||
{
|
||||
/* remove write permission for user */
|
||||
case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
|
||||
attr = (attr & ~MMU_AP_MASK) | (MMU_AP_KAUA << MMU_AP_SHIFT);
|
||||
break;
|
||||
default:
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove permission from attribution
|
||||
*
|
||||
* @param attr architecture specified mmu attribution
|
||||
* @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)
|
||||
{
|
||||
switch (prot)
|
||||
{
|
||||
/* remove write permission for user */
|
||||
case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
|
||||
if (attr & 0x40)
|
||||
attr |= 0x80;
|
||||
break;
|
||||
default:
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test permission from attribution
|
||||
*
|
||||
* @param attr architecture specified mmu attribution
|
||||
* @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_bool_t rc;
|
||||
switch (prot)
|
||||
{
|
||||
/* test write permission for user */
|
||||
case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
|
||||
if ((attr & MMU_AP_MASK) == (MMU_AP_KAUA << MMU_AP_SHIFT))
|
||||
rc = RT_TRUE;
|
||||
else
|
||||
rc = RT_FALSE;
|
||||
break;
|
||||
default:
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size,
|
||||
enum rt_mmu_cntl cmd);
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
|
||||
#include <backtrace.h>
|
||||
|
||||
#define DBG_TAG "libcpu.trap"
|
||||
#define DBG_LVL DBG_LOG
|
||||
#include <rtdbg.h>
|
||||
|
||||
void rt_unwind(struct rt_hw_exp_stack *regs, int pc_adj)
|
||||
{
|
||||
}
|
||||
@@ -40,7 +44,7 @@ static void _check_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *in
|
||||
|
||||
if ((mode & 0x1f) == 0x00)
|
||||
{
|
||||
rt_kprintf("%s! pc = 0x%08x\n", info, regs->pc - pc_adj);
|
||||
rt_kprintf("%s! pc = 0x%x\n", info, regs->pc - pc_adj);
|
||||
|
||||
/* user stack backtrace */
|
||||
#ifdef RT_USING_LWP
|
||||
@@ -79,7 +83,7 @@ static void _check_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *in
|
||||
}
|
||||
}
|
||||
|
||||
int _get_type(unsigned long esr)
|
||||
rt_inline int _get_type(unsigned long esr)
|
||||
{
|
||||
int ret;
|
||||
int fsc = esr & 0x3f;
|
||||
@@ -91,19 +95,31 @@ int _get_type(unsigned long esr)
|
||||
case 0x7:
|
||||
ret = MM_FAULT_TYPE_PAGE_FAULT;
|
||||
break;
|
||||
case 0xc:
|
||||
case 0xd:
|
||||
case 0xe:
|
||||
case 0xf:
|
||||
ret = MM_FAULT_TYPE_ACCESS_FAULT;
|
||||
break;
|
||||
case 0x8:
|
||||
case 0x9:
|
||||
case 0xa:
|
||||
case 0xb:
|
||||
ret = MM_FAULT_TYPE_ACCESS_FAULT;
|
||||
break;
|
||||
/* access flag fault */
|
||||
default:
|
||||
ret = MM_FAULT_TYPE_GENERIC;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int check_user_stack(unsigned long esr, struct rt_hw_exp_stack *regs)
|
||||
rt_inline long _irq_is_disable(long cpsr)
|
||||
{
|
||||
return !!(cpsr & 0x80);
|
||||
}
|
||||
|
||||
static int user_fault_fixable(unsigned long esr, struct rt_hw_exp_stack *regs)
|
||||
{
|
||||
rt_ubase_t level;
|
||||
unsigned char ec;
|
||||
void *dfar;
|
||||
int ret = 0;
|
||||
@@ -130,20 +146,24 @@ int check_user_stack(unsigned long esr, struct rt_hw_exp_stack *regs)
|
||||
break;
|
||||
}
|
||||
|
||||
if (fault_op)
|
||||
/* page fault exception only allow from user space */
|
||||
lwp = lwp_self();
|
||||
if (lwp && fault_op)
|
||||
{
|
||||
asm volatile("mrs %0, far_el1":"=r"(dfar));
|
||||
__asm__ volatile("mrs %0, far_el1":"=r"(dfar));
|
||||
struct rt_aspace_fault_msg msg = {
|
||||
.fault_op = fault_op,
|
||||
.fault_type = fault_type,
|
||||
.fault_vaddr = dfar,
|
||||
};
|
||||
lwp = lwp_self();
|
||||
RT_ASSERT(lwp);
|
||||
|
||||
lwp_user_setting_save(rt_thread_self());
|
||||
__asm__ volatile("mrs %0, daif\nmsr daifclr, 0x3\nisb\n":"=r"(level));
|
||||
if (rt_aspace_fault_try_fix(lwp->aspace, &msg))
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
__asm__ volatile("msr daif, %0\nisb\n"::"r"(level));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -269,6 +289,12 @@ void rt_hw_trap_irq(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
#define DBG_CHECK_EVENT(regs, esr) dbg_check_event(regs, esr)
|
||||
#else
|
||||
#define DBG_CHECK_EVENT(regs, esr) (0)
|
||||
#endif
|
||||
|
||||
void rt_hw_trap_fiq(void)
|
||||
{
|
||||
void *param;
|
||||
@@ -292,7 +318,7 @@ void rt_hw_trap_fiq(void)
|
||||
rt_hw_interrupt_ack(ir);
|
||||
}
|
||||
|
||||
void process_exception(unsigned long esr, unsigned long epc);
|
||||
void print_exception(unsigned long esr, unsigned long epc);
|
||||
void SVC_Handler(struct rt_hw_exp_stack *regs);
|
||||
void rt_hw_trap_exception(struct rt_hw_exp_stack *regs)
|
||||
{
|
||||
@@ -302,27 +328,43 @@ void rt_hw_trap_exception(struct rt_hw_exp_stack *regs)
|
||||
asm volatile("mrs %0, esr_el1":"=r"(esr));
|
||||
ec = (unsigned char)((esr >> 26) & 0x3fU);
|
||||
|
||||
#ifdef RT_USING_LWP
|
||||
if (dbg_check_event(regs, esr))
|
||||
if (DBG_CHECK_EVENT(regs, esr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (ec == 0x15) /* is 64bit syscall ? */
|
||||
else if (ec == 0x15) /* is 64bit syscall ? */
|
||||
{
|
||||
SVC_Handler(regs);
|
||||
/* never return here */
|
||||
}
|
||||
#ifdef RT_USING_LWP
|
||||
if (check_user_stack(esr, regs))
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
/**
|
||||
* Note: check_user_stack will take lock and it will possibly be a dead-lock
|
||||
* if exception comes from kernel.
|
||||
*/
|
||||
if ((regs->cpsr & 0x1f) == 0)
|
||||
{
|
||||
return;
|
||||
if (user_fault_fixable(esr, regs))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_irq_is_disable(regs->cpsr))
|
||||
{
|
||||
LOG_E("Kernel fault from interrupt/critical section");
|
||||
}
|
||||
if (rt_critical_level() != 0)
|
||||
{
|
||||
LOG_E("scheduler is not available");
|
||||
}
|
||||
else if (user_fault_fixable(esr, regs))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
process_exception(esr, regs->pc);
|
||||
print_exception(esr, regs->pc);
|
||||
rt_hw_show_register(regs);
|
||||
rt_kprintf("current: %s\n", rt_thread_self()->parent.name);
|
||||
LOG_E("current thread: %s\n", rt_thread_self()->parent.name);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
list_thread();
|
||||
|
||||
@@ -38,8 +38,8 @@ boot_arg1 .req x23
|
||||
boot_arg2 .req x24
|
||||
stack_top .req x25
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
.global __start
|
||||
__start:
|
||||
/*
|
||||
* Boot CPU general-purpose register settings:
|
||||
* x0 = physical address of device tree blob (dtb) in system RAM.
|
||||
@@ -165,8 +165,8 @@ _start:
|
||||
dsb sy
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
ldr x2, =_start
|
||||
GET_PHY x3, _start
|
||||
ldr x2, =__start
|
||||
GET_PHY x3, __start
|
||||
sub x3, x3, x2
|
||||
#else
|
||||
mov x3,0
|
||||
|
||||
Reference in New Issue
Block a user