summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/lwp/SConscript8
-rw-r--r--components/lwp/arch/aarch64/common/vdso_data.c34
-rw-r--r--components/lwp/arch/common/vdso.c116
-rw-r--r--components/lwp/arch/common/vdso_kernel.c302
-rw-r--r--components/lwp/arch/risc-v/common/vdso_data.c34
-rw-r--r--components/lwp/lwp_elf.c6
-rw-r--r--components/lwp/vdso/SConscript14
-rw-r--r--components/lwp/vdso/kernel/vdso.h39
-rw-r--r--components/lwp/vdso/kernel/vdso_data.h48
-rw-r--r--components/lwp/vdso/kernel/vdso_image.S (renamed from components/lwp/vdso/kernel/vdso_text.S)14
-rw-r--r--components/lwp/vdso/kernel/vdso_kernel.h40
-rw-r--r--components/lwp/vdso/kernel/vdso_kernel_internal.h47
-rw-r--r--components/lwp/vdso/user/SConstruct97
-rw-r--r--components/lwp/vdso/user/arch/aarch64/SConstruct35
-rw-r--r--components/lwp/vdso/user/arch/aarch64/vdso.lds.S58
-rw-r--r--components/lwp/vdso/user/arch/aarch64/vdso_arch.h38
-rw-r--r--components/lwp/vdso/user/arch/aarch64/vdso_sys.c95
-rw-r--r--components/lwp/vdso/user/arch/aarch64/vdso_sys.h153
-rw-r--r--components/lwp/vdso/user/arch/risc-v/SConstruct62
-rw-r--r--components/lwp/vdso/user/arch/risc-v/vdso.lds.S58
-rw-r--r--components/lwp/vdso/user/arch/risc-v/vdso_arch.h42
-rw-r--r--components/lwp/vdso/user/arch/risc-v/vdso_sys.c101
-rw-r--r--components/lwp/vdso/user/arch/risc-v/vdso_sys.h147
-rw-r--r--components/lwp/vdso/user/common/vdso_clock_gettime.c80
-rw-r--r--components/lwp/vdso/user/common/vdso_user_internal.h115
-rw-r--r--components/lwp/vdso/vdso_constants.h (renamed from components/lwp/vdso/vdso_config.h)22
-rw-r--r--components/lwp/vdso/vdso_data_page.h46
-rw-r--r--components/lwp/vdso/vdso_datapage.h75
-rw-r--r--components/lwp/vdso/vdso_weak.c23
29 files changed, 882 insertions, 1067 deletions
diff --git a/components/lwp/SConscript b/components/lwp/SConscript
index c53b3f483c..56279cb998 100644
--- a/components/lwp/SConscript
+++ b/components/lwp/SConscript
@@ -26,11 +26,13 @@ if platform in platform_file.keys(): # support platforms
asm_path = 'arch/' + arch + '/' + cpu + '/*_' + platform_file[platform]
arch_common = 'arch/' + arch + '/' + 'common/*.c'
common = 'arch/common/*.c'
+ common_excluded = []
if not GetDepend('RT_USING_VDSO'):
- vdso_files = ['vdso_data.c', 'vdso.c']
- src += [f for f in Glob(arch_common) if os.path.basename(str(f)) not in vdso_files]
- src += [f for f in Glob(common) if os.path.basename(str(f)) not in vdso_files]
+ common_excluded.append('vdso_kernel.c')
+ src += Glob(arch_common)
+ src += [f for f in Glob(common) if os.path.basename(str(f)) not in common_excluded]
else:
+ CPPPATH += [cwd + '/vdso', cwd + '/vdso/kernel']
src += Glob(arch_common)
src += Glob(common)
if not GetDepend('ARCH_MM_MMU'):
diff --git a/components/lwp/arch/aarch64/common/vdso_data.c b/components/lwp/arch/aarch64/common/vdso_data.c
deleted file mode 100644
index b33094db9d..0000000000
--- a/components/lwp/arch/aarch64/common/vdso_data.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 <drivers/clock_time.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_clock_boottime_get_ns(vdso_ts);
- vdso_ts->tv_sec = initdata + vdso_ts->tv_sec;
-
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
- rt_clock_boottime_get_ns(vdso_ts);
-
- vdata->cycle_last = rt_hw_get_cntpct_val();
- rt_vdso_write_end(vdata);
-}
diff --git a/components/lwp/arch/common/vdso.c b/components/lwp/arch/common/vdso.c
deleted file mode 100644
index 823fd5b61e..0000000000
--- a/components/lwp/arch/common/vdso.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2006-2025 RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2024-07-04 rcitach init ver.
- * 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
- */
-
-#include <rtthread.h>
-#include <mmu.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_COMMON,
-};
-
-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_COMMON] = {
- .name = "vdso_common",
- .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_COMMON, 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_COMMON].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_COMMON].vdso_pages = (vdso_info[VDSO_ABI_COMMON].vdso_code_end - vdso_info[VDSO_ABI_COMMON].vdso_code_start) >> ARCH_PAGE_SHIFT;
-
- __initdata();
- return RT_EOK;
-}
-INIT_COMPONENT_EXPORT(validate_vdso_elf);
diff --git a/components/lwp/arch/common/vdso_kernel.c b/components/lwp/arch/common/vdso_kernel.c
new file mode 100644
index 0000000000..61a20fc4c9
--- /dev/null
+++ b/components/lwp/arch/common/vdso_kernel.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2006-2025 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2024-07-04 rcitach init ver.
+ * 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
+ * 2026-04-21 rcitach Refactor vDSO runtime around the clock data page.
+ */
+
+#include <rtthread.h>
+#include <mmu.h>
+#include <elf.h>
+#include <time.h>
+#include <lwp_user_mm.h>
+#include <drivers/clock_time.h>
+#ifdef RT_USING_RTC
+#include <rtdevice.h>
+#endif
+
+#include <vdso_kernel.h>
+#include <vdso_kernel_internal.h>
+#define DBG_TAG "vdso"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+enum rt_vdso_binary_id
+{
+ RT_VDSO_BINARY_COMMON,
+};
+
+struct rt_vdso_binary_info
+{
+ const char *name;
+ const char *image_start;
+ const char *image_end;
+ unsigned long page_count;
+};
+
+static struct rt_vdso_binary_info rt_vdso_binaries[] = {
+ [RT_VDSO_BINARY_COMMON] = {
+ .name = "rt_vdso_common",
+ .image_start = __rt_vdso_image_start,
+ .image_end = __rt_vdso_image_end,
+ },
+};
+
+static union {
+ struct rt_vdso_data_page data_page;
+ 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;
+static int rt_vdso_runtime_status = RT_EOK;
+
+static struct timespec rt_vdso_realtime_offset;
+static rt_bool_t rt_vdso_realtime_offset_ready;
+
+#ifndef MMU_MAP_U_ROCB
+#define MMU_MAP_U_ROCB MMU_MAP_U_RWCB
+#endif
+
+#ifndef MMU_MAP_U_RWCB_XN
+#define MMU_MAP_U_RWCB_XN MMU_MAP_U_RWCB
+#endif
+
+#ifdef MMU_MAP_U_ROCB_XN
+#define RT_VDSO_DATA_PAGE_ATTR MMU_MAP_U_ROCB_XN
+#elif defined(MMU_MAP_U_RWCB_XN)
+#define RT_VDSO_DATA_PAGE_ATTR MMU_MAP_U_RWCB_XN
+#else
+#define RT_VDSO_DATA_PAGE_ATTR MMU_MAP_U_ROCB
+#endif
+
+#define RT_VDSO_IMAGE_PAGE_ATTR MMU_MAP_U_ROCB
+
+static void rt_vdso_normalize_timespec(struct timespec *ts)
+{
+ while (ts->tv_nsec >= RT_VDSO_NSEC_PER_SEC)
+ {
+ ts->tv_sec += 1;
+ ts->tv_nsec -= RT_VDSO_NSEC_PER_SEC;
+ }
+
+ while (ts->tv_nsec < 0)
+ {
+ ts->tv_sec -= 1;
+ ts->tv_nsec += RT_VDSO_NSEC_PER_SEC;
+ }
+}
+
+static struct timespec rt_vdso_add_timespec(const struct timespec *lhs,
+ const struct timespec *rhs)
+{
+ struct timespec ret;
+
+ ret.tv_sec = lhs->tv_sec + rhs->tv_sec;
+ ret.tv_nsec = lhs->tv_nsec + rhs->tv_nsec;
+ rt_vdso_normalize_timespec(&ret);
+
+ return ret;
+}
+
+static int rt_vdso_read_monotonic_snapshot(struct timespec *monotonic_time,
+ rt_uint64_t *counter_value,
+ rt_uint64_t *counter_freq)
+{
+ if (rt_clock_boottime_get_ns(monotonic_time) != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+
+ *counter_value = rt_clock_time_get_counter();
+ *counter_freq = rt_clock_time_get_freq();
+
+ return RT_EOK;
+}
+
+static void rt_vdso_store_clock_snapshot(const struct timespec *monotonic_time,
+ rt_uint64_t counter_value,
+ rt_uint64_t counter_freq)
+{
+ rt_vdso_kernel_data_page->counter_last = counter_value;
+ rt_vdso_kernel_data_page->counter_freq = counter_freq;
+ rt_vdso_kernel_data_page->base_time[RT_VDSO_CLOCK_MONOTONIC_INDEX] = *monotonic_time;
+ rt_vdso_kernel_data_page->base_time[RT_VDSO_CLOCK_REALTIME_INDEX] =
+ rt_vdso_add_timespec(monotonic_time, &rt_vdso_realtime_offset);
+}
+
+static void *rt_vdso_map_physical_pages(struct rt_lwp *lwp, void *user_va,
+ void *kernel_pa, size_t map_size,
+ rt_size_t attr)
+{
+ int err;
+ char *va;
+ size_t offset = 0;
+
+ if (!map_size)
+ {
+ return RT_NULL;
+ }
+
+ if (user_va)
+ {
+ if (((size_t)user_va & ARCH_PAGE_MASK) !=
+ ((size_t)kernel_pa & ARCH_PAGE_MASK))
+ {
+ return RT_NULL;
+ }
+ }
+
+ offset = (size_t)kernel_pa & ARCH_PAGE_MASK;
+ map_size += offset + ARCH_PAGE_SIZE - 1;
+ map_size &= ~ARCH_PAGE_MASK;
+ kernel_pa = (void *)((size_t)kernel_pa & ~ARCH_PAGE_MASK);
+ struct rt_mm_va_hint hint = {
+ .flags = 0,
+ .limit_range_size = lwp->aspace->size,
+ .limit_start = lwp->aspace->start,
+ .prefer = user_va,
+ .map_size = map_size,
+ };
+
+ if (user_va != RT_NULL)
+ {
+ hint.flags |= MMF_MAP_FIXED;
+ }
+
+ err = rt_aspace_map_phy(lwp->aspace, &hint, attr, MM_PA_TO_OFF(kernel_pa),
+ (void **)&va);
+ if (err != RT_EOK)
+ {
+ return RT_NULL;
+ }
+
+ return va + offset;
+}
+
+
+static int rt_vdso_map_binary_pages(enum rt_vdso_binary_id binary_id,
+ struct rt_lwp *lwp)
+{
+ void *data_page_base = RT_NULL;
+ void *image_base = RT_NULL;
+ unsigned long data_page_len;
+ unsigned long image_len;
+
+ RT_ASSERT(lwp != RT_NULL);
+
+ data_page_len = RT_VDSO_DATA_PAGE_COUNT * ARCH_PAGE_SIZE;
+ image_len = rt_vdso_binaries[binary_id].page_count << ARCH_PAGE_SHIFT;
+
+ data_page_base = rt_vdso_map_physical_pages(
+ lwp, RT_NULL, rt_kmem_v2p((void *)rt_vdso_get_kernel_data_page()),
+ data_page_len, RT_VDSO_DATA_PAGE_ATTR);
+ if (data_page_base == RT_NULL)
+ {
+ lwp->vdso_vbase = RT_NULL;
+ return RT_ERROR;
+ }
+
+ image_base = (uint8_t *)data_page_base + data_page_len;
+ image_base = rt_vdso_map_physical_pages(
+ lwp, image_base,
+ rt_kmem_v2p((void *)rt_vdso_binaries[binary_id].image_start),
+ image_len, RT_VDSO_IMAGE_PAGE_ATTR);
+ if (image_base == RT_NULL)
+ {
+ lwp_unmap_user_phy(lwp, data_page_base);
+ lwp->vdso_vbase = RT_NULL;
+ return RT_ERROR;
+ }
+
+ lwp->vdso_vbase = image_base;
+ return RT_EOK;
+}
+
+int rt_vdso_map_process_image(struct rt_lwp *lwp)
+{
+ if (rt_vdso_runtime_status != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+
+ return rt_vdso_map_binary_pages(RT_VDSO_BINARY_COMMON, lwp);
+}
+
+void rt_vdso_sync_clock_data(void)
+{
+ struct timespec monotonic;
+ rt_uint64_t counter;
+ rt_uint64_t freq;
+
+ if (rt_vdso_runtime_status != RT_EOK)
+ {
+ return;
+ }
+
+ if (rt_vdso_read_monotonic_snapshot(&monotonic, &counter, &freq) != RT_EOK)
+ {
+ return;
+ }
+
+ 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);
+}
+
+static int rt_vdso_validate_image(void)
+{
+ const Elf64_Ehdr *ehdr =
+ (const Elf64_Ehdr *)rt_vdso_binaries[RT_VDSO_BINARY_COMMON].image_start;
+
+ rt_memset(rt_vdso_data_page_store.raw, 0, sizeof(rt_vdso_data_page_store.raw));
+ rt_vdso_realtime_offset_ready = RT_FALSE;
+
+ if (rt_memcmp(rt_vdso_binaries[RT_VDSO_BINARY_COMMON].image_start,
+ RT_VDSO_IMAGE_ELF_MAGIC, RT_VDSO_IMAGE_ELF_MAGIC_LEN))
+ {
+ LOG_E("vDSO is not a valid ELF object!");
+ rt_vdso_runtime_status = -RT_ERROR;
+ return -RT_ERROR;
+ }
+
+ if (ehdr->e_ident[EI_CLASS] != ELFCLASS64 || ehdr->e_type != ET_DYN)
+ {
+ LOG_E("vDSO ELF class/type mismatch!");
+ rt_vdso_runtime_status = -RT_ERROR;
+ return -RT_ERROR;
+ }
+
+#if defined(__aarch64__)
+ if (ehdr->e_machine != EM_AARCH64)
+ {
+ LOG_E("vDSO machine mismatch: expect AArch64");
+ rt_vdso_runtime_status = -RT_ERROR;
+ return -RT_ERROR;
+ }
+#elif defined(__riscv)
+ if (ehdr->e_machine != EM_RISCV)
+ {
+ LOG_E("vDSO machine mismatch: expect RISC-V");
+ rt_vdso_runtime_status = -RT_ERROR;
+ return -RT_ERROR;
+ }
+#endif
+
+ rt_vdso_binaries[RT_VDSO_BINARY_COMMON].page_count =
+ (rt_vdso_binaries[RT_VDSO_BINARY_COMMON].image_end -
+ rt_vdso_binaries[RT_VDSO_BINARY_COMMON].image_start) >>
+ ARCH_PAGE_SHIFT;
+ if (rt_vdso_binaries[RT_VDSO_BINARY_COMMON].page_count == 0)
+ {
+ LOG_E("vDSO image is empty!");
+ rt_vdso_runtime_status = -RT_ERROR;
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+INIT_COMPONENT_EXPORT(rt_vdso_validate_image);
diff --git a/components/lwp/arch/risc-v/common/vdso_data.c b/components/lwp/arch/risc-v/common/vdso_data.c
deleted file mode 100644
index b457c1f7ee..0000000000
--- a/components/lwp/arch/risc-v/common/vdso_data.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2006-2025 RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
- */
-
-#include <rtthread.h>
-#include <drivers/clock_time.h>
-#include <time.h>
-#include <vdso_datapage.h>
-#include <vdso_data.h>
-#include <encoding.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_clock_boottime_get_ns(vdso_ts);
- vdso_ts->tv_sec = initdata + vdso_ts->tv_sec;
-
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
- rt_clock_boottime_get_ns(vdso_ts);
-
- vdata->cycle_last = rdtime();
- rt_vdso_write_end(vdata);
-}
diff --git a/components/lwp/lwp_elf.c b/components/lwp/lwp_elf.c
index 93aa082d2b..0af6d9c68e 100644
--- a/components/lwp/lwp_elf.c
+++ b/components/lwp/lwp_elf.c
@@ -26,7 +26,7 @@
#endif
#ifdef RT_USING_VDSO
-#include <vdso.h>
+#include <vdso_kernel.h>
#endif
#define DBG_TAG "load.elf"
@@ -783,13 +783,13 @@ static int elf_aux_fill(elf_load_info_t *load_info)
ELF_AUX_ENT(aux_info, AT_SECURE, 0);
#ifdef RT_USING_VDSO
- if(RT_EOK == arch_setup_additional_pages(load_info->lwp))
+ if(RT_EOK == rt_vdso_map_process_image(load_info->lwp))
{
ELF_AUX_ENT(aux_info, AT_SYSINFO_EHDR, (size_t)load_info->lwp->vdso_vbase);
}
else
{
- LOG_W("vdso map error,VDSO currently only supports aarch64 architecture!");
+ LOG_W("vdso map error, skip AT_SYSINFO_EHDR setup");
}
#endif
diff --git a/components/lwp/vdso/SConscript b/components/lwp/vdso/SConscript
index 07889d73a9..33fabc66b7 100644
--- a/components/lwp/vdso/SConscript
+++ b/components/lwp/vdso/SConscript
@@ -16,15 +16,7 @@ if rtconfig.ARCH != "aarch64" and rtconfig.ARCH != "risc-v":
# not supported arch
src = []
else:
- if not hasattr(rtconfig, 'CPP') or rtconfig.CPP is None:
- rtconfig.CPP = rtconfig.PREFIX + 'cpp'
- if not hasattr(rtconfig, 'CPPFLAGS') or rtconfig.CPPFLAGS is None:
- rtconfig.CPPFLAGS = ' -E -P -x assembler-with-cpp'
-
- if not os.path.exists(cwd + "/user" + "/arch" +"/" + rtconfig.ARCH + "/vdso.lds"):
- Preprocessing("user/arch/" + rtconfig.ARCH + "/vdso.lds.S", ".lds", CPPPATH=[cwd])
-
- vdso_arch = os.path.join(cwd, 'user',"arch", rtconfig.ARCH)
+ vdso_user = os.path.join(cwd, 'user')
process_env = os.environ.copy()
if hasattr(rtconfig, 'EXEC_PATH') and rtconfig.EXEC_PATH is not None:
@@ -34,9 +26,9 @@ else:
if hasattr(rtconfig, 'DEVICE') and rtconfig.DEVICE is not None:
process_env['RTT_DEVICE'] = rtconfig.DEVICE
- command = ["scons", "-C", vdso_arch]
+ command = ["scons", "-C", vdso_user, "RTT_VDSO_ARCH=%s" % rtconfig.ARCH]
if GetOption('clean'):
- command = ["scons", "-C", vdso_arch, "--clean"]
+ command = ["scons", "-C", vdso_user, "RTT_VDSO_ARCH=%s" % rtconfig.ARCH, "--clean"]
try:
result = subprocess.run(command, env=process_env, check=True)
diff --git a/components/lwp/vdso/kernel/vdso.h b/components/lwp/vdso/kernel/vdso.h
deleted file mode 100644
index 1cb3b44e8c..0000000000
--- a/components/lwp/vdso/kernel/vdso.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _VDSO_H
-#define _VDSO_H
-
-#include <lwp.h>
-#include <mmu.h>
-#include <vdso_config.h>
-#include <vdso_datapage.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern char __vdso_text_start[];
-extern char __vdso_text_end[];
-
-#define ELF_HEAD "\177ELF"
-#define ELF_HEAD_LEN 4
-#define MAX_PAGES 5
-
-#define __page_aligned_data __attribute__((section(".data.vdso.datapage"))) __attribute__((aligned(VDSO_PAGE_SIZE)))
-
-int arch_setup_additional_pages(struct rt_lwp *lwp);
-void rt_vdso_update_glob_time(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _VDSO_H */
diff --git a/components/lwp/vdso/kernel/vdso_data.h b/components/lwp/vdso/kernel/vdso_data.h
deleted file mode 100644
index 5d077e4a9e..0000000000
--- a/components/lwp/vdso/kernel/vdso_data.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _VDSO_KDATA_H
-#define _VDSO_KDATA_H
-
-#include <rtatomic.h>
-#include <vdso_datapage.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern struct vdso_data *vdso_data;
-
-rt_inline
-struct vdso_data *_get_k_vdso_data(void)
-{
- return vdso_data;
-}
-#define get_k_vdso_data _get_k_vdso_data
-
-rt_inline
-void rt_vdso_write_begin(struct vdso_data *vd)
-{
- rt_atomic_add(&vd[CS_HRES_COARSE].seq, 1);
- rt_atomic_add(&vd[CS_RAW].seq, 1);
-}
-
-rt_inline
-void rt_vdso_write_end(struct vdso_data *vd)
-{
- rt_atomic_add(&vd[CS_HRES_COARSE].seq, 1);
- rt_atomic_add(&vd[CS_RAW].seq, 1);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _VDSO_KDATA_H */
diff --git a/components/lwp/vdso/kernel/vdso_text.S b/components/lwp/vdso/kernel/vdso_image.S
index a8c771682d..4ca5d51a55 100644
--- a/components/lwp/vdso/kernel/vdso_text.S
+++ b/components/lwp/vdso/kernel/vdso_image.S
@@ -8,14 +8,14 @@
* 2024-07-04 rcitach init ver.
*/
-#include <vdso_config.h>
+#include <vdso_constants.h>
- .globl __vdso_text_start, __vdso_text_end
+ .globl __rt_vdso_image_start, __rt_vdso_image_end
.section .rodata
- .balign VDSO_PAGE_SIZE
-__vdso_text_start:
- .incbin VDSO_PATH
- .balign VDSO_PAGE_SIZE
-__vdso_text_end:
+ .balign RT_VDSO_PAGE_SIZE
+__rt_vdso_image_start:
+ .incbin RT_VDSO_IMAGE_PATH
+ .balign RT_VDSO_PAGE_SIZE
+__rt_vdso_image_end:
.previous
diff --git a/components/lwp/vdso/kernel/vdso_kernel.h b/components/lwp/vdso/kernel/vdso_kernel.h
new file mode 100644
index 0000000000..7d13ec7d47
--- /dev/null
+++ b/components/lwp/vdso/kernel/vdso_kernel.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef RT_VDSO_KERNEL_H
+#define RT_VDSO_KERNEL_H
+
+#include <lwp.h>
+#include <vdso_constants.h>
+#include <vdso_data_page.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char __rt_vdso_image_start[];
+extern char __rt_vdso_image_end[];
+
+#define RT_VDSO_IMAGE_ELF_MAGIC "\177ELF"
+#define RT_VDSO_IMAGE_ELF_MAGIC_LEN 4
+#define RT_VDSO_DATA_PAGE_ALIGNED \
+ __attribute__((section(".data.vdso.datapage"))) \
+ __attribute__((aligned(RT_VDSO_PAGE_SIZE)))
+
+int rt_vdso_map_process_image(struct rt_lwp *lwp);
+void rt_vdso_sync_clock_data(void);
+void rt_vdso_sync_realtime(void);
+void rt_vdso_set_realtime(const struct timespec *realtime);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RT_VDSO_KERNEL_H */
diff --git a/components/lwp/vdso/kernel/vdso_kernel_internal.h b/components/lwp/vdso/kernel/vdso_kernel_internal.h
new file mode 100644
index 0000000000..79562a7749
--- /dev/null
+++ b/components/lwp/vdso/kernel/vdso_kernel_internal.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef RT_VDSO_KERNEL_INTERNAL_H
+#define RT_VDSO_KERNEL_INTERNAL_H
+
+#include <rtatomic.h>
+#include <vdso_data_page.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct rt_vdso_data_page *rt_vdso_kernel_data_page;
+
+rt_inline
+struct rt_vdso_data_page *rt_vdso_get_kernel_data_page(void)
+{
+ return rt_vdso_kernel_data_page;
+}
+
+rt_inline
+void rt_vdso_data_page_write_begin(struct rt_vdso_data_page *data_page)
+{
+ rt_atomic_add(&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);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RT_VDSO_KERNEL_INTERNAL_H */
diff --git a/components/lwp/vdso/user/SConstruct b/components/lwp/vdso/user/SConstruct
new file mode 100644
index 0000000000..ffc7c14393
--- /dev/null
+++ b/components/lwp/vdso/user/SConstruct
@@ -0,0 +1,97 @@
+import os
+import subprocess
+
+arch = ARGUMENTS.get('RTT_VDSO_ARCH') or os.getenv('RTT_VDSO_ARCH')
+user_dir = os.path.normpath(Dir('.').abspath)
+vdso_root = os.path.normpath(os.path.join(user_dir, '..'))
+
+arch_def_config = {
+ 'aarch64': {
+ 'prefix': 'aarch64-none-elf-',
+ 'device': '-march=armv8-a -mtune=cortex-a53',
+ 'linker': os.path.join(user_dir, 'arch', 'aarch64', 'vdso.lds.S'),
+ },
+ 'risc-v': {
+ 'prefix': 'riscv64-none-elf-',
+ 'device': '-march=rv64imafdc -mabi=lp64',
+ 'linker': os.path.join(user_dir, 'arch', 'risc-v', 'vdso.lds.S'),
+ },
+}
+
+if arch not in arch_def_config:
+ raise RuntimeError('Unsupported vDSO arch: %s' % arch)
+
+exec_path = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
+prefix = os.getenv('RTT_CC_PREFIX') or arch_def_config[arch]['prefix']
+device = os.getenv('RTT_DEVICE') or arch_def_config[arch]['device']
+linker_script_src = arch_def_config[arch]['linker']
+
+cc = prefix + 'gcc'
+cpp = prefix + 'cpp'
+ar = prefix + 'ar'
+
+common_dir = os.path.join(user_dir, 'common')
+arch_dir = os.path.join(user_dir, 'arch', arch)
+build_dir = os.path.join(user_dir, 'build', arch)
+os.makedirs(build_dir, exist_ok=True)
+linker_script = os.path.join(build_dir, 'vdso.lds')
+
+cflags = ' '.join([
+ device,
+ '-Wall',
+ '-Wextra',
+ '-Wno-unused-parameter',
+ '-Wno-cpp',
+ '-std=gnu99',
+ '-O2',
+ '-fPIC',
+ '-ffreestanding',
+ '-fno-builtin',
+ '-fvisibility=hidden',
+ '-nostdlib',
+ '-nostartfiles',
+])
+
+linkflags = ' '.join([
+ device,
+ '-nostdlib',
+ '-nostartfiles',
+ '-shared',
+ '-Wl,--gc-sections',
+ '-Wl,--build-id=none',
+ '-Wl,-soname=rtt-vdso.so.1',
+ '-T %s' % linker_script,
+])
+
+env = Environment(
+ tools=['gcc', 'link'],
+ AS=cc,
+ ASFLAGS='-x assembler-with-cpp',
+ CC=cc,
+ CFLAGS=cflags,
+ CPP=cpp,
+ AR=ar,
+ LINK=cc,
+ LINKFLAGS=linkflags,
+ CPPPATH=[user_dir, common_dir, arch_dir, vdso_root],
+)
+env.PrependENVPath('PATH', exec_path)
+
+def preprocess_linker_script(target, source, env):
+ cmd = [env['CC'], '-E', '-P', '-x', 'assembler-with-cpp']
+ for include_dir in env['CPPPATH']:
+ cmd.append('-I' + include_dir)
+ cmd.extend([str(source[0]), '-o', str(target[0])])
+ return subprocess.call(cmd)
+
+preprocessed_linker = env.Command(linker_script, linker_script_src, preprocess_linker_script)
+
+target = os.path.join(build_dir, 'libvdso.so')
+source = os.path.join(common_dir, 'vdso_clock_gettime.c')
+objects = [env.SharedObject(target=os.path.join(build_dir, 'vdso_clock_gettime'), source=source)]
+shared_lib = env.SharedLibrary(target=target, source=objects)
+env.Depends(shared_lib, preprocessed_linker)
+
+Clean(shared_lib, build_dir)
+Clean(shared_lib, '.sconsign.dblite')
+env.Default(shared_lib)
diff --git a/components/lwp/vdso/user/arch/aarch64/SConstruct b/components/lwp/vdso/user/arch/aarch64/SConstruct
deleted file mode 100644
index 56bd014926..0000000000
--- a/components/lwp/vdso/user/arch/aarch64/SConstruct
+++ /dev/null
@@ -1,35 +0,0 @@
-import os
-import sys
-
-arguments = sys.argv[2]
-vdso_usr = arguments
-vdso_path = os.path.join(vdso_usr, '..', '..', '..')
-
-EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
-PREFIX = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
-DEVICE = os.getenv('RTT_DEVICE') or ' -march=armv8-a -mtune=cortex-a53'
-
-CC = PREFIX + 'gcc'
-CPP = PREFIX + 'cpp'
-AS = PREFIX + 'gcc'
-AR = PREFIX + 'ar'
-LINK = PREFIX + 'gcc'
-
-AFLAGS = ' -x assembler-with-cpp'
-CFLAGS = DEVICE + ' -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing -Wall -Wno-cpp -std=gnu99 -fdiagnostics-color=always -fPIC -O2'
-LFLAGS = DEVICE + ' -Bsymbolic -Wl,--gc-sections,-u,system_vectors -T {path}/vdso.lds'.format(path=vdso_usr)
-CFLAGS += " -I . -I {vdso_path} ".format(vdso_path=vdso_path)
-
-src = Glob('*.c')
-env = Environment(tools=['gcc', 'link'],
- AS = AS, ASFLAGS = AFLAGS,
- CC = CC, CFLAGS = CFLAGS,
- CPP = CPP, AR = AR,
- LINK = LINK, LINKFLAGS = LFLAGS)
-env.PrependENVPath('PATH', EXEC_PATH)
-
-target = os.path.join(vdso_path, 'user', 'build', 'libvdso.so')
-shared_lib = env.SharedLibrary(target=target, source=src)
-Clean(shared_lib, '{vdso_usr}/vdso.lds'.format(vdso_usr=vdso_usr))
-Clean(shared_lib, '.sconsign.dblite')
-env.Default(shared_lib)
diff --git a/components/lwp/vdso/user/arch/aarch64/vdso.lds.S b/components/lwp/vdso/user/arch/aarch64/vdso.lds.S
index 8b0038ee2d..4b9dace298 100644
--- a/components/lwp/vdso/user/arch/aarch64/vdso.lds.S
+++ b/components/lwp/vdso/user/arch/aarch64/vdso.lds.S
@@ -1,53 +1,38 @@
-/*
- * Copyright (c) 2006-2023, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2024-07-04 rcitach init ver.
- */
-
-#include <vdso_config.h>
+#include <vdso_constants.h>
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
SECTIONS
{
- PROVIDE(_vdso_data = . - __VVAR_PAGES * VDSO_PAGE_SIZE);
+ PROVIDE(__rt_vdso_data_page = . - (RT_VDSO_DATA_PAGE_COUNT * RT_VDSO_PAGE_SIZE));
. = SIZEOF_HEADERS;
- .hash : { *(.hash) } :text
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
+ .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
- .dynamic : { *(.dynamic) } :text :dynamic
- .rela.dyn : ALIGN(8) { *(.rela .rela*) }
-
- .rodata : {
- *(.rodata*)
- *(.got)
- *(.got.plt)
- *(.plt)
- *(.plt.*)
- *(.iplt)
- *(.igot .igot.plt)
- } :text
- /DISCARD/ : {
+ /DISCARD/ : {
*(.data .data.* .sdata*)
- *(.bss .sbss .dynbss .dynsbss)
+ *(.bss .bss.* .sbss .sbss.*)
+ *(.comment*)
+ *(.note*)
+ *(.eh_frame*)
+ *(.interp)
}
}
PHDRS
{
- text PT_LOAD FLAGS(5) FILEHDR PHDRS;
- dynamic PT_DYNAMIC FLAGS(4);
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS;
+ dynamic PT_DYNAMIC FLAGS(4);
}
VERSION
@@ -55,6 +40,7 @@ VERSION
LINUX_2.6.39 {
global:
__kernel_clock_gettime;
- local: *;
+ local:
+ *;
};
}
diff --git a/components/lwp/vdso/user/arch/aarch64/vdso_arch.h b/components/lwp/vdso/user/arch/aarch64/vdso_arch.h
new file mode 100644
index 0000000000..3ae1f0646a
--- /dev/null
+++ b/components/lwp/vdso/user/arch/aarch64/vdso_arch.h
@@ -0,0 +1,38 @@
+#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)
+{
+ uint64_t value;
+ uint64_t tmp;
+
+ __asm__ volatile("mrs %0, CNTVCT_EL0" : "=r"(value));
+ __asm__ volatile(
+ "eor %0, %1, %1\n"
+ "add %0, sp, %0\n"
+ "ldr xzr, [%0]"
+ : "=r"(tmp)
+ : "r"(value));
+
+ return value;
+}
+
+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, ishld);
+}
+
+#endif
diff --git a/components/lwp/vdso/user/arch/aarch64/vdso_sys.c b/components/lwp/vdso/user/arch/aarch64/vdso_sys.c
deleted file mode 100644
index d30e7bbccc..0000000000
--- a/components/lwp/vdso/user/arch/aarch64/vdso_sys.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <time.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <vdso_sys.h>
-
-#ifndef rt_vdso_cycles_ready
-static inline bool rt_vdso_cycles_ready(uint64_t cycles)
-{
- return true;
-}
-#endif
-
-#ifndef rt_vdso_get_ns
-static inline
-uint64_t rt_vdso_get_ns(uint64_t cycles, uint64_t last)
-{
- return (cycles - last) * NSEC_PER_SEC / __arch_get_hw_frq();
-}
-#endif
-
-static int
-__rt_vdso_getcoarse(struct timespec *ts, clockid_t clock, const struct vdso_data *vdns)
-{
- const struct vdso_data *vd;
- const struct timespec *vdso_ts;
- uint32_t seq;
- uint64_t sec, last, ns, cycles;
-
- if (clock != CLOCK_MONOTONIC_RAW)
- vd = &vdns[CS_HRES_COARSE];
- else
- vd = &vdns[CS_RAW];
-
- vdso_ts = &vd->basetime[clock];
-
- do {
- seq = rt_vdso_read_begin(vd);
- cycles = __arch_get_hw_counter();
- if (unlikely(!rt_vdso_cycles_ready(cycles)))
- return -1;
- ns = vdso_ts->tv_nsec;
- last = vd->cycle_last;
- ns += rt_vdso_get_ns(cycles, last);
- sec = vdso_ts->tv_sec;
- } while (unlikely(rt_vdso_read_retry(vd, seq)));
-
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
-
- return 0;
-}
-
-static inline int
-__vdso_clock_gettime_common(const struct vdso_data *vd, clockid_t clock,
- struct timespec *ts)
-{
- u_int32_t msk;
-
- if (unlikely((u_int32_t) clock >= MAX_CLOCKS))
- return -1;
-
- msk = 1U << clock;
- if (likely(msk & VDSO_REALTIME))
- return __rt_vdso_getcoarse(ts,CLOCK_REALTIME,vd);
- else if (msk & VDSO_MONOTIME)
- return __rt_vdso_getcoarse(ts,CLOCK_MONOTONIC,vd);
- else
- return ENOENT;
-}
-
-static __maybe_unused int
-rt_vdso_clock_gettime_data(const struct vdso_data *vd, clockid_t clock,
- struct timespec *ts)
-{
- int ret = 0;
- ret = __vdso_clock_gettime_common(vd, clock, ts);
- return ret;
-}
-
-int
-__kernel_clock_gettime(clockid_t clock, struct timespec *ts)
-{
- return rt_vdso_clock_gettime_data(__arch_get_vdso_data(), clock, ts);
-}
diff --git a/components/lwp/vdso/user/arch/aarch64/vdso_sys.h b/components/lwp/vdso/user/arch/aarch64/vdso_sys.h
deleted file mode 100644
index 60fb12fccb..0000000000
--- a/components/lwp/vdso/user/arch/aarch64/vdso_sys.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ASM_VDSO_SYS_H
-#define ASM_VDSO_SYS_H
-
-#include <time.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <vdso_config.h>
-#include <vdso_datapage.h>
-
-#define __always_unused __attribute__((__unused__))
-#define __maybe_unused __attribute__((__unused__))
-
-#define likely(x) __builtin_expect(!!(x), 1)
-#define unlikely(x) __builtin_expect(!!(x), 0)
-
-#define arch_counter_enforce_ordering(val) do { \
- uint64_t tmp, _val = (val); \
- \
- asm volatile( \
- " eor %0, %1, %1\n" \
- " add %0, sp, %0\n" \
- " ldr xzr, [%0]" \
- : "=r" (tmp) : "r" (_val)); \
-} while (0)
-
-static inline uint64_t __arch_get_hw_counter(void)
-{
- uint64_t res;
-
- __asm__ volatile("mrs %0, CNTVCT_EL0":"=r"(res));
-
- arch_counter_enforce_ordering(res);
- return res;
-}
-
-static inline uint64_t __arch_get_hw_frq()
-{
- uint64_t res;
-
- __asm__ volatile("mrs %0, CNTFRQ_EL0":"=r"(res));
-
- arch_counter_enforce_ordering(res);
- return res;
-}
-
-static inline uint32_t
-__iter_div_u64_rem(uint64_t dividend, uint32_t divisor, uint64_t *remainder)
-{
- uint32_t ret = 0;
-
- while (dividend >= divisor) {
- /* The following asm() prevents the compiler from
- optimising this loop into a modulo operation. */
- __asm__("" : "+rm"(dividend));
-
- dividend -= divisor;
- ret++;
- }
-
- *remainder = dividend;
-
- return ret;
-}
-
-#define __RT_STRINGIFY(x...) #x
-#define RT_STRINGIFY(x...) __RT_STRINGIFY(x)
-#define rt_hw_barrier(cmd, ...) \
- __asm__ volatile (RT_STRINGIFY(cmd) " "RT_STRINGIFY(__VA_ARGS__):::"memory")
-
-#define rt_hw_isb() rt_hw_barrier(isb)
-#define rt_hw_dmb() rt_hw_barrier(dmb, ish)
-#define rt_hw_wmb() rt_hw_barrier(dmb, ishst)
-#define rt_hw_rmb() rt_hw_barrier(dmb, ishld)
-#define rt_hw_dsb() rt_hw_barrier(dsb, ish)
-
-#ifndef barrier
-/* The "volatile" is due to gcc bugs */
-# define barrier() __asm__ __volatile__("": : :"memory")
-#endif
-
-static inline void cpu_relax(void)
-{
- __asm__ volatile("yield" ::: "memory");
-}
-
-#define __READ_ONCE_SIZE \
-({ \
- switch (size) { \
- case 1: *(__u8 *)res = *(volatile __u8 *)p; break; \
- case 2: *(__u16 *)res = *(volatile __u16 *)p; break; \
- case 4: *(__u32 *)res = *(volatile __u32 *)p; break; \
- case 8: *(__u64 *)res = *(volatile __u64 *)p; break; \
- default: \
- barrier(); \
- __builtin_memcpy((void *)res, (const void *)p, size); \
- barrier(); \
- } \
-})
-
-static inline
-void __read_once_size(const volatile void *p, void *res, int size)
-{
- __READ_ONCE_SIZE;
-}
-
-#define __READ_ONCE(x, check) \
-({ \
- union { typeof(x) __val; char __c[1]; } __u; \
- if (check) \
- __read_once_size(&(x), __u.__c, sizeof(x)); \
- smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \
- __u.__val; \
-})
-#define READ_ONCE(x) __READ_ONCE(x, 1)
-
-extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
-static inline struct vdso_data *__arch_get_vdso_data(void)
-{
- return _vdso_data;
-}
-
-static inline uint32_t rt_vdso_read_begin(const struct vdso_data *vd)
-{
- uint32_t seq;
-
- while (unlikely((seq = READ_ONCE(vd->seq)) & 1))
- cpu_relax();
-
- rt_hw_rmb();
- return seq;
-}
-
-static inline uint32_t rt_vdso_read_retry(const struct vdso_data *vd,
- uint32_t start)
-{
- uint32_t seq;
-
- rt_hw_rmb();
- seq = READ_ONCE(vd->seq);
- return seq != start;
-}
-
-#endif
diff --git a/components/lwp/vdso/user/arch/risc-v/SConstruct b/components/lwp/vdso/user/arch/risc-v/SConstruct
deleted file mode 100644
index 4680384ca0..0000000000
--- a/components/lwp/vdso/user/arch/risc-v/SConstruct
+++ /dev/null
@@ -1,62 +0,0 @@
-import os
-import sys
-import subprocess
-
-arguments = sys.argv[2]
-vdso_usr = arguments
-vdso_path = os.path.join(vdso_usr, '..', '..', '..')
-
-EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
-PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-none-elf-'
-
-def get_riscv64_default_arch_abi(gcc_bin):
- try:
- result = subprocess.check_output(
- [gcc_bin, '-Q', '--help=target'],
- universal_newlines=True
- )
- arch = None
- abi = None
- for line in result.splitlines():
- if '-march=' in line:
- arch = line.strip().split()[1]
- arch = arch.split('_')[0] # Get the base architecture, e.g., rv64imafdc
- if '-mabi=' in line and 'option' not in line:
- abi = line.strip().split()[1]
- return arch, abi
- except Exception as e:
- print("Error getting arch/abi:", e)
- return None, None
-
-# get the gcc path
-CC_BIN = PREFIX + 'gcc'
-arch, abi = get_riscv64_default_arch_abi(CC_BIN)
-if arch and abi:
- DEVICE = f' -march={arch} -mabi={abi} '
-else:
- DEVICE = ' -march=rv64imafdc -mabi=lp64' # fallback
-
-CC = PREFIX + 'gcc'
-CPP = PREFIX + 'cpp'
-AS = PREFIX + 'gcc'
-AR = PREFIX + 'ar'
-LINK = PREFIX + 'gcc'
-
-AFLAGS = ' -x assembler-with-cpp'
-CFLAGS = DEVICE + ' -Wall -Wno-cpp -std=gnu99 -fdiagnostics-color=always -fPIC -O2'
-LFLAGS = DEVICE + ' -Bsymbolic -Wl,--gc-sections -T {path}/vdso.lds'.format(path=vdso_usr)
-CFLAGS += " -I . -I {vdso_path} ".format(vdso_path=vdso_path)
-
-src = Glob('*.c')
-env = Environment(tools=['gcc', 'link'],
- AS = AS, ASFLAGS = AFLAGS,
- CC = CC, CFLAGS = CFLAGS,
- CPP = CPP, AR = AR,
- LINK = LINK, LINKFLAGS = LFLAGS)
-env.PrependENVPath('PATH', EXEC_PATH)
-
-target = os.path.join(vdso_path, 'user', 'build', 'libvdso.so')
-shared_lib = env.SharedLibrary(target=target, source=src)
-Clean(shared_lib, '{vdso_usr}/vdso.lds'.format(vdso_usr=vdso_usr))
-Clean(shared_lib, '.sconsign.dblite')
-env.Default(shared_lib)
diff --git a/components/lwp/vdso/user/arch/risc-v/vdso.lds.S b/components/lwp/vdso/user/arch/risc-v/vdso.lds.S
index 956366e93e..b7f51ed887 100644
--- a/components/lwp/vdso/user/arch/risc-v/vdso.lds.S
+++ b/components/lwp/vdso/user/arch/risc-v/vdso.lds.S
@@ -1,53 +1,38 @@
-/*
- * Copyright (c) 2006-2025 RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
- */
-
-#include <vdso_config.h>
+#include <vdso_constants.h>
OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
OUTPUT_ARCH(riscv)
SECTIONS
{
- PROVIDE(_vdso_data = . - __VVAR_PAGES * VDSO_PAGE_SIZE);
+ PROVIDE(__rt_vdso_data_page = . - (RT_VDSO_DATA_PAGE_COUNT * RT_VDSO_PAGE_SIZE));
. = SIZEOF_HEADERS;
- .hash : { *(.hash) } :text
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
+ .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
- .dynamic : { *(.dynamic) } :text :dynamic
- .rela.dyn : ALIGN(8) { *(.rela .rela*) }
-
- .rodata : {
- *(.rodata*)
- *(.got)
- *(.got.plt)
- *(.plt)
- *(.plt.*)
- *(.iplt)
- *(.igot .igot.plt)
- } :text
- /DISCARD/ : {
+ /DISCARD/ : {
*(.data .data.* .sdata*)
- *(.bss .sbss .dynbss .dynsbss)
+ *(.bss .bss.* .sbss .sbss.*)
+ *(.comment*)
+ *(.note*)
+ *(.eh_frame*)
+ *(.interp)
}
}
PHDRS
{
- text PT_LOAD FLAGS(5) FILEHDR PHDRS;
- dynamic PT_DYNAMIC FLAGS(4);
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS;
+ dynamic PT_DYNAMIC FLAGS(4);
}
VERSION
@@ -55,6 +40,7 @@ VERSION
LINUX_2.6 {
global:
__vdso_clock_gettime;
- local: *;
+ local:
+ *;
};
}
diff --git a/components/lwp/vdso/user/arch/risc-v/vdso_arch.h b/components/lwp/vdso/user/arch/risc-v/vdso_arch.h
new file mode 100644
index 0000000000..0cfad6b5d9
--- /dev/null
+++ b/components/lwp/vdso/user/arch/risc-v/vdso_arch.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2026-04-21 rcitach init ver.
+ */
+
+#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)
+{
+ uint64_t value;
+
+ __asm__ volatile("rdtime %0" : "=r"(value));
+ rt_vdso_arch_barrier(fence, rw, rw);
+
+ return value;
+}
+
+static inline void rt_vdso_arch_cpu_relax(void)
+{
+ __asm__ volatile("nop" ::: "memory");
+}
+
+static inline void rt_vdso_arch_rmb(void)
+{
+ rt_vdso_arch_barrier(fence, r, r);
+}
+
+#endif
diff --git a/components/lwp/vdso/user/arch/risc-v/vdso_sys.c b/components/lwp/vdso/user/arch/risc-v/vdso_sys.c
deleted file mode 100644
index bb697aa009..0000000000
--- a/components/lwp/vdso/user/arch/risc-v/vdso_sys.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2006-2025 RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
- * 2025-05-10 Bernard Move __arch_get_hw_frq() to vdso_sys.c as a weak function.
- */
-
-#include <stdio.h>
-#include <time.h>
-#include <errno.h>
-#include <stdbool.h>
-
-#include <vdso_sys.h>
-
-#ifndef rt_vdso_cycles_ready
-static inline bool rt_vdso_cycles_ready(uint64_t cycles)
-{
- return true;
-}
-#endif
-
-#ifndef rt_vdso_get_ns
-/* Implement as a weak function because there is no CPU cycle for RISCV */
-__attribute__((weak)) uint64_t __arch_get_hw_frq()
-{
- return 10000000;
-}
-
-static inline uint64_t rt_vdso_get_ns(uint64_t cycles, uint64_t last)
-{
- return (cycles - last) * NSEC_PER_SEC / __arch_get_hw_frq();
-}
-#endif
-
-static int
-__rt_vdso_getcoarse(struct timespec *ts, clockid_t clock, const struct vdso_data *vdns)
-{
- const struct vdso_data *vd;
- const struct timespec *vdso_ts;
- uint32_t seq;
- uint64_t sec, last, ns, cycles;
-
- if (clock != CLOCK_MONOTONIC_RAW)
- vd = &vdns[CS_HRES_COARSE];
- else
- vd = &vdns[CS_RAW];
-
- vdso_ts = &vd->basetime[clock];
-
- do {
- seq = rt_vdso_read_begin(vd);
- cycles = __arch_get_hw_counter();
- if (unlikely(!rt_vdso_cycles_ready(cycles)))
- return -1;
- ns = vdso_ts->tv_nsec;
- last = vd->cycle_last;
- ns += rt_vdso_get_ns(cycles, last);
- sec = vdso_ts->tv_sec;
- } while (unlikely(rt_vdso_read_retry(vd, seq)));
-
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
-
- return 0;
-}
-
-static inline int
-__vdso_clock_gettime_common(const struct vdso_data *vd, clockid_t clock,
- struct timespec *ts)
-{
- u_int32_t msk;
-
- if (unlikely((u_int32_t)clock >= MAX_CLOCKS))
- return -1;
-
- msk = 1U << clock;
- if (likely(msk & VDSO_REALTIME))
- return __rt_vdso_getcoarse(ts, CLOCK_REALTIME, vd);
- else if (msk & VDSO_MONOTIME)
- return __rt_vdso_getcoarse(ts, CLOCK_MONOTONIC, vd);
- else
- return ENOENT;
-}
-
-static __maybe_unused int
-rt_vdso_clock_gettime_data(const struct vdso_data *vd, clockid_t clock,
- struct timespec *ts)
-{
- int ret = 0;
- ret = __vdso_clock_gettime_common(vd, clock, ts);
- return ret;
-}
-
-int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
-{
- return rt_vdso_clock_gettime_data(__arch_get_vdso_data(), clock, ts);
-}
diff --git a/components/lwp/vdso/user/arch/risc-v/vdso_sys.h b/components/lwp/vdso/user/arch/risc-v/vdso_sys.h
deleted file mode 100644
index fe326c19d0..0000000000
--- a/components/lwp/vdso/user/arch/risc-v/vdso_sys.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2006-2025 RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2025-04-22 ScuDays Add VDSO functionality under the riscv64 architecture.
- */
-
-#ifndef ASM_VDSO_SYS_H
-#define ASM_VDSO_SYS_H
-
-#include <time.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <vdso_config.h>
-#include <vdso_datapage.h>
-
-#define __always_unused __attribute__((__unused__))
-#define __maybe_unused __attribute__((__unused__))
-
-#define likely(x) __builtin_expect(!!(x), 1)
-#define unlikely(x) __builtin_expect(!!(x), 0)
-
-#define arch_counter_enforce_ordering \
- __asm__ volatile("fence rw, rw" ::: "memory")
-
-static inline uint64_t __arch_get_hw_counter(void)
-{
- uint64_t res;
- __asm__ volatile("rdtime %0" : "=r"(res));
- arch_counter_enforce_ordering;
- return res;
-}
-
-static inline uint32_t
-__iter_div_u64_rem(uint64_t dividend, uint32_t divisor, uint64_t *remainder)
-{
- uint32_t ret = 0;
-
- while (dividend >= divisor)
- {
- /* The following asm() prevents the compiler from
- optimising this loop into a modulo operation. */
- __asm__("" : "+rm"(dividend));
-
- dividend -= divisor;
- ret++;
- }
-
- *remainder = dividend;
-
- return ret;
-}
-
-#define __RT_STRINGIFY(x...) #x
-#define RT_STRINGIFY(x...) __RT_STRINGIFY(x)
-#define rt_hw_barrier(cmd, ...) \
- __asm__ volatile(RT_STRINGIFY(cmd) " " RT_STRINGIFY(__VA_ARGS__)::: "memory")
-
-#define rt_hw_isb() rt_hw_barrier(fence.i)
-#define rt_hw_dmb() rt_hw_barrier(fence, rw, rw)
-#define rt_hw_wmb() rt_hw_barrier(fence, w, w)
-#define rt_hw_rmb() rt_hw_barrier(fence, r, r)
-#define rt_hw_dsb() rt_hw_barrier(fence, rw, rw)
-
-#ifndef barrier
-
-#define barrier() __asm__ __volatile__("fence" : : : "memory")
-#endif
-
-static inline void cpu_relax(void)
-{
- __asm__ volatile("nop" ::: "memory");
-}
-
-#define __READ_ONCE_SIZE \
- ({ \
- switch (size) \
- { \
- case 1: \
- *(__u8 *)res = *(volatile __u8 *)p; \
- break; \
- case 2: \
- *(__u16 *)res = *(volatile __u16 *)p; \
- break; \
- case 4: \
- *(__u32 *)res = *(volatile __u32 *)p; \
- break; \
- case 8: \
- *(__u64 *)res = *(volatile __u64 *)p; \
- break; \
- default: \
- barrier(); \
- __builtin_memcpy((void *)res, (const void *)p, size); \
- barrier(); \
- } \
- })
-
-static inline void __read_once_size(const volatile void *p, void *res, int size)
-{
- __READ_ONCE_SIZE;
-}
-
-#define __READ_ONCE(x, check) \
- ({ \
- union { \
- typeof(x) __val; \
- char __c[1]; \
- } __u; \
- if (check) \
- __read_once_size(&(x), __u.__c, sizeof(x)); \
- smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \
- __u.__val; \
- })
-#define READ_ONCE(x) __READ_ONCE(x, 1)
-
-extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
-static inline struct vdso_data *__arch_get_vdso_data(void)
-{
- return _vdso_data;
-}
-
-static inline uint32_t rt_vdso_read_begin(const struct vdso_data *vd)
-{
- uint32_t seq;
-
- while (unlikely((seq = READ_ONCE(vd->seq)) & 1))
- cpu_relax();
-
- rt_hw_rmb();
- return seq;
-}
-
-static inline uint32_t rt_vdso_read_retry(const struct vdso_data *vd,
- uint32_t start)
-{
- uint32_t seq;
-
- rt_hw_rmb();
- seq = READ_ONCE(vd->seq);
- return seq != start;
-}
-
-#endif
diff --git a/components/lwp/vdso/user/common/vdso_clock_gettime.c b/components/lwp/vdso/user/common/vdso_clock_gettime.c
new file mode 100644
index 0000000000..89889d2726
--- /dev/null
+++ b/components/lwp/vdso/user/common/vdso_clock_gettime.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2026-04-21 rcitach init ver.
+ */
+#include "vdso_user_internal.h"
+
+static int rt_vdso_resolve_clock_index(clockid_t clock, unsigned int *index)
+{
+ switch (clock)
+ {
+ case CLOCK_REALTIME:
+ case CLOCK_REALTIME_COARSE:
+ *index = RT_VDSO_CLOCK_REALTIME_INDEX;
+ return 0;
+
+ case CLOCK_MONOTONIC:
+ case CLOCK_MONOTONIC_COARSE:
+ case CLOCK_MONOTONIC_RAW:
+ case CLOCK_BOOTTIME:
+ *index = RT_VDSO_CLOCK_MONOTONIC_INDEX;
+ return 0;
+
+ default:
+ if ((unsigned int)clock >= RT_VDSO_CLOCK_ID_MAX)
+ {
+ return -EINVAL;
+ }
+ return -ENOSYS;
+ }
+}
+
+int rt_vdso_clock_gettime_impl(clockid_t clock, struct timespec *ts)
+{
+ const struct rt_vdso_data_page *data_page = rt_vdso_get_data_page();
+ uint32_t seq;
+ unsigned int index;
+ uint64_t last;
+ uint64_t freq;
+ uint64_t now;
+ uint64_t delta_ns;
+ struct timespec base_time;
+ int ret;
+
+ ret = rt_vdso_resolve_clock_index(clock, &index);
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ do
+ {
+ seq = rt_vdso_data_read_begin(data_page);
+ base_time = data_page->base_time[index];
+ last = data_page->counter_last;
+ freq = data_page->counter_freq;
+ now = rt_vdso_arch_read_counter();
+ } while (unlikely(rt_vdso_data_read_retry(data_page, seq)));
+
+ if (freq == 0)
+ {
+ return -ENOSYS;
+ }
+
+ delta_ns = rt_vdso_counter_delta_to_ns(now, last, freq);
+ rt_vdso_timespec_add_nanoseconds(&base_time, delta_ns);
+ *ts = base_time;
+
+ return 0;
+}
+
+int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
+ __attribute__((alias("rt_vdso_clock_gettime_impl"), visibility("default")));
+
+int __kernel_clock_gettime(clockid_t clock, struct timespec *ts)
+ __attribute__((alias("rt_vdso_clock_gettime_impl"), visibility("default")));
diff --git a/components/lwp/vdso/user/common/vdso_user_internal.h b/components/lwp/vdso/user/common/vdso_user_internal.h
new file mode 100644
index 0000000000..38a66a6eb1
--- /dev/null
+++ b/components/lwp/vdso/user/common/vdso_user_internal.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2026-04-21 rcitach init ver.
+ */
+
+#ifndef RT_VDSO_USER_INTERNAL_H
+#define RT_VDSO_USER_INTERNAL_H
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <time.h>
+#include <sys/types.h>
+
+#include <vdso_data_page.h>
+#include <vdso_arch.h>
+
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
+#ifndef barrier
+#define barrier() __asm__ __volatile__("" : : : "memory")
+#endif
+
+static inline void rt_vdso_read_once_size(const volatile void *ptr, void *dst, int size)
+{
+ switch (size)
+ {
+ case 1:
+ *(uint8_t *)dst = *(const volatile uint8_t *)ptr;
+ break;
+ case 2:
+ *(uint16_t *)dst = *(const volatile uint16_t *)ptr;
+ break;
+ case 4:
+ *(uint32_t *)dst = *(const volatile uint32_t *)ptr;
+ break;
+ case 8:
+ *(uint64_t *)dst = *(const volatile uint64_t *)ptr;
+ break;
+ default:
+ barrier();
+ __builtin_memcpy(dst, (const void *)ptr, size);
+ barrier();
+ break;
+ }
+}
+
+#define READ_ONCE(x) \
+ ({ \
+ union \
+ { \
+ typeof(x) value; \
+ char bytes[sizeof(x)]; \
+ } once; \
+ rt_vdso_read_once_size(&(x), once.bytes, sizeof(x)); \
+ once.value; \
+ })
+
+extern const struct rt_vdso_data_page __rt_vdso_data_page[] __attribute__((visibility("hidden")));
+
+static inline const struct rt_vdso_data_page *rt_vdso_get_data_page(void)
+{
+ return __rt_vdso_data_page;
+}
+
+static inline uint32_t rt_vdso_data_read_begin(const struct rt_vdso_data_page *data_page)
+{
+ uint32_t seq;
+
+ while (unlikely((seq = READ_ONCE(data_page->seq_counter)) & 1U))
+ {
+ rt_vdso_arch_cpu_relax();
+ }
+
+ rt_vdso_arch_rmb();
+ return seq;
+}
+
+static inline uint32_t rt_vdso_data_read_retry(const struct rt_vdso_data_page *data_page,
+ uint32_t start)
+{
+ rt_vdso_arch_rmb();
+ return READ_ONCE(data_page->seq_counter) != start;
+}
+
+static inline uint64_t rt_vdso_counter_delta_to_ns(uint64_t now, uint64_t last,
+ uint64_t freq)
+{
+ if (freq == 0)
+ {
+ return 0;
+ }
+
+ return (now - last) * RT_VDSO_NSEC_PER_SEC / freq;
+}
+
+static inline void rt_vdso_timespec_add_nanoseconds(struct timespec *ts, uint64_t ns)
+{
+ ts->tv_sec += (time_t)(ns / RT_VDSO_NSEC_PER_SEC);
+ ns = (uint64_t)ts->tv_nsec + (ns % RT_VDSO_NSEC_PER_SEC);
+ if (ns >= RT_VDSO_NSEC_PER_SEC)
+ {
+ ts->tv_sec += 1;
+ ns -= RT_VDSO_NSEC_PER_SEC;
+ }
+ ts->tv_nsec = (long)ns;
+}
+
+#endif /* RT_VDSO_USER_INTERNAL_H */
diff --git a/components/lwp/vdso/vdso_config.h b/components/lwp/vdso/vdso_constants.h
index fd79b46b02..ec1cfb6040 100644
--- a/components/lwp/vdso/vdso_config.h
+++ b/components/lwp/vdso/vdso_constants.h
@@ -8,18 +8,16 @@
* 2024-07-04 rcitach init ver.
*/
-#ifndef __ASM_VDSO_H
-#define __ASM_VDSO_H
+#ifndef RT_VDSO_CONSTANTS_H
+#define RT_VDSO_CONSTANTS_H
#ifdef __cplusplus
extern "C" {
#endif
-#define __VVAR_PAGES 2
-#define VDSO_PAGE_SHIFT 12
-#define VDSO_PAGE_SIZE (1 << VDSO_PAGE_SHIFT)
-
-#define BIT_MASK(nr) ((1) << (nr))
+#define RT_VDSO_DATA_PAGE_COUNT 1
+#define RT_VDSO_PAGE_SHIFT 12
+#define RT_VDSO_PAGE_SIZE (1 << RT_VDSO_PAGE_SHIFT)
#ifndef read_barrier_depends
#define read_barrier_depends() do { } while (0)
@@ -29,10 +27,16 @@ extern "C" {
#define smp_read_barrier_depends() read_barrier_depends()
#endif
-#define VDSO_PATH "../user/build/libvdso.so"
+#if defined(__aarch64__)
+#define RT_VDSO_IMAGE_PATH "../user/build/aarch64/libvdso.so"
+#elif defined(__riscv)
+#define RT_VDSO_IMAGE_PATH "../user/build/risc-v/libvdso.so"
+#else
+#error "Unsupported architecture for vDSO"
+#endif
#ifdef __cplusplus
}
#endif
-#endif /* __ASM_VDSO_H */
+#endif /* RT_VDSO_CONSTANTS_H */
diff --git a/components/lwp/vdso/vdso_data_page.h b/components/lwp/vdso/vdso_data_page.h
new file mode 100644
index 0000000000..8bdeaeccae
--- /dev/null
+++ b/components/lwp/vdso/vdso_data_page.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef RT_VDSO_DATA_PAGE_H
+#define RT_VDSO_DATA_PAGE_H
+
+#include <stdint.h>
+#include <time.h>
+#include <sys/types.h>
+#include "vdso_constants.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RT_VDSO_CLOCK_ID_MAX 16
+#define RT_VDSO_NSEC_PER_SEC 1000000000ULL
+
+enum rt_vdso_clock_data_index
+{
+ RT_VDSO_CLOCK_REALTIME_INDEX = 0,
+ RT_VDSO_CLOCK_MONOTONIC_INDEX,
+ RT_VDSO_CLOCK_DATA_COUNT,
+};
+
+struct rt_vdso_data_page
+{
+ uint32_t seq_counter;
+ uint32_t flags;
+ uint64_t counter_last;
+ uint64_t counter_freq;
+ struct timespec base_time[RT_VDSO_CLOCK_DATA_COUNT];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RT_VDSO_DATA_PAGE_H */
diff --git a/components/lwp/vdso/vdso_datapage.h b/components/lwp/vdso/vdso_datapage.h
deleted file mode 100644
index 243af48bf1..0000000000
--- a/components/lwp/vdso/vdso_datapage.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _VDSO_DATAPAGE_H
-#define _VDSO_DATAPAGE_H
-
-#include <time.h>
-#include <sys/types.h>
-#include "vdso_config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef signed char __s8;
-typedef signed short __s16;
-typedef signed int __s32;
-typedef signed long __s64;
-
-typedef unsigned char __u8;
-typedef unsigned short __u16;
-typedef unsigned int __u32;
-typedef unsigned long __u64;
-
-#define MAX_CLOCKS 16
-
-#define VDSO_BASES (CLOCK_TAI + 1)
-#define VDSO_REALTIME (BIT_MASK(CLOCK_REALTIME) | \
- BIT_MASK(CLOCK_REALTIME_COARSE))
-#define VDSO_MONOTIME (BIT_MASK(CLOCK_MONOTONIC) | \
- BIT_MASK(CLOCK_MONOTONIC_COARSE) | \
- BIT_MASK(CLOCK_MONOTONIC_RAW) | \
- BIT_MASK(CLOCK_BOOTTIME))
-
-#define CS_HRES_COARSE 0
-#define CS_RAW 1
-#define CS_BASES (CS_RAW + 1)
-
-/* 2018-01-30 14:44:50 = RTC_TIME_INIT(2018, 1, 30, 14, 44, 50) */
-#define RTC_VDSOTIME_INIT(year, month, day, hour, minute, second) \
- {.tm_year = year - 1900, .tm_mon = month - 1, .tm_mday = day, .tm_hour = hour, .tm_min = minute, .tm_sec = second}
-
-#ifndef SOFT_RTC_VDSOTIME_DEFAULT
-#define SOFT_RTC_VDSOTIME_DEFAULT RTC_VDSOTIME_INIT(2018, 1, 1, 0, 0 ,0)
-#endif
-
-struct vdso_data {
- uint32_t seq;
- uint32_t clock_mode;
- uint64_t realtime_initdata;
- uint64_t cycle_last;
- struct timespec basetime[VDSO_BASES];
-};
-typedef struct vdso_data *vdso_data_t;
-
-#define MSEC_PER_SEC 1000L
-#define USEC_PER_MSEC 1000L
-#define NSEC_PER_USEC 1000L
-#define NSEC_PER_MSEC 1000000L
-#define USEC_PER_SEC 1000000L
-#define NSEC_PER_SEC 1000000000L
-#define FSEC_PER_SEC 1000000000000000LL
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _VDSO_DATAPAGE_H */
diff --git a/components/lwp/vdso/vdso_weak.c b/components/lwp/vdso/vdso_weak.c
deleted file mode 100644
index d628212189..0000000000
--- a/components/lwp/vdso/vdso_weak.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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 <lwp_user_mm.h>
-#include "vdso.h"
-
-rt_weak int arch_setup_additional_pages(struct rt_lwp *lwp)
-{
- return -RT_ERROR;
-}
-
-rt_weak void rt_vdso_update_glob_time(void)
-{
- return ;
-}