first commit for chrg

This commit is contained in:
wmano
2025-08-16 22:58:22 +08:00
commit 52a3ed5862
2306 changed files with 1021208 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
config RT_USING_VDSO
bool "vDSO (Virtual Dynamic Shared Object)"
depends on (ARCH_ARMV8 || ARCH_RISCV)
default y
+51
View File
@@ -0,0 +1,51 @@
import os
import rtconfig
import subprocess
from building import *
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" 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)
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]
if GetOption('clean'):
command = ["scons", "-C", vdso_arch, "--clean"]
try:
result = subprocess.run(command, env=process_env, check=True)
# generic error handle
except :
print('exec command: "%s" failed.' % ' '.join(command))
exit(1)
print("Command executed successfully")
group = DefineGroup('lwProcess', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
Return('group')
@@ -0,0 +1,39 @@
/*
* 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 */
@@ -0,0 +1,48 @@
/*
* 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 */
@@ -0,0 +1,21 @@
/*
* 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>
.globl __vdso_text_start, __vdso_text_end
.section .rodata
.balign VDSO_PAGE_SIZE
__vdso_text_start:
.incbin VDSO_PATH
.balign VDSO_PAGE_SIZE
__vdso_text_end:
.previous
@@ -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)
@@ -0,0 +1,60 @@
/*
* 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>
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
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.39 {
global:
__kernel_clock_gettime;
local: *;
};
}
@@ -0,0 +1,95 @@
/*
* 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);
}
@@ -0,0 +1,153 @@
/*
* 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
@@ -0,0 +1,62 @@
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)
@@ -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: *;
};
}
@@ -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();
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);
}
@@ -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(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
@@ -0,0 +1,38 @@
/*
* 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_H
#define __ASM_VDSO_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))
#ifndef read_barrier_depends
#define read_barrier_depends() do { } while (0)
#endif
#ifndef smp_read_barrier_depends
#define smp_read_barrier_depends() read_barrier_depends()
#endif
#define VDSO_PATH "../user/build/libvdso.so"
#ifdef __cplusplus
}
#endif
#endif /* __ASM_VDSO_H */
@@ -0,0 +1,75 @@
/*
* 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 */
+23
View File
@@ -0,0 +1,23 @@
/*
* 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 ;
}