diff --git a/components/lwp/Kconfig b/components/lwp/Kconfig index 8740fc34577..4a83405d8a0 100644 --- a/components/lwp/Kconfig +++ b/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 - diff --git a/components/lwp/SConscript b/components/lwp/SConscript index cd8a2428a5b..6eb8763fde5 100644 --- a/components/lwp/SConscript +++ b/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) diff --git a/components/lwp/arch/aarch64/common/vdso.c b/components/lwp/arch/common/vdso.c similarity index 52% rename from components/lwp/arch/aarch64/common/vdso.c rename to components/lwp/arch/common/vdso.c index 41b0a6d8f0e..823fd5b61e9 100644 --- a/components/lwp/arch/aarch64/common/vdso.c +++ b/components/lwp/arch/common/vdso.c @@ -1,68 +1,73 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * 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 #include -#include #include #include "vdso.h" #include "vdso_datapage.h" -#define DBG_TAG "vdso" -#define DBG_LVL DBG_INFO +#define DBG_TAG "vdso" +#define DBG_LVL DBG_INFO #include -enum vdso_abi { - VDSO_ABI_AA64, +enum vdso_abi +{ + VDSO_ABI_COMMON, }; -enum vvar_pages { + +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; + +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, - }, + [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]; + 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; +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; + 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) + if (vdso_base != RT_NULL) { ret = RT_EOK; } @@ -70,8 +75,9 @@ static int __setup_additional_pages(enum vdso_abi abi, struct rt_lwp *lwp) { 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); + 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; @@ -81,28 +87,28 @@ 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); + ret = __setup_additional_pages(VDSO_ABI_COMMON, lwp); return ret; } + static void __initdata(void) { - struct tm time_vdso = SOFT_RTC_VDSOTIME_DEFAULT; + 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)) { + 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_AA64].vdso_pages = ( - vdso_info[VDSO_ABI_AA64].vdso_code_end - - vdso_info[VDSO_ABI_AA64].vdso_code_start) >> - ARCH_PAGE_SHIFT; + 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; diff --git a/components/lwp/arch/risc-v/rv64/reloc.c b/components/lwp/arch/risc-v/common/reloc.c similarity index 77% rename from components/lwp/arch/risc-v/rv64/reloc.c rename to components/lwp/arch/risc-v/common/reloc.c index bdd8d310aa4..bc7c2dc97e3 100644 --- a/components/lwp/arch/risc-v/rv64/reloc.c +++ b/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++) { diff --git a/components/lwp/arch/risc-v/common/vdso_data.c b/components/lwp/arch/risc-v/common/vdso_data.c new file mode 100644 index 00000000000..e31305af8f1 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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); +} diff --git a/components/lwp/terminal/Kconfig b/components/lwp/terminal/Kconfig index a62df007538..bbc030014c5 100644 --- a/components/lwp/terminal/Kconfig +++ b/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. diff --git a/components/lwp/vdso/Kconfig b/components/lwp/vdso/Kconfig index 144a945892e..883414dd973 100644 --- a/components/lwp/vdso/Kconfig +++ b/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 diff --git a/components/lwp/vdso/SConscript b/components/lwp/vdso/SConscript index addcdfc8409..4360e8bf238 100644 --- a/components/lwp/vdso/SConscript +++ b/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') diff --git a/components/lwp/vdso/kernel/vdso_text.S b/components/lwp/vdso/kernel/vdso_text.S index f9c1f8aa720..a8c771682dd 100644 --- a/components/lwp/vdso/kernel/vdso_text.S +++ b/components/lwp/vdso/kernel/vdso_text.S @@ -8,7 +8,7 @@ * 2024-07-04 rcitach init ver. */ -#include +#include .globl __vdso_text_start, __vdso_text_end .section .rodata diff --git a/components/lwp/vdso/user/SConstruct b/components/lwp/vdso/user/SConstruct deleted file mode 100644 index a7cee1127f6..00000000000 --- a/components/lwp/vdso/user/SConstruct +++ /dev/null @@ -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) diff --git a/components/lwp/vdso/user/arch/aarch64/SConstruct b/components/lwp/vdso/user/arch/aarch64/SConstruct new file mode 100644 index 00000000000..56bd014926e --- /dev/null +++ b/components/lwp/vdso/user/arch/aarch64/SConstruct @@ -0,0 +1,35 @@ +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/vdso.lds.S b/components/lwp/vdso/user/arch/aarch64/vdso.lds.S similarity index 100% rename from components/lwp/vdso/user/vdso.lds.S rename to components/lwp/vdso/user/arch/aarch64/vdso.lds.S diff --git a/components/lwp/vdso/user/vdso_sys.c b/components/lwp/vdso/user/arch/aarch64/vdso_sys.c similarity index 97% rename from components/lwp/vdso/user/vdso_sys.c rename to components/lwp/vdso/user/arch/aarch64/vdso_sys.c index 61da379f045..d30e7bbccc4 100644 --- a/components/lwp/vdso/user/vdso_sys.c +++ b/components/lwp/vdso/user/arch/aarch64/vdso_sys.c @@ -46,7 +46,7 @@ __rt_vdso_getcoarse(struct timespec *ts, clockid_t clock, const struct vdso_data do { seq = rt_vdso_read_begin(vd); - cycles = __arch_get_hw_counter(vd->clock_mode, vd); + cycles = __arch_get_hw_counter(); if (unlikely(!rt_vdso_cycles_ready(cycles))) return -1; ns = vdso_ts->tv_nsec; diff --git a/components/lwp/vdso/user/vdso_sys.h b/components/lwp/vdso/user/arch/aarch64/vdso_sys.h similarity index 98% rename from components/lwp/vdso/user/vdso_sys.h rename to components/lwp/vdso/user/arch/aarch64/vdso_sys.h index ecc7b366adf..60fb12fccb4 100644 --- a/components/lwp/vdso/user/vdso_sys.h +++ b/components/lwp/vdso/user/arch/aarch64/vdso_sys.h @@ -33,7 +33,7 @@ : "=r" (tmp) : "r" (_val)); \ } while (0) -static inline uint64_t __arch_get_hw_counter() +static inline uint64_t __arch_get_hw_counter(void) { uint64_t res; diff --git a/components/lwp/vdso/user/arch/risc-v/SConstruct b/components/lwp/vdso/user/arch/risc-v/SConstruct new file mode 100644 index 00000000000..6613239bf2b --- /dev/null +++ b/components/lwp/vdso/user/arch/risc-v/SConstruct @@ -0,0 +1,35 @@ +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) +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 new file mode 100644 index 00000000000..956366e93ea --- /dev/null +++ b/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 + +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: *; + }; +} diff --git a/components/lwp/vdso/user/arch/risc-v/vdso_sys.c b/components/lwp/vdso/user/arch/risc-v/vdso_sys.c new file mode 100644 index 00000000000..bb697aa0094 --- /dev/null +++ b/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 +#include +#include +#include + +#include + +#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 new file mode 100644 index 00000000000..fe326c19d01 --- /dev/null +++ b/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 +#include +#include + +#include +#include + +#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/xmake.lua b/components/lwp/vdso/user/xmake.lua deleted file mode 100644 index c36448131f7..00000000000 --- a/components/lwp/vdso/user/xmake.lua +++ /dev/null @@ -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() diff --git a/components/lwp/vdso/vdso_config.h b/components/lwp/vdso/vdso_config.h index ec5d775a332..fd79b46b022 100644 --- a/components/lwp/vdso/vdso_config.h +++ b/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 } diff --git a/components/lwp/vdso/vdso_weak.c b/components/lwp/vdso/vdso_weak.c index 56f452cc877..d6282121899 100644 --- a/components/lwp/vdso/vdso_weak.c +++ b/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 ; }