Browse Source

[smart] Add vDSO support for RISC-V architecture and refactor related components

- Implemented vDSO functionality for the RISC-V architecture, including the necessary source files and linker scripts.
- Introduced a new `vdso_sys.c` file for RISC-V, containing functions to handle time retrieval using the vDSO mechanism.
- Created architecture-specific linker scripts (`vdso.lds.S`) for both AArch64 and RISC-V.
- Updated the build system to support vDSO compilation for RISC-V, including necessary adjustments in `SConstruct` files.
- Refactored existing vDSO code to improve compatibility and maintainability across architectures.
- Adjusted the maximum number of PTY devices in the terminal configuration from 64 to 32 for better resource management.
- Fixed minor issues in existing code, including correcting the path for the vDSO shared library and ensuring proper function definitions.
bernard 1 week ago
parent
commit
721dfbfe01

+ 1 - 2
components/lwp/Kconfig

@@ -1,5 +1,5 @@
 menuconfig RT_USING_LWP
-    bool "light-weight process"
+    bool "lwP(light weight Process)"
     depends on RT_USING_SMART
     default y
     help
@@ -87,4 +87,3 @@ if RT_USING_LWP
 rsource "terminal/Kconfig"
 rsource "vdso/Kconfig"
 endif
-

+ 3 - 0
components/lwp/SConscript

@@ -25,11 +25,14 @@ if platform in platform_file.keys(): # support platforms
     if arch in support_arch.keys() and cpu in support_arch[arch]:
         asm_path = 'arch/' + arch + '/' + cpu + '/*_' + platform_file[platform]
         arch_common = 'arch/' + arch + '/' + 'common/*.c'
+        common = 'arch/common/*.c'
         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]
         else:
             src += Glob(arch_common)
+            src += Glob(common)
         if not GetDepend('ARCH_MM_MMU'):
             excluded_files = ['ioremap.c', 'lwp_futex.c', 'lwp_mm_area.c', 'lwp_pmutex.c', 'lwp_shm.c', 'lwp_user_mm.c']
             src += [f for f in Glob('*.c') if os.path.basename(str(f)) not in excluded_files] + Glob(asm_path)

+ 0 - 110
components/lwp/arch/aarch64/common/vdso.c

@@ -1,110 +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 <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);

+ 12 - 12
components/lwp/arch/risc-v/rv64/reloc.c → components/lwp/arch/risc-v/common/reloc.c

@@ -10,19 +10,19 @@
 
 typedef struct
 {
-    Elf64_Word st_name;
-    Elf64_Addr st_value;
-    Elf64_Word st_size;
+    Elf64_Word    st_name;
+    Elf64_Addr    st_value;
+    Elf64_Word    st_size;
     unsigned char st_info;
     unsigned char st_other;
-    Elf64_Half st_shndx;
+    Elf64_Half    st_shndx;
 } Elf64_sym;
 
 #ifdef ARCH_MM_MMU
 void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf64_sym *dynsym)
 {
     size_t rel_off;
-    void* addr;
+    void  *addr;
 
     if (rel_dyn_size && !dynsym)
     {
@@ -40,7 +40,7 @@ void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, s
         addr = rt_hw_mmu_v2p(aspace, (void *)((rt_size_t)text_start + v1));
         if ((v2 & 0xff) == R_ARM_RELATIVE)
         {
-            *(rt_size_t*)addr += (rt_size_t)text_start;
+            *(rt_size_t *)addr += (rt_size_t)text_start;
         }
         else if ((v2 & 0xff) == R_ARM_ABS32)
         {
@@ -48,18 +48,18 @@ void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, s
             t = (v2 >> 8);
             if (t) /* 0 is UDF */
             {
-                *(rt_size_t*)addr = (((rt_size_t)text_start) + dynsym[t].st_value);
+                *(rt_size_t *)addr = (((rt_size_t)text_start) + dynsym[t].st_value);
             }
         }
     }
     /* modify got */
     if (got_size)
     {
-        uint32_t *got_item = (uint32_t*)got_start;
+        uint32_t *got_item = (uint32_t *)got_start;
 
         for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
         {
-            addr = rt_hw_mmu_v2p(aspace, got_item);
+            addr                = rt_hw_mmu_v2p(aspace, got_item);
             *(rt_size_t *)addr += (rt_size_t)text_start;
         }
     }
@@ -83,7 +83,7 @@ void arch_elf_reloc(void *text_start, void *rel_dyn_start, size_t rel_dyn_size,
 
         if ((v2 & 0xff) == R_ARM_RELATIVE)
         {
-            *(uint32_t*)(((rt_size_t)text_start) + v1) += (uint32_t)text_start;
+            *(uint32_t *)(((rt_size_t)text_start) + v1) += (uint32_t)text_start;
         }
         else if ((v2 & 0xff) == R_ARM_ABS32)
         {
@@ -91,14 +91,14 @@ void arch_elf_reloc(void *text_start, void *rel_dyn_start, size_t rel_dyn_size,
             t = (v2 >> 8);
             if (t) /* 0 is UDF */
             {
-                *(uint32_t*)(((rt_size_t)text_start) + v1) = (uint32_t)(((rt_size_t)text_start) + dynsym[t].st_value);
+                *(uint32_t *)(((rt_size_t)text_start) + v1) = (uint32_t)(((rt_size_t)text_start) + dynsym[t].st_value);
             }
         }
     }
     /* modify got */
     if (got_size)
     {
-        uint32_t *got_item = (uint32_t*)got_start;
+        uint32_t *got_item = (uint32_t *)got_start;
 
         for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
         {

+ 34 - 0
components/lwp/arch/risc-v/common/vdso_data.c

@@ -0,0 +1,34 @@
+/*
+ * 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 <ktime.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_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 = rdtime();
+    rt_vdso_write_end(vdata);
+}

+ 1 - 1
components/lwp/terminal/Kconfig

@@ -7,7 +7,7 @@ menuconfig LWP_USING_TERMINAL
 if LWP_USING_TERMINAL
     config LWP_PTY_MAX_PARIS_LIMIT
         int "Max number of pty devices registered at the same time"
-        default 64
+        default 32
         help
             This upper limit is set to protect kernel memory from draining
             out by the application if it keeps allocating pty devices.

+ 3 - 3
components/lwp/vdso/Kconfig

@@ -1,4 +1,4 @@
-menuconfig RT_USING_VDSO
-    bool "vDSO"
+config RT_USING_VDSO
+    bool "vDSO (??Virtual Dynamic Shared Object)"
+    depends on (ARCH_ARMV8 || ARCH_RISCV)
     default y
-    depends on RT_USING_SMART && ARCH_ARMV8

+ 40 - 36
components/lwp/vdso/SConscript

@@ -2,47 +2,51 @@ import os
 import rtconfig
 import subprocess
 from building import *
-Import('RTT_ROOT')
 
-group = []
-
-cwd = GetCurrentDir()
+group   = []
+cwd     = GetCurrentDir()
 CPPPATH = [cwd, cwd + "/kernel"]
+list    = os.listdir(cwd)
+src     = Glob('kernel/*.c') + Glob('kernel/*.S')
 
 if not GetDepend(['RT_USING_VDSO']):
     Return('group')
 
-if rtconfig.ARCH != "aarch64":
-    src = Glob('*.c')
-    group = DefineGroup('VDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
-    Return('group')
-
-list = os.listdir(cwd)
-src    = Glob('kernel/*.c')
-src    +=Glob('kernel/*.S')
-
-if not os.path.exists(cwd + "/user/vdso.lds"):
-    Preprocessing("user/vdso.lds.S", ".lds", CPPPATH=[cwd])
-
-#aarch64 vdso xmake
-# vdso_file = os.path.join(cwd, 'usr', 'xmake.lua')
-# command = ["xmake", "-F", vdso_file]
-# clean = ["xmake", "clean"]
-
-vdso_file = os.path.join(cwd, 'user', 'SConstruct')
-command = ["scons", "-f", vdso_file]
-clean = ["scons", "-f", vdso_file, "--clean"]
-
-if not GetOption('clean'):
-    result = subprocess.run(command)
+if rtconfig.ARCH != "aarch64" and rtconfig.ARCH != "risc-v":
+    # not supported arch
+    src = []
 else:
-    result = subprocess.run(clean)
-
-if result.returncode == 0:
-    print("Command executed successfully")
-else:
-    print("Command failed with exit code:", result.returncode)
-    exit(1)
-
-group = DefineGroup('VDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
+    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)
+
+    process_env = os.environ.copy()
+    if hasattr(rtconfig, 'EXEC_PATH') and rtconfig.EXEC_PATH is not None:
+        process_env['RTT_EXEC_PATH'] = rtconfig.EXEC_PATH
+    if hasattr(rtconfig, 'PREFIX') and rtconfig.PREFIX is not None:
+        process_env['RTT_CC_PREFIX'] = rtconfig.PREFIX
+    if hasattr(rtconfig, 'DEVICE') and rtconfig.DEVICE is not None:
+        process_env['RTT_DEVICE'] = rtconfig.DEVICE
+
+    command = ["scons", "-C", vdso_arch]
+    clean_command = ["scons", "-C", vdso_arch, "--clean"] 
+
+    if not GetOption('clean'):    
+        result = subprocess.run(command, env=process_env, check=True)
+    else:
+        result = subprocess.run(clean_command, env=process_env, check=True)
+
+    if result.returncode == 0:
+        print("Command executed successfully")
+    else:
+        print("Command failed with exit code:", result.returncode)
+        exit(1)
+
+group = DefineGroup('vDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
 Return('group')

+ 1 - 1
components/lwp/vdso/kernel/vdso_text.S

@@ -8,7 +8,7 @@
  * 2024-07-04     rcitach        init ver.
  */
  
-#include <vdso_config.h>    
+#include <vdso_config.h>
 
     .globl __vdso_text_start, __vdso_text_end
     .section .rodata

+ 0 - 39
components/lwp/vdso/user/SConstruct

@@ -1,39 +0,0 @@
-import os
-import sys
-import subprocess
-
-arguments = sys.argv[2]
-vdso_usr = os.path.dirname(arguments)
-vdso_root = os.path.dirname(vdso_usr)
-
-
-EXEC_PATH  = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
-PREFIX     = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
-
-CC      = PREFIX + 'gcc'
-CXX     = PREFIX + 'g++'
-CPP     = PREFIX + 'cpp'
-AS      = PREFIX + 'gcc'
-AR      = PREFIX + 'ar'
-LINK    = PREFIX + 'gcc'
-
-DEVICE   = ' -march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'
-CXXFLAGS = DEVICE + ' -Wall -fdiagnostics-color=always'
-AFLAGS   = ' -x assembler-with-cpp'
-CFLAGS  = DEVICE + ' -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 {path} -I{path}/user".format(path=vdso_root)
-
-env = Environment(tools=['gcc', 'link'],
-    AS   = AS,   ASFLAGS = AFLAGS,
-    CC   = CC,   CFLAGS = CFLAGS,
-    CXX  = CXX,  CXXFLAGS = CXXFLAGS,
-    AR   = AR,   
-    LINK = LINK, LINKFLAGS = LFLAGS)
-env.PrependENVPath('PATH', EXEC_PATH)
-
-src = os.path.join(vdso_usr,'vdso_sys.c')
-target_name = 'librtos_vdso.so'
-target = os.path.join(vdso_usr, "build", target_name)
-shared_lib = env.SharedLibrary(target=target, source=src)
-env.Default(shared_lib)

+ 33 - 0
components/lwp/vdso/user/arch/aarch64/SConstruct

@@ -0,0 +1,33 @@
+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)
+env.Default(shared_lib)

+ 0 - 0
components/lwp/vdso/user/vdso.lds.S → components/lwp/vdso/user/arch/aarch64/vdso.lds.S


+ 0 - 0
components/lwp/vdso/user/vdso_sys.c → components/lwp/vdso/user/arch/aarch64/vdso_sys.c


+ 0 - 0
components/lwp/vdso/user/vdso_sys.h → components/lwp/vdso/user/arch/aarch64/vdso_sys.h


+ 33 - 0
components/lwp/vdso/user/arch/risc-v/SConstruct

@@ -0,0 +1,33 @@
+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 'riscv64-none-elf-'
+DEVICE    = os.getenv('RTT_DEVICE') or ' -march=rv64imafdc -mabi=lp64'
+
+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)
+env.Default(shared_lib)

+ 60 - 0
components/lwp/vdso/user/arch/risc-v/vdso.lds.S

@@ -0,0 +1,60 @@
+/*
+ * 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>
+
+OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
+OUTPUT_ARCH(riscv)
+
+SECTIONS
+{
+    PROVIDE(_vdso_data = . - __VVAR_PAGES * 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) }
+
+    .dynamic     : { *(.dynamic) }    :text    :dynamic
+    .rela.dyn    : ALIGN(8) { *(.rela .rela*) }
+
+    .rodata      : {
+        *(.rodata*) 
+        *(.got)
+        *(.got.plt)
+        *(.plt)
+        *(.plt.*)
+        *(.iplt)
+        *(.igot .igot.plt)
+    }    :text
+    /DISCARD/    : {
+        *(.data .data.* .sdata*)
+        *(.bss .sbss .dynbss .dynsbss)
+    }
+}
+
+PHDRS
+{
+    text        PT_LOAD       FLAGS(5) FILEHDR PHDRS;
+    dynamic     PT_DYNAMIC    FLAGS(4);
+}
+
+VERSION
+{
+    LINUX_2.6 {
+    global:
+        __vdso_clock_gettime;
+    local: *;
+    };
+}

+ 101 - 0
components/lwp/vdso/user/arch/risc-v/vdso_sys.c

@@ -0,0 +1,101 @@
+/*
+ * 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(vd->clock_mode, vd);
+        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);
+}

+ 147 - 0
components/lwp/vdso/user/arch/risc-v/vdso_sys.h

@@ -0,0 +1,147 @@
+/*
+ * 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()
+{
+    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

+ 0 - 58
components/lwp/vdso/user/xmake.lua

@@ -1,58 +0,0 @@
-/*
- * 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.
- */
- 
-toolchain("aarch64-smart-musleabi")
-    set_kind("standalone")
-    
-    local exec_path = os.getenv("RTT_EXEC_PATH") or "/opt/aarch64-linux-musleabi/bin/"
-    local sdkdir = exec_path .. "/../"
-    local incdir = os.curdir() .. "/../include"
-    local device = '-march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'
-    
-    set_bindir(exec_path)
-    set_sdkdir(sdkdir)
-    
-    set_toolset("sh", "aarch64-linux-musleabi-gcc")
-    on_load(function(toolchain)
-        toolchain:load_cross_toolchain()
-        toolchain:add("cxflags", device)
-        toolchain:add("cxflags", "-Wall -Wno-cpp -std=gnu99")
-        toolchain:add("cxflags", "-fdiagnostics-color=always")
-        toolchain:add("cxflags", "-O2")
-        toolchain:add("cxflags", "-I" .. incdir)
-
-        toolchain:add("shflags", device)
-        toolchain:add("shflags", "-Wl,--gc-sections")
-        toolchain:add("shflags", "-u,system_vectors")
-        toolchain:add("shflags", "-T vdso.lds")
-    end)
-toolchain_end()
-
-set_config("plat", "cross")
-set_config("target_os", "rt-smart")
-set_config("arch", "aarch64")
-
-rule("vdso_lds")
-    set_extensions(".lds.S")
-    on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
-        local incdir = os.curdir() .. "/../include"
-        local targetfile = path.basename(sourcefile)
-        local prefix = os.getenv("RTT_CC_PREFIX=") or "aarch64-linux-musleabi-"
-        batchcmds:vrunv(prefix .. "gcc", {"-E", "-P", sourcefile, "-o", targetfile, "-I", incdir})
-    end)
-
-target("rtos_vdso")
-    set_toolchains("aarch64-smart-musleabi")
-    add_rules("vdso_lds")
-    set_kind("shared")
-    add_files("vdso.lds.S")
-    add_files("vdso_sys.c")
-    set_targetdir("build")
-target_end()

+ 3 - 3
components/lwp/vdso/vdso_config.h

@@ -15,11 +15,11 @@
 extern "C" {
 #endif
 
-#define __VVAR_PAGES    2
+#define __VVAR_PAGES        2
 #define VDSO_PAGE_SHIFT     12
 #define VDSO_PAGE_SIZE      (1 << VDSO_PAGE_SHIFT)
 
-#define BIT_MASK(nr)         ((1) << (nr))
+#define BIT_MASK(nr)        ((1) << (nr))
 
 #ifndef read_barrier_depends
 #define read_barrier_depends()      do { } while (0)
@@ -29,7 +29,7 @@ extern "C" {
 #define smp_read_barrier_depends()  read_barrier_depends()
 #endif
 
-#define VDSO_PATH "../user/build/librtos_vdso.so"
+#define VDSO_PATH "../user/build/libvdso.so"
 
 #ifdef __cplusplus
 }

+ 1 - 1
components/lwp/vdso/vdso_weak.c

@@ -19,5 +19,5 @@ rt_weak int arch_setup_additional_pages(struct rt_lwp *lwp)
 
 rt_weak void rt_vdso_update_glob_time(void)
 {
-
+    return ;
 }