rtt更新

This commit is contained in:
2025-01-18 13:25:25 +08:00
parent c6a7554b51
commit d6009a0773
726 changed files with 103376 additions and 6270 deletions

View File

@@ -0,0 +1,110 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-07-04 rcitach init ver.
*/
#include <rtthread.h>
#include <mmu.h>
#include <gtimer.h>
#include <lwp_user_mm.h>
#include "vdso.h"
#include "vdso_datapage.h"
#define DBG_TAG "vdso"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
enum vdso_abi {
VDSO_ABI_AA64,
};
enum vvar_pages {
VVAR_DATA_PAGE_OFFSET,
VVAR_TIMENS_PAGE_OFFSET,
VVAR_NR_PAGES,
};
struct vdso_abi_info {
const char *name;
const char *vdso_code_start;
const char *vdso_code_end;
unsigned long vdso_pages;
};
static struct vdso_abi_info vdso_info[] = {
[VDSO_ABI_AA64] = {
.name = "vdso_aarch64",
.vdso_code_start = __vdso_text_start,
.vdso_code_end = __vdso_text_end,
},
};
static union {
struct vdso_data data[CS_BASES];
uint8_t page[ARCH_PAGE_SIZE];
} vdso_data_store __page_aligned_data;
struct vdso_data *vdso_data = vdso_data_store.data;
int init_ret_flag = RT_EOK;
static int __setup_additional_pages(enum vdso_abi abi, struct rt_lwp *lwp)
{
RT_ASSERT(lwp != RT_NULL);
int ret;
void *vdso_base = RT_NULL;
unsigned long vdso_data_len, vdso_text_len;
vdso_data_len = VVAR_NR_PAGES * ARCH_PAGE_SIZE;
vdso_text_len = vdso_info[abi].vdso_pages << ARCH_PAGE_SHIFT;
vdso_base = lwp_map_user_phy(lwp, RT_NULL, rt_kmem_v2p((void *)vdso_data), vdso_data_len, 0);
if(vdso_base != RT_NULL)
{
ret = RT_EOK;
}
else
{
ret = RT_ERROR;
}
vdso_base += vdso_data_len;
vdso_base = lwp_map_user_phy(lwp, vdso_base, rt_kmem_v2p((void *)vdso_info[abi].vdso_code_start), vdso_text_len, 0);
lwp->vdso_vbase = vdso_base;
return ret;
}
int arch_setup_additional_pages(struct rt_lwp *lwp)
{
int ret;
if (init_ret_flag != RT_EOK) return -RT_ERROR;
ret = __setup_additional_pages(VDSO_ABI_AA64, lwp);
return ret;
}
static void __initdata(void)
{
struct tm time_vdso = SOFT_RTC_VDSOTIME_DEFAULT;
vdso_data->realtime_initdata = timegm(&time_vdso);
}
static int validate_vdso_elf(void)
{
if (rt_memcmp(vdso_info[VDSO_ABI_AA64].vdso_code_start, ELF_HEAD, ELF_HEAD_LEN)) {
LOG_E("vDSO is not a valid ELF object!");
init_ret_flag = -RT_ERROR;
return -RT_ERROR;
}
vdso_info[VDSO_ABI_AA64].vdso_pages = (
vdso_info[VDSO_ABI_AA64].vdso_code_end -
vdso_info[VDSO_ABI_AA64].vdso_code_start) >>
ARCH_PAGE_SHIFT;
__initdata();
return RT_EOK;
}
INIT_COMPONENT_EXPORT(validate_vdso_elf);

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-07-04 rcitach init ver.
*/
#include <rtthread.h>
#include <gtimer.h>
#include <ktime.h>
#include <time.h>
#include <vdso_datapage.h>
#include <vdso_data.h>
void rt_vdso_update_glob_time(void)
{
struct vdso_data *vdata = get_k_vdso_data();
struct timespec *vdso_ts;
uint64_t initdata = vdata->realtime_initdata;
rt_vdso_write_begin(vdata);
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
rt_ktime_boottime_get_ns(vdso_ts);
vdso_ts->tv_sec = initdata + vdso_ts->tv_sec;
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
rt_ktime_boottime_get_ns(vdso_ts);
vdata->cycle_last = rt_hw_get_cntpct_val();
rt_vdso_write_end(vdata);
}

View File

@@ -106,18 +106,16 @@ int arch_set_thread_context(void (*exit)(void), void *new_thread_stack,
struct rt_hw_exp_stack *ori_syscall = rt_thread_self()->user_ctx.ctx;
RT_ASSERT(ori_syscall != RT_NULL);
thread_frame = (void *)((long)new_thread_stack - sizeof(struct rt_hw_exp_stack));
syscall_frame = (void *)((long)new_thread_stack - 2 * sizeof(struct rt_hw_exp_stack));
new_thread_stack = (rt_ubase_t*)RT_ALIGN_DOWN((rt_ubase_t)new_thread_stack, 16);
syscall_frame = (void *)((long)new_thread_stack - sizeof(struct rt_hw_exp_stack));
memcpy(syscall_frame, ori_syscall, sizeof(*syscall_frame));
syscall_frame->sp_el0 = (long)user_stack;
syscall_frame->x0 = 0;
thread_frame->cpsr = ((3 << 6) | 0x4 | 0x1);
thread_frame->pc = (long)exit;
thread_frame->x0 = 0;
thread_frame = (void *)rt_hw_stack_init(exit, RT_NULL, (void *)syscall_frame, RT_NULL);
*thread_sp = syscall_frame;
*thread_sp = thread_frame;
return 0;
}

View File

@@ -17,6 +17,7 @@
#include <rtconfig.h>
#include <asm-generic.h>
#include <asm-fpu.h>
#include <vector_gcc.h>
#include <armv8.h>
#include <lwp_arch.h>
@@ -105,6 +106,7 @@ arch_get_user_sp:
.global arch_clone_exit
arch_fork_exit:
arch_clone_exit:
mov x0, xzr
b arch_syscall_exit
/*
@@ -125,15 +127,37 @@ lwp_exec_user:
* since this routine reset the SP, we take it as a start point
*/
START_POINT(SVC_Handler)
mov fp, xzr
mov lr, xzr
/* x0 is initial sp */
mov sp, x0
bl _SVC_Handler
/* jump explictly, make this code position independant */
b arch_syscall_exit
START_POINT_END(SVC_Handler)
TRACE_SYMBOL(_SVC_Handler)
#define FRAME_REG x19
/**
* x0 -> frame_addr
*/
_SVC_Handler:
.local _SVC_Handler
stp fp, lr, [sp, -16]!
mov fp, sp
mov FRAME_REG, x0 /* save the value of frame address */
msr daifclr, #3 /* enable interrupt */
bl rt_thread_self
GET_THREAD_SELF x0
bl lwp_user_setting_save
ldp x8, x9, [sp, #(CONTEXT_OFFSET_X8)]
ldp x8, x9, [FRAME_REG, #(CONTEXT_OFFSET_X8)]
and x0, x8, #0xf000
cmp x0, #0xe000
beq arch_signal_quit
@@ -146,78 +170,46 @@ START_POINT(SVC_Handler)
cmp x0, xzr
mov x30, x0
beq arch_syscall_exit
ldp x0, x1, [sp, #(CONTEXT_OFFSET_X0)]
ldp x2, x3, [sp, #(CONTEXT_OFFSET_X2)]
ldp x4, x5, [sp, #(CONTEXT_OFFSET_X4)]
ldp x6, x7, [sp, #(CONTEXT_OFFSET_X6)]
ldp x0, x1, [FRAME_REG, #(CONTEXT_OFFSET_X0)]
ldp x2, x3, [FRAME_REG, #(CONTEXT_OFFSET_X2)]
ldp x4, x5, [FRAME_REG, #(CONTEXT_OFFSET_X4)]
ldp x6, x7, [FRAME_REG, #(CONTEXT_OFFSET_X6)]
blr x30
/* jump explictly, make this code position independant */
b arch_syscall_exit
START_POINT_END(SVC_Handler)
.global arch_syscall_exit
ldp fp, lr, [sp], 16
ret
/**
* void arch_syscall_exit(long rc)
*/
arch_syscall_exit:
.global arch_syscall_exit
/**
* @brief back up former x0 which is required to restart syscall, then setup
* backup former x0 which is required to restart syscall, then setup
* syscall return value in stack frame
*/
mov x1, sp
bl arch_syscall_prepare_signal
/**
* disable local irq so we don't messup with the spsr_el1 witch is not saved
* for kernel space IRQ/EXCEPTION
*/
msr daifset, #3
ldp x2, x3, [sp], #0x10 /* SPSR and ELR. */
msr spsr_el1, x3
msr elr_el1, x2
ldp x29, x30, [sp], #0x10
msr sp_el0, x29
ldp x28, x29, [sp], #0x10
msr fpcr, x28
msr fpsr, x29
ldp x28, x29, [sp], #0x10
ldp x26, x27, [sp], #0x10
ldp x24, x25, [sp], #0x10
ldp x22, x23, [sp], #0x10
ldp x20, x21, [sp], #0x10
ldp x18, x19, [sp], #0x10
ldp x16, x17, [sp], #0x10
ldp x14, x15, [sp], #0x10
ldp x12, x13, [sp], #0x10
ldp x10, x11, [sp], #0x10
ldp x8, x9, [sp], #0x10
ldp x6, x7, [sp], #0x10
ldp x4, x5, [sp], #0x10
ldp x2, x3, [sp], #0x10
ldp x0, x1, [sp], #0x10
RESTORE_FPU sp
b arch_ret_to_user
/* the sp is reset to the outer most level, irq and fiq are disabled */
START_POINT(arch_ret_to_user)
msr daifset, #3
/* save exception frame */
SAVE_FPU sp
stp x0, x1, [sp, #-0x10]!
stp x2, x3, [sp, #-0x10]!
stp x4, x5, [sp, #-0x10]!
stp x6, x7, [sp, #-0x10]!
stp x8, x9, [sp, #-0x10]!
stp x10, x11, [sp, #-0x10]!
stp x12, x13, [sp, #-0x10]!
stp x14, x15, [sp, #-0x10]!
stp x16, x17, [sp, #-0x10]!
stp x18, x19, [sp, #-0x10]!
stp x20, x21, [sp, #-0x10]!
stp x22, x23, [sp, #-0x10]!
stp x24, x25, [sp, #-0x10]!
stp x26, x27, [sp, #-0x10]!
stp x28, x29, [sp, #-0x10]!
mrs x0, fpcr
mrs x1, fpsr
stp x0, x1, [sp, #-0x10]!
stp x29, x30, [sp, #-0x10]!
ldr x2, [sp, #CONTEXT_OFFSET_SP_EL0]
msr sp_el0, x2
ldr x2, [sp, #CONTEXT_OFFSET_ELR_EL1]
msr elr_el1, x2
ldr x3, [sp, #CONTEXT_OFFSET_SPSR_EL1]
msr spsr_el1, x3
/* pre-action */
bl lwp_check_debug
@@ -228,7 +220,8 @@ START_POINT(arch_ret_to_user)
msr daifclr, #3
mov x0, xzr
b sys_exit
1:
1: /* handling dbg */
/* check if dbg ops exist */
ldr x0, =rt_dbg_ops
ldr x0, [x0]
@@ -240,104 +233,42 @@ START_POINT(arch_ret_to_user)
orr x2, x2, x1
msr spsr_el1, x2
b 3f
2:
2: /* clear software step */
bic x2, x2, x1
msr spsr_el1, x2
3:
3: /* handling signal */
/**
* push 2 dummy words to simulate a exception frame of interrupt
* Note: in kernel state, the context switch dont saved the context
* push updated spsr & elr to exception frame.
* Note: these 2 maybe updated after handling dbg
*/
mrs x0, spsr_el1
str x0, [sp, #CONTEXT_OFFSET_SPSR_EL1]
mrs x1, elr_el1
stp x1, x0, [sp, #-0x10]!
str x1, [sp, #CONTEXT_OFFSET_ELR_EL1]
mov x0, sp
/* restore the thread execution environment */
msr daifclr, #3
bl lwp_thread_signal_catch
/* restore the exception-return exec-flow */
msr daifset, #3
ldp x1, x0, [sp], #0x10
msr spsr_el1, x0
msr elr_el1, x1
/* check debug */
/* restore exception frame */
ldp x29, x30, [sp], #0x10
ldp x0, x1, [sp], #0x10
msr fpcr, x0
msr fpsr, x1
ldp x28, x29, [sp], #0x10
ldp x26, x27, [sp], #0x10
ldp x24, x25, [sp], #0x10
ldp x22, x23, [sp], #0x10
ldp x20, x21, [sp], #0x10
ldp x18, x19, [sp], #0x10
ldp x16, x17, [sp], #0x10
ldp x14, x15, [sp], #0x10
ldp x12, x13, [sp], #0x10
ldp x10, x11, [sp], #0x10
ldp x8, x9, [sp], #0x10
ldp x6, x7, [sp], #0x10
ldp x4, x5, [sp], #0x10
ldp x2, x3, [sp], #0x10
ldp x0, x1, [sp], #0x10
RESTORE_FPU sp
stp x0, x1, [sp, #-0x10]!
ldr x0, =rt_dbg_ops
ldr x0, [x0]
cmp x0, xzr
ldp x0, x1, [sp], #0x10
beq 1f
/* save */
SAVE_FPU sp
stp x0, x1, [sp, #-0x10]!
stp x2, x3, [sp, #-0x10]!
stp x4, x5, [sp, #-0x10]!
stp x6, x7, [sp, #-0x10]!
stp x8, x9, [sp, #-0x10]!
stp x10, x11, [sp, #-0x10]!
stp x12, x13, [sp, #-0x10]!
stp x14, x15, [sp, #-0x10]!
stp x16, x17, [sp, #-0x10]!
stp x18, x19, [sp, #-0x10]!
stp x20, x21, [sp, #-0x10]!
stp x22, x23, [sp, #-0x10]!
stp x24, x25, [sp, #-0x10]!
stp x26, x27, [sp, #-0x10]!
stp x28, x29, [sp, #-0x10]!
mrs x0, fpcr
mrs x1, fpsr
stp x0, x1, [sp, #-0x10]!
stp x29, x30, [sp, #-0x10]!
mrs x0, elr_el1
ldr x0, [sp, #CONTEXT_OFFSET_ELR_EL1]
bl dbg_attach_req
/* restore */
ldp x29, x30, [sp], #0x10
ldp x0, x1, [sp], #0x10
msr fpcr, x0
msr fpsr, x1
ldp x28, x29, [sp], #0x10
ldp x26, x27, [sp], #0x10
ldp x24, x25, [sp], #0x10
ldp x22, x23, [sp], #0x10
ldp x20, x21, [sp], #0x10
ldp x18, x19, [sp], #0x10
ldp x16, x17, [sp], #0x10
ldp x14, x15, [sp], #0x10
ldp x12, x13, [sp], #0x10
ldp x10, x11, [sp], #0x10
ldp x8, x9, [sp], #0x10
ldp x6, x7, [sp], #0x10
ldp x4, x5, [sp], #0x10
ldp x2, x3, [sp], #0x10
ldp x0, x1, [sp], #0x10
RESTORE_FPU sp
1:
RESTORE_IRQ_CONTEXT_NO_SPEL0
eret
START_POINT_END(arch_ret_to_user)
@@ -407,32 +338,7 @@ arch_syscall_restart:
/* restore previous exception frame */
msr spsel, #0
ldp x2, x3, [sp], #0x10
msr elr_el1, x2
msr spsr_el1, x3
ldp x29, x30, [sp], #0x10
ldp x28, x29, [sp], #0x10
msr fpcr, x28
msr fpsr, x29
ldp x28, x29, [sp], #0x10
ldp x26, x27, [sp], #0x10
ldp x24, x25, [sp], #0x10
ldp x22, x23, [sp], #0x10
ldp x20, x21, [sp], #0x10
ldp x18, x19, [sp], #0x10
ldp x16, x17, [sp], #0x10
ldp x14, x15, [sp], #0x10
ldp x12, x13, [sp], #0x10
ldp x10, x11, [sp], #0x10
ldp x8, x9, [sp], #0x10
ldp x6, x7, [sp], #0x10
ldp x4, x5, [sp], #0x10
ldp x2, x3, [sp], #0x10
ldp x0, x1, [sp], #0x10
RESTORE_FPU sp
RESTORE_IRQ_CONTEXT_NO_SPEL0
msr spsel, #1
@@ -440,8 +346,8 @@ arch_syscall_restart:
arch_signal_quit:
/* drop current exception frame */
add sp, sp, #CONTEXT_SIZE
/* drop current exception frame & sigreturn */
add sp, sp, #(CONTEXT_SIZE + 0x10)
mov x1, sp
mrs x0, sp_el0
bl arch_signal_ucontext_restore
@@ -457,35 +363,12 @@ arch_signal_quit:
/* restore previous exception frame */
msr spsel, #0
ldp x2, x3, [sp], #0x10
msr elr_el1, x2
msr spsr_el1, x3
ldp x29, x30, [sp], #0x10
ldp x28, x29, [sp], #0x10
msr fpcr, x28
msr fpsr, x29
ldp x28, x29, [sp], #0x10
ldp x26, x27, [sp], #0x10
ldp x24, x25, [sp], #0x10
ldp x22, x23, [sp], #0x10
ldp x20, x21, [sp], #0x10
ldp x18, x19, [sp], #0x10
ldp x16, x17, [sp], #0x10
ldp x14, x15, [sp], #0x10
ldp x12, x13, [sp], #0x10
ldp x10, x11, [sp], #0x10
ldp x8, x9, [sp], #0x10
ldp x6, x7, [sp], #0x10
ldp x4, x5, [sp], #0x10
ldp x2, x3, [sp], #0x10
ldp x0, x1, [sp], #0x10
RESTORE_FPU sp
RESTORE_IRQ_CONTEXT_NO_SPEL0
msr spsel, #1
SAVE_IRQ_CONTEXT
b arch_ret_to_user
/**

View File

@@ -48,7 +48,7 @@ int arch_expand_user_stack(void *addr)
else /* map failed, send signal SIGSEGV */
{
#ifdef RT_USING_SIGNALS
dbg_log(DBG_ERROR, "[fault] thread %s mapped addr %p failed!\n", rt_thread_self()->parent.name, addr);
LOG_E("[fault] thread %s mapped addr %p failed!\n", rt_thread_self()->parent.name, addr);
lwp_thread_kill(rt_thread_self(), SIGSEGV);
ret = 1; /* return 1, will return back to intr, then check exit */
#endif
@@ -57,7 +57,7 @@ int arch_expand_user_stack(void *addr)
else /* not stack, send signal SIGSEGV */
{
#ifdef RT_USING_SIGNALS
dbg_log(DBG_ERROR, "[fault] thread %s access unmapped addr %p!\n", rt_thread_self()->parent.name, addr);
LOG_E("[fault] thread %s access unmapped addr %p!\n", rt_thread_self()->parent.name, addr);
lwp_thread_kill(rt_thread_self(), SIGSEGV);
ret = 1; /* return 1, will return back to intr, then check exit */
#endif