From 5a28bd1c151ab2a504d2297e618c93fe2fb64ede Mon Sep 17 00:00:00 2001 From: idings Date: Wed, 15 Nov 2023 21:29:43 +0800 Subject: [PATCH 1/2] [libc][picolibc] add tls support --- bsp/qemu-vexpress-a9/link.lds | 29 ++++++++++++++++++++ bsp/qemu-vexpress-a9/rtconfig.py | 4 ++- examples/libc/SConscript | 5 +++- examples/libc/tls.c | 45 ++++++++++++++++++++++++++++++++ include/rtdef.h | 13 +++++++++ src/scheduler_mp.c | 6 +++++ src/scheduler_up.c | 3 +++ src/thread.c | 9 +++++++ 8 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 examples/libc/tls.c diff --git a/bsp/qemu-vexpress-a9/link.lds b/bsp/qemu-vexpress-a9/link.lds index 83acbe95fdc6..2efd80c2ec20 100644 --- a/bsp/qemu-vexpress-a9/link.lds +++ b/bsp/qemu-vexpress-a9/link.lds @@ -85,6 +85,35 @@ SECTIONS } __data_end = .; + . = ALIGN(8); + .tdata : + { + __tdata_start = .; + *(.tdata .tdata.* .gnu.linkonce.td.*) + __tdata_end = .; + } + __tdata_source = LOADADDR(.tdata); + __tdata_size = SIZEOF(.tdata); + + /* + * TLS zeroed data is relocated as if it immediately followed + * the tdata values. However, the linker 'magically' erases the + * memory allocation so that no ROM is consumed by this + * section + */ + .tbss : + { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + __tbss_end = .; + } + __tls_size = __tbss_end - __tdata_start; + __tbss_size = __tls_size - __tdata_size; + PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) ); + . = ALIGN(4); __bss_start = .; .bss : diff --git a/bsp/qemu-vexpress-a9/rtconfig.py b/bsp/qemu-vexpress-a9/rtconfig.py index 77cc9dfb4ab9..4436e9a3ba19 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.py +++ b/bsp/qemu-vexpress-a9/rtconfig.py @@ -49,7 +49,9 @@ def get_mac_address(): STRIP = PREFIX + 'strip' CFPFLAGS = ' -msoft-float' AFPFLAGS = ' -mfloat-abi=softfp -mfpu=neon' - DEVICE = ' -march=armv7-a -mtune=cortex-a7 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing' + DEVICE = '' + #DEVICE += ' --specs=picolibc.specs --picolibc-prefix=' + EXEC_PATH + '/../' + DEVICE += ' -march=armv7-a -mtune=cortex-a7 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing' CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall -fdiagnostics-color=always' CFLAGS = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99 -D_POSIX_SOURCE -fdiagnostics-color=always' diff --git a/examples/libc/SConscript b/examples/libc/SConscript index e9794f3de08f..d1620dfd5fae 100644 --- a/examples/libc/SConscript +++ b/examples/libc/SConscript @@ -1,6 +1,9 @@ from building import * src = Glob('*.c') -group = DefineGroup('UTest', src, depend = ['RT_USING_NEWLIBC', 'RT_USING_PTHREADS']) +if GetDepend(['RT_USING_PICOLIBC']): + group = DefineGroup('UTest', src, depend = ['RT_USING_PTHREADS']) +else: + group = DefineGroup('UTest', src, depend = ['RT_USING_NEWLIBC', 'RT_USING_PTHREADS']) Return('group') diff --git a/examples/libc/tls.c b/examples/libc/tls.c new file mode 100644 index 000000000000..83e0ccdb5f67 --- /dev/null +++ b/examples/libc/tls.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-12-19 iDings first version + */ + +#include +#include +#include +#include +#include + +static __thread int i; + +static void child_routine(void *param) +{ + printf("child_thread: i:%d\n", i); + i = 300; + printf("child_thread: i:%d\n", i); +} + +static int tls_test(void) +{ + rt_thread_t child; + + char name[RT_NAME_MAX]; + rt_thread_get_name(rt_thread_self(), name, sizeof(name)); + + printf("i:%d\n", i); + i = 200; + printf("main_thread: i:%d\n", i); + + child = rt_thread_create("tls_thread", child_routine, NULL, 4096, 10, 20); + rt_thread_startup(child); + + sleep(1); + printf("main_thread: i:%d\n", i); + + return 0; +} +MSH_CMD_EXPORT(tls_test, thread local storage example); diff --git a/include/rtdef.h b/include/rtdef.h index 16f016371048..83f79c41b644 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -71,6 +71,13 @@ #endif /* defined(RT_USING_SIGNALS) || defined(RT_USING_SMART) */ #endif /* RT_USING_NANO */ +#ifdef RT_USING_PICOLIBC +#include +#ifdef PICOLIBC_TLS +#include +#endif +#endif + #ifdef __cplusplus extern "C" { #endif @@ -996,6 +1003,12 @@ struct rt_thread #ifdef RT_USING_HW_STACK_GUARD void *stack_buf; #endif +#endif + +#ifdef RT_USING_PICOLIBC +#ifdef PICOLIBC_TLS + void *tls; +#endif #endif rt_atomic_t ref_count; diff --git a/src/scheduler_mp.c b/src/scheduler_mp.c index ff3a4f7a1163..6a300da9c482 100644 --- a/src/scheduler_mp.c +++ b/src/scheduler_mp.c @@ -546,6 +546,9 @@ void rt_schedule(void) _rt_schedule_remove_thread(to_thread, RT_FALSE); to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK); +#ifdef PICOLIBC_TLS + _set_tls(to_thread->tls); +#endif /* switch to new thread */ LOG_D("[%d]switch to priority#%d " "thread:%.*s(sp:0x%08x), " @@ -700,6 +703,9 @@ void rt_scheduler_do_irq_switch(void *context) _rt_schedule_remove_thread(to_thread, RT_FALSE); to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK); +#ifdef PICOLIBC_TLS + _set_tls(to_thread->tls); +#endif #ifdef RT_USING_OVERFLOW_CHECK _scheduler_stack_check(to_thread); #endif /* RT_USING_OVERFLOW_CHECK */ diff --git a/src/scheduler_up.c b/src/scheduler_up.c index 34193b0acc39..7821c853c017 100644 --- a/src/scheduler_up.c +++ b/src/scheduler_up.c @@ -295,6 +295,9 @@ void rt_schedule(void) rt_schedule_remove_thread(to_thread); to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK); +#ifdef PICOLIBC_TLS + _set_tls(to_thread->tls); +#endif /* switch to new thread */ LOG_D("[%d]switch to priority#%d " "thread:%.*s(sp:0x%08x), " diff --git a/src/thread.c b/src/thread.c index bda2be0fa6cd..c0cb81b1f815 100644 --- a/src/thread.c +++ b/src/thread.c @@ -184,6 +184,15 @@ static rt_err_t _thread_init(struct rt_thread *thread, thread->entry = (void *)entry; thread->parameter = parameter; +#ifdef PICOLIBC_TLS +#define TLS_ALIGN (_tls_align() > 8 ? _tls_align() : 8) + char *tls = (char *)stack_start + stack_size - _tls_size(); + thread->tls = (void *)RT_ALIGN_DOWN((rt_ubase_t)tls, TLS_ALIGN); + stack_size = (char *)thread->tls - (char *)stack_start; + + _init_tls(thread->tls); +#endif + /* stack init */ thread->stack_addr = stack_start; thread->stack_size = stack_size; From f485fa08cad6e39d294b7d0bdacaf4426bfa1657 Mon Sep 17 00:00:00 2001 From: idings Date: Thu, 21 Dec 2023 19:08:14 +0800 Subject: [PATCH 2/2] [bsp][ra8m1] fix llvm-arm compile error --- bsp/renesas/ra8m1-ek/script/fsp.ld | 36 +++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/bsp/renesas/ra8m1-ek/script/fsp.ld b/bsp/renesas/ra8m1-ek/script/fsp.ld index 5f4ed7af2967..c1e1bbeed187 100644 --- a/bsp/renesas/ra8m1-ek/script/fsp.ld +++ b/bsp/renesas/ra8m1-ek/script/fsp.ld @@ -611,6 +611,40 @@ SECTIONS __bss_end__ = .; } > RAM + .tdata : + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + __tdata_end = .; + } > RAM AT > FLASH + PROVIDE( __tls_base = ADDR(.tdata)); + PROVIDE( __tdata_start = ADDR(.tdata)); + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) ); + PROVIDE( __data_source_end = __tdata_source_end ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + + /* + * TLS zeroed data is relocated as if it immediately followed + * the tdata values. However, the linker 'magically' erases the + * memory allocation so that no ROM is consumed by this + * section + */ + .tbss : + { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + PROVIDE( __tbss_end = . ); + } > RAM + PROVIDE( __tbss_start = ADDR(.tbss)); + PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) ); + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) ); + .heap (NOLOAD): { . = ALIGN(8); @@ -837,4 +871,4 @@ SECTIONS /* Symbol required for RA Configuration tool. */ __tz_OPTION_SETTING_DATA_FLASH_S_N = __OPTION_SETTING_DATA_FLASH_S_End; -} \ No newline at end of file +}