Sync dfs lwp (#8123)

This commit is contained in:
geniusgogo
2023-10-17 13:07:59 +08:00
committed by GitHub
parent 7d64cdcf58
commit ecd29fda60
79 changed files with 7410 additions and 729 deletions
-4
View File
@@ -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
{
+9 -1
View File
@@ -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;
+23 -4
View File
@@ -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
View File
@@ -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);
+62 -20
View File
@@ -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();
+4 -4
View File
@@ -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