Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions libcpu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ config ARCH_RISCV64
select ARCH_CPU_64BIT
bool

config ARCH_RISCV_XUANTIE
select ARCH_RISCV
bool

if ARCH_RISCV
orsource "./risc-v/Kconfig"
endif
Expand All @@ -304,6 +308,14 @@ if ARCH_RISCV64
select ARCH_USING_NEW_CTX_SWITCH
help
Using the common64 implementation under ./libcpu/risc-v

if RT_USING_SMART
config CONFIG_XUANTIE_SVPBMT
int
depends on ARCH_RISCV_XUANTIE
default 1
endif

endif

config ARCH_REMAP_KERNEL
Expand Down
31 changes: 28 additions & 3 deletions libcpu/risc-v/common/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ static int mmu_map_early(rt_ubase_t *tbl, rt_uint8_t max_level,
rt_ubase_t va, rt_ubase_t pa, rt_ubase_t attr, rt_bool_t flush)
{
rt_ubase_t page, *table, off, level_shift;
rt_ubase_t pv_off = flush ? rt_kmem_pvoff() : 0;

attr = mmu_attr_fixup(attr);

Expand Down Expand Up @@ -168,7 +169,7 @@ static int mmu_map_early(rt_ubase_t *tbl, rt_uint8_t max_level,
return MMU_MAP_ERROR_NOPAGE;
}

rt_memset((void *)page, 0, ARCH_PAGE_SIZE);
rt_memset((void *)(page - pv_off), 0, ARCH_PAGE_SIZE);
table[off] = ((page >> ARCH_PAGE_SHIFT) << PTE_BITS) | PTE_V;

if (flush)
Expand All @@ -185,7 +186,7 @@ static int mmu_map_early(rt_ubase_t *tbl, rt_uint8_t max_level,

/* Step into the next level page table */
page = (table[off] >> PTE_BITS) << ARCH_PAGE_SHIFT;
table = (rt_ubase_t *)page;
table = (rt_ubase_t *)(page - pv_off);

level_shift -= VPN_BITS;
}
Expand Down Expand Up @@ -934,6 +935,12 @@ int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, rt_ubase_t size,
#if __riscv_xlen == 32 && !defined(RT_USING_SMART)
/* The RV32 ioremap and MPR regions are placed below the kernel image. */
aspace_start = (rt_ubase_t)v_address - rt_mpr_size;
#elif defined(RT_USING_SMART)
/* The runtime-sized MPR can extend below the linked kernel base. */
if ((rt_ubase_t)v_address - rt_mpr_size < aspace_start)
{
aspace_start = (rt_ubase_t)v_address - rt_mpr_size;
}
#endif

rt_aspace_init(aspace, (void *)aspace_start, 0UL - aspace_start, vtable);
Expand Down Expand Up @@ -1395,10 +1402,28 @@ void *rt_hw_mmu_pgtbl_create(void)
(void *)rt_kernel_space.page_table + i * ARCH_PAGE_SIZE,
ARCH_PAGE_SIZE);
}
#else
rt_memcpy(mmu_table, rt_kernel_space.page_table, ARCH_PAGE_SIZE);
#endif

#ifdef RT_USING_SMART
/* Do not share early identity mappings with the user address space. */
rt_size_t user_start = get_top_vpn(USER_VADDR_START, satp_level_4k);
rt_size_t user_end = get_top_vpn(USER_VADDR_TOP - 1, satp_level_4k);

for (int i = 0; i < (1UL << alloc_bits); ++i)
{
rt_ubase_t *table = (void *)mmu_table + i * ARCH_PAGE_SIZE;

rt_memset(table + user_start, 0,
(user_end - user_start + 1) * sizeof(*table));
}
#endif

#ifdef MMU_PERCPU
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table,
RT_CPUS_NR * ARCH_PAGE_SIZE);
#else
rt_memcpy(mmu_table, rt_kernel_space.page_table, ARCH_PAGE_SIZE);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, ARCH_PAGE_SIZE);
#endif

Expand Down
21 changes: 18 additions & 3 deletions libcpu/risc-v/common/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
extern long list_thread(void);
#endif

void rt_hw_show_register(struct rt_hw_stack_frame *regs);

#ifdef RT_USING_LWP
#include <mm_aspace.h>
#include <lwp.h>
Expand All @@ -46,10 +48,14 @@ static void _check_fault(struct rt_hw_stack_frame *regs, uint32_t pc_adj, char *
{
rt_thread_t th;
rt_bool_t is_user_fault = !(regs->xstatus & SR_PP);
rt_base_t saved_stat = 0;

if (is_user_fault)
{
/* User backtrace and process teardown can acquire sleeping locks. */
saved_stat = csr_read_set(CSR_STATUS, SR_IE);
rt_kprintf("%s! pc = %p\n", info, regs->epc - pc_adj);
rt_hw_show_register(regs);
}

/* User stack backtrace */
Expand All @@ -65,6 +71,7 @@ static void _check_fault(struct rt_hw_stack_frame *regs, uint32_t pc_adj, char *
lwp_core_dump(regs, pc_adj);
#endif
sys_exit_group(-1);
csr_write(CSR_STATUS, saved_stat);
Comment on lines 73 to +74

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

熊老师好呀!sys_exit_group(-1) 后面的 csr_write 按理走不到,IE 会一直开着。是不是先恢复再调更稳?如有误解请指正,谢谢!

}
}

Expand Down Expand Up @@ -296,6 +303,7 @@ void rt_hw_trap(struct rt_hw_stack_frame *regs)
{
rt_ubase_t xcause = regs->xcause;
rt_ubase_t tval = csr_read_clear(CSR_TVAL, 0);
rt_bool_t is_user_fault = !(regs->xstatus & SR_PP);

/* IRQ */
if (xcause & CAUSE_IRQ_FLAG)
Expand Down Expand Up @@ -364,16 +372,23 @@ void rt_hw_trap(struct rt_hw_stack_frame *regs)
case EXC_INST_PAGE_FAULT:
case EXC_LOAD_PAGE_FAULT:
case EXC_STORE_PAGE_FAULT:
#ifdef RT_USING_SMART
if (!(regs->xstatus & SR_PP) ||
#ifdef RT_USING_SMART
if (is_user_fault ||
(tval >= USER_VADDR_START && tval < USER_VADDR_TOP))
{
if (user_fault_fixable(regs, xcause, tval))
{
return;
}

/* A failed user mapping must terminate only the LWP. */
if (is_user_fault && rt_thread_self())
{
_check_fault(regs, 0, "user fault");
return;
}
}
#endif /* RT_USING_SMART */
#endif /* RT_USING_SMART */

default:
LOG_E("Unhandle Execption: (%d) %s, TVAL = %p", xcause,
Expand Down
35 changes: 33 additions & 2 deletions libcpu/risc-v/common64/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

#include <rtthread.h>
#include <rthw.h>
#include <stddef.h>
#include <stdint.h>

Expand Down Expand Up @@ -85,6 +86,20 @@ void rt_hw_aspace_switch(rt_aspace_t aspace)
uint32_t hartid = rt_hw_cpu_id();
uintptr_t ptr = (uintptr_t)aspace->page_table + (uintptr_t)(hartid * ARCH_PAGE_SIZE);
uintptr_t page_table = (uintptr_t)rt_kmem_v2p((void *)ptr);

if (page_table == (uintptr_t)ARCH_MAP_FAILED)
{
/*
* During early K230 bring-up the kernel still runs with low physical
* pointers after relocation, including MMUTable. The formal kernel
* aspace does not translate that low pointer yet, but SATP needs the
* physical page-table address, so use the low address directly.
*/
if (ptr < KERNEL_VADDR_START)
{
page_table = ptr;
}
}
#ifndef RT_USING_SMP
current_mmu_table = aspace->page_table;
#else
Expand Down Expand Up @@ -632,14 +647,14 @@ static inline void _init_region(void *vaddr, size_t size)
{
rt_ioremap_start = vaddr;
rt_ioremap_size = size;
rt_mpr_start = rt_ioremap_start - rt_mpr_size;
rt_mpr_start = (void *)((rt_ubase_t)rt_ioremap_start - rt_mpr_size);
LOG_D("rt_ioremap_start: %p, rt_mpr_start: %p", rt_ioremap_start,
rt_mpr_start);
}
#else
static inline void _init_region(void *vaddr, size_t size)
{
rt_mpr_start = vaddr - rt_mpr_size;
rt_mpr_start = (void *)((rt_ubase_t)vaddr - rt_mpr_size);
}
#endif

Expand Down Expand Up @@ -1057,6 +1072,9 @@ void rt_hw_mem_setup_early(void *pgtbl, rt_uint64_t hartid)
vs += EARLY_MAP_PAGE_SIZE_2M;
}
#endif
/* flush page table entries from data cache before enabling MMU */
rt_hw_cpu_dcache_clean(early_pgtbl, ARCH_PAGE_SIZE);

/* apply new mapping */
asm volatile("sfence.vma x0, x0");
write_csr(satp, SATP_BASE | ((size_t)early_pgtbl >> PAGE_OFFSET_BIT));
Expand Down Expand Up @@ -1121,6 +1139,19 @@ void *rt_hw_mmu_pgtbl_create(void)
return RT_NULL;
}
rt_memcpy(mmu_table, rt_kernel_space.page_table, ARCH_PAGE_SIZE);

#ifdef RT_USING_SMART
{
int i;
int start_idx = USER_VADDR_START >> VPN2_SHIFT;
int end_idx = USER_VADDR_TOP >> VPN2_SHIFT;
for (i = start_idx; i <= end_idx; i++)
{
mmu_table[i] = 0;
Comment on lines +1146 to +1150

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

熊老师好呀!这段清零好像只在非 SMP 分支,SMP 下每个 hart 的 table 是不是也要清一下?另外 common 用的是 USER_VADDR_TOP - 1,这里是 TOP,不知道是不是有意的?如有误解请指正,谢谢!

}
}
#endif

rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, mmu_table, ARCH_PAGE_SIZE);
#endif

Expand Down
Loading