From 3b8c9fcdca418aab58d3178a5f93fda853a539fa Mon Sep 17 00:00:00 2001 From: rcitach Date: Wed, 22 Apr 2026 02:23:35 +0000 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8D=20arm=20=E6=9E=B6=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/lwp/arch/common/vdso_kernel.c | 7 ++- components/lwp/vdso/SConscript | 5 +- .../lwp/vdso/kernel/vdso_kernel_internal.h | 6 +-- components/lwp/vdso/user/SConstruct | 5 ++ components/lwp/vdso/user/arch/arm/vdso.lds.S | 46 +++++++++++++++++++ components/lwp/vdso/user/arch/arm/vdso_arch.h | 33 +++++++++++++ components/lwp/vdso/vdso_constants.h | 2 + components/lwp/vdso/vdso_data_page.h | 5 +- 8 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 components/lwp/vdso/user/arch/arm/vdso.lds.S create mode 100644 components/lwp/vdso/user/arch/arm/vdso_arch.h diff --git a/components/lwp/arch/common/vdso_kernel.c b/components/lwp/arch/common/vdso_kernel.c index f64010e3a1..cfb5939878 100644 --- a/components/lwp/arch/common/vdso_kernel.c +++ b/components/lwp/arch/common/vdso_kernel.c @@ -53,6 +53,7 @@ static union uint8_t raw[RT_VDSO_DATA_PAGE_COUNT * ARCH_PAGE_SIZE]; } rt_vdso_data_page_store RT_VDSO_DATA_PAGE_ALIGNED; struct rt_vdso_data_page *rt_vdso_kernel_data_page = &rt_vdso_data_page_store.data_page; +RT_DEFINE_HW_SPINLOCK(rt_vdso_data_page_lock); static int rt_vdso_runtime_status = RT_EOK; static struct timespec rt_vdso_realtime_offset; @@ -143,7 +144,7 @@ static int rt_vdso_read_monotonic_snapshot(struct timespec *monotonic_time, static void rt_vdso_update_data_page_flags(void) { - rt_uint32_t flags = 0; + rt_uint64_t flags = 0; if (rt_vdso_realtime_offset_ready) { @@ -188,11 +189,13 @@ void rt_vdso_set_realtime(const struct timespec *realtime) return; } + rt_hw_spin_lock(&rt_vdso_data_page_lock); rt_vdso_data_page_write_begin(rt_vdso_kernel_data_page); rt_vdso_realtime_offset = rt_vdso_timespec_subtract(realtime, &monotonic); rt_vdso_realtime_offset_ready = RT_TRUE; rt_vdso_store_clock_snapshot(&monotonic, counter, freq); rt_vdso_data_page_write_end(rt_vdso_kernel_data_page); + rt_hw_spin_unlock(&rt_vdso_data_page_lock); } static void *rt_vdso_map_physical_pages(struct rt_lwp *lwp, void *user_va, @@ -309,9 +312,11 @@ void rt_vdso_sync_clock_data(void) return; } + rt_hw_spin_lock(&rt_vdso_data_page_lock); rt_vdso_data_page_write_begin(rt_vdso_kernel_data_page); rt_vdso_store_clock_snapshot(&monotonic, counter, freq); rt_vdso_data_page_write_end(rt_vdso_kernel_data_page); + rt_hw_spin_unlock(&rt_vdso_data_page_lock); } static int rt_vdso_validate_image(void) diff --git a/components/lwp/vdso/SConscript b/components/lwp/vdso/SConscript index 33fabc66b7..e28390303d 100644 --- a/components/lwp/vdso/SConscript +++ b/components/lwp/vdso/SConscript @@ -12,7 +12,10 @@ src = Glob('kernel/*.c') + Glob('kernel/*.S') if not GetDepend(['RT_USING_VDSO']): Return('group') -if rtconfig.ARCH != "aarch64" and rtconfig.ARCH != "risc-v": +if rtconfig.ARCH != "aarch64" and rtconfig.ARCH != "risc-v" and rtconfig.ARCH != "arm": + # not supported arch + src = [] +elif rtconfig.ARCH == "arm" and rtconfig.CPU != "cortex-a": # not supported arch src = [] else: diff --git a/components/lwp/vdso/kernel/vdso_kernel_internal.h b/components/lwp/vdso/kernel/vdso_kernel_internal.h index bead93b7e7..d24488a9ab 100644 --- a/components/lwp/vdso/kernel/vdso_kernel_internal.h +++ b/components/lwp/vdso/kernel/vdso_kernel_internal.h @@ -11,7 +11,7 @@ #ifndef RT_VDSO_KERNEL_INTERNAL_H #define RT_VDSO_KERNEL_INTERNAL_H -#include +#include #include #ifdef __cplusplus @@ -27,14 +27,14 @@ rt_inline struct rt_vdso_data_page *rt_vdso_get_kernel_data_page(void) rt_inline void rt_vdso_data_page_write_begin(struct rt_vdso_data_page *data_page) { - rt_atomic_add(&data_page->seq_counter, 1); + data_page->seq_counter += 1; rt_hw_dmb(); } rt_inline void rt_vdso_data_page_write_end(struct rt_vdso_data_page *data_page) { rt_hw_dmb(); - rt_atomic_add(&data_page->seq_counter, 1); + data_page->seq_counter += 1; } #ifdef __cplusplus diff --git a/components/lwp/vdso/user/SConstruct b/components/lwp/vdso/user/SConstruct index ffc7c14393..778b875279 100644 --- a/components/lwp/vdso/user/SConstruct +++ b/components/lwp/vdso/user/SConstruct @@ -11,6 +11,11 @@ arch_def_config = { 'device': '-march=armv8-a -mtune=cortex-a53', 'linker': os.path.join(user_dir, 'arch', 'aarch64', 'vdso.lds.S'), }, + 'arm': { + 'prefix': 'arm-none-eabi-', + 'device': '-march=armv7-a -marm', + 'linker': os.path.join(user_dir, 'arch', 'arm', 'vdso.lds.S'), + }, 'risc-v': { 'prefix': 'riscv64-none-elf-', 'device': '-march=rv64imafdc -mabi=lp64', diff --git a/components/lwp/vdso/user/arch/arm/vdso.lds.S b/components/lwp/vdso/user/arch/arm/vdso.lds.S new file mode 100644 index 0000000000..8b058412d2 --- /dev/null +++ b/components/lwp/vdso/user/arch/arm/vdso.lds.S @@ -0,0 +1,46 @@ +#include + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +SECTIONS +{ + PROVIDE(__rt_vdso_data_page = . - (RT_VDSO_DATA_PAGE_COUNT * RT_VDSO_PAGE_SIZE)); + . = SIZEOF_HEADERS; + + .hash : { *(.hash) } :text + .gnu.hash : { *(.gnu.hash) } :text + .dynsym : { *(.dynsym) } :text + .dynstr : { *(.dynstr) } :text + .gnu.version : { *(.gnu.version) } :text + .gnu.version_d : { *(.gnu.version_d) } :text + .gnu.version_r : { *(.gnu.version_r) } :text + .dynamic : { *(.dynamic) } :text :dynamic + .rodata : ALIGN(16) { *(.rodata*) } :text + .text : ALIGN(16) { *(.text*) } :text + + /DISCARD/ : { + *(.data .data.* .sdata*) + *(.bss .bss.* .sbss .sbss.*) + *(.comment*) + *(.note*) + *(.eh_frame*) + *(.interp) + } +} + +PHDRS +{ + text PT_LOAD FLAGS(5) FILEHDR PHDRS; + dynamic PT_DYNAMIC FLAGS(4); +} + +VERSION +{ + LINUX_2.6 { + global: + __vdso_clock_gettime; + local: + *; + }; +} diff --git a/components/lwp/vdso/user/arch/arm/vdso_arch.h b/components/lwp/vdso/user/arch/arm/vdso_arch.h new file mode 100644 index 0000000000..5dd0e38ffe --- /dev/null +++ b/components/lwp/vdso/user/arch/arm/vdso_arch.h @@ -0,0 +1,33 @@ +#ifndef RT_VDSO_ARCH_H +#define RT_VDSO_ARCH_H + +#include + +#define __RT_STRINGIFY(x...) #x +#define RT_STRINGIFY(x...) __RT_STRINGIFY(x) + +#define rt_vdso_arch_barrier(cmd, ...) \ + __asm__ volatile(RT_STRINGIFY(cmd) " " RT_STRINGIFY(__VA_ARGS__)::: "memory") + +static inline uint64_t rt_vdso_arch_read_counter(void) +{ + uint32_t lo; + uint32_t hi; + + __asm__ volatile("mrrc p15, 1, %0, %1, c14" : "=r"(lo), "=r"(hi)); + rt_vdso_arch_barrier(dmb, ish); + + return ((uint64_t)hi << 32) | lo; +} + +static inline void rt_vdso_arch_cpu_relax(void) +{ + __asm__ volatile("yield" ::: "memory"); +} + +static inline void rt_vdso_arch_rmb(void) +{ + rt_vdso_arch_barrier(dmb, ish); +} + +#endif diff --git a/components/lwp/vdso/vdso_constants.h b/components/lwp/vdso/vdso_constants.h index 5ebe158b0d..bbd78a8725 100644 --- a/components/lwp/vdso/vdso_constants.h +++ b/components/lwp/vdso/vdso_constants.h @@ -32,6 +32,8 @@ extern "C" { #if defined(__aarch64__) #define RT_VDSO_IMAGE_PATH "../user/build/aarch64/libvdso.so" +#elif defined(__arm__) +#define RT_VDSO_IMAGE_PATH "../user/build/arm/libvdso.so" #elif defined(__riscv) #define RT_VDSO_IMAGE_PATH "../user/build/risc-v/libvdso.so" #else diff --git a/components/lwp/vdso/vdso_data_page.h b/components/lwp/vdso/vdso_data_page.h index 722490db2d..a1c962c54d 100644 --- a/components/lwp/vdso/vdso_data_page.h +++ b/components/lwp/vdso/vdso_data_page.h @@ -22,7 +22,7 @@ extern "C" { #define RT_VDSO_CLOCK_ID_MAX 16 #define RT_VDSO_NSEC_PER_SEC 1000000000ULL -#define RT_VDSO_FLAG_REALTIME_VALID (1U << 0) +#define RT_VDSO_FLAG_REALTIME_VALID (1ULL << 0) enum rt_vdso_clock_data_index { @@ -34,7 +34,8 @@ enum rt_vdso_clock_data_index struct rt_vdso_data_page { uint32_t seq_counter; - uint32_t flags; + uint32_t reserved0; + uint64_t flags; uint64_t counter_last; uint64_t counter_freq; struct timespec base_time[RT_VDSO_CLOCK_DATA_COUNT];