Browse Source

适配 arm 架构

rcitach 1 week ago
parent
commit
3b8c9fcdca

+ 6 - 1
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)

+ 4 - 1
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:

+ 3 - 3
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 <rtatomic.h>
+#include <rthw.h>
 #include <vdso_data_page.h>
 
 #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

+ 5 - 0
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',

+ 46 - 0
components/lwp/vdso/user/arch/arm/vdso.lds.S

@@ -0,0 +1,46 @@
+#include <vdso_constants.h>
+
+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:
+        *;
+    };
+}

+ 33 - 0
components/lwp/vdso/user/arch/arm/vdso_arch.h

@@ -0,0 +1,33 @@
+#ifndef RT_VDSO_ARCH_H
+#define RT_VDSO_ARCH_H
+
+#include <stdint.h>
+
+#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

+ 2 - 0
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

+ 3 - 2
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];