Skip to content

Commit 3313714

Browse files
committed
xtensa: support for C library provided by Xtensa toolchain
This change add an additional C library implementation provided by Xtensa toolchain. Signed-off-by: William Tambe <williamt@cadence.com>
1 parent 2d4e05a commit 3313714

File tree

10 files changed

+117
-1
lines changed

10 files changed

+117
-1
lines changed

arch/xtensa/core/thread.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ Z_THREAD_LOCAL uint32_t is_user_mode;
2727

2828
#endif /* CONFIG_USERSPACE */
2929

30+
#if defined(CONFIG_XTENSA_LIBC) && defined(CONFIG_MULTITHREADING)
31+
#include <sys/reent.h>
32+
#endif
33+
3034
/**
3135
* Initializes a stack area such that it can be "restored" later and
3236
* begin running with the specified function and three arguments. The
@@ -125,6 +129,9 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack,
125129
__ASSERT((((size_t)stack_ptr) % XCHAL_DCACHE_LINESIZE) == 0, "");
126130
sys_cache_data_flush_and_invd_range(stack, (char *)stack_ptr - (char *)stack);
127131
#endif
132+
#if defined(CONFIG_XTENSA_LIBC) && defined(CONFIG_MULTITHREADING)
133+
_init_reent(&thread->arch.reent);
134+
#endif
128135
}
129136

130137
#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)

arch/xtensa/include/kernel_arch_func.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,18 @@ extern "C" {
2424
K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS,
2525
CONFIG_ISR_STACK_SIZE);
2626

27+
#if defined(CONFIG_XTENSA_LIBC)
28+
void _Initlocks(void);
29+
#endif
30+
2731
static ALWAYS_INLINE void arch_kernel_init(void)
2832
{
33+
#if defined(CONFIG_XTENSA_LIBC)
34+
if (arch_proc_id() == 0) {
35+
_Initlocks();
36+
}
37+
#endif
38+
2939
#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK
3040
soc_per_core_init_hook();
3141
#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */

boards/cdns/xt-sim/xt-sim_defconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ CONFIG_GEN_IRQ_VECTOR_TABLE=n
88
CONFIG_SIMULATOR_XTENSA=y
99

1010
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=2000000
11+
12+
CONFIG_XTENSA_LIBC=y

cmake/linker/xt-ld/linker_libraries.cmake

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,9 @@ set_linker_property(NO_CREATE PROPERTY c_library "-lc")
66
set_linker_property(NO_CREATE PROPERTY rt_library "-lgcc")
77
set_linker_property(NO_CREATE PROPERTY c++_library "-lstdc++")
88
set_linker_property(NO_CREATE PROPERTY hal_library "-lhal")
9-
set_linker_property(PROPERTY link_order_library "c;rt;hal")
9+
if(CONFIG_XTENSA_LIBC)
10+
set_linker_property(NO_CREATE PROPERTY sim_library "-lsim")
11+
set_linker_property(PROPERTY link_order_library "c;rt;sim;hal")
12+
else()
13+
set_linker_property(PROPERTY link_order_library "c;rt;hal")
14+
endif()

include/zephyr/arch/xtensa/thread.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
#include <zephyr/arch/xtensa/mpu.h>
1515
#endif
1616

17+
#ifdef CONFIG_XTENSA_LIBC
18+
#include <sys/reent.h>
19+
#endif
20+
1721
/* Xtensa doesn't use these structs, but Zephyr core requires they be
1822
* defined so they can be included in struct _thread_base. Dummy
1923
* field exists for sizeof compatibility with C++.
@@ -48,6 +52,9 @@ struct _thread_arch {
4852
*/
4953
uint32_t return_ps;
5054
#endif
55+
#ifdef CONFIG_XTENSA_LIBC
56+
struct _reent reent;
57+
#endif
5158
};
5259

5360
typedef struct _thread_arch _thread_arch_t;

lib/libc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ add_subdirectory_ifdef(CONFIG_IAR_LIBC iar)
1010
add_subdirectory_ifdef(CONFIG_MINIMAL_LIBC minimal)
1111
add_subdirectory_ifdef(CONFIG_NEWLIB_LIBC newlib)
1212
add_subdirectory_ifdef(CONFIG_PICOLIBC picolibc)
13+
add_subdirectory_ifdef(CONFIG_XTENSA_LIBC xclib)
1314

1415
add_subdirectory(common)

lib/libc/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ config IAR_LIBC
143143
A reduced Zephyr minimal libc will be used for library functionality
144144
not provided by the IAR C Runtime Library.
145145

146+
config XTENSA_LIBC
147+
bool "Xtensa C library"
148+
depends on !NATIVE_APPLICATION
149+
depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "xt-clang"
150+
help
151+
C library provided by Xtensa toolchain.
152+
146153
endchoice # LIBC_IMPLEMENTATION
147154

148155
config HAS_NEWLIB_LIBC_NANO

lib/libc/xclib/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
zephyr_library()
4+
5+
zephyr_library_sources(
6+
libc-hooks.c
7+
multithreading.c
8+
)

lib/libc/xclib/libc-hooks.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2025 Cadence Design Systems, Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
char __os_flag __attribute__((retain)); /* Needed by xclib to indicate the presense of an OS */
8+
9+
int arch_printk_char_out(int c);
10+
static int (*_stdout_hook)(int c) = arch_printk_char_out;
11+
12+
void __stdout_hook_install(int (*hook)(int))
13+
{
14+
_stdout_hook = hook;
15+
}

lib/libc/xclib/multithreading.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) 2025 Cadence Design Systems, Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifdef CONFIG_MULTITHREADING
8+
9+
#include <zephyr/kernel.h>
10+
#include <stdlib.h>
11+
#include <sys/reent.h>
12+
13+
typedef struct k_mutex *_Rmtx;
14+
15+
void _Mtxinit(_Rmtx *mtx)
16+
{
17+
*mtx = malloc(sizeof(struct k_mutex));
18+
if (!*mtx) {
19+
k_panic();
20+
}
21+
k_mutex_init(*mtx);
22+
}
23+
24+
void _Mtxdst(_Rmtx *mtx)
25+
{
26+
if ((mtx != NULL) && (*mtx != NULL)) {
27+
free(*mtx);
28+
}
29+
}
30+
31+
void _Mtxlock(_Rmtx *mtx)
32+
{
33+
if ((mtx != NULL) && (*mtx != NULL)) {
34+
k_mutex_lock(*mtx, K_FOREVER);
35+
}
36+
}
37+
38+
void _Mtxunlock(_Rmtx *mtx)
39+
{
40+
if ((mtx != NULL) && (*mtx != NULL)) {
41+
k_mutex_unlock(*mtx);
42+
}
43+
}
44+
45+
#if defined (__DYNAMIC_REENT__)
46+
struct _reent *__getreent(void)
47+
{
48+
return &k_current_get()->arch.reent;
49+
}
50+
#else
51+
#error __DYNAMIC_REENT__ support missing
52+
#endif
53+
54+
#endif /* CONFIG_MULTITHREADING */

0 commit comments

Comments
 (0)