From 8b22b70addd9619936467a83c3fb75d371a64dbe Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Sat, 10 Jan 2026 22:49:28 +0100 Subject: [PATCH 01/17] libs/libxx: Add support for libcxx and libcxxabi version 21.1.8 This commit adds support for LLVM libcxx and libcxxabi version 21.1.8, including necessary patches and CMake configuration for building with NuttX. Signed-off-by: Bartosz --- CMakeLists.txt | 8 + arch/arm/src/cmake/gcc.cmake | 5 + arch/arm/src/common/Toolchain.defs | 6 + libs/libxx/Kconfig | 8 +- libs/libxx/__config_site | 49 +++--- ...x-build-error-about-__GLIBC___21.1.8.patch | 13 ++ ...-libcxx-fix-exception-no-rtti_21.1.8.patch | 12 ++ ...cxx-fix-ostream-no-exceptions_21.1.8.patch | 16 ++ ...001-libcxx-remove-mach-time-h_21.1.8.patch | 13 ++ ..._fix_stdatomic_h_miss_typedef_21.1.8.patch | 11 ++ ...cxx-fix-locale-instantiations_21.1.8.patch | 18 +++ ...invalid-locale-instantiations_21.1.8.patch | 45 ++++++ ...tring-template-instantiations_21.1.8.patch | 16 ++ ...x-locale-call-once-no-threads_21.1.8.patch | 25 +++ ...ecation-warnings-redefinition_21.1.8.patch | 10 ++ libs/libxx/libcxx/CMakeLists.txt | 62 ++++++-- libs/libxx/libcxx/Make.defs | 34 ++++- libs/libxx/libcxx/__assertion_handler | 30 ++++ libs/libxx/libcxx/mbstate_t_21.1.8.patch | 17 +++ ...bi-fix-exception-handler-init_21.1.8.patch | 21 +++ ...isable-threading-in-cxa-guard_21.1.8.patch | 29 ++++ libs/libxx/libcxxabi/CMakeLists.txt | 38 ++++- libs/libxx/libcxxabi/Make.defs | 20 ++- .../src/cxa_exception_storage_stub.cpp | 104 +++++++++++++ .../libcxxabi/src/fallback_malloc_stub.cpp | 143 ++++++++++++++++++ 25 files changed, 703 insertions(+), 50 deletions(-) create mode 100644 libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch create mode 100644 libs/libxx/libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch create mode 100644 libs/libxx/libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch create mode 100644 libs/libxx/libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch create mode 100644 libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch create mode 100644 libs/libxx/libcxx/0007-libcxx-fix-locale-instantiations_21.1.8.patch create mode 100644 libs/libxx/libcxx/0008-libcxx-remove-invalid-locale-instantiations_21.1.8.patch create mode 100644 libs/libxx/libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch create mode 100644 libs/libxx/libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch create mode 100644 libs/libxx/libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch create mode 100644 libs/libxx/libcxx/__assertion_handler create mode 100644 libs/libxx/libcxx/mbstate_t_21.1.8.patch create mode 100644 libs/libxx/libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch create mode 100644 libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch create mode 100644 libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp create mode 100644 libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 82ff10e2cd9a2..af6e09ee499de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -522,6 +522,14 @@ add_definitions(-D__NuttX__) add_compile_options($<$:-D__ASSEMBLY__>) +if(CONFIG_LIBCXX) + if(CONFIG_ARCH_ARM) + add_compile_options($<$:-mlong-calls>) + elseif(CONFIG_ARCH_RISCV) + add_compile_options($<$:-mcmodel=medany>) + endif() +endif() + # Setup main nuttx target #################################################### add_executable(nuttx) diff --git a/arch/arm/src/cmake/gcc.cmake b/arch/arm/src/cmake/gcc.cmake index b11518bab3298..c924edd820afe 100644 --- a/arch/arm/src/cmake/gcc.cmake +++ b/arch/arm/src/cmake/gcc.cmake @@ -274,6 +274,11 @@ if(NOT CONFIG_CXX_RTTI) add_compile_options($<$:-fno-rtti>) endif() +# Add -mlong-calls for C++ when using libcxx to fix relocation issues +if(CONFIG_LIBCXX) + add_compile_options($<$:-mlong-calls>) +endif() + set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs") set(PREPROCESS ${CMAKE_C_COMPILER} ${CMAKE_C_FLAG_ARGS} -E -P -x c) diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index f38ab852f0928..5bc566b8042bb 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -405,6 +405,12 @@ endif ifneq ($(CONFIG_CXX_RTTI),y) ARCHCXXFLAGS += -fno-rtti endif + +# Add -mlong-calls for C++ when using libcxx to fix relocation issues +ifeq ($(CONFIG_LIBCXX),y) + ARCHCXXFLAGS += -mlong-calls +endif + ifeq ($(CONFIG_ARM_TOOLCHAIN_GHS),y) ARCHOPTIMIZATION += --no_commons else diff --git a/libs/libxx/Kconfig b/libs/libxx/Kconfig index 62618e15bb603..2dc1cdefaf1e8 100644 --- a/libs/libxx/Kconfig +++ b/libs/libxx/Kconfig @@ -100,15 +100,15 @@ config LIBCXXABI_VERSION string "Select libcxxabi version" depends on LIBCXXABI default LIBCXX_VERSION if LIBCXX - default "17.0.6" if !LIBCXX + default "21.1.8" if !LIBCXX config CXX_STANDARD string "Language standard" - default "gnu++20" if LIBCXX + default "gnu++23" if LIBCXX default "gnu++17" if !LIBCXX ---help--- Possible values: - gnu++98/c++98, gnu++11/c++11, gnu++14/c++14, gnu++17/c++17 and gnu++20/c++20 + gnu++98/c++98, gnu++11/c++11, gnu++14/c++14, gnu++17/c++17, gnu++20/c++20 and gnu++23/c++23 config CXX_EXCEPTION bool "Enable Exception Support" @@ -134,6 +134,6 @@ endif config LIBCXX_VERSION string "Select libcxx version" depends on LIBCXX - default "17.0.6" + default "21.1.8" endif diff --git a/libs/libxx/__config_site b/libs/libxx/__config_site index e7d5116ceb0ce..efc59e1068011 100644 --- a/libs/libxx/__config_site +++ b/libs/libxx/__config_site @@ -15,8 +15,11 @@ #define _LIBCPP_ABI_NAMESPACE __1 /* #undef _LIBCPP_ABI_FORCE_ITANIUM */ /* #undef _LIBCPP_ABI_FORCE_MICROSOFT */ -/* #undef _LIBCPP_HAS_NO_THREADS */ -/* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */ +#define _LIBCPP_HAS_NO_THREADS +#define _LIBCPP_HAS_THREADS 0 +#define _LIBCPP_HAS_NO_MONOTONIC_CLOCK +#define _LIBCPP_HAS_MONOTONIC_CLOCK 0 +#define _LIBCPP_HAS_TIME_ZONE_DATABASE 0 /* #undef _LIBCPP_HAS_MUSL_LIBC */ /* #undef _LIBCPP_HAS_THREAD_API_PTHREAD */ /* #undef _LIBCPP_HAS_THREAD_API_EXTERNAL */ @@ -26,38 +29,50 @@ /* #undef _LIBCPP_NO_VCRUNTIME */ /* #undef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION */ /* #undef _LIBCPP_HAS_NO_FILESYSTEM */ +#define _LIBCPP_HAS_FILESYSTEM 1 /* #undef _LIBCPP_HAS_NO_RANDOM_DEVICE */ -#ifndef CONFIG_CXX_LOCALIZATION -# define _LIBCPP_HAS_NO_LOCALIZATION +#define _LIBCPP_HAS_RANDOM_DEVICE 0 +#ifdef CONFIG_CXX_LOCALIZATION +#define _LIBCPP_HAS_LOCALIZATION 1 +#else +#define _LIBCPP_HAS_NO_LOCALIZATION +#define _LIBCPP_HAS_LOCALIZATION 0 #endif -#ifndef CONFIG_CXX_WCHAR -# define _LIBCPP_HAS_NO_WIDE_CHARACTERS +#ifdef CONFIG_CXX_WCHAR +#define _LIBCPP_HAS_WIDE_CHARACTERS 1 +#else +#define _LIBCPP_HAS_NO_WIDE_CHARACTERS +#define _LIBCPP_HAS_WIDE_CHARACTERS 0 #endif #define _LIBCPP_ENABLE_ASSERTIONS_DEFAULT 0 +// Define assertion macros for libcxx 21.x +#define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(...) ((void)0) + // PSTL backends -#define _LIBCPP_PSTL_CPU_BACKEND_SERIAL -/* #undef _LIBCPP_PSTL_CPU_BACKEND_THREAD */ -/* #undef _LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH */ +#define _LIBCPP_PSTL_BACKEND_SERIAL +/* #undef _LIBCPP_PSTL_BACKEND_STD_THREAD */ +/* #undef _LIBCPP_PSTL_BACKEND_LIBDISPATCH */ // Hardening. -#define _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT 0 -#define _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT 0 +#ifndef NDEBUG +#define _LIBCPP_HARDENING_MODE_DEFAULT _LIBCPP_HARDENING_MODE_EXTENSIVE +#else +#define _LIBCPP_HARDENING_MODE_DEFAULT _LIBCPP_HARDENING_MODE_FAST +#endif +#define _LIBCPP_ENABLE_ASSERTIONS_DEFAULT 0 #define _LIBCPP_DISABLE_DEPRECATION_WARNINGS 1 #define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT 1 // __USE_MINGW_ANSI_STDIO gets redefined on MinGW #ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmacro-redefined" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmacro-redefined" #endif - - - #ifdef __clang__ -# pragma clang diagnostic pop +#pragma clang diagnostic pop #endif #define _SYS_REENT_H_ diff --git a/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch b/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch new file mode 100644 index 0000000000000..c9d61883643a7 --- /dev/null +++ b/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch @@ -0,0 +1,13 @@ +--- a/src/locale.cpp ++++ b/src/locale.cpp +@@ -37,6 +37,10 @@ + #include "include/atomic_support.h" + #include "include/sso_allocator.h" + ++#if defined(__NuttX__) && defined(__GLIBC__) ++# undef __GLIBC__ ++#endif ++ + // On Linux, wint_t and wchar_t have different signed-ness, and this causes + // lots of noise in the build log, but no bugs that I know of. + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion") diff --git a/libs/libxx/libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch b/libs/libxx/libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch new file mode 100644 index 0000000000000..b2f777338f699 --- /dev/null +++ b/libs/libxx/libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch @@ -0,0 +1,12 @@ +--- libcxx/src/exception.cpp.orig 2025-01-10 00:00:00.000000000 +0000 ++++ libcxx/src/exception.cpp 2025-01-10 00:00:00.000000000 +0000 +@@ -22,6 +22,9 @@ + #if defined(_LIBCPP_ABI_MICROSOFT) + # include "support/runtime/exception_msvc.ipp" + # include "support/runtime/exception_pointer_msvc.ipp" ++#elif defined(LIBCXX_BUILDING_LIBCXXABI) && defined(_LIBCPP_HAS_NO_EXCEPTIONS) ++# include "include/atomic_support.h" ++# include "support/runtime/exception_pointer_unimplemented.ipp" + #elif defined(_LIBCPPABI_VERSION) + # include "support/runtime/exception_libcxxabi.ipp" + # include "support/runtime/exception_pointer_cxxabi.ipp" diff --git a/libs/libxx/libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch b/libs/libxx/libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch new file mode 100644 index 0000000000000..b7a9ce5362dd2 --- /dev/null +++ b/libs/libxx/libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch @@ -0,0 +1,16 @@ +--- a/include/__ostream/basic_ostream.h ++++ b/include/__ostream/basic_ostream.h +@@ -207,7 +207,12 @@ + + template + basic_ostream<_CharT, _Traits>::sentry::~sentry() { +- if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && uncaught_exceptions() == 0) { ++ if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) ++# if _LIBCPP_HAS_EXCEPTIONS ++ && uncaught_exceptions() == 0 ++# endif ++ ) { ++ + # if _LIBCPP_HAS_EXCEPTIONS + try { + # endif // _LIBCPP_HAS_EXCEPTIONS diff --git a/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch b/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch new file mode 100644 index 0000000000000..e65e530c3d011 --- /dev/null +++ b/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch @@ -0,0 +1,13 @@ +--- a/src/chrono.cpp ++++ b/src/chrono.cpp +@@ -54,10 +54,6 @@ + # include + #endif + +-#if __has_include() +-# include +-#endif +- + #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) + # pragma comment(lib, "rt") + #endif diff --git a/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch b/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch new file mode 100644 index 0000000000000..ca17ef6e6c087 --- /dev/null +++ b/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch @@ -0,0 +1,11 @@ +--- a/include/stdatomic.h ++++ b/include/stdatomic.h +@@ -231,7 +231,7 @@ + using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS; + using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS; + +-# elif defined(_LIBCPP_COMPILER_CLANG_BASED) ++# else + + // Before C++23, we include the next on the path to avoid hijacking + // the header. We do this because Clang has historically shipped a diff --git a/libs/libxx/libcxx/0007-libcxx-fix-locale-instantiations_21.1.8.patch b/libs/libxx/libcxx/0007-libcxx-fix-locale-instantiations_21.1.8.patch new file mode 100644 index 0000000000000..3002bb169b2e8 --- /dev/null +++ b/libs/libxx/libcxx/0007-libcxx-fix-locale-instantiations_21.1.8.patch @@ -0,0 +1,18 @@ +--- libcxx/src/locale.cpp.orig ++++ libcxx/src/locale.cpp +@@ -5605,6 +5605,7 @@ + + // explicit instantiation + ++#ifndef _LIBCPP_HAS_NO_LOCALIZATION + template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; + template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate_byname; + template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; +@@ -5645,6 +5646,7 @@ + template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate_byname; + template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; + #endif ++#endif // _LIBCPP_HAS_NO_LOCALIZATION + + // FIXME: These explicit instantiations seem wrong since it depends on localization support which can be disabled + _LIBCPP_SUPPRESS_DEPRECATED_PUSH diff --git a/libs/libxx/libcxx/0008-libcxx-remove-invalid-locale-instantiations_21.1.8.patch b/libs/libxx/libcxx/0008-libcxx-remove-invalid-locale-instantiations_21.1.8.patch new file mode 100644 index 0000000000000..c32a33d312a6e --- /dev/null +++ b/libs/libxx/libcxx/0008-libcxx-remove-invalid-locale-instantiations_21.1.8.patch @@ -0,0 +1,45 @@ +--- a/src/locale.cpp ++++ b/src/locale.cpp +@@ -5607,42 +5607,6 @@ + return __mb_cur_max_l((locale_t)__l); + } + +-// explicit instantiation +- +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; +-# if _LIBCPP_HAS_WIDE_CHARACTERS +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +- codecvt_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +- codecvt_byname; +-# endif +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; +- +-# if _LIBCPP_HAS_WIDE_CHARACTERS +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname; +-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; +-# endif +- + // FIXME: These explicit instantiations seem wrong since it depends on localization support which can be disabled + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname; diff --git a/libs/libxx/libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch b/libs/libxx/libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch new file mode 100644 index 0000000000000..325e8a690e272 --- /dev/null +++ b/libs/libxx/libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch @@ -0,0 +1,16 @@ +--- a/src/string.cpp 2026-01-10 09:53:40.035509375 +0100 ++++ b/src/string.cpp 2026-01-10 09:53:40.045300744 +0100 +@@ -382,4 +382,13 @@ + wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string()(), L"%Lf", val); } + #endif + ++// Explicit template instantiations for embedded systems ++template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string; ++#if _LIBCPP_HAS_WIDE_CHARACTERS ++template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string; ++#endif ++#ifndef _LIBCPP_HAS_NO_CHAR8_T ++template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string; ++#endif ++ + _LIBCPP_END_NAMESPACE_STD diff --git a/libs/libxx/libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch b/libs/libxx/libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch new file mode 100644 index 0000000000000..28f47e580a2d8 --- /dev/null +++ b/libs/libxx/libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch @@ -0,0 +1,25 @@ +--- a/src/locale.cpp ++++ b/src/locale.cpp +@@ -589,8 +589,22 @@ + constinit int32_t locale::id::__next_id = 0; + + long locale::id::__get() { ++#ifdef _LIBCPP_HAS_NO_THREADS ++ // Interrupt-safe ID assignment: Read current ID first to minimize race window ++ // Even if interrupted between read and write, atomic_add ensures unique IDs ++ int32_t current = __id_; ++ if (current == 0) { ++ // Generate unique ID atomically - each call gets different value ++ int32_t new_id = __libcpp_atomic_add(&__next_id, 1) + 1; ++ // Write back - safe because atomic_add guarantees uniqueness ++ __id_ = new_id; ++ current = new_id; ++ } ++ return current - 1; ++#else + call_once(__flag_, [&] { __id_ = __libcpp_atomic_add(&__next_id, 1); }); + return __id_ - 1; ++#endif + } + + // template <> class collate_byname diff --git a/libs/libxx/libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch b/libs/libxx/libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch new file mode 100644 index 0000000000000..e50761c611df6 --- /dev/null +++ b/libs/libxx/libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch @@ -0,0 +1,10 @@ +--- a/src/exception.cpp ++++ b/src/exception.cpp +@@ -7,7 +7,6 @@ + //===----------------------------------------------------------------------===// + + #define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION +-#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS + + #include + #include diff --git a/libs/libxx/libcxx/CMakeLists.txt b/libs/libxx/libcxx/CMakeLists.txt index 664600337647f..58b74874e84c2 100644 --- a/libs/libxx/libcxx/CMakeLists.txt +++ b/libs/libxx/libcxx/CMakeLists.txt @@ -44,17 +44,23 @@ if(CONFIG_LIBCXX) "" PATCH_COMMAND patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001_fix_stdatomic_h_miss_typedef.patch && - patch -p3 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/mbstate_t.patch && patch -p1 -d - ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-remove-mach-time-h.patch && patch - -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ld-errors.patch && patch -p1 - -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC__.patch && + ${CMAKE_CURRENT_LIST_DIR}/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libc-Fix-failures-with-GCC-14-92663.patch + ${CMAKE_CURRENT_LIST_DIR}/mbstate_t_21.1.8.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-remove-mach-time-h_21.1.8.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-exception-no-rtti_21.1.8.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC___21.1.8.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -69,8 +75,15 @@ if(CONFIG_LIBCXX) nuttx_create_symlink(${CMAKE_CURRENT_LIST_DIR}/libcxx/include ${CMAKE_BINARY_DIR}/include/libcxx) + # Copy config files to the libcxx source include directory before symlinking + # Remove existing files first to allow reconfiguration + file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__config_site) configure_file(${CMAKE_CURRENT_LIST_DIR}/../__config_site - ${CMAKE_BINARY_DIR}/include/libcxx/__config_site COPYONLY) + ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__config_site COPYONLY) + + file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__assertion_handler) + configure_file(${CMAKE_CURRENT_LIST_DIR}/__assertion_handler + ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__assertion_handler COPYONLY) set_property( TARGET nuttx @@ -98,6 +111,23 @@ if(CONFIG_LIBCXX) file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ryu/*.cpp) list(APPEND SRCS ${SRCSTMP}) + # Exclude threading-related files since _LIBCPP_HAS_NO_THREADS is defined + file( + GLOB + SRCSTMP + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/barrier.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/condition_variable.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/condition_variable_destructor.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/mutex.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/mutex_destructor.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/thread.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/future.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/shared_mutex.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/call_once.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/atomic.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/charconv.cpp) + list(REMOVE_ITEM SRCS ${SRCSTMP}) + if(NOT CONFIG_CXX_LOCALIZATION) file( GLOB @@ -111,6 +141,16 @@ if(CONFIG_LIBCXX) list(REMOVE_ITEM SRCS ${SRCSTMP}) endif() + # Exclude files with embedded-incompatible dependencies + file( + GLOB + SRCSTMP + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/atomic.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/charconv.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/random.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/*.cpp) + list(REMOVE_ITEM SRCS ${SRCSTMP}) + set(FLAGS -Wno-attributes -Wno-deprecated-declarations -Wno-shadow -Wno-sign-compare -Wno-cpp) diff --git a/libs/libxx/libcxx/Make.defs b/libs/libxx/libcxx/Make.defs index e5cc01af997b0..77b44acc74cce 100644 --- a/libs/libxx/libcxx/Make.defs +++ b/libs/libxx/libcxx/Make.defs @@ -31,18 +31,22 @@ libcxx/libcxx: libcxx-$(LIBCXX_VERSION).src.tar.xz $(Q) tar -xf $< \ --exclude libcxx-$(LIBCXX_VERSION).src/test/std/pstl $(Q) mv libcxx-$(LIBCXX_VERSION).src $@ - $(Q) patch -p0 < libcxx/0001_fix_stdatomic_h_miss_typedef.patch -d libcxx - $(Q) patch -p2 < libcxx/mbstate_t.patch -d libcxx - $(Q) patch -p0 < libcxx/0001-libcxx-remove-mach-time-h.patch -d libcxx - $(Q) patch -p0 < libcxx/0001-libcxx-fix-ld-errors.patch -d libcxx - $(Q) patch -p0 < libcxx/0001-Fix-build-error-about-__GLIBC__.patch -d libcxx - $(Q) patch -p0 < libcxx/0001-libc-Fix-failures-with-GCC-14-92663.patch -d libcxx + $(Q) patch -p1 < libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch -d libcxx/libcxx + $(Q) patch -p1 < libcxx/mbstate_t_21.1.8.patch -d libcxx/libcxx + $(Q) patch -p1 < libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch -d libcxx/libcxx + $(Q) patch -p1 < libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch -d libcxx/libcxx + $(Q) patch -p1 < libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch -d libcxx/libcxx + $(Q) patch -p1 < libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch -d libcxx/libcxx + $(Q) patch -p1 < libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch -d libcxx/libcxx + $(Q) patch -p1 < libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch -d libcxx/libcxx + $(Q) patch -p1 < libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch -d libcxx/libcxx endif $(TOPDIR)/include/libcxx: libcxx/libcxx $(Q) $(DIRLINK) $(CURDIR)/$= 12), 1) endif CPPSRCS += $(wildcard libcxx/libcxx/src/*.cpp) -CPPSRCS += $(wildcard libcxx/libcxx/src/experimental/*.cpp) CPPSRCS += $(wildcard libcxx/libcxx/src/filesystem/*.cpp) CPPSRCS += $(wildcard libcxx/libcxx/src/ryu/*.cpp) +# Exclude threading-related files when _LIBCPP_HAS_NO_THREADS is defined +THREAD_CPPSRCS := libcxx/libcxx/src/atomic.cpp +THREAD_CPPSRCS += libcxx/libcxx/src/barrier.cpp +THREAD_CPPSRCS += libcxx/libcxx/src/condition_variable.cpp +THREAD_CPPSRCS += libcxx/libcxx/src/condition_variable_destructor.cpp +THREAD_CPPSRCS += libcxx/libcxx/src/future.cpp +THREAD_CPPSRCS += libcxx/libcxx/src/mutex.cpp +THREAD_CPPSRCS += libcxx/libcxx/src/mutex_destructor.cpp +THREAD_CPPSRCS += libcxx/libcxx/src/shared_mutex.cpp +THREAD_CPPSRCS += libcxx/libcxx/src/thread.cpp +CPPSRCS := $(filter-out $(THREAD_CPPSRCS), $(CPPSRCS)) + +# Exclude files with embedded-incompatible dependencies +INCOMPATIBLE_CPPSRCS := libcxx/libcxx/src/charconv.cpp +INCOMPATIBLE_CPPSRCS += libcxx/libcxx/src/random.cpp +CPPSRCS := $(filter-out $(INCOMPATIBLE_CPPSRCS), $(CPPSRCS)) + ifeq ($(CONFIG_CXX_LOCALIZATION),) LOCALE_CPPSRCS := libcxx/libcxx/src/ios.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/ios.instantiations.cpp diff --git a/libs/libxx/libcxx/__assertion_handler b/libs/libxx/libcxx/__assertion_handler new file mode 100644 index 0000000000000..147c71318d690 --- /dev/null +++ b/libs/libxx/libcxx/__assertion_handler @@ -0,0 +1,30 @@ +// __assertion_handler for libcxx 21.x +// This file provides the assertion handler for libcxx when +// _LIBCPP_ENABLE_ASSERTIONS is enabled. + +#ifndef _LIBCPP_ASSERTION_HANDLER_H +#define _LIBCPP_ASSERTION_HANDLER_H + +#include <__config> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Forward declare the verbose abort function from libcxx with proper attributes +[[noreturn]] _LIBCPP_EXPORTED_FROM_ABI void +__libcpp_verbose_abort(const char *, ...) _NOEXCEPT; + +// Default assertion handler that uses verbose abort directly +[[noreturn]] inline void __libcpp_assertion_handler(char const *format, ...) { + // Simply pass format string to verbose abort - no formatting to avoid stdio + // dependency + __libcpp_verbose_abort(format); +} + +_LIBCPP_END_NAMESPACE_STD + +// Define the assertion handler macro +// Cast to void to make it work with exceptions disabled +#define _LIBCPP_ASSERTION_HANDLER(...) \ + (::std::__libcpp_assertion_handler(__VA_ARGS__), static_cast(0)) + +#endif // _LIBCPP_ASSERTION_HANDLER_H diff --git a/libs/libxx/libcxx/mbstate_t_21.1.8.patch b/libs/libxx/libcxx/mbstate_t_21.1.8.patch new file mode 100644 index 0000000000000..2920e517365c3 --- /dev/null +++ b/libs/libxx/libcxx/mbstate_t_21.1.8.patch @@ -0,0 +1,17 @@ +--- a/include/__mbstate_t.h ++++ b/include/__mbstate_t.h +@@ -39,12 +39,12 @@ + # define __NEED_mbstate_t + # include + # undef __NEED_mbstate_t ++#elif __has_include_next() ++# include_next // use the C standard provider of mbstate_t if present + #elif __has_include() + # include // works on most Unixes + #elif __has_include() + # include // works on Darwin +-#elif __has_include_next() +-# include_next // use the C standard provider of mbstate_t if present + #elif __has_include_next() + # include_next // Try in absence of for mbstate_t + #else diff --git a/libs/libxx/libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch b/libs/libxx/libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch new file mode 100644 index 0000000000000..47fc0014846fb --- /dev/null +++ b/libs/libxx/libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch @@ -0,0 +1,21 @@ +--- src/cxa_exception.cpp.orig 2026-01-10 08:23:14.212626633 +0100 ++++ src/cxa_exception.cpp 2026-01-10 08:23:14.510070337 +0100 +@@ -215,8 +215,16 @@ + #endif + __cxa_exception* exception_header = cxa_exception_from_thrown_object(object); + exception_header->referenceCount = 0; +- exception_header->unexpectedHandler = std::get_unexpected(); +- exception_header->terminateHandler = std::get_terminate(); ++ // Use libcxxabi's handlers directly instead of std::get_terminate() ++ // to avoid issues with uninitialized libcxx fallback handlers when ++ // both libcxx and libcxxabi are linked together ++ extern std::terminate_handler __cxa_terminate_handler; ++ extern std::unexpected_handler __cxa_unexpected_handler; ++ exception_header->unexpectedHandler = __cxa_unexpected_handler; ++ exception_header->terminateHandler = __cxa_terminate_handler; ++#if defined(_LIBCXXABI_ARM_EHABI) ++ exception_header->propagationCount = 0; ++#endif + exception_header->exceptionType = tinfo; + exception_header->exceptionDestructor = dest; + setOurExceptionClass(&exception_header->unwindHeader); diff --git a/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch b/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch new file mode 100644 index 0000000000000..04d8ba1f363b6 --- /dev/null +++ b/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch @@ -0,0 +1,29 @@ +--- libcxxabi.orig/src/cxa_guard_impl.h 2026-01-10 14:08:51.808835600 +0100 ++++ libcxxabi/src/cxa_guard_impl.h 2026-01-10 14:08:51.819473598 +0100 +@@ -64,7 +64,7 @@ + #include + #include + +-#ifndef _LIBCXXABI_HAS_NO_THREADS ++#if !defined(_LIBCXXABI_HAS_NO_THREADS) && !defined(_LIBCPP_HAS_NO_THREADS) + # if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB) + # pragma comment(lib, "pthread") + # endif +@@ -280,7 +280,7 @@ + struct LibcppMutex; + struct LibcppCondVar; + +-#ifndef _LIBCXXABI_HAS_NO_THREADS ++#if !defined(_LIBCXXABI_HAS_NO_THREADS) && !defined(_LIBCPP_HAS_NO_THREADS) + struct LibcppMutex { + LibcppMutex() = default; + LibcppMutex(LibcppMutex const&) = delete; +@@ -663,7 +663,7 @@ + // TODO(EricWF): We should prefer the futex implementation when available. But + // it should be done in a separate step from adding the implementation. + constexpr Implementation CurrentImplementation = +-#if defined(_LIBCXXABI_HAS_NO_THREADS) ++#if defined(_LIBCXXABI_HAS_NO_THREADS) || defined(_LIBCPP_HAS_NO_THREADS) + Implementation::NoThreads; + #elif defined(_LIBCXXABI_USE_FUTEX) + Implementation::Futex; diff --git a/libs/libxx/libcxxabi/CMakeLists.txt b/libs/libxx/libcxxabi/CMakeLists.txt index ab747e6ee31bd..6f4593c85bc78 100644 --- a/libs/libxx/libcxxabi/CMakeLists.txt +++ b/libs/libxx/libcxxabi/CMakeLists.txt @@ -41,7 +41,15 @@ if(CONFIG_LIBCXXABI) "" TEST_COMMAND "" - PATCH_COMMAND "" + PATCH_COMMAND + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < + ${CMAKE_CURRENT_LIST_DIR}/0002-libcxxabi-fix-compilation-errors.patch && + patch -p0 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < + ${CMAKE_CURRENT_LIST_DIR}/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < + ${CMAKE_CURRENT_LIST_DIR}/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -70,12 +78,12 @@ if(CONFIG_LIBCXXABI) cxa_aux_runtime.cpp cxa_default_handlers.cpp cxa_demangle.cpp - cxa_exception_storage.cpp cxa_guard.cpp cxa_handlers.cpp - cxa_thread_atexit.cpp cxa_vector.cpp cxa_virtual.cpp) + # Excluded: cxa_exception_storage.cpp (uses thread-local storage __aeabi_read_tp) + # Excluded threading-dependent files: cxa_thread_atexit.cpp add_compile_definitions(_LIBCPP_BUILDING_LIBRARY) if(CONFIG_LIBSUPCXX_TOOLCHAIN) add_compile_definitions(__GLIBCXX__) @@ -88,8 +96,17 @@ if(CONFIG_LIBCXXABI) list(APPEND SRCS stdlib_exception.cpp stdlib_new_delete.cpp stdlib_stdexcept.cpp stdlib_typeinfo.cpp) - # Internal files - list(APPEND SRCS abort_message.cpp fallback_malloc.cpp private_typeinfo.cpp) + # Internal files and stub implementations (no threading, no TLS) + list(APPEND SRCS abort_message.cpp private_typeinfo.cpp) + + # Add stub files from libs/libxx/libcxxabi/src/ (not from libcxxabi/src/) + list(APPEND STUB_SRCS + ${CMAKE_CURRENT_LIST_DIR}/src/cxa_exception_storage_stub.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/fallback_malloc_stub.cpp) + + # Exclude threading-dependent files when _LIBCPP_HAS_NO_THREADS is defined + # These files use __libcpp_mutex_t, __libcpp_condvar_t, __libcpp_tls_key which are not available without threading + # list(APPEND SRCS cxa_guard.cpp cxa_thread_atexit.cpp) if(CONFIG_CXX_EXCEPTION) list(APPEND SRCS cxa_exception.cpp cxa_personality.cpp) @@ -107,6 +124,15 @@ if(CONFIG_LIBCXXABI) # RTTI is required for building the libcxxabi library target_compile_options(libcxxabi PRIVATE -frtti) + # Fix ARM unwinder enum type conversion warnings without disabling all type safety + if(CONFIG_ARCH_ARM) + target_compile_options(libcxxabi PRIVATE -Wno-error=conversion -Wno-error=enum-conversion) + endif() + + # Disable threading support to match libcxx configuration + # Note: _LIBCPP_HAS_NO_THREADS is already defined in __config_site + target_compile_definitions(libcxxabi PRIVATE _LIBCXXABI_HAS_NO_THREADS) + if(CONFIG_SIM_UBSAN OR CONFIG_MM_UBSAN) target_compile_options(libcxxabi PRIVATE -fno-sanitize=vptr) endif() @@ -124,7 +150,7 @@ if(CONFIG_LIBCXXABI) target_compile_definitions(libcxxabi PRIVATE LIBCXXABI_NON_DEMANGLING_TERMINATE) - target_sources(libcxxabi PRIVATE ${TARGET_SRCS}) + target_sources(libcxxabi PRIVATE ${TARGET_SRCS} ${STUB_SRCS}) target_include_directories( libcxxabi BEFORE PRIVATE ${NUTTX_DIR}/libs/libxx/libcxx/libcxx/src ${CMAKE_CURRENT_LIST_DIR}/libcxxabi/include) diff --git a/libs/libxx/libcxxabi/Make.defs b/libs/libxx/libcxxabi/Make.defs index 362a7a575fce5..57ce77e012c4a 100644 --- a/libs/libxx/libcxxabi/Make.defs +++ b/libs/libxx/libcxxabi/Make.defs @@ -30,8 +30,10 @@ libcxxabi-$(LIBCXXABI_VERSION).src.tar.xz: libcxxabi/libcxxabi: libcxxabi-$(LIBCXXABI_VERSION).src.tar.xz $(Q) tar -xf $< $(Q) mv libcxxabi-$(LIBCXXABI_VERSION).src $@ - $(Q) patch -p0 < libcxxabi/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch -d libcxxabi - $(Q) patch -p0 < libcxxabi/0002-libcxxabi-fix-compilation-errors.patch -d libcxxabi + $(Q) patch -p1 < libcxxabi/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch -d libcxxabi/libcxxabi + $(Q) patch -p1 < libcxxabi/0002-libcxxabi-fix-compilation-errors.patch -d libcxxabi/libcxxabi + $(Q) patch -p0 < libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch -d libcxxabi/libcxxabi + $(Q) patch -p1 < libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch -d libcxxabi/libcxxabi endif $(TOPDIR)/include/libcxxabi: libcxxabi/libcxxabi @@ -51,6 +53,9 @@ ifeq ($(CONFIG_LIBCXXABI), y) CXXFLAGS += ${DEFINE_PREFIX}LIBCXX_BUILDING_LIBCXXABI CXXFLAGS += -I $(TOPDIR)/libs/libxx/libcxxabi/libcxxabi/include +# Define _LIBCPP_HAS_NO_THREADS for no-threading builds +CXXFLAGS += ${DEFINE_PREFIX}_LIBCPP_HAS_NO_THREADS + # Disable dynamic type checking when enabling libcxxabi # It results in a recursive call: # cxxabiv1::__dynamic_case -> is_equal -> __ubsan::checkDynamic -> cxxabiv1::__dynamic_case @@ -61,12 +66,15 @@ endif endif # C++ABI files -CPPSRCS += cxa_aux_runtime.cpp cxa_default_handlers.cpp cxa_demangle.cpp cxa_exception_storage.cpp -CPPSRCS += cxa_guard.cpp cxa_handlers.cpp cxa_thread_atexit.cpp cxa_vector.cpp cxa_virtual.cpp +CPPSRCS += cxa_aux_runtime.cpp cxa_default_handlers.cpp cxa_demangle.cpp +CPPSRCS += cxa_guard.cpp cxa_handlers.cpp cxa_vector.cpp cxa_virtual.cpp # C++ STL files CPPSRCS += stdlib_exception.cpp stdlib_new_delete.cpp stdlib_stdexcept.cpp stdlib_typeinfo.cpp # Internal files -CPPSRCS += abort_message.cpp fallback_malloc.cpp private_typeinfo.cpp +CPPSRCS += abort_message.cpp private_typeinfo.cpp + +# Use stub files instead of originals (no threading, no TLS) +CPPSRCS += cxa_exception_storage_stub.cpp fallback_malloc_stub.cpp ifeq ($(CONFIG_CXX_EXCEPTION),y) CPPSRCS += cxa_exception.cpp cxa_personality.cpp @@ -85,4 +93,6 @@ CXXFLAGS += -DLIBCXXABI_NON_DEMANGLING_TERMINATE CXXFLAGS += -frtti DEPPATH += --dep-path libcxxabi/libcxxabi/src +DEPPATH += --dep-path libcxxabi/src VPATH += libcxxabi/libcxxabi/src +VPATH += libcxxabi/src diff --git a/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp b/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp new file mode 100644 index 0000000000000..79b9e0e71eada --- /dev/null +++ b/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// ============================================================================ +// CRITICAL SAFETY WARNING - READ BEFORE USE +// ============================================================================ +// +// This implementation uses a SINGLE GLOBAL exception state without any +// synchronization mechanism. It is ONLY safe under these conditions: +// +// 1. Single-threaded execution (no RTOS task switching during exception +// handling) +// 2. No interrupt-based exception throwing +// 3. No concurrent exception handling across tasks +// 4. _LIBCPP_HAS_NO_THREADS must be defined at compile time +// +// UNSAFE SCENARIOS (will cause data corruption): +// - Multiple RTOS tasks throwing exceptions simultaneously +// - Exception thrown from ISR while task is handling exception +// - Nested exceptions across different execution contexts +// +// FOR MULTI-THREADED SYSTEMS: +// Implement per-task exception storage using NuttX TLS or task-local storage. +// +// RECOMMENDED FOR CRITICAL SYSTEMS: +// Disable C++ exceptions entirely (CONFIG_CXX_EXCEPTION=n) and use +// error codes instead. +// ============================================================================ + +#include "../libcxxabi/src/cxa_exception.h" +#include +#include +#include + +// Use NuttX Task Local Storage for per-task exception state +#include + +// Compile-time safety check: ensure threading is disabled for libcxx +#ifndef _LIBCPP_HAS_NO_THREADS +#error \ + "cxa_exception_storage_stub.cpp requires _LIBCPP_HAS_NO_THREADS to be defined." +#endif + +namespace __cxxabiv1 { + +// Per-task exception storage using NuttX TLS +// This is THREAD-SAFE and works correctly with NuttX RTOS task switching +static int tls_key = -1; + +// Initialize TLS key on first use (lazy initialization) +static void init_tls_key() { + if (tls_key == -1) { + // Allocate TLS slot with destructor to free memory on task exit + tls_key = task_tls_alloc([](void *ptr) { + if (ptr) { + free(ptr); + } + }); + // Verify allocation succeeded + assert(tls_key >= 0 && "Failed to allocate TLS key for exception storage"); + } +} + +extern __cxa_eh_globals *__cxa_get_globals() { + // Ensure TLS key is initialized + init_tls_key(); + + // Get per-task exception state from TLS (returns uintptr_t, needs + // reinterpret_cast) + __cxa_eh_globals *eh = + reinterpret_cast<__cxa_eh_globals *>(task_tls_get_value(tls_key)); + + if (!eh) { + // First exception in this task - allocate storage + eh = static_cast<__cxa_eh_globals *>(malloc(sizeof(__cxa_eh_globals))); + if (!eh) { + // Out of memory - this is fatal for exception handling + assert(false && "Out of memory allocating exception state"); + return nullptr; + } + + // Initialize to zero + memset(eh, 0, sizeof(__cxa_eh_globals)); + + // Store in TLS for this task (requires uintptr_t cast) + task_tls_set_value(tls_key, reinterpret_cast(eh)); + } + + return eh; +} + +extern __cxa_eh_globals *__cxa_get_globals_fast() { + // Fast version assumes TLS is already initialized + // SAFETY: Only call this after __cxa_get_globals() has been called once + init_tls_key(); + return reinterpret_cast<__cxa_eh_globals *>(task_tls_get_value(tls_key)); +} + +} // namespace __cxxabiv1 diff --git a/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp b/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp new file mode 100644 index 0000000000000..6bfbaa59fc084 --- /dev/null +++ b/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp @@ -0,0 +1,143 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include + +namespace __cxxabiv1 { + +// Simple malloc wrapper for fallback allocation +void *__aligned_malloc_with_fallback(size_t size) { return malloc(size); } + +// Proper aligned allocation for embedded systems +// SAFETY: Alignment requirements are critical for ARM/RISC-V architectures +// CRITICAL SAFETY CHECKS: +// 1. Integer overflow protection on size calculations +// 2. Alignment validation (must be power of 2) +// 3. NULL pointer checks on all allocations +// 4. Bounds validation before pointer arithmetic +void *__aligned_malloc_with_fallback(size_t alignment, size_t size) { + // SAFETY: Validate alignment is power of 2 and non-zero + assert(alignment > 0 && (alignment & (alignment - 1)) == 0); + + // SAFETY: Reject zero-size allocations explicitly + if (size == 0) { + return nullptr; + } + + // For small alignments that malloc already provides, use malloc directly + if (alignment <= alignof(max_align_t)) { + void *ptr = malloc(size); + // SAFETY: Check malloc success + if (!ptr) { + return nullptr; + } + return ptr; + } + + // CRITICAL SAFETY CHECK: Prevent integer overflow in size calculation + // total_size = size + alignment + sizeof(void*) + // Check: size <= SIZE_MAX - alignment - sizeof(void*) + if (size > SIZE_MAX - alignment - sizeof(void *)) { + // Integer overflow would occur - MUST reject to prevent buffer overflow + return nullptr; + } + + size_t total_size = size + alignment + sizeof(void *); + + // SAFETY: Additional sanity check that total_size is reasonable + assert(total_size > size && "Integer overflow detected"); + + void *raw_ptr = malloc(total_size); + + // SAFETY: Check malloc failure + if (!raw_ptr) { + return nullptr; + } + + // Calculate aligned address + uintptr_t raw_addr = reinterpret_cast(raw_ptr); + uintptr_t offset = alignment - (raw_addr % alignment); + + // Ensure we have space to store the original pointer + if (offset < sizeof(void *)) { + offset += alignment; + } + + // SAFETY: Verify offset is within allocated bounds + assert(offset <= total_size - size && "Alignment calculation error"); + + void *aligned_ptr = reinterpret_cast(raw_addr + offset); + + // Store original pointer just before the aligned pointer + void **ptr_storage = reinterpret_cast(aligned_ptr) - 1; + + // SAFETY: Verify pointer storage location is within allocated memory + assert(reinterpret_cast(ptr_storage) >= raw_addr && + reinterpret_cast(ptr_storage) < raw_addr + total_size && + "Pointer storage out of bounds"); + + *ptr_storage = raw_ptr; + + // SAFETY: Final verification that aligned pointer meets alignment requirement + assert((reinterpret_cast(aligned_ptr) & (alignment - 1)) == 0 && + "Alignment requirement not met"); + + return aligned_ptr; +} + +// Allocate zero-initialized memory with overflow protection +// SAFETY: calloc checks for overflow internally, but we add explicit validation +void *__calloc_with_fallback(size_t count, size_t size) { + // SAFETY: Check for multiplication overflow before calling calloc + // Many implementations check this, but we verify explicitly for safety + if (count != 0 && size > SIZE_MAX / count) { + // Overflow would occur - reject allocation + return nullptr; + } + + void *ptr = calloc(count, size); + + // SAFETY: Check allocation success + if (!ptr && count > 0 && size > 0) { + // Allocation failed - return nullptr + return nullptr; + } + + return ptr; +} + +// Free properly aligned memory with safety validation +// SAFETY: Validates pointer before freeing to prevent corruption +void __aligned_free_with_fallback(void *ptr) { + // SAFETY: NULL pointer is valid to free (no-op) + if (!ptr) { + return; + } + + // Retrieve the original pointer stored before the aligned pointer + void **ptr_storage = reinterpret_cast(ptr) - 1; + void *original_ptr = *ptr_storage; + + // SAFETY: Validate that original pointer is not NULL + // If this fails, memory corruption has occurred + assert(original_ptr != nullptr && "Corrupted alignment metadata detected"); + + // SAFETY: Verify original_ptr is before or equal to aligned ptr + // This catches some forms of corruption + assert(reinterpret_cast(original_ptr) <= + reinterpret_cast(ptr) && + "Memory corruption: original pointer after aligned pointer"); + + // Free the original allocation + free(original_ptr); +} + +} // namespace __cxxabiv1 From 6cb466cc1f60cd9954320e08ff881a883d541bbe Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Sat, 10 Jan 2026 23:17:06 +0100 Subject: [PATCH 02/17] libs/libxx: Fix issue with exception handling Fix exception handling issues in libcxx and libcxxabi to work properly with NuttX's exception model. Signed-off-by: Bartosz --- .../configs/testlibcxx/defconfig | 4 ++ libs/libxx/libcxxabi/CMakeLists.txt | 2 + libs/libxx/libcxxabi/Make.defs | 2 + .../libcxxabi/src/fallback_malloc_stub.cpp | 38 ++++++++++++------- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig b/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig index fd17d3158312a..3349007bd8735 100644 --- a/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig +++ b/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig @@ -23,6 +23,7 @@ CONFIG_HAVE_CXX=y CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INTELHEX_BINARY=y CONFIG_LIBCXX=y +CONFIG_LIBCXXABI=y CONFIG_LIBC_FLOATINGPOINT=y CONFIG_LIBC_LOCALE=y CONFIG_LIBC_LOCALTIME=y @@ -49,3 +50,6 @@ CONFIG_TLS_TASK_NELEM=8 CONFIG_USART2_RXBUFSIZE=128 CONFIG_USART2_SERIAL_CONSOLE=y CONFIG_USART2_TXBUFSIZE=128 +CONFIG_CXX_EXCEPTION=y +CONFIG_CXX_RTTI=y +CONFIG_TESTING_CXXTEST=y diff --git a/libs/libxx/libcxxabi/CMakeLists.txt b/libs/libxx/libcxxabi/CMakeLists.txt index 6f4593c85bc78..e13ad4c5dd2dd 100644 --- a/libs/libxx/libcxxabi/CMakeLists.txt +++ b/libs/libxx/libcxxabi/CMakeLists.txt @@ -141,6 +141,8 @@ if(CONFIG_LIBCXXABI) # error: '_URC_FATAL_PHASE1_ERROR' was not declared in this scope 594 | # results.reason = _URC_FATAL_PHASE1_ERROR; if(CONFIG_ARCH_ARM) + # Enable bare-metal mode for correct TARGET2 relocation handling + target_compile_definitions(libcxxabi PRIVATE LIBCXXABI_BAREMETAL) target_compile_definitions(libcxxabi PRIVATE _URC_FATAL_PHASE2_ERROR=_URC_FAILURE) target_compile_definitions(libcxxabi diff --git a/libs/libxx/libcxxabi/Make.defs b/libs/libxx/libcxxabi/Make.defs index 57ce77e012c4a..b87cd1f87b924 100644 --- a/libs/libxx/libcxxabi/Make.defs +++ b/libs/libxx/libcxxabi/Make.defs @@ -84,6 +84,8 @@ endif # libcxxabi/src/cxa_personality.cpp:594:22: error: '_URC_FATAL_PHASE1_ERROR' was not declared in this scope # 594 | results.reason = _URC_FATAL_PHASE1_ERROR; ifeq ($(CONFIG_ARCH_ARM),y) +# Enable bare-metal mode for correct TARGET2 relocation handling +CXXFLAGS += -DLIBCXXABI_BAREMETAL CXXFLAGS += -D_URC_FATAL_PHASE2_ERROR=_URC_FAILURE -D_URC_FATAL_PHASE1_ERROR=_URC_FAILURE endif diff --git a/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp b/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp index 6bfbaa59fc084..53f78fe7d7c04 100644 --- a/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp +++ b/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp @@ -116,28 +116,40 @@ void *__calloc_with_fallback(size_t count, size_t size) { // Free properly aligned memory with safety validation // SAFETY: Validates pointer before freeing to prevent corruption +// NOTE: For single-argument __aligned_malloc_with_fallback(size), we just use +// malloc/free directly For two-argument version with alignment, we store the +// original pointer before the aligned address void __aligned_free_with_fallback(void *ptr) { // SAFETY: NULL pointer is valid to free (no-op) if (!ptr) { return; } - // Retrieve the original pointer stored before the aligned pointer + // Check if this pointer has the alignment metadata + // If alignment was requested, the original pointer is stored at ptr - + // sizeof(void*) For simple malloc (no alignment), we just free directly void **ptr_storage = reinterpret_cast(ptr) - 1; void *original_ptr = *ptr_storage; - // SAFETY: Validate that original pointer is not NULL - // If this fails, memory corruption has occurred - assert(original_ptr != nullptr && "Corrupted alignment metadata detected"); - - // SAFETY: Verify original_ptr is before or equal to aligned ptr - // This catches some forms of corruption - assert(reinterpret_cast(original_ptr) <= - reinterpret_cast(ptr) && - "Memory corruption: original pointer after aligned pointer"); - - // Free the original allocation - free(original_ptr); + // Heuristic: If the stored "pointer" value looks invalid (not aligned, or + // points way before current ptr), assume this was allocated with malloc(size) + // directly and just free it. Otherwise, use the stored original pointer. + uintptr_t ptr_addr = reinterpret_cast(ptr); + uintptr_t orig_addr = reinterpret_cast(original_ptr); + + // Check if original_ptr looks valid: + // 1. Not NULL + // 2. Points before or at aligned ptr + // 3. Within reasonable distance (< 1MB offset indicates alignment padding, + // not corruption) + if (original_ptr != nullptr && orig_addr <= ptr_addr && + (ptr_addr - orig_addr) < (1024 * 1024)) { + // Looks like aligned allocation with stored pointer + free(original_ptr); + } else { + // Looks like simple malloc allocation without alignment metadata + free(ptr); + } } } // namespace __cxxabiv1 From 0b3dd3004c9e29f9af9ba2760e95bb1d01de3957 Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Sun, 11 Jan 2026 15:26:58 +0100 Subject: [PATCH 03/17] arch/esp32: Add changes for esp32 riscv work Add necessary changes to support ESP32 RISC-V initialization with proper C++ constructor handling including code style fixes. Signed-off-by: Bartosz --- .../common/scripts/esp32c3_sections.ld | 2 +- .../esp32/common/scripts/esp32_sections.ld | 3 +- .../common/scripts/esp32s2_sections.ld | 3 +- .../common/scripts/esp32s3_sections.ld | 3 +- libs/libc/misc/lib_cxx_initialize.c | 94 ++++++++++++++++++- libs/libxx/libcxx/CMakeLists.txt | 38 ++++---- libs/libxx/libcxxabi/CMakeLists.txt | 27 +++--- 7 files changed, 133 insertions(+), 37 deletions(-) diff --git a/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld b/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld index a17778cd55afc..3fe6251e9c0dc 100644 --- a/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld +++ b/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld @@ -401,7 +401,7 @@ SECTIONS *(.fini) *(.gnu.version) - . += 16; + . = ALIGN(4); _text_end = ABSOLUTE(.); _instruction_reserved_end = ABSOLUTE(.); /* This is a symbol marking the flash.text end, this can be used for mmu driver to maintain virtual address */ diff --git a/boards/xtensa/esp32/common/scripts/esp32_sections.ld b/boards/xtensa/esp32/common/scripts/esp32_sections.ld index 45aa551873c18..b6fea359d945a 100644 --- a/boards/xtensa/esp32/common/scripts/esp32_sections.ld +++ b/boards/xtensa/esp32/common/scripts/esp32_sections.ld @@ -619,7 +619,6 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) __init_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ @@ -635,6 +634,8 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); + /* TLS data. */ . = ALIGN(4); diff --git a/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld b/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld index 59b70e6ecb305..d1af400032318 100644 --- a/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld +++ b/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld @@ -529,7 +529,6 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) __init_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ @@ -545,6 +544,8 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); + /* TLS data. */ . = ALIGN(4); diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld b/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld index 5ecf431c2f5ca..878041a60be2d 100644 --- a/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld +++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld @@ -693,7 +693,6 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) __init_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ @@ -709,6 +708,8 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); + /* TLS data. */ . = ALIGN(4); diff --git a/libs/libc/misc/lib_cxx_initialize.c b/libs/libc/misc/lib_cxx_initialize.c index 4db113fcd10fd..17c2278282449 100644 --- a/libs/libc/misc/lib_cxx_initialize.c +++ b/libs/libc/misc/lib_cxx_initialize.c @@ -24,8 +24,8 @@ * Included Files ****************************************************************************/ -#include #include +#include #include #include @@ -42,6 +42,35 @@ extern void macho_call_saved_init_funcs(void); #endif +/* ESP32 platforms have linker scripts that place non-constructor data + * (soc_reserved_memory_region, esp_system_init_fn_array) between _sinit + * and _einit. This requires explicit handling to avoid calling invalid + * function pointers. + * + * ESP32 RISC-V chips: Have __init_priority_array and __init_array + * ESP32 Xtensa chips: Have only __init_array (using .ctors) + */ + +#if defined(CONFIG_ARCH_CHIP_ESP32) || defined(CONFIG_ARCH_CHIP_ESP32S2) || \ + defined(CONFIG_ARCH_CHIP_ESP32S3) + +/* Xtensa ESP32 chips: Only __init_array exists */ + +extern initializer_t __init_array_start[]; +extern initializer_t __init_array_end[]; +#define USE_ESP32_XTENSA_INIT_ARRAYS 1 +#elif defined(CONFIG_ARCH_CHIP_ESP32C3) || \ + defined(CONFIG_ARCH_CHIP_ESP32C6) || defined(CONFIG_ARCH_CHIP_ESP32H2) + +/* RISC-V ESP32 chips: Both __init_priority_array and __init_array exist */ + +extern initializer_t __init_priority_array_start[]; +extern initializer_t __init_priority_array_end[]; +extern initializer_t __init_array_start[]; +extern initializer_t __init_array_end[]; +#define USE_ESP32_RISCV_INIT_ARRAYS 1 +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -71,6 +100,65 @@ void lib_cxx_initialize(void) { #if defined(CONFIG_ARCH_SIM) && defined(CONFIG_HOST_MACOS) macho_call_saved_init_funcs(); +#elif defined(USE_ESP32_XTENSA_INIT_ARRAYS) + initializer_t *initp; + + /* ESP32 Xtensa platforms: Only iterate __init_array, skipping + * non-constructor data after it. + */ + + sinfo("__init_array: %p to %p\n", __init_array_start, + __init_array_end); + + for (initp = __init_array_start; initp < __init_array_end; initp++) + { + initializer_t initializer = *initp; + sinfo("initp: %p initializer: %p\n", initp, initializer); + + if (initializer) + { + sinfo("Calling %p\n", initializer); + initializer(); + } + } +#elif defined(USE_ESP32_RISCV_INIT_ARRAYS) + initializer_t *initp; + + /* ESP32 RISC-V platforms: Iterate through priority array first, + * then regular array, skipping the non-constructor data sections + * in between. + */ + + sinfo("__init_priority_array: %p to %p\n", + __init_priority_array_start, __init_priority_array_end); + + for (initp = __init_priority_array_start; + initp < __init_priority_array_end; initp++) + { + initializer_t initializer = *initp; + sinfo("priority initp: %p initializer: %p\n", initp, initializer); + + if (initializer) + { + sinfo("Calling %p\n", initializer); + initializer(); + } + } + + sinfo("__init_array: %p to %p\n", __init_array_start, + __init_array_end); + + for (initp = __init_array_start; initp < __init_array_end; initp++) + { + initializer_t initializer = *initp; + sinfo("initp: %p initializer: %p\n", initp, initializer); + + if (initializer) + { + sinfo("Calling %p\n", initializer); + initializer(); + } + } #else initializer_t *initp; @@ -83,8 +171,8 @@ void lib_cxx_initialize(void) initializer_t initializer = *initp; sinfo("initp: %p initializer: %p\n", initp, initializer); - /* Make sure that the address is non-NULL. Some toolchains may put - * NULL values or counts in the initialization table. + /* Make sure that the address is non-NULL. Some toolchains + * may put NULL values or counts in the initialization table. */ if (initializer) diff --git a/libs/libxx/libcxx/CMakeLists.txt b/libs/libxx/libcxx/CMakeLists.txt index 58b74874e84c2..404ff5be202c4 100644 --- a/libs/libxx/libcxx/CMakeLists.txt +++ b/libs/libxx/libcxx/CMakeLists.txt @@ -44,22 +44,22 @@ if(CONFIG_LIBCXX) "" PATCH_COMMAND patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/mbstate_t_21.1.8.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/mbstate_t_21.1.8.patch && patch -p1 -d + ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-remove-mach-time-h_21.1.8.patch && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-exception-no-rtti_21.1.8.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC___21.1.8.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-exception-no-rtti_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC___21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -78,12 +78,14 @@ if(CONFIG_LIBCXX) # Copy config files to the libcxx source include directory before symlinking # Remove existing files first to allow reconfiguration file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__config_site) - configure_file(${CMAKE_CURRENT_LIST_DIR}/../__config_site - ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__config_site COPYONLY) + configure_file( + ${CMAKE_CURRENT_LIST_DIR}/../__config_site + ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__config_site COPYONLY) file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__assertion_handler) - configure_file(${CMAKE_CURRENT_LIST_DIR}/__assertion_handler - ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__assertion_handler COPYONLY) + configure_file( + ${CMAKE_CURRENT_LIST_DIR}/__assertion_handler + ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__assertion_handler COPYONLY) set_property( TARGET nuttx diff --git a/libs/libxx/libcxxabi/CMakeLists.txt b/libs/libxx/libcxxabi/CMakeLists.txt index e13ad4c5dd2dd..1744270d0a049 100644 --- a/libs/libxx/libcxxabi/CMakeLists.txt +++ b/libs/libxx/libcxxabi/CMakeLists.txt @@ -43,12 +43,12 @@ if(CONFIG_LIBCXXABI) "" PATCH_COMMAND patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < ${CMAKE_CURRENT_LIST_DIR}/0002-libcxxabi-fix-compilation-errors.patch && patch -p0 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < - ${CMAKE_CURRENT_LIST_DIR}/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < + ${CMAKE_CURRENT_LIST_DIR}/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < ${CMAKE_CURRENT_LIST_DIR}/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -82,8 +82,8 @@ if(CONFIG_LIBCXXABI) cxa_handlers.cpp cxa_vector.cpp cxa_virtual.cpp) - # Excluded: cxa_exception_storage.cpp (uses thread-local storage __aeabi_read_tp) - # Excluded threading-dependent files: cxa_thread_atexit.cpp + # Excluded: cxa_exception_storage.cpp (uses thread-local storage + # __aeabi_read_tp) Excluded threading-dependent files: cxa_thread_atexit.cpp add_compile_definitions(_LIBCPP_BUILDING_LIBRARY) if(CONFIG_LIBSUPCXX_TOOLCHAIN) add_compile_definitions(__GLIBCXX__) @@ -105,8 +105,9 @@ if(CONFIG_LIBCXXABI) ${CMAKE_CURRENT_LIST_DIR}/src/fallback_malloc_stub.cpp) # Exclude threading-dependent files when _LIBCPP_HAS_NO_THREADS is defined - # These files use __libcpp_mutex_t, __libcpp_condvar_t, __libcpp_tls_key which are not available without threading - # list(APPEND SRCS cxa_guard.cpp cxa_thread_atexit.cpp) + # These files use __libcpp_mutex_t, __libcpp_condvar_t, __libcpp_tls_key which + # are not available without threading list(APPEND SRCS cxa_guard.cpp + # cxa_thread_atexit.cpp) if(CONFIG_CXX_EXCEPTION) list(APPEND SRCS cxa_exception.cpp cxa_personality.cpp) @@ -124,13 +125,15 @@ if(CONFIG_LIBCXXABI) # RTTI is required for building the libcxxabi library target_compile_options(libcxxabi PRIVATE -frtti) - # Fix ARM unwinder enum type conversion warnings without disabling all type safety + # Fix ARM unwinder enum type conversion warnings without disabling all type + # safety if(CONFIG_ARCH_ARM) - target_compile_options(libcxxabi PRIVATE -Wno-error=conversion -Wno-error=enum-conversion) + target_compile_options(libcxxabi PRIVATE -Wno-error=conversion + -Wno-error=enum-conversion) endif() - # Disable threading support to match libcxx configuration - # Note: _LIBCPP_HAS_NO_THREADS is already defined in __config_site + # Disable threading support to match libcxx configuration Note: + # _LIBCPP_HAS_NO_THREADS is already defined in __config_site target_compile_definitions(libcxxabi PRIVATE _LIBCXXABI_HAS_NO_THREADS) if(CONFIG_SIM_UBSAN OR CONFIG_MM_UBSAN) From d2094d68fa19876764c13acf0f79c33d1017e938 Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Mon, 12 Jan 2026 08:56:19 +0100 Subject: [PATCH 04/17] libs/libxx/libcxx/: Added supported for threads This commit adds support for threads using pthread support. Signed-off-by: Bartosz --- .../configs/testlibcxx/defconfig | 59 +++++++++ libs/libxx/__config_site | 10 +- libs/libxx/libcxx/CMakeLists.txt | 22 ++-- libs/libxx/libcxx/Make.defs | 13 +- ...isable-threading-in-cxa-guard_21.1.8.patch | 21 +--- libs/libxx/libcxxabi/Make.defs | 3 - .../src/cxa_exception_storage_stub.cpp | 112 +++++++++--------- 7 files changed, 130 insertions(+), 110 deletions(-) create mode 100644 boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig new file mode 100644 index 0000000000000..d718b452f4d0c --- /dev/null +++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig @@ -0,0 +1,59 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="esp32c3-devkit" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32C3_DEVKIT=y +CONFIG_ARCH_CHIP="esp32c3" +CONFIG_ARCH_CHIP_ESP32C3=y +CONFIG_ARCH_INTERRUPTSTACK=1536 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BOARD_LOOPSPERMSEC=15000 +CONFIG_BUILTIN=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_BACKTRACE=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_DUMPSTACK=y +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_GETPRIME=y +CONFIG_TESTING_OSTEST=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_BUILTIN=y +CONFIG_CXX_LOCALIZATION=y +CONFIG_CXX_WCHAR=y +CONFIG_EXAMPLES_HELLOXX=y +CONFIG_HAVE_CXX=y +CONFIG_LIBCXX=y +CONFIG_LIBCXXABI=y +CONFIG_CXX_EXCEPTION=y +CONFIG_CXX_RTTI=y +CONFIG_TESTING_CXXTEST=y +CONFIG_LIBC_LOCALE=y +CONFIG_TLS_NELEM=16 +CONFIG_TLS_TASK_NELEM=8 +CONFIG_DEFAULT_THREAD_STACKSIZE=4096 diff --git a/libs/libxx/__config_site b/libs/libxx/__config_site index efc59e1068011..e5fde40902cb8 100644 --- a/libs/libxx/__config_site +++ b/libs/libxx/__config_site @@ -15,13 +15,13 @@ #define _LIBCPP_ABI_NAMESPACE __1 /* #undef _LIBCPP_ABI_FORCE_ITANIUM */ /* #undef _LIBCPP_ABI_FORCE_MICROSOFT */ -#define _LIBCPP_HAS_NO_THREADS -#define _LIBCPP_HAS_THREADS 0 -#define _LIBCPP_HAS_NO_MONOTONIC_CLOCK -#define _LIBCPP_HAS_MONOTONIC_CLOCK 0 +/* #undef _LIBCPP_HAS_NO_THREADS */ +#define _LIBCPP_HAS_THREADS 1 +#define _LIBCPP_HAS_THREAD_API_PTHREAD 1 +/* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */ +#define _LIBCPP_HAS_MONOTONIC_CLOCK 1 #define _LIBCPP_HAS_TIME_ZONE_DATABASE 0 /* #undef _LIBCPP_HAS_MUSL_LIBC */ -/* #undef _LIBCPP_HAS_THREAD_API_PTHREAD */ /* #undef _LIBCPP_HAS_THREAD_API_EXTERNAL */ /* #undef _LIBCPP_HAS_THREAD_API_WIN32 */ /* #undef _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS */ diff --git a/libs/libxx/libcxx/CMakeLists.txt b/libs/libxx/libcxx/CMakeLists.txt index 404ff5be202c4..edc56ab3c57f7 100644 --- a/libs/libxx/libcxx/CMakeLists.txt +++ b/libs/libxx/libcxx/CMakeLists.txt @@ -113,21 +113,13 @@ if(CONFIG_LIBCXX) file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ryu/*.cpp) list(APPEND SRCS ${SRCSTMP}) - # Exclude threading-related files since _LIBCPP_HAS_NO_THREADS is defined - file( - GLOB - SRCSTMP - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/barrier.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/condition_variable.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/condition_variable_destructor.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/mutex.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/mutex_destructor.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/thread.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/future.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/shared_mutex.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/call_once.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/atomic.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/charconv.cpp) + # Always exclude C++20 barrier (has additional dependencies not available in + # NuttX) + file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/barrier.cpp) + list(REMOVE_ITEM SRCS ${SRCSTMP}) + + # Exclude files with embedded-incompatible dependencies + file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/charconv.cpp) list(REMOVE_ITEM SRCS ${SRCSTMP}) if(NOT CONFIG_CXX_LOCALIZATION) diff --git a/libs/libxx/libcxx/Make.defs b/libs/libxx/libcxx/Make.defs index 77b44acc74cce..7a10230ac94f8 100644 --- a/libs/libxx/libcxx/Make.defs +++ b/libs/libxx/libcxx/Make.defs @@ -79,17 +79,8 @@ CPPSRCS += $(wildcard libcxx/libcxx/src/*.cpp) CPPSRCS += $(wildcard libcxx/libcxx/src/filesystem/*.cpp) CPPSRCS += $(wildcard libcxx/libcxx/src/ryu/*.cpp) -# Exclude threading-related files when _LIBCPP_HAS_NO_THREADS is defined -THREAD_CPPSRCS := libcxx/libcxx/src/atomic.cpp -THREAD_CPPSRCS += libcxx/libcxx/src/barrier.cpp -THREAD_CPPSRCS += libcxx/libcxx/src/condition_variable.cpp -THREAD_CPPSRCS += libcxx/libcxx/src/condition_variable_destructor.cpp -THREAD_CPPSRCS += libcxx/libcxx/src/future.cpp -THREAD_CPPSRCS += libcxx/libcxx/src/mutex.cpp -THREAD_CPPSRCS += libcxx/libcxx/src/mutex_destructor.cpp -THREAD_CPPSRCS += libcxx/libcxx/src/shared_mutex.cpp -THREAD_CPPSRCS += libcxx/libcxx/src/thread.cpp -CPPSRCS := $(filter-out $(THREAD_CPPSRCS), $(CPPSRCS)) +# Always exclude C++20 barrier (has additional dependencies not available in NuttX) +CPPSRCS := $(filter-out libcxx/libcxx/src/barrier.cpp, $(CPPSRCS)) # Exclude files with embedded-incompatible dependencies INCOMPATIBLE_CPPSRCS := libcxx/libcxx/src/charconv.cpp diff --git a/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch b/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch index 04d8ba1f363b6..c989a8f8bff83 100644 --- a/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch +++ b/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch @@ -1,24 +1,6 @@ --- libcxxabi.orig/src/cxa_guard_impl.h 2026-01-10 14:08:51.808835600 +0100 +++ libcxxabi/src/cxa_guard_impl.h 2026-01-10 14:08:51.819473598 +0100 -@@ -64,7 +64,7 @@ - #include - #include - --#ifndef _LIBCXXABI_HAS_NO_THREADS -+#if !defined(_LIBCXXABI_HAS_NO_THREADS) && !defined(_LIBCPP_HAS_NO_THREADS) - # if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB) - # pragma comment(lib, "pthread") - # endif -@@ -280,7 +280,7 @@ - struct LibcppMutex; - struct LibcppCondVar; - --#ifndef _LIBCXXABI_HAS_NO_THREADS -+#if !defined(_LIBCXXABI_HAS_NO_THREADS) && !defined(_LIBCPP_HAS_NO_THREADS) - struct LibcppMutex { - LibcppMutex() = default; - LibcppMutex(LibcppMutex const&) = delete; -@@ -663,7 +663,7 @@ +@@ -665,7 +665,7 @@ // TODO(EricWF): We should prefer the futex implementation when available. But // it should be done in a separate step from adding the implementation. constexpr Implementation CurrentImplementation = @@ -27,3 +9,4 @@ Implementation::NoThreads; #elif defined(_LIBCXXABI_USE_FUTEX) Implementation::Futex; + diff --git a/libs/libxx/libcxxabi/Make.defs b/libs/libxx/libcxxabi/Make.defs index b87cd1f87b924..e9d5a3111fa92 100644 --- a/libs/libxx/libcxxabi/Make.defs +++ b/libs/libxx/libcxxabi/Make.defs @@ -53,9 +53,6 @@ ifeq ($(CONFIG_LIBCXXABI), y) CXXFLAGS += ${DEFINE_PREFIX}LIBCXX_BUILDING_LIBCXXABI CXXFLAGS += -I $(TOPDIR)/libs/libxx/libcxxabi/libcxxabi/include -# Define _LIBCPP_HAS_NO_THREADS for no-threading builds -CXXFLAGS += ${DEFINE_PREFIX}_LIBCPP_HAS_NO_THREADS - # Disable dynamic type checking when enabling libcxxabi # It results in a recursive call: # cxxabiv1::__dynamic_case -> is_equal -> __ubsan::checkDynamic -> cxxabiv1::__dynamic_case diff --git a/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp b/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp index 79b9e0e71eada..f73f72f292867 100644 --- a/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp +++ b/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp @@ -7,76 +7,67 @@ //===----------------------------------------------------------------------===// // ============================================================================ -// CRITICAL SAFETY WARNING - READ BEFORE USE +// THREAD-SAFE EXCEPTION STORAGE FOR NUTTX // ============================================================================ // -// This implementation uses a SINGLE GLOBAL exception state without any -// synchronization mechanism. It is ONLY safe under these conditions: +// This implementation provides per-thread exception storage using pthread +// thread-local storage (TLS). It is THREAD-SAFE and works correctly with: // -// 1. Single-threaded execution (no RTOS task switching during exception -// handling) -// 2. No interrupt-based exception throwing -// 3. No concurrent exception handling across tasks -// 4. _LIBCPP_HAS_NO_THREADS must be defined at compile time +// 1. Multi-threaded execution with NuttX RTOS task switching +// 2. Concurrent exception handling across different threads +// 3. Nested exceptions within the same thread +// 4. Proper cleanup when threads exit // -// UNSAFE SCENARIOS (will cause data corruption): -// - Multiple RTOS tasks throwing exceptions simultaneously -// - Exception thrown from ISR while task is handling exception -// - Nested exceptions across different execution contexts +// SAFETY FEATURES: +// - Uses pthread_key_create with destructor for automatic cleanup +// - Thread-safe initialization using pthread_once +// - Per-thread exception state isolation +// - No shared mutable state between threads // -// FOR MULTI-THREADED SYSTEMS: -// Implement per-task exception storage using NuttX TLS or task-local storage. -// -// RECOMMENDED FOR CRITICAL SYSTEMS: -// Disable C++ exceptions entirely (CONFIG_CXX_EXCEPTION=n) and use -// error codes instead. +// NOTE: This implementation requires pthread support to be enabled in NuttX +// (CONFIG_PTHREAD=y) // ============================================================================ #include "../libcxxabi/src/cxa_exception.h" #include #include #include - -// Use NuttX Task Local Storage for per-task exception state -#include - -// Compile-time safety check: ensure threading is disabled for libcxx -#ifndef _LIBCPP_HAS_NO_THREADS -#error \ - "cxa_exception_storage_stub.cpp requires _LIBCPP_HAS_NO_THREADS to be defined." -#endif +#include namespace __cxxabiv1 { -// Per-task exception storage using NuttX TLS -// This is THREAD-SAFE and works correctly with NuttX RTOS task switching -static int tls_key = -1; - -// Initialize TLS key on first use (lazy initialization) -static void init_tls_key() { - if (tls_key == -1) { - // Allocate TLS slot with destructor to free memory on task exit - tls_key = task_tls_alloc([](void *ptr) { - if (ptr) { - free(ptr); - } - }); - // Verify allocation succeeded - assert(tls_key >= 0 && "Failed to allocate TLS key for exception storage"); +// pthread key for per-thread exception storage +static pthread_key_t exception_storage_key; +static pthread_once_t key_init_once = PTHREAD_ONCE_INIT; + +// Destructor called when thread exits - frees the exception storage +static void exception_storage_destructor(void *ptr) { + if (ptr) { + free(ptr); } } -extern __cxa_eh_globals *__cxa_get_globals() { - // Ensure TLS key is initialized - init_tls_key(); +// Initialize pthread key once (thread-safe) +static void init_exception_storage_key() { + int result = + pthread_key_create(&exception_storage_key, exception_storage_destructor); + assert(result == 0 && "Failed to create pthread key for exception storage"); + (void)result; // Suppress unused variable warning in release builds +} - // Get per-task exception state from TLS (returns uintptr_t, needs - // reinterpret_cast) - __cxa_eh_globals *eh = - reinterpret_cast<__cxa_eh_globals *>(task_tls_get_value(tls_key)); +extern "C" { + +// Get per-thread exception globals, allocating if necessary +__cxa_eh_globals *__cxa_get_globals() { + // Ensure pthread key is initialized (thread-safe, happens only once) + pthread_once(&key_init_once, init_exception_storage_key); + + // Get per-thread exception state from pthread TLS + __cxa_eh_globals *eh = static_cast<__cxa_eh_globals *>( + pthread_getspecific(exception_storage_key)); if (!eh) { - // First exception in this task - allocate storage + // First exception in this thread - allocate storage eh = static_cast<__cxa_eh_globals *>(malloc(sizeof(__cxa_eh_globals))); if (!eh) { // Out of memory - this is fatal for exception handling @@ -87,18 +78,25 @@ extern __cxa_eh_globals *__cxa_get_globals() { // Initialize to zero memset(eh, 0, sizeof(__cxa_eh_globals)); - // Store in TLS for this task (requires uintptr_t cast) - task_tls_set_value(tls_key, reinterpret_cast(eh)); + // Store in pthread TLS for this thread + int result = pthread_setspecific(exception_storage_key, eh); + assert(result == 0 && "Failed to set pthread-specific exception storage"); + (void)result; } return eh; } -extern __cxa_eh_globals *__cxa_get_globals_fast() { - // Fast version assumes TLS is already initialized - // SAFETY: Only call this after __cxa_get_globals() has been called once - init_tls_key(); - return reinterpret_cast<__cxa_eh_globals *>(task_tls_get_value(tls_key)); +// Fast version - assumes __cxa_get_globals() has been called at least once +__cxa_eh_globals *__cxa_get_globals_fast() { + // Ensure pthread key is initialized + pthread_once(&key_init_once, init_exception_storage_key); + + // Get per-thread exception state (may be nullptr if not yet initialized) + return static_cast<__cxa_eh_globals *>( + pthread_getspecific(exception_storage_key)); } +} // extern "C" + } // namespace __cxxabiv1 From 141a55fae636effab948aa45c9428eab66feb0aa Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Mon, 12 Jan 2026 12:43:15 +0100 Subject: [PATCH 05/17] arch/arm: Remove long-calls Remove flag for long-calls for arm architecture. Signed-off-by: Bartosz --- CMakeLists.txt | 8 -------- arch/arm/src/cmake/gcc.cmake | 5 ----- arch/arm/src/common/Toolchain.defs | 5 ----- 3 files changed, 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af6e09ee499de..82ff10e2cd9a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -522,14 +522,6 @@ add_definitions(-D__NuttX__) add_compile_options($<$:-D__ASSEMBLY__>) -if(CONFIG_LIBCXX) - if(CONFIG_ARCH_ARM) - add_compile_options($<$:-mlong-calls>) - elseif(CONFIG_ARCH_RISCV) - add_compile_options($<$:-mcmodel=medany>) - endif() -endif() - # Setup main nuttx target #################################################### add_executable(nuttx) diff --git a/arch/arm/src/cmake/gcc.cmake b/arch/arm/src/cmake/gcc.cmake index c924edd820afe..b11518bab3298 100644 --- a/arch/arm/src/cmake/gcc.cmake +++ b/arch/arm/src/cmake/gcc.cmake @@ -274,11 +274,6 @@ if(NOT CONFIG_CXX_RTTI) add_compile_options($<$:-fno-rtti>) endif() -# Add -mlong-calls for C++ when using libcxx to fix relocation issues -if(CONFIG_LIBCXX) - add_compile_options($<$:-mlong-calls>) -endif() - set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs") set(PREPROCESS ${CMAKE_C_COMPILER} ${CMAKE_C_FLAG_ARGS} -E -P -x c) diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index 5bc566b8042bb..3e544748c2c64 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -406,11 +406,6 @@ ifneq ($(CONFIG_CXX_RTTI),y) ARCHCXXFLAGS += -fno-rtti endif -# Add -mlong-calls for C++ when using libcxx to fix relocation issues -ifeq ($(CONFIG_LIBCXX),y) - ARCHCXXFLAGS += -mlong-calls -endif - ifeq ($(CONFIG_ARM_TOOLCHAIN_GHS),y) ARCHOPTIMIZATION += --no_commons else From b434ed5279a0c6263bca00e0baf56be9de66da5a Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Mon, 12 Jan 2026 14:20:43 +0100 Subject: [PATCH 06/17] ci/docker/: Update Ubuntu version with ARM, RISCV gnu toolchains boards/sim/: Change gcc to clang This commit will update Docker file to latest Ubuntu LTS with update of GCC for ARM and RISCV. Also SIM boards with LIBCXX are build with clang because GCC < 15 have lack of some builtin features. Signed-off-by: Bartosz --- boards/sim/sim/sim/configs/citest/defconfig | 1 + boards/sim/sim/sim/configs/libcxxtest/defconfig | 1 + boards/sim/sim/sim/configs/matter/defconfig | 1 + boards/sim/sim/sim/configs/tflm/defconfig | 1 + boards/sim/sim/sim/scripts/Make.defs | 6 ++++++ libs/libxx/libcxx/CMakeLists.txt | 3 +-- libs/libxx/libcxx/Make.defs | 8 ++++++++ tools/ci/docker/linux/Dockerfile | 16 ++++++++-------- 8 files changed, 27 insertions(+), 10 deletions(-) diff --git a/boards/sim/sim/sim/configs/citest/defconfig b/boards/sim/sim/sim/configs/citest/defconfig index 6f371fb9a4698..7b4dd9eaa518a 100644 --- a/boards/sim/sim/sim/configs/citest/defconfig +++ b/boards/sim/sim/sim/configs/citest/defconfig @@ -15,6 +15,7 @@ CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD_SIM=y CONFIG_ARCH_CHIP="sim" CONFIG_ARCH_SIM=y +CONFIG_SIM_TOOLCHAIN_CLANG=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARDCTL_ROMDISK=y diff --git a/boards/sim/sim/sim/configs/libcxxtest/defconfig b/boards/sim/sim/sim/configs/libcxxtest/defconfig index 86df52f1db1f1..1c07c49eb797b 100644 --- a/boards/sim/sim/sim/configs/libcxxtest/defconfig +++ b/boards/sim/sim/sim/configs/libcxxtest/defconfig @@ -11,6 +11,7 @@ CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD_SIM=y CONFIG_ARCH_CHIP="sim" CONFIG_ARCH_SIM=y +CONFIG_SIM_TOOLCHAIN_CLANG=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARD_LOOPSPERMSEC=0 diff --git a/boards/sim/sim/sim/configs/matter/defconfig b/boards/sim/sim/sim/configs/matter/defconfig index 34eeb8afec0ec..f5b5d6a1b5909 100644 --- a/boards/sim/sim/sim/configs/matter/defconfig +++ b/boards/sim/sim/sim/configs/matter/defconfig @@ -12,6 +12,7 @@ CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD_SIM=y CONFIG_ARCH_CHIP="sim" CONFIG_ARCH_SIM=y +CONFIG_SIM_TOOLCHAIN_CLANG=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARD_LOOPSPERMSEC=0 diff --git a/boards/sim/sim/sim/configs/tflm/defconfig b/boards/sim/sim/sim/configs/tflm/defconfig index e688f5d9a2866..e74edb8003b9d 100644 --- a/boards/sim/sim/sim/configs/tflm/defconfig +++ b/boards/sim/sim/sim/configs/tflm/defconfig @@ -11,6 +11,7 @@ CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD_SIM=y CONFIG_ARCH_CHIP="sim" CONFIG_ARCH_SIM=y +CONFIG_SIM_TOOLCHAIN_CLANG=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARD_LOOPSPERMSEC=0 diff --git a/boards/sim/sim/sim/scripts/Make.defs b/boards/sim/sim/sim/scripts/Make.defs index 4106e7412479f..8599193188630 100644 --- a/boards/sim/sim/sim/scripts/Make.defs +++ b/boards/sim/sim/sim/scripts/Make.defs @@ -186,9 +186,15 @@ endif ARCHPICFLAGS = -fpic +ifeq ($(CONFIG_SIM_TOOLCHAIN_CLANG),y) +CC = $(CROSSDEV)clang +CXX = $(CROSSDEV)clang++ +CPP = $(CROSSDEV)clang -E -P -x c +else CC = $(CROSSDEV)cc CXX = $(CROSSDEV)c++ CPP = $(CROSSDEV)cc -E -P -x c +endif LD = $(CROSSDEV)ld ifeq ($(CONFIG_HOST_MACOS),y) STRIP = $(CROSSDEV)strip diff --git a/libs/libxx/libcxx/CMakeLists.txt b/libs/libxx/libcxx/CMakeLists.txt index edc56ab3c57f7..4e581fe157db5 100644 --- a/libs/libxx/libcxx/CMakeLists.txt +++ b/libs/libxx/libcxx/CMakeLists.txt @@ -55,8 +55,7 @@ if(CONFIG_LIBCXX) ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC___21.1.8.patch && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch + $,$,$>,&& patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch,> && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < diff --git a/libs/libxx/libcxx/Make.defs b/libs/libxx/libcxx/Make.defs index 7a10230ac94f8..0ef0bc38365b9 100644 --- a/libs/libxx/libcxx/Make.defs +++ b/libs/libxx/libcxx/Make.defs @@ -37,7 +37,15 @@ libcxx/libcxx: libcxx-$(LIBCXX_VERSION).src.tar.xz $(Q) patch -p1 < libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch -d libcxx/libcxx $(Q) patch -p1 < libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch -d libcxx/libcxx $(Q) patch -p1 < libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch -d libcxx/libcxx +ifdef CONFIG_ARCH_ARM $(Q) patch -p1 < libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch -d libcxx/libcxx +endif +ifdef CONFIG_ARCH_ARM64 + $(Q) patch -p1 < libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch -d libcxx/libcxx +endif +ifdef CONFIG_ARCH_RISCV + $(Q) patch -p1 < libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch -d libcxx/libcxx +endif $(Q) patch -p1 < libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch -d libcxx/libcxx $(Q) patch -p1 < libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch -d libcxx/libcxx diff --git a/tools/ci/docker/linux/Dockerfile b/tools/ci/docker/linux/Dockerfile index f91681bbbd522..b80737e0f65ed 100644 --- a/tools/ci/docker/linux/Dockerfile +++ b/tools/ci/docker/linux/Dockerfile @@ -15,7 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. -FROM ubuntu:22.04 AS builder-base +FROM ubuntu:24.04 AS builder-base # NOTE WE ARE NOT REMOVING APT CACHE. # This should only be used for temp build images that artifacts will be copied from RUN apt-get update -qq && apt-get install -y -qq \ @@ -109,9 +109,9 @@ RUN mkdir -p $CARGO_HOME \ # ENV SWIFT_VERSION=6.0-DEVELOPMENT-SNAPSHOT-2024-08-22-a # ENV SWIFT_HOME=/tools/swift # RUN mkdir -p ${SWIFT_HOME} \ -# && curl -s -O -L https://download.swift.org/swift-6.0-branch/ubuntu2204/swift-${SWIFT_VERSION}/swift-${SWIFT_VERSION}-ubuntu22.04.tar.gz \ -# && tar xzf swift-${SWIFT_VERSION}-ubuntu22.04.tar.gz -C ${SWIFT_HOME} \ -# && rm swift-${SWIFT_VERSION}-ubuntu22.04.tar.gz +# && curl -s -O -L https://download.swift.org/swift-6.0-branch/ubuntu2204/swift-${SWIFT_VERSION}/swift-${SWIFT_VERSION}-ubuntu24.04.tar.gz \ +# && tar xzf swift-${SWIFT_VERSION}-ubuntu24.04.tar.gz -C ${SWIFT_HOME} \ +# && rm swift-${SWIFT_VERSION}-ubuntu24.04.tar.gz # Install Zig latest release ENV ZIG_VERSION=0.13.0 @@ -153,7 +153,7 @@ RUN mkdir -p clang-arm-none-eabi && \ # Download the latest ARM GCC toolchain prebuilt by ARM RUN mkdir -p gcc-arm-none-eabi && \ - curl -s -L "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.Rel1/binrel/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi.tar.xz" \ + curl -s -L "https://developer.arm.com/-/media/Files/downloads/gnu/15.2.Rel1/binrel/arm-gnu-toolchain-15.2.Rel1-x86_64-arm-none-eabi.tar.xz" \ | tar -C gcc-arm-none-eabi --strip-components 1 -xJ ############################################################################### @@ -162,7 +162,7 @@ RUN mkdir -p gcc-arm-none-eabi && \ FROM nuttx-toolchain-base AS nuttx-toolchain-arm64 # Download the latest ARM64 GCC toolchain prebuilt by ARM RUN mkdir gcc-aarch64-none-elf && \ - curl -s -L "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.Rel1/binrel/arm-gnu-toolchain-13.2.Rel1-x86_64-aarch64-none-elf.tar.xz" \ + curl -s -L "https://developer.arm.com/-/media/Files/downloads/gnu/15.2.Rel1/binrel/arm-gnu-toolchain-15.2.Rel1-x86_64-aarch64-none-elf.tar.xz" \ | tar -C gcc-aarch64-none-elf --strip-components 1 -xJ ############################################################################### @@ -250,7 +250,7 @@ RUN cd /tools/renesas-tools/build/gcc && \ FROM nuttx-toolchain-base AS nuttx-toolchain-riscv # Download the latest RISCV GCC toolchain prebuilt by xPack RUN mkdir -p riscv-none-elf-gcc && \ - curl -s -L "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-3/xpack-riscv-none-elf-gcc-14.2.0-3-linux-x64.tar.gz" \ + curl -s -L "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v15.2.0-1/xpack-riscv-none-elf-gcc-15.2.0-1-linux-x64.tar.gz" \ | tar -C riscv-none-elf-gcc --strip-components 1 -xz ############################################################################### @@ -318,7 +318,7 @@ RUN mkdir -p picotool && \ # Final Docker image used for running CI system. This includes all toolchains # supported by the CI system. ############################################################################### -FROM ubuntu:22.04 +FROM ubuntu:24.04 LABEL maintainer="dev@nuttx.apache.org" RUN apt-get update -qq && DEBIAN_FRONTEND="noninteractive" apt-get install -y -qq \ From 527bf765ba94693d54741c956b16d64b81d6dd7b Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Mon, 12 Jan 2026 14:22:54 +0100 Subject: [PATCH 07/17] libs/libxx/: Fix CMakeLists.txt formatting Fix cmake formatting. Signed-off-by: Bartosz --- libs/libxx/libcxx/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/libxx/libcxx/CMakeLists.txt b/libs/libxx/libcxx/CMakeLists.txt index 4e581fe157db5..1077c262ad67b 100644 --- a/libs/libxx/libcxx/CMakeLists.txt +++ b/libs/libxx/libcxx/CMakeLists.txt @@ -55,7 +55,9 @@ if(CONFIG_LIBCXX) ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC___21.1.8.patch && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch - $,$,$>,&& patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch,> + $,$,$>,&& + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch,> && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < ${CMAKE_CURRENT_LIST_DIR}/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < From 05f48aff36383fa784013e66776684d40983d857 Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Mon, 12 Jan 2026 15:01:43 +0100 Subject: [PATCH 08/17] boards/sim/: Change mcmodel to large Change mcmodel to large and update bloaty to latest version Signed-off-by: Bartosz --- boards/sim/sim/sim/scripts/Make.defs | 4 ++-- tools/ci/docker/linux/Dockerfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/sim/sim/sim/scripts/Make.defs b/boards/sim/sim/sim/scripts/Make.defs index 8599193188630..55df92cdb5d76 100644 --- a/boards/sim/sim/sim/scripts/Make.defs +++ b/boards/sim/sim/sim/scripts/Make.defs @@ -152,8 +152,8 @@ else ARCHCFLAGS += -fno-pic ARCHCXXFLAGS += -fno-pic ifneq ($(CONFIG_HOST_MACOS),y) - ARCHCFLAGS += -mcmodel=medium - ARCHCXXFLAGS += -mcmodel=medium + ARCHCFLAGS += -mcmodel=large + ARCHCXXFLAGS += -mcmodel=large endif endif diff --git a/tools/ci/docker/linux/Dockerfile b/tools/ci/docker/linux/Dockerfile index b80737e0f65ed..19c5b855a968f 100644 --- a/tools/ci/docker/linux/Dockerfile +++ b/tools/ci/docker/linux/Dockerfile @@ -54,7 +54,7 @@ RUN curl -s -L https://bitbucket.org/nuttx/tools/get/9ad3e1ee75c7.tar.gz \ | tar -C nuttx-tools --strip-components=1 -xz RUN mkdir -p /tools/bloaty \ - && git clone --depth 1 --branch v1.1 https://github.com/google/bloaty bloaty-src \ + && git clone --depth 1 https://github.com/google/bloaty bloaty-src \ && cd bloaty-src \ && cmake -B build -DCMAKE_INSTALL_PREFIX=/tools/bloaty \ && cmake --build build \ From 8fe85d4837eadad9a83817c32fedffd9bcea242b Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Mon, 12 Jan 2026 17:58:55 +0100 Subject: [PATCH 09/17] libs/libxx/: FIx CMakLists.txt patches Fix patches includes in libcxx. Signed-off-by: Bartosz --- libs/libxx/libcxx/CMakeLists.txt | 56 ++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/libs/libxx/libcxx/CMakeLists.txt b/libs/libxx/libcxx/CMakeLists.txt index 1077c262ad67b..78b9374f57b33 100644 --- a/libs/libxx/libcxx/CMakeLists.txt +++ b/libs/libxx/libcxx/CMakeLists.txt @@ -25,6 +25,41 @@ if(CONFIG_LIBCXX) set(LIBCXX_VERSION ${CONFIG_LIBCXX_VERSION}) + # Build patch command conditionally + set(LIBCXX_PATCH_COMMAND + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/mbstate_t_21.1.8.patch && patch -p1 -d + ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-remove-mach-time-h_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-exception-no-rtti_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC___21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch + ) + + # Add architecture-specific patch for ARM, ARM64, and RISC-V + if(CONFIG_ARCH_ARM + OR CONFIG_ARCH_ARM64 + OR CONFIG_ARCH_RISCV) + set(LIBCXX_PATCH_COMMAND + ${LIBCXX_PATCH_COMMAND} && patch -p1 -d + ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch + ) + endif() + + set(LIBCXX_PATCH_COMMAND + ${LIBCXX_PATCH_COMMAND} && patch -p1 -d + ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch + && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch + ) + FetchContent_Declare( libcxx DOWNLOAD_NAME "libcxx-${LIBCXX_VERSION}.src.tar.xz" @@ -42,26 +77,7 @@ if(CONFIG_LIBCXX) "" TEST_COMMAND "" - PATCH_COMMAND - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/mbstate_t_21.1.8.patch && patch -p1 -d - ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-remove-mach-time-h_21.1.8.patch && - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-exception-no-rtti_21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC___21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch - $,$,$>,&& - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch,> - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch + PATCH_COMMAND ${LIBCXX_PATCH_COMMAND} DOWNLOAD_NO_PROGRESS true TIMEOUT 30) From 804d1f1347ed4193e6198eb1cb47cf417a5827a3 Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Mon, 12 Jan 2026 21:57:50 +0100 Subject: [PATCH 10/17] tools/ci/docker/: Update clang to version 21 in Dockerfile Update Clang to version 21. Signed-off-by: Bartosz --- tools/ci/docker/linux/Dockerfile | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/tools/ci/docker/linux/Dockerfile b/tools/ci/docker/linux/Dockerfile index 19c5b855a968f..bbccd373294e1 100644 --- a/tools/ci/docker/linux/Dockerfile +++ b/tools/ci/docker/linux/Dockerfile @@ -15,7 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. -FROM ubuntu:24.04 AS builder-base +FROM ubuntu:22.04 AS builder-base # NOTE WE ARE NOT REMOVING APT CACHE. # This should only be used for temp build images that artifacts will be copied from RUN apt-get update -qq && apt-get install -y -qq \ @@ -109,9 +109,9 @@ RUN mkdir -p $CARGO_HOME \ # ENV SWIFT_VERSION=6.0-DEVELOPMENT-SNAPSHOT-2024-08-22-a # ENV SWIFT_HOME=/tools/swift # RUN mkdir -p ${SWIFT_HOME} \ -# && curl -s -O -L https://download.swift.org/swift-6.0-branch/ubuntu2204/swift-${SWIFT_VERSION}/swift-${SWIFT_VERSION}-ubuntu24.04.tar.gz \ -# && tar xzf swift-${SWIFT_VERSION}-ubuntu24.04.tar.gz -C ${SWIFT_HOME} \ -# && rm swift-${SWIFT_VERSION}-ubuntu24.04.tar.gz +# && curl -s -O -L https://download.swift.org/swift-6.0-branch/ubuntu2204/swift-${SWIFT_VERSION}/swift-${SWIFT_VERSION}-ubuntu22.04.tar.gz \ +# && tar xzf swift-${SWIFT_VERSION}-ubuntu22.04.tar.gz -C ${SWIFT_HOME} \ +# && rm swift-${SWIFT_VERSION}-ubuntu22.04.tar.gz # Install Zig latest release ENV ZIG_VERSION=0.13.0 @@ -318,14 +318,23 @@ RUN mkdir -p picotool && \ # Final Docker image used for running CI system. This includes all toolchains # supported by the CI system. ############################################################################### -FROM ubuntu:24.04 +FROM ubuntu:22.04 LABEL maintainer="dev@nuttx.apache.org" RUN apt-get update -qq && DEBIAN_FRONTEND="noninteractive" apt-get install -y -qq \ build-essential \ curl \ gcc \ - libssl-dev + libssl-dev \ + software-properties-common \ + wget \ + gnupg \ + lsb-release + +# Add LLVM repository for clang-21 +RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc +RUN echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-21 main" | tee /etc/apt/sources.list.d/llvm.list +RUN apt-get update -qq RUN mkdir -p cmake && \ curl -s -L https://cmake.org/files/v3.26/cmake-3.26.0.tar.gz \ @@ -339,8 +348,9 @@ RUN apt-get update -qq && DEBIAN_FRONTEND="noninteractive" TZ=Etc/UTC apt-get in -o APT::Immediate-Configure=0 \ avr-libc \ ccache \ - clang \ - clang-tidy \ + clang-21 \ + clang++-21 \ + clang-tidy-21 \ g++-12-multilib \ gcc-avr \ gcc-12-multilib \ @@ -388,6 +398,11 @@ RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 20 && \ update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30 && \ update-alternatives --set c++ /usr/bin/g++ +# Set Clang-21 as Default clang compiler +RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-21 50 && \ + update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-21 50 && \ + update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-21 50 + # Configure out base setup for adding python packages ENV PIP_DISABLE_PIP_VERSION_CHECK=true # This disables the cache with value 0. We do not want caching as it From ce13662b2c6d1e1126cced82dbe82ec9d41e0627 Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Mon, 12 Jan 2026 22:34:50 +0100 Subject: [PATCH 11/17] /tools/ci/docker/: Fix clang version for ubuntu 22.04 Fix version of Clang-21 for Ubuntu jammy Signed-off-by: Bartosz --- tools/ci/docker/linux/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ci/docker/linux/Dockerfile b/tools/ci/docker/linux/Dockerfile index bbccd373294e1..653e5de2884b1 100644 --- a/tools/ci/docker/linux/Dockerfile +++ b/tools/ci/docker/linux/Dockerfile @@ -333,7 +333,7 @@ RUN apt-get update -qq && DEBIAN_FRONTEND="noninteractive" apt-get install -y -q # Add LLVM repository for clang-21 RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc -RUN echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-21 main" | tee /etc/apt/sources.list.d/llvm.list +RUN echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-21 main" | tee /etc/apt/sources.list.d/llvm.list RUN apt-get update -qq RUN mkdir -p cmake && \ From fa52c205a4c820e35f96c07e566725c33ef23e3f Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Tue, 13 Jan 2026 07:59:27 +0100 Subject: [PATCH 12/17] /nuttx/boards/: Revert changes for SIM boards This commit will revert changes for SIM boards, there are in separate PR. Signed-off-by: Bartosz --- arch/arm/src/common/Toolchain.defs | 1 - boards/sim/sim/sim/configs/citest/defconfig | 1 - .../sim/sim/sim/configs/libcxxtest/defconfig | 1 - boards/sim/sim/sim/configs/matter/defconfig | 1 - boards/sim/sim/sim/configs/tflm/defconfig | 1 - boards/sim/sim/sim/scripts/Make.defs | 10 ++----- tools/ci/docker/linux/Dockerfile | 29 +++++-------------- 7 files changed, 9 insertions(+), 35 deletions(-) diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index 3e544748c2c64..f38ab852f0928 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -405,7 +405,6 @@ endif ifneq ($(CONFIG_CXX_RTTI),y) ARCHCXXFLAGS += -fno-rtti endif - ifeq ($(CONFIG_ARM_TOOLCHAIN_GHS),y) ARCHOPTIMIZATION += --no_commons else diff --git a/boards/sim/sim/sim/configs/citest/defconfig b/boards/sim/sim/sim/configs/citest/defconfig index 7b4dd9eaa518a..6f371fb9a4698 100644 --- a/boards/sim/sim/sim/configs/citest/defconfig +++ b/boards/sim/sim/sim/configs/citest/defconfig @@ -15,7 +15,6 @@ CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD_SIM=y CONFIG_ARCH_CHIP="sim" CONFIG_ARCH_SIM=y -CONFIG_SIM_TOOLCHAIN_CLANG=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARDCTL_ROMDISK=y diff --git a/boards/sim/sim/sim/configs/libcxxtest/defconfig b/boards/sim/sim/sim/configs/libcxxtest/defconfig index 1c07c49eb797b..86df52f1db1f1 100644 --- a/boards/sim/sim/sim/configs/libcxxtest/defconfig +++ b/boards/sim/sim/sim/configs/libcxxtest/defconfig @@ -11,7 +11,6 @@ CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD_SIM=y CONFIG_ARCH_CHIP="sim" CONFIG_ARCH_SIM=y -CONFIG_SIM_TOOLCHAIN_CLANG=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARD_LOOPSPERMSEC=0 diff --git a/boards/sim/sim/sim/configs/matter/defconfig b/boards/sim/sim/sim/configs/matter/defconfig index f5b5d6a1b5909..34eeb8afec0ec 100644 --- a/boards/sim/sim/sim/configs/matter/defconfig +++ b/boards/sim/sim/sim/configs/matter/defconfig @@ -12,7 +12,6 @@ CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD_SIM=y CONFIG_ARCH_CHIP="sim" CONFIG_ARCH_SIM=y -CONFIG_SIM_TOOLCHAIN_CLANG=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARD_LOOPSPERMSEC=0 diff --git a/boards/sim/sim/sim/configs/tflm/defconfig b/boards/sim/sim/sim/configs/tflm/defconfig index e74edb8003b9d..5b269ecc4c8c5 100644 --- a/boards/sim/sim/sim/configs/tflm/defconfig +++ b/boards/sim/sim/sim/configs/tflm/defconfig @@ -10,7 +10,6 @@ CONFIG_ARCH="sim" CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD_SIM=y CONFIG_ARCH_CHIP="sim" -CONFIG_ARCH_SIM=y CONFIG_SIM_TOOLCHAIN_CLANG=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y diff --git a/boards/sim/sim/sim/scripts/Make.defs b/boards/sim/sim/sim/scripts/Make.defs index 55df92cdb5d76..4106e7412479f 100644 --- a/boards/sim/sim/sim/scripts/Make.defs +++ b/boards/sim/sim/sim/scripts/Make.defs @@ -152,8 +152,8 @@ else ARCHCFLAGS += -fno-pic ARCHCXXFLAGS += -fno-pic ifneq ($(CONFIG_HOST_MACOS),y) - ARCHCFLAGS += -mcmodel=large - ARCHCXXFLAGS += -mcmodel=large + ARCHCFLAGS += -mcmodel=medium + ARCHCXXFLAGS += -mcmodel=medium endif endif @@ -186,15 +186,9 @@ endif ARCHPICFLAGS = -fpic -ifeq ($(CONFIG_SIM_TOOLCHAIN_CLANG),y) -CC = $(CROSSDEV)clang -CXX = $(CROSSDEV)clang++ -CPP = $(CROSSDEV)clang -E -P -x c -else CC = $(CROSSDEV)cc CXX = $(CROSSDEV)c++ CPP = $(CROSSDEV)cc -E -P -x c -endif LD = $(CROSSDEV)ld ifeq ($(CONFIG_HOST_MACOS),y) STRIP = $(CROSSDEV)strip diff --git a/tools/ci/docker/linux/Dockerfile b/tools/ci/docker/linux/Dockerfile index 653e5de2884b1..f91681bbbd522 100644 --- a/tools/ci/docker/linux/Dockerfile +++ b/tools/ci/docker/linux/Dockerfile @@ -54,7 +54,7 @@ RUN curl -s -L https://bitbucket.org/nuttx/tools/get/9ad3e1ee75c7.tar.gz \ | tar -C nuttx-tools --strip-components=1 -xz RUN mkdir -p /tools/bloaty \ - && git clone --depth 1 https://github.com/google/bloaty bloaty-src \ + && git clone --depth 1 --branch v1.1 https://github.com/google/bloaty bloaty-src \ && cd bloaty-src \ && cmake -B build -DCMAKE_INSTALL_PREFIX=/tools/bloaty \ && cmake --build build \ @@ -153,7 +153,7 @@ RUN mkdir -p clang-arm-none-eabi && \ # Download the latest ARM GCC toolchain prebuilt by ARM RUN mkdir -p gcc-arm-none-eabi && \ - curl -s -L "https://developer.arm.com/-/media/Files/downloads/gnu/15.2.Rel1/binrel/arm-gnu-toolchain-15.2.Rel1-x86_64-arm-none-eabi.tar.xz" \ + curl -s -L "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.Rel1/binrel/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi.tar.xz" \ | tar -C gcc-arm-none-eabi --strip-components 1 -xJ ############################################################################### @@ -162,7 +162,7 @@ RUN mkdir -p gcc-arm-none-eabi && \ FROM nuttx-toolchain-base AS nuttx-toolchain-arm64 # Download the latest ARM64 GCC toolchain prebuilt by ARM RUN mkdir gcc-aarch64-none-elf && \ - curl -s -L "https://developer.arm.com/-/media/Files/downloads/gnu/15.2.Rel1/binrel/arm-gnu-toolchain-15.2.Rel1-x86_64-aarch64-none-elf.tar.xz" \ + curl -s -L "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.Rel1/binrel/arm-gnu-toolchain-13.2.Rel1-x86_64-aarch64-none-elf.tar.xz" \ | tar -C gcc-aarch64-none-elf --strip-components 1 -xJ ############################################################################### @@ -250,7 +250,7 @@ RUN cd /tools/renesas-tools/build/gcc && \ FROM nuttx-toolchain-base AS nuttx-toolchain-riscv # Download the latest RISCV GCC toolchain prebuilt by xPack RUN mkdir -p riscv-none-elf-gcc && \ - curl -s -L "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v15.2.0-1/xpack-riscv-none-elf-gcc-15.2.0-1-linux-x64.tar.gz" \ + curl -s -L "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-3/xpack-riscv-none-elf-gcc-14.2.0-3-linux-x64.tar.gz" \ | tar -C riscv-none-elf-gcc --strip-components 1 -xz ############################################################################### @@ -325,16 +325,7 @@ RUN apt-get update -qq && DEBIAN_FRONTEND="noninteractive" apt-get install -y -q build-essential \ curl \ gcc \ - libssl-dev \ - software-properties-common \ - wget \ - gnupg \ - lsb-release - -# Add LLVM repository for clang-21 -RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc -RUN echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-21 main" | tee /etc/apt/sources.list.d/llvm.list -RUN apt-get update -qq + libssl-dev RUN mkdir -p cmake && \ curl -s -L https://cmake.org/files/v3.26/cmake-3.26.0.tar.gz \ @@ -348,9 +339,8 @@ RUN apt-get update -qq && DEBIAN_FRONTEND="noninteractive" TZ=Etc/UTC apt-get in -o APT::Immediate-Configure=0 \ avr-libc \ ccache \ - clang-21 \ - clang++-21 \ - clang-tidy-21 \ + clang \ + clang-tidy \ g++-12-multilib \ gcc-avr \ gcc-12-multilib \ @@ -398,11 +388,6 @@ RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 20 && \ update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30 && \ update-alternatives --set c++ /usr/bin/g++ -# Set Clang-21 as Default clang compiler -RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-21 50 && \ - update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-21 50 && \ - update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-21 50 - # Configure out base setup for adding python packages ENV PIP_DISABLE_PIP_VERSION_CHECK=true # This disables the cache with value 0. We do not want caching as it From c86ef55b531e46b69c32fc12d369a6d9f2395984 Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Tue, 13 Jan 2026 08:02:19 +0100 Subject: [PATCH 13/17] /boards/sim/: Minor fix of TFLM defconfig Revert SIM TFLM config. Signed-off-by: Bartosz --- boards/sim/sim/sim/configs/tflm/defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/sim/sim/sim/configs/tflm/defconfig b/boards/sim/sim/sim/configs/tflm/defconfig index 5b269ecc4c8c5..e688f5d9a2866 100644 --- a/boards/sim/sim/sim/configs/tflm/defconfig +++ b/boards/sim/sim/sim/configs/tflm/defconfig @@ -10,7 +10,7 @@ CONFIG_ARCH="sim" CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD_SIM=y CONFIG_ARCH_CHIP="sim" -CONFIG_SIM_TOOLCHAIN_CLANG=y +CONFIG_ARCH_SIM=y CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARD_LOOPSPERMSEC=0 From 7a9888bcdf3d7b25a21c1bfc36197dd2475a7cc6 Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Tue, 13 Jan 2026 08:15:27 +0100 Subject: [PATCH 14/17] boards/riscv/: Change _einit section This commit will change _einit section for esp32 mcu's for proper cxx initialization. Signed-off-by: Bartosz --- .../common/scripts/esp32c3_sections.ld | 4 +- .../common/scripts/esp32c6_sections.ld | 4 +- .../common/scripts/esp32h2_sections.ld | 4 +- .../esp32/common/scripts/esp32_sections.ld | 4 +- .../common/scripts/esp32s2_sections.ld | 4 +- .../common/scripts/esp32s3_sections.ld | 4 +- libs/libc/misc/lib_cxx_initialize.c | 130 +++--------------- 7 files changed, 31 insertions(+), 123 deletions(-) diff --git a/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld b/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld index 3fe6251e9c0dc..fd897e373a3ed 100644 --- a/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld +++ b/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld @@ -512,6 +512,8 @@ SECTIONS KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) __init_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); + /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ . = ALIGN(4); @@ -526,8 +528,6 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); - } >default_rodata_seg AT > ROM .flash.rodata_noload (NOLOAD) : diff --git a/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld b/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld index cb0c9459457aa..ac34baa1d905e 100644 --- a/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld +++ b/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld @@ -524,6 +524,8 @@ SECTIONS KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) __init_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); + /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ . = ALIGN(4); @@ -538,8 +540,6 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); - } >default_rodata_seg AT > ROM .flash.rodata_noload (NOLOAD) : diff --git a/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld b/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld index f7c3526db0cad..5020f2e50ebe3 100644 --- a/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld +++ b/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld @@ -522,6 +522,8 @@ SECTIONS KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) __init_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); + /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ . = ALIGN(4); @@ -536,8 +538,6 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); - } >default_rodata_seg AT > ROM .flash.rodata_noload (NOLOAD) : diff --git a/boards/xtensa/esp32/common/scripts/esp32_sections.ld b/boards/xtensa/esp32/common/scripts/esp32_sections.ld index b6fea359d945a..3744aef809fe0 100644 --- a/boards/xtensa/esp32/common/scripts/esp32_sections.ld +++ b/boards/xtensa/esp32/common/scripts/esp32_sections.ld @@ -620,6 +620,8 @@ SECTIONS KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) __init_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); + /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ . = ALIGN(4); @@ -634,8 +636,6 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); - /* TLS data. */ . = ALIGN(4); diff --git a/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld b/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld index d1af400032318..37c9a41c2eb3c 100644 --- a/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld +++ b/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld @@ -530,6 +530,8 @@ SECTIONS KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) __init_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); + /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ . = ALIGN(4); @@ -544,8 +546,6 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); - /* TLS data. */ . = ALIGN(4); diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld b/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld index 878041a60be2d..e8f301e47e017 100644 --- a/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld +++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld @@ -694,6 +694,8 @@ SECTIONS KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) __init_array_end = ABSOLUTE(.); + _einit = ABSOLUTE(.); + /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ . = ALIGN(4); @@ -708,8 +710,6 @@ SECTIONS KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*))) _esp_system_init_fn_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); - /* TLS data. */ . = ALIGN(4); diff --git a/libs/libc/misc/lib_cxx_initialize.c b/libs/libc/misc/lib_cxx_initialize.c index 17c2278282449..61074a0cc7506 100644 --- a/libs/libc/misc/lib_cxx_initialize.c +++ b/libs/libc/misc/lib_cxx_initialize.c @@ -42,35 +42,6 @@ extern void macho_call_saved_init_funcs(void); #endif -/* ESP32 platforms have linker scripts that place non-constructor data - * (soc_reserved_memory_region, esp_system_init_fn_array) between _sinit - * and _einit. This requires explicit handling to avoid calling invalid - * function pointers. - * - * ESP32 RISC-V chips: Have __init_priority_array and __init_array - * ESP32 Xtensa chips: Have only __init_array (using .ctors) - */ - -#if defined(CONFIG_ARCH_CHIP_ESP32) || defined(CONFIG_ARCH_CHIP_ESP32S2) || \ - defined(CONFIG_ARCH_CHIP_ESP32S3) - -/* Xtensa ESP32 chips: Only __init_array exists */ - -extern initializer_t __init_array_start[]; -extern initializer_t __init_array_end[]; -#define USE_ESP32_XTENSA_INIT_ARRAYS 1 -#elif defined(CONFIG_ARCH_CHIP_ESP32C3) || \ - defined(CONFIG_ARCH_CHIP_ESP32C6) || defined(CONFIG_ARCH_CHIP_ESP32H2) - -/* RISC-V ESP32 chips: Both __init_priority_array and __init_array exist */ - -extern initializer_t __init_priority_array_start[]; -extern initializer_t __init_priority_array_end[]; -extern initializer_t __init_array_start[]; -extern initializer_t __init_array_end[]; -#define USE_ESP32_RISCV_INIT_ARRAYS 1 -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -91,99 +62,36 @@ extern initializer_t __init_array_end[]; * ****************************************************************************/ -void lib_cxx_initialize(void) -{ +void lib_cxx_initialize(void) { #ifdef CONFIG_HAVE_CXXINITIALIZE static int inited = 0; - if (inited == 0) - { + if (inited == 0) { #if defined(CONFIG_ARCH_SIM) && defined(CONFIG_HOST_MACOS) - macho_call_saved_init_funcs(); -#elif defined(USE_ESP32_XTENSA_INIT_ARRAYS) - initializer_t *initp; - - /* ESP32 Xtensa platforms: Only iterate __init_array, skipping - * non-constructor data after it. - */ - - sinfo("__init_array: %p to %p\n", __init_array_start, - __init_array_end); - - for (initp = __init_array_start; initp < __init_array_end; initp++) - { - initializer_t initializer = *initp; - sinfo("initp: %p initializer: %p\n", initp, initializer); - - if (initializer) - { - sinfo("Calling %p\n", initializer); - initializer(); - } - } -#elif defined(USE_ESP32_RISCV_INIT_ARRAYS) - initializer_t *initp; - - /* ESP32 RISC-V platforms: Iterate through priority array first, - * then regular array, skipping the non-constructor data sections - * in between. - */ - - sinfo("__init_priority_array: %p to %p\n", - __init_priority_array_start, __init_priority_array_end); - - for (initp = __init_priority_array_start; - initp < __init_priority_array_end; initp++) - { - initializer_t initializer = *initp; - sinfo("priority initp: %p initializer: %p\n", initp, initializer); - - if (initializer) - { - sinfo("Calling %p\n", initializer); - initializer(); - } - } - - sinfo("__init_array: %p to %p\n", __init_array_start, - __init_array_end); - - for (initp = __init_array_start; initp < __init_array_end; initp++) - { - initializer_t initializer = *initp; - sinfo("initp: %p initializer: %p\n", initp, initializer); - - if (initializer) - { - sinfo("Calling %p\n", initializer); - initializer(); - } - } + macho_call_saved_init_funcs(); #else - initializer_t *initp; + initializer_t *initp; - sinfo("_sinit: %p _einit: %p\n", _sinit, _einit); + sinfo("_sinit: %p _einit: %p\n", _sinit, _einit); - /* Visit each entry in the initialization table */ + /* Visit each entry in the initialization table */ - for (initp = _sinit; initp < _einit; initp++) - { - initializer_t initializer = *initp; - sinfo("initp: %p initializer: %p\n", initp, initializer); + for (initp = _sinit; initp < _einit; initp++) { + initializer_t initializer = *initp; + sinfo("initp: %p initializer: %p\n", initp, initializer); - /* Make sure that the address is non-NULL. Some toolchains - * may put NULL values or counts in the initialization table. - */ + /* Make sure that the address is non-NULL. Some toolchains + * may put NULL values or counts in the initialization table. + */ - if (initializer) - { - sinfo("Calling %p\n", initializer); - initializer(); - } - } + if (initializer) { + sinfo("Calling %p\n", initializer); + initializer(); + } + } #endif - inited = 1; - } + inited = 1; + } #endif } From d3393591eb04f9de0c136d489fb6445264480ac6 Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Tue, 13 Jan 2026 08:17:37 +0100 Subject: [PATCH 15/17] /libs/libc/: Fix formatting Fix formatting. Signed-off-by: Bartosz --- libs/libc/misc/lib_cxx_initialize.c | 46 ++++++++++++++++------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/libs/libc/misc/lib_cxx_initialize.c b/libs/libc/misc/lib_cxx_initialize.c index 61074a0cc7506..d4c422b701ab1 100644 --- a/libs/libc/misc/lib_cxx_initialize.c +++ b/libs/libc/misc/lib_cxx_initialize.c @@ -24,8 +24,8 @@ * Included Files ****************************************************************************/ -#include #include +#include #include #include @@ -62,36 +62,40 @@ extern void macho_call_saved_init_funcs(void); * ****************************************************************************/ -void lib_cxx_initialize(void) { +void lib_cxx_initialize(void) +{ #ifdef CONFIG_HAVE_CXXINITIALIZE static int inited = 0; - if (inited == 0) { + if (inited == 0) + { #if defined(CONFIG_ARCH_SIM) && defined(CONFIG_HOST_MACOS) - macho_call_saved_init_funcs(); + macho_call_saved_init_funcs(); #else - initializer_t *initp; + initializer_t *initp; - sinfo("_sinit: %p _einit: %p\n", _sinit, _einit); + sinfo("_sinit: %p _einit: %p\n", _sinit, _einit); - /* Visit each entry in the initialization table */ + /* Visit each entry in the initialization table */ - for (initp = _sinit; initp < _einit; initp++) { - initializer_t initializer = *initp; - sinfo("initp: %p initializer: %p\n", initp, initializer); + for (initp = _sinit; initp < _einit; initp++) + { + initializer_t initializer = *initp; + sinfo("initp: %p initializer: %p\n", initp, initializer); - /* Make sure that the address is non-NULL. Some toolchains - * may put NULL values or counts in the initialization table. - */ + /* Make sure that the address is non-NULL. Some toolchains may put + * NULL values or counts in the initialization table. + */ - if (initializer) { - sinfo("Calling %p\n", initializer); - initializer(); - } - } + if (initializer) + { + sinfo("Calling %p\n", initializer); + initializer(); + } + } #endif - inited = 1; - } + inited = 1; + } #endif -} +} \ No newline at end of file From 553a703b4e9f8c59c30e6cf0830103d439e6cc24 Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Tue, 13 Jan 2026 08:20:25 +0100 Subject: [PATCH 16/17] /libs/libc/: Minor style fix Style fix. Signed-off-by: Bartosz --- libs/libc/misc/lib_cxx_initialize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/libc/misc/lib_cxx_initialize.c b/libs/libc/misc/lib_cxx_initialize.c index d4c422b701ab1..4db113fcd10fd 100644 --- a/libs/libc/misc/lib_cxx_initialize.c +++ b/libs/libc/misc/lib_cxx_initialize.c @@ -98,4 +98,4 @@ void lib_cxx_initialize(void) inited = 1; } #endif -} \ No newline at end of file +} From 737c7413edeb8faa97bac584d42aa9c882b989fa Mon Sep 17 00:00:00 2001 From: Bartosz Wawrzynek Date: Thu, 22 Jan 2026 09:02:30 +0100 Subject: [PATCH 17/17] /libcxx/libcxx/: Change libcxx and libcxxabi version to 19 Signed-off-by: Bartosz --- .github/workflows/build.yml | 5 +- CMakeLists.txt | 29 +- Documentation/ReleaseNotes/NuttX-7.29 | 2 +- Documentation/components/crypto.rst | 134 ++- .../components/drivers/special/ioexpander.rst | 256 ++++- Documentation/components/tools/index.rst | 42 + Documentation/reference/os/nuttx.rst | 10 - Documentation/reference/os/time_clock.rst | 59 +- arch/Kconfig | 7 + arch/arm/src/am335x/CMakeLists.txt | 50 + arch/arm/src/armv7-a/arm_gicv2.c | 23 +- arch/arm/src/armv7-a/arm_gicv2m.c | 3 +- arch/arm/src/armv7-a/gic.h | 25 +- arch/arm/src/armv7-m/Toolchain.defs | 8 +- arch/arm/src/armv7-m/arm_exception.S | 2 +- arch/arm/src/armv7-r/arm_gicv2.c | 23 +- arch/arm/src/armv7-r/gic.h | 25 +- arch/arm/src/armv8-r/arm_gic.h | 2 - arch/arm/src/armv8-r/arm_gicv3.c | 21 +- arch/arm/src/cmake/armv7-m_ghs.cmake | 8 +- arch/arm/src/cmake/ghs.cmake | 36 +- arch/arm/src/common/Toolchain.defs | 11 +- arch/arm/src/common/iar/fork.S | 2 +- arch/arm/src/cxd56xx/cxd56_farapistub.S | 18 +- arch/arm/src/imx6/imx_enet.c | 3 +- arch/arm/src/imx6/imx_serial.c | 2 +- arch/arm/src/imx6/imx_timerisr.c | 2 +- arch/arm/src/imxrt/imxrt_clockconfig_ver1.h | 2 +- arch/arm/src/imxrt/imxrt_tickless.c | 10 +- arch/arm/src/lpc43xx/lpc43_rit.c | 2 +- arch/arm/src/lpc43xx/lpc43_tickless_rit.c | 2 +- arch/arm/src/lpc54xx/lpc54_tickless.c | 2 +- arch/arm/src/moxart/moxart_head.S | 4 +- arch/arm/src/nrf52/nrf52_tickless_rtc.c | 4 +- arch/arm/src/nrf53/nrf53_tickless_rtc.c | 4 +- arch/arm/src/nrf91/nrf91_tickless_rtc.c | 4 +- arch/arm/src/sam34/sam4cm_tickless.c | 10 +- arch/arm/src/sama5/sam_tickless.c | 10 +- arch/arm/src/samd5e5/sam_tickless.c | 10 +- arch/arm/src/samv7/Kconfig | 1 - arch/arm/src/samv7/sam_tickless.c | 10 +- arch/arm/src/stm32/stm32_tickless.c | 10 +- arch/arm/src/stm32f7/stm32_tickless.c | 10 +- arch/arm/src/stm32h7/stm32_tickless.c | 10 +- arch/arm/src/stm32l4/stm32l4_tickless.c | 10 +- arch/arm/src/stm32wb/stm32wb_tickless.c | 10 +- .../src/tlsr82/chip/b87/boot/cstartup_flash.S | 2 +- arch/arm/src/xmc4/xmc4_tickless.c | 10 +- arch/arm64/Kconfig | 9 + arch/arm64/src/a64/a64_serial.c | 3 +- arch/arm64/src/a64/a64_twi.c | 3 +- arch/arm64/src/bcm2711/bcm2711_gpio.c | 3 +- arch/arm64/src/bcm2711/bcm2711_i2c.c | 3 +- arch/arm64/src/bcm2711/bcm2711_sdio.c | 3 +- arch/arm64/src/bcm2711/bcm2711_serial.c | 3 +- arch/arm64/src/bcm2711/bcm2711_spi.c | 3 +- arch/arm64/src/common/arm64_backtrace.c | 4 +- arch/arm64/src/common/arm64_gic.h | 12 - arch/arm64/src/common/arm64_gicv2.c | 73 +- arch/arm64/src/common/arm64_gicv2m.c | 3 +- arch/arm64/src/common/arm64_gicv3.c | 66 +- arch/arm64/src/common/arm64_initialstate.c | 4 + arch/arm64/src/common/arm64_mpu.c | 10 +- arch/arm64/src/common/arm64_syscall.c | 12 + arch/arm64/src/imx9/ddr/imx9_ddr_training.c | 2 +- arch/arm64/src/rk3399/rk3399_serial.c | 3 +- arch/arm64/src/zynq-mpsoc/zynq_serial.c | 3 +- .../src/avrdx/avrdx_timerisr_tickless_alarm.c | 4 +- .../src/common/espressif/esp_tickless.c | 8 +- .../src/esp32c3-legacy/esp32c3_tickless.c | 8 +- arch/risc-v/src/litex/litex_tickless.c | 8 +- arch/sim/Kconfig | 24 +- arch/sim/include/setjmp.h | 16 +- arch/sim/src/Makefile | 5 +- arch/sim/src/cmake/Toolchain.cmake | 4 + arch/sim/src/sim/CMakeLists.txt | 7 + arch/sim/src/sim/posix/sim_alsa.c | 16 +- arch/sim/src/sim/posix/sim_errno.c | 46 + arch/sim/src/sim/posix/sim_hostfs.c | 147 ++- arch/sim/src/sim/posix/sim_hostirq.c | 28 +- arch/sim/src/sim/posix/sim_hostmisc.c | 22 +- arch/sim/src/sim/posix/sim_hostuart.c | 49 +- arch/sim/src/sim/posix/sim_hostusrsock.c | 14 +- arch/sim/src/sim/posix/sim_rawgadget.c | 2 +- arch/sim/src/sim/sim_initialize.c | 50 +- arch/sim/src/sim/sim_internal.h | 32 +- arch/sim/src/sim/sim_netdriver.c | 62 +- arch/sim/src/sim/sim_rpmsg_virtio.c | 15 +- arch/sim/src/sim/sim_rptun.c | 13 +- arch/sim/src/sim/sim_usbdev.c | 12 +- arch/sim/src/sim/sim_usbhost.c | 13 +- arch/sim/src/sim/sim_usrsock.c | 10 +- .../sim/{sim_wifidriver.c => sim_wifihost.c} | 145 +-- arch/sim/src/sim/sim_wifihost.h | 73 ++ arch/sim/src/sim/win/sim_errno.c | 46 + arch/sim/src/sim/win/sim_hostirq.c | 16 +- arch/sparc/src/bm3803/bm3803_tickless.c | 10 +- arch/tricore/include/inttypes.h | 4 +- arch/tricore/include/irq.h | 79 +- arch/tricore/include/tc3xx/irq.h | 5 +- arch/tricore/src/common/CMakeLists.txt | 1 - arch/tricore/src/common/Make.defs | 1 - arch/tricore/src/common/tricore_csa.c | 6 +- arch/tricore/src/common/tricore_doirq.c | 44 +- arch/tricore/src/common/tricore_exit.c | 10 +- arch/tricore/src/common/tricore_initialize.c | 6 +- arch/tricore/src/common/tricore_internal.h | 23 +- .../tricore/src/common/tricore_registerdump.c | 98 ++ .../src/common/tricore_saveusercontext.c | 31 +- .../src/common/tricore_schedulesigaction.c | 19 +- arch/tricore/src/common/tricore_sigdeliver.c | 3 +- arch/tricore/src/common/tricore_svcall.c | 78 +- .../src/common/tricore_switchcontext.c | 27 +- arch/tricore/src/common/tricore_trapcall.c | 314 +++++- arch/x86_64/include/irq.h | 2 +- arch/x86_64/src/cmake/platform.cmake | 31 + arch/x86_64/src/common/CMakeLists.txt | 2 +- arch/x86_64/src/common/Make.defs | 2 +- arch/x86_64/src/common/fork.S | 4 + arch/x86_64/src/common/x86_64_syscall.c | 21 +- arch/x86_64/src/intel64/Kconfig | 4 +- arch/x86_64/src/intel64/intel64_cpu.c | 4 +- arch/x86_64/src/intel64/intel64_head.S | 10 +- .../src/intel64/intel64_saveusercontext.S | 2 +- .../x86_64/src/intel64/intel64_tsc_timerisr.c | 2 +- arch/xtensa/src/esp32/esp32_tickless.c | 8 +- arch/xtensa/src/esp32s3/esp32s3_tickless.c | 8 +- .../am335x/beaglebone-black/CMakeLists.txt | 23 + .../beaglebone-black/src/CMakeLists.txt | 39 + .../gd32f450zk-aiotbox/src/gd32f4xx_romfs.c | 2 +- .../gd32f450zk-eval/src/gd32f4xx_romfs.c | 2 +- .../gd32f470ik-eval/src/gd32f4xx_romfs.c | 2 +- .../gd32f470zk-aiotbox/src/gd32f4xx_romfs.c | 2 +- .../gd32f470zk-eval/src/gd32f4xx_romfs.c | 2 +- .../kinetis/freedom-k28f/src/k28_usbhshost.c | 2 +- .../pnev5180b/src/lpc17_40_romfs.c | 2 +- .../configs/netnsh/defconfig | 1 + .../src/stm32_romfs_initialize.c | 2 +- .../src/stm32_romfs_initialize.c | 2 +- .../omnibusf4/src/stm32_romfs_initialize.c | 2 +- .../stm32/stm32f103-minimum/src/stm32_gpio.c | 22 +- .../configs/testlibcxx/defconfig | 1 + .../src/stm32_romfs_initialize.c | 2 +- .../common/src/stm32_romfs_initialize.c | 2 +- .../src/stm32_romfs_initialize.c | 2 +- .../arm64/a64/pinephone/configs/lcd/defconfig | 1 + .../a64/pinephone/configs/lvgl/defconfig | 1 + .../arm64/a64/pinephone/configs/nsh/defconfig | 1 + .../a64/pinephone/configs/sensor/defconfig | 1 + .../arm64/a64/pinephone/src/pinephone_touch.c | 3 +- .../raspberrypi-4b/configs/cgol/defconfig | 1 + .../raspberrypi-4b/configs/fb/defconfig | 1 + .../raspberrypi-4b/configs/lvgl/defconfig | 1 + .../raspberrypi-4b/configs/nsh/defconfig | 1 + .../raspberrypi-4b/configs/sd/defconfig | 1 + .../rk3399/nanopi_m4/configs/nsh/defconfig | 1 + .../rk3399/pinephonepro/configs/nsh/defconfig | 1 + .../zynq-mpsoc/zcu111/configs/jtag/defconfig | 1 + .../zcu111/configs/netjtag/defconfig | 1 + .../zcu111/configs/netnsh/defconfig | 1 + .../zynq-mpsoc/zcu111/configs/nsh/defconfig | 1 + .../common/scripts/esp32c3_legacy_sections.ld | 16 + .../common/scripts/esp32c3_sections.ld | 19 +- .../configs/testlibcxx/defconfig | 3 +- .../esp32c3-xiao/configs/ble/defconfig | 2 - .../common/scripts/esp32c6_sections.ld | 18 +- .../common/scripts/esp32h2_sections.ld | 19 +- .../qemu-rv/rv-virt/configs/citest/defconfig | 1 + boards/sim/sim/sim/configs/citest/defconfig | 1 + .../sim/sim/sim/configs/posix_test/defconfig | 4 +- .../esp32/common/scripts/esp32_sections.ld | 1 - .../common/scripts/esp32s2_sections.ld | 1 - .../common/scripts/esp32s3_sections.ld | 1 - cmake/menuconfig.cmake | 11 +- cmake/nuttx_add_application.cmake | 5 +- cmake/nuttx_add_library.cmake | 6 + cmake/nuttx_extensions.cmake | 17 +- cmake/nuttx_kconfig.cmake | 12 + cmake/nuttx_process_config.cmake | 40 +- cmake/nuttx_toolchain.cmake | 16 + cmake/savedefconfig.cmake | 7 +- crypto/cryptodev.c | 3 + drivers/can/can_sender.c | 1 + drivers/drivers_initialize.c | 7 + drivers/misc/optee.c | 1 + drivers/mmcsd/mmcsd_sdio.c | 2 +- drivers/mtd/Kconfig | 23 +- drivers/mtd/cfi.c | 5 +- drivers/mtd/ftl.c | 21 +- drivers/mtd/mtd_config_fs.c | 806 ++++++++------ drivers/mtd/mtd_partition.c | 2 +- drivers/net/Kconfig | 6 + drivers/net/igc.c | 4 +- drivers/net/rpmsgdrv.c | 992 +++++++++--------- drivers/net/wifi_sim.c | 25 + drivers/pci/pci.c | 23 +- drivers/rpmsg/rpmsg.c | 52 +- drivers/rpmsg/rpmsg_port.c | 14 - drivers/rpmsg/rpmsg_port.h | 6 - drivers/rpmsg/rpmsg_port_spi.c | 4 +- drivers/rpmsg/rpmsg_port_spi_slave.c | 4 +- drivers/rpmsg/rpmsg_port_uart.c | 6 +- drivers/rpmsg/rpmsg_router.h | 6 +- drivers/rpmsg/rpmsg_router_edge.c | 29 +- drivers/rpmsg/rpmsg_router_hub.c | 38 + drivers/sensors/Kconfig | 1 - drivers/sensors/fakesensor_uorb.c | 30 +- drivers/sensors/sensor.c | 1 + drivers/timers/arch_alarm.c | 16 +- drivers/timers/arch_timer.c | 16 +- drivers/virtio/virtio-net.c | 15 +- fs/driver/fs_blockproxy.c | 45 +- fs/driver/fs_mtdproxy.c | 43 +- include/crypto/cryptodev.h | 66 +- include/fcntl.h | 10 +- include/limits.h | 6 + include/netinet/if_ether.h | 1 + include/netinet/in.h | 2 +- include/nuttx/arch.h | 68 +- include/nuttx/hrtimer.h | 24 +- include/nuttx/ioexpander/ioexpander.h | 4 + include/nuttx/net/net.h | 35 + include/nuttx/net/rpmsg.h | 6 +- include/nuttx/net/rpmsgdrv.h | 100 +- include/nuttx/net/wifi_sim.h | 1 + include/nuttx/notifier.h | 19 +- include/nuttx/rpmsg/rpmsg.h | 5 +- include/nuttx/tls.h | 3 +- include/nuttx/uorb.h | 19 +- include/pthread.h | 52 +- include/signal.h | 5 + include/stddef.h | 4 + include/stdint.h | 4 + include/stdio.h | 4 +- include/sys/ioctl.h | 7 + include/sys/resource.h | 2 + include/sys/types.h | 49 + include/sys/wait.h | 11 +- include/ulimit.h | 52 + include/unistd.h | 2 +- libs/libc/gdbstub/lib_gdbstub.c | 13 +- libs/libc/machine/arm/armv7-m/arch_memchr.S | 2 +- libs/libc/machine/arm/armv7-m/arch_memcpy.S | 2 +- libs/libc/machine/arm/armv7-m/arch_strcmp.S | 2 +- libs/libc/machine/arm/armv7-m/arch_strcpy.S | 2 +- libs/libc/machine/arm/armv7-m/arch_strlen.S | 2 +- libs/libc/misc/CMakeLists.txt | 1 + libs/libc/misc/Make.defs | 10 +- libs/libc/misc/lib_creat.c | 52 + libs/libc/misc/lib_ftok.c | 2 +- libs/libc/netdb/lib_dnsaddserver.c | 4 +- libs/libc/pthread/CMakeLists.txt | 1 + libs/libc/pthread/Make.defs | 2 +- libs/libc/pthread/pthread_equal.c | 55 + libs/libc/stdio/lib_freopen.c | 38 +- libs/libc/stdio/lib_fsetpos.c | 2 +- libs/libc/unistd/CMakeLists.txt | 3 +- libs/libc/unistd/Make.defs | 2 +- libs/libc/unistd/lib_pathconf.c | 3 + libs/libc/unistd/lib_sysconf.c | 248 ++--- libs/libc/unistd/lib_ulimit.c | 76 ++ libs/libc/wqueue/CMakeLists.txt | 2 +- libs/libm/libm/lib_atanf.c | 5 +- libs/libxx/Kconfig | 24 +- libs/libxx/__assertion_handler | 20 + libs/libxx/__config_site | 44 +- ...0001-Fix-build-error-about-__GLIBC__.patch | 12 +- ...x-build-error-about-__GLIBC___21.1.8.patch | 13 - ...-libcxx-fix-exception-no-rtti_21.1.8.patch | 12 - .../libcxx/0001-libcxx-fix-ld-errors.patch | 37 +- ...cxx-fix-ostream-no-exceptions_21.1.8.patch | 16 - .../0001-libcxx-remove-mach-time-h.patch | 6 +- ...001-libcxx-remove-mach-time-h_21.1.8.patch | 13 - .../0001_fix_stdatomic_h_miss_typedef.patch | 8 +- ..._fix_stdatomic_h_miss_typedef_21.1.8.patch | 11 - .../0002-libcxx-decay-and-tzdb-fixes.patch | 49 + ...cxx-fix-locale-instantiations_21.1.8.patch | 18 - ...invalid-locale-instantiations_21.1.8.patch | 45 - ...tring-template-instantiations_21.1.8.patch | 16 - ...x-locale-call-once-no-threads_21.1.8.patch | 25 - ...ecation-warnings-redefinition_21.1.8.patch | 10 - libs/libxx/libcxx/CMakeLists.txt | 325 ++++-- libs/libxx/libcxx/Make.defs | 58 +- libs/libxx/libcxx/__assertion_handler | 30 - libs/libxx/libcxx/mbstate_t.patch | 24 +- libs/libxx/libcxx/mbstate_t_21.1.8.patch | 17 - .../libcxx/nuttx_string_instantiations.cpp | 22 + ...bi-fix-exception-handler-init_21.1.8.patch | 21 - ...isable-threading-in-cxa-guard_21.1.8.patch | 12 - libs/libxx/libcxxabi/CMakeLists.txt | 67 +- libs/libxx/libcxxabi/Make.defs | 35 +- libs/libxx/libcxxabi/__config_site | 14 + .../src/cxa_exception_storage_stub.cpp | 102 -- .../libcxxabi/src/fallback_malloc_stub.cpp | 155 --- net/devif/ipv4_input.c | 61 +- net/icmpv6/icmpv6_autoconfig.c | 7 + net/inet/ipv4_setsockopt.c | 4 +- net/ipfrag/ipv4_frag.c | 2 +- net/ipfrag/ipv6_frag.c | 2 +- net/neighbor/neighbor_ethernet_out.c | 4 +- net/netdev/netdev.h | 35 - net/netdev/netdev_ioctl.c | 27 +- net/route/net_add_ramroute.c | 10 +- net/route/net_alloc_ramroute.c | 149 +-- net/route/net_foreach_ramroute.c | 12 +- net/route/net_initroute.c | 4 - net/route/ramroute.h | 45 +- net/tcp/tcp_input.c | 28 +- net/tcp/tcp_timer.c | 10 +- sched/Kconfig | 10 +- sched/hrtimer/hrtimer.h | 7 +- sched/hrtimer/hrtimer_process.c | 1 + sched/hrtimer/hrtimer_start.c | 5 +- sched/misc/assert.c | 6 +- sched/sched/sched_get_tls.c | 3 +- sched/sched/sched_processtimer.c | 16 +- sched/sched/sched_timerexpiration.c | 6 +- sched/signal/sig_default.c | 3 + sched/task/task_argvstr.c | 9 +- sched/task/task_setup.c | 3 + sched/tls/tls_dupinfo.c | 7 + sched/tls/tls_initinfo.c | 6 + tools/checkkconfig.py | 307 ++++++ tools/nxstyle.c | 4 + tools/process_config.py | 470 ++++++++- 325 files changed, 5827 insertions(+), 3285 deletions(-) create mode 100644 arch/arm/src/am335x/CMakeLists.txt create mode 100644 arch/sim/src/sim/posix/sim_errno.c rename arch/sim/src/sim/{sim_wifidriver.c => sim_wifihost.c} (91%) create mode 100644 arch/sim/src/sim/sim_wifihost.h create mode 100644 arch/sim/src/sim/win/sim_errno.c create mode 100644 boards/arm/am335x/beaglebone-black/CMakeLists.txt create mode 100644 boards/arm/am335x/beaglebone-black/src/CMakeLists.txt create mode 100644 include/ulimit.h create mode 100644 libs/libc/misc/lib_creat.c create mode 100644 libs/libc/pthread/pthread_equal.c create mode 100644 libs/libc/unistd/lib_ulimit.c create mode 100644 libs/libxx/__assertion_handler delete mode 100644 libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch delete mode 100644 libs/libxx/libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch delete mode 100644 libs/libxx/libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch delete mode 100644 libs/libxx/libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch delete mode 100644 libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch create mode 100644 libs/libxx/libcxx/0002-libcxx-decay-and-tzdb-fixes.patch delete mode 100644 libs/libxx/libcxx/0007-libcxx-fix-locale-instantiations_21.1.8.patch delete mode 100644 libs/libxx/libcxx/0008-libcxx-remove-invalid-locale-instantiations_21.1.8.patch delete mode 100644 libs/libxx/libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch delete mode 100644 libs/libxx/libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch delete mode 100644 libs/libxx/libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch delete mode 100644 libs/libxx/libcxx/__assertion_handler delete mode 100644 libs/libxx/libcxx/mbstate_t_21.1.8.patch create mode 100644 libs/libxx/libcxx/nuttx_string_instantiations.cpp delete mode 100644 libs/libxx/libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch delete mode 100644 libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch create mode 100644 libs/libxx/libcxxabi/__config_site delete mode 100644 libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp delete mode 100644 libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp create mode 100755 tools/checkkconfig.py mode change 100644 => 100755 tools/process_config.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 292ba4cb05e7b..6398869b34fee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -192,10 +192,9 @@ jobs: BLOBDIR: /tools/blobs with: run: | - # install venv + # install python venv apt-get update - apt install -y python3-dev - apt install -y python3-venv + apt-get install -y python3 python3-dev python3-venv # get NTFC sources git clone -b release-0.0.1 https://github.com/szafonimateusz-mi/nuttx-ntfc diff --git a/CMakeLists.txt b/CMakeLists.txt index 82ff10e2cd9a2..4761cb6560eca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,20 +166,9 @@ if(NOT EXISTS "${NUTTX_DEFCONFIG}") endif() # Process initial defconfig ################################################### -# Process initial defconfig to recursively expand #include in it +# Process initial defconfig to recursively expand #include in it include(nuttx_process_config) -get_filename_component(NUTTX_DEFCONFIG_DIR "${NUTTX_DEFCONFIG}" DIRECTORY) -process_config( - ${CMAKE_BINARY_DIR}/.defconfig.processed - ${NUTTX_DEFCONFIG} - INCLUDE_PATHS - ${NUTTX_DEFCONFIG_DIR}/../../common/configs - ${NUTTX_DEFCONFIG_DIR}/../common - ${NUTTX_DEFCONFIG_DIR} - ${NUTTX_DIR}/../apps - ${NUTTX_DIR}/../nuttx-apps) -set(NUTTX_DEFCONFIG ${CMAKE_BINARY_DIR}/.defconfig.processed) # Generate initial .config ################################################### # This is needed right before any other configure step so that we can source @@ -502,22 +491,6 @@ if(CONFIG_NDEBUG) add_compile_options(-DNDEBUG) endif() -# Cmake build provide absolute paths to compile files. If __FILE__ macros are -# used in the source code(ASSERT), the binary will contain many invalid paths. -# This saves some memory, stops exposing build systems locations in binaries, -# make failure logs more deterministic and most importantly makes builds more -# failure logs more deterministic and most importantly makes builds more -# deterministic. Debuggers usually have a path mapping feature to ensure the -# files are still found. -if(NOT MSVC) - if(CONFIG_OUTPUT_STRIP_PATHS) - add_compile_options(-fmacro-prefix-map=${NUTTX_DIR}=) - add_compile_options(-fmacro-prefix-map=${NUTTX_APPS_DIR}=) - add_compile_options(-fmacro-prefix-map=${NUTTX_BOARD_ABS_DIR}=) - add_compile_options(-fmacro-prefix-map=${NUTTX_CHIP_ABS_DIR}=) - endif() -endif() - add_definitions(-D__NuttX__) add_compile_options($<$:-D__ASSEMBLY__>) diff --git a/Documentation/ReleaseNotes/NuttX-7.29 b/Documentation/ReleaseNotes/NuttX-7.29 index e51c46dfdd6fe..5b6c01baf049c 100644 --- a/Documentation/ReleaseNotes/NuttX-7.29 +++ b/Documentation/ReleaseNotes/NuttX-7.29 @@ -25,7 +25,7 @@ still needed). From Gregory Nutt. - Rename all internal OS functions from task_* to nxtask_* to indicate that they are NuttX internal functions. From Gregory Nutt. - Rename sched_process_timer to nxsched_process_timer. Rename -sched_timer_expiration to nxsched_timer_expiration. Rename +sched_timer_expiration to nxsched_tick_expiration. Rename sched_alarm_expiration to nxsched_alarm_expiration. Those are the appropriate names for an internal sched/ function (still many named incorrectly). From Gregory Nutt. diff --git a/Documentation/components/crypto.rst b/Documentation/components/crypto.rst index 1a94ae0b05767..8d6862752d883 100644 --- a/Documentation/components/crypto.rst +++ b/Documentation/components/crypto.rst @@ -2,4 +2,136 @@ Crypto API Subsystem ==================== -In the future this page will contain details about the Crypto API in NuttX. +Overview +======== + +The NuttX Crypto API subsystem provides a unified interface for cryptographic operations, supporting various encryption, decryption, hashing, and authentication algorithms. The subsystem abstracts hardware and software crypto implementations through a common interface. + +Supported Algorithms +==================== + +Symmetric Encryption Algorithms +-------------------------------- + +**AES (Advanced Encryption Standard)** + +- AES-CBC Mode: + - CRYPTO_AES_CBC (128-bit key size) + - CRYPTO_AES_192_CBC (192-bit key size) + - CRYPTO_AES_256_CBC (256-bit key size) + +- AES-CTR Mode (Counter mode): + - CRYPTO_AES_CTR + +- AES-XTS Mode (XEX-based Tweaked CodeBook): + - CRYPTO_AES_XTS + +- AES-GCM Mode (Galois/Counter Mode): + - CRYPTO_AES_GCM_16 + +- AES-OFB Mode (Output Feedback): + - CRYPTO_AES_OFB + +- AES-CFB Mode (Cipher Feedback): + - CRYPTO_AES_CFB_8 (8-bit) + - CRYPTO_AES_CFB_128 (128-bit) + +**Other Block Cipher Modes** + +- Blowfish (BLF): + - CRYPTO_BLF_CBC + +- CAST (CAST-128): + - CRYPTO_CAST_CBC + +- Rijndael (128-bit): + - CRYPTO_RIJNDAEL128_CBC + +- Null (No encryption): + - CRYPTO_NULL + +Authentication and Hashing Algorithms +-------------------------------------- + +**HMAC (Hash-based Message Authentication Code)** + +- MD5-HMAC: + - CRYPTO_MD5_HMAC + +- SHA-1 HMAC: + - CRYPTO_SHA1_HMAC + +- SHA-2 HMAC: + - CRYPTO_SHA2_256_HMAC (256-bit) + - CRYPTO_SHA2_384_HMAC (384-bit) + - CRYPTO_SHA2_512_HMAC (512-bit) + +**Hash Functions** + +- MD5: + - CRYPTO_MD5 + +- SHA-1: + - CRYPTO_SHA1 + +- SHA-2: + - CRYPTO_SHA2_224 (224-bit) + - CRYPTO_SHA2_256 (256-bit) + - CRYPTO_SHA2_384 (384-bit) + - CRYPTO_SHA2_512 (512-bit) + +- RIPEMD-160: + - CRYPTO_RIPEMD160 (as hash function) + - CRYPTO_RIPEMD160_HMAC + +**Message Authentication Codes** + +- AES-GMAC (Galois Message Authentication Code): + - CRYPTO_AES_128_GMAC (128-bit key) + - CRYPTO_AES_192_GMAC (192-bit key) + - CRYPTO_AES_256_GMAC (256-bit key) + - CRYPTO_AES_GMAC (generic) + +- AES-CMAC (Cipher-based Message Authentication Code): + - CRYPTO_AES_CMAC + - CRYPTO_AES_128_CMAC (128-bit) + +- Poly1305: + - CRYPTO_POLY1305 + - CRYPTO_CHACHA20_POLY1305 + - CRYPTO_CHACHA20_POLY1305_MAC + +**Stream Ciphers** + +- ChaCha20: + - CRYPTO_CHACHA20_POLY1305 (with Poly1305 MAC) + +Integrity and Checksums +------------------------ + +- CRC-32: + - CRYPTO_CRC32 + +- Extended Sequence Numbers (ESN): + - CRYPTO_ESN + +Compression +----------- + +- Deflate Compression: + - CRYPTO_DEFLATE_COMP + +Usage +===== + +The Crypto API is accessed through the cryptodev interface, which provides ioctl commands for initializing cryptographic sessions and performing operations. + +Basic Usage Pattern +------------------- + +1. Open the cryptodev device (/dev/crypto) +2. Initialize a cryptographic session with desired algorithm +3. Submit crypto operations (encrypt/decrypt/hash) +4. Close the session when done + +For more details, refer to the cryptodev.h header file and specific driver documentation. diff --git a/Documentation/components/drivers/special/ioexpander.rst b/Documentation/components/drivers/special/ioexpander.rst index 5a2f5134dd998..f52f019df434b 100644 --- a/Documentation/components/drivers/special/ioexpander.rst +++ b/Documentation/components/drivers/special/ioexpander.rst @@ -2,29 +2,37 @@ IO Expander Device Drivers ========================== -- ``include/nuttx/ioexpander/ioexpander.h`` and ``include/nuttx/ioexpander/gpio.h``. - All structures and APIs needed to work with ioexpander drivers are provided in - this header file. +The IO Expander subsystem is defined in the following headers: -- ``struct ioexpander_ops_s``. Each ioexpand device driver must implement - an instance of ``struct ioexpander_ops_s``. That structure defines a - call table with the methods, and we also provide macros to help access methods. +- ``include/nuttx/ioexpander/ioexpander.h`` — defines the public IO expander + interface: macros, types, and helper access macros used by drivers and + consumers. +- ``include/nuttx/ioexpander/gpio.h`` — provides the "gpio lower half" + helper that allows registering an IO expander pin as a standard GPIO + character device (see ``gpio_lower_half`` and ``gpio_lower_half_byname``). -- we also provide method ``gpio_lower_half`` to make ioexpander compatible with normal gpio. +Each IO expander driver must implement an instance of ``struct +ioexpander_ops_s``. That structure defines the lower-half call table and +the operations a driver must provide; the public header also includes +helper macros that dispatch to the lower-half operations table. -- **Binding ioexpander Drivers**. ioexpander drivers are not normally directly - accessed by user code, we should always get lower level drivers, for example I2C, - and map extended gpio feature same asa normal gpio. See for example, - ``int nrf52_sx1509_initialize(void)`` - in ``boards/arm/nrf52/thingy52/src/nrf52_sx1509.c``. In general, the binding - sequence is: +The helper ``gpio_lower_half`` can be used to register individual expander +pins as standard GPIO devices so that upper-half GPIO consumers can access +expander pins through the common GPIO character driver. - #. Get an instance of ``struct i2c_master_s`` from the - hardware-specific I2C device driver, and - #. Provide that instance and configurations to the ioexpander initialization method - to get the ``struct ioexpander_dev_s`` ioe device instance. - #. Then use ioe device instance to do ioexpander operations, or use ``gpio_lower_half`` - to make ioexpand compatible with normal gpio. +**Binding IO expander drivers** + +IO expander drivers are usually bound by board-specific code rather than +accessed directly from application code. For I2C- or SPI-connected +expanders the typical sequence is: + +#. Obtain the bus instance (for example, a ``struct i2c_master_s *``) from + the hardware-specific bus driver. +#. Call the expander driver's initialization routine with the bus instance + and device-specific configuration; the init routine returns a + ``struct ioexpander_dev_s *`` instance. +#. Use the returned ``ioe`` instance directly, or register individual + expander pins with the upper-half GPIO driver via ``gpio_lower_half``. - **Examples**: ``drivers/ioexpander/pca9555.c``, @@ -33,3 +41,213 @@ IO Expander Device Drivers ``drivers/ioexpander/ioe_rpmsg.c``, ``boards/sim/sim/sim/src/sim_ioexpander.c``, ``boards/arm/nrf52/thingy52/src/nrf52_sx1509.c`` etc. + +Further details +=============== + +Header files +------------ + +The relevant header files are: + +- ``include/nuttx/ioexpander/ioexpander.h`` — defines macros, types and access + macros used to interact with IO expanders. +- ``include/nuttx/ioexpander/gpio.h`` — provides the "gpio lower half" helper + that allows registering an IO expander pin as a standard GPIO device. + +Overview of key macros and options +---------------------------------- + +The following is a concise reference of the important macros defined in the +header. These are the options you will typically use through ``IOEXP_SETOPTION`` +and the various access macros. The primary preprocessor definitions are +listed below (C syntax): + +.. code-block:: c + + /* Direction definitions */ + #define IOEXPANDER_DIRECTION_IN 0 /* float */ + #define IOEXPANDER_DIRECTION_IN_PULLUP 1 + #define IOEXPANDER_DIRECTION_IN_PULLDOWN 2 + #define IOEXPANDER_DIRECTION_OUT 3 /* push-pull */ + #define IOEXPANDER_DIRECTION_OUT_OPENDRAIN 4 + #define IOEXPANDER_DIRECTION_OUT_LED 5 /* LED output */ + + /* Pinset mask helpers */ + #define IOEXPANDER_PINMASK (((ioe_pinset_t)1 << CONFIG_IOEXPANDER_NPINS) - 1) + #define PINSET_ALL (~((ioe_pinset_t)0)) + + /* Common option values (used with IOEXP_SETOPTION) */ + /* Invert (active level) */ + #define IOEXPANDER_OPTION_INVERT 1 + #define IOEXPANDER_VAL_NORMAL 0 /* normal polarity */ + #define IOEXPANDER_VAL_INVERT 1 /* inverted polarity */ + + /* Interrupt configuration (level/edge and high/low/rising/falling/both) */ + #define IOEXPANDER_OPTION_INTCFG 2 + #define IOEXPANDER_VAL_DISABLE 0 /* 0000 disable interrupts */ + #define IOEXPANDER_VAL_LEVEL 1 /* xx01: level triggered */ + #define IOEXPANDER_VAL_EDGE 2 /* xx10: edge triggered */ + #define IOEXPANDER_VAL_HIGH 5 /* 0101: high level */ + #define IOEXPANDER_VAL_LOW 9 /* 1001: low level */ + #define IOEXPANDER_VAL_RISING 6 /* 0110: rising edge */ + #define IOEXPANDER_VAL_FALLING 10 /* 1010: falling edge */ + #define IOEXPANDER_VAL_BOTH 14 /* 1110: both edges */ + + /* LED configuration */ + #define IOEXPANDER_OPTION_LEDCFG 3 /* assign an LED number to a pin */ + + /* Non-generic (driver-specific) option */ + #define IOEXPANDER_OPTION_NONGENERIC 4 /* pass driver-specific struct */ + + /* Wakeup configuration (configure pin as SoC wake-up source) */ + #define IOEXPANDER_OPTION_WAKEUPCFG 5 + #define IOEXPANDER_WAKEUP_DISABLE 0 + #define IOEXPANDER_WAKEUP_ENABLE 1 + + /* Debounce and interrupt mask (recent additions) */ + #define IOEXPANDER_OPTION_SETDEBOUNCE 6 /* configure debounce */ + #define IOEXPANDER_DEBOUNCE_DISABLE 0 + #define IOEXPANDER_DEBOUNCE_ENABLE 1 + + #define IOEXPANDER_OPTION_SETMASK 7 /* control interrupt masking */ + #define IOEXPANDER_MASK_DISABLE 0 /* unmask (enable) interrupts */ + #define IOEXPANDER_MASK_ENABLE 1 /* mask (suppress) interrupts */ + +Access macros (API) +------------------- + +The header exposes a set of helper macros that dispatch to the underlying +driver operations table (``struct ioexpander_ops_s``): + +.. c:macro:: IOEXP_SETDIRECTION(dev, pin, dir) + + Set a pin direction (input, output, open-drain, LED, pull-up/down). + Returns 0 on success or a negative errno on failure. + +.. c:macro:: IOEXP_SETOPTION(dev, pin, opt, val) + + Generic option setting interface used to configure the options listed + above. Note that ``val`` is a ``void *``; drivers may accept an integer + casted to a pointer or a pointer to a driver-specific structure. + + Examples:: + + /* Invert pin polarity */ + IOEXP_SETOPTION(dev, 3, IOEXPANDER_OPTION_INVERT, + (FAR void *)IOEXPANDER_VAL_INVERT); + + /* Enable debounce on pin 2 */ + IOEXP_SETOPTION(dev, 2, IOEXPANDER_OPTION_SETDEBOUNCE, + (FAR void *)IOEXPANDER_DEBOUNCE_ENABLE); + + /* Mask interrupts for pin 5 */ + IOEXP_SETOPTION(dev, 5, IOEXPANDER_OPTION_SETMASK, + (FAR void *)IOEXPANDER_MASK_ENABLE); + +.. c:macro:: IOEXP_WRITEPIN(dev, pin, val) + + Set the pin level. Returns 0 on success or a negative errno on error. + +.. c:macro:: IOEXP_READPIN(dev, pin, valptr) + + Read the actual physical pin level. The value is returned via ``valptr``. + +.. c:macro:: IOEXP_READBUF(dev, pin, valptr) + + Read the buffered/register value cached by the expander. + + - ``IOEXP_WRITEPIN`` sets the pin level (TRUE typically means high). + Drivers handle polarity inversion if configured. + - ``IOEXP_READPIN`` reads the actual physical pin level. + - ``IOEXP_READBUF`` reads the buffered/register value cached by the + expander. + +Multi-pin operations +-------------------- + +When ``CONFIG_IOEXPANDER_MULTIPIN`` is enabled, batch operations are +available that may be more efficient than repeated single-pin calls: + +- ``IOEXP_MULTIWRITEPIN(dev, pins, vals, count)`` +- ``IOEXP_MULTIREADPIN(dev, pins, vals, count)`` +- ``IOEXP_MULTIREADBUF(dev, pins, vals, count)`` + +Interrupts and callbacks +------------------------ + +If ``CONFIG_IOEXPANDER_INT_ENABLE`` is enabled the header defines the +callback type and attach/detach helper macros. The callback signature +is:: + + typedef CODE int (*ioe_callback_t)(FAR struct ioexpander_dev_s *dev, + ioe_pinset_t pinset, FAR void *arg); + +The callback is invoked when events occur for the monitored pinset. The +attach/detach helpers are provided as macros that dispatch to the lower-half +driver when ``CONFIG_IOEXPANDER_INT_ENABLE`` is enabled: + +.. c:macro:: IOEP_ATTACH(dev, pinset, callback, arg) + + Attach and enable a pin interrupt callback. Returns a non-NULL opaque + handle on success. ``pinset`` selects which pin(s) will generate the + callback; ``callback`` is a function of type ``ioe_callback_t`` and + ``arg`` is passed through to the callback. + +.. c:macro:: IOEP_DETACH(dev, handle) + + Detach and disable a previously attached callback referenced by ``handle``. + +Note: when ``CONFIG_IOEXPANDER_NPINS`` > 64, ``ioe_pinset_t`` represents a +single interrupt pin number rather than a bitmask. + +Driver interface (lower-half) +----------------------------- + +Each IO expander driver must implement the operations table +``struct ioexpander_ops_s``. At minimum the driver should provide: + +- ``ioe_direction`` +- ``ioe_option`` +- ``ioe_writepin`` +- ``ioe_readpin`` +- ``ioe_readbuf`` + +Optional multi-pin and interrupt attach/detach methods should be provided +when the corresponding configuration options are enabled. + +Binding to the upper layer (gpio_lower_half) +-------------------------------------------- + +Applications normally do not access IO expander drivers directly. Typical +binding steps are: + +1. Obtain the bus instance (for example, ``struct i2c_master_s *``) from + the hardware-specific bus driver. +2. Call the expander driver's initialization routine with the bus instance + and device configuration to obtain a ``struct ioexpander_dev_s *``. +3. Use the returned ``ioe`` instance directly, or register individual + expander pins as standard GPIO devices via ``gpio_lower_half`` or + ``gpio_lower_half_byname``. + +Example (pseudocode):: + + /* Get the I2C bus */ + struct i2c_master_s *i2c = up_i2cinitialize(0); + + /* Initialize the expander (driver-specific init) */ + struct ioexpander_dev_s *ioe = pca9555_initialize(i2c, CONFIG_PCA9555_ADDR); + + /* Configure pin 0 as input with pull-up and enable debounce */ + IOEXP_SETDIRECTION(ioe, 0, IOEXPANDER_DIRECTION_IN_PULLUP); + IOEXP_SETOPTION(ioe, 0, IOEXPANDER_OPTION_SETDEBOUNCE, + (FAR void *)IOEXPANDER_DEBOUNCE_ENABLE); + +Examples and references +----------------------- + +See the following drivers and board examples for concrete usage: + +- ``drivers/ioexpander/pca9555.c`` — I2C IO expander implementation. +- ``drivers/ioexpander/ioe_rpmsg.c`` — RPMSG-based IO expander. +- ``boards/arm/nrf52/thingy52/src/nrf52_sx1509.c`` — binding example. diff --git a/Documentation/components/tools/index.rst b/Documentation/components/tools/index.rst index f380acfbe20ea..65ccb8e054574 100644 --- a/Documentation/components/tools/index.rst +++ b/Documentation/components/tools/index.rst @@ -13,6 +13,48 @@ cmpconfig.c This C file can be used to build a utility for comparing two NuttX configuration files. +checkkconfig.py +--------------- + +``checkkconfig.py`` is a Python script that simulates the effects of modifying a CONFIG item. +It can be used to check whether my config changes are what I expected. + +Help message:: + + $ tools/checkkconfig.py -h + usage: checkkconfig.py [-h] -f FILE (-s CONFIG VALUE | -d DIFF) + + optional arguments: + -h, --help show this help message and exit + -f FILE, --file FILE Path to the input defconfig file + -s CONFIG_XXX VALUE, --single CONFIG VALUE + Analyze single change: CONFIG_NAME y/m/n + -d DIFF, --diff DIFF Analyze changes from diff file + + example: ./tools/checkkconfig.py -f defconfig -s ELF n + + outputs: + Change report for ELF=n + Config Option Old New + ---------------------------------------------------------------------- + BINFMT_LOADABLE y n + ELF y n + ELF_STACKSIZE 8192 + LIBC_ARCH_ELF y n + LIBC_MODLIB y n + MODLIB_ALIGN_LOG2 2 + MODLIB_BUFFERINCR 32 + MODLIB_BUFFERSIZE 32 + MODLIB_MAXDEPEND 2 + MODLIB_RELOCATION_BUFFERCOUNT 256 + MODLIB_SYMBOL_CACHECOUNT 256 + +As we can see, we can clearly know that +if I turn off ELF in defconfig at this time, +it will bring about the following configuration linkage changes + +It can also parse diff files, which can be used to check the changes of multiple configs. + checkpatch.sh ------------- diff --git a/Documentation/reference/os/nuttx.rst b/Documentation/reference/os/nuttx.rst index 5678d2d9bac11..04c8b606435c9 100644 --- a/Documentation/reference/os/nuttx.rst +++ b/Documentation/reference/os/nuttx.rst @@ -22,16 +22,6 @@ OS List Management APIs periodically -- the calling interval must be ``CONFIG_USEC_PER_TICK``. -.. c:function:: void nxsched_timer_expiration(void) - - Description: if ``CONFIG_SCHED_TICKLESS`` is defined, then this - function is provided by the RTOS base code and called from - platform-specific code when the interval timer used to implemented - the tick-less OS expires. - - **Assumptions**: Base code implementation assumes that this - function is called from interrupt handling logic with interrupts disabled. - .. c:function:: void irq_dispatch(int irq, FAR void *context) This function must be called from the diff --git a/Documentation/reference/os/time_clock.rst b/Documentation/reference/os/time_clock.rst index 86d35955827c7..f178f9807513c 100644 --- a/Documentation/reference/os/time_clock.rst +++ b/Documentation/reference/os/time_clock.rst @@ -372,7 +372,7 @@ In addition to these imported interfaces, the RTOS will export the following interfaces for use by the platform-specific interval timer implementation: -- ``nxsched_timer_expiration()``: called by the platform-specific logic when the interval time expires. +- ``nxsched_process_timer()``: called by the platform-specific logic when the interval time expires. .. c:function:: void archname_timer_initialize(void) @@ -410,7 +410,7 @@ timer implementation: Cancel the alarm and return the time of cancellation of the alarm. These two steps need to be as nearly atomic as possible. - ``nxsched_timer_expiration()`` will not be called unless the alarm + ``nxsched_process_timer()`` will not be called unless the alarm is restarted with ``up_alarm_start()``. If, as a race condition, the alarm has already expired when this function is called, then time returned is the current time. @@ -427,13 +427,13 @@ timer implementation: .. c:function:: int up_alarm_start(FAR const struct timespec *ts) - Start the alarm. ``nxsched_timer_expiration()`` will be called + Start the alarm. ``nxsched_process_timer()`` will be called when the alarm occurs (unless ``up_alarm_cancel`` is called to stop it). :param ts: The time in the future at the alarm is expected to occur. When the alarm occurs the timer logic will call - ``nxsched_timer_expiration()``. + ``nxsched_process_timer()``. :return: Zero (OK) on success; a negated errno value on failure. @@ -445,11 +445,11 @@ timer implementation: Cancel the interval timer and return the time remaining on the timer. These two steps need to be as nearly atomic as possible. -``nxsched_timer_expiration()`` will not be called unless the timer +``nxsched_process_timer()`` will not be called unless the timer is restarted with ``up_timer_start()``. If, as a race condition, the timer has already expired when this function is called, then that pending interrupt must be cleared so that -``nxsched_timer_expiration()`` is not called spuriously and the +``nxsched_process_timer()`` is not called spuriously and the remaining time of zero should be returned. :param ts: Location to return the remaining time. Zero should be @@ -463,12 +463,12 @@ disabled internally to assure non-reentrancy. .. c:function:: int up_timer_start(FAR const struct timespec *ts) -Start the interval timer. ``nxsched_timer_expiration()`` will be +Start the interval timer. ``nxsched_process_timer()`` will be called at the completion of the timeout (unless ``up_timer_cancel()`` is called to stop the timing). :param ts: Provides the time interval until - ``nxsched_timer_expiration()`` is called. + ``nxsched_process_timer()`` is called. :return: Zero (OK) on success; a negated errno value on failure. @@ -564,41 +564,6 @@ or ``kill()`` to communicate with NuttX tasks. context of the timer interrupt handler and is subject to all ISR restrictions. -.. c:function:: int wd_restart(FAR struct wdog_s *wdog, clock_t delay) - - This function restarts the specified watchdog timer using the same - function and argument that were specified in the previous wd_start() - call, but with a new delay value. It can be used when the user wants - to restart the same watchdog with a different timeout value, or to - refresh (feed) an existing watchdog before it expires. - - :param wdog: Pointer to the watchdog timer to restart - :param delay: Delay count in clock ticks - - **NOTE**: The parameter must be of type ``wdparm_t``. - - :return: Zero (``OK``) is returned on success; a negated ``errno`` value - is return to indicate the nature of any failure. - -.. c:function:: int wd_restart_next(FAR struct wdog_s *wdog, clock_t delay) - - This function restarts the specified watchdog timer using a new delay - value, but schedules the next expiration based on the previous - expiration time (wdog->expired + delay). This allows the watchdog to - maintain a consistent periodic interval even if there is some delay in - handling the expiration callback. - - It can be used when the user wants to restart a watchdog for a different - purpose or continue periodic timing based on the previous timeout point. - - :param wdog: Pointer to the watchdog timer to restart - :param delay: Delay count in clock ticks - - **NOTE**: The parameter must be of type ``wdparm_t``. - - :return: Zero (``OK``) is returned on success; a negated ``errno`` value - is return to indicate the nature of any failure. - .. c:function:: int wd_cancel(FAR struct wdog_s *wdog) This function cancels a currently running @@ -745,12 +710,15 @@ that returns immediately without waiting for the timer to stop executing. **POSIX Compatibility:** This is a NON-POSIX interface. -.. c:function:: int hrtimer_start(FAR hrtimer_t *hrtimer, uint64_t ns, \ +.. c:function:: int hrtimer_start(FAR hrtimer_t *hrtimer, \ + hrtimer_entry_t func, \ + uint64_t expired, \ enum hrtimer_mode_e mode) This function starts a high-resolution timer in absolute or relative mode. :param hrtimer: Timer instance to cancel + :param func: Expiration callback function :param ns: Timer expiration in nanoseconds (absolute or relative) :param mode: HRTIMER_MODE_ABS or HRTIMER_MODE_REL @@ -758,7 +726,8 @@ that returns immediately without waiting for the timer to stop executing. **POSIX Compatibility:** This is a NON-POSIX interface. -.. c:type:: uint64_t (*hrtimer_cb)(FAR hrtimer_t *hrtimer, uint64_t expired) +.. c:type:: uint64_t (*hrtimer_entry_t)(FAR hrtimer_t *hrtimer, \ + uint64_t expired) **High-resolution Timer Callback**: when a hrtimer expires, the callback function with this type is called. diff --git a/arch/Kconfig b/arch/Kconfig index ea801c57f5cc3..597a0490de802 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -200,6 +200,7 @@ config ARCH_TRICORE select ARCH_HAVE_STACKCHECK select ARCH_HAVE_CUSTOMOPT select ARCH_HAVE_TCBINFO + select ARCH_HAVE_REGCPY ---help--- Infineon 32-bit AURIX TriCore architectures @@ -1134,6 +1135,12 @@ config ARCH_STACKDUMP ---help--- Enable to do stack dumps after assertions +config ARCH_HAVE_REGCPY + bool "common copy of cpu regs" + default n + ---help--- + Supports context data copying with different architectures + config ARCH_STACKDUMP_MAX_LENGTH int "The maximum length for dump stack on assertions" depends on ARCH_STACKDUMP diff --git a/arch/arm/src/am335x/CMakeLists.txt b/arch/arm/src/am335x/CMakeLists.txt new file mode 100644 index 0000000000000..45e786b93c4bd --- /dev/null +++ b/arch/arm/src/am335x/CMakeLists.txt @@ -0,0 +1,50 @@ +# ############################################################################## +# arch/arm/src/am335x/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +# AM335x-specific C source files + +set(SRCS + am335x_boot.c + am335x_clockconfig.c + am335x_pinmux.c + am335x_irq.c + am335x_gpio.c + am335x_lowputc.c + am335x_serial.c + am335x_wdog.c + am335x_sysclk.c + am335x_i2c.c + am335x_can.c) + +if(NOT CONFIG_SCHED_TICKLESS) + list(APPEND SRCS am335x_timerisr.c) +endif() + +if(CONFIG_AM335X_GPIO_IRQ) + list(APPEND SRCS am335x_gpioirq.c) +endif() + +if(CONFIG_AM335X_LCDC) + list(APPEND SRCS am335x_lcdc.c am335x_edid.c) +endif() + +target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/arm/src/armv7-a/arm_gicv2.c b/arch/arm/src/armv7-a/arm_gicv2.c index 1020c01e776d4..03ad226ba94ac 100644 --- a/arch/arm/src/armv7-a/arm_gicv2.c +++ b/arch/arm/src/armv7-a/arm_gicv2.c @@ -668,7 +668,7 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) } /**************************************************************************** - * Name: arm_gic_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -677,32 +677,37 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ****************************************************************************/ -int arm_gic_irq_trigger(int irq, bool edge) +int up_set_irq_type(int irq, int mode) { uintptr_t regaddr; uint32_t regval; uint32_t intcfg; - if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS) + if (!GIC_IS_SGI(irq)) { + if (mode == IRQ_HIGH_LEVEL || mode == IRQ_LOW_LEVEL) + { + intcfg = INT_ICDICFR_1N; + } + else + { + intcfg = INT_ICDICFR_EDGE | INT_ICDICFR_1N; + } + /* Get the address of the Interrupt Configuration Register for this * irq. */ regaddr = GIC_ICDICFR(irq); - /* Get the new Interrupt configuration bit setting */ - - intcfg = (edge ? (INT_ICDICFR_EDGE | INT_ICDICFR_1N) : INT_ICDICFR_1N); - /* Write the correct interrupt trigger to the Interrupt Configuration * Register. */ diff --git a/arch/arm/src/armv7-a/arm_gicv2m.c b/arch/arm/src/armv7-a/arm_gicv2m.c index d00b7abc658b9..ecdad35d91b0c 100644 --- a/arch/arm/src/armv7-a/arm_gicv2m.c +++ b/arch/arm/src/armv7-a/arm_gicv2m.c @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -117,7 +118,7 @@ int up_alloc_irq_msi(uint8_t busno, uint32_t devfn, int *pirq, int num) irq = g_v2m.spi_start + offset; for (i = 0; i < num; i++) { - arm_gic_irq_trigger(i + irq, true); + up_set_irq_type(i + irq, IRQ_RISING_EDGE); pirq[i] = i + irq; } diff --git a/arch/arm/src/armv7-a/gic.h b/arch/arm/src/armv7-a/gic.h index e23193d6bc3cc..879ac3b483325 100644 --- a/arch/arm/src/armv7-a/gic.h +++ b/arch/arm/src/armv7-a/gic.h @@ -623,6 +623,8 @@ #define GIC_IRQ_SGI14 14 /* Software Generated Interrupt (SGI) 14 */ #define GIC_IRQ_SGI15 15 /* Software Generated Interrupt (SGI) 15 */ +#define GIC_IRQ_PPI0 16 + #define GIC_IRQ_VM 25 /* Virtual Maintenance Interrupt (VM) PPI(6) */ #define GIC_IRQ_HTM 26 /* Hypervisor Timer (HTM) PPI(5) */ #define GIC_IRQ_VTM 27 /* Virtual Timer (VTM) PPI(4) */ @@ -631,6 +633,9 @@ #define GIC_IRQ_PTM 30 /* Non-secure Physical Timer (PTM) PPI(2) */ #define GIC_IRQ_IRQ 31 /* Interrupt Request (nIRQ) PPI(3) */ +#define GIC_IS_SGI(intid) ((intid) >= GIC_IRQ_SGI0 && \ + (intid) < GIC_IRQ_PPI0) + /* Shared Peripheral Interrupts (SPI) follow */ #define GIC_IRQ_SPI 32 /* First SPI interrupt ID */ @@ -746,26 +751,6 @@ void arm_gic0_initialize(void); void arm_gic_initialize(void); -/**************************************************************************** - * Name: arm_gic_irq_trigger - * - * Description: - * Set the trigger type for the specificd IRQ source and the current CPU. - * - * Since this API is not supported on all architectures, it should be - * avoided in common implementations where possible. - * - * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive - * - * Returned Value: - * Zero (OK) on success; a negated errno value is returned on any failure. - * - ****************************************************************************/ - -int arm_gic_irq_trigger(int irq, bool edge); - /**************************************************************************** * Name: arm_decodeirq * diff --git a/arch/arm/src/armv7-m/Toolchain.defs b/arch/arm/src/armv7-m/Toolchain.defs index 499be35aed135..180dd97ebaa68 100644 --- a/arch/arm/src/armv7-m/Toolchain.defs +++ b/arch/arm/src/armv7-m/Toolchain.defs @@ -28,9 +28,9 @@ ifeq ($(CONFIG_ARCH_CORTEXM4),y) TOOLCHAIN_MTUNE := -cpu=cortexm4 ifeq ($(CONFIG_ARCH_FPU),y) ifeq ($(CONFIG_ARCH_DPFPU),y) - TOOLCHAIN_MFLOAT := -fpu=vfpv3 + TOOLCHAIN_MFLOAT := -fpu=vfpv4 else - TOOLCHAIN_MFLOAT := -fpu=vfpv3_d16 + TOOLCHAIN_MFLOAT := -fpu=vfpv4_d16 endif endif else @@ -47,9 +47,9 @@ else ifeq ($(CONFIG_ARCH_CORTEXM7),y) TOOLCHAIN_MTUNE := -cpu=cortexm7 ifeq ($(CONFIG_ARCH_FPU),y) ifeq ($(CONFIG_ARCH_DPFPU),y) - TOOLCHAIN_MFLOAT := -fpu=vfpv3 + TOOLCHAIN_MFLOAT := -fpu=vfpv5 else - TOOLCHAIN_MFLOAT := -fpu=vfpv3_d16 + TOOLCHAIN_MFLOAT := -fpu=vfpv5_d16 endif endif else diff --git a/arch/arm/src/armv7-m/arm_exception.S b/arch/arm/src/armv7-m/arm_exception.S index d209e4cf853e4..c2053a59e1725 100644 --- a/arch/arm/src/armv7-m/arm_exception.S +++ b/arch/arm/src/armv7-m/arm_exception.S @@ -113,7 +113,7 @@ */ .text - .section .text.exception_common + .section .text.exception_common, "ax" #ifdef __ghs__ .type exception_common, $function #else diff --git a/arch/arm/src/armv7-r/arm_gicv2.c b/arch/arm/src/armv7-r/arm_gicv2.c index 6aecd09e29958..f8ea1ab3987a1 100644 --- a/arch/arm/src/armv7-r/arm_gicv2.c +++ b/arch/arm/src/armv7-r/arm_gicv2.c @@ -610,7 +610,7 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) } /**************************************************************************** - * Name: arm_gic_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -619,32 +619,37 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ****************************************************************************/ -int arm_gic_irq_trigger(int irq, bool edge) +int up_set_irq_type(int irq, int mode) { uintptr_t regaddr; uint32_t regval; uint32_t intcfg; - if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS) + if (!GIC_IS_SGI(irq)) { + if (mode == IRQ_HIGH_LEVEL || mode == IRQ_LOW_LEVEL) + { + intcfg = INT_ICDICFR_1N; + } + else + { + intcfg = INT_ICDICFR_EDGE | INT_ICDICFR_1N; + } + /* Get the address of the Interrupt Configuration Register for this * irq. */ regaddr = GIC_ICDICFR(irq); - /* Get the new Interrupt configuration bit setting */ - - intcfg = (edge ? (INT_ICDICFR_EDGE | INT_ICDICFR_1N) : INT_ICDICFR_1N); - /* Write the correct interrupt trigger to the Interrupt Configuration * Register. */ diff --git a/arch/arm/src/armv7-r/gic.h b/arch/arm/src/armv7-r/gic.h index ceb1b5594e73c..87fd4308c929e 100644 --- a/arch/arm/src/armv7-r/gic.h +++ b/arch/arm/src/armv7-r/gic.h @@ -596,6 +596,8 @@ #define GIC_IRQ_SGI14 14 /* Software Generated Interrupt (SGI) 14 */ #define GIC_IRQ_SGI15 15 /* Software Generated Interrupt (SGI) 15 */ +#define GIC_IRQ_PPI0 16 + #define GIC_IRQ_VM 25 /* Virtual Maintenance Interrupt (VM) PPI(6) */ #define GIC_IRQ_HTM 26 /* Hypervisor Timer (HTM) PPI(5) */ #define GIC_IRQ_VTM 27 /* Virtual Timer (VTM) PPI(4) */ @@ -604,6 +606,9 @@ #define GIC_IRQ_PTM 30 /* Non-secure Physical Timer (PTM) PPI(2) */ #define GIC_IRQ_IRQ 31 /* Interrupt Request (nIRQ) PPI(3) */ +#define GIC_IS_SGI(intid) ((intid) >= GIC_IRQ_SGI0 && \ + (intid) < GIC_IRQ_PPI0) + /* Shared Peripheral Interrupts (SPI) follow */ #define GIC_IRQ_SPI 32 /* First SPI interrupt ID */ @@ -748,26 +753,6 @@ void arm_gic0_initialize(void); void arm_gic_initialize(void); -/**************************************************************************** - * Name: arm_gic_irq_trigger - * - * Description: - * Set the trigger type for the specificd IRQ source and the current CPU. - * - * Since this API is not supported on all architectures, it should be - * avoided in common implementations where possible. - * - * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive - * - * Returned Value: - * Zero (OK) on success; a negated errno value is returned on any failure. - * - ****************************************************************************/ - -int arm_gic_irq_trigger(int irq, bool edge); - /**************************************************************************** * Name: arm_decodeirq * diff --git a/arch/arm/src/armv8-r/arm_gic.h b/arch/arm/src/armv8-r/arm_gic.h index 2a5c1a1941c29..eb03f48fd4a96 100644 --- a/arch/arm/src/armv8-r/arm_gic.h +++ b/arch/arm/src/armv8-r/arm_gic.h @@ -335,8 +335,6 @@ void arm_gic_irq_set_priority(unsigned int intid, unsigned int prio, void arm_gic_set_group(unsigned int intid, unsigned int group); #endif -int arm_gic_irq_trigger(unsigned int intid, uint32_t flags); - int arm_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list); #ifdef CONFIG_SMP diff --git a/arch/arm/src/armv8-r/arm_gicv3.c b/arch/arm/src/armv8-r/arm_gicv3.c index f0b723a9ce37d..cf69315b81e9f 100644 --- a/arch/arm/src/armv8-r/arm_gicv3.c +++ b/arch/arm/src/armv8-r/arm_gicv3.c @@ -207,7 +207,7 @@ void arm_gic_irq_set_priority(unsigned int intid, unsigned int prio, } /*************************************************************************** - * Name: arm_gic_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -216,27 +216,26 @@ void arm_gic_irq_set_priority(unsigned int intid, unsigned int prio, * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * flags - irq type, IRQ_TYPE_EDGE or IRQ_TYPE_LEVEL - * Default is IRQ_TYPE_LEVEL + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ***************************************************************************/ -int arm_gic_irq_trigger(unsigned int intid, uint32_t flags) +int up_set_irq_type(int irq, int mode) { - uint32_t idx = intid / GIC_NUM_INTR_PER_REG; + uint32_t idx = irq / GIC_NUM_INTR_PER_REG; uint32_t shift; uint32_t val; - unsigned long base = GET_DIST_BASE(intid); + unsigned long base = GET_DIST_BASE(irq); irqstate_t irq_flags; - if (!GIC_IS_SGI(intid)) + if (!GIC_IS_SGI(irq)) { - idx = intid / GIC_NUM_CFG_PER_REG; - shift = (intid & (GIC_NUM_CFG_PER_REG - 1)) * 2; + idx = irq / GIC_NUM_CFG_PER_REG; + shift = (irq & (GIC_NUM_CFG_PER_REG - 1)) * 2; /* GICD_ICFGR requires full 32-bit RMW operations. * Each interrupt uses 2 bits; thus updates must be synchronized @@ -246,7 +245,7 @@ int arm_gic_irq_trigger(unsigned int intid, uint32_t flags) irq_flags = spin_lock_irqsave(&g_gic_lock); val = getreg32(ICFGR(base, idx)); val &= ~(GICD_ICFGR_MASK << shift); - if (flags & IRQ_TYPE_EDGE) + if (mode != IRQ_HIGH_LEVEL && mode != IRQ_LOW_LEVEL) { val |= (GICD_ICFGR_TYPE << shift); } diff --git a/arch/arm/src/cmake/armv7-m_ghs.cmake b/arch/arm/src/cmake/armv7-m_ghs.cmake index c78665b97e8d4..ad1c4b5919e8e 100644 --- a/arch/arm/src/cmake/armv7-m_ghs.cmake +++ b/arch/arm/src/cmake/armv7-m_ghs.cmake @@ -26,18 +26,18 @@ if(CONFIG_ARCH_CORTEXM4) list(APPEND PLATFORM_FLAGS -cpu=cortexm4) if(CONFIG_ARCH_FPU) if(CONFIG_ARCH_DPFPU) - list(APPEND PLATFORM_FLAGS -fpu=vfpv3) + list(APPEND PLATFORM_FLAGS -fpu=vfpv4) else() - list(APPEND PLATFORM_FLAGS -fpu=vfpv3_d16) + list(APPEND PLATFORM_FLAGS -fpu=vfpv4_d16) endif() endif() elseif(CONFIG_ARCH_CORTEXM7) list(APPEND PLATFORM_FLAGS -cpu=cortexm7) if(CONFIG_ARCH_FPU) if(CONFIG_ARCH_DPFPU) - list(APPEND PLATFORM_FLAGS -fpu=vfpv3) + list(APPEND PLATFORM_FLAGS -fpu=vfpv5) else() - list(APPEND PLATFORM_FLAGS -fpu=vfpv3_d16) + list(APPEND PLATFORM_FLAGS -fpu=vfpv5_d16) endif() endif() else() diff --git a/arch/arm/src/cmake/ghs.cmake b/arch/arm/src/cmake/ghs.cmake index c7529eb9a96a4..8ad3015c5f5f4 100644 --- a/arch/arm/src/cmake/ghs.cmake +++ b/arch/arm/src/cmake/ghs.cmake @@ -60,7 +60,7 @@ endif() # Architecture flags add_link_options(-entry=__start) -add_compile_options(--no_commons -Wall -Wshadow -Wundef -nostdlib) +add_compile_options(--no_commons --ghstd=last -Wshadow -Wundef -nostdlib) add_compile_options(--option=305) if(CONFIG_DEBUG_CUSTOMOPT) @@ -147,6 +147,12 @@ if(CONFIG_ARM_THUMB) add_compile_options(-thumb) endif() +# Optimization of unused sections + +if(CONFIG_DEBUG_OPT_UNUSED_SECTIONS) + add_compile_options(-ffunction-sections -fdata-sections) +endif() + # Debug --whole-archive if(CONFIG_DEBUG_LINK_WHOLE_ARCHIVE) @@ -219,12 +225,34 @@ function(nuttx_generate_preprocess_target) ARGN ${ARGN}) + # in greenhills, for file to pre-process, if the file name is ends with + # "*.ld", will report error, and we need to change the target file name to + # "*.ld.i" or "*.ld.tmp", this is a special corner case, and the official + # greenhills reference manual do not have explanation about why the only + # "*.ld" should handle + set(EXPECT_TARGET_FILE_NAME ${TARGET_FILE}) + string(REGEX MATCH ".*\.ld$" ends_with_ld ${TARGET_FILE}) + + if(ends_with_ld STREQUAL ${TARGET_FILE}) + set(EXPECT_TARGET_FILE_NAME "${TARGET_FILE}.i") + endif() + add_custom_command( - OUTPUT ${TARGET_FILE} - COMMAND ${PREPROCESS} -I${CMAKE_BINARY_DIR}/include -filetype.cpp - ${SOURCE_FILE} -o ${TARGET_FILE} + OUTPUT ${EXPECT_TARGET_FILE_NAME} + COMMAND + ${PREPROCESS} + $> + -I${CMAKE_BINARY_DIR}/include -filetype.cpp ${SOURCE_FILE} -o + ${EXPECT_TARGET_FILE_NAME} DEPENDS ${SOURCE_FILE} ${DEPENDS}) + if(NOT ${EXPECT_TARGET_FILE_NAME} STREQUAL ${TARGET_FILE}) + add_custom_command( + OUTPUT ${TARGET_FILE} + COMMAND ${CMAKE_COMMAND} -E copy ${EXPECT_TARGET_FILE_NAME} ${TARGET_FILE} + DEPENDS ${EXPECT_TARGET_FILE_NAME}) + endif() + endfunction() # override nuttx_find_toolchain_lib diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index f38ab852f0928..5b683e26c9edf 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -410,7 +410,14 @@ ARCHOPTIMIZATION += --no_commons else ARCHOPTIMIZATION += -fno-common endif -ARCHOPTIMIZATION += -Wall -Wshadow -Wundef + +ifeq ($(CONFIG_ARM_TOOLCHAIN_GHS),y) + ARCHOPTIMIZATION += --ghstd=last +else + ARCHOPTIMIZATION += -Wall +endif + +ARCHOPTIMIZATION += -Wshadow -Wundef ifeq ($(CONFIG_ARM_TOOLCHAIN_ARMCLANG),y) ARCHOPTIMIZATION += -nostdlib @@ -438,8 +445,8 @@ ifeq ($(CONFIG_ARM_TOOLCHAIN_ARMCLANG),) ifeq ($(CONFIG_DEBUG_OPT_UNUSED_SECTIONS),y) ifeq ($(CONFIG_ARCH_TOOLCHAIN_GHS),) LDFLAGS += --gc-sections - ARCHOPTIMIZATION += -ffunction-sections -fdata-sections endif + ARCHOPTIMIZATION += -ffunction-sections -fdata-sections endif endif diff --git a/arch/arm/src/common/iar/fork.S b/arch/arm/src/common/iar/fork.S index 4177a1f8e8dec..3f16484a36530 100644 --- a/arch/arm/src/common/iar/fork.S +++ b/arch/arm/src/common/iar/fork.S @@ -29,7 +29,7 @@ #include "arm_fork.h" MODULE up_fork - SECTION .text:CODE:NOROOT(2) + SECTION .text:CODE:NOROOT(2), "ax" /**************************************************************************** * Pre-processor Definitions diff --git a/arch/arm/src/cxd56xx/cxd56_farapistub.S b/arch/arm/src/cxd56xx/cxd56_farapistub.S index 9982a02409087..7c72ab5dcf38e 100644 --- a/arch/arm/src/cxd56xx/cxd56_farapistub.S +++ b/arch/arm/src/cxd56xx/cxd56_farapistub.S @@ -21,7 +21,7 @@ ****************************************************************************/ .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -193,7 +193,7 @@ _modulelist_power_mgr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -319,7 +319,7 @@ _modulelist_flash_mgr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -389,7 +389,7 @@ _modulelist_rtc_mgr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -551,7 +551,7 @@ _modulelist_gnss_pwr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -591,7 +591,7 @@ _modulelist_aca: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -631,7 +631,7 @@ _modulelist_pinconfig: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -707,7 +707,7 @@ _modulelist_uart: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} @@ -783,7 +783,7 @@ _modulelist_update_mgr: .word 0 .syntax unified - .section .text.stub + .section .text.stub, "ax" .align 1 1: push {r0-r3} diff --git a/arch/arm/src/imx6/imx_enet.c b/arch/arm/src/imx6/imx_enet.c index dcf7ab0c75be2..655398d652c5a 100644 --- a/arch/arm/src/imx6/imx_enet.c +++ b/arch/arm/src/imx6/imx_enet.c @@ -39,6 +39,7 @@ #include +#include #include #include #include @@ -2581,7 +2582,7 @@ int imx_netinitialize(int intf) /* Configure as a (high) level interrupt */ - arm_gic_irq_trigger(IMX_IRQ_ENET0, false); + up_set_irq_type(IMX_IRQ_ENET0, IRQ_HIGH_LEVEL); #ifdef CONFIG_NET_ETHERNET /* Determine a semi-unique MAC address from MCU UID diff --git a/arch/arm/src/imx6/imx_serial.c b/arch/arm/src/imx6/imx_serial.c index c68f7c79b0da6..81070ba5c77ea 100644 --- a/arch/arm/src/imx6/imx_serial.c +++ b/arch/arm/src/imx6/imx_serial.c @@ -599,7 +599,7 @@ static int imx_attach(struct uart_dev_s *dev) { /* Configure as a (high) level interrupt */ - arm_gic_irq_trigger(priv->irq, false); + up_set_irq_type(priv->irq, IRQ_HIGH_LEVEL); /* Enable the interrupt (RX and TX interrupts are still disabled * in the UART diff --git a/arch/arm/src/imx6/imx_timerisr.c b/arch/arm/src/imx6/imx_timerisr.c index f6d4fe20c30b7..8937b04256ecc 100644 --- a/arch/arm/src/imx6/imx_timerisr.c +++ b/arch/arm/src/imx6/imx_timerisr.c @@ -246,7 +246,7 @@ void up_timer_initialize(void) /* Configure as a (rising) edge-triggered interrupt */ - arm_gic_irq_trigger(IMX_IRQ_GPT, true); + up_set_irq_type(IMX_IRQ_GPT, IRQ_RISING_EDGE); /* Attach the timer interrupt vector */ diff --git a/arch/arm/src/imxrt/imxrt_clockconfig_ver1.h b/arch/arm/src/imxrt/imxrt_clockconfig_ver1.h index 73433b1db92b7..e7b0f627e033f 100644 --- a/arch/arm/src/imxrt/imxrt_clockconfig_ver1.h +++ b/arch/arm/src/imxrt/imxrt_clockconfig_ver1.h @@ -21,7 +21,7 @@ ****************************************************************************/ #ifndef __ARCH_ARM_SRC_IMXRT_IMXRT_CLOCKCONFIG_VER1_H -#define __ARCH_ARM_SRC_IMXRT_IMXRT_CLOCKCONFIG_VER2_H +#define __ARCH_ARM_SRC_IMXRT_IMXRT_CLOCKCONFIG_VER1_H /**************************************************************************** * Included Files diff --git a/arch/arm/src/imxrt/imxrt_tickless.c b/arch/arm/src/imxrt/imxrt_tickless.c index 406bd23cb0866..bbcd10263d1d3 100644 --- a/arch/arm/src/imxrt/imxrt_tickless.c +++ b/arch/arm/src/imxrt/imxrt_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * * NOTE @@ -183,7 +183,7 @@ static void imxrt_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -477,7 +477,7 @@ int up_timer_gettime(struct timespec *ts) * Name: up_alarm_start * * Description: - * Start the alarm. nxsched_timer_expiration() will be called when the + * Start the alarm. nxsched_process_timer() will be called when the * alarm occurs (unless up_alaram_cancel is called to stop it). * * Provided by platform-specific code and called from the RTOS base code. @@ -485,7 +485,7 @@ int up_timer_gettime(struct timespec *ts) * Input Parameters: * ts - The time in the future at the alarm is expected to occur. When * the alarm occurs the timer logic will call - * nxsched_timer_expiration(). + * nxsched_process_timer(). * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -553,7 +553,7 @@ int up_alarm_start(const struct timespec *ts) * Description: * Cancel the alarm and return the time of cancellation of the alarm. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the alarm is + * nxsched_process_timer() will not be called unless the alarm is * restarted with up_alarm_start(). * * If, as a race condition, the alarm has already expired when this diff --git a/arch/arm/src/lpc43xx/lpc43_rit.c b/arch/arm/src/lpc43xx/lpc43_rit.c index 0188723a8d548..f7e788672f1b2 100644 --- a/arch/arm/src/lpc43xx/lpc43_rit.c +++ b/arch/arm/src/lpc43xx/lpc43_rit.c @@ -86,7 +86,7 @@ static int lpc43_rit_isr(int irq, void *context, void *arg) { /* handle expired alarm */ - nxsched_timer_expiration(); + nxsched_process_timer(); } leave_critical_section(flags); diff --git a/arch/arm/src/lpc43xx/lpc43_tickless_rit.c b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c index 8c08db6b8b6db..5dac6789b618a 100644 --- a/arch/arm/src/lpc43xx/lpc43_tickless_rit.c +++ b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c @@ -496,7 +496,7 @@ static inline void lpc43_tl_alarm(uint32_t curr) lpc43_tl_init_timer_vars(); lpc43_tl_set_default_compare(curr); - nxsched_timer_expiration(); + nxsched_process_timer(); } /* Interrupt handler */ diff --git a/arch/arm/src/lpc54xx/lpc54_tickless.c b/arch/arm/src/lpc54xx/lpc54_tickless.c index dedd2a00db9d1..2ef0d16d91131 100644 --- a/arch/arm/src/lpc54xx/lpc54_tickless.c +++ b/arch/arm/src/lpc54xx/lpc54_tickless.c @@ -539,7 +539,7 @@ static inline void lpc54_tl_alarm(uint64_t curr) lpc54_init_timer_vars(); lpc54_set_default_compare(curr); - nxsched_timer_expiration(); + nxsched_process_timer(); } /* Interrupt handler */ diff --git a/arch/arm/src/moxart/moxart_head.S b/arch/arm/src/moxart/moxart_head.S index 0b8b6cd3cf91f..a67cdeabaf06c 100644 --- a/arch/arm/src/moxart/moxart_head.S +++ b/arch/arm/src/moxart/moxart_head.S @@ -22,7 +22,7 @@ /* Place a branch to the real head at the entry point */ -.section .text.start +.section .text.start, "ax" b __start /* Exception Vectors like they are needed for the exception vector @@ -30,7 +30,7 @@ * linked to appear at 0x80001c */ -.section .text.exceptions +.section .text.exceptions, "ax" _undef_instr: b arm_vectorundefinsn _sw_interr: diff --git a/arch/arm/src/nrf52/nrf52_tickless_rtc.c b/arch/arm/src/nrf52/nrf52_tickless_rtc.c index 78aeb7f68886b..9d05a70322954 100644 --- a/arch/arm/src/nrf52/nrf52_tickless_rtc.c +++ b/arch/arm/src/nrf52/nrf52_tickless_rtc.c @@ -246,7 +246,7 @@ static int rtc_handler(int irq, void *context, void *arg) /* let scheduler now of alarm firing */ - nxsched_timer_expiration(); + nxsched_process_timer(); } leave_critical_section(flags); @@ -357,5 +357,5 @@ void up_timer_initialize(void) /* kick off alarm scheduling */ - nxsched_timer_expiration(); + nxsched_process_timer(); } diff --git a/arch/arm/src/nrf53/nrf53_tickless_rtc.c b/arch/arm/src/nrf53/nrf53_tickless_rtc.c index 0af41431673c9..8fa6e0df3386a 100644 --- a/arch/arm/src/nrf53/nrf53_tickless_rtc.c +++ b/arch/arm/src/nrf53/nrf53_tickless_rtc.c @@ -244,7 +244,7 @@ static int rtc_handler(int irq, void *context, void *arg) /* let scheduler now of alarm firing */ - nxsched_timer_expiration(); + nxsched_process_timer(); } leave_critical_section(flags); @@ -355,5 +355,5 @@ void up_timer_initialize(void) /* kick off alarm scheduling */ - nxsched_timer_expiration(); + nxsched_process_timer(); } diff --git a/arch/arm/src/nrf91/nrf91_tickless_rtc.c b/arch/arm/src/nrf91/nrf91_tickless_rtc.c index 4165c01f3615a..b3065a546206d 100644 --- a/arch/arm/src/nrf91/nrf91_tickless_rtc.c +++ b/arch/arm/src/nrf91/nrf91_tickless_rtc.c @@ -240,7 +240,7 @@ static int rtc_handler(int irq, void *context, void *arg) /* let scheduler now of alarm firing */ - nxsched_timer_expiration(); + nxsched_process_timer(); } leave_critical_section(flags); @@ -351,5 +351,5 @@ void up_timer_initialize(void) /* kick off alarm scheduling */ - nxsched_timer_expiration(); + nxsched_process_timer(); } diff --git a/arch/arm/src/sam34/sam4cm_tickless.c b/arch/arm/src/sam34/sam4cm_tickless.c index a2f2621df130d..b8262b751d20a 100644 --- a/arch/arm/src/sam34/sam4cm_tickless.c +++ b/arch/arm/src/sam34/sam4cm_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -188,7 +188,7 @@ static struct sam_tickless_s g_tickless; static void sam_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -323,7 +323,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -365,14 +365,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/sama5/sam_tickless.c b/arch/arm/src/sama5/sam_tickless.c index da588817430f5..cf497896013a3 100644 --- a/arch/arm/src/sama5/sam_tickless.c +++ b/arch/arm/src/sama5/sam_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -200,7 +200,7 @@ static struct sam_tickless_s g_tickless; static void sam_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -335,7 +335,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -377,14 +377,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/samd5e5/sam_tickless.c b/arch/arm/src/samd5e5/sam_tickless.c index bde7eb332e8be..7629bdab14b25 100644 --- a/arch/arm/src/samd5e5/sam_tickless.c +++ b/arch/arm/src/samd5e5/sam_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -198,7 +198,7 @@ static struct sam_tickless_s g_tickless; static void sam_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -333,7 +333,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -375,14 +375,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/samv7/Kconfig b/arch/arm/src/samv7/Kconfig index 257096a71a334..3a3c6f6500d24 100644 --- a/arch/arm/src/samv7/Kconfig +++ b/arch/arm/src/samv7/Kconfig @@ -3258,7 +3258,6 @@ config SAMV7_EMAC0_MII config SAMV7_EMAC0_RMII bool "RMII" - depends on !ARCH_CHIP_SAM4E ---help--- Support Ethernet RMII interface (vs MII). diff --git a/arch/arm/src/samv7/sam_tickless.c b/arch/arm/src/samv7/sam_tickless.c index f867d0f94aea5..6777cf2f8ead9 100644 --- a/arch/arm/src/samv7/sam_tickless.c +++ b/arch/arm/src/samv7/sam_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -212,7 +212,7 @@ static struct sam_tickless_s g_tickless; static void sam_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -321,7 +321,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -363,14 +363,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32/stm32_tickless.c b/arch/arm/src/stm32/stm32_tickless.c index 6062912deafd5..d7eb0b7499938 100644 --- a/arch/arm/src/stm32/stm32_tickless.c +++ b/arch/arm/src/stm32/stm32_tickless.c @@ -54,7 +54,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -318,7 +318,7 @@ static void stm32_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -746,7 +746,7 @@ void up_timer_getmask(clock_t *mask) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -883,14 +883,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32f7/stm32_tickless.c b/arch/arm/src/stm32f7/stm32_tickless.c index fcb9d1b5e3d08..3e426826d27ea 100644 --- a/arch/arm/src/stm32f7/stm32_tickless.c +++ b/arch/arm/src/stm32f7/stm32_tickless.c @@ -54,7 +54,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -322,7 +322,7 @@ static void stm32_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -787,7 +787,7 @@ void up_timer_getmask(clock_t *mask) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -926,14 +926,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32h7/stm32_tickless.c b/arch/arm/src/stm32h7/stm32_tickless.c index feb5d85c754e7..7e3b712f9ffd9 100644 --- a/arch/arm/src/stm32h7/stm32_tickless.c +++ b/arch/arm/src/stm32h7/stm32_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -309,7 +309,7 @@ static void stm32_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -761,7 +761,7 @@ void up_timer_getmask(clock_t *mask) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -900,14 +900,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32l4/stm32l4_tickless.c b/arch/arm/src/stm32l4/stm32l4_tickless.c index de6172ea04d39..6ca4f157bb310 100644 --- a/arch/arm/src/stm32l4/stm32l4_tickless.c +++ b/arch/arm/src/stm32l4/stm32l4_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -144,7 +144,7 @@ static struct stm32l4_tickless_s g_tickless; static void stm32l4_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -273,7 +273,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -312,14 +312,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/stm32wb/stm32wb_tickless.c b/arch/arm/src/stm32wb/stm32wb_tickless.c index fc24296d3acc3..88c7a1bca596b 100644 --- a/arch/arm/src/stm32wb/stm32wb_tickless.c +++ b/arch/arm/src/stm32wb/stm32wb_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -272,7 +272,7 @@ static void stm32wb_interval_handler(void) g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -612,7 +612,7 @@ void up_timer_getmask(clock_t *mask) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -749,14 +749,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/arm/src/tlsr82/chip/b87/boot/cstartup_flash.S b/arch/arm/src/tlsr82/chip/b87/boot/cstartup_flash.S index 735ccc413ab51..c2627de59dcaf 100644 --- a/arch/arm/src/tlsr82/chip/b87/boot/cstartup_flash.S +++ b/arch/arm/src/tlsr82/chip/b87/boot/cstartup_flash.S @@ -404,7 +404,7 @@ __irq: tjl tc32_exception ASMEND: - .section .bss + .section .bss, "aw" .global g_intstackalloc .global g_intstacktop .align 4 diff --git a/arch/arm/src/xmc4/xmc4_tickless.c b/arch/arm/src/xmc4/xmc4_tickless.c index ce7e35b0a8d5d..85c7a95111891 100644 --- a/arch/arm/src/xmc4/xmc4_tickless.c +++ b/arch/arm/src/xmc4/xmc4_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * * NOTE @@ -150,7 +150,7 @@ static void xmc4_interval_handler(void *arg) putreg32(CCU4_CC4_TCCLR_TRBC_MASK, XMC4_CCU41_CC40TCCLR); g_tickless.pending = false; - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -385,7 +385,7 @@ int up_timer_gettime(struct timespec *ts) * Name: up_alarm_start * * Description: - * Start the alarm. nxsched_timer_expiration() will be called when the + * Start the alarm. nxsched_process_timer() will be called when the * alarm occurs (unless up_alaram_cancel is called to stop it). * * Provided by platform-specific code and called from the RTOS base code. @@ -393,7 +393,7 @@ int up_timer_gettime(struct timespec *ts) * Input Parameters: * ts - The time in the future at the alarm is expected to occur. When * the alarm occurs the timer logic will call - * nxsched_timer_expiration(). + * nxsched_process_timer(). * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -466,7 +466,7 @@ int up_timer_start(const struct timespec *ts) * Description: * Cancel the alarm and return the time of cancellation of the alarm. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the alarm is + * nxsched_process_timer() will not be called unless the alarm is * restarted with up_alarm_start(). * * If, as a race condition, the alarm has already expired when this diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 51f28f74d972b..6ed533f771a31 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -34,6 +34,7 @@ config ARCH_CHIP_A64 select ARCH_HAVE_IRQTRIGGER select ARCH_NEED_ADDRENV_MAPPING select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- Allwinner A64 SoC @@ -44,6 +45,7 @@ config ARCH_CHIP_RK3399 select ARCH_HAVE_RESET select ARCH_NEED_ADDRENV_MAPPING select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- Rockchip RK3399 SoC @@ -57,6 +59,7 @@ config ARCH_CHIP_QEMU select ARCH_HAVE_RESET select ARCH_HAVE_TEXT_HEAP select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- QEMU virt platform (ARMv8a) @@ -72,6 +75,7 @@ config ARCH_CHIP_GOLDFISH select ARCH_HAVE_RESET select ARCH_NEED_ADDRENV_MAPPING select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- Android GoldFish platform for NuttX (ARMv8a), based on ARM virt board @@ -80,6 +84,7 @@ config ARCH_CHIP_FVP_ARMV8R bool "ARM FVP virt platform (ARMv8r)" select ARCH_CORTEX_R82 select ARCH_HAVE_IRQTRIGGER + select ARCH_HAVE_IRQPRIO ---help--- ARM FVP virt platform (ARMv8r) @@ -88,6 +93,7 @@ config ARCH_CHIP_IMX8 select ARCH_HAVE_ADDRENV select ARCH_HAVE_IRQTRIGGER select ARCH_NEED_ADDRENV_MAPPING + select ARCH_HAVE_IRQPRIO ---help--- NXP i.MX8 (ARMv8a) applications processors @@ -98,6 +104,7 @@ config ARCH_CHIP_IMX9 select ARCH_HAVE_I2CRESET select ARCH_HAVE_IRQTRIGGER select ARCH_NEED_ADDRENV_MAPPING + select ARCH_HAVE_IRQPRIO ---help--- NXP i.MX9 (ARMv8.2a) applications processors @@ -109,6 +116,7 @@ config ARCH_CHIP_ZYNQ_MPSOC select ARCH_HAVE_IRQTRIGGER select ARCH_NEED_ADDRENV_MAPPING select ARM64_HAVE_PSCI + select ARCH_HAVE_IRQPRIO ---help--- XilinX ZYNQ MPSOC @@ -123,6 +131,7 @@ config ARCH_CHIP_BCM2711 select ARCH_USE_MMU # Required for up_testset select ARMV8A_HAVE_GICv2 select ARCH_HAVE_SDIO + select ARCH_HAVE_IRQPRIO ---help--- Broadcom BCM2711 quad-core ARM Cortex A72 diff --git a/arch/arm64/src/a64/a64_serial.c b/arch/arm64/src/a64/a64_serial.c index b795faf629659..737623869aa67 100644 --- a/arch/arm64/src/a64/a64_serial.c +++ b/arch/arm64/src/a64/a64_serial.c @@ -648,7 +648,8 @@ static int a64_uart_attach(struct uart_dev_s *dev) /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(port->irq_num, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(port->irq_num, 0); + up_set_irq_type(port->irq_num, IRQ_HIGH_LEVEL); /* Enable UART Interrupt */ diff --git a/arch/arm64/src/a64/a64_twi.c b/arch/arm64/src/a64/a64_twi.c index 79d913a72f12b..a016c0151e767 100644 --- a/arch/arm64/src/a64/a64_twi.c +++ b/arch/arm64/src/a64/a64_twi.c @@ -1845,7 +1845,8 @@ static void twi_hw_initialize(struct a64_twi_priv_s *priv) /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(priv->config->irq, IRQ_TYPE_LEVEL, 0); + up_prioritize_irq(priv->config->irq, 0); + up_set_irq_type(priv->config->irq, IRQ_HIGH_LEVEL); /* Enable TWI Interrupt */ diff --git a/arch/arm64/src/bcm2711/bcm2711_gpio.c b/arch/arm64/src/bcm2711/bcm2711_gpio.c index f155e58a66ad1..e47ae8580eaba 100644 --- a/arch/arm64/src/bcm2711/bcm2711_gpio.c +++ b/arch/arm64/src/bcm2711/bcm2711_gpio.c @@ -272,7 +272,8 @@ static int bcm2711_gpio_irqs_init(void) for (int i = 0; i < NUM_GPIO_IRQS; i++) { up_enable_irq(g_gpio_irqs[i]); - arm64_gic_irq_set_priority(g_gpio_irqs[i], 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(g_gpio_irqs[i], 0); + up_set_irq_type(g_gpio_irqs[i], IRQ_HIGH_LEVEL); } /* Mark as initialized. */ diff --git a/arch/arm64/src/bcm2711/bcm2711_i2c.c b/arch/arm64/src/bcm2711/bcm2711_i2c.c index 706c0002299f6..c5aa8ea1db261 100644 --- a/arch/arm64/src/bcm2711/bcm2711_i2c.c +++ b/arch/arm64/src/bcm2711/bcm2711_i2c.c @@ -1106,7 +1106,8 @@ struct i2c_master_s *bcm2711_i2cbus_initialize(int port) /* Enable interrupt handler */ - arm64_gic_irq_set_priority(BCM_IRQ_VC_I2C, 0, IRQ_TYPE_EDGE); + up_prioritize_irq(BCM_IRQ_VC_I2C, 0); + up_set_irq_type(BCM_IRQ_VC_I2C, IRQ_RISING_EDGE); up_enable_irq(BCM_IRQ_VC_I2C); g_i2c_irqinit = true; /* Mark IRQ handler as initialized */ i2cinfo("I2C IRQ enabled\n"); diff --git a/arch/arm64/src/bcm2711/bcm2711_sdio.c b/arch/arm64/src/bcm2711/bcm2711_sdio.c index a0d395b4e6c71..8e54c2e6e4f8e 100644 --- a/arch/arm64/src/bcm2711/bcm2711_sdio.c +++ b/arch/arm64/src/bcm2711/bcm2711_sdio.c @@ -1068,7 +1068,8 @@ static int bcm2711_attach(FAR struct sdio_dev_s *dev) /* Enable the interrupt handler */ - arm64_gic_irq_set_priority(BCM_IRQ_VC_EMMC, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(BCM_IRQ_VC_EMMC, 0); + up_set_irq_type(BCM_IRQ_VC_EMMC, IRQ_HIGH_LEVEL); up_enable_irq(BCM_IRQ_VC_EMMC); g_emmc_irqinit = true; mcinfo("EMMC IRQ enabled."); diff --git a/arch/arm64/src/bcm2711/bcm2711_serial.c b/arch/arm64/src/bcm2711/bcm2711_serial.c index dc4d0c0415239..15ebc54dc459b 100644 --- a/arch/arm64/src/bcm2711/bcm2711_serial.c +++ b/arch/arm64/src/bcm2711/bcm2711_serial.c @@ -568,7 +568,8 @@ static int bcm2711_miniuart_attach(struct uart_dev_s *dev) /* Set interrupt priority in GICv2 */ - arm64_gic_irq_set_priority(BCM_IRQ_VC_AUX, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(BCM_IRQ_VC_AUX, 0); + up_set_irq_type(BCM_IRQ_VC_AUX, IRQ_HIGH_LEVEL); /* Enable UART interrupt */ diff --git a/arch/arm64/src/bcm2711/bcm2711_spi.c b/arch/arm64/src/bcm2711/bcm2711_spi.c index 585c63215b67f..28f27cf8d2baa 100644 --- a/arch/arm64/src/bcm2711/bcm2711_spi.c +++ b/arch/arm64/src/bcm2711/bcm2711_spi.c @@ -1020,7 +1020,8 @@ struct spi_dev_s *bcm2711_spibus_initialize(int port) return NULL; } - arm64_gic_irq_set_priority(BCM_IRQ_VC_SPI, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(BCM_IRQ_VC_SPI, 0); + up_set_irq_type(BCM_IRQ_VC_SPI, IRQ_HIGH_LEVEL); up_enable_irq(BCM_IRQ_VC_SPI); g_interrupts = true; diff --git a/arch/arm64/src/common/arm64_backtrace.c b/arch/arm64/src/common/arm64_backtrace.c index ee908fee736a1..828a16aecd521 100644 --- a/arch/arm64/src/common/arm64_backtrace.c +++ b/arch/arm64/src/common/arm64_backtrace.c @@ -162,8 +162,8 @@ int up_backtrace(struct tcb_s *tcb, { ret = backtrace(tcb->stack_base_ptr, tcb->stack_base_ptr + tcb->adj_stack_size, - running_regs()[REG_X29], - running_regs()[REG_ELR], + (void *)(tcb->xcp.regs)[REG_X29], + (void *)(tcb->xcp.regs)[REG_ELR], buffer, size, &skip); } diff --git a/arch/arm64/src/common/arm64_gic.h b/arch/arm64/src/common/arm64_gic.h index 43eec799a5aab..ffb5f10bba18c 100644 --- a/arch/arm64/src/common/arm64_gic.h +++ b/arch/arm64/src/common/arm64_gic.h @@ -248,10 +248,6 @@ #define GICD_ICFGR_MASK BIT_MASK(2) #define GICD_ICFGR_TYPE BIT(1) -/* BIT(0) reserved for IRQ_ZERO_LATENCY */ -#define IRQ_TYPE_LEVEL BIT(1) -#define IRQ_TYPE_EDGE BIT(2) - #define GIC_SPI_INT_BASE 32 #define GIC_SPI_MAX_INTID 1019 #define GIC_IS_SPI(intid) (((intid) >= GIC_SPI_INT_BASE) && \ @@ -261,10 +257,6 @@ #define GIC_DIST_IROUTER 0x6000 #define IROUTER(base, n) (base + GIC_DIST_IROUTER + (n) * 8) -/* BIT(0) reserved for IRQ_ZERO_LATENCY */ -#define IRQ_TYPE_LEVEL BIT(1) -#define IRQ_TYPE_EDGE BIT(2) - #define IRQ_DEFAULT_PRIORITY 0xa0 #define GIC_IRQ_SGI0 0 @@ -300,9 +292,6 @@ bool arm64_gic_irq_is_enabled(unsigned int intid); int arm64_gic_initialize(void); -void arm64_gic_irq_set_priority(unsigned int intid, unsigned int prio, - uint32_t flags); -int arm64_gic_irq_trigger(unsigned int intid, uint32_t flags); /**************************************************************************** * Name: arm64_decodeirq @@ -323,7 +312,6 @@ uint64_t * arm64_decodeirq(uint64_t *regs); void arm64_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list); -int arm64_gicv_irq_trigger(int irq, bool edge); #ifdef CONFIG_ARM64_GICV2M int arm64_gic_v2m_initialize(void); #endif diff --git a/arch/arm64/src/common/arm64_gicv2.c b/arch/arm64/src/common/arm64_gicv2.c index ab7b789d3c0c3..ef9fb5e3433ea 100644 --- a/arch/arm64/src/common/arm64_gicv2.c +++ b/arch/arm64/src/common/arm64_gicv2.c @@ -1318,7 +1318,7 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) } /**************************************************************************** - * Name: arm64_gicv_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -1327,32 +1327,37 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * edge - False: Active HIGH level sensitive, True: Rising edge sensitive + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ****************************************************************************/ -int arm64_gicv_irq_trigger(int irq, bool edge) +int up_set_irq_type(int irq, int mode) { uintptr_t regaddr; uint32_t regval; uint32_t intcfg; - if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS) + if (!GIC_IS_SGI(irq)) { + if (mode == IRQ_HIGH_LEVEL || mode == IRQ_LOW_LEVEL) + { + intcfg = INT_ICDICFR_1N; + } + else + { + intcfg = INT_ICDICFR_EDGE | INT_ICDICFR_1N; + } + /* Get the address of the Interrupt Configuration Register for this * irq. */ regaddr = GIC_ICDICFR(irq); - /* Get the new Interrupt configuration bit setting */ - - intcfg = (edge ? (INT_ICDICFR_EDGE | INT_ICDICFR_1N) : INT_ICDICFR_1N); - /* Write the correct interrupt trigger to the Interrupt Configuration * Register. */ @@ -1368,56 +1373,6 @@ int arm64_gicv_irq_trigger(int irq, bool edge) return -EINVAL; } -/**************************************************************************** - * Name: arm64_gic_irq_set_priority - * - * Description: - * Set the interrupt priority and type. - * - * If CONFIG_SMP is not selected, the cpuset is ignored and SGI is sent - * only to the current CPU. - * - * Input Parameters - * intid - The SGI interrupt ID (0-15) - * prio - The interrupt priority - * flags - Bit IRQ_TYPE_EDGE is 1 if interrupt should be edge-triggered - * - * Returned Value: - * None - * - ****************************************************************************/ - -void arm64_gic_irq_set_priority(unsigned int intid, unsigned int prio, - uint32_t flags) -{ - int ret; - - /* Disable the interrupt */ - - up_disable_irq(intid); - - /* Set the interrupt priority */ - - ret = up_prioritize_irq(intid, prio); - DEBUGASSERT(ret == OK); - - /* Configure interrupt type */ - - if (!GIC_IS_SGI(intid)) - { - if (flags & IRQ_TYPE_EDGE) - { - ret = arm64_gicv_irq_trigger(intid, true); - DEBUGASSERT(ret == OK); - } - else - { - ret = arm64_gicv_irq_trigger(intid, false); - DEBUGASSERT(ret == OK); - } - } -} - /**************************************************************************** * Name: arm64_gic_initialize * diff --git a/arch/arm64/src/common/arm64_gicv2m.c b/arch/arm64/src/common/arm64_gicv2m.c index bb97882edb08e..f987a82460584 100644 --- a/arch/arm64/src/common/arm64_gicv2m.c +++ b/arch/arm64/src/common/arm64_gicv2m.c @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -132,7 +133,7 @@ int up_alloc_irq_msi(uint8_t busno, uint32_t devfn, int *pirq, int num) irq = g_v2m.spi_start + offset; for (i = 0; i < num; i++) { - arm64_gicv_irq_trigger(i + irq, true); + up_set_irq_type(i + irq, IRQ_RISING_EDGE); pirq[i] = irq + i; } diff --git a/arch/arm64/src/common/arm64_gicv3.c b/arch/arm64/src/common/arm64_gicv3.c index ad3bd40b74bdb..e776dd6e92ab4 100644 --- a/arch/arm64/src/common/arm64_gicv3.c +++ b/arch/arm64/src/common/arm64_gicv3.c @@ -156,53 +156,8 @@ static inline void arm64_gic_write_irouter(uint64_t val, unsigned int intid) putreg64(val, addr); } -void arm64_gic_irq_set_priority(unsigned int intid, unsigned int prio, - uint32_t flags) -{ - uint32_t mask = BIT(intid & (GIC_NUM_INTR_PER_REG - 1)); - uint32_t idx = intid / GIC_NUM_INTR_PER_REG; - uint32_t shift; - uint32_t val; - unsigned long base = GET_DIST_BASE(intid); - irqstate_t irq_flags; - - /* Disable the interrupt */ - - putreg32(mask, ICENABLER(base, idx)); - gic_wait_rwp(intid); - - /* PRIORITYR registers provide byte access */ - - putreg8(prio & GIC_PRI_MASK, IPRIORITYR(base, intid)); - - /* Interrupt type config */ - - if (!GIC_IS_SGI(intid)) - { - idx = intid / GIC_NUM_CFG_PER_REG; - shift = (intid & (GIC_NUM_CFG_PER_REG - 1)) * 2; - - /* GICD_ICFGR requires full 32-bit RMW operations. - * Each interrupt uses 2 bits; thus updates must be synchronized - * to avoid losing configuration in concurrent environments. - */ - - irq_flags = spin_lock_irqsave(&g_gic_lock); - - val = getreg32(ICFGR(base, idx)); - val &= ~(GICD_ICFGR_MASK << shift); - if (flags & IRQ_TYPE_EDGE) - { - val |= (GICD_ICFGR_TYPE << shift); - } - - putreg32(val, ICFGR(base, idx)); - spin_unlock_irqrestore(&g_gic_lock, irq_flags); - } -} - /*************************************************************************** - * Name: arm64_gic_irq_trigger + * Name: up_set_irq_type * * Description: * Set the trigger type for the specified IRQ source and the current CPU. @@ -211,27 +166,26 @@ void arm64_gic_irq_set_priority(unsigned int intid, unsigned int prio, * avoided in common implementations where possible. * * Input Parameters: - * irq - The interrupt request to modify. - * flags - irq type, IRQ_TYPE_EDGE or IRQ_TYPE_LEVEL - * Default is IRQ_TYPE_LEVEL + * irq - The interrupt request to modify. + * mode - Level sensitive or edge sensitive * * Returned Value: * Zero (OK) on success; a negated errno value is returned on any failure. * ***************************************************************************/ -int arm64_gic_irq_trigger(unsigned int intid, uint32_t flags) +int up_set_irq_type(int irq, int mode) { - uint32_t idx = intid / GIC_NUM_INTR_PER_REG; + uint32_t idx = irq / GIC_NUM_INTR_PER_REG; uint32_t shift; uint32_t val; - unsigned long base = GET_DIST_BASE(intid); + unsigned long base = GET_DIST_BASE(irq); irqstate_t irq_flags; - if (!GIC_IS_SGI(intid)) + if (!GIC_IS_SGI(irq)) { - idx = intid / GIC_NUM_CFG_PER_REG; - shift = (intid & (GIC_NUM_CFG_PER_REG - 1)) * 2; + idx = irq / GIC_NUM_CFG_PER_REG; + shift = (irq & (GIC_NUM_CFG_PER_REG - 1)) * 2; /* GICD_ICFGR requires full 32-bit RMW operations. * Each interrupt uses 2 bits; thus updates must be synchronized @@ -242,7 +196,7 @@ int arm64_gic_irq_trigger(unsigned int intid, uint32_t flags) val = getreg32(ICFGR(base, idx)); val &= ~(GICD_ICFGR_MASK << shift); - if (flags & IRQ_TYPE_EDGE) + if (mode != IRQ_HIGH_LEVEL && mode != IRQ_LOW_LEVEL) { val |= (GICD_ICFGR_TYPE << shift); } diff --git a/arch/arm64/src/common/arm64_initialstate.c b/arch/arm64/src/common/arm64_initialstate.c index ff2d9c5cffc48..a70d5cf5bd0e5 100644 --- a/arch/arm64/src/common/arm64_initialstate.c +++ b/arch/arm64/src/common/arm64_initialstate.c @@ -91,6 +91,10 @@ void arm64_new_task(struct tcb_s * tcb) xcp->regs[REG_SCTLR_EL1] |= SCTLR_TCF1_BIT; #endif +#ifndef CONFIG_ARM64_DECODEFIQ + xcp->regs[REG_SPSR] |= DAIF_FIQ_BIT; +#endif + #ifdef CONFIG_SUPPRESS_INTERRUPTS xcp->regs[REG_SPSR] |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT); #endif /* CONFIG_SUPPRESS_INTERRUPTS */ diff --git a/arch/arm64/src/common/arm64_mpu.c b/arch/arm64/src/common/arm64_mpu.c index 098c9a2b15da2..41f3c081a6446 100644 --- a/arch/arm64/src/common/arm64_mpu.c +++ b/arch/arm64/src/common/arm64_mpu.c @@ -73,7 +73,7 @@ * regions. */ -static unsigned int g_mpu_region; +static unsigned int g_mpu_region[CONFIG_SMP_NCPUS]; /**************************************************************************** * Private Functions @@ -153,12 +153,12 @@ static void mpu_init(void) unsigned int mpu_allocregion(void) { unsigned int num_regions = get_num_regions(); - unsigned int i = ffs(~g_mpu_region) - 1; + unsigned int i = ffs(~g_mpu_region[this_cpu()]) - 1; /* There are not enough regions to apply */ DEBUGASSERT(i < num_regions); - g_mpu_region |= 1 << i; + g_mpu_region[this_cpu()] |= 1 << i; return i; } @@ -191,7 +191,7 @@ void mpu_freeregion(unsigned int region) write_sysreg(0, prbar_el1); write_sysreg(0, prlar_el1); - g_mpu_region &= ~(1 << region); + g_mpu_region[this_cpu()] &= ~(1 << region); UP_MB(); } @@ -275,7 +275,7 @@ void mpu_modify_region(unsigned int region, /* Check that the region is valid */ - DEBUGASSERT(g_mpu_region & (1 << region)); + DEBUGASSERT(g_mpu_region[this_cpu()] & (1 << region)); rbar |= table->attr.rbar & (MPU_RBAR_XN_MSK | MPU_RBAR_AP_MSK | MPU_RBAR_SH_MSK); diff --git a/arch/arm64/src/common/arm64_syscall.c b/arch/arm64/src/common/arm64_syscall.c index 166dc8963d051..6e837df1c23e3 100644 --- a/arch/arm64/src/common/arm64_syscall.c +++ b/arch/arm64/src/common/arm64_syscall.c @@ -164,6 +164,10 @@ uint64_t *arm64_syscall(uint64_t *regs) uint64_t spsr; #endif + /* Set irq flag */ + + write_sysreg((uintptr_t)tcb | 1, tpidr_el1); + /* Nested interrupts are not supported */ DEBUGASSERT(regs); @@ -314,6 +318,10 @@ uint64_t *arm64_syscall(uint64_t *regs) default: { svcerr("ERROR: Bad SYS call: 0x%" PRIx64 "\n", cmd); + + /* Clear irq flag */ + + write_sysreg((uintptr_t)tcb & ~1ul, tpidr_el1); return 0; } break; @@ -326,5 +334,9 @@ uint64_t *arm64_syscall(uint64_t *regs) */ (*running_task)->xcp.regs = NULL; + + /* Clear irq flag */ + + write_sysreg((uintptr_t)tcb & ~1ul, tpidr_el1); return regs; } diff --git a/arch/arm64/src/imx9/ddr/imx9_ddr_training.c b/arch/arm64/src/imx9/ddr/imx9_ddr_training.c index ddd66646b8576..bc86f6fcf7384 100644 --- a/arch/arm64/src/imx9/ddr/imx9_ddr_training.c +++ b/arch/arm64/src/imx9/ddr/imx9_ddr_training.c @@ -58,7 +58,7 @@ /* DDR training binaries via incbin */ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 64 \n" " .globl g_dmem1d_begin \n" "g_dmem1d_begin: \n" diff --git a/arch/arm64/src/rk3399/rk3399_serial.c b/arch/arm64/src/rk3399/rk3399_serial.c index cb7c3968675cc..1ab9c3ed86a7b 100644 --- a/arch/arm64/src/rk3399/rk3399_serial.c +++ b/arch/arm64/src/rk3399/rk3399_serial.c @@ -641,7 +641,8 @@ static int a64_uart_attach(struct uart_dev_s *dev) /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(port->irq_num, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(port->irq_num, 0); + up_set_irq_type(port->irq_num, IRQ_RISING_EDGE); /* Enable UART Interrupt */ diff --git a/arch/arm64/src/zynq-mpsoc/zynq_serial.c b/arch/arm64/src/zynq-mpsoc/zynq_serial.c index 9285b952fe0c9..8b63a91c3f279 100644 --- a/arch/arm64/src/zynq-mpsoc/zynq_serial.c +++ b/arch/arm64/src/zynq-mpsoc/zynq_serial.c @@ -775,7 +775,8 @@ static int zynq_uart_attach(struct uart_dev_s *dev) /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(port->irq_num, 0, IRQ_TYPE_LEVEL); + up_prioritize_irq(port->irq_num, 0); + up_set_irq_type(port->irq_num, IRQ_HIGH_LEVEL); /* Enable UART Interrupt */ diff --git a/arch/avr/src/avrdx/avrdx_timerisr_tickless_alarm.c b/arch/avr/src/avrdx/avrdx_timerisr_tickless_alarm.c index 323bcd8e53cc2..0257da058b2f6 100644 --- a/arch/avr/src/avrdx/avrdx_timerisr_tickless_alarm.c +++ b/arch/avr/src/avrdx/avrdx_timerisr_tickless_alarm.c @@ -269,7 +269,7 @@ static void avrdx_check_alarm_expired(uint8_t context) * context. Remove non-interrupt flags from the context before * using it. * - * Deactivate alarm first. Call to nxsched_timer_expiration() + * Deactivate alarm first. Call to nxsched_process_timer() * in turns calls up_timer_gettick(), that one calls * up_timer_gettime() which calls this method through * avrdx_increment_uptime(), causing a recursion loop. @@ -283,7 +283,7 @@ static void avrdx_check_alarm_expired(uint8_t context) */ avrdx_deactivate_alarm(); - nxsched_timer_expiration(); + nxsched_process_timer(); } else { diff --git a/arch/risc-v/src/common/espressif/esp_tickless.c b/arch/risc-v/src/common/espressif/esp_tickless.c index 9d7b57224ebeb..f66688a19b395 100644 --- a/arch/risc-v/src/common/espressif/esp_tickless.c +++ b/arch/risc-v/src/common/espressif/esp_tickless.c @@ -97,7 +97,7 @@ static int esp_tickless_isr(int irq, void *context, void *arg) systimer_ll_clear_alarm_int(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0); - nxsched_timer_expiration(); + nxsched_process_timer(); return OK; } @@ -235,7 +235,7 @@ int IRAM_ATTR up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -325,14 +325,14 @@ int IRAM_ATTR up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/risc-v/src/esp32c3-legacy/esp32c3_tickless.c b/arch/risc-v/src/esp32c3-legacy/esp32c3_tickless.c index 4176ccee90941..d16ea6308fee1 100644 --- a/arch/risc-v/src/esp32c3-legacy/esp32c3_tickless.c +++ b/arch/risc-v/src/esp32c3-legacy/esp32c3_tickless.c @@ -281,7 +281,7 @@ static void IRAM_ATTR up_timer_expire(int irq, void *regs, void *arg) { g_timer_started = false; setbits(SYS_TIMER_TARGET0_INT_CLR, SYS_TIMER_SYSTIMER_INT_CLR_REG); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -343,7 +343,7 @@ int IRAM_ATTR up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -420,14 +420,14 @@ int IRAM_ATTR up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/risc-v/src/litex/litex_tickless.c b/arch/risc-v/src/litex/litex_tickless.c index cb9efbaa21240..48b6c6228f780 100644 --- a/arch/risc-v/src/litex/litex_tickless.c +++ b/arch/risc-v/src/litex/litex_tickless.c @@ -79,7 +79,7 @@ static int up_timer_expire(int irq, void *regs, void *arg) { g_timer_started = false; putreg32(1 << LITEX_TIMER0_TIMEOUT_EV_OFFSET, LITEX_TIMER0_EV_PENDING); - nxsched_timer_expiration(); + nxsched_process_timer(); return OK; } @@ -211,7 +211,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -272,14 +272,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/sim/Kconfig b/arch/sim/Kconfig index 944a12c6c7e4c..c545404454a86 100644 --- a/arch/sim/Kconfig +++ b/arch/sim/Kconfig @@ -284,16 +284,38 @@ config SIM_NETDEV_NUMBER Note that only one network device will be brought up by netinit automatically, others will be kept in DOWN state by default. +if SIM_NETDEV && DRIVERS_IEEE80211 && NETDEV_WIRELESS_HANDLER + config SIM_WIFIDEV_NUMBER int "Number of Simulated WiFi Device" default 0 range 0 SIM_NETDEV_NUMBER - depends on SIM_NETDEV && DRIVERS_IEEE80211 && NETDEV_WIRELESS_HANDLER ---help--- The number of simulated wifi network devices. Note that only one network device will be brought up by netinit automatically, others will be kept in DOWN state by default. + +choice + prompt "Select SimWiFi Platform" + depends on SIM_WIFIDEV_NUMBER != 0 + default SIM_WIFIDEV_HOST + +config SIM_WIFIDEV_HOST + bool "Use the host Wi-Fi interfaces" + ---help--- + Use the host Wi-Fi interfaces, which are either simulated by + hwsim or the real wireless network cards. + +config SIM_WIFIDEV_PSEUDO + bool "Use the Simulated Wi-Fi devices" + depends on DRIVERS_WIFI_SIM + ---help--- + Use the the Simulated Wi-Fi devices, which are supported by the bss file. +endchoice + +endif + endif config SIM_NETDEV_VPNKIT_PATH diff --git a/arch/sim/include/setjmp.h b/arch/sim/include/setjmp.h index 042eeed980fdf..3c252575fe8b0 100644 --- a/arch/sim/include/setjmp.h +++ b/arch/sim/include/setjmp.h @@ -40,7 +40,7 @@ #if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32) /* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */ -# define XCPTCONTEXT_REGS 9 +# define XCPTCONTEXT_REGS 11 # define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS) # ifdef __ASSEMBLY__ @@ -54,6 +54,8 @@ # define JB_R15 (6*8) # define JB_RIP (7*8) # define JB_FLAG (8*8) +# define JB_ERRNO (9*8) +# define JB_ALIGN0 (10*8) # else @@ -66,6 +68,8 @@ # define JB_R15 (6) # define JB_RIP (7) # define JB_FLAG (8) +# define JB_ERRNO (9) +# define JB_ALIGN0 (10) # endif /* __ASSEMBLY__ */ @@ -78,7 +82,7 @@ #elif defined(CONFIG_HOST_X86) || defined(CONFIG_SIM_M32) /* Storage order: %ebx, %esi, %edi, %ebp, sp, and return PC */ -# define XCPTCONTEXT_REGS (8) +# define XCPTCONTEXT_REGS (9) # define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) # ifdef __ASSEMBLY__ @@ -91,6 +95,7 @@ # define JB_EIP (5*4) # define JB_FLAG (6*4) # define JB_FLAG1 (7*4) +# define JB_ERRNO (8*4) # else @@ -102,6 +107,7 @@ # define JB_EIP (5) # define JB_FLAG (6) # define JB_FLAG1 (7) +# define JB_ERRNO (8) # endif /* __ASSEMBLY__ */ @@ -113,7 +119,7 @@ #elif defined(CONFIG_HOST_ARM) -# define XCPTCONTEXT_REGS 18 +# define XCPTCONTEXT_REGS 19 # define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) # define JB_FP 7 @@ -121,10 +127,11 @@ # define JB_PC 9 # define JB_FLAG 16 # define JB_FLAG1 17 +# define JB_ERRNO 18 #elif defined(CONFIG_HOST_ARM64) -# define XCPTCONTEXT_REGS 33 +# define XCPTCONTEXT_REGS 34 # define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS) # ifdef __ASSEMBLY__ @@ -148,6 +155,7 @@ # define JB_FP (12) # define JB_SP (13) # define JB_FLAG (32) +# define JB_ERRNO (33) # endif /* __ASSEMBLY__ */ diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile index 542a0567470fd..9c4b42e8e762e 100644 --- a/arch/sim/src/Makefile +++ b/arch/sim/src/Makefile @@ -118,7 +118,7 @@ ifeq ($(CONFIG_FS_LARGEFILE),y) endif HOSTSRCS = sim_hostirq.c sim_hostmemory.c sim_hostmisc.c sim_hosttime.c sim_hostuart.c -HOSTSRCS += sim_hostfs.c +HOSTSRCS += sim_hostfs.c sim_errno.c hostfs.h: $(TOPDIR)/include/nuttx/fs/hostfs.h @echo "CP: $<" @@ -209,8 +209,9 @@ ifeq ($(CONFIG_FS_FAT),y) STDLIBS += -lz endif -ifneq ($(CONFIG_SIM_WIFIDEV_NUMBER),0) +ifeq ($(CONFIG_SIM_WIFIDEV_HOST),y) CFLAGS += -DTOPDIR=\"$(TOPDIR)\" + CSRCS += sim_wifihost.c endif ifeq ($(CONFIG_SIM_NETDEV_TAP),y) diff --git a/arch/sim/src/cmake/Toolchain.cmake b/arch/sim/src/cmake/Toolchain.cmake index fa1be1575b1f6..b5d87923a8c6d 100644 --- a/arch/sim/src/cmake/Toolchain.cmake +++ b/arch/sim/src/cmake/Toolchain.cmake @@ -220,6 +220,10 @@ if(CONFIG_LIBCXX) add_compile_options($<$:-D_LIBCPP_DISABLE_AVAILABILITY>) endif() +if(CONFIG_LIBCXX_TEST) + add_link_options(-Wl,-latomic) +endif() + if(APPLE) add_link_options(-Wl,-dead_strip) else() diff --git a/arch/sim/src/sim/CMakeLists.txt b/arch/sim/src/sim/CMakeLists.txt index 3b3da83e189b8..875040d5ef0aa 100644 --- a/arch/sim/src/sim/CMakeLists.txt +++ b/arch/sim/src/sim/CMakeLists.txt @@ -213,6 +213,11 @@ if(CONFIG_SIM_X11FB) endif() endif() +if(NOT ${CONFIG_SIM_WIFIDEV_NUMBER} EQUAL 0) + add_compile_options(-DTOPDIR=$(TOPDIR)) + list(APPEND SRCS sim_wifihost.c) +endif() + if(CONFIG_SIM_NETDEV_TAP) list(APPEND SRCS sim_netdriver.c) @@ -284,6 +289,8 @@ endif() list(APPEND HOSTSRCS sim_hostfs.c) list(APPEND HOST_DEFINITIONS CONFIG_NAME_MAX=${CONFIG_NAME_MAX}) +list(APPEND HOSTSRCS sim_errno.c) + configure_file(${NUTTX_DIR}/include/nuttx/fs/hostfs.h ${CMAKE_CURRENT_BINARY_DIR}/hostfs.h COPYONLY) configure_file(${CMAKE_BINARY_DIR}/include/nuttx/config.h diff --git a/arch/sim/src/sim/posix/sim_alsa.c b/arch/sim/src/sim/posix/sim_alsa.c index 064dc2480fb9d..5c8e566148d17 100644 --- a/arch/sim/src/sim/posix/sim_alsa.c +++ b/arch/sim/src/sim/posix/sim_alsa.c @@ -29,8 +29,7 @@ #include #include #include -#include - +#include #include #include @@ -53,10 +52,9 @@ struct sim_audio_s { struct audio_lowerhalf_s dev; struct dq_queue_s pendq; + struct work_s work; mutex_t pendlock; - struct wdog_s wdog; /* Watchdog for event loop */ - bool playback; bool offload; bool paused; @@ -1134,13 +1132,14 @@ static int sim_mixer_open(struct sim_audio_s *priv) return 0; } -static void sim_alsa_interrupt(wdparm_t arg) +static void sim_audio_work(FAR void *arg) { struct sim_audio_s *priv = (struct sim_audio_s *)arg; sim_audio_process(priv); - wd_start_next(&priv->wdog, SIM_AUDIO_PERIOD, sim_alsa_interrupt, arg); + work_queue_next_wq(g_work_queue, &priv->work, sim_audio_work, priv, + SIM_AUDIO_PERIOD); } /**************************************************************************** @@ -1169,7 +1168,9 @@ struct audio_lowerhalf_s *sim_audio_initialize(bool playback, bool offload) return NULL; } - wd_start(&priv->wdog, 0, sim_alsa_interrupt, (wdparm_t)priv); + memset(&priv->work, 0, sizeof(struct work_s)); + work_queue_wq(g_work_queue, &priv->work, sim_audio_work, priv, + SIM_AUDIO_PERIOD); /* Setting default config */ @@ -1181,6 +1182,5 @@ struct audio_lowerhalf_s *sim_audio_initialize(bool playback, bool offload) priv->channels = 2; priv->bps = 16; priv->frame_size = 4; - return &priv->dev; } diff --git a/arch/sim/src/sim/posix/sim_errno.c b/arch/sim/src/sim/posix/sim_errno.c new file mode 100644 index 0000000000000..77066082a1721 --- /dev/null +++ b/arch/sim/src/sim/posix/sim_errno.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * arch/sim/src/sim/posix/sim_errno.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_errno_convert(int errcode) +{ + return errcode; +} + +int host_errno_get(void) +{ + return errno; +} + +void host_errno_set(int errcode) +{ + errno = errcode; +} diff --git a/arch/sim/src/sim/posix/sim_hostfs.c b/arch/sim/src/sim/posix/sim_hostfs.c index a22d7118d3272..8597b036f1ca1 100644 --- a/arch/sim/src/sim/posix/sim_hostfs.c +++ b/arch/sim/src/sim/posix/sim_hostfs.c @@ -194,7 +194,13 @@ int host_open(const char *pathname, int flags, int mode) mapflags |= O_DIRECTORY; } - return host_uninterruptible_errno(open, pathname, mapflags, mode); + int ret = open(pathname, mapflags, mode); + if (ret == -1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -205,7 +211,13 @@ int host_close(int fd) { /* Just call the close routine */ - return host_uninterruptible_errno(close, fd); + int ret = close(fd); + if (ret == -1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -216,7 +228,13 @@ nuttx_ssize_t host_read(int fd, void *buf, nuttx_size_t count) { /* Just call the read routine */ - return host_uninterruptible_errno(read, fd, buf, count); + nuttx_ssize_t ret = read(fd, buf, count); + if (ret == -1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -227,7 +245,13 @@ nuttx_ssize_t host_write(int fd, const void *buf, nuttx_size_t count) { /* Just call the write routine */ - return host_uninterruptible_errno(write, fd, buf, count); + nuttx_ssize_t ret = write(fd, buf, count); + if (ret == -1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -239,7 +263,13 @@ nuttx_off_t host_lseek(int fd, nuttx_off_t pos, nuttx_off_t offset, { /* Just call the lseek routine */ - return host_uninterruptible_errno(lseek, fd, offset, whence); + nuttx_off_t ret = lseek(fd, offset, whence); + if (ret == (nuttx_off_t)-1) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -250,7 +280,13 @@ int host_ioctl(int fd, int request, unsigned long arg) { /* Just call the ioctl routine */ - return host_uninterruptible_errno(ioctl, fd, request, arg); + int ret = ioctl(fd, request, arg); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -270,7 +306,13 @@ void host_sync(int fd) int host_dup(int fd) { - return host_uninterruptible_errno(dup, fd); + int ret = dup(fd); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -284,7 +326,11 @@ int host_fstat(int fd, struct nuttx_stat_s *buf) /* Call the host's stat routine */ - ret = host_uninterruptible_errno(fstat, fd, &hostbuf); + ret = fstat(fd, &hostbuf); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } /* Map the return values */ @@ -303,19 +349,19 @@ int host_fchstat(int fd, const struct nuttx_stat_s *buf, int flags) if (flags & NUTTX_CH_STAT_MODE) { - ret = host_uninterruptible_errno(fchmod, fd, buf->st_mode); + ret = fchmod(fd, buf->st_mode); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } if (flags & (NUTTX_CH_STAT_UID | NUTTX_CH_STAT_GID)) { - ret = host_uninterruptible_errno(fchown, fd, buf->st_uid, buf->st_gid); + ret = fchown(fd, buf->st_uid, buf->st_gid); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } @@ -343,10 +389,10 @@ int host_fchstat(int fd, const struct nuttx_stat_s *buf, int flags) times[1].tv_nsec = UTIME_OMIT; } - ret = host_uninterruptible_errno(futimens, fd, times); + ret = futimens(fd, times); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } @@ -359,7 +405,13 @@ int host_fchstat(int fd, const struct nuttx_stat_s *buf, int flags) int host_ftruncate(int fd, nuttx_off_t length) { - return host_uninterruptible_errno(ftruncate, fd, length); + int ret = ftruncate(fd, length); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -449,7 +501,13 @@ void host_rewinddir(void *dirp) int host_closedir(void *dirp) { - return host_uninterruptible_errno(closedir, dirp); + int ret = closedir(dirp); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -463,7 +521,11 @@ int host_statfs(const char *path, struct nuttx_statfs_s *buf) /* Call the host's statfs routine */ - ret = host_uninterruptible_errno(statvfs, path, &hostbuf); + ret = statvfs(path, &hostbuf); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } /* Map the struct statfs value */ @@ -485,7 +547,13 @@ int host_statfs(const char *path, struct nuttx_statfs_s *buf) int host_unlink(const char *pathname) { - return host_uninterruptible_errno(unlink, pathname); + int ret = unlink(pathname); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -496,7 +564,13 @@ int host_mkdir(const char *pathname, int mode) { /* Just call the host's mkdir routine */ - return host_uninterruptible_errno(mkdir, pathname, mode); + int ret = mkdir(pathname, mode); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -505,7 +579,13 @@ int host_mkdir(const char *pathname, int mode) int host_rmdir(const char *pathname) { - return host_uninterruptible_errno(rmdir, pathname); + int ret = rmdir(pathname); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -514,7 +594,13 @@ int host_rmdir(const char *pathname) int host_rename(const char *oldpath, const char *newpath) { - return host_uninterruptible_errno(rename, oldpath, newpath); + int ret = rename(oldpath, newpath); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } + + return ret; } /**************************************************************************** @@ -528,7 +614,11 @@ int host_stat(const char *path, struct nuttx_stat_s *buf) /* Call the host's stat routine */ - ret = host_uninterruptible_errno(stat, path, &hostbuf); + ret = stat(path, &hostbuf); + if (ret < 0) + { + ret = host_errno_convert(-errno); + } /* Map the return values */ @@ -547,20 +637,19 @@ int host_chstat(const char *path, const struct nuttx_stat_s *buf, int flags) if (flags & NUTTX_CH_STAT_MODE) { - ret = host_uninterruptible_errno(chmod, path, buf->st_mode); + ret = chmod(path, buf->st_mode); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } if (flags & (NUTTX_CH_STAT_UID | NUTTX_CH_STAT_GID)) { - ret = host_uninterruptible_errno(chown, path, - buf->st_uid, buf->st_gid); + ret = chown(path, buf->st_uid, buf->st_gid); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } @@ -588,10 +677,10 @@ int host_chstat(const char *path, const struct nuttx_stat_s *buf, int flags) times[1].tv_nsec = UTIME_OMIT; } - ret = host_uninterruptible_errno(utimensat, AT_FDCWD, path, times, 0); + ret = utimensat(AT_FDCWD, path, times, 0); if (ret < 0) { - return ret; + return host_errno_convert(-errno); } } diff --git a/arch/sim/src/sim/posix/sim_hostirq.c b/arch/sim/src/sim/posix/sim_hostirq.c index 06c2f70d81a9c..6a678589be8ad 100644 --- a/arch/sim/src/sim/posix/sim_hostirq.c +++ b/arch/sim/src/sim/posix/sim_hostirq.c @@ -134,20 +134,6 @@ void up_irq_enable(void) up_irq_restore(0); } -/**************************************************************************** - * Name: up_irqinitialize - ****************************************************************************/ - -void up_irqinitialize(void) -{ -#ifdef CONFIG_SMP - /* Register the pause handler */ - - sim_init_ipi(SIGUSR1); - sim_init_func_call_ipi(SIGUSR2); -#endif -} - /**************************************************************************** * Name: up_enable_irq * @@ -192,3 +178,17 @@ void up_disable_irq(int irq) signal(irq, SIG_IGN); } + +/**************************************************************************** + * Name: host_irqinitialize + ****************************************************************************/ + +void host_irqinitialize(void) +{ +#ifdef CONFIG_SMP + /* Register the pause handler */ + + sim_init_ipi(SIGUSR1); + sim_init_func_call_ipi(SIGUSR2); +#endif +} diff --git a/arch/sim/src/sim/posix/sim_hostmisc.c b/arch/sim/src/sim/posix/sim_hostmisc.c index 6015af0701eed..d759f1f57ccb3 100644 --- a/arch/sim/src/sim/posix/sim_hostmisc.c +++ b/arch/sim/src/sim/posix/sim_hostmisc.c @@ -128,38 +128,32 @@ int host_system(char *buf, size_t len, const char *fmt, ...) int ret; char cmd[512]; va_list vars; - uint64_t flags; va_start(vars, fmt); - ret = host_uninterruptible_errno(vsnprintf, cmd, sizeof(cmd), fmt, vars); + ret = vsnprintf(cmd, sizeof(cmd), fmt, vars); va_end(vars); if (ret <= 0 || ret > sizeof(cmd)) { - return ret < 0 ? ret : -EINVAL; + return ret < 0 ? -errno : -EINVAL; } if (buf == NULL) { - ret = host_uninterruptible_errno(system, cmd); + ret = host_uninterruptible(system, cmd); } else { - flags = up_irq_save(); fp = host_uninterruptible(popen, cmd, "r"); if (fp == NULL) { - ret = -errno; - up_irq_restore(flags); - return ret; + return -errno; } - up_irq_restore(flags); - - ret = host_uninterruptible_errno(fread, buf, 1, len, fp); + ret = host_uninterruptible(fread, buf, 1, len, fp); host_uninterruptible(pclose, fp); } - return ret; + return ret < 0 ? -errno : ret; } /**************************************************************************** @@ -229,6 +223,6 @@ int host_waitpid(pid_t pid) { int status; - pid = host_uninterruptible_errno(waitpid, pid, &status, 0); - return pid < 0 ? pid : status; + pid = host_uninterruptible(waitpid, pid, &status, 0); + return pid < 0 ? -errno : status; } diff --git a/arch/sim/src/sim/posix/sim_hostuart.c b/arch/sim/src/sim/posix/sim_hostuart.c index 12f1965895e4a..facc21e467e0e 100644 --- a/arch/sim/src/sim/posix/sim_hostuart.c +++ b/arch/sim/src/sim/posix/sim_hostuart.c @@ -96,15 +96,15 @@ void host_uart_start(void) { /* Get the current stdin terminal mode */ - host_uninterruptible_no_return(tcgetattr, 0, &g_cooked); + tcgetattr(0, &g_cooked); /* Put stdin into raw mode */ - host_uninterruptible_no_return(setrawmode, 0); + setrawmode(0); /* Restore the original terminal mode before exit */ - host_uninterruptible_no_return(atexit, restoremode); + atexit(restoremode); } /**************************************************************************** @@ -115,12 +115,16 @@ int host_uart_open(const char *pathname) { int fd; - fd = host_uninterruptible_errno(open, pathname, O_RDWR | O_NONBLOCK); + fd = open(pathname, O_RDWR | O_NONBLOCK); if (fd >= 0) { /* keep raw mode */ - host_uninterruptible_no_return(setrawmode, fd); + setrawmode(fd); + } + else + { + fd = -errno; } return fd; @@ -132,7 +136,7 @@ int host_uart_open(const char *pathname) void host_uart_close(int fd) { - host_uninterruptible(close, fd); + close(fd); } /**************************************************************************** @@ -145,11 +149,11 @@ int host_uart_puts(int fd, const char *buf, size_t size) do { - ret = host_uninterruptible_errno(write, fd, buf, size); + ret = write(fd, buf, size); } - while (ret < 0 && ret == -EINTR); + while (ret < 0 && errno == EINTR); - return ret; + return ret < 0 ? -errno : ret; } /**************************************************************************** @@ -162,11 +166,11 @@ int host_uart_gets(int fd, char *buf, size_t size) do { - ret = host_uninterruptible_errno(read, fd, buf, size); + ret = read(fd, buf, size); } - while (ret < 0 && ret == -EINTR); + while (ret < 0 && errno == EINTR); - return ret; + return ret < 0 ? -errno : ret; } /**************************************************************************** @@ -178,8 +182,12 @@ int host_uart_getcflag(int fd, unsigned int *cflag) struct termios t; int ret; - ret = host_uninterruptible_errno(tcgetattr, fd, &t); - if (ret >= 0) + ret = tcgetattr(fd, &t); + if (ret < 0) + { + ret = -errno; + } + else { *cflag = t.c_cflag; } @@ -196,11 +204,16 @@ int host_uart_setcflag(int fd, unsigned int cflag) struct termios t; int ret; - ret = host_uninterruptible_errno(tcgetattr, fd, &t); + ret = tcgetattr(fd, &t); if (!ret) { t.c_cflag = cflag; - ret = host_uninterruptible_errno(tcsetattr, fd, TCSANOW, &t); + ret = tcsetattr(fd, TCSANOW, &t); + } + + if (ret < 0) + { + ret = -errno; } return ret; @@ -216,7 +229,7 @@ bool host_uart_checkin(int fd) pfd.fd = fd; pfd.events = POLLIN; - return host_uninterruptible(poll, &pfd, 1, 0) == 1; + return poll(&pfd, 1, 0) == 1; } /**************************************************************************** @@ -229,7 +242,7 @@ bool host_uart_checkout(int fd) pfd.fd = fd; pfd.events = POLLOUT; - return host_uninterruptible(poll, &pfd, 1, 0) == 1; + return poll(&pfd, 1, 0) == 1; } /**************************************************************************** diff --git a/arch/sim/src/sim/posix/sim_hostusrsock.c b/arch/sim/src/sim/posix/sim_hostusrsock.c index 6c5f8a897acee..4ba0fb0dafa54 100644 --- a/arch/sim/src/sim/posix/sim_hostusrsock.c +++ b/arch/sim/src/sim/posix/sim_hostusrsock.c @@ -188,7 +188,7 @@ static int optname_to_native(int optname) default: syslog(LOG_ERR, "Invalid optname: %x\n", optname); - return -1; + return -ENOPROTOOPT; } } @@ -198,6 +198,10 @@ static int host_usrsock_sockopt(int sockfd, int level, int optname, { int ret = -EINVAL; + /* For the parameters that nuttx does not support, + * return the ENOPROTOOPT. + */ + if (level == NUTTX_SOL_SOCKET) { level = SOL_SOCKET; @@ -216,13 +220,13 @@ static int host_usrsock_sockopt(int sockfd, int level, int optname, } else { - return ret; + return -ENOPROTOOPT; } optname = optname_to_native(optname); if (optname < 0) { - return ret; + return optname; } if (set) @@ -263,6 +267,10 @@ int host_usrsock_socket(int domain, int type, int protocol) { type = SOCK_DGRAM; } + else if (type == NUTTX_SOCK_RAW) + { + type = SOCK_RAW; + } else { return -EINVAL; diff --git a/arch/sim/src/sim/posix/sim_rawgadget.c b/arch/sim/src/sim/posix/sim_rawgadget.c index e9bf63f17f431..b0164e9cf6ab8 100644 --- a/arch/sim/src/sim/posix/sim_rawgadget.c +++ b/arch/sim/src/sim/posix/sim_rawgadget.c @@ -325,7 +325,7 @@ static void host_raw_init(int fd, enum usb_device_speed speed, static int host_raw_run(int fd) { - int rv = host_uninterruptible_errno(ioctl, fd, USB_RAW_IOCTL_RUN, 0); + int rv = host_uninterruptible(ioctl, fd, USB_RAW_IOCTL_RUN, 0); if (rv < 0) { ERROR("ioctl(USB_RAW_IOCTL_RUN) fail"); diff --git a/arch/sim/src/sim/sim_initialize.c b/arch/sim/src/sim/sim_initialize.c index f736c8415ff34..45584ed8ed339 100644 --- a/arch/sim/src/sim/sim_initialize.c +++ b/arch/sim/src/sim/sim_initialize.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -51,13 +52,19 @@ #if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ defined(CONFIG_SIM_BUTTONS) -static struct wdog_s g_x11event_wdog; /* Watchdog for event loop */ +static struct work_s g_x11event_work; /* Watchdog for event loop */ #endif #ifdef CONFIG_SIM_X11FB -static struct wdog_s g_x11update_wdog; /* Watchdog for update loop */ +static struct work_s g_x11update_work; /* Watchdog for update loop */ #endif +/**************************************************************************** + * Public Data + ****************************************************************************/ + +struct kwork_wqueue_s *g_work_queue; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -88,11 +95,11 @@ static void sim_init_cmdline(void) #if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ defined(CONFIG_SIM_BUTTONS) -static void sim_x11event_interrupt(wdparm_t arg) +static void sim_x11event_work(void *arg) { sim_x11events(); - wd_start_next((FAR struct wdog_s *)arg, SIM_X11EVENT_PERIOD, - sim_x11event_interrupt, arg); + work_queue_next_wq(g_work_queue, &g_x11event_work, sim_x11event_work, + NULL, SIM_X11EVENT_PERIOD); } #endif @@ -105,11 +112,11 @@ static void sim_x11event_interrupt(wdparm_t arg) ****************************************************************************/ #ifdef CONFIG_SIM_X11FB -static void sim_x11update_interrupt(wdparm_t arg) +static void sim_x11update_work(void *arg) { sim_x11loop(); - wd_start_next((FAR struct wdog_s *)arg, SIM_X11UPDATE_PERIOD, - sim_x11update_interrupt, arg); + work_queue_next_wq(g_work_queue, &g_x11update_work, sim_x11update_work, + NULL, SIM_X11UPDATE_PERIOD); } #endif @@ -317,12 +324,31 @@ void up_initialize(void) #if defined(CONFIG_SIM_TOUCHSCREEN) || defined(CONFIG_SIM_AJOYSTICK) || \ defined(CONFIG_SIM_BUTTONS) - wd_start(&g_x11event_wdog, 0, sim_x11event_interrupt, - (wdparm_t)&g_x11event_wdog); + work_queue_wq(g_work_queue, &g_x11event_work, sim_x11event_work, + NULL, SIM_X11EVENT_PERIOD); #endif #ifdef CONFIG_SIM_X11FB - wd_start(&g_x11update_wdog, 0, sim_x11update_interrupt, - (wdparm_t)&g_x11update_wdog); + work_queue_wq(g_work_queue, &g_x11update_work, sim_x11update_work, + NULL, SIM_X11UPDATE_PERIOD); #endif } + +/**************************************************************************** + * Name: up_irqinitialize + * + * Description: + * initialize the high-priority work queue used for handling + * periodic or async tasks within the simulator, then invokes the + * platform-specific IRQ initialize. + * + ****************************************************************************/ + +void up_irqinitialize(void) +{ + g_work_queue = work_queue_create("sim_loop_wq", + CONFIG_SCHED_HPWORKPRIORITY, NULL, + CONFIG_SCHED_HPWORKSTACKSIZE, 1u); + + host_irqinitialize(); +} diff --git a/arch/sim/src/sim/sim_internal.h b/arch/sim/src/sim/sim_internal.h index 68247ebb7da56..1db555c4140e6 100644 --- a/arch/sim/src/sim/sim_internal.h +++ b/arch/sim/src/sim/sim_internal.h @@ -107,12 +107,6 @@ #define sim_savestate(regs) sim_copyfullstate(regs, up_current_regs()) #define sim_restorestate(regs) up_set_current_regs(regs) -/* Provide a common interface, which should have different conversions - * on different platforms. - */ - -#define host_errno_convert(errcode) (errcode) - #define sim_saveusercontext(saveregs, ret) \ do \ { \ @@ -123,6 +117,7 @@ val[0] = flags & UINT32_MAX; \ val[1] = (flags >> 32) & UINT32_MAX; \ \ + env[JB_ERRNO] = host_errno_get(); \ ret = setjmp(saveregs); \ } \ while (0) @@ -134,6 +129,8 @@ uint32_t *flags = (uint32_t *)&env[JB_FLAG]; \ \ up_irq_restore(((uint64_t)flags[1] << 32) | flags[0]); \ + \ + host_errno_set(env[JB_ERRNO]); \ longjmp(env, 1); \ } \ while (0) @@ -155,18 +152,6 @@ } \ while (0) -#define host_uninterruptible_errno(func, ...) \ - ({ \ - uint64_t flags_ = up_irq_save(); \ - typeof(func(__VA_ARGS__)) ret_ = func(__VA_ARGS__); \ - if (ret_ < 0) \ - { \ - ret_ = host_errno_convert(-errno); \ - } \ - up_irq_restore(flags_); \ - ret_; \ - }) - /* File System Definitions **************************************************/ /* These definitions characterize the compressed filesystem image */ @@ -213,6 +198,7 @@ struct i2c_master_s; extern int g_argc; extern char **g_argv; +extern struct kwork_wqueue_s *g_work_queue; /**************************************************************************** * Public Function Prototypes @@ -227,6 +213,16 @@ void sim_copyfullstate(xcpt_reg_t *dest, xcpt_reg_t *src); void *sim_doirq(int irq, void *regs); void sim_unlock(void); +/* sim_errno.c */ + +int host_errno_convert(int errcode); +int host_errno_get(void); +void host_errno_set(int errcode); + +/* sim_hostirq.c ************************************************************/ + +void host_irqinitialize(void); + /* sim_hostmisc.c ***********************************************************/ void host_abort(int status); diff --git a/arch/sim/src/sim/sim_netdriver.c b/arch/sim/src/sim/sim_netdriver.c index 4dfef8da682e1..535b4e3c86db3 100644 --- a/arch/sim/src/sim/sim_netdriver.c +++ b/arch/sim/src/sim/sim_netdriver.c @@ -70,8 +70,10 @@ #include #include #include +#include #include "sim_internal.h" +#include "sim_wifihost.h" #define SIM_NETDEV_BUFSIZE (CONFIG_SIM_NETDEV_MTU + ETH_HDRLEN + \ CONFIG_NET_GUARDSIZE) @@ -90,20 +92,24 @@ #define DEVIDX(p) ((struct sim_netdev_s *)(p) - g_sim_dev) #define DEVBUF(p) (((struct sim_netdev_s *)(p))->buf) -#if CONFIG_SIM_WIFIDEV_NUMBER != 0 -# include "sim_wifidriver.c" -#else +#define IDXDEV(i) ((struct netdev_lowerhalf_s *)(&g_sim_dev[i].dev)) + /**************************************************************************** * Private Types ****************************************************************************/ struct sim_netdev_s { +#if defined(CONFIG_SIM_WIFIDEV_HOST) + struct sim_wifihost_lowerhalf_s dev; +#elif defined(CONFIG_SIM_WIFIDEV_PSEUDO) + struct wifi_sim_lowerhalf_s dev; +#else struct netdev_lowerhalf_s dev; +#endif uint8_t buf[SIM_NETDEV_BUFSIZE]; /* Used when packet buffer is fragmented */ - struct wdog_s wdog; + struct work_s work; }; -#endif /**************************************************************************** * Private Function Prototypes @@ -211,7 +217,11 @@ static int netdriver_ifup(struct netdev_lowerhalf_s *dev) #if CONFIG_SIM_WIFIDEV_NUMBER != 0 if (DEVIDX(dev) < CONFIG_SIM_WIFIDEV_NUMBER) { - if (wifidriver_connected(dev)) +# if defined(CONFIG_SIM_WIFIDEV_HOST) + if (sim_wifihost_connected((struct sim_wifihost_lowerhalf_s *)dev)) +# elif defined(CONFIG_SIM_WIFIDEV_PSEUDO) + if (wifi_sim_connected((struct wifi_sim_lowerhalf_s *)dev)) +# endif { netdev_lower_carrier_on(dev); } @@ -258,7 +268,7 @@ static void netdriver_rxready_interrupt(void *priv) netdev_lower_rxready(dev); } -static void sim_netdev_interrupt(wdparm_t arg) +static void sim_netdev_work(void *arg) { struct sim_netdev_s *priv = (struct sim_netdev_s *)arg; struct netdev_lowerhalf_s *dev = &priv->dev; @@ -268,8 +278,8 @@ static void sim_netdev_interrupt(wdparm_t arg) netdev_lower_rxready(dev); } - wd_start_next(&priv->wdog, SIM_NETDEV_PERIOD, - sim_netdev_interrupt, arg); + work_queue_next_wq(g_work_queue, &priv->work, sim_netdev_work, arg, + SIM_NETDEV_PERIOD); } /**************************************************************************** @@ -283,7 +293,7 @@ int sim_netdriver_init(void) for (devidx = 0; devidx < CONFIG_SIM_NETDEV_NUMBER; devidx++) { - dev = &g_sim_dev[devidx].dev; + dev = IDXDEV(devidx); /* Internal initialization */ @@ -300,7 +310,17 @@ int sim_netdriver_init(void) #if CONFIG_SIM_WIFIDEV_NUMBER != 0 if (devidx < CONFIG_SIM_WIFIDEV_NUMBER) { - wifidriver_init(dev, devidx); + int ret = +# if defined(CONFIG_SIM_WIFIDEV_HOST) + sim_wifihost_init((struct sim_wifihost_lowerhalf_s *)dev, + devidx); +# elif defined(CONFIG_SIM_WIFIDEV_PSEUDO) + wifi_sim_init((struct wifi_sim_lowerhalf_s *)dev); +# endif + if (ret < 0) + { + return ret; + } } #endif @@ -310,8 +330,9 @@ int sim_netdriver_init(void) netdev_lower_register(dev, devidx < CONFIG_SIM_WIFIDEV_NUMBER ? NET_LL_IEEE80211 : NET_LL_ETHERNET); - wd_start(&g_sim_dev[devidx].wdog, 0, - sim_netdev_interrupt, (wdparm_t)&g_sim_dev[devidx]); + work_queue_wq(g_work_queue, &g_sim_dev[devidx].work, + sim_netdev_work, &g_sim_dev[devidx], + SIM_NETDEV_PERIOD); } return OK; @@ -319,13 +340,24 @@ int sim_netdriver_init(void) void sim_netdriver_setmacaddr(int devidx, unsigned char *macaddr) { - memcpy(g_sim_dev[devidx].dev.netdev.d_mac.ether.ether_addr_octet, macaddr, + memcpy(IDXDEV(devidx)->netdev.d_mac.ether.ether_addr_octet, macaddr, IFHWADDRLEN); } void sim_netdriver_setmtu(int devidx, int mtu) { - g_sim_dev[devidx].dev.netdev.d_pktsize = MIN(SIM_NETDEV_BUFSIZE, + IDXDEV(devidx)->netdev.d_pktsize = MIN(SIM_NETDEV_BUFSIZE, mtu + ETH_HDRLEN); } +void sim_netdriver_loop(void) +{ + int devidx; + for (devidx = 0; devidx < CONFIG_SIM_NETDEV_NUMBER; devidx++) + { + if (sim_netdev_avail(devidx)) + { + netdev_lower_rxready(IDXDEV(devidx)); + } + } +} diff --git a/arch/sim/src/sim/sim_rpmsg_virtio.c b/arch/sim/src/sim/sim_rpmsg_virtio.c index fbedcf8bd57c1..e2f6bcfac9b43 100644 --- a/arch/sim/src/sim/sim_rpmsg_virtio.c +++ b/arch/sim/src/sim/sim_rpmsg_virtio.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "sim_internal.h" @@ -67,9 +67,9 @@ struct sim_rpmsg_virtio_dev_s char cpuname[RPMSG_NAME_SIZE + 1]; char shmemname[RPMSG_NAME_SIZE + 1]; - /* Wdog for transmit */ + /* Work for transmit */ - struct wdog_s wdog; + struct work_s work; }; /**************************************************************************** @@ -164,7 +164,7 @@ sim_rpmsg_virtio_register_callback(struct rpmsg_virtio_lite_s *dev, return 0; } -static void sim_rpmsg_virtio_work(wdparm_t arg) +static void sim_rpmsg_virtio_work(void *arg) { struct sim_rpmsg_virtio_dev_s *dev = (struct sim_rpmsg_virtio_dev_s *)arg; @@ -189,8 +189,8 @@ static void sim_rpmsg_virtio_work(wdparm_t arg) } } - wd_start(&dev->wdog, SIM_RPMSG_VIRTIO_WORK_DELAY, - sim_rpmsg_virtio_work, (wdparm_t)dev); + work_queue_next_wq(g_work_queue, &dev->work, sim_rpmsg_virtio_work, dev, + SIM_RPMSG_VIRTIO_WORK_DELAY); } static int sim_rpmsg_virtio_notify(struct rpmsg_virtio_lite_s *dev, @@ -252,5 +252,6 @@ int sim_rpmsg_virtio_init(const char *shmemname, const char *cpuname, return ret; } - return wd_start(&priv->wdog, 0, sim_rpmsg_virtio_work, (wdparm_t)priv); + return work_queue_wq(g_work_queue, &priv->work, sim_rpmsg_virtio_work, + priv, 0); } diff --git a/arch/sim/src/sim/sim_rptun.c b/arch/sim/src/sim/sim_rptun.c index 5295cab5f5e5f..f8641146eab6d 100644 --- a/arch/sim/src/sim/sim_rptun.c +++ b/arch/sim/src/sim/sim_rptun.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include "sim_internal.h" @@ -74,9 +74,9 @@ struct sim_rptun_dev_s char shmemname[RPMSG_NAME_SIZE + 1]; pid_t pid; - /* Wdog for transmit */ + /* Work for transmit */ - struct wdog_s wdog; + struct work_s work; }; /**************************************************************************** @@ -327,7 +327,7 @@ static void sim_rptun_check_reset(struct sim_rptun_dev_s *priv) } } -static void sim_rptun_work(wdparm_t arg) +static void sim_rptun_work(void *arg) { struct sim_rptun_dev_s *dev = (struct sim_rptun_dev_s *)arg; @@ -358,7 +358,8 @@ static void sim_rptun_work(wdparm_t arg) } } - wd_start(&dev->wdog, SIM_RPTUN_WORK_DELAY, sim_rptun_work, (wdparm_t)dev); + work_queue_next_wq(g_work_queue, &dev->work, sim_rptun_work, dev, + SIM_RPTUN_WORK_DELAY); } /**************************************************************************** @@ -405,5 +406,5 @@ int sim_rptun_init(const char *shmemname, const char *cpuname, int master) return ret; } - return wd_start(&dev->wdog, 0, sim_rptun_work, (wdparm_t)dev); + return work_queue_wq(g_work_queue, &dev->work, sim_rptun_work, dev, 0); } diff --git a/arch/sim/src/sim/sim_usbdev.c b/arch/sim/src/sim/sim_usbdev.c index f3a48196323ac..19a4a5a0def77 100644 --- a/arch/sim/src/sim/sim_usbdev.c +++ b/arch/sim/src/sim/sim_usbdev.c @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include #include @@ -159,7 +159,7 @@ struct sim_usbdev_s uint16_t epavail; /* Bitset of available endpoints */ struct sim_ep_s eps[SIM_USB_EPNUM]; spinlock_t lock; /* Spinlock */ - struct wdog_s wdog; /* Watchdog for event loop */ + struct work_s work; /* Work for event loop */ }; struct sim_req_s @@ -1045,7 +1045,7 @@ static void sim_usbdev_devinit(struct sim_usbdev_s *dev) dev->epavail = SIM_EPSET_NOEP0; } -static void sim_usbdev_interrupt(wdparm_t arg) +static void sim_usbdev_work(void *arg) { struct sim_usbdev_s *priv = (struct sim_usbdev_s *)arg; struct sim_ep_s *privep; @@ -1080,7 +1080,8 @@ static void sim_usbdev_interrupt(wdparm_t arg) } } - wd_start_next(&priv->wdog, SIM_USB_PERIOD, sim_usbdev_interrupt, arg); + work_queue_next_wq(g_work_queue, &priv->work, sim_usbdev_work, priv, + SIM_USB_PERIOD); } /**************************************************************************** @@ -1138,7 +1139,8 @@ int usbdev_register(struct usbdevclass_driver_s *driver) #endif } - wd_start(&priv->wdog, 0, sim_usbdev_interrupt, (wdparm_t)priv); + work_queue_wq(g_work_queue, &priv->work, sim_usbdev_work, priv, + SIM_USB_PERIOD); return ret; } diff --git a/arch/sim/src/sim/sim_usbhost.c b/arch/sim/src/sim/sim_usbhost.c index 4f3df26b19829..000d08b97553d 100644 --- a/arch/sim/src/sim/sim_usbhost.c +++ b/arch/sim/src/sim/sim_usbhost.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "sim_usbhost.h" #include "sim_internal.h" @@ -111,7 +112,7 @@ struct sim_usbhost_s sem_t pscsem; /* Semaphore to wait for port status change events */ struct usbhost_devaddr_s devgen; /* Address generation data */ - struct wdog_s wdog; + struct work_s work; }; /**************************************************************************** @@ -709,10 +710,10 @@ static void sim_usbhost_rqcomplete(struct sim_usbhost_s *drvr) } /**************************************************************************** - * Name: sim_usbhost_interrupt + * Name: sim_usbhost_work ****************************************************************************/ -static void sim_usbhost_interrupt(wdparm_t arg) +static void sim_usbhost_work(void *arg) { struct sim_usbhost_s *priv = (struct sim_usbhost_s *)arg; struct usbhost_hubport_s *hport; @@ -778,7 +779,8 @@ static void sim_usbhost_interrupt(wdparm_t arg) } } - wd_start_next(&priv->wdog, SIM_USBHOST_PERIOD, sim_usbhost_interrupt, arg); + work_queue_next_wq(g_work_queue, &priv->work, sim_usbhost_work, priv, + SIM_USBHOST_PERIOD); } /**************************************************************************** @@ -851,7 +853,8 @@ int sim_usbhost_initialize(void) return -ENODEV; } - wd_start(&priv->wdog, 0, sim_usbhost_interrupt, (wdparm_t)priv); + work_queue_wq(g_work_queue, &priv->work, sim_usbhost_work, priv, + SIM_USBHOST_PERIOD); return OK; } diff --git a/arch/sim/src/sim/sim_usrsock.c b/arch/sim/src/sim/sim_usrsock.c index 8605890fc8a18..17ce01baa4e98 100644 --- a/arch/sim/src/sim/sim_usrsock.c +++ b/arch/sim/src/sim/sim_usrsock.c @@ -32,7 +32,9 @@ #include #include +#include +#include "sim_internal.h" #include "sim_hostusrsock.h" /**************************************************************************** @@ -395,8 +397,8 @@ static const usrsock_handler_t g_usrsock_handler[] = static void sim_usrsock_work(void *arg) { - work_queue(HPWORK, &g_usrsock.work, (void *)sim_usrsock_work, - NULL, SIM_USRSOCK_PERIOD); + work_queue_next_wq(g_work_queue, &g_usrsock.work, sim_usrsock_work, + NULL, SIM_USRSOCK_PERIOD); } /**************************************************************************** @@ -410,8 +412,8 @@ int usrsock_event_callback(int16_t usockid, uint16_t events) void usrsock_register(void) { - work_queue(HPWORK, &g_usrsock.work, (void *)sim_usrsock_work, - NULL, SIM_USRSOCK_PERIOD); + work_queue_wq(g_work_queue, &g_usrsock.work, sim_usrsock_work, + NULL, SIM_USRSOCK_PERIOD); } /**************************************************************************** diff --git a/arch/sim/src/sim/sim_wifidriver.c b/arch/sim/src/sim/sim_wifihost.c similarity index 91% rename from arch/sim/src/sim/sim_wifidriver.c rename to arch/sim/src/sim/sim_wifihost.c index 16036860e332e..5d45177167e50 100644 --- a/arch/sim/src/sim/sim_wifidriver.c +++ b/arch/sim/src/sim/sim_wifihost.c @@ -1,7 +1,6 @@ /**************************************************************************** - * arch/sim/src/sim/sim_wifidriver.c - * - * SPDX-License-Identifier: Apache-2.0 + * arch/sim/src/sim/sim_wifihost.c + * Manage the host wireless * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -35,6 +34,7 @@ #include #include "sim_internal.h" +#include "sim_wifihost.h" /**************************************************************************** * Pre-processor Definitions @@ -105,6 +105,9 @@ ret__; \ }) +#define NETDEV2WIFI(dev) \ + ((struct sim_wifi_s *)((struct sim_wifihost_lowerhalf_s *)dev)->wifi) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -155,10 +158,9 @@ struct sim_bss_info_s int16_t snr; /* average SNR of during frame reception */ }; -struct sim_netdev_s +struct sim_wifi_s { - struct netdev_lowerhalf_s dev; - uint8_t buf[SIM_NETDEV_BUFSIZE]; /* Used when packet buffer is fragmented */ + struct netdev_lowerhalf_s *dev; char ssid[SSID_MAX_LEN]; char bssid[ETH_ALEN]; uint16_t channel; @@ -257,7 +259,7 @@ static const struct wireless_ops_s g_iw_ops = * Private Functions ****************************************************************************/ -static int get_cmd_result_num(struct sim_netdev_s *wifidev, char *cmd) +static int get_cmd_result_num(struct sim_wifi_s *wifidev, char *cmd) { int num = 0; char rbuf[BUF_LEN]; @@ -277,21 +279,21 @@ static int get_cmd_result_num(struct sim_netdev_s *wifidev, char *cmd) /* For sta, add an available network. */ -static int wpa_add_network(struct sim_netdev_s *wifidev) +static int wpa_add_network(struct sim_wifi_s *wifidev) { return get_cmd_result_num(wifidev, "add_network"); } /* For sta, get the number of available networks. */ -static int wpa_get_network_num(struct sim_netdev_s *wifidev) +static int wpa_get_network_num(struct sim_wifi_s *wifidev) { return get_cmd_result_num(wifidev, "list_network | grep \"\\[\" | wc -l"); } /* For sta, get the available network_id. */ -static int wpa_get_last_network_id(struct sim_netdev_s *wifidev, +static int wpa_get_last_network_id(struct sim_wifi_s *wifidev, int network_num) { int num; @@ -823,7 +825,7 @@ static int get_bss_info(struct sim_bss_info_s *bss_info, char *buf, int len) return OK; } -static int get_scan_results(struct sim_netdev_s *wifidev, +static int get_scan_results(struct sim_wifi_s *wifidev, struct sim_scan_result_s *scan_reqs) { int ret; @@ -898,7 +900,7 @@ static int get_scan_results(struct sim_netdev_s *wifidev, return ret; } -static bool get_wpa_state(struct sim_netdev_s *wifidev) +static bool get_wpa_state(struct sim_wifi_s *wifidev) { int ret; char rbuf[BUF_LEN]; @@ -914,7 +916,7 @@ static bool get_wpa_state(struct sim_netdev_s *wifidev) return false; } -static bool get_wpa_bssid(struct sim_netdev_s *wifidev, +static bool get_wpa_bssid(struct sim_wifi_s *wifidev, unsigned char *bssid) { int ret; @@ -931,7 +933,7 @@ static bool get_wpa_bssid(struct sim_netdev_s *wifidev, return false; } -static bool get_wpa_rssi(struct sim_netdev_s *wifidev, int32_t *rssi) +static bool get_wpa_rssi(struct sim_wifi_s *wifidev, int32_t *rssi) { int ret; char rbuf[BUF_LEN]; @@ -948,14 +950,14 @@ static bool get_wpa_rssi(struct sim_netdev_s *wifidev, int32_t *rssi) return false; } -static void get_wpa_ssid(struct sim_netdev_s *wifidev, +static void get_wpa_ssid(struct sim_wifi_s *wifidev, struct iw_point *essid) { essid->length = strlen(wifidev->ssid); strlcpy(essid->pointer, wifidev->ssid, essid->length + 1); } -static int get_wpa_freq(struct sim_netdev_s *wifidev) +static int get_wpa_freq(struct sim_wifi_s *wifidev) { return get_cmd_result_num(wifidev, "status | grep freq | awk -F'=' '{print $2}'"); @@ -1075,7 +1077,7 @@ static int wifi_send_event(struct net_driver_s *dev, unsigned int cmd, return OK; } -static int wifidriver_start_scan(struct sim_netdev_s *wifidev, +static int wifidriver_start_scan(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret; @@ -1110,7 +1112,7 @@ static int wifidriver_start_scan(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_scan_result(struct sim_netdev_s *wifidev, +static int wifidriver_scan_result(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { struct sim_scan_result_s scan_req; @@ -1139,7 +1141,7 @@ static int wifidriver_scan_result(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_set_auth(struct sim_netdev_s *wifidev, +static int wifidriver_set_auth(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret = 0; @@ -1210,7 +1212,7 @@ static int wifidriver_set_auth(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_get_auth(struct sim_netdev_s *wifidev, +static int wifidriver_get_auth(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret = 0; @@ -1233,7 +1235,7 @@ static int wifidriver_get_auth(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_set_psk(struct sim_netdev_s *wifidev, +static int wifidriver_set_psk(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { struct iw_encode_ext *ext; @@ -1287,7 +1289,7 @@ static int wifidriver_set_psk(struct sim_netdev_s *wifidev, return ret ; } -static int wifidriver_get_psk(struct sim_netdev_s *wifidev, +static int wifidriver_get_psk(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { struct iw_encode_ext *ext; @@ -1323,7 +1325,7 @@ static int wifidriver_get_psk(struct sim_netdev_s *wifidev, return ret ; } -static int wifidriver_set_essid(struct sim_netdev_s *wifidev, +static int wifidriver_set_essid(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { char ssid_buf[SSID_MAX_LEN]; @@ -1379,7 +1381,7 @@ static int wifidriver_set_essid(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_get_essid(struct sim_netdev_s *wifidev, +static int wifidriver_get_essid(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret = 0; @@ -1414,7 +1416,7 @@ static int wifidriver_get_essid(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_set_bssid(struct sim_netdev_s *wifidev, +static int wifidriver_set_bssid(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret = 0; @@ -1453,7 +1455,7 @@ static int wifidriver_set_bssid(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_get_bssid(struct sim_netdev_s *wifidev, +static int wifidriver_get_bssid(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { struct sockaddr *sockaddr = &pwrq->u.ap_addr; @@ -1485,7 +1487,7 @@ static int wifidriver_get_bssid(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_start_connect(struct sim_netdev_s *wifidev) +static int wifidriver_start_connect(struct sim_wifi_s *wifidev) { int timeout = 10; @@ -1519,7 +1521,7 @@ static int wifidriver_start_connect(struct sim_netdev_s *wifidev) memset(&wrqu, 0, sizeof(wrqu)); memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); - wifi_send_event(&wifidev->dev.netdev, SIOCGIWAP, &wrqu); + wifi_send_event(&wifidev->dev->netdev, SIOCGIWAP, &wrqu); return OK; } @@ -1544,7 +1546,7 @@ static int wifidriver_start_connect(struct sim_netdev_s *wifidev) return OK; } -static int wifidriver_start_disconnect(struct sim_netdev_s *wifidev) +static int wifidriver_start_disconnect(struct sim_wifi_s *wifidev) { int ret; @@ -1564,14 +1566,14 @@ static int wifidriver_start_disconnect(struct sim_netdev_s *wifidev) return ret; } -static int wifidriver_get_mode(struct sim_netdev_s *wifidev, +static int wifidriver_get_mode(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { pwrq->u.mode = wifidev->mode; return OK; } -static int wifidriver_set_mode(struct sim_netdev_s *wifidev, +static int wifidriver_set_mode(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int ret; @@ -1638,7 +1640,7 @@ static int wifidriver_set_mode(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_set_country(struct sim_netdev_s *wifidev, +static int wifidriver_set_country(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { char country[4] = @@ -1658,7 +1660,7 @@ static int wifidriver_set_country(struct sim_netdev_s *wifidev, return set_cmd(wifidev, "set country %s", country); } -static int wifidriver_get_country(struct sim_netdev_s *wifidev, +static int wifidriver_get_country(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { char country[128]; @@ -1696,7 +1698,7 @@ static int wifidriver_get_country(struct sim_netdev_s *wifidev, return ret; } -static int wifidriver_get_sensitivity(struct sim_netdev_s *wifidev, +static int wifidriver_get_sensitivity(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int32_t rssi; @@ -1722,7 +1724,7 @@ static int wifidriver_get_sensitivity(struct sim_netdev_s *wifidev, return ret; } -int wifidriver_set_freq(struct sim_netdev_s *wifidev, struct iwreq *pwrq) +int wifidriver_set_freq(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int channel; int ret = 0; @@ -1747,7 +1749,7 @@ int wifidriver_set_freq(struct sim_netdev_s *wifidev, struct iwreq *pwrq) return ret; } -static int wifidriver_get_freq(struct sim_netdev_s *wifidev, +static int wifidriver_get_freq(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { switch (wifidev->mode) @@ -1775,7 +1777,7 @@ static int wifidriver_get_freq(struct sim_netdev_s *wifidev, return OK; } -static int wifidriver_get_range(struct sim_netdev_s *wifidev, +static int wifidriver_get_range(struct sim_wifi_s *wifidev, struct iwreq *pwrq) { int k; @@ -1798,7 +1800,7 @@ static int wifidriver_connect(struct netdev_lowerhalf_s *dev) { int ret; - ret = wifidriver_start_connect((struct sim_netdev_s *)dev); + ret = wifidriver_start_connect(NETDEV2WIFI(dev)); if (ret >= 0) { netdev_lower_carrier_on(dev); @@ -1812,7 +1814,7 @@ static int wifidriver_disconnect(struct netdev_lowerhalf_s *dev) int ret; union iwreq_data wrqu; - ret = wifidriver_start_disconnect((struct sim_netdev_s *)dev); + ret = wifidriver_start_disconnect(NETDEV2WIFI(dev)); if (ret >= 0) { netdev_lower_carrier_off(dev); @@ -1827,7 +1829,7 @@ static int wifidriver_disconnect(struct netdev_lowerhalf_s *dev) static int wifidriver_essid(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1843,7 +1845,7 @@ static int wifidriver_bssid(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { int ret; - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1866,18 +1868,18 @@ static int wifidriver_passwd(struct netdev_lowerhalf_s *dev, { if (set) { - return wifidriver_set_psk((struct sim_netdev_s *)dev, iwr); + return wifidriver_set_psk(NETDEV2WIFI(dev), iwr); } else { - return wifidriver_get_psk((struct sim_netdev_s *)dev, iwr); + return wifidriver_get_psk(NETDEV2WIFI(dev), iwr); } } static int wifidriver_mode(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1892,7 +1894,7 @@ static int wifidriver_mode(struct netdev_lowerhalf_s *dev, static int wifidriver_auth(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1907,7 +1909,7 @@ static int wifidriver_auth(struct netdev_lowerhalf_s *dev, static int wifidriver_freq(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1934,7 +1936,7 @@ static int wifidriver_txpower(struct netdev_lowerhalf_s *dev, static int wifidriver_country(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1949,7 +1951,7 @@ static int wifidriver_country(struct netdev_lowerhalf_s *dev, static int wifidriver_sensitivity(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1964,7 +1966,7 @@ static int wifidriver_sensitivity(struct netdev_lowerhalf_s *dev, static int wifidriver_scan(struct netdev_lowerhalf_s *dev, struct iwreq *iwr, bool set) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = NETDEV2WIFI(dev); if (set) { @@ -1979,12 +1981,20 @@ static int wifidriver_scan(struct netdev_lowerhalf_s *dev, static int wifidriver_range(struct netdev_lowerhalf_s *dev, struct iwreq *iwr) { - return wifidriver_get_range((struct sim_netdev_s *)dev, iwr); + return wifidriver_get_range(NETDEV2WIFI(dev), iwr); } -static bool wifidriver_connected(struct netdev_lowerhalf_s *dev) +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sim_wifihost_connected + ****************************************************************************/ + +bool sim_wifihost_connected(struct sim_wifihost_lowerhalf_s *dev) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *wifidev = (struct sim_wifi_s *)dev->wifi; if (wifidev->mode == IW_MODE_MASTER) { @@ -1998,21 +2008,36 @@ static bool wifidriver_connected(struct netdev_lowerhalf_s *dev) return false; } -static void wifidriver_init(struct netdev_lowerhalf_s *dev, int devidx) +/**************************************************************************** + * Name: sim_wifihost_init + ****************************************************************************/ + +int sim_wifihost_init(struct sim_wifihost_lowerhalf_s *dev, int devidx) { - struct sim_netdev_s *wifidev = (struct sim_netdev_s *)dev; + struct sim_wifi_s *priv; - wifidev->mode = IW_MODE_AUTO; - wifidev->devidx = devidx; + priv = kmm_zalloc(sizeof(*priv)); + if (priv == NULL) + { + nerr("wifi driver priv alloc failed\n"); + return -ENOMEM; + } + + dev->wifi = priv; + priv->dev = &dev->lower; + priv->mode = IW_MODE_AUTO; + priv->devidx = devidx; + + /* Bind the wireless ops interfaces. */ + + dev->lower.iw_ops = &g_iw_ops; /* The default host wlan interface name is corresponding to the nuttx * wlan interface name. If not, should modify the host wlan interface * name. */ - snprintf(wifidev->host_ifname, IFNAMSIZ, "wlan%d", devidx); + snprintf(priv->host_ifname, IFNAMSIZ, "wlan%d", devidx); - /* Bind the wireless ops interfaces. */ - - dev->iw_ops = &g_iw_ops; + return OK; } diff --git a/arch/sim/src/sim/sim_wifihost.h b/arch/sim/src/sim/sim_wifihost.h new file mode 100644 index 0000000000000..8c2c0d90b4f6a --- /dev/null +++ b/arch/sim/src/sim/sim_wifihost.h @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/sim/src/sim/sim_wifihost.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_SIM_SRC_SIM_WIFIHOST_H +#define __ARCH_SIM_SRC_SIM_WIFIHOST_H + +#if CONFIG_SIM_WIFIDEV_NUMBER != 0 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +struct sim_wifihost_lowerhalf_s +{ + /* This holds the information visible to the NuttX network */ + + struct netdev_lowerhalf_s lower; /* The netdev lowerhalf */ + + void *wifi; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int sim_wifihost_init(struct sim_wifihost_lowerhalf_s *dev, int devidx); +bool sim_wifihost_connected(struct sim_wifihost_lowerhalf_s *dev); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_DRIVERS_WIFI_SIM */ +#endif /* __ARCH_SIM_SRC_SIM_WIFIHOST_H */ diff --git a/arch/sim/src/sim/win/sim_errno.c b/arch/sim/src/sim/win/sim_errno.c new file mode 100644 index 0000000000000..b416b5d14e113 --- /dev/null +++ b/arch/sim/src/sim/win/sim_errno.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * arch/sim/src/sim/win/sim_errno.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int host_errno_convert(int errcode) +{ + return errcode; +} + +int host_errno_get(void) +{ + return errno; +} + +void host_errno_set(int errcode) +{ + errno = errcode; +} diff --git a/arch/sim/src/sim/win/sim_hostirq.c b/arch/sim/src/sim/win/sim_hostirq.c index 2945f33eed501..3db2b92a1fd27 100644 --- a/arch/sim/src/sim/win/sim_hostirq.c +++ b/arch/sim/src/sim/win/sim_hostirq.c @@ -80,14 +80,6 @@ void up_irq_restore(uint64_t flags) { } -/**************************************************************************** - * Name: up_irqinitialize - ****************************************************************************/ - -void up_irqinitialize(void) -{ -} - /**************************************************************************** * Name: up_enable_irq * @@ -111,3 +103,11 @@ void up_enable_irq(int irq) void up_disable_irq(int irq) { } + +/**************************************************************************** + * Name: host_irqinitialize + ****************************************************************************/ + +void host_irqinitialize(void) +{ +} diff --git a/arch/sparc/src/bm3803/bm3803_tickless.c b/arch/sparc/src/bm3803/bm3803_tickless.c index 121d506772e96..b7e100bfc12f8 100644 --- a/arch/sparc/src/bm3803/bm3803_tickless.c +++ b/arch/sparc/src/bm3803/bm3803_tickless.c @@ -38,7 +38,7 @@ * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -144,7 +144,7 @@ static struct bm3803_tickless_s g_tickless; static void bm3803_oneshot_handler(void *arg) { tmrinfo("Expired...\n"); - nxsched_timer_expiration(); + nxsched_process_timer(); } /**************************************************************************** @@ -273,7 +273,7 @@ int up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -312,14 +312,14 @@ int up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/tricore/include/inttypes.h b/arch/tricore/include/inttypes.h index d5b5ba723ab38..5e762312f1fd1 100644 --- a/arch/tricore/include/inttypes.h +++ b/arch/tricore/include/inttypes.h @@ -69,14 +69,14 @@ #define PRIx32 "lx" #define PRIx64 "llx" -#define PRIxPTR "x" +#define PRIxPTR "lx" #define PRIX8 "X" #define PRIX16 "X" #define PRIX32 "lX" #define PRIX64 "llX" -#define PRIXPTR "X" +#define PRIXPTR "lX" #define SCNd8 "hhd" #define SCNd16 "hd" diff --git a/arch/tricore/include/irq.h b/arch/tricore/include/irq.h index cedddc410bea0..9f357334229d0 100644 --- a/arch/tricore/include/irq.h +++ b/arch/tricore/include/irq.h @@ -34,6 +34,7 @@ #include #ifndef __ASSEMBLY__ # include +# include #endif /* Include NuttX-specific IRQ definitions */ @@ -73,17 +74,9 @@ extern "C" * Public Data ****************************************************************************/ -/* g_current_regs[] holds a references to the current interrupt level - * register storage structure. If is non-NULL only during interrupt - * processing. Access to g_current_regs[] must be through the macro - * g_current_regs for portability. - */ - -/* For the case of architectures with multiple CPUs, then there must be one - * such value for each processor that can receive an interrupt. - */ +/* g_interrupt_context store irq status */ -EXTERN volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS]; +EXTERN volatile bool g_interrupt_context[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Function Prototypes @@ -155,21 +148,21 @@ void up_irq_restore(irqstate_t flags) * Inline Functions ****************************************************************************/ -static inline_function uintptr_t *up_current_regs(void) -{ -#ifdef CONFIG_SMP - return (uintptr_t *)g_current_regs[up_cpu_index()]; -#else - return (uintptr_t *)g_current_regs[0]; -#endif -} +/**************************************************************************** + * Name: up_set_interrupt_context + * + * Description: + * Set the interrupt handler context. + * + ****************************************************************************/ -static inline_function void up_set_current_regs(uintptr_t *regs) +noinstrument_function +static inline_function void up_set_interrupt_context(bool flag) { #ifdef CONFIG_SMP - g_current_regs[up_cpu_index()] = regs; + g_interrupt_context[up_this_cpu()] = flag; #else - g_current_regs[0] = regs; + g_interrupt_context[0] = flag; #endif } @@ -187,15 +180,14 @@ static inline_function bool up_interrupt_context(void) { #ifdef CONFIG_SMP irqstate_t flags = up_irq_save(); -#endif - - bool ret = up_current_regs() != NULL; + bool ret = g_interrupt_context[up_this_cpu()]; -#ifdef CONFIG_SMP up_irq_restore(flags); -#endif return ret; +#else + return g_interrupt_context[0]; +#endif } /**************************************************************************** @@ -204,21 +196,42 @@ static inline_function bool up_interrupt_context(void) static inline_function uintptr_t up_getusrsp(void *regs) { - uintptr_t *csa = regs; + uintptr_t *csaregs = regs; - while (((uintptr_t)csa & PCXI_UL) == 0) + if (csaregs[REG_LPCXI] & PCXI_UL) { - csa = tricore_csa2addr((uintptr_t)csa); - csa = (uintptr_t *)csa[0]; + csaregs = tricore_csa2addr(csaregs[REG_LPCXI]); + } + else + { + csaregs += TC_CONTEXT_REGS; } - csa = tricore_csa2addr((uintptr_t)csa); - - return csa[REG_SP]; + return csaregs[REG_SP]; } #endif /* __ASSEMBLY__ */ +/**************************************************************************** + * Name: up_switch_context + ****************************************************************************/ + +#define up_switch_context(tcb, rtcb) \ + do { \ + if (!up_interrupt_context()) \ + { \ + sys_call0(SYS_switch_context); \ + } \ + UNUSED(rtcb); \ + } while (0) + +/**************************************************************************** + * Name: up_getusrpc + ****************************************************************************/ + +#define up_getusrpc(regs) \ + (((uint32_t *)((regs) ? (regs) : running_regs()))[REG_UPC]) + #undef EXTERN #ifdef __cplusplus } diff --git a/arch/tricore/include/tc3xx/irq.h b/arch/tricore/include/tc3xx/irq.h index d7b7b399540c4..a9b76965b6875 100644 --- a/arch/tricore/include/tc3xx/irq.h +++ b/arch/tricore/include/tc3xx/irq.h @@ -83,9 +83,10 @@ #define REG_LPC REG_LA11 #define TC_CONTEXT_REGS (16) +#define TC_CONTEXT_SIZE (sizeof(void *) * TC_CONTEXT_REGS) -#define XCPTCONTEXT_REGS (TC_CONTEXT_REGS) -#define XCPTCONTEXT_SIZE (sizeof(void *) * TC_CONTEXT_REGS) +#define XCPTCONTEXT_REGS (TC_CONTEXT_REGS * 2) +#define XCPTCONTEXT_SIZE (sizeof(void *) * XCPTCONTEXT_REGS) #define NR_IRQS (255) diff --git a/arch/tricore/src/common/CMakeLists.txt b/arch/tricore/src/common/CMakeLists.txt index 1183ed621e939..c0f55332edb3a 100644 --- a/arch/tricore/src/common/CMakeLists.txt +++ b/arch/tricore/src/common/CMakeLists.txt @@ -40,7 +40,6 @@ set(SRCS tricore_sigdeliver.c tricore_stackframe.c tricore_svcall.c - tricore_switchcontext.c tricore_tcbinfo.c tricore_trapcall.c tricore_systimer.c diff --git a/arch/tricore/src/common/Make.defs b/arch/tricore/src/common/Make.defs index c3e9c77dd30c2..8dbfbffd42755 100644 --- a/arch/tricore/src/common/Make.defs +++ b/arch/tricore/src/common/Make.defs @@ -41,7 +41,6 @@ CMN_CSRCS += tricore_schedulesigaction.c CMN_CSRCS += tricore_sigdeliver.c CMN_CSRCS += tricore_stackframe.c CMN_CSRCS += tricore_svcall.c -CMN_CSRCS += tricore_switchcontext.c CMN_CSRCS += tricore_tcbinfo.c CMN_CSRCS += tricore_trapcall.c CMN_CSRCS += tricore_systimer.c diff --git a/arch/tricore/src/common/tricore_csa.c b/arch/tricore/src/common/tricore_csa.c index 74dd8931ac8bf..d68ea4ae215f6 100644 --- a/arch/tricore/src/common/tricore_csa.c +++ b/arch/tricore/src/common/tricore_csa.c @@ -64,8 +64,8 @@ uintptr_t *tricore_alloc_csa(uintptr_t pc, uintptr_t sp, __isync(); - memset(pucsa, 0, XCPTCONTEXT_SIZE); - memset(plcsa, 0, XCPTCONTEXT_SIZE); + memset(pucsa, 0, TC_CONTEXT_SIZE); + memset(plcsa, 0, TC_CONTEXT_SIZE); pucsa[REG_SP] = sp; pucsa[REG_PSW] = psw; @@ -82,7 +82,7 @@ uintptr_t *tricore_alloc_csa(uintptr_t pc, uintptr_t sp, plcsa[REG_LPCXI] |= PCXI_PIE; } - return (uintptr_t *)tricore_addr2csa(plcsa); + return plcsa; } /**************************************************************************** diff --git a/arch/tricore/src/common/tricore_doirq.c b/arch/tricore/src/common/tricore_doirq.c index f5d686c3532d4..02da6543d69e5 100644 --- a/arch/tricore/src/common/tricore_doirq.c +++ b/arch/tricore/src/common/tricore_doirq.c @@ -46,8 +46,8 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255) { - struct tcb_s *running_task = g_running_tasks[this_cpu()]; - struct tcb_s *tcb; + struct tcb_s **running_task = &g_running_tasks[this_cpu()]; + struct tcb_s *tcb = this_task(); #ifdef CONFIG_SUPPRESS_INTERRUPTS PANIC(); @@ -56,40 +56,31 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255) uintptr_t *regs; icr.U = __mfcr(CPU_ICR); - regs = (uintptr_t *)__mfcr(CPU_PCXI); + regs = tricore_csa2addr(__mfcr(CPU_PCXI)); - if (running_task != NULL) + if (*running_task != NULL) { - running_task->xcp.regs = regs; + (*running_task)->xcp.regs = regs; } board_autoled_on(LED_INIRQ); /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + up_set_interrupt_context(true); /* Deliver the IRQ */ irq_dispatch(icr.B.CCPN, regs); - /* Check for a context switch. If a context switch occurred, then - * g_current_regs will have a different value than it did on entry. If an - * interrupt level context switch has occurred, then restore the floating - * point state and the establish the correct address environment before - * returning from the interrupt. - */ + /* Check for a context switch. */ - if (regs != up_current_regs()) + if (*running_task != tcb) { - tcb = this_task(); - #ifdef CONFIG_ARCH_ADDRENV /* Make sure that the address environment for the previously * running task is closed down gracefully (data caches dump, @@ -102,31 +93,28 @@ IFX_INTERRUPT_INTERNAL(tricore_doirq, 0, 255) /* Update scheduler parameters */ - nxsched_switch_context(running_task, tcb); + nxsched_switch_context(*running_task, tcb); /* Record the new "running" task when context switch occurred. * g_running_tasks[] is only used by assertion logic for reporting * crashes. */ - running_task = tcb; - g_running_tasks[this_cpu()] = running_task; + *running_task = tcb; - __mtcr(CPU_PCXI, (uintptr_t)up_current_regs()); + __mtcr(CPU_PCXI, tricore_addr2csa(tcb->xcp.regs)); __isync(); } - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + up_set_interrupt_context(false); /* running_task->xcp.regs is about to become invalid * and will be marked as NULL to avoid misusage. */ - running_task->xcp.regs = NULL; + (*running_task)->xcp.regs = NULL; board_autoled_off(LED_INIRQ); #endif } diff --git a/arch/tricore/src/common/tricore_exit.c b/arch/tricore/src/common/tricore_exit.c index ffa58ddc38154..71201c3b3ecda 100644 --- a/arch/tricore/src/common/tricore_exit.c +++ b/arch/tricore/src/common/tricore_exit.c @@ -56,25 +56,17 @@ void up_exit(int status) { - struct tcb_s *tcb = this_task(); - /* Destroy the task at the head of the ready to run list. */ nxtask_exit(); - /* Now, perform the context switch to the new ready-to-run task at the - * head of the list. - */ - - tcb = this_task(); - /* Scheduler parameters will update inside syscall */ g_running_tasks[this_cpu()] = NULL; /* Then switch contexts */ - tricore_fullcontextrestore(tcb->xcp.regs); + tricore_fullcontextrestore(); /* tricore_fullcontextrestore() should not return but could if the software * interrupts are disabled. diff --git a/arch/tricore/src/common/tricore_initialize.c b/arch/tricore/src/common/tricore_initialize.c index 9fa6ac844686d..21173d355fd81 100644 --- a/arch/tricore/src/common/tricore_initialize.c +++ b/arch/tricore/src/common/tricore_initialize.c @@ -34,7 +34,9 @@ * Public Data ****************************************************************************/ -volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS]; +/* g_interrupt_context store irq status */ + +volatile bool g_interrupt_context[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -59,6 +61,8 @@ volatile uintptr_t *g_current_regs[CONFIG_SMP_NCPUS]; void up_initialize(void) { + tricore_trapinit(); + /* Initialize the serial device driver */ #ifdef USE_SERIALDRIVER diff --git a/arch/tricore/src/common/tricore_internal.h b/arch/tricore/src/common/tricore_internal.h index b6df70c1ace0f..57d4557146f70 100644 --- a/arch/tricore/src/common/tricore_internal.h +++ b/arch/tricore/src/common/tricore_internal.h @@ -129,22 +129,7 @@ #define modreg32(v,m,a) putreg32((getreg32(a) & ~(m)) | ((v) & (m)), (a)) #define modreg64(v,m,a) putreg64((getreg64(a) & ~(m)) | ((v) & (m)), (a)) -/* Context switching */ - -#ifndef tricore_fullcontextrestore -# define tricore_fullcontextrestore(restoreregs) \ - sys_call1(SYS_restore_context, (uintptr_t)restoreregs); -#else -extern void tricore_fullcontextrestore(uintptr_t *restoreregs); -#endif - -#ifndef tricore_switchcontext -# define tricore_switchcontext(saveregs, restoreregs) \ - sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs); -#else -extern void tricore_switchcontext(uintptr_t **saveregs, - uintptr_t *restoreregs); -#endif +#define tricore_fullcontextrestore() sys_call0(SYS_restore_context) /**************************************************************************** * Public Types @@ -204,11 +189,6 @@ extern uintptr_t __A0_MEM[]; /* End+1 of .data */ * Inline Functions ****************************************************************************/ -/* Macros to handle saving and restoring interrupt state. */ - -#define tricore_savestate(regs) (regs = up_current_regs()) -#define tricore_restorestate(regs) (up_set_current_regs(regs)) - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -221,6 +201,7 @@ void tricore_sigdeliver(void); void tricore_svcall(volatile void *trap); void tricore_trapcall(volatile void *trap); +void tricore_trapinit(void); /* Context Save Areas *******************************************************/ diff --git a/arch/tricore/src/common/tricore_registerdump.c b/arch/tricore/src/common/tricore_registerdump.c index bc29358ca1b80..4a225e60b2ba0 100644 --- a/arch/tricore/src/common/tricore_registerdump.c +++ b/arch/tricore/src/common/tricore_registerdump.c @@ -39,10 +39,108 @@ * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: tricore_dump_upcsa + ****************************************************************************/ + +void tricore_dump_upcsa(volatile uint32_t *regs) +{ + _alert("UPCXI:%-13.8" PRIX32 "PSW:%-15.8" PRIX32 + "SP:%-16.8" PRIX32 "A11:%-15.8" PRIX32 "\n", + regs[REG_UPCXI], regs[REG_PSW], regs[REG_A10], regs[REG_UA11]); + _alert("D8:%-16.8" PRIX32 "D9:%-16.8" PRIX32 + "D10:%-15.8" PRIX32 "D11:%-15.8" PRIX32 "\n", + regs[REG_D8], regs[REG_D9], regs[REG_D10], regs[REG_D11]); + _alert("A12:%-15.8" PRIX32 "A13:%-15.8" PRIX32 + "A14:%-15.8" PRIX32 "A15:%-15.8" PRIX32 "\n", + regs[REG_A12], regs[REG_A13], regs[REG_A14], regs[REG_A15]); + _alert("D12:%-15.8" PRIX32 "D13:%-15.8" PRIX32 + "D14:%-15.8" PRIX32 "D15:%-15.8" PRIX32 "\n\n", + regs[REG_D12], regs[REG_D13], regs[REG_D14], regs[REG_D15]); +} + +/**************************************************************************** + * Name: tricore_dump_lowcsa + ****************************************************************************/ + +void tricore_dump_lowcsa(volatile uint32_t *regs) +{ + _alert("LPCXI:%-13.8" PRIX32 "PC:%-16.8" PRIX32 + "A2:%-16.8" PRIX32 "A3:%-16.8" PRIX32 "\n", + regs[REG_LPCXI] | PCXI_UL, regs[REG_LA11], + regs[REG_A2], regs[REG_A3]); + _alert("D0:%-16.8" PRIX32 "D1:%-16.8" PRIX32 + "D2:%-16.8" PRIX32 "D3:%-16.8" PRIX32 "\n", + regs[REG_D0], regs[REG_D1], regs[REG_D2], regs[REG_D3]); + _alert("A4:%-16.8" PRIX32 "A5:%-16.8" PRIX32 + "A6:%-16.8" PRIX32 "A7:%-16.8" PRIX32 "\n", + regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); + _alert("D4:%-16.8" PRIX32 "D5:%-16.8" PRIX32 + "D6:%-16.8" PRIX32 "D7:%-16.8" PRIX32 "\n\n", + regs[REG_D4], regs[REG_D5], regs[REG_D6], regs[REG_D7]); +} + +/**************************************************************************** + * Name: tricore_dump_trapctrl + ****************************************************************************/ + +void tricore_dump_trapctrl(void) +{ + _alert("PSTR:%-14.8" PRIX32 "DSTR:%-14.8" PRIX32 + "DATR:%-14.8" PRIX32 "DEADD:%-13.8" PRIX32 "\n\n", + (uint32_t)__mfcr(CPU_PSTR), (uint32_t)__mfcr(CPU_DSTR), + (uint32_t)__mfcr(CPU_DATR), (uint32_t)__mfcr(CPU_DEADD)); +} + +/**************************************************************************** + * Name: tricore_dump_csachain + ****************************************************************************/ + +void tricore_dump_csachain(uintptr_t pcxi) +{ + while (pcxi & FCX_FREE) + { + if (pcxi & PCXI_UL) + { + tricore_dump_upcsa((uint32_t *)tricore_csa2addr(pcxi)); + } + else + { + tricore_dump_lowcsa((uint32_t *)tricore_csa2addr(pcxi)); + } + + pcxi = tricore_csa2addr(pcxi)[0]; + } +} + /**************************************************************************** * Name: up_dump_register ****************************************************************************/ void up_dump_register(void *dumpregs) { + volatile uint32_t *regs = dumpregs; + + tricore_dump_lowcsa(regs); + + tricore_dump_upcsa(regs + TC_CONTEXT_REGS); + + tricore_dump_trapctrl(); +} + +/**************************************************************************** + * Name: up_regs_memcpy + ****************************************************************************/ + +void up_regs_memcpy(FAR void *dest, FAR void *src, size_t count) +{ + int csa_size = TC_CONTEXT_REGS * sizeof(uintptr_t); + int csa_num = count / csa_size; + + while (csa_num--) + { + memcpy(dest, src, csa_size); + dest = (char *)dest + csa_size; + src = tricore_csa2addr(((uintptr_t *)src)[REG_LPCXI]); + } } diff --git a/arch/tricore/src/common/tricore_saveusercontext.c b/arch/tricore/src/common/tricore_saveusercontext.c index c2b6152305b2c..25a46f8201753 100644 --- a/arch/tricore/src/common/tricore_saveusercontext.c +++ b/arch/tricore/src/common/tricore_saveusercontext.c @@ -32,6 +32,10 @@ * Pre-processor Definitions ****************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -46,7 +50,30 @@ int up_saveusercontext(void *saveregs) { - uintptr_t *regs = tricore_csa2addr(__mfcr(CPU_PCXI)); - memcpy(saveregs, regs, XCPTCONTEXT_SIZE); + uintptr_t *regs; + uintptr_t pcxi; + int csa_size = TC_CONTEXT_REGS * sizeof(uintptr_t); + + pcxi = __mfcr(CPU_PCXI); + regs = tricore_csa2addr(pcxi); + memcpy((char *)saveregs + csa_size, regs, csa_size); + + /* to unify the trap processing, extra save lowcsa */ + + __asm("svlcx"); + + regs = tricore_csa2addr(__mfcr(CPU_PCXI)); + memcpy(saveregs, regs, csa_size); + + /* lowcsa[REG_LPCXI] saves the upcsa's pcxi, but if lowcsa and upcsa is + * stored at continuous addresses, pcxi has no meaning. Use PCXI_UL + * without marking whether it is lowcsa or upcsa, but to mark whether + * lowcsa and upcsa is stored at continuous addresses. + */ + + ((uintptr_t *)saveregs)[REG_LPCXI] = pcxi & (~PCXI_UL); + + __asm("rslcx"); + return 0; } diff --git a/arch/tricore/src/common/tricore_schedulesigaction.c b/arch/tricore/src/common/tricore_schedulesigaction.c index ffac299f1ac3b..3f4662077cb24 100644 --- a/arch/tricore/src/common/tricore_schedulesigaction.c +++ b/arch/tricore/src/common/tricore_schedulesigaction.c @@ -90,7 +90,7 @@ void up_schedule_sigaction(struct tcb_s *tcb) * a task is signalling itself for some reason. */ - if (up_current_regs() == NULL) + if (!up_interrupt_context()) { /* In this case just deliver the signal now. */ @@ -117,16 +117,16 @@ void up_schedule_sigaction(struct tcb_s *tcb) * been delivered. */ - tricore_savestate(tcb->xcp.saved_regs); + tcb->xcp.saved_regs = tcb->xcp.regs; /* Create a new CSA for signal delivery. The new context * will borrow the process stack of the current tcb. */ - up_set_current_regs(tricore_alloc_csa((uintptr_t) - tricore_sigdeliver, - STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), - PSW_IO_SUPERVISOR | PSW_CDE, true)); + tcb->xcp.regs = + tricore_alloc_csa((uintptr_t)tricore_sigdeliver, + STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), + PSW_IO_SUPERVISOR | PSW_CDE, true); } } @@ -151,8 +151,9 @@ void up_schedule_sigaction(struct tcb_s *tcb) * will borrow the process stack of the current tcb. */ - tcb->xcp.regs = tricore_alloc_csa((uintptr_t)tricore_sigdeliver, - STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), - PSW_IO_SUPERVISOR | PSW_CDE, true); + tcb->xcp.regs = + tricore_alloc_csa((uintptr_t)tricore_sigdeliver, + STACK_ALIGN_DOWN(up_getusrsp(tcb->xcp.regs)), + PSW_IO_SUPERVISOR | PSW_CDE, true); } } diff --git a/arch/tricore/src/common/tricore_sigdeliver.c b/arch/tricore/src/common/tricore_sigdeliver.c index 5149dec75ba45..bddb489298533 100644 --- a/arch/tricore/src/common/tricore_sigdeliver.c +++ b/arch/tricore/src/common/tricore_sigdeliver.c @@ -116,5 +116,6 @@ void tricore_sigdeliver(void) board_autoled_off(LED_SIGNAL); - tricore_fullcontextrestore(regs); + rtcb->xcp.regs = regs; + tricore_fullcontextrestore(); } diff --git a/arch/tricore/src/common/tricore_svcall.c b/arch/tricore/src/common/tricore_svcall.c index 575a43eebf503..fb1f35c686b0e 100644 --- a/arch/tricore/src/common/tricore_svcall.c +++ b/arch/tricore/src/common/tricore_svcall.c @@ -56,87 +56,53 @@ void tricore_svcall(volatile void *trap) { - struct tcb_s *running_task; - struct tcb_s *tcb; - int cpu = this_cpu(); - + struct tcb_s **running_task = &g_running_tasks[this_cpu()]; + struct tcb_s *tcb = this_task(); uintptr_t *regs; uint32_t cmd; regs = (uintptr_t *)__mfcr(CPU_PCXI); - running_task = g_running_tasks[cpu]; - tcb = this_task(); - /* DSYNC instruction should be executed immediately prior to the MTCR */ __dsync(); regs = tricore_csa2addr((uintptr_t)regs); - up_set_current_regs(regs); + /* Set irq flag */ + + up_set_interrupt_context(true); cmd = regs[REG_D8]; + if (cmd != SYS_restore_context) + { + (*running_task)->xcp.regs = tricore_csa2addr(regs[REG_UPCXI]); + } + else + { + tricore_reclaim_csa(regs[REG_UPCXI]); + } + /* Handle the SVCall according to the command in R0 */ switch (cmd) { - /* R0=SYS_restore_context: This a restore context command: - * - * void tricore_fullcontextrestore(uint32_t *restoreregs) - * noreturn_function; - * - * At this point, the following values are saved in context: - * - * R0 = SYS_restore_context - * R1 = restoreregs - * - * In this case, we simply need to set g_current_regs to restore - * register area referenced in the saved R1. context == g_current_regs - * is the normal exception return. By setting g_current_regs = - * context[R1], we force the return to the saved context referenced - * in R1. - */ + case SYS_switch_context: + nxsched_switch_context(*running_task, tcb); case SYS_restore_context: - { - tricore_reclaim_csa(regs[REG_UPCXI]); - up_set_current_regs((uintptr_t *)regs[REG_D9]); - } - break; - - case SYS_switch_context: - { - *(uintptr_t **)regs[REG_D9] = (uintptr_t *)regs[REG_UPCXI]; - up_set_current_regs((uintptr_t *)regs[REG_D10]); - } + *running_task = tcb; + regs[REG_UPCXI] = tricore_addr2csa(tcb->xcp.regs); + __isync(); break; default: - { - svcerr("ERROR: Bad SYS call: %d\n", (int)regs[REG_D0]); - } + svcerr("ERROR: Bad SYS call: %d\n", (int)regs[REG_D0]); break; } - if (regs != up_current_regs()) - { - /* Update scheduler parameters */ - - nxsched_switch_context(running_task, tcb); - - /* Record the new "running" task when context switch occurred. - * g_running_tasks[] is only used by assertion logic for reporting - * crashes. - */ - - g_running_tasks[cpu] = this_task(); - - regs[REG_UPCXI] = (uintptr_t)up_current_regs(); - - __isync(); - } + /* Set irq flag */ - up_set_current_regs(NULL); + up_set_interrupt_context(false); } diff --git a/arch/tricore/src/common/tricore_switchcontext.c b/arch/tricore/src/common/tricore_switchcontext.c index 7d08421a8ffe5..532fe248a3a34 100644 --- a/arch/tricore/src/common/tricore_switchcontext.c +++ b/arch/tricore/src/common/tricore_switchcontext.c @@ -59,35 +59,10 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb) { - /* Are we in an interrupt handler? */ - - if (up_current_regs()) - { - /* Yes, then we have to do things differently. - * Just copy the g_current_regs into the OLD rtcb. - */ - - tricore_savestate(rtcb->xcp.regs); - - /* Then switch contexts. Any necessary address environment - * changes will be made when the interrupt returns. - */ - - tricore_restorestate(tcb->xcp.regs); - } - - /* No, then we will need to perform the user context switch */ - - else + if (!up_interrupt_context()) { /* Then switch contexts */ tricore_switchcontext(&rtcb->xcp.regs, tcb->xcp.regs); - - /* tricore_switchcontext forces a context switch to the task at the - * head of the ready-to-run list. It does not 'return' in the - * normal sense. When it does return, it is because the blocked - * task is again ready to run and has execution priority. - */ } } diff --git a/arch/tricore/src/common/tricore_trapcall.c b/arch/tricore/src/common/tricore_trapcall.c index a83bcb21a4a4a..b924ad77d4832 100644 --- a/arch/tricore/src/common/tricore_trapcall.c +++ b/arch/tricore/src/common/tricore_trapcall.c @@ -34,20 +34,262 @@ #include #include +#include #include #include "tricore_internal.h" #include "IfxCpu_Trap.h" +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static IfxCpu_Trap g_trapinfo; + /**************************************************************************** * Private Functions ****************************************************************************/ +static void tricore_trapinfo(volatile void *trap) +{ + IfxCpu_Trap *ctrap = (IfxCpu_Trap *)trap; + + g_trapinfo.tCpu = ctrap->tCpu; + g_trapinfo.tClass = ctrap->tClass; + g_trapinfo.tId = ctrap->tId; + g_trapinfo.tAddr = ctrap->tAddr; +} + /**************************************************************************** * Public Functions ****************************************************************************/ +int tricore_mmutrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! MMU Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_memoryManagement, + tid, context); + + _alert("MMU Trap Reason:\n"); + if (tid == IfxCpu_Trap_MemoryManagement_Id_virtualAddressFill) + { + _alert("\tVirtual Address Fill\n"); + } + + if (tid == IfxCpu_Trap_MemoryManagement_Id_virtualAddressProtection) + { + _alert("\tVirtual Address Protection\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_internalprotrape(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! Internal Protection Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_internalProtection, tid, context); + + _alert("Internal Protection Reason:\n"); + if (tid == IfxCpu_Trap_InternalProtection_Id_privilegeViolation) + { + _alert("\tPrivileged Instruction\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_memoryProtectionRead) + { + _alert("\tMemory Protection Read\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_memoryProtectionWrite) + { + _alert("\tMemory Proteciton Write\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_memoryProtectionExecute) + { + _alert("\tMemory Protection Execution\n"); + } + + if (tid == + IfxCpu_Trap_InternalProtection_Id_memoryProtectionPeripheralAccess) + { + _alert("\tMemory Protection Peripheral Access\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_memoryProtectionNullAddress) + { + _alert("\tMemory Protection Null Address\n"); + } + + if (tid == IfxCpu_Trap_InternalProtection_Id_globalRegisterWriteProtection) + { + _alert("\tGlobal Register Write Protection\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_insterrorstrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! Instruction Errors Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_instructionErrors, tid, context); + + _alert("Instruction Errors Trap Reason:\n"); + if (tid == IfxCpu_Trap_InstructionErrors_Id_illegalOpcode) + { + _alert("\tIllegal Opcode\n"); + } + + if (tid == IfxCpu_Trap_InstructionErrors_Id_unimplementedOpcode) + { + _alert("\tUnimplemented Opcode\n"); + } + + if (tid == IfxCpu_Trap_InstructionErrors_Id_invalidOperand) + { + _alert("\tInvalid Operand Specification\n"); + } + + if (tid == IfxCpu_Trap_InstructionErrors_Id_dataAddressAlignment) + { + _alert("\tData Address Alignment\n"); + } + + if (tid == IfxCpu_Trap_InstructionErrors_Id_invalidMemoryAddress) + { + _alert("\tInvalid Local Memory Address\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_contexmnttrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! Context Management Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_contextManagement, tid, context); + + _alert("Context Management Reason:\n"); + if (tid == IfxCpu_Trap_ContextManagement_Id_freeContextListDepletion) + { + _alert("\tFree Context List Depletion\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_callDepthOverflow) + { + _alert("\tCall Depth Overflow\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_callDepthUnderflow) + { + _alert("\tCall Depth Underflow\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_freeContextListUnderflow) + { + _alert("\tFree Context List Underflow\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_callStackUnderflow) + { + _alert("\tCall Stack Underflow\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_contextType) + { + _alert("\tContext Type\n"); + } + + if (tid == IfxCpu_Trap_ContextManagement_Id_nestingError) + { + _alert("\tNesting Error:RFE with non-zero call depth\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_bustrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! System Bus Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", IfxCpu_Trap_Class_bus, + tid, context); + + _alert("System Bus Reason:\n"); + if (tid == IfxCpu_Trap_Bus_Id_programFetchSynchronousError) + { + _alert("\tProgram Fetch Synchronous Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_dataAccessSynchronousError) + { + _alert("\tData Access Synchronous Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_dataAccessAsynchronousError) + { + _alert("\tData Access Asysnchronous Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_CoprocessorTrapAsynchronousError) + { + _alert("\tCoprocessor Trap Asynchronous Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_programMemoryIntegrityError) + { + _alert("\tProgram Memory Integrity Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_dataMemoryIntegrityError) + { + _alert("\tData Memory Integrity Error\n"); + } + + if (tid == IfxCpu_Trap_Bus_Id_temporalAsynchronousError) + { + _alert("\tTemporal Asynchronous Error\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + +int tricore_assertiontrap(uint32_t tid, void *context, void *arg) +{ + _alert("PANIC!!! Assertion Trap:\n"); + _alert("\tClass %d TID: %" PRId32 " regs: %p\n", + IfxCpu_Trap_Class_assertion, + tid, context); + + _alert("System Bus Reason:\n"); + if (tid == IfxCpu_Trap_Assertion_Id_arithmeticOverflow) + { + _alert("\tArithmetic Overflow\n"); + } + + if (tid == IfxCpu_Trap_Assertion_Id_stickyArithmeticOverflow) + { + _alert("\tSticky Arithmetic Overflow\n"); + } + + up_irq_save(); + PANIC_WITH_REGS("panic", context); + return OK; +} + /**************************************************************************** * Name: tricore_trapcall * @@ -59,11 +301,79 @@ void tricore_trapcall(volatile void *trap) { uintptr_t *regs; + uintptr_t pcxi; + + IfxCpu_Trap *ctrap = (IfxCpu_Trap *)trap; + IfxCpu_Trap_Class tclass = (IfxCpu_Trap_Class)ctrap->tClass; + unsigned int tid = ctrap->tId; + + tricore_trapinfo(trap); regs = tricore_csa2addr(__mfcr(CPU_PCXI)); + pcxi = regs[REG_UPCXI]; + regs = tricore_csa2addr(pcxi); + + if (!up_interrupt_context()) + { + /* Update the current task's regs */ + + g_running_tasks[this_cpu()]->xcp.regs = regs; + } + + up_set_interrupt_context(true); + + if (tclass == IfxCpu_Trap_Class_memoryManagement) + { + tricore_mmutrap(tid, regs, NULL); + return; + } + + if (tclass == IfxCpu_Trap_Class_internalProtection) + { + tricore_internalprotrape(tid, regs, NULL); + return; + } + + if (tclass == IfxCpu_Trap_Class_instructionErrors) + { + tricore_insterrorstrap(tid, regs, NULL); + return; + } + + if (tclass == IfxCpu_Trap_Class_contextManagement) + { + tricore_contexmnttrap(tid, regs, NULL); + return; + } - up_set_current_regs(regs); + if (tclass == IfxCpu_Trap_Class_bus) + { + tricore_bustrap(tid, regs, NULL); + return; + } + + if (tclass == IfxCpu_Trap_Class_assertion) + { + tricore_assertiontrap(tid, regs, NULL); + return; + } up_irq_save(); - PANIC_WITH_REGS("Trap", up_current_regs()); + PANIC_WITH_REGS("Trap", regs); +} + +/**************************************************************************** + * Function: tricore_trapinit + * + * Description: + * Trap init for tricore arch. + * + ****************************************************************************/ + +void tricore_trapinit(void) +{ +#ifdef CONFIG_COREDUMP + coredump_add_memory_region(&g_trapinfo, sizeof(g_trapinfo), + PF_REGISTER); +#endif } diff --git a/arch/x86_64/include/irq.h b/arch/x86_64/include/irq.h index 8a1db30b81c05..89f6eaa1867b6 100644 --- a/arch/x86_64/include/irq.h +++ b/arch/x86_64/include/irq.h @@ -76,7 +76,7 @@ struct intel64_cpu_s struct tcb_s *this_task; -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL /* Current user RSP for syscall */ uint64_t *ustack; diff --git a/arch/x86_64/src/cmake/platform.cmake b/arch/x86_64/src/cmake/platform.cmake index 30b1047094b65..705f0613edd10 100644 --- a/arch/x86_64/src/cmake/platform.cmake +++ b/arch/x86_64/src/cmake/platform.cmake @@ -84,3 +84,34 @@ endif() nuttx_add_extra_library(${EXTRA_LIB}) set(PREPROCESS ${CMAKE_C_COMPILER} ${CMAKE_C_FLAG_ARGS} -E -P -x c) + +if(CONFIG_ARCH_MULTIBOOT1) + message(STATUS "Generating: nuttx.mb1 in ELF32/multiboot1") + if(CONFIG_ALLSYMS) + set(FINAL_NUTTX_ELF "${CMAKE_BINARY_DIR}/final_nuttx") + else() + set(FINAL_NUTTX_ELF "${CMAKE_BINARY_DIR}/nuttx") + endif() + set(NUTTX_ELF "${CMAKE_BINARY_DIR}/nuttx") + set(NUTTX_BIN "${NUTTX_ELF}.bin") + set(NUTTX_REALMODE_BIN "${NUTTX_ELF}_realmode.bin") + set(NUTTX_MB1 "${NUTTX_ELF}.mb1") + add_custom_command( + OUTPUT ${NUTTX_BIN} ${NUTTX_REALMODE_BIN} + COMMAND ${CMAKE_OBJCOPY} -R .realmode -R .note.* -O binary + ${FINAL_NUTTX_ELF} ${NUTTX_BIN} + COMMAND ${CMAKE_OBJCOPY} -j .realmode -O binary ${FINAL_NUTTX_ELF} + ${NUTTX_REALMODE_BIN} + DEPENDS ${FINAL_NUTTX_ELF} + COMMENT "Generating binary and realmode segments from nuttx ELF") + add_custom_command( + OUTPUT ${NUTTX_MB1} + COMMAND + ${CMAKE_C_COMPILER} -m32 -no-pie -nostdlib -DNUTTX_BIN='"${NUTTX_BIN}"' + -DNUTTX_REALMODE_BIN='"${NUTTX_REALMODE_BIN}"' + ${CMAKE_SOURCE_DIR}/arch/x86_64/src/common/multiboot1.S -T + ${CMAKE_SOURCE_DIR}/arch/x86_64/src/common/multiboot1.ld -o ${NUTTX_MB1} + DEPENDS ${NUTTX_BIN} ${NUTTX_REALMODE_BIN} + COMMENT "Building nuttx.mb1 multiboot1 image") + add_custom_target(multiboot1 ALL DEPENDS ${NUTTX_MB1}) +endif() diff --git a/arch/x86_64/src/common/CMakeLists.txt b/arch/x86_64/src/common/CMakeLists.txt index c797d00619ee4..045b1aeece8f7 100644 --- a/arch/x86_64/src/common/CMakeLists.txt +++ b/arch/x86_64/src/common/CMakeLists.txt @@ -38,7 +38,7 @@ if(CONFIG_ARCH_HAVE_FORK) list(APPEND SRCS x86_64_fork.c fork.S) endif() -if(CONFIG_LIB_SYSCALL) +if(CONFIG_ARCH_HAVE_SYSCALL) list(APPEND SRCS x86_64_syscall.c) endif() diff --git a/arch/x86_64/src/common/Make.defs b/arch/x86_64/src/common/Make.defs index f63e2cbce822f..47e1dc16a19b4 100644 --- a/arch/x86_64/src/common/Make.defs +++ b/arch/x86_64/src/common/Make.defs @@ -34,7 +34,7 @@ CMN_CSRCS += x86_64_fork.c CMN_ASRCS += fork.S endif -ifeq ($(CONFIG_LIB_SYSCALL),y) +ifeq ($(CONFIG_ARCH_HAVE_SYSCALL),y) CMN_CSRCS += x86_64_syscall.c endif diff --git a/arch/x86_64/src/common/fork.S b/arch/x86_64/src/common/fork.S index f526a5fa9569d..1621b560474a1 100644 --- a/arch/x86_64/src/common/fork.S +++ b/arch/x86_64/src/common/fork.S @@ -118,10 +118,14 @@ up_fork: pushq %r12 movq %rsp, %rdi + subq $8, %rsp + /* call function */ callq x86_64_fork + addq $8, %rsp + /* Do not modify return value %rax */ /* Restore non-volatile registers */ diff --git a/arch/x86_64/src/common/x86_64_syscall.c b/arch/x86_64/src/common/x86_64_syscall.c index 960b992bb0210..833c191bf5bcb 100644 --- a/arch/x86_64/src/common/x86_64_syscall.c +++ b/arch/x86_64/src/common/x86_64_syscall.c @@ -109,7 +109,10 @@ uint64_t *x86_64_syscall(uint64_t *regs) uint64_t arg4 = regs[REG_R10]; uint64_t arg5 = regs[REG_R8]; uint64_t arg6 = regs[REG_R9]; - uintptr_t ret = 0; + + UNUSED(arg4); + UNUSED(arg5); + UNUSED(arg6); /* The syscall command is in RAX on entry */ @@ -293,11 +296,13 @@ uint64_t *x86_64_syscall(uint64_t *regs) default: { +#ifdef CONFIG_LIB_SYSCALL int nbr = cmd - CONFIG_SYS_RESERVED; - struct tcb_s *rtcb = nxsched_self(); syscall_stub_t stub = (syscall_stub_t)g_stublookup[nbr]; #ifdef CONFIG_ARCH_KERNEL_STACK + struct tcb_s *rtcb = nxsched_self(); + /* Store reference to user RSP for signals */ rtcb->xcp.saved_ursp = regs[REG_RSP]; @@ -312,20 +317,18 @@ uint64_t *x86_64_syscall(uint64_t *regs) up_irq_restore(X86_64_RFLAGS_IF); } - /* Call syscall function */ - - ret = stub(nbr, arg1, arg2, arg3, arg4, arg5, arg6); + /* Call syscall function and store return value in RAX register */ + regs[REG_RAX] = stub(nbr, arg1, arg2, arg3, arg4, arg5, arg6); +#else + svcerr("ERROR: Bad SYS call: %" PRId32 "\n", cmd); +#endif break; } } dump_syscall("Exit", regs); - /* Store return value in RAX register */ - - regs[REG_RAX] = ret; - /* Return pointer to regs */ return regs; diff --git a/arch/x86_64/src/intel64/Kconfig b/arch/x86_64/src/intel64/Kconfig index 9787d9896701e..1d13fce8a7a1d 100644 --- a/arch/x86_64/src/intel64/Kconfig +++ b/arch/x86_64/src/intel64/Kconfig @@ -23,10 +23,10 @@ config ARCH_INTEL64_HAVE_TSC config ARCH_INTEL64_HAS_TSC_ADJUST bool "MSR_IA32_TSC_ADJUST support" - depends on ARCH_INTEL64_HAVE_TSC + depends on ARCH_INTEL64_HAVE_TSC && SCHED_TICKLESS default y ---help--- - MSR_IA32_TSC_ADJUST is used to adjust the offset of the Time Stamp Counter (TSC). + MSR_IA32_TSC_ADJUST is used to adjust the offset of the Time Stamp Counter (TSC). config ARCH_INTEL64_CACHE_LINESIZE diff --git a/arch/x86_64/src/intel64/intel64_cpu.c b/arch/x86_64/src/intel64/intel64_cpu.c index f93289ae789e4..2f91da3f15beb 100644 --- a/arch/x86_64/src/intel64/intel64_cpu.c +++ b/arch/x86_64/src/intel64/intel64_cpu.c @@ -244,7 +244,7 @@ void x86_64_cpu_init(void) g_cpu_priv[i].loapic_id = lapic->apic_id; g_cpu_priv[i].id = i; g_cpu_priv[i].ready = false; -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL g_cpu_priv[i].ustack = NULL; g_cpu_priv[i].uvbase = (uint64_t *)CONFIG_ARCH_TEXT_VBASE; #endif @@ -383,7 +383,7 @@ void x86_64_cpu_priv_set(uint8_t cpu) write_gsbase((uintptr_t)&g_cpu_priv[cpu]); -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL /* Configure SYSCALL instruction entry point */ write_msr(MSR_LSTAR, (uintptr_t)x86_64_syscall_entry); diff --git a/arch/x86_64/src/intel64/intel64_head.S b/arch/x86_64/src/intel64/intel64_head.S index 154c849344f42..060d3d184f385 100644 --- a/arch/x86_64/src/intel64/intel64_head.S +++ b/arch/x86_64/src/intel64/intel64_head.S @@ -80,7 +80,7 @@ .global __enable_sse_avx .global __enable_pcid .global __revoke_low_memory -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL .global x86_64_syscall_entry .global x86_64_syscall #endif @@ -348,7 +348,7 @@ start64_init: movl $MSR_EFER, %ecx rdmsr -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL or $(EFER_LME | EFER_SCE), %eax #else or $EFER_LME, %eax @@ -536,7 +536,7 @@ __enable_pcid: .size __enable_pcid, . - __enable_pcid -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL /**************************************************************************** * Name: x86_64_syscall_entry * @@ -696,6 +696,10 @@ no_kstack_switch: syscall_no_ring3: # endif + /* Restore the value of RFLAGS from R11 */ + pushq %r11 + popfq + /* Return to address pointed in RCX - must be on stack */ pushq %rcx ret diff --git a/arch/x86_64/src/intel64/intel64_saveusercontext.S b/arch/x86_64/src/intel64/intel64_saveusercontext.S index 7e40f91035d3b..78151d090304f 100644 --- a/arch/x86_64/src/intel64/intel64_saveusercontext.S +++ b/arch/x86_64/src/intel64/intel64_saveusercontext.S @@ -105,7 +105,7 @@ up_saveusercontext: movq %rbp, (8*REG_RBP)(%rdi) -#ifdef CONFIG_LIB_SYSCALL +#ifdef CONFIG_ARCH_HAVE_SYSCALL /* Save CS and SS if we support syscalls */ xor %rax, %rax mov %cs, %ax diff --git a/arch/x86_64/src/intel64/intel64_tsc_timerisr.c b/arch/x86_64/src/intel64/intel64_tsc_timerisr.c index b2dc70e435407..23d9eadda4ce1 100644 --- a/arch/x86_64/src/intel64/intel64_tsc_timerisr.c +++ b/arch/x86_64/src/intel64/intel64_tsc_timerisr.c @@ -55,7 +55,7 @@ * Private Data ****************************************************************************/ -unsigned long g_x86_64_timer_freq; +extern unsigned long g_x86_64_timer_freq; /**************************************************************************** * Private Functions diff --git a/arch/xtensa/src/esp32/esp32_tickless.c b/arch/xtensa/src/esp32/esp32_tickless.c index c57661cf6fa8f..d621f7d71c310 100644 --- a/arch/xtensa/src/esp32/esp32_tickless.c +++ b/arch/xtensa/src/esp32/esp32_tickless.c @@ -270,7 +270,7 @@ static int up_timer_expire(int irq, void *regs, void *arg) if (do_sched) { up_timer_cancel(NULL); - nxsched_timer_expiration(); + nxsched_process_timer(); } } else @@ -340,7 +340,7 @@ int IRAM_ATTR up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -415,14 +415,14 @@ int IRAM_ATTR up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/arch/xtensa/src/esp32s3/esp32s3_tickless.c b/arch/xtensa/src/esp32s3/esp32s3_tickless.c index fc5e56c7453dc..e8357b5eb95db 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_tickless.c +++ b/arch/xtensa/src/esp32s3/esp32s3_tickless.c @@ -255,7 +255,7 @@ static int IRAM_ATTR tickless_isr(int irq, void *context, void *arg) return OK; } - nxsched_timer_expiration(); + nxsched_process_timer(); return OK; } @@ -319,7 +319,7 @@ int IRAM_ATTR up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -397,14 +397,14 @@ int IRAM_ATTR up_timer_cancel(struct timespec *ts) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be + * Start the interval timer. nxsched_process_timer() will be * called at the completion of the timeout (unless up_timer_cancel * is called to stop the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/boards/arm/am335x/beaglebone-black/CMakeLists.txt b/boards/arm/am335x/beaglebone-black/CMakeLists.txt new file mode 100644 index 0000000000000..152e98405a698 --- /dev/null +++ b/boards/arm/am335x/beaglebone-black/CMakeLists.txt @@ -0,0 +1,23 @@ +# ############################################################################## +# boards/arm/am335x/beaglebone-black/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +add_subdirectory(src) diff --git a/boards/arm/am335x/beaglebone-black/src/CMakeLists.txt b/boards/arm/am335x/beaglebone-black/src/CMakeLists.txt new file mode 100644 index 0000000000000..90057ac2ca6fd --- /dev/null +++ b/boards/arm/am335x/beaglebone-black/src/CMakeLists.txt @@ -0,0 +1,39 @@ +# ############################################################################## +# boards/arm/am335x/beaglebone-black/src/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +set(SRCS am335x_boot.c am335x_bringup.c am335x_leds.c) + +if(CONFIG_BOARDCTL) + list(APPEND SRCS am335x_appinit.c) +endif() + +if(CONFIG_ARCH_BUTTONS) + list(APPEND SRCS am335x_buttons.c) +endif() + +if(CONFIG_AM335X_LCDC) + list(APPEND SRCS am335x_lcd.c) +endif() + +target_sources(board PRIVATE ${SRCS}) + +set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/sdram.ld") diff --git a/boards/arm/gd32f4/gd32f450zk-aiotbox/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f450zk-aiotbox/src/gd32f4xx_romfs.c index 6f81c0ed4a6fc..8e17344333c15 100644 --- a/boards/arm/gd32f4/gd32f450zk-aiotbox/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f450zk-aiotbox/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_romfs.c index a77bd149721fc..73fa182b78f44 100644 --- a/boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c index 91e0b0df63618..667ef8b345d70 100644 --- a/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f470ik-eval/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/gd32f4/gd32f470zk-aiotbox/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f470zk-aiotbox/src/gd32f4xx_romfs.c index 3dcd603c46ddc..a5a162fb61003 100644 --- a/boards/arm/gd32f4/gd32f470zk-aiotbox/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f470zk-aiotbox/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/gd32f4/gd32f470zk-eval/src/gd32f4xx_romfs.c b/boards/arm/gd32f4/gd32f470zk-eval/src/gd32f4xx_romfs.c index e201cbeda3db9..1794fc6ab6342 100644 --- a/boards/arm/gd32f4/gd32f470zk-eval/src/gd32f4xx_romfs.c +++ b/boards/arm/gd32f4/gd32f470zk-eval/src/gd32f4xx_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/kinetis/freedom-k28f/src/k28_usbhshost.c b/boards/arm/kinetis/freedom-k28f/src/k28_usbhshost.c index f10e3218a433c..6e109c885152b 100644 --- a/boards/arm/kinetis/freedom-k28f/src/k28_usbhshost.c +++ b/boards/arm/kinetis/freedom-k28f/src/k28_usbhshost.c @@ -377,7 +377,7 @@ static void usb_msc_disconnect(void *arg) else { - ferr("ERROR: Unmount failed: %d\n", errcode); + ferr("ERROR: Unmount failed: %d\n", ret); } } } diff --git a/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_romfs.c b/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_romfs.c index 2d22cb139c58b..7570b09d80397 100644 --- a/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_romfs.c +++ b/boards/arm/lpc17xx_40xx/pnev5180b/src/lpc17_40_romfs.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - ".section .rodata\n" + ".section .rodata, \"a\"\n" ".balign 16\n" ".globl romfs_data_begin\n" "romfs_data_begin:\n" diff --git a/boards/arm/lpc54xx/lpcxpresso-lpc54628/configs/netnsh/defconfig b/boards/arm/lpc54xx/lpcxpresso-lpc54628/configs/netnsh/defconfig index e137fea389bd3..cbba6d078db66 100644 --- a/boards/arm/lpc54xx/lpcxpresso-lpc54628/configs/netnsh/defconfig +++ b/boards/arm/lpc54xx/lpcxpresso-lpc54628/configs/netnsh/defconfig @@ -43,6 +43,7 @@ CONFIG_NET_ICMPv6=y CONFIG_NET_ICMPv6_NEIGHBOR=y CONFIG_NET_ICMPv6_SOCKET=y CONFIG_NET_IPv6=y +CONFIG_NET_SOCKOPTS=y CONFIG_NET_STATISTICS=y CONFIG_NET_TCP=y CONFIG_NET_TCP_WRITE_BUFFERS=y diff --git a/boards/arm/stm32/nucleo-f429zi/src/stm32_romfs_initialize.c b/boards/arm/stm32/nucleo-f429zi/src/stm32_romfs_initialize.c index feceef0b1167f..61ea69b5dab50 100644 --- a/boards/arm/stm32/nucleo-f429zi/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32/nucleo-f429zi/src/stm32_romfs_initialize.c @@ -71,7 +71,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/stm32/nucleo-f446re/src/stm32_romfs_initialize.c b/boards/arm/stm32/nucleo-f446re/src/stm32_romfs_initialize.c index 4bb1c495fc0d8..e984d4d194802 100644 --- a/boards/arm/stm32/nucleo-f446re/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32/nucleo-f446re/src/stm32_romfs_initialize.c @@ -71,7 +71,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm/stm32/omnibusf4/src/stm32_romfs_initialize.c b/boards/arm/stm32/omnibusf4/src/stm32_romfs_initialize.c index c5418c4f1e8d5..3f5e6e9e3df80 100644 --- a/boards/arm/stm32/omnibusf4/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32/omnibusf4/src/stm32_romfs_initialize.c @@ -83,7 +83,7 @@ ****************************************************************************/ __asm__ ( - ".section .rodata\n" + ".section .rodata, \"a\"\n" ".balign 16\n" ".globl romfs_data_begin\n" "romfs_data_begin:\n" diff --git a/boards/arm/stm32/stm32f103-minimum/src/stm32_gpio.c b/boards/arm/stm32/stm32f103-minimum/src/stm32_gpio.c index 8e91c3c77a793..34685edc3f1d9 100644 --- a/boards/arm/stm32/stm32f103-minimum/src/stm32_gpio.c +++ b/boards/arm/stm32/stm32f103-minimum/src/stm32_gpio.c @@ -62,18 +62,25 @@ struct stm32gpint_dev_s * Private Function Prototypes ****************************************************************************/ +#if BOARD_NGPIOIN > 0 static int gpin_read(struct gpio_dev_s *dev, bool *value); +#endif /* BOARD_NGPIOIN > 0 */ +#if BOARD_NGPIOOUT > 0 static int gpout_read(struct gpio_dev_s *dev, bool *value); static int gpout_write(struct gpio_dev_s *dev, bool value); +#endif /* BOARD_NGPIOOUT > 0 */ +#if BOARD_NGPIOINT > 0 static int gpint_read(struct gpio_dev_s *dev, bool *value); static int gpint_attach(struct gpio_dev_s *dev, pin_interrupt_t callback); static int gpint_enable(struct gpio_dev_s *dev, bool enable); +#endif /* BOARD_NGPIOINT > 0 */ /**************************************************************************** * Private Data ****************************************************************************/ +#if BOARD_NGPIOIN > 0 static const struct gpio_operations_s gpin_ops = { .go_read = gpin_read, @@ -81,7 +88,9 @@ static const struct gpio_operations_s gpin_ops = .go_attach = NULL, .go_enable = NULL, }; +#endif /* BOARD_NGPIOIN > 0 */ +#if BOARD_NGPIOOUT > 0 static const struct gpio_operations_s gpout_ops = { .go_read = gpout_read, @@ -89,7 +98,9 @@ static const struct gpio_operations_s gpout_ops = .go_attach = NULL, .go_enable = NULL, }; +#endif /* BOARD_NGPIOOUT > 0 */ +#if BOARD_NGPIOINT > 0 static const struct gpio_operations_s gpint_ops = { .go_read = gpint_read, @@ -97,6 +108,7 @@ static const struct gpio_operations_s gpint_ops = .go_attach = gpint_attach, .go_enable = gpint_enable, }; +#endif /* BOARD_NGPIOINT > 0 */ #if BOARD_NGPIOIN > 0 /* This array maps the GPIO pins used as INPUT */ @@ -109,7 +121,7 @@ static const uint32_t g_gpioinputs[BOARD_NGPIOIN] = static struct stm32gpio_dev_s g_gpin[BOARD_NGPIOIN]; #endif -#if BOARD_NGPIOOUT +#if BOARD_NGPIOOUT > 0 /* This array maps the GPIO pins used as OUTPUT */ static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] = @@ -135,6 +147,7 @@ static struct stm32gpint_dev_s g_gpint[BOARD_NGPIOINT]; * Private Functions ****************************************************************************/ + #if BOARD_NGPIOINT > 0 static int stm32gpio_interrupt(int irq, void *context, void *arg) { struct stm32gpint_dev_s *stm32gpint = @@ -147,7 +160,9 @@ static int stm32gpio_interrupt(int irq, void *context, void *arg) stm32gpint->stm32gpio.id); return OK; } +#endif /* BOARD_NGPIOINT > 0 */ +#if BOARD_NGPIOIN > 0 static int gpin_read(struct gpio_dev_s *dev, bool *value) { struct stm32gpio_dev_s *stm32gpio = @@ -160,7 +175,9 @@ static int gpin_read(struct gpio_dev_s *dev, bool *value) *value = stm32_gpioread(g_gpioinputs[stm32gpio->id]); return OK; } +#endif /* BOARD_NGPIOIN > 0*/ +#if BOARD_NGPIOOUT > 0 static int gpout_read(struct gpio_dev_s *dev, bool *value) { struct stm32gpio_dev_s *stm32gpio = @@ -186,7 +203,9 @@ static int gpout_write(struct gpio_dev_s *dev, bool value) stm32_gpiowrite(g_gpiooutputs[stm32gpio->id], value); return OK; } +#endif /* BOARD_NGPIOOUT > 0 */ +#if BOARD_NGPIOINT > 0 static int gpint_read(struct gpio_dev_s *dev, bool *value) { struct stm32gpint_dev_s *stm32gpint = @@ -245,6 +264,7 @@ static int gpint_enable(struct gpio_dev_s *dev, bool enable) return OK; } +#endif /* BOARD_NGPIOINT > 0 */ /**************************************************************************** * Public Functions diff --git a/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig b/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig index 3349007bd8735..c31179247f3c4 100644 --- a/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig +++ b/boards/arm/stm32/stm32f4discovery/configs/testlibcxx/defconfig @@ -37,6 +37,7 @@ CONFIG_RAM_SIZE=114688 CONFIG_RAM_START=0x20000000 CONFIG_RAW_BINARY=y CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_THREAD_LOCAL=y CONFIG_SCHED_WAITPID=y CONFIG_START_DAY=2 CONFIG_START_MONTH=11 diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32_romfs_initialize.c b/boards/arm/stm32/stm32f4discovery/src/stm32_romfs_initialize.c index 1c453643f5dfd..e52b94b231808 100644 --- a/boards/arm/stm32/stm32f4discovery/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32/stm32f4discovery/src/stm32_romfs_initialize.c @@ -84,7 +84,7 @@ ****************************************************************************/ __asm__ ( - ".section .rodata\n" + ".section .rodata, \"a\"\n" ".balign 16\n" ".globl romfs_data_begin\n" "romfs_data_begin:\n" diff --git a/boards/arm/stm32f7/common/src/stm32_romfs_initialize.c b/boards/arm/stm32f7/common/src/stm32_romfs_initialize.c index 171e35352e723..4351cbf11666c 100644 --- a/boards/arm/stm32f7/common/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32f7/common/src/stm32_romfs_initialize.c @@ -83,7 +83,7 @@ ****************************************************************************/ __asm__ ( - ".section .rodata\n" + ".section .rodata, \"a\"\n" ".balign 16\n" ".globl romfs_data_begin\n" "romfs_data_begin:\n" diff --git a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_romfs_initialize.c b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_romfs_initialize.c index 241430732717e..4476ebe23156b 100644 --- a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_romfs_initialize.c +++ b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_romfs_initialize.c @@ -69,7 +69,7 @@ ****************************************************************************/ __asm__ ( - " .section .rodata \n" + " .section .rodata, \"a\" \n" " .balign 16 \n" " .globl romfs_data_begin \n" "romfs_data_begin: \n" diff --git a/boards/arm64/a64/pinephone/configs/lcd/defconfig b/boards/arm64/a64/pinephone/configs/lcd/defconfig index f96772ab24eb9..b2fb74644c300 100644 --- a/boards/arm64/a64/pinephone/configs/lcd/defconfig +++ b/boards/arm64/a64/pinephone/configs/lcd/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_BOARD_PINEPHONE=y CONFIG_ARCH_CHIP="a64" CONFIG_ARCH_CHIP_A64=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y diff --git a/boards/arm64/a64/pinephone/configs/lvgl/defconfig b/boards/arm64/a64/pinephone/configs/lvgl/defconfig index 81b1f6dc1bfcb..afe848365b612 100644 --- a/boards/arm64/a64/pinephone/configs/lvgl/defconfig +++ b/boards/arm64/a64/pinephone/configs/lvgl/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_BOARD_PINEPHONE=y CONFIG_ARCH_CHIP="a64" CONFIG_ARCH_CHIP_A64=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y diff --git a/boards/arm64/a64/pinephone/configs/nsh/defconfig b/boards/arm64/a64/pinephone/configs/nsh/defconfig index 4b41f295da254..22260c9573d04 100644 --- a/boards/arm64/a64/pinephone/configs/nsh/defconfig +++ b/boards/arm64/a64/pinephone/configs/nsh/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_BOARD_PINEPHONE=y CONFIG_ARCH_CHIP="a64" CONFIG_ARCH_CHIP_A64=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y diff --git a/boards/arm64/a64/pinephone/configs/sensor/defconfig b/boards/arm64/a64/pinephone/configs/sensor/defconfig index 3c261f5f0f642..861b3b4d310ac 100644 --- a/boards/arm64/a64/pinephone/configs/sensor/defconfig +++ b/boards/arm64/a64/pinephone/configs/sensor/defconfig @@ -15,6 +15,7 @@ CONFIG_ARCH_BOARD_PINEPHONE=y CONFIG_ARCH_CHIP="a64" CONFIG_ARCH_CHIP_A64=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARDCTL_RESET=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y diff --git a/boards/arm64/a64/pinephone/src/pinephone_touch.c b/boards/arm64/a64/pinephone/src/pinephone_touch.c index 138140e2a84ff..3b581f1360389 100644 --- a/boards/arm64/a64/pinephone/src/pinephone_touch.c +++ b/boards/arm64/a64/pinephone/src/pinephone_touch.c @@ -117,7 +117,8 @@ static int pinephone_gt9xx_irq_attach(const struct gt9xx_board_s *state, /* Set Interrupt Priority in Generic Interrupt Controller v2 */ - arm64_gic_irq_set_priority(A64_IRQ_PH_EINT, 0, IRQ_TYPE_EDGE); + up_prioritize_irq(A64_IRQ_PH_EINT, 0); + up_set_irq_type(A64_IRQ_PH_EINT, IRQ_RISING_EDGE); /* Enable Interrupts for Port PH */ diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/cgol/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/cgol/defconfig index 90a30df936bac..ba110299cde40 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/cgol/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/cgol/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BCM2711_FRAMEBUFFER=y CONFIG_BOARD_LOOPSPERMSEC=132954 CONFIG_BUILTIN=y diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/fb/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/fb/defconfig index a8268ea2cd786..0459e7f031cb1 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/fb/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/fb/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BCM2711_FRAMEBUFFER=y CONFIG_BOARD_LOOPSPERMSEC=132954 CONFIG_BUILTIN=y diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/lvgl/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/lvgl/defconfig index d959a08a0c4d4..539f85ad073c0 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/lvgl/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/lvgl/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BCM2711_FRAMEBUFFER=y CONFIG_BOARD_LATE_INITIALIZE=y CONFIG_BOARD_LOOPSPERMSEC=132954 diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig index d0ddcd64efca1..5d0766b5262dc 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARD_LOOPSPERMSEC=132954 CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig index a521ef1b36d92..af3389573a0c0 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="bcm2711" CONFIG_ARCH_CHIP_BCM2711=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BCM2711_EMMC2=y CONFIG_BCM2711_EMMC=y CONFIG_BOARD_LOOPSPERMSEC=132954 diff --git a/boards/arm64/rk3399/nanopi_m4/configs/nsh/defconfig b/boards/arm64/rk3399/nanopi_m4/configs/nsh/defconfig index 5bbde6996df2f..0ad77abe8fd37 100644 --- a/boards/arm64/rk3399/nanopi_m4/configs/nsh/defconfig +++ b/boards/arm64/rk3399/nanopi_m4/configs/nsh/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="rk3399" CONFIG_ARCH_CHIP_RK3399=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y diff --git a/boards/arm64/rk3399/pinephonepro/configs/nsh/defconfig b/boards/arm64/rk3399/pinephonepro/configs/nsh/defconfig index 7ceae852668df..4cdda4dd59947 100644 --- a/boards/arm64/rk3399/pinephonepro/configs/nsh/defconfig +++ b/boards/arm64/rk3399/pinephonepro/configs/nsh/defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_CHIP="rk3399" CONFIG_ARCH_CHIP_RK3399=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_BOARD_LOOPSPERMSEC=116524 CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y diff --git a/boards/arm64/zynq-mpsoc/zcu111/configs/jtag/defconfig b/boards/arm64/zynq-mpsoc/zcu111/configs/jtag/defconfig index 2d00862bcb16d..97737c569f6e9 100644 --- a/boards/arm64/zynq-mpsoc/zcu111/configs/jtag/defconfig +++ b/boards/arm64/zynq-mpsoc/zcu111/configs/jtag/defconfig @@ -15,6 +15,7 @@ CONFIG_ARCH_CHIP="zynq-mpsoc" CONFIG_ARCH_CHIP_ZYNQ_MPSOC=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_ARM64_DCACHE_DISABLE=y CONFIG_ARM64_GIC_VERSION=2 CONFIG_ARM64_ICACHE_DISABLE=y diff --git a/boards/arm64/zynq-mpsoc/zcu111/configs/netjtag/defconfig b/boards/arm64/zynq-mpsoc/zcu111/configs/netjtag/defconfig index 8775f4cdce8a1..f64751f4409f5 100644 --- a/boards/arm64/zynq-mpsoc/zcu111/configs/netjtag/defconfig +++ b/boards/arm64/zynq-mpsoc/zcu111/configs/netjtag/defconfig @@ -15,6 +15,7 @@ CONFIG_ARCH_CHIP="zynq-mpsoc" CONFIG_ARCH_CHIP_ZYNQ_MPSOC=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_ARM64_DCACHE_DISABLE=y CONFIG_ARM64_GIC_VERSION=2 CONFIG_ARM64_ICACHE_DISABLE=y diff --git a/boards/arm64/zynq-mpsoc/zcu111/configs/netnsh/defconfig b/boards/arm64/zynq-mpsoc/zcu111/configs/netnsh/defconfig index ed7f23b3a6752..91c5b72030569 100644 --- a/boards/arm64/zynq-mpsoc/zcu111/configs/netnsh/defconfig +++ b/boards/arm64/zynq-mpsoc/zcu111/configs/netnsh/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_CHIP="zynq-mpsoc" CONFIG_ARCH_CHIP_ZYNQ_MPSOC=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_ARM64_DCACHE_DISABLE=y CONFIG_ARM64_GIC_VERSION=2 CONFIG_ARM64_ICACHE_DISABLE=y diff --git a/boards/arm64/zynq-mpsoc/zcu111/configs/nsh/defconfig b/boards/arm64/zynq-mpsoc/zcu111/configs/nsh/defconfig index 74b9e4a22c66f..1d7c7bbdf5773 100644 --- a/boards/arm64/zynq-mpsoc/zcu111/configs/nsh/defconfig +++ b/boards/arm64/zynq-mpsoc/zcu111/configs/nsh/defconfig @@ -13,6 +13,7 @@ CONFIG_ARCH_CHIP="zynq-mpsoc" CONFIG_ARCH_CHIP_ZYNQ_MPSOC=y CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 +CONFIG_ARCH_IRQPRIO=y CONFIG_ARM64_DCACHE_DISABLE=y CONFIG_ARM64_GIC_VERSION=2 CONFIG_ARM64_ICACHE_DISABLE=y diff --git a/boards/risc-v/esp32c3/common/scripts/esp32c3_legacy_sections.ld b/boards/risc-v/esp32c3/common/scripts/esp32c3_legacy_sections.ld index 30085c090d3f7..a78f41df69b81 100644 --- a/boards/risc-v/esp32c3/common/scripts/esp32c3_legacy_sections.ld +++ b/boards/risc-v/esp32c3/common/scripts/esp32c3_legacy_sections.ld @@ -72,9 +72,25 @@ SECTIONS *(.noinit.*) } >dram0_0_seg + .tbss (NOLOAD) : + { + . = ALIGN(4); + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon) + _etbss = ABSOLUTE(.); + . = ALIGN(4); + } >dram0_0_seg + .dram0.data : { + . = ALIGN(4); + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _etdata = ABSOLUTE(.); + . = ALIGN(4); + _sdata = ABSOLUTE(.); + *(.data) *(.data.*) *(.gnu.linkonce.d.*) diff --git a/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld b/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld index fd897e373a3ed..34e62006d6789 100644 --- a/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld +++ b/boards/risc-v/esp32c3/common/scripts/esp32c3_sections.ld @@ -248,10 +248,26 @@ SECTIONS . = ALIGN(4) ; } >dram0_0_seg + .tbss (NOLOAD) : + { + . = ALIGN(4); + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon) + _etbss = ABSOLUTE(.); + . = ALIGN(4); + } >dram0_0_seg + .dram0.data : { . = ALIGN (16); _data_start = ABSOLUTE(.); + + . = ALIGN(4); + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _etdata = ABSOLUTE(.); + . = ALIGN(4); + _sdata = ABSOLUTE(.); *(.data) *(.data.*) @@ -401,7 +417,7 @@ SECTIONS *(.fini) *(.gnu.version) - . = ALIGN(4); + . += 16; _text_end = ABSOLUTE(.); _instruction_reserved_end = ABSOLUTE(.); /* This is a symbol marking the flash.text end, this can be used for mmu driver to maintain virtual address */ @@ -511,7 +527,6 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) __init_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig index d718b452f4d0c..7c73421feaed8 100644 --- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig +++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/testlibcxx/defconfig @@ -35,6 +35,7 @@ CONFIG_PREALLOC_TIMERS=0 CONFIG_RR_INTERVAL=200 CONFIG_SCHED_BACKTRACE=y CONFIG_SCHED_WAITPID=y +CONFIG_SCHED_THREAD_LOCAL=y CONFIG_START_DAY=29 CONFIG_START_MONTH=11 CONFIG_START_YEAR=2019 @@ -56,4 +57,4 @@ CONFIG_TESTING_CXXTEST=y CONFIG_LIBC_LOCALE=y CONFIG_TLS_NELEM=16 CONFIG_TLS_TASK_NELEM=8 -CONFIG_DEFAULT_THREAD_STACKSIZE=4096 +CONFIG_DEFAULT_TASK_STACKSIZE=4096 diff --git a/boards/risc-v/esp32c3/esp32c3-xiao/configs/ble/defconfig b/boards/risc-v/esp32c3/esp32c3-xiao/configs/ble/defconfig index b85ccf328a750..0f69698320f04 100644 --- a/boards/risc-v/esp32c3/esp32c3-xiao/configs/ble/defconfig +++ b/boards/risc-v/esp32c3/esp32c3-xiao/configs/ble/defconfig @@ -28,8 +28,6 @@ CONFIG_DRIVERS_WIRELESS=y CONFIG_ESPRESSIF_BLE=y CONFIG_ESPRESSIF_USBSERIAL=y CONFIG_FS_PROCFS=y -CONFIG_HAVE_CXX=y -CONFIG_HAVE_CXXINITIALIZE=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INTELHEX_BINARY=y diff --git a/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld b/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld index ac34baa1d905e..edb0de6f6896f 100644 --- a/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld +++ b/boards/risc-v/esp32c6/common/scripts/esp32c6_sections.ld @@ -273,11 +273,28 @@ SECTIONS *(.noinit.*) } >dram0_0_seg + .tbss (NOLOAD) : + { + . = ALIGN(4); + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon) + _etbss = ABSOLUTE(.); + . = ALIGN(4); + } >dram0_0_seg + .dram0.data : { . = ALIGN (16); _data_start = ABSOLUTE(.); + + . = ALIGN(4); + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _etdata = ABSOLUTE(.); + . = ALIGN(4); + _sdata = ABSOLUTE(.); + *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -523,7 +540,6 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) __init_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ diff --git a/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld b/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld index 5020f2e50ebe3..8d0246fb8165c 100644 --- a/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld +++ b/boards/risc-v/esp32h2/common/scripts/esp32h2_sections.ld @@ -264,11 +264,28 @@ SECTIONS *(.noinit.*) } >dram0_0_seg + .tbss (NOLOAD) : + { + . = ALIGN(4); + _stbss = ABSOLUTE(.); + *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon) + _etbss = ABSOLUTE(.); + . = ALIGN(4); + } >dram0_0_seg + .dram0.data : { . = ALIGN (16); _data_start = ABSOLUTE(.); + + . = ALIGN(4); + _stdata = ABSOLUTE(.); + *(.tdata .tdata.* .gnu.linkonce.td.*) + _etdata = ABSOLUTE(.); + . = ALIGN(4); + _sdata = ABSOLUTE(.); + *(.data) *(.data.*) *(.gnu.linkonce.d.*) @@ -513,6 +530,7 @@ SECTIONS _sinit = ABSOLUTE(.); . = ALIGN(4); + _sdata = ABSOLUTE(.); __init_priority_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*)) __init_priority_array_end = ABSOLUTE(.); @@ -521,7 +539,6 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array)) __init_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ diff --git a/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig b/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig index c711d7defe273..f94782f57f09b 100644 --- a/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig +++ b/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig @@ -125,6 +125,7 @@ CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_POPEN=y CONFIG_SYSTEM_SETLOGMASK=y CONFIG_TESTING_CMOCKA=y +CONFIG_TESTING_CMOCKA_PROG=y CONFIG_TESTING_CXXTEST=y CONFIG_TESTING_FMEMOPEN_TEST=y CONFIG_TESTING_FOPENCOOKIE_TEST=y diff --git a/boards/sim/sim/sim/configs/citest/defconfig b/boards/sim/sim/sim/configs/citest/defconfig index 6f371fb9a4698..f6a89d075308d 100644 --- a/boards/sim/sim/sim/configs/citest/defconfig +++ b/boards/sim/sim/sim/configs/citest/defconfig @@ -133,6 +133,7 @@ CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_POPEN=y CONFIG_SYSTEM_SETLOGMASK=y CONFIG_TESTING_CMOCKA=y +CONFIG_TESTING_CMOCKA_PROG=y CONFIG_TESTING_CXXTEST=y CONFIG_TESTING_DRIVER_TEST=y CONFIG_TESTING_DRIVER_TEST_SIMPLE=y diff --git a/boards/sim/sim/sim/configs/posix_test/defconfig b/boards/sim/sim/sim/configs/posix_test/defconfig index c9a79c1866424..4e936955c260d 100644 --- a/boards/sim/sim/sim/configs/posix_test/defconfig +++ b/boards/sim/sim/sim/configs/posix_test/defconfig @@ -59,6 +59,8 @@ CONFIG_LIBC_NUMBERED_ARGS=y CONFIG_LIBC_PASSWD_FILE=y CONFIG_MQ_MAXMSGSIZE=64 CONFIG_NDEBUG=y +CONFIG_NET=y +CONFIG_NET_SOCKOPTS=y CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILE_APPS=y @@ -81,7 +83,6 @@ CONFIG_SCHED_LPNTHREADS=1 CONFIG_SCHED_LPWORK=y CONFIG_SCHED_SPORADIC=y CONFIG_SCHED_USER_IDENTITY=y -CONFIG_SCHED_WAITPID=y CONFIG_SIG_DEFAULT=y CONFIG_SIG_EVTHREAD=y CONFIG_SIM_HOSTFS=y @@ -91,6 +92,7 @@ CONFIG_START_MONTH=6 CONFIG_START_YEAR=2008 CONFIG_SYSTEM_DUMPSTACK=y CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_SYSTEM=y CONFIG_TESTING_LTP=y CONFIG_TLS_NCLEANUP=4 CONFIG_TLS_NELEM=16 diff --git a/boards/xtensa/esp32/common/scripts/esp32_sections.ld b/boards/xtensa/esp32/common/scripts/esp32_sections.ld index 3744aef809fe0..45aa551873c18 100644 --- a/boards/xtensa/esp32/common/scripts/esp32_sections.ld +++ b/boards/xtensa/esp32/common/scripts/esp32_sections.ld @@ -619,7 +619,6 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) __init_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ diff --git a/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld b/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld index 37c9a41c2eb3c..59b70e6ecb305 100644 --- a/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld +++ b/boards/xtensa/esp32s2/common/scripts/esp32s2_sections.ld @@ -529,7 +529,6 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) __init_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld b/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld index e8f301e47e017..5ecf431c2f5ca 100644 --- a/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld +++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld @@ -693,7 +693,6 @@ SECTIONS __init_array_start = ABSOLUTE(.); KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) __init_array_end = ABSOLUTE(.); - _einit = ABSOLUTE(.); /* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */ diff --git a/cmake/menuconfig.cmake b/cmake/menuconfig.cmake index 694c29845a62e..22093f57da1a7 100644 --- a/cmake/menuconfig.cmake +++ b/cmake/menuconfig.cmake @@ -95,6 +95,13 @@ add_custom_target( ${CMAKE_BINARY_DIR}/defconfig.tmp COMMAND ${CMAKE_COMMAND} -P ${NUTTX_DIR}/cmake/savedefconfig.cmake ${CMAKE_BINARY_DIR}/.config ${CMAKE_BINARY_DIR}/defconfig.tmp - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/defconfig - ${NUTTX_DEFCONFIG} + COMMAND + ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/process_config.py + postprocess ${CMAKE_BINARY_DIR}/config_tree.json + ${CMAKE_BINARY_DIR}/defconfig.orig ${CMAKE_BINARY_DIR}/defconfig + ${CMAKE_BINARY_DIR}/defconfig.post + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/defconfig.post ${NUTTX_DEFCONFIG} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/defconfig.post ${NUTTX_ORIG_DEFCONFIG} WORKING_DIRECTORY ${NUTTX_DIR}) diff --git a/cmake/nuttx_add_application.cmake b/cmake/nuttx_add_application.cmake index 1c8259e3a76b8..efee621dda720 100644 --- a/cmake/nuttx_add_application.cmake +++ b/cmake/nuttx_add_application.cmake @@ -233,9 +233,8 @@ function(nuttx_add_application) endif() if(INCLUDE_DIRECTORIES) - foreach(inc ${INCLUDE_DIRECTORIES}) - target_include_directories(${TARGET} PRIVATE ${inc}) - endforeach() + target_include_directories(${TARGET} BEFORE + PRIVATE ${INCLUDE_DIRECTORIES}) endif() endif() diff --git a/cmake/nuttx_add_library.cmake b/cmake/nuttx_add_library.cmake index 1b9b409f6b5f1..2b4c1172bf1d0 100644 --- a/cmake/nuttx_add_library.cmake +++ b/cmake/nuttx_add_library.cmake @@ -62,6 +62,12 @@ function(nuttx_add_library_internal target) # Set install config for all library install(TARGETS ${target}) + # Set target information for debug and dump + set_property( + TARGET nuttx_target_interface + APPEND + PROPERTY ALL_TARGETS ${target}) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/targets "${target}\n") endfunction() # Auxiliary libraries diff --git a/cmake/nuttx_extensions.cmake b/cmake/nuttx_extensions.cmake index 9eeb1164a5afa..89594dcdcfa42 100644 --- a/cmake/nuttx_extensions.cmake +++ b/cmake/nuttx_extensions.cmake @@ -28,6 +28,10 @@ include(nuttx_parse_function_args) # compiler options and include path needed by all apps libraries. add_custom_target(nuttx_apps_interface) +# "nuttx_target_interface" is a source-less target that hold target information +# for target debug and dump +add_custom_target(nuttx_target_interface) + # Macro: nuttx_library # # Creates a library target with the given name and mode. If MODE is "KERNEL", it @@ -153,7 +157,7 @@ endfunction() # Usage: nuttx_include_directories("include/path1" "include/path2") function(nuttx_include_directories) if(TARGET ${NX_CURRENT_LIBRARY}) - target_include_directories(${NX_CURRENT_LIBRARY} PRIVATE ${ARGN}) + target_include_directories(${NX_CURRENT_LIBRARY} PUBLIC ${ARGN}) endif() endfunction() @@ -298,3 +302,14 @@ function(nuttx_link_libraries) endforeach() endif() endfunction() + +# dump targets information +add_custom_target( + dump_targets + COMMAND ${CMAKE_COMMAND} -E remove target_dump + COMMAND ${CMAKE_COMMAND} -E echo + "'$'" + COMMAND + ${CMAKE_COMMAND} -E echo + "'$'" >> target_dump + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/cmake/nuttx_kconfig.cmake b/cmake/nuttx_kconfig.cmake index f9364ea9a2c62..cc55acc9f86bb 100644 --- a/cmake/nuttx_kconfig.cmake +++ b/cmake/nuttx_kconfig.cmake @@ -216,6 +216,18 @@ function(nuttx_olddefconfig) "nuttx_olddefconfig: Failed to initialize Kconfig configuration: ${KCONFIG_OUTPUT}" ) endif() + + # save the orig compressed formatted defconfig at the very beginning + execute_process(COMMAND savedefconfig --out ${CMAKE_BINARY_DIR}/defconfig.tmp + WORKING_DIRECTORY ${NUTTX_DIR}) + + execute_process( + COMMAND + ${CMAKE_COMMAND} -P ${NUTTX_DIR}/cmake/savedefconfig.cmake + ${CMAKE_BINARY_DIR}/.config.compressed ${CMAKE_BINARY_DIR}/defconfig.tmp + ${CMAKE_BINARY_DIR}/defconfig.orig + WORKING_DIRECTORY ${NUTTX_DIR}) + endfunction() function(nuttx_setconfig) diff --git a/cmake/nuttx_process_config.cmake b/cmake/nuttx_process_config.cmake index 8fab3b72eddd0..f66238b0f7e6a 100644 --- a/cmake/nuttx_process_config.cmake +++ b/cmake/nuttx_process_config.cmake @@ -20,7 +20,10 @@ # # ############################################################################## -function(process_config OUTPUT INPUT) +# save preprocess defconfig as orig by default +set(NUTTX_ORIG_DEFCONFIG ${NUTTX_DEFCONFIG}) + +function(process_config OUTPUT INPUT TREE_FILE) set(options) set(oneValueArgs) set(multiValueArgs INCLUDE_PATHS) @@ -32,10 +35,14 @@ function(process_config OUTPUT INPUT) list(APPEND include_args "${path}") endforeach() - message(STATUS "Processing includes: ${INPUT} -> ${OUTPUT}") + if(TREE_FILE) + set(TREE_OPTION --tree) + endif() + message(STATUS "Processing includes: ${INPUT} → ${OUTPUT}") execute_process( - COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/process_config.py - ${OUTPUT} ${INPUT} ${include_args} + COMMAND + ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/process_config.py + preprocess ${OUTPUT} ${INPUT} ${include_args} ${TREE_OPTION} ${TREE_FILE} RESULT_VARIABLE result OUTPUT_VARIABLE out ERROR_VARIABLE err) @@ -44,3 +51,28 @@ function(process_config OUTPUT INPUT) message(FATAL_ERROR "Failed to process includes:\n${err}") endif() endfunction() + +# fetch defconfig content +file(READ "${NUTTX_DEFCONFIG}" FILE_CONTENTS) +string(FIND "${FILE_CONTENTS}" "#include" INCLUDE_FOUND) + +if(NOT EXISTS ${CMAKE_BINARY_DIR}/.defconfig.processed) + set(TREE_FILE ${CMAKE_BINARY_DIR}/config_tree.json) +else() + set(TREE_FILE ${CMAKE_BINARY_DIR}/config_tree_dirty.json) +endif() +# Should we preprocess defconfig? +if(INCLUDE_FOUND GREATER -1) + get_filename_component(NUTTX_DEFCONFIG_DIR "${NUTTX_DEFCONFIG}" DIRECTORY) + process_config( + ${CMAKE_BINARY_DIR}/.defconfig.processed + ${NUTTX_DEFCONFIG} + ${TREE_FILE} + INCLUDE_PATHS + ${NUTTX_DEFCONFIG_DIR}/../../common/configs + ${NUTTX_DEFCONFIG_DIR}/../common + ${NUTTX_DEFCONFIG_DIR} + ${NUTTX_DIR}/../apps + ${NUTTX_DIR}/../nuttx-apps) + set(NUTTX_DEFCONFIG ${CMAKE_BINARY_DIR}/.defconfig.processed) +endif() diff --git a/cmake/nuttx_toolchain.cmake b/cmake/nuttx_toolchain.cmake index 0b728f2c47f44..beecf63424a20 100644 --- a/cmake/nuttx_toolchain.cmake +++ b/cmake/nuttx_toolchain.cmake @@ -30,6 +30,22 @@ if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") endif() endif() +# Cmake build provide absolute paths to compile files. If __FILE__ macros are +# used in the source code(ASSERT), the binary will contain many invalid paths. +# This saves some memory, stops exposing build systems locations in binaries, +# make failure logs more deterministic and most importantly makes builds more +# failure logs more deterministic and most importantly makes builds more +# deterministic. Debuggers usually have a path mapping feature to ensure the +# files are still found. +if((NOT MSVC) AND (NOT CONFIG_ARCH_TOOLCHAIN_GHS)) + if(CONFIG_OUTPUT_STRIP_PATHS) + add_compile_options(-fmacro-prefix-map=${NUTTX_DIR}=) + add_compile_options(-fmacro-prefix-map=${NUTTX_APPS_DIR}=) + add_compile_options(-fmacro-prefix-map=${NUTTX_BOARD_ABS_DIR}=) + add_compile_options(-fmacro-prefix-map=${NUTTX_CHIP_ABS_DIR}=) + endif() +endif() + # Support CMake to define additional configuration options if(EXTRA_FLAGS) diff --git a/cmake/savedefconfig.cmake b/cmake/savedefconfig.cmake index c6f06e3ff4cef..de94ff10e0fd1 100644 --- a/cmake/savedefconfig.cmake +++ b/cmake/savedefconfig.cmake @@ -45,8 +45,11 @@ endforeach() get_filename_component(BINARY_DIR "${TARGET_FILE}" DIRECTORY) -set(OUTPUT_FILE ${BINARY_DIR}/defconfig) - +if(CMAKE_ARGV5) + set(OUTPUT_FILE ${CMAKE_ARGV5}) +else() + set(OUTPUT_FILE ${BINARY_DIR}/defconfig) +endif() # cmake-format: off file(WRITE ${OUTPUT_FILE} "") file(APPEND ${OUTPUT_FILE} "\#\n") diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c index ce242b871809c..bd9cfe9367319 100644 --- a/crypto/cryptodev.c +++ b/crypto/cryptodev.c @@ -228,6 +228,8 @@ static int cryptof_ioctl(FAR struct file *filep, case CRYPTO_BLF_CBC: case CRYPTO_CAST_CBC: case CRYPTO_AES_CBC: + case CRYPTO_AES_192_CBC: + case CRYPTO_AES_256_CBC: case CRYPTO_AES_CMAC: case CRYPTO_AES_CTR: case CRYPTO_AES_XTS: @@ -980,6 +982,7 @@ static int cryptof_open(FAR struct file *filep) kmm_free(cria.cri_key); } + free(fcrd); return ret; } diff --git a/drivers/can/can_sender.c b/drivers/can/can_sender.c index 666fbd07b416e..eee0cabd6fee4 100644 --- a/drivers/can/can_sender.c +++ b/drivers/can/can_sender.c @@ -25,6 +25,7 @@ ****************************************************************************/ #include +#include #include /**************************************************************************** diff --git a/drivers/drivers_initialize.c b/drivers/drivers_initialize.c index 1a012f928e71a..7393f37d93d5e 100644 --- a/drivers/drivers_initialize.c +++ b/drivers/drivers_initialize.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -267,6 +268,12 @@ void drivers_initialize(void) usrsock_rpmsg_server_initialize(); #endif +#ifdef CONFIG_NET_RPMSG_DRV_SERVER + /* Initialize the net rpmsg default server */ + + net_rpmsg_drv_server_init(); +#endif + #ifdef CONFIG_SMART_DEV_LOOP smart_loop_register_driver(); #endif diff --git a/drivers/misc/optee.c b/drivers/misc/optee.c index 5d49136aab61b..71497f461180c 100644 --- a/drivers/misc/optee.c +++ b/drivers/misc/optee.c @@ -36,6 +36,7 @@ #include #ifdef CONFIG_ARCH_ADDRENV +# include # include # include # include diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c index a9cdf7fbf7e14..1149e821ac142 100644 --- a/drivers/mmcsd/mmcsd_sdio.c +++ b/drivers/mmcsd/mmcsd_sdio.c @@ -951,7 +951,7 @@ static void mmcsd_decode_csd(FAR struct mmcsd_state_s *priv, uint32_t csd[4]) finfo(" FILE_FORMAT: %d ECC: %d (MMC) CRC: %d\n", decoded.fileformat, decoded.mmcecc, decoded.crc); - finfo("Capacity: %luKb, Block size: %db, nblocks: %d wrprotect: %d\n", + finfo("Capacity: %luKB, Block size: %dB, nblocks: %d wrprotect: %d\n", (unsigned long)MMCSD_CAPACITY(priv->part[0].nblocks, priv->blockshift), priv->blocksize, priv->part[0].nblocks, priv->wrprotect); diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 3686d8bcc5261..08b6472f7b7d7 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -189,20 +189,12 @@ config MTD_CONFIG_NAME_LEN config MTD_CONFIG_FAIL_SAFE bool "Enable Fail Safe MTD Config" default n - depends on MTD_BYTE_WRITE ---help--- Enable the new storage layout to support the resilient to power loss. This replaces the drivers/mtd/mtd_config, which is resilient to power loss. -config MTD_WRITE_ALIGN_SIZE - int "align size [1,2,4,8,16] for per write operation" - default 1 - depends on MTD_CONFIG_FAIL_SAFE - ---help--- - align size will be one of 1,2,4,8,16 - -config MTD_BLOCKSIZE_MULTIPLE +config MTD_CONFIG_BLOCKSIZE_MULTIPLE int "Set NVS blocksize multiple" default 1 depends on MTD_CONFIG_FAIL_SAFE @@ -1503,4 +1495,17 @@ config MTD_CFI ---help--- Support CFI(common flash interface) NOR FLASH. +config MTD_CFI_PAGE_SIZE + int "Page Size of MTD CFI NOR FLASH (bytes)" + default 16 + range 1 524288 + depends on MTD_CFI + ---help--- + Configure the write page size (in bytes) used by the CFI NOR Flash + driver. The value must be at least 1 and should not exceed the maximum + write buffer size supported by the CFI device. + In the driver, this capability is typically exposed as the device's + "write page size" parameter for each write, so this configuration + value should be chosen such that it is equal to write page size for + the target flash. endif # MTD diff --git a/drivers/mtd/cfi.c b/drivers/mtd/cfi.c index c51f5ed881431..ce6e1c3ab6bc3 100644 --- a/drivers/mtd/cfi.c +++ b/drivers/mtd/cfi.c @@ -969,8 +969,9 @@ int cfi_check(FAR struct cfi_dev_s *cfi) cfi->cfi_offset = g_cfi_query_address[i]; cfi->dev_num = cfi->bankwidth / cfi->dev_width; - cfi->page_size = (1 << info->max_write_bytes_num) * - cfi->dev_num; + cfi->page_size = MIN(CONFIG_MTD_CFI_PAGE_SIZE, + (1 << info->max_write_bytes_num) * + cfi->dev_num); /* fix amd feature */ diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index ace0eeb2c539b..253ce90564264 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -392,13 +392,14 @@ static ssize_t ftl_mtd_erase(FAR struct ftl_struct_s *dev, off_t startblock) if (dev->lptable == NULL) { ret = MTD_ERASE(dev->mtd, startblock, 1); - if (ret < 0) + if (ret < 0 && ret != -ENOSYS) { ferr("ERROR: Erase block %" PRIdOFF " failed: %zd\n", startblock, ret); + return ret; } - return ret; + return OK; } while (1) @@ -409,9 +410,9 @@ static ssize_t ftl_mtd_erase(FAR struct ftl_struct_s *dev, off_t startblock) } ret = MTD_ERASE(dev->mtd, dev->lptable[startblock], 1); - if (ret == 1) + if (ret >= 0 || ret == -ENOSYS) { - return ret; + return OK; } MTD_MARKBAD(dev->mtd, dev->lptable[startblock]); @@ -561,6 +562,18 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, int nbytes; int ret; + if (dev->mtd->erase == NULL && dev->lptable == NULL) + { + ret = MTD_BWRITE(dev->mtd, startblock, nblocks, buffer); + if (ret != nblocks) + { + ferr("ERROR: Direct write block %" PRIdOFF " failed: %d\n", + startblock, ret); + } + + return ret; + } + if (dev->oflags & O_DIRECT) { /* Direct write mode */ diff --git a/drivers/mtd/mtd_config_fs.c b/drivers/mtd/mtd_config_fs.c index 0b89520648961..37215d5e1982d 100644 --- a/drivers/mtd/mtd_config_fs.c +++ b/drivers/mtd/mtd_config_fs.c @@ -51,35 +51,13 @@ * low 2 bytes represent the offset in a block */ -#define ADDR_BLOCK_MASK 0xFFFF0000 -#define ADDR_BLOCK_SHIFT 16 -#define ADDR_OFFS_MASK 0x0000FFFF +#define NVS_ADDR_BLOCK_MASK 0xFFFF0000 +#define NVS_ADDR_BLOCK_SHIFT 16 +#define NVS_ADDR_OFFS_MASK 0x0000FFFF -/* We don't want to store all the read content in stack or heap, - * so we make a buffer to do compare or move. - */ - -#define NVS_BUFFER_SIZE MAX(NVS_ALIGN_UP(32), NVS_ALIGN_SIZE) - -/* If data is written after last ate, and power loss happens, - * we need to find a clean offset by skipping dirty data. - * This macro defines how many bytes to skip when dirty data - * is spotted(may take several skips). - * Normally 1 byte is okay, such process only happens when - * nvs is started, and it is acceptable to take some time during - * starting. - */ - -#define NVS_CORRUPT_DATA_SKIP_STEP NVS_ALIGN_SIZE - -/* Gc done or close ate has the id of 0xffffffff. - * We can tell if the ate is special by looking at its id. - */ - -#define NVS_SPECIAL_ATE_ID 0xffffffff - -#define NVS_ALIGN_SIZE CONFIG_MTD_WRITE_ALIGN_SIZE -#define NVS_ALIGN_UP(x) (((x) + NVS_ALIGN_SIZE - 1) & ~(NVS_ALIGN_SIZE - 1)) +#define NVS_ATE(name, size) \ + char name##_buf[size]; \ + FAR struct nvs_ate *name = (FAR struct nvs_ate *)name##_buf /**************************************************************************** * Private Types @@ -90,6 +68,7 @@ struct nvs_fs { FAR struct mtd_dev_s *mtd; /* MTD device */ + uint32_t progsize; /* Size of one read/write block */ uint32_t blocksize; /* Size of one nvs block */ uint32_t nblocks; /* Number of nvs blocks */ uint8_t erasestate; /* Erased value */ @@ -113,15 +92,7 @@ begin_packed_struct struct nvs_ate uint16_t key_len; /* Key string len */ uint8_t part; /* Part of a multipart data - future extension */ uint8_t crc8; /* Crc8 check of the ate entry */ -#if CONFIG_MTD_WRITE_ALIGN_SIZE <= 4 - /* stay compatible with situation which align byte be 1 */ - - uint8_t expired[NVS_ALIGN_SIZE]; - uint8_t reserved[4 - NVS_ALIGN_SIZE]; -#else - uint8_t padding[NVS_ALIGN_UP(12) - 12]; - uint8_t expired[NVS_ALIGN_SIZE]; -#endif + uint8_t expired[0]; } end_packed_struct; /**************************************************************************** @@ -189,6 +160,66 @@ static uint32_t nvs_fnv_hash(FAR const uint8_t *input, uint32_t len) return hval; } +/**************************************************************************** + * Name: nvs_align_up + ****************************************************************************/ + +static inline size_t nvs_align_up(FAR struct nvs_fs *fs, size_t len) +{ + return (len + (fs->progsize - 1)) & ~(fs->progsize - 1); +} + +/**************************************************************************** + * Name: nvs_ate_size + ****************************************************************************/ + +static inline size_t nvs_ate_size(FAR struct nvs_fs *fs) +{ + /* Stay compatible with situation which align byte be 1 */ + + if (fs->progsize == 1) + { + return sizeof(struct nvs_ate) + 4; + } + + return nvs_align_up(fs, sizeof(struct nvs_ate)) + fs->progsize; +} + +/**************************************************************************** + * Name: nvs_buffer_size + ****************************************************************************/ + +static inline size_t nvs_buffer_size(FAR struct nvs_fs *fs) +{ + return nvs_align_up(fs, 32); +} + +/**************************************************************************** + * Name: nvs_ate_expired + ****************************************************************************/ + +static inline bool nvs_ate_expired(FAR struct nvs_fs *fs, + FAR struct nvs_ate *entry) +{ + return entry->expired[nvs_align_up(fs, sizeof(*entry)) - sizeof(*entry)] != + fs->erasestate; +} + +/**************************************************************************** + * Name: nvs_special_ate_id + * + * Description: + * Gc done or close ate has the id of 0xffffffff. + * We can tell if the ate is special by looking at its id. + * + ****************************************************************************/ + +static inline uint32_t nvs_special_ate_id(FAR struct nvs_fs *fs) +{ + return (fs->erasestate << 24) | (fs->erasestate << 16) | + (fs->erasestate << 8) | fs->erasestate; +} + /**************************************************************************** * Name: nvs_flash_wrt * @@ -201,18 +232,58 @@ static int nvs_flash_wrt(FAR struct nvs_fs *fs, uint32_t addr, FAR const void *data, size_t len) { off_t offset; - int ret; + int rc; - offset = fs->blocksize * (addr >> ADDR_BLOCK_SHIFT); - offset += addr & ADDR_OFFS_MASK; + offset = fs->blocksize * (addr >> NVS_ADDR_BLOCK_SHIFT); + offset += addr & NVS_ADDR_OFFS_MASK; - ret = MTD_WRITE(fs->mtd, offset, len, data); - if (ret < 0) +#ifdef CONFIG_MTD_BYTE_WRITE + rc = MTD_WRITE(fs->mtd, offset, len, data); +#else + rc = MTD_BWRITE(fs->mtd, offset / fs->progsize, len / fs->progsize, data); +#endif + + return rc < 0 ? rc : 0; +} + +/**************************************************************************** + * Name: nvs_flash_brd + ****************************************************************************/ + +static int nvs_flash_brd(FAR struct nvs_fs *fs, off_t offset, + FAR void *data, size_t len) +{ + int rc; + +#ifdef CONFIG_MTD_BYTE_WRITE + rc = MTD_READ(fs->mtd, offset, len, data); +#else + rc = MTD_BREAD(fs->mtd, offset / fs->progsize, len / fs->progsize, data); +#endif + if (rc == -EBADMSG) { - return ret; + /* ECC fail first time + * try again to avoid transient electronic interference + */ + +#ifdef CONFIG_MTD_BYTE_WRITE + rc = MTD_READ(fs->mtd, offset, len, data); +#else + rc = MTD_BREAD(fs->mtd, offset / fs->progsize, len / fs->progsize, + data); +#endif + if (rc == -EBADMSG) + { + /* ECC fail second time + * fill ~erasestate to trigger recovery process + */ + + memset(data, ~fs->erasestate, len); + rc = 0; + } } - return OK; + return rc < 0 ? rc : 0; } /**************************************************************************** @@ -226,32 +297,67 @@ static int nvs_flash_wrt(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_rd(FAR struct nvs_fs *fs, uint32_t addr, FAR void *data, size_t len) { +#ifdef CONFIG_MTD_BYTE_WRITE off_t offset; - int ret; - offset = fs->blocksize * (addr >> ADDR_BLOCK_SHIFT); - offset += addr & ADDR_OFFS_MASK; + offset = fs->blocksize * (addr >> NVS_ADDR_BLOCK_SHIFT); + offset += addr & NVS_ADDR_OFFS_MASK; - ret = MTD_READ(fs->mtd, offset, len, data); - if (ret == -EBADMSG) + return nvs_flash_brd(fs, offset, data, len); +#else + uint8_t buf[fs->progsize]; + size_t bytes_to_rd; + off_t begin_padding; + off_t offset; + int rc; + + offset = fs->blocksize * (addr >> NVS_ADDR_BLOCK_SHIFT) + + (addr & NVS_ADDR_OFFS_MASK); + begin_padding = offset % fs->progsize; + + if (begin_padding > 0) { - /* ECC fail first time - * try again to avoid transient electronic interference - */ + offset -= begin_padding; + bytes_to_rd = MIN(fs->progsize - begin_padding, len); + rc = nvs_flash_brd(fs, offset, buf, fs->progsize); + if (rc < 0) + { + return rc; + } - ret = MTD_READ(fs->mtd, offset, len, data); - if (ret == -EBADMSG) + memcpy(data, buf + begin_padding, bytes_to_rd); + offset += fs->progsize; + data += bytes_to_rd; + len -= bytes_to_rd; + } + + if (len >= fs->progsize) + { + bytes_to_rd = len / fs->progsize * fs->progsize; + rc = nvs_flash_brd(fs, offset, data, bytes_to_rd); + if (rc < 0) { - /* ECC fail second time - * fill ~erasestate to trigger recovery process - */ + return rc; + } - memset(data, ~fs->erasestate, len); - ret = 0; + offset += bytes_to_rd; + data += bytes_to_rd; + len -= bytes_to_rd; + } + + if (len > 0) + { + rc = nvs_flash_brd(fs, offset, buf, fs->progsize); + if (rc < 0) + { + return rc; } + + memcpy(data, buf, len); } - return ret < 0 ? ret : 0; + return 0; +#endif } /**************************************************************************** @@ -265,10 +371,11 @@ static int nvs_flash_rd(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_ate_wrt(FAR struct nvs_fs *fs, FAR const struct nvs_ate *entry) { + size_t ate_size = nvs_ate_size(fs); int rc; - rc = nvs_flash_wrt(fs, fs->ate_wra, entry, sizeof(struct nvs_ate)); - fs->ate_wra -= sizeof(struct nvs_ate); + rc = nvs_flash_wrt(fs, fs->ate_wra, entry, ate_size); + fs->ate_wra -= ate_size; return rc; } @@ -297,7 +404,7 @@ static int nvs_flash_data_wrt(FAR struct nvs_fs *fs, static int nvs_flash_ate_rd(FAR struct nvs_fs *fs, uint32_t addr, FAR struct nvs_ate *entry) { - return nvs_flash_rd(fs, addr, entry, sizeof(struct nvs_ate)); + return nvs_flash_rd(fs, addr, entry, nvs_ate_size(fs)); } /**************************************************************************** @@ -314,13 +421,13 @@ static int nvs_flash_block_cmp(FAR struct nvs_fs *fs, uint32_t addr, FAR const void *data, size_t len) { FAR const uint8_t *data8 = (FAR const uint8_t *)data; - int rc; + uint8_t buf[nvs_buffer_size(fs)]; size_t bytes_to_cmp; - uint8_t buf[NVS_BUFFER_SIZE]; + int rc; while (len > 0) { - bytes_to_cmp = MIN(NVS_BUFFER_SIZE, len); + bytes_to_cmp = MIN(sizeof(buf), len); rc = nvs_flash_rd(fs, addr, buf, bytes_to_cmp); if (rc) { @@ -354,14 +461,14 @@ static int nvs_flash_block_cmp(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_direct_cmp(FAR struct nvs_fs *fs, uint32_t addr1, uint32_t addr2, size_t len) { - int rc; + uint8_t buf1[nvs_buffer_size(fs)]; + uint8_t buf2[sizeof(buf1)]; size_t bytes_to_cmp; - uint8_t buf1[NVS_BUFFER_SIZE]; - uint8_t buf2[NVS_BUFFER_SIZE]; + int rc; while (len > 0) { - bytes_to_cmp = MIN(NVS_BUFFER_SIZE, len); + bytes_to_cmp = MIN(sizeof(buf1), len); rc = nvs_flash_rd(fs, addr1, buf1, bytes_to_cmp); if (rc) { @@ -401,14 +508,14 @@ static int nvs_flash_direct_cmp(FAR struct nvs_fs *fs, uint32_t addr1, static int nvs_flash_cmp_const(FAR struct nvs_fs *fs, uint32_t addr, uint8_t value, size_t len) { - int rc; + uint8_t cmp[nvs_buffer_size(fs)]; size_t bytes_to_cmp; - uint8_t cmp[NVS_BUFFER_SIZE]; + int rc; - memset(cmp, value, NVS_BUFFER_SIZE); + memset(cmp, value, sizeof(cmp)); while (len > 0) { - bytes_to_cmp = MIN(NVS_BUFFER_SIZE, len); + bytes_to_cmp = MIN(sizeof(cmp), len); rc = nvs_flash_block_cmp(fs, addr, cmp, bytes_to_cmp); if (rc) { @@ -434,13 +541,13 @@ static int nvs_flash_cmp_const(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_block_move(FAR struct nvs_fs *fs, uint32_t addr, size_t len) { - int rc; + uint8_t buf[nvs_buffer_size(fs)]; size_t bytes_to_copy; - uint8_t buf[NVS_BUFFER_SIZE]; + int rc; while (len) { - bytes_to_copy = MIN(NVS_BUFFER_SIZE, len); + bytes_to_copy = MIN(sizeof(buf), len); rc = nvs_flash_rd(fs, addr, buf, bytes_to_copy); if (rc) { @@ -475,8 +582,9 @@ static int nvs_flash_erase_block(FAR struct nvs_fs *fs, uint32_t addr) finfo("Erasing addr %" PRIx32 "\n", addr); rc = MTD_ERASE(fs->mtd, - CONFIG_MTD_BLOCKSIZE_MULTIPLE * (addr >> ADDR_BLOCK_SHIFT), - CONFIG_MTD_BLOCKSIZE_MULTIPLE); + CONFIG_MTD_CONFIG_BLOCKSIZE_MULTIPLE * + (addr >> NVS_ADDR_BLOCK_SHIFT), + CONFIG_MTD_CONFIG_BLOCKSIZE_MULTIPLE); if (rc < 0) { ferr("Erasing failed %d\n", rc); @@ -508,22 +616,17 @@ static void nvs_ate_crc8_update(FAR struct nvs_ate *entry) * * Description: * Crc check on allocation entry. - * Returns 0 if OK, 1 on crc fail. + * Returns true if OK, false on crc fail. * ****************************************************************************/ -static int nvs_ate_crc8_check(FAR const struct nvs_ate *entry) +static bool nvs_ate_crc8_check(FAR const struct nvs_ate *entry) { uint8_t ate_crc; ate_crc = crc8part((FAR const uint8_t *)entry, offsetof(struct nvs_ate, crc8), 0xff); - if (ate_crc == entry->crc8) - { - return 0; - } - - return 1; + return ate_crc == entry->crc8; } /**************************************************************************** @@ -536,12 +639,12 @@ static int nvs_ate_crc8_check(FAR const struct nvs_ate *entry) ****************************************************************************/ static int nvs_ate_cmp_const(FAR const struct nvs_ate *entry, - uint8_t value) + uint8_t value, size_t len) { FAR const uint8_t *data8 = (FAR const uint8_t *)entry; - int i; + size_t i; - for (i = 0; i < sizeof(struct nvs_ate); i++) + for (i = 0; i < len; i++) { if (data8[i] != value) { @@ -556,20 +659,15 @@ static int nvs_ate_cmp_const(FAR const struct nvs_ate *entry, * Name: nvs_ate_valid * * Description: - * Return 1 if crc8 and offset valid, 0 otherwise + * Return true if crc8 and offset valid, false otherwise * ****************************************************************************/ -static int nvs_ate_valid(FAR struct nvs_fs *fs, +static bool nvs_ate_valid(FAR struct nvs_fs *fs, FAR const struct nvs_ate *entry) { - if (nvs_ate_crc8_check(entry) || - entry->offset >= (fs->blocksize - sizeof(struct nvs_ate))) - { - return 0; - } - - return 1; + return nvs_ate_crc8_check(entry) && + entry->offset < (fs->blocksize - nvs_ate_size(fs)); } /**************************************************************************** @@ -581,25 +679,25 @@ static int nvs_ate_valid(FAR struct nvs_fs *fs, * - Calid ate. * - Len = 0 and id = 0xFFFFFFFF. * - Offset points to location at ate multiple from block size. - * Return 1 if valid, 0 otherwise. + * Return true if valid, false otherwise. * ****************************************************************************/ -static int nvs_close_ate_valid(FAR struct nvs_fs *fs, +static bool nvs_close_ate_valid(FAR struct nvs_fs *fs, FAR const struct nvs_ate *entry) { if (!nvs_ate_valid(fs, entry) || entry->len != 0 || - entry->id != NVS_SPECIAL_ATE_ID) + entry->id != nvs_special_ate_id(fs)) { - return 0; + return false; } - if ((fs->blocksize - entry->offset) % sizeof(struct nvs_ate)) + if ((fs->blocksize - entry->offset) % nvs_ate_size(fs)) { - return 0; + return false; } - return 1; + return true; } /**************************************************************************** @@ -616,14 +714,12 @@ static int nvs_close_ate_valid(FAR struct nvs_fs *fs, int nvs_flash_write_multi_blk(FAR struct nvs_fs *fs, const uint8_t *addr, size_t size) { - size_t blk_cnt; int left; int rc; - blk_cnt = size / NVS_ALIGN_SIZE; - left = size % NVS_ALIGN_SIZE; + left = size % fs->progsize; - if (blk_cnt) + if (size > left) { rc = nvs_flash_data_wrt(fs, addr, size - left); if (rc) @@ -648,19 +744,20 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, FAR const uint8_t *key, size_t key_size, FAR const void *data, size_t len) { - int rc; - struct nvs_ate entry; - uint16_t left; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(entry, ate_size); + uint8_t buf[fs->progsize]; uint16_t copy_len = 0; - uint8_t buf[NVS_ALIGN_SIZE]; + uint16_t left; + int rc; - memset(&entry, fs->erasestate, sizeof(entry)); - entry.id = id; - entry.offset = fs->data_wra & ADDR_OFFS_MASK; - entry.len = len; - entry.key_len = key_size; + memset(entry, fs->erasestate, ate_size); + entry->id = id; + entry->offset = fs->data_wra & NVS_ADDR_OFFS_MASK; + entry->len = len; + entry->key_len = key_size; - nvs_ate_crc8_update(&entry); + nvs_ate_crc8_update(entry); /* Let's save key and data into one, key comes first, then data */ @@ -675,14 +772,14 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, /* Write align block which include part key + part data */ left = rc; - memset(buf, fs->erasestate, NVS_ALIGN_SIZE); + memset(buf, fs->erasestate, sizeof(buf)); - copy_len = (left + len) <= NVS_ALIGN_SIZE ? - len : (NVS_ALIGN_SIZE - left); + copy_len = (left + len) <= sizeof(buf) ? + len : (sizeof(buf) - left); memcpy(buf, key + key_size - left, left); memcpy(buf + left, data, copy_len); - rc = nvs_flash_data_wrt(fs, buf, NVS_ALIGN_SIZE); + rc = nvs_flash_data_wrt(fs, buf, sizeof(buf)); if (rc) { ferr("Write value failed, rc=%d\n", rc); @@ -701,10 +798,10 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, /* Add padding at the end of data */ left = rc; - memset(buf, fs->erasestate, NVS_ALIGN_SIZE); + memset(buf, fs->erasestate, sizeof(buf)); memcpy(buf, data + len - left, left); - rc = nvs_flash_data_wrt(fs, buf, NVS_ALIGN_SIZE); + rc = nvs_flash_data_wrt(fs, buf, sizeof(buf)); if (rc) { ferr("Write value failed, rc=%d\n", rc); @@ -714,7 +811,7 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, /* Last, let's save entry to flash */ - rc = nvs_flash_ate_wrt(fs, &entry); + rc = nvs_flash_ate_wrt(fs, entry); if (rc) { ferr("Write ate failed, rc=%d\n", rc); @@ -740,41 +837,42 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, static int nvs_recover_last_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr) { + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(end_ate, ate_size); uint32_t data_end_addr; uint32_t ate_end_addr; - struct nvs_ate end_ate; int rc; finfo("Recovering last ate from block %" PRIu32 "\n", - (*addr >> ADDR_BLOCK_SHIFT)); + (*addr >> NVS_ADDR_BLOCK_SHIFT)); - *addr -= sizeof(struct nvs_ate); + *addr -= ate_size; ate_end_addr = *addr; - data_end_addr = *addr & ADDR_BLOCK_MASK; + data_end_addr = *addr & NVS_ADDR_BLOCK_MASK; while (ate_end_addr > data_end_addr) { - rc = nvs_flash_ate_rd(fs, ate_end_addr, &end_ate); + rc = nvs_flash_ate_rd(fs, ate_end_addr, end_ate); if (rc) { return rc; } - if (nvs_ate_valid(fs, &end_ate)) + if (nvs_ate_valid(fs, end_ate)) { /* Found a valid ate, update data_end_addr and *addr */ - data_end_addr &= ADDR_BLOCK_MASK; - data_end_addr += end_ate.offset + - NVS_ALIGN_UP(end_ate.key_len + end_ate.len); + data_end_addr &= NVS_ADDR_BLOCK_MASK; + data_end_addr += end_ate->offset + + nvs_align_up(fs, end_ate->key_len + end_ate->len); *addr = ate_end_addr; } - if (ate_end_addr < sizeof(struct nvs_ate)) + if (ate_end_addr < ate_size) { break; } - ate_end_addr -= sizeof(struct nvs_ate); + ate_end_addr -= ate_size; } return 0; @@ -792,8 +890,9 @@ static int nvs_recover_last_ate(FAR struct nvs_fs *fs, static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, FAR struct nvs_ate *ate) { + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(close_ate, ate_size); int rc; - struct nvs_ate close_ate; rc = nvs_flash_ate_rd(fs, *addr, ate); if (rc) @@ -801,31 +900,30 @@ static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, return rc; } - *addr += sizeof(struct nvs_ate); - if (((*addr) & ADDR_OFFS_MASK) != - (fs->blocksize - sizeof(struct nvs_ate))) + *addr += ate_size; + if (((*addr) & NVS_ADDR_OFFS_MASK) != (fs->blocksize - ate_size)) { return 0; } /* Last ate in block, do jump to previous block */ - if (((*addr) >> ADDR_BLOCK_SHIFT) == 0) + if (((*addr) >> NVS_ADDR_BLOCK_SHIFT) == 0) { - *addr += ((fs->nblocks - 1) << ADDR_BLOCK_SHIFT); + *addr += ((fs->nblocks - 1) << NVS_ADDR_BLOCK_SHIFT); } else { - *addr -= (1 << ADDR_BLOCK_SHIFT); + *addr -= (1 << NVS_ADDR_BLOCK_SHIFT); } - rc = nvs_flash_ate_rd(fs, *addr, &close_ate); + rc = nvs_flash_ate_rd(fs, *addr, close_ate); if (rc) { return rc; } - rc = nvs_ate_cmp_const(&close_ate, fs->erasestate); + rc = nvs_ate_cmp_const(close_ate, fs->erasestate, ate_size); /* At the end of filesystem */ @@ -837,10 +935,10 @@ static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, /* Update the address if the close ate is valid. */ - if (nvs_close_ate_valid(fs, &close_ate)) + if (nvs_close_ate_valid(fs, close_ate)) { - *addr &= ADDR_BLOCK_MASK; - *addr += close_ate.offset; + *addr &= NVS_ADDR_BLOCK_MASK; + *addr += close_ate->offset; return 0; } @@ -861,10 +959,10 @@ static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, static void nvs_block_advance(FAR struct nvs_fs *fs, FAR uint32_t *addr) { - *addr += (1 << ADDR_BLOCK_SHIFT); - if ((*addr >> ADDR_BLOCK_SHIFT) == fs->nblocks) + *addr += (1 << NVS_ADDR_BLOCK_SHIFT); + if ((*addr >> NVS_ADDR_BLOCK_SHIFT) == fs->nblocks) { - *addr -= (fs->nblocks << ADDR_BLOCK_SHIFT); + *addr -= (fs->nblocks << NVS_ADDR_BLOCK_SHIFT); } } @@ -879,22 +977,22 @@ static void nvs_block_advance(FAR struct nvs_fs *fs, FAR uint32_t *addr) static int nvs_block_close(FAR struct nvs_fs *fs) { + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(close_ate, ate_size); int rc; - struct nvs_ate close_ate; - memset(&close_ate, fs->erasestate, sizeof(close_ate)); - close_ate.id = NVS_SPECIAL_ATE_ID; - close_ate.len = 0; - close_ate.key_len = 0; - close_ate.offset = - (fs->ate_wra + sizeof(struct nvs_ate)) & ADDR_OFFS_MASK; + memset(close_ate, fs->erasestate, ate_size); + close_ate->id = nvs_special_ate_id(fs); + close_ate->len = 0; + close_ate->key_len = 0; + close_ate->offset = (fs->ate_wra + ate_size) & NVS_ADDR_OFFS_MASK; - fs->ate_wra &= ADDR_BLOCK_MASK; - fs->ate_wra += fs->blocksize - sizeof(struct nvs_ate); + fs->ate_wra &= NVS_ADDR_BLOCK_MASK; + fs->ate_wra += fs->blocksize - ate_size; - nvs_ate_crc8_update(&close_ate); + nvs_ate_crc8_update(close_ate); - rc = nvs_flash_ate_wrt(fs, &close_ate); + rc = nvs_flash_ate_wrt(fs, close_ate); if (rc < 0) { ferr("Write ate failed, rc=%d\n", rc); @@ -902,7 +1000,7 @@ static int nvs_block_close(FAR struct nvs_fs *fs) nvs_block_advance(fs, &fs->ate_wra); - fs->data_wra = fs->ate_wra & ADDR_BLOCK_MASK; + fs->data_wra = fs->ate_wra & NVS_ADDR_BLOCK_MASK; finfo("block close, data_wra=0x%" PRIx32 "\n", fs->data_wra); return 0; @@ -914,17 +1012,19 @@ static int nvs_block_close(FAR struct nvs_fs *fs) static int nvs_add_gc_done_ate(FAR struct nvs_fs *fs) { - struct nvs_ate gc_done_ate; - - finfo("Adding gc done ate at %" PRIx32 "\n", fs->ate_wra & ADDR_OFFS_MASK); - memset(&gc_done_ate, fs->erasestate, sizeof(gc_done_ate)); - gc_done_ate.id = NVS_SPECIAL_ATE_ID; - gc_done_ate.len = 0; - gc_done_ate.key_len = 0; - gc_done_ate.offset = fs->data_wra & ADDR_OFFS_MASK; - nvs_ate_crc8_update(&gc_done_ate); - - return nvs_flash_ate_wrt(fs, &gc_done_ate); + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(gc_done_ate, ate_size); + + finfo("Adding gc done ate at %" PRIx32 "\n", + fs->ate_wra & NVS_ADDR_OFFS_MASK); + memset(gc_done_ate, fs->erasestate, ate_size); + gc_done_ate->id = nvs_special_ate_id(fs); + gc_done_ate->len = 0; + gc_done_ate->key_len = 0; + gc_done_ate->offset = fs->data_wra & NVS_ADDR_OFFS_MASK; + nvs_ate_crc8_update(gc_done_ate); + + return nvs_flash_ate_wrt(fs, gc_done_ate); } /**************************************************************************** @@ -933,10 +1033,10 @@ static int nvs_add_gc_done_ate(FAR struct nvs_fs *fs) static int nvs_expire_ate(FAR struct nvs_fs *fs, uint32_t addr) { - uint8_t expired[NVS_ALIGN_SIZE]; + uint8_t expired[fs->progsize]; memset(expired, ~fs->erasestate, sizeof(expired)); - return nvs_flash_wrt(fs, addr + offsetof(struct nvs_ate, expired), + return nvs_flash_wrt(fs, addr + nvs_align_up(fs, sizeof(struct nvs_ate)), expired, sizeof(expired)); } @@ -952,27 +1052,28 @@ static int nvs_expire_ate(FAR struct nvs_fs *fs, uint32_t addr) static int nvs_gc(FAR struct nvs_fs *fs) { - int rc; - struct nvs_ate close_ate; - struct nvs_ate gc_ate; - uint32_t sec_addr; - uint32_t gc_addr; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(close_ate, ate_size); + NVS_ATE(gc_ate, ate_size); uint32_t gc_prev_addr; uint32_t data_addr; uint32_t stop_addr; + uint32_t sec_addr; + uint32_t gc_addr; + int rc; finfo("gc: before gc, ate_wra %" PRIx32 "\n", fs->ate_wra); - sec_addr = (fs->ate_wra & ADDR_BLOCK_MASK); + sec_addr = (fs->ate_wra & NVS_ADDR_BLOCK_MASK); nvs_block_advance(fs, &sec_addr); - gc_addr = sec_addr + fs->blocksize - sizeof(struct nvs_ate); + gc_addr = sec_addr + fs->blocksize - ate_size; finfo("gc: set, sec_addr %" PRIx32 ", gc_addr %" PRIx32 "\n", sec_addr, gc_addr); /* If the block is not closed don't do gc */ - rc = nvs_flash_ate_rd(fs, gc_addr, &close_ate); + rc = nvs_flash_ate_rd(fs, gc_addr, close_ate); if (rc < 0) { /* Flash error */ @@ -980,18 +1081,18 @@ static int nvs_gc(FAR struct nvs_fs *fs) return rc; } - rc = nvs_ate_cmp_const(&close_ate, fs->erasestate); + rc = nvs_ate_cmp_const(close_ate, fs->erasestate, ate_size); if (!rc) { goto gc_done; } - stop_addr = gc_addr - sizeof(struct nvs_ate); + stop_addr = gc_addr - ate_size; - if (nvs_close_ate_valid(fs, &close_ate)) + if (nvs_close_ate_valid(fs, close_ate)) { - gc_addr &= ADDR_BLOCK_MASK; - gc_addr += close_ate.offset; + gc_addr &= NVS_ADDR_BLOCK_MASK; + gc_addr += close_ate->offset; } else { @@ -1005,45 +1106,45 @@ static int nvs_gc(FAR struct nvs_fs *fs) do { gc_prev_addr = gc_addr; - rc = nvs_prev_ate(fs, &gc_addr, &gc_ate); + rc = nvs_prev_ate(fs, &gc_addr, gc_ate); if (rc) { return rc; } - if (gc_ate.expired[0] != fs->erasestate) + if (nvs_ate_expired(fs, gc_ate)) { /* Deleted or old ate, ignore it */ continue; } - if (!nvs_ate_valid(fs, &gc_ate)) + if (!nvs_ate_valid(fs, gc_ate)) { continue; } - if (gc_ate.id != NVS_SPECIAL_ATE_ID) + if (gc_ate->id != nvs_special_ate_id(fs)) { /* Copy needed */ finfo("Moving %" PRIu32 ", key_len %" PRIu16 ", len %" PRIu16 "\n", - gc_ate.id, gc_ate.key_len, gc_ate.len); + gc_ate->id, gc_ate->key_len, gc_ate->len); - data_addr = gc_prev_addr & ADDR_BLOCK_MASK; - data_addr += gc_ate.offset; - - gc_ate.offset = fs->data_wra & ADDR_OFFS_MASK; - nvs_ate_crc8_update(&gc_ate); + data_addr = gc_prev_addr & NVS_ADDR_BLOCK_MASK; + data_addr += gc_ate->offset; + gc_ate->offset = fs->data_wra & NVS_ADDR_OFFS_MASK; + nvs_ate_crc8_update(gc_ate); rc = nvs_flash_block_move(fs, data_addr, - NVS_ALIGN_UP(gc_ate.key_len + gc_ate.len)); + nvs_align_up(fs, gc_ate->key_len + + gc_ate->len)); if (rc) { return rc; } - rc = nvs_flash_ate_wrt(fs, &gc_ate); + rc = nvs_flash_ate_wrt(fs, gc_ate); if (rc) { return rc; @@ -1076,23 +1177,21 @@ static int nvs_gc(FAR struct nvs_fs *fs) static int nvs_startup(FAR struct nvs_fs *fs) { - int rc; - struct nvs_ate last_ate; - size_t empty_len; - uint32_t wlk_addr; + struct mtd_geometry_s geo; uint32_t second_addr; uint32_t last_addr; - struct nvs_ate second_ate; - struct mtd_geometry_s geo; + uint32_t wlk_addr; + size_t empty_len; /* Initialize addr to 0 for the case fs->nblocks == 0. This * should never happen but both * Coverity and GCC believe the contrary. */ + uint16_t closed_blocks = 0; uint32_t addr = 0; uint16_t i; - uint16_t closed_blocks = 0; + int rc; fs->ate_wra = 0; fs->data_wra = 0; @@ -1112,6 +1211,14 @@ static int nvs_startup(FAR struct nvs_fs *fs) return rc; } + fs->blocksize = CONFIG_MTD_CONFIG_BLOCKSIZE_MULTIPLE * geo.erasesize; + fs->nblocks = geo.neraseblocks / CONFIG_MTD_CONFIG_BLOCKSIZE_MULTIPLE; + fs->progsize = geo.blocksize; + + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(second_ate, ate_size); + NVS_ATE(last_ate, ate_size); + rc = MTD_IOCTL(fs->mtd, MTDIOC_ERASESTATE, (unsigned long)((uintptr_t)&fs->erasestate)); if (rc < 0) @@ -1120,9 +1227,6 @@ static int nvs_startup(FAR struct nvs_fs *fs) return rc; } - fs->blocksize = CONFIG_MTD_BLOCKSIZE_MULTIPLE * geo.erasesize; - fs->nblocks = geo.neraseblocks / CONFIG_MTD_BLOCKSIZE_MULTIPLE; - /* Check the number of blocks, it should be at least 2. */ if (fs->nblocks < 2) @@ -1137,10 +1241,9 @@ static int nvs_startup(FAR struct nvs_fs *fs) for (i = 0; i < fs->nblocks; i++) { - addr = (i << ADDR_BLOCK_SHIFT) + - (uint16_t)(fs->blocksize - sizeof(struct nvs_ate)); - rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, - sizeof(struct nvs_ate)); + addr = (i << NVS_ADDR_BLOCK_SHIFT) + + (uint16_t)(fs->blocksize - ate_size); + rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, ate_size); fwarn("rc=%d\n", rc); if (rc) { @@ -1148,8 +1251,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) closed_blocks++; nvs_block_advance(fs, &addr); - rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, - sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, ate_size); if (!rc) { /* Open block */ @@ -1177,8 +1279,8 @@ static int nvs_startup(FAR struct nvs_fs *fs) * the last block contains no ate's. So we check this first */ - rc = nvs_flash_cmp_const(fs, addr - sizeof(struct nvs_ate), - fs->erasestate, sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr - ate_size, + fs->erasestate, ate_size); if (!rc) { /* Empty ate */ @@ -1203,19 +1305,19 @@ static int nvs_startup(FAR struct nvs_fs *fs) */ fs->ate_wra = addr; - fs->data_wra = addr & ADDR_BLOCK_MASK; + fs->data_wra = addr & NVS_ADDR_BLOCK_MASK; finfo("recovered ate ate_wra=0x%" PRIx32 ", data_wra=0x%" PRIx32 "\n", fs->ate_wra, fs->data_wra); while (fs->ate_wra >= fs->data_wra) { - rc = nvs_flash_ate_rd(fs, fs->ate_wra, &last_ate); + rc = nvs_flash_ate_rd(fs, fs->ate_wra, last_ate); if (rc) { return rc; } - rc = nvs_ate_cmp_const(&last_ate, fs->erasestate); + rc = nvs_ate_cmp_const(last_ate, fs->erasestate, ate_size); if (!rc) { /* Found 0xff empty location */ @@ -1223,17 +1325,18 @@ static int nvs_startup(FAR struct nvs_fs *fs) break; } - if (nvs_ate_valid(fs, &last_ate)) + if (nvs_ate_valid(fs, last_ate)) { /* Complete write of ate was performed */ - fs->data_wra = addr & ADDR_BLOCK_MASK; - fs->data_wra += last_ate.offset + - NVS_ALIGN_UP(last_ate.key_len + last_ate.len); + fs->data_wra = addr & NVS_ADDR_BLOCK_MASK; + fs->data_wra += last_ate->offset + + nvs_align_up(fs, last_ate->key_len + + last_ate->len); finfo("recovered data_wra=0x%" PRIx32 "\n", fs->data_wra); } - fs->ate_wra -= sizeof(struct nvs_ate); + fs->ate_wra -= ate_size; } /* If the block after the write block is not empty, gc was interrupted @@ -1243,7 +1346,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) * data might not fit into the block. */ - addr = fs->ate_wra & ADDR_BLOCK_MASK; + addr = fs->ate_wra & NVS_ADDR_BLOCK_MASK; nvs_block_advance(fs, &addr); rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, fs->blocksize); if (rc < 0) @@ -1258,27 +1361,27 @@ static int nvs_startup(FAR struct nvs_fs *fs) */ bool gc_done_marker = false; - struct nvs_ate gc_done_ate; + NVS_ATE(gc_done_ate, ate_size); - addr = fs->ate_wra + sizeof(struct nvs_ate); - while ((addr & ADDR_OFFS_MASK) < - (fs->blocksize - sizeof(struct nvs_ate))) + addr = fs->ate_wra + ate_size; + while ((addr & NVS_ADDR_OFFS_MASK) < + (fs->blocksize - ate_size)) { - rc = nvs_flash_ate_rd(fs, addr, &gc_done_ate); + rc = nvs_flash_ate_rd(fs, addr, gc_done_ate); if (rc) { return rc; } - if (nvs_ate_valid(fs, &gc_done_ate) && - (gc_done_ate.id == NVS_SPECIAL_ATE_ID) && - (gc_done_ate.len == 0)) + if (nvs_ate_valid(fs, gc_done_ate) && + (gc_done_ate->id == nvs_special_ate_id(fs)) && + (gc_done_ate->len == 0)) { gc_done_marker = true; break; } - addr += sizeof(struct nvs_ate); + addr += ate_size; } if (gc_done_marker) @@ -1286,7 +1389,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) /* Erase the next block */ fwarn("GC Done marker found\n"); - addr = fs->ate_wra & ADDR_BLOCK_MASK; + addr = fs->ate_wra & NVS_ADDR_BLOCK_MASK; nvs_block_advance(fs, &addr); rc = nvs_flash_erase_block(fs, addr); goto end; @@ -1299,9 +1402,9 @@ static int nvs_startup(FAR struct nvs_fs *fs) return rc; } - fs->ate_wra &= ADDR_BLOCK_MASK; - fs->ate_wra += (fs->blocksize - 2 * sizeof(struct nvs_ate)); - fs->data_wra = (fs->ate_wra & ADDR_BLOCK_MASK); + fs->ate_wra &= NVS_ADDR_BLOCK_MASK; + fs->ate_wra += (fs->blocksize - 2 * ate_size); + fs->data_wra = (fs->ate_wra & NVS_ADDR_BLOCK_MASK); finfo("GC when data_wra=0x%" PRIx32 "\n", fs->data_wra); rc = nvs_gc(fs); goto end; @@ -1324,7 +1427,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) break; } - fs->data_wra += NVS_CORRUPT_DATA_SKIP_STEP; + fs->data_wra += fs->progsize; finfo("update for powerloss data write, data_wra=0x%" PRIx32 "\n", fs->data_wra); } @@ -1334,8 +1437,8 @@ static int nvs_startup(FAR struct nvs_fs *fs) * valid data (this also avoids closing a block without any data). */ - if (((fs->ate_wra + 2 * sizeof(struct nvs_ate)) == fs->blocksize) && - (fs->data_wra != (fs->ate_wra & ADDR_BLOCK_MASK))) + if (((fs->ate_wra + 2 * ate_size) == fs->blocksize) && + (fs->data_wra != (fs->ate_wra & NVS_ADDR_BLOCK_MASK))) { rc = nvs_flash_erase_block(fs, fs->ate_wra); if (rc) @@ -1343,7 +1446,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) return rc; } - fs->data_wra = fs->ate_wra & ADDR_BLOCK_MASK; + fs->data_wra = fs->ate_wra & NVS_ADDR_BLOCK_MASK; finfo("erase due to no data, data_wra=0x%" PRIx32 "\n", fs->data_wra); } @@ -1358,7 +1461,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) while (1) { last_addr = wlk_addr; - rc = nvs_prev_ate(fs, &wlk_addr, &last_ate); + rc = nvs_prev_ate(fs, &wlk_addr, last_ate); if (rc) { return rc; @@ -1371,35 +1474,39 @@ static int nvs_startup(FAR struct nvs_fs *fs) break; } - if (nvs_ate_valid(fs, &last_ate) - && (last_ate.id != NVS_SPECIAL_ATE_ID)) + if (nvs_ate_valid(fs, last_ate) + && (last_ate->id != nvs_special_ate_id(fs))) { finfo("ate found at 0x%" PRIx32 ", id %" PRIu32 ", " "key_len %" PRIu16 ", offset %" PRIu16 "\n", - last_addr, last_ate.id, last_ate.key_len, last_ate.offset); + last_addr, last_ate->id, last_ate->key_len, + last_ate->offset); while (1) { second_addr = wlk_addr; - rc = nvs_prev_ate(fs, &wlk_addr, &second_ate); + rc = nvs_prev_ate(fs, &wlk_addr, second_ate); if (rc) { return rc; } - if (nvs_ate_valid(fs, &second_ate) - && second_ate.id == last_ate.id - && second_ate.expired[0] == fs->erasestate) + if (nvs_ate_valid(fs, second_ate) + && second_ate->id == last_ate->id + && !nvs_ate_expired(fs, second_ate)) { finfo("same id at 0x%" PRIx32 ", key_len %" PRIu16 ", " "offset %" PRIu16 "\n", - second_addr, second_ate.key_len, second_ate.offset); - if ((second_ate.key_len == last_ate.key_len) && + second_addr, second_ate->key_len, + second_ate->offset); + if ((second_ate->key_len == last_ate->key_len) && !nvs_flash_direct_cmp(fs, - (last_addr & ADDR_BLOCK_MASK) + - last_ate.offset, - (second_addr & ADDR_BLOCK_MASK) + - second_ate.offset, - last_ate.key_len)) + (last_addr & + NVS_ADDR_BLOCK_MASK) + + last_ate->offset, + (second_addr & + NVS_ADDR_BLOCK_MASK) + + second_ate->offset, + last_ate->key_len)) { finfo("old ate found at 0x%" PRIx32 "\n", second_addr); rc = nvs_expire_ate(fs, second_addr); @@ -1431,8 +1538,8 @@ static int nvs_startup(FAR struct nvs_fs *fs) * space when doing gc. */ - if ((!rc) && ((fs->ate_wra & ADDR_OFFS_MASK) == - (fs->blocksize - 2 * sizeof(struct nvs_ate)))) + if ((!rc) && ((fs->ate_wra & NVS_ADDR_OFFS_MASK) == + (fs->blocksize - 2 * ate_size))) { rc = nvs_add_gc_done_ate(fs); } @@ -1440,9 +1547,11 @@ static int nvs_startup(FAR struct nvs_fs *fs) finfo("%" PRIu32 " Eraseblocks of %" PRIu32 " bytes\n", fs->nblocks, fs->blocksize); finfo("alloc wra: %" PRIu32 ", 0x%" PRIx32 "\n", - (fs->ate_wra >> ADDR_BLOCK_SHIFT), (fs->ate_wra & ADDR_OFFS_MASK)); + fs->ate_wra >> NVS_ADDR_BLOCK_SHIFT, + fs->ate_wra & NVS_ADDR_OFFS_MASK); finfo("data wra: %" PRIu32 ", 0x%" PRIx32 "\n", - (fs->data_wra >> ADDR_BLOCK_SHIFT), (fs->data_wra & ADDR_OFFS_MASK)); + fs->data_wra >> NVS_ADDR_BLOCK_SHIFT, + fs->data_wra & NVS_ADDR_OFFS_MASK); return rc; } @@ -1474,12 +1583,13 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, size_t key_size, FAR void *data, size_t len, FAR uint32_t *ate_addr) { - int rc; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(wlk_ate, ate_size); uint32_t wlk_addr; uint32_t rd_addr; uint32_t hist_addr; - struct nvs_ate wlk_ate; uint32_t hash_id; + int rc; hash_id = nvs_fnv_hash(key, key_size) % 0xfffffffd + 1; wlk_addr = fs->ate_wra; @@ -1489,22 +1599,23 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, { rd_addr = wlk_addr; hist_addr = wlk_addr; - rc = nvs_prev_ate(fs, &wlk_addr, &wlk_ate); + rc = nvs_prev_ate(fs, &wlk_addr, wlk_ate); if (rc) { ferr("Walk to previous ate failed, rc=%d\n", rc); return rc; } - if ((wlk_ate.id == hash_id) && (nvs_ate_valid(fs, &wlk_ate))) + if (wlk_ate->id == hash_id && nvs_ate_valid(fs, wlk_ate)) { - if ((wlk_ate.key_len == key_size) + if ((wlk_ate->key_len == key_size) && (!nvs_flash_block_cmp(fs, - (rd_addr & ADDR_BLOCK_MASK) + wlk_ate.offset, key, key_size))) + (rd_addr & NVS_ADDR_BLOCK_MASK) + + wlk_ate->offset, key, key_size))) { /* It is old or deleted, return -ENOENT */ - if (wlk_ate.expired[0] != fs->erasestate) + if (nvs_ate_expired(fs, wlk_ate)) { return -ENOENT; } @@ -1525,10 +1636,10 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, if (data && len) { - rd_addr &= ADDR_BLOCK_MASK; - rd_addr += wlk_ate.offset + wlk_ate.key_len; + rd_addr &= NVS_ADDR_BLOCK_MASK; + rd_addr += wlk_ate->offset + wlk_ate->key_len; rc = nvs_flash_rd(fs, rd_addr, data, - MIN(len, wlk_ate.len)); + MIN(len, wlk_ate->len)); if (rc) { ferr("Data read failed, rc=%d\n", rc); @@ -1541,7 +1652,7 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, *ate_addr = hist_addr; } - return wlk_ate.len; + return wlk_ate->len; } /**************************************************************************** @@ -1567,7 +1678,8 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, int gc_count; size_t data_size; size_t key_size; - struct nvs_ate wlk_ate; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(wlk_ate, ate_size); uint32_t wlk_addr; uint32_t rd_addr; uint32_t hist_addr; @@ -1593,7 +1705,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* Data now contains input data and input key, input key first. */ - data_size = NVS_ALIGN_UP(key_size + pdata->len); + data_size = nvs_align_up(fs, key_size + pdata->len); /* The maximum data size is block size - 3 ate * where: 1 ate for data, 1 ate for block close, 1 ate for gc done. @@ -1602,7 +1714,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, finfo("key_size=%zu, len=%zu, data_size = %zu\n", key_size, pdata->len, data_size); - if ((data_size > (fs->blocksize - 3 * sizeof(struct nvs_ate))) || + if ((data_size > (fs->blocksize - 3 * ate_size)) || ((pdata->len > 0) && (pdata->configdata == NULL))) { return -EINVAL; @@ -1620,18 +1732,18 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, { rd_addr = wlk_addr; hist_addr = wlk_addr; - rc = nvs_prev_ate(fs, &wlk_addr, &wlk_ate); + rc = nvs_prev_ate(fs, &wlk_addr, wlk_ate); if (rc) { return rc; } - if ((wlk_ate.id == hash_id) && (nvs_ate_valid(fs, &wlk_ate))) + if (wlk_ate->id == hash_id && nvs_ate_valid(fs, wlk_ate)) { - if ((wlk_ate.key_len == key_size) + if ((wlk_ate->key_len == key_size) && !nvs_flash_block_cmp(fs, - (rd_addr & ADDR_BLOCK_MASK) + - wlk_ate.offset, key, key_size)) + (rd_addr & NVS_ADDR_BLOCK_MASK) + + wlk_ate->offset, key, key_size)) { prev_found = true; break; @@ -1654,13 +1766,13 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* Previous entry found. */ - rd_addr &= ADDR_BLOCK_MASK; + rd_addr &= NVS_ADDR_BLOCK_MASK; if (pdata->len == 0) { /* If prev ate is expired, it is deleted. */ - if (wlk_ate.expired[0] != fs->erasestate) + if (nvs_ate_expired(fs, wlk_ate)) { /* Skip delete entry as it is already the * last one. @@ -1683,15 +1795,14 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, return 0; } } - else if (pdata->len == wlk_ate.len && - wlk_ate.expired[0] == fs->erasestate) + else if (pdata->len == wlk_ate->len && !nvs_ate_expired(fs, wlk_ate)) { /* Do not try to compare if lengths are not equal * or prev one is deleted. * Compare the data and if equal return 0. */ - rd_addr += wlk_ate.offset + wlk_ate.key_len; + rd_addr += wlk_ate->offset + wlk_ate->key_len; rc = nvs_flash_block_cmp(fs, rd_addr, pdata->configdata, pdata->len); if (rc <= 0) @@ -1712,9 +1823,9 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* Leave space for gc_done ate */ - required_space = data_size + sizeof(struct nvs_ate); + required_space = data_size + ate_size; gc_count = 0; - block_to_write_befor_gc = fs->ate_wra >> ADDR_BLOCK_SHIFT; + block_to_write_befor_gc = fs->ate_wra >> NVS_ADDR_BLOCK_SHIFT; while (1) { if (gc_count == fs->nblocks) @@ -1731,7 +1842,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* Nvs is changed after gc, we will look for the old ate. */ - if (prev_found && wlk_ate.expired[0] == fs->erasestate) + if (prev_found && !nvs_ate_expired(fs, wlk_ate)) { finfo("prev entry exists, search for it\n"); @@ -1739,7 +1850,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, if (gc_count >= fs->nblocks - 1 - (block_to_write_befor_gc + fs->nblocks - - (hist_addr >> ADDR_BLOCK_SHIFT)) + (hist_addr >> NVS_ADDR_BLOCK_SHIFT)) % fs->nblocks) { rc = nvs_read_entry(fs, key, key_size, NULL, 0, @@ -1774,7 +1885,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, * already expired) */ - if (prev_found && wlk_ate.expired[0] == fs->erasestate) + if (prev_found && !nvs_ate_expired(fs, wlk_ate)) { rc = nvs_expire_ate(fs, hist_addr); finfo("expir prev entry, %" PRIx32 ", rc %d\n", @@ -1854,7 +1965,7 @@ static ssize_t nvs_read(FAR struct nvs_fs *fs, FAR struct config_data_s *pdata) { size_t key_size; - ssize_t ret; + ssize_t rc; #ifdef CONFIG_MTD_CONFIG_NAMED FAR const uint8_t *key; @@ -1876,15 +1987,15 @@ static ssize_t nvs_read(FAR struct nvs_fs *fs, key_size = sizeof(pdata->id) + sizeof(pdata->instance); #endif - ret = nvs_read_entry(fs, key, key_size, pdata->configdata, pdata->len, + rc = nvs_read_entry(fs, key, key_size, pdata->configdata, pdata->len, NULL); - if (ret > 0) + if (rc > 0) { - pdata->len = ret; + pdata->len = rc; return 0; } - return ret; + return rc; } /**************************************************************************** @@ -1906,9 +2017,10 @@ static ssize_t nvs_read(FAR struct nvs_fs *fs, static int nvs_next(FAR struct nvs_fs *fs, FAR struct config_data_s *pdata, bool first) { - int rc; - struct nvs_ate step_ate; + size_t ate_size = nvs_ate_size(fs); + NVS_ATE(step_ate, ate_size); uint32_t rd_addr; + int rc; if (pdata == NULL || pdata->len == 0 || pdata->configdata == NULL) { @@ -1936,15 +2048,15 @@ static int nvs_next(FAR struct nvs_fs *fs, do { rd_addr = fs->step_addr; - rc = nvs_prev_ate(fs, &(fs->step_addr), &step_ate); + rc = nvs_prev_ate(fs, &(fs->step_addr), step_ate); if (rc) { return rc; } - if (nvs_ate_valid(fs, &step_ate) - && step_ate.id != NVS_SPECIAL_ATE_ID - && step_ate.expired[0] == fs->erasestate) + if (nvs_ate_valid(fs, step_ate) + && step_ate->id != nvs_special_ate_id(fs) + && !nvs_ate_expired(fs, step_ate)) { break; } @@ -1957,8 +2069,8 @@ static int nvs_next(FAR struct nvs_fs *fs, while (true); #ifdef CONFIG_MTD_CONFIG_NAMED - rc = nvs_flash_rd(fs, (rd_addr & ADDR_BLOCK_MASK) + step_ate.offset, - key, MIN(step_ate.key_len, CONFIG_MTD_CONFIG_NAME_LEN)); + rc = nvs_flash_rd(fs, (rd_addr & NVS_ADDR_BLOCK_MASK) + step_ate->offset, + key, MIN(step_ate->key_len, CONFIG_MTD_CONFIG_NAME_LEN)); if (rc) { ferr("Key read failed, rc=%d\n", rc); @@ -1967,8 +2079,8 @@ static int nvs_next(FAR struct nvs_fs *fs, key[CONFIG_MTD_CONFIG_NAME_LEN - 1] = 0; #else - rc = nvs_flash_rd(fs, (rd_addr & ADDR_BLOCK_MASK) + step_ate.offset, - key, MIN(sizeof(key), step_ate.key_len)); + rc = nvs_flash_rd(fs, (rd_addr & NVS_ADDR_BLOCK_MASK) + step_ate->offset, + key, MIN(sizeof(key), step_ate->key_len)); if (rc) { ferr("Key read failed, rc=%d\n", rc); @@ -1979,16 +2091,16 @@ static int nvs_next(FAR struct nvs_fs *fs, memcpy(&pdata->instance, key + sizeof(pdata->id), sizeof(pdata->instance)); #endif - rc = nvs_flash_rd(fs, (rd_addr & ADDR_BLOCK_MASK) + step_ate.offset + - step_ate.key_len, pdata->configdata, - MIN(pdata->len, step_ate.len)); + rc = nvs_flash_rd(fs, (rd_addr & NVS_ADDR_BLOCK_MASK) + step_ate->offset + + step_ate->key_len, pdata->configdata, + MIN(pdata->len, step_ate->len)); if (rc) { ferr("Value read failed, rc=%d\n", rc); return rc; } - pdata->len = MIN(pdata->len, step_ate.len); + pdata->len = MIN(pdata->len, step_ate->len); return OK; } @@ -2067,12 +2179,12 @@ static int mtdconfig_ioctl(FAR struct file *filep, int cmd, FAR struct inode *inode = filep->f_inode; FAR struct nvs_fs *fs = inode->i_private; FAR struct config_data_s *pdata = (FAR struct config_data_s *)arg; - int ret = -ENOTTY; + int rc = -ENOTTY; - ret = nxmutex_lock(&fs->nvs_lock); - if (ret < 0) + rc = nxmutex_lock(&fs->nvs_lock); + if (rc < 0) { - return ret; + return rc; } switch (cmd) @@ -2081,15 +2193,15 @@ static int mtdconfig_ioctl(FAR struct file *filep, int cmd, /* Read a nvs item. */ - ret = nvs_read(fs, pdata); + rc = nvs_read(fs, pdata); break; case CFGDIOC_SETCONFIG: /* Write a nvs item. */ - ret = nvs_write(fs, pdata); - if (ret >= 0) + rc = nvs_write(fs, pdata); + if (rc >= 0) { mtdconfig_notify(fs, POLLPRI); } @@ -2100,8 +2212,8 @@ static int mtdconfig_ioctl(FAR struct file *filep, int cmd, /* Delete a nvs item. */ - ret = nvs_delete(fs, pdata); - if (ret >= 0) + rc = nvs_delete(fs, pdata); + if (rc >= 0) { mtdconfig_notify(fs, POLLPRI); } @@ -2112,31 +2224,31 @@ static int mtdconfig_ioctl(FAR struct file *filep, int cmd, /* Get the first item. */ - ret = nvs_next(fs, pdata, true); + rc = nvs_next(fs, pdata, true); break; case CFGDIOC_NEXTCONFIG: /* Get the next item. */ - ret = nvs_next(fs, pdata, false); + rc = nvs_next(fs, pdata, false); break; case MTDIOC_BULKERASE: /* Call the MTD's ioctl for this. */ - ret = MTD_IOCTL(fs->mtd, cmd, arg); - if (ret >= 0) + rc = MTD_IOCTL(fs->mtd, cmd, arg); + if (rc >= 0) { - ret = nvs_startup(fs); + rc = nvs_startup(fs); } break; } nxmutex_unlock(&fs->nvs_lock); - return ret; + return rc; } /**************************************************************************** @@ -2185,8 +2297,8 @@ static int mtdconfig_poll(FAR struct file *filep, FAR struct pollfd *fds, int mtdconfig_register_by_path(FAR struct mtd_dev_s *mtd, FAR const char *path) { - int ret; FAR struct nvs_fs *fs; + int rc; fs = kmm_malloc(sizeof(struct nvs_fs)); if (fs == NULL) @@ -2197,35 +2309,35 @@ int mtdconfig_register_by_path(FAR struct mtd_dev_s *mtd, /* Initialize the mtdnvs device structure */ fs->mtd = mtd; - ret = nxmutex_init(&fs->nvs_lock); - if (ret < 0) + rc = nxmutex_init(&fs->nvs_lock); + if (rc < 0) { - ferr("ERROR: nxmutex_init failed: %d\n", ret); + ferr("ERROR: nxmutex_init failed: %d\n", rc); goto errout; } - ret = nvs_startup(fs); - if (ret < 0) + rc = nvs_startup(fs); + if (rc < 0) { - ferr("ERROR: nvs_init failed: %d\n", ret); + ferr("ERROR: nvs_init failed: %d\n", rc); goto mutex_err; } - ret = register_driver(path, &g_mtdnvs_fops, 0666, fs); - if (ret < 0) + rc = register_driver(path, &g_mtdnvs_fops, 0666, fs); + if (rc < 0) { - ferr("ERROR: register mtd config failed: %d\n", ret); + ferr("ERROR: register mtd config failed: %d\n", rc); goto mutex_err; } - return ret; + return rc; mutex_err: nxmutex_destroy(&fs->nvs_lock); errout: kmm_free(fs); - return ret; + return rc; } /**************************************************************************** @@ -2251,16 +2363,16 @@ int mtdconfig_register(FAR struct mtd_dev_s *mtd) int mtdconfig_unregister_by_path(FAR const char *path) { - int ret; - struct file file; FAR struct inode *inode; FAR struct nvs_fs *fs; + struct file file; + int rc; - ret = file_open(&file, path, O_CLOEXEC); - if (ret < 0) + rc = file_open(&file, path, O_CLOEXEC); + if (rc < 0) { - ferr("ERROR: open file %s err: %d\n", path, ret); - return ret; + ferr("ERROR: open file %s err: %d\n", path, rc); + return rc; } inode = file.f_inode; diff --git a/drivers/mtd/mtd_partition.c b/drivers/mtd/mtd_partition.c index 20401040bc27a..b9a87c2029c03 100644 --- a/drivers/mtd/mtd_partition.c +++ b/drivers/mtd/mtd_partition.c @@ -901,7 +901,7 @@ FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd, * nullified by kmm_zalloc). */ - part->child.erase = part_erase; + part->child.erase = mtd->erase ? part_erase : NULL; part->child.bread = part_bread; part->child.bwrite = part_bwrite; part->child.read = mtd->read ? part_read : NULL; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 992a22b27e342..7a792b5370264 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -66,6 +66,12 @@ config NET_RPMSG_STACKSIZE ---help--- The stack size allocated for the net RPMSG task. +config NET_RPMSG_DRV_SERVER + bool "Net rpmsg default server" + default n + ---help--- + Enable the net rpmsg default server. + endif # NET_RPMSG_DRV config NETDEV_TELNET diff --git a/drivers/net/igc.c b/drivers/net/igc.c index 96fef7e275b06..7d3a720401c45 100644 --- a/drivers/net/igc.c +++ b/drivers/net/igc.c @@ -652,7 +652,7 @@ static FAR netpkt_t *igc_receive(FAR struct netdev_lowerhalf_s *dev) if (rx->errors) { nerr("RX error reported (%"PRIu8")\n", rx->errors); - NETDEV_RXERRORS(&priv->dev); + NETDEV_RXERRORS(&priv->dev.netdev); netpkt_free(dev, pkt, NETPKT_RX); return NULL; } @@ -691,7 +691,7 @@ static void igc_txdone(FAR struct netdev_lowerhalf_s *dev) if (!(priv->tx[priv->tx_done].status & IGC_TDESC_STATUS_DD)) { nerr("tx failed: 0x%" PRIx32 "\n", priv->tx[priv->tx_done].status); - NETDEV_TXERRORS(priv->dev); + NETDEV_TXERRORS(&priv->dev.netdev); } /* Free net packet */ diff --git a/drivers/net/rpmsgdrv.c b/drivers/net/rpmsgdrv.c index 6a3bc1676bc1f..fcffdc272a5ad 100644 --- a/drivers/net/rpmsgdrv.c +++ b/drivers/net/rpmsgdrv.c @@ -34,30 +34,27 @@ #include #include #include +#include #include #include #include -#include +#include #include #include +#include #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -/* Work queue support is required. */ - -#if !defined(CONFIG_SCHED_WORKQUEUE) -# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE) -#endif - -#ifdef CONFIG_NET_DUMPPACKET -# define net_rpmsg_drv_dumppacket lib_dumpbuffer -#else -# define net_rpmsg_drv_dumppacket(m, b, l) -#endif +#define NET_RPMSG_DRV_BUFSIZE (CONFIG_NET_ETH_PKTSIZE + CONFIG_NET_GUARDSIZE) +#define NET_RPMSG_DRV_MAX_PKT_SIZE \ + ((CONFIG_NET_LL_GUARDSIZE - ETH_HDRLEN) + NET_RPMSG_DRV_BUFSIZE) +#define NET_RPMSG_DRV_MAX_NIOB \ + ((NET_RPMSG_DRV_MAX_PKT_SIZE + CONFIG_IOB_BUFSIZE - 1) / \ + CONFIG_IOB_BUFSIZE) /**************************************************************************** * Private Types @@ -75,32 +72,39 @@ struct net_rpmsg_drv_cookie_s struct net_rpmsg_drv_s { - FAR const char *cpuname; - FAR const char *devname; + char cpuname[RPMSG_NAME_SIZE]; + netpkt_queue_t rxqueue; /* RX packet queue */ + spinlock_t lock; /* Spinlock for protecting rxqueue */ + FAR void *priv; /* Private data for upper layer */ + net_rpmsg_drv_cb_t cb; /* IFUP/DOWN Callback function */ + sem_t wait; /* Wait sem, used for preventing any + * operation until the connection + * between two cpu established. + */ struct rpmsg_endpoint ept; - struct work_s pollwork; /* For deferring poll work to the work queue */ /* This holds the information visible to the NuttX network */ - struct net_driver_s dev; /* Interface understood by the network */ + struct netdev_lowerhalf_s dev; /* Interface understood by the network */ }; /**************************************************************************** * Private Function Prototypes ****************************************************************************/ -/* Common TX logic */ - -static int net_rpmsg_drv_transmit(FAR struct net_driver_s *dev, - bool nocopy); -static int net_rpmsg_drv_txpoll(FAR struct net_driver_s *dev); -static void net_rpmsg_drv_reply(FAR struct net_driver_s *dev); - /* RPMSG related functions */ +/* Request handler functions */ + static int net_rpmsg_drv_default_handler(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv); +static int net_rpmsg_drv_ifup_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv); +static int net_rpmsg_drv_ifdown_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv); static int net_rpmsg_drv_sockioctl_handler(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv); @@ -108,35 +112,46 @@ static int net_rpmsg_drv_transfer_handler(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv); +/* Response handler functions */ + +static int net_rpmsg_drv_default_response(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv); + +/* RPMSG device related functions */ + static void net_rpmsg_drv_device_created(FAR struct rpmsg_device *rdev, - FAR void *priv_); + FAR void *priv); static void net_rpmsg_drv_device_destroy(FAR struct rpmsg_device *rdev, - FAR void *priv_); + FAR void *priv); static int net_rpmsg_drv_ept_cb(FAR struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, FAR void *priv); -static int net_rpmsg_drv_send_recv(struct net_driver_s *dev, - void *header_, uint32_t command, int len); +static int net_rpmsg_drv_send_recv(struct netdev_lowerhalf_s *dev, + void *header_, uint32_t command, + int len); /* NuttX callback functions */ -static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev); -static int net_rpmsg_drv_ifdown(FAR struct net_driver_s *dev); +static int net_rpmsg_drv_ifup(FAR struct netdev_lowerhalf_s *dev); +static int net_rpmsg_drv_ifdown(FAR struct netdev_lowerhalf_s *dev); -static void net_rpmsg_drv_txavail_work(FAR void *arg); -static int net_rpmsg_drv_txavail(FAR struct net_driver_s *dev); +static int net_rpmsg_drv_transmit(FAR struct netdev_lowerhalf_s *dev, + FAR netpkt_t *pkt); +static FAR netpkt_t * +net_rpmsg_drv_receive(FAR struct netdev_lowerhalf_s *dev); -#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) -static int net_rpmsg_drv_addmac(FAR struct net_driver_s *dev, - FAR const uint8_t *mac); +#ifdef CONFIG_NET_MCASTGROUP +static int net_rpmsg_drv_addmac(FAR struct netdev_lowerhalf_s *dev, + FAR const uint8_t *mac); #ifdef CONFIG_NET_IGMP -static int net_rpmsg_drv_rmmac(FAR struct net_driver_s *dev, - FAR const uint8_t *mac); +static int net_rpmsg_drv_rmmac(FAR struct netdev_lowerhalf_s *dev, + FAR const uint8_t *mac); #endif #endif #ifdef CONFIG_NETDEV_IOCTL -static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, - unsigned long arg); +static int net_rpmsg_drv_ioctl(FAR struct netdev_lowerhalf_s *dev, int cmd, + unsigned long arg); #endif /**************************************************************************** @@ -145,8 +160,8 @@ static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, static const rpmsg_ept_cb g_net_rpmsg_drv_handler[] = { - [NET_RPMSG_IFUP] = net_rpmsg_drv_default_handler, - [NET_RPMSG_IFDOWN] = net_rpmsg_drv_default_handler, + [NET_RPMSG_IFUP] = net_rpmsg_drv_ifup_handler, + [NET_RPMSG_IFDOWN] = net_rpmsg_drv_ifdown_handler, [NET_RPMSG_ADDMCAST] = net_rpmsg_drv_default_handler, [NET_RPMSG_RMMCAST] = net_rpmsg_drv_default_handler, [NET_RPMSG_DEVIOCTL] = net_rpmsg_drv_default_handler, @@ -154,23 +169,45 @@ static const rpmsg_ept_cb g_net_rpmsg_drv_handler[] = [NET_RPMSG_TRANSFER] = net_rpmsg_drv_transfer_handler, }; +static const rpmsg_ept_cb g_net_rpmsg_drv_response[] = +{ + [NET_RPMSG_IFUP] = net_rpmsg_drv_default_response, + [NET_RPMSG_IFDOWN] = net_rpmsg_drv_default_response, + [NET_RPMSG_ADDMCAST] = net_rpmsg_drv_default_response, + [NET_RPMSG_RMMCAST] = net_rpmsg_drv_default_response, + [NET_RPMSG_DEVIOCTL] = net_rpmsg_drv_default_response, + [NET_RPMSG_SOCKIOCTL] = net_rpmsg_drv_default_response, + [NET_RPMSG_TRANSFER] = net_rpmsg_drv_default_response, +}; + +static const struct netdev_ops_s g_net_rpmsg_drv_ops = +{ + .ifup = net_rpmsg_drv_ifup, + .ifdown = net_rpmsg_drv_ifdown, + .transmit = net_rpmsg_drv_transmit, + .receive = net_rpmsg_drv_receive, +#ifdef CONFIG_NET_MCASTGROUP + .addmac = net_rpmsg_drv_addmac, + .rmmac = net_rpmsg_drv_rmmac, +#endif +#ifdef CONFIG_NETDEV_IOCTL + .ioctl = net_rpmsg_drv_ioctl, +#endif +}; + /**************************************************************************** * Private Functions ****************************************************************************/ -static void net_rpmsg_drv_wait(FAR sem_t *sem) -{ - net_sem_wait_uninterruptible(sem); -} - /**************************************************************************** * Name: net_rpmsg_drv_transmit * * Description: - * Start hardware transmission. Called from watchdog based polling. + * Start hardware transmission. * * Parameters: * dev - Reference to the NuttX driver state structure + * pkt - The packet to be sent * * Returned Value: * OK on success; a negated errno on failure @@ -180,148 +217,123 @@ static void net_rpmsg_drv_wait(FAR sem_t *sem) * ****************************************************************************/ -static int net_rpmsg_drv_transmit(FAR struct net_driver_s *dev, bool nocopy) +static int net_rpmsg_drv_transmit(FAR struct netdev_lowerhalf_s *dev, + FAR netpkt_t *pkt) { - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - FAR struct net_rpmsg_transfer_s *msg; + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); + FAR struct net_rpmsg_transfer_s *transfer; + unsigned int datalen = netpkt_getdatalen(dev, pkt); + uint32_t len; int ret; - /* Verify that the hardware is ready to send another packet. If we get - * here, then we are committed to sending a packet; Higher level logic - * must have assured that there is no transmission in progress. - */ - - /* Increment statistics */ - - net_rpmsg_drv_dumppacket("transmit", dev->d_buf, dev->d_len); - NETDEV_TXPACKETS(dev); - - /* Send the packet: address=dev->d_buf, length=dev->d_len */ - - msg = (FAR struct net_rpmsg_transfer_s *)dev->d_buf - 1; - - msg->header.command = NET_RPMSG_TRANSFER; - msg->header.result = 0; - msg->header.cookie = 0; - msg->length = dev->d_len; - - if (nocopy) + transfer = rpmsg_get_tx_payload_buffer(&drv->ept, &len, true); + if (transfer == NULL) { - ret = rpmsg_send_nocopy(&priv->ept, msg, sizeof(*msg) + msg->length); + nwarn("WARNING: Failed to get buffer for xmit\n"); + return -ENOMEM; } - else + + if (len < sizeof(*transfer) + datalen) { - ret = rpmsg_send(&priv->ept, msg, sizeof(*msg) + msg->length); + nerr("ERROR: Buffer is too small for xmit\n"); + rpmsg_release_tx_buffer(&drv->ept, transfer); + return -ENOMEM; } + transfer->header.command = NET_RPMSG_TRANSFER; + transfer->header.result = 0; + transfer->header.cookie = 0; + transfer->length = datalen; + netpkt_copyout(dev, (FAR uint8_t *)(transfer + 1), pkt, datalen, 0); + + len = sizeof(*transfer) + datalen; + ret = rpmsg_send_nocopy(&drv->ept, transfer, len); if (ret < 0) { - if (nocopy) - { - rpmsg_release_tx_buffer(&priv->ept, msg); - } - - NETDEV_TXERRORS(dev); + nerr("ERROR: Failed to send packet\n"); + rpmsg_release_tx_buffer(&drv->ept, transfer); return ret; } - else - { - NETDEV_TXDONE(dev); - return OK; - } -} -/**************************************************************************** - * Name: net_rpmsg_drv_txpoll - * - * Description: - * The transmitter is available, check if the network has any outgoing - * packets ready to send. This is a callback from devif_poll(). - * devif_poll() may be called: - * - * 1. When the preceding TX packet send is complete, - * 2. When the preceding TX packet send fail - * 3. During normal TX polling - * - * Parameters: - * dev - Reference to the NuttX driver state structure - * - * Returned Value: - * OK on success; a negated errno on failure - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ + netpkt_free(dev, pkt, NETPKT_TX); + netdev_lower_txdone(dev); + return OK; +} -static int net_rpmsg_drv_txpoll(FAR struct net_driver_s *dev) +static FAR netpkt_t * +net_rpmsg_drv_receive(FAR struct netdev_lowerhalf_s *dev) { - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - uint32_t size; + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); + FAR netpkt_t *pkt; + irqstate_t flags; - /* Send the packet */ + flags = spin_lock_irqsave(&drv->lock); + pkt = netpkt_remove_queue(&drv->rxqueue); + spin_unlock_irqrestore(&drv->lock, flags); - net_rpmsg_drv_transmit(dev, true); + return pkt; +} + +/* RPMSG related functions */ - /* Check if there is room in the device to hold another packet. If - * not, return a non-zero value to terminate the poll. - */ +static void rpmsg_send_response(FAR struct rpmsg_endpoint *ept, + FAR struct net_rpmsg_header_s *header, + size_t len, int result) +{ + header->command |= NET_RPMSG_RESPONSE; + header->result = result; + rpmsg_send(ept, header, len); +} + +static int net_rpmsg_drv_default_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) +{ + FAR struct net_rpmsg_header_s *header = data; - dev->d_buf = rpmsg_get_tx_payload_buffer(&priv->ept, &size, false); - if (dev->d_buf) + if (header->cookie) { - dev->d_buf += sizeof(struct net_rpmsg_transfer_s); - dev->d_pktsize = size - sizeof(struct net_rpmsg_transfer_s); + rpmsg_send_response(ept, header, sizeof(*header), -EOPNOTSUPP); } - return dev->d_buf == NULL; + return 0; } -/**************************************************************************** - * Name: net_rpmsg_drv_reply - * - * Description: - * After a packet has been received and dispatched to the network, it - * may return with an outgoing packet. This function checks for - * that case and performs the transmission if necessary. - * - * Parameters: - * dev - Reference to the NuttX driver state structure - * - * Returned Value: - * None - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ - -static void net_rpmsg_drv_reply(FAR struct net_driver_s *dev) +static int net_rpmsg_drv_ifup_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) { - /* If the packet dispatch resulted in data that should be sent out on the - * network, the field d_len will set to a value > 0. - */ + FAR struct net_rpmsg_drv_s *drv = priv; + FAR struct net_rpmsg_header_s *header = data; - if (dev->d_len > 0) + netdev_lower_carrier_on(&drv->dev); + if (drv->cb != NULL) { - /* And send the packet */ - - net_rpmsg_drv_transmit(dev, false); + drv->cb(&drv->dev, NET_RPMSG_EVENT_CARRIER_ON); } -} -/* RPMSG related functions */ + rpmsg_send_response(ept, header, sizeof(*header), 0); -static int net_rpmsg_drv_default_handler(FAR struct rpmsg_endpoint *ept, - FAR void *data, size_t len, - uint32_t src, FAR void *priv) + return 0; +} + +static int net_rpmsg_drv_ifdown_handler(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) { + FAR struct net_rpmsg_drv_s *drv = priv; FAR struct net_rpmsg_header_s *header = data; - FAR struct net_rpmsg_drv_cookie_s *cookie = - (struct net_rpmsg_drv_cookie_s *)(uintptr_t)header->cookie; - memcpy(cookie->header, header, len); - nxsem_post(&cookie->sem); + netdev_lower_carrier_off(&drv->dev); + if (drv->cb != NULL) + { + drv->cb(&drv->dev, NET_RPMSG_EVENT_CARRIER_OFF); + } + + rpmsg_send_response(ept, header, sizeof(*header), 0); + return 0; } @@ -361,7 +373,8 @@ static int net_rpmsg_drv_sockioctl_task(int argc, FAR char *argv[]) if (msg->header.cookie) { - rpmsg_send(ept, msg, sizeof(*msg) + msg->length); + rpmsg_send_response(ept, &msg->header, sizeof(*msg) + msg->length, + msg->header.result); } rpmsg_release_rx_buffer(ept, msg); @@ -394,58 +407,6 @@ static int net_rpmsg_drv_sockioctl_handler(FAR struct rpmsg_endpoint *ept, return 0; } -#ifdef CONFIG_NET_IPv4 -static bool net_rpmsg_drv_is_ipv4(FAR struct net_driver_s *dev) -{ - FAR struct ipv4_hdr_s *ip = - (FAR struct ipv4_hdr_s *)(dev->d_buf + dev->d_llhdrlen); - FAR struct eth_hdr_s *eth = (FAR struct eth_hdr_s *)dev->d_buf; - - if (dev->d_lltype == NET_LL_ETHERNET || dev->d_lltype == NET_LL_IEEE80211) - { - return eth->type == HTONS(ETHTYPE_IP); - } - else - { - return (ip->vhl & IP_VERSION_MASK) == IPv4_VERSION; - } -} -#endif - -#ifdef CONFIG_NET_IPv6 -static bool net_rpmsg_drv_is_ipv6(FAR struct net_driver_s *dev) -{ - FAR struct ipv6_hdr_s *ip = - (FAR struct ipv6_hdr_s *)(dev->d_buf + dev->d_llhdrlen); - FAR struct eth_hdr_s *eth = (FAR struct eth_hdr_s *)dev->d_buf; - - if (dev->d_lltype == NET_LL_ETHERNET || dev->d_lltype == NET_LL_IEEE80211) - { - return eth->type == HTONS(ETHTYPE_IP6); - } - else - { - return (ip->vtc & IP_VERSION_MASK) == IPv6_VERSION; - } -} -#endif - -#ifdef CONFIG_NET_ARP -static bool net_rpmsg_drv_is_arp(FAR struct net_driver_s *dev) -{ - FAR struct eth_hdr_s *eth = (FAR struct eth_hdr_s *)dev->d_buf; - - if (dev->d_lltype == NET_LL_ETHERNET || dev->d_lltype == NET_LL_IEEE80211) - { - return eth->type == HTONS(ETHTYPE_ARP); - } - else - { - return false; - } -} -#endif - /**************************************************************************** * Name: net_rpmsg_drv_transfer_handler * @@ -467,128 +428,145 @@ static int net_rpmsg_drv_transfer_handler(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv) { - FAR struct net_driver_s *dev = ept->priv; - FAR struct net_rpmsg_transfer_s *msg = data; - FAR void *oldbuf; - - /* Lock the network and serialize driver operations if necessary. - * NOTE: Serialization is only required in the case where the driver work - * is performed on an LP worker thread and where more than one LP worker - * thread has been configured. - */ - - net_lock(); - - /* Check for errors and update statistics */ - - net_rpmsg_drv_dumppacket("receive", msg->data, msg->length); - - NETDEV_RXPACKETS(dev); - - /* Copy the data from the hardware to dev->d_buf. Set - * amount of data in dev->d_len - */ - - oldbuf = dev->d_buf; - - dev->d_buf = msg->data; - dev->d_len = msg->length; - -#ifdef CONFIG_NET_PKT - /* When packet sockets are enabled, feed the frame into the tap */ + FAR struct net_rpmsg_transfer_s *transfer = data; + FAR struct net_rpmsg_drv_s *drv = priv; + FAR struct netdev_lowerhalf_s *dev = &drv->dev; + FAR netpkt_t *pkt; + irqstate_t flags; + int ret; - pkt_input(dev); -#endif + if (transfer->length > len - sizeof(*transfer)) + { + nerr("ERROR: net_rpmsg got invalid transfer length!"); + goto drop; + } - /* We only accept IP packets of the configured type and ARP packets */ + /* TODO: No-Copy, hold rx buffer */ -#ifdef CONFIG_NET_IPv4 - if (net_rpmsg_drv_is_ipv4(dev)) + pkt = netpkt_alloc(dev, NETPKT_RX); + if (pkt == NULL) { - ninfo("IPv4 frame\n"); - NETDEV_RXIPV4(dev); + nerr("ERROR: Failed to allocate buffer!\n"); + goto drop; + } - /* Receive an IPv4 packet from the network device */ + if (netpkt_copyin(dev, pkt, (FAR uint8_t *)(transfer + 1), + transfer->length, 0) < 0) + { + nerr("ERROR: Failed to copy in data!\n"); + goto free; + } - ipv4_input(dev); + flags = spin_lock_irqsave(&drv->lock); + ret = netpkt_tryadd_queue(pkt, &drv->rxqueue); + spin_unlock_irqrestore(&drv->lock, flags); + if (ret < 0) + { + nerr("ERROR: Failed to add pkt to queue!\n"); + goto free; + } - /* Check for a reply to the IPv4 packet */ + netdev_lower_rxready(dev); + return 0; - net_rpmsg_drv_reply(dev); - } - else -#endif -#ifdef CONFIG_NET_IPv6 - if (net_rpmsg_drv_is_ipv6(dev)) - { - ninfo("IPv6 frame\n"); - NETDEV_RXIPV6(dev); +free: + netpkt_free(dev, pkt, NETPKT_RX); - /* Dispatch IPv6 packet to the network layer */ +drop: + NETDEV_RXDROPPED(&dev->netdev); + return 0; +} - ipv6_input(dev); +/**************************************************************************** + * Name: net_rpmsg_drv_default_response + * + * Description: + * This function is used to handle the response from the RPMSG device. + * It is used to copy the response to the cookie and post the semaphore. + * + ****************************************************************************/ - /* Check for a reply to the IPv6 packet */ +static int net_rpmsg_drv_default_response(FAR struct rpmsg_endpoint *ept, + FAR void *data, size_t len, + uint32_t src, FAR void *priv) +{ + FAR struct net_rpmsg_header_s *header = data; + FAR struct net_rpmsg_drv_cookie_s *cookie = + (struct net_rpmsg_drv_cookie_s *)(uintptr_t)header->cookie; - net_rpmsg_drv_reply(dev); - } - else -#endif -#ifdef CONFIG_NET_ARP - if (net_rpmsg_drv_is_arp(dev)) - { - ninfo("ARP frame\n"); - NETDEV_RXARP(dev); + memcpy(cookie->header, header, len); + nxsem_post(&cookie->sem); + return 0; +} - /* Dispatch ARP packet to the network layer */ +/**************************************************************************** + * Name: net_rpmsg_drv_ept_release + ****************************************************************************/ - arp_input(dev); +static void net_rpmsg_drv_ept_release(FAR struct rpmsg_endpoint *ept) +{ + FAR struct net_rpmsg_drv_s *drv = ept->priv; - /* Check for a reply to the ARP packet */ + netdev_lower_carrier_off(&drv->dev); + rpmsg_wait(&drv->ept, &drv->wait); +} - net_rpmsg_drv_reply(dev); - } - else -#endif - { - NETDEV_RXDROPPED(dev); - } +/**************************************************************************** + * Name: net_rpmsg_drv_ns_bound + * + * Description: + * Rpmsg device end point service bound callback function , called when + * remote end point address is received. + * + * Parameters: + * ept - The rpmsg-device end point + * + * Returned Values: + * None + * + ****************************************************************************/ - dev->d_buf = oldbuf; - net_unlock(); +static void net_rpmsg_drv_ns_bound(FAR struct rpmsg_endpoint *ept) +{ + FAR struct net_rpmsg_drv_s *drv = ept->priv; - return 0; + rpmsg_post(&drv->ept, &drv->wait); } +/**************************************************************************** + * Name: net_rpmsg_drv_device_created + ****************************************************************************/ + static void net_rpmsg_drv_device_created(FAR struct rpmsg_device *rdev, - FAR void *priv_) + FAR void *priv) { - FAR struct net_driver_s *dev = priv_; - FAR struct net_rpmsg_drv_s *priv = dev->d_private; + FAR struct net_rpmsg_drv_s *drv = priv; char eptname[RPMSG_NAME_SIZE]; - if (!strcmp(priv->cpuname, rpmsg_get_cpuname(rdev))) + if (!strcmp(drv->cpuname, rpmsg_get_cpuname(rdev))) { - priv->ept.priv = dev; + drv->ept.priv = drv; snprintf(eptname, sizeof(eptname), - NET_RPMSG_EPT_NAME, priv->devname); + NET_RPMSG_EPT_PREFIX "%s", drv->dev.netdev.d_ifname); - rpmsg_create_ept(&priv->ept, rdev, eptname, + rpmsg_create_ept(&drv->ept, rdev, eptname, RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, net_rpmsg_drv_ept_cb, NULL); } } +/**************************************************************************** + * Name: net_rpmsg_drv_device_destroy + ****************************************************************************/ + static void net_rpmsg_drv_device_destroy(FAR struct rpmsg_device *rdev, - FAR void *priv_) + FAR void *priv) { - FAR struct net_driver_s *dev = priv_; - FAR struct net_rpmsg_drv_s *priv = dev->d_private; + FAR struct net_rpmsg_drv_s *drv = priv; - if (!strcmp(priv->cpuname, rpmsg_get_cpuname(rdev))) + if (!strcmp(drv->cpuname, rpmsg_get_cpuname(rdev))) { - rpmsg_destroy_ept(&priv->ept); - dev->d_buf = NULL; + rpmsg_destroy_ept(&drv->ept); } } @@ -596,26 +574,41 @@ static int net_rpmsg_drv_ept_cb(FAR struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, FAR void *priv) { FAR struct net_rpmsg_header_s *header = data; - uint32_t command = header->command; + uint32_t cmd = NET_RPMSG_GET_COMMAND(header->command); - if (command < sizeof(g_net_rpmsg_drv_handler) / - sizeof(g_net_rpmsg_drv_handler[0])) + if (cmd < nitems(g_net_rpmsg_drv_handler)) { - return g_net_rpmsg_drv_handler[command](ept, data, len, src, priv); + if (NET_RPMSG_IS_RESPONSE(header->command)) + { + return g_net_rpmsg_drv_response[cmd](ept, data, len, src, priv); + } + else + { + return g_net_rpmsg_drv_handler[cmd](ept, data, len, src, priv); + } } return -EINVAL; } -static int net_rpmsg_drv_send_recv(FAR struct net_driver_s *dev, +static int net_rpmsg_drv_send_recv(FAR struct netdev_lowerhalf_s *dev, FAR void *header_, uint32_t command, int len) { - FAR struct net_rpmsg_drv_s *priv = dev->d_private; + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); FAR struct net_rpmsg_header_s *header = header_; FAR struct net_rpmsg_drv_cookie_s cookie; + int sval = 0; int ret; + nxsem_get_value(&drv->wait, &sval); + if (sval <= 0) + { + rpmsg_wait(&drv->ept, &drv->wait); + rpmsg_post(&drv->ept, &drv->wait); + } + nxsem_init(&cookie.sem, 0, 0); cookie.header = header; @@ -623,13 +616,14 @@ static int net_rpmsg_drv_send_recv(FAR struct net_driver_s *dev, header->result = -ENXIO; header->cookie = (uintptr_t)&cookie; - ret = rpmsg_send(&priv->ept, header, len); + ret = rpmsg_send(&drv->ept, header, len); if (ret < 0) { goto out; } - net_rpmsg_drv_wait(&cookie.sem); + net_sem_timedwait2(&cookie.sem, false, UINT_MAX, &dev->netdev.d_lock, + NULL); ret = cookie.header->result; out: @@ -655,8 +649,10 @@ static int net_rpmsg_drv_send_recv(FAR struct net_driver_s *dev, * ****************************************************************************/ -static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) +static int net_rpmsg_drv_ifup(FAR struct netdev_lowerhalf_s *dev) { + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); struct net_rpmsg_ifup_s msg = { }; @@ -665,33 +661,34 @@ static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) #ifdef CONFIG_NET_IPv4 ninfo("Bringing up: %u.%u.%u.%u\n", - ip4_addr1(dev->d_ipaddr), ip4_addr2(dev->d_ipaddr), - ip4_addr3(dev->d_ipaddr), ip4_addr4(dev->d_ipaddr)); + ip4_addr1(dev->netdev.d_ipaddr), ip4_addr2(dev->netdev.d_ipaddr), + ip4_addr3(dev->netdev.d_ipaddr), ip4_addr4(dev->netdev.d_ipaddr)); #endif #ifdef CONFIG_NET_IPv6 ninfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], - dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], - dev->d_ipv6addr[6], dev->d_ipv6addr[7]); + dev->netdev.d_ipv6addr[0], dev->netdev.d_ipv6addr[1], + dev->netdev.d_ipv6addr[2], dev->netdev.d_ipv6addr[3], + dev->netdev.d_ipv6addr[4], dev->netdev.d_ipv6addr[5], + dev->netdev.d_ipv6addr[6], dev->netdev.d_ipv6addr[7]); #endif - net_lock(); + netdev_lock(&dev->netdev); /* Prepare the message */ - msg.lnkaddr.length = netdev_lladdrsize(dev); - memcpy(msg.lnkaddr.addr, &dev->d_mac, msg.lnkaddr.length); + msg.lnkaddr.length = netdev_lladdrsize(&dev->netdev); + memcpy(msg.lnkaddr.addr, &dev->netdev.d_mac, msg.lnkaddr.length); #ifdef CONFIG_NET_IPv4 - net_ipv4addr_copy(msg.ipaddr, dev->d_ipaddr); - net_ipv4addr_copy(msg.draddr, dev->d_draddr); - net_ipv4addr_copy(msg.netmask, dev->d_netmask); + net_ipv4addr_copy(msg.ipaddr, dev->netdev.d_ipaddr); + net_ipv4addr_copy(msg.draddr, dev->netdev.d_draddr); + net_ipv4addr_copy(msg.netmask, dev->netdev.d_netmask); #endif #ifdef CONFIG_NET_IPv6 - net_ipv6addr_copy(msg.ipv6addr, dev->d_ipv6addr); - net_ipv6addr_copy(msg.ipv6draddr, dev->d_ipv6draddr); - net_ipv6addr_copy(msg.ipv6netmask, dev->d_ipv6netmask); + net_ipv6addr_copy(msg.ipv6addr, dev->netdev.d_ipv6addr); + net_ipv6addr_copy(msg.ipv6draddr, dev->netdev.d_ipv6draddr); + net_ipv6addr_copy(msg.ipv6netmask, dev->netdev.d_ipv6netmask); #endif /* Send the message */ @@ -699,27 +696,27 @@ static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) ret = net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_IFUP, sizeof(msg)); if (ret < 0) { - net_unlock(); + netdev_unlock(&dev->netdev); return ret; } /* Update net_driver_t field */ - memcpy(&dev->d_mac, msg.lnkaddr.addr, msg.lnkaddr.length); + memcpy(&dev->netdev.d_mac, msg.lnkaddr.addr, msg.lnkaddr.length); #ifdef CONFIG_NET_IPv4 - net_ipv4addr_copy(dev->d_ipaddr, msg.ipaddr); - net_ipv4addr_copy(dev->d_draddr, msg.draddr); - net_ipv4addr_copy(dev->d_netmask, msg.netmask); + net_ipv4addr_copy(dev->netdev.d_ipaddr, msg.ipaddr); + net_ipv4addr_copy(dev->netdev.d_draddr, msg.draddr); + net_ipv4addr_copy(dev->netdev.d_netmask, msg.netmask); #endif #ifdef CONFIG_NET_IPv6 - net_ipv6addr_copy(dev->d_ipv6addr, msg.ipv6addr); - net_ipv6addr_copy(dev->d_ipv6draddr, msg.ipv6draddr); - net_ipv6addr_copy(dev->d_ipv6netmask, msg.ipv6netmask); + net_ipv6addr_copy(dev->netdev.d_ipv6addr, msg.ipv6addr); + net_ipv6addr_copy(dev->netdev.d_ipv6draddr, msg.ipv6draddr); + net_ipv6addr_copy(dev->netdev.d_ipv6netmask, msg.ipv6netmask); #endif - net_unlock(); + netdev_unlock(&dev->netdev); #ifdef CONFIG_NETDB_DNSCLIENT # ifdef CONFIG_NET_IPv4 @@ -755,6 +752,11 @@ static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) # endif #endif + if (drv->cb != NULL) + { + drv->cb(dev, NET_RPMSG_EVENT_IF_UP); + } + return OK; } @@ -775,120 +777,28 @@ static int net_rpmsg_drv_ifup(FAR struct net_driver_s *dev) * ****************************************************************************/ -static int net_rpmsg_drv_ifdown(FAR struct net_driver_s *dev) -{ - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - FAR struct net_rpmsg_ifdown_s msg; - - work_cancel(LPWORK, &priv->pollwork); - - /* Put the EMAC in its reset, non-operational state. This should be - * a known configuration that will guarantee the net_rpmsg_drv_ifup() - * always successfully brings the interface back up. - */ - - return net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_IFDOWN, sizeof(msg)); -} - -/**************************************************************************** - * Name: net_rpmsg_drv_txavail_work - * - * Description: - * Perform an out-of-cycle poll on the worker thread. - * - * Parameters: - * arg - Reference to the NuttX driver state structure (cast to void*) - * - * Returned Value: - * None - * - * Assumptions: - * Runs on a work queue thread. - * - ****************************************************************************/ - -static void net_rpmsg_drv_txavail_work(FAR void *arg) +static int net_rpmsg_drv_ifdown(FAR struct netdev_lowerhalf_s *dev) { - FAR struct net_driver_s *dev = arg; - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - uint32_t size; - - /* Lock the network and serialize driver operations if necessary. - * NOTE: Serialization is only required in the case where the driver work - * is performed on an LP worker thread and where more than one LP worker - * thread has been configured. - */ - - net_lock(); + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); + struct net_rpmsg_ifdown_s msg = + { + }; - /* Ignore the notification if the interface is not yet up */ + int ret; - if (IFF_IS_UP(dev->d_flags)) + ret = net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_IFDOWN, sizeof(msg)); + if (ret < 0) { - /* Try to get the payload buffer if not yet */ - - if (dev->d_buf == NULL) - { - dev->d_buf = rpmsg_get_tx_payload_buffer(&priv->ept, &size, false); - if (dev->d_buf) - { - dev->d_buf += sizeof(struct net_rpmsg_transfer_s); - dev->d_pktsize = size - sizeof(struct net_rpmsg_transfer_s); - } - } - - /* Check if there is room in the hardware to hold another outgoing - * packet. - */ - - if (dev->d_buf) - { - /* If so, then poll the network for new XMIT data */ - - devif_poll(dev, net_rpmsg_drv_txpoll); - } + return ret; } - net_unlock(); -} - -/**************************************************************************** - * Name: net_rpmsg_drv_txavail - * - * Description: - * Driver callback invoked when new TX data is available. This is a - * stimulus perform an out-of-cycle poll and, thereby, reduce the TX - * latency. - * - * Parameters: - * dev - Reference to the NuttX driver state structure - * - * Returned Value: - * None - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ - -static int net_rpmsg_drv_txavail(FAR struct net_driver_s *dev) -{ - FAR struct net_rpmsg_drv_s *priv = dev->d_private; - - /* Is our single work structure available? It may not be if there are - * pending interrupt actions and we will have to ignore the Tx - * availability action. - */ - - if (work_available(&priv->pollwork)) + if (drv->cb != NULL) { - /* Schedule to serialize the poll on the worker thread. */ - - work_queue(LPWORK, &priv->pollwork, net_rpmsg_drv_txavail_work, - dev, 0); + drv->cb(dev, NET_RPMSG_EVENT_IF_DOWN); } - return OK; + return ret; } /**************************************************************************** @@ -907,19 +817,18 @@ static int net_rpmsg_drv_txavail(FAR struct net_driver_s *dev) * ****************************************************************************/ -#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) -static int net_rpmsg_drv_addmac(FAR struct net_driver_s *dev, +#ifdef CONFIG_NET_MCASTGROUP +static int net_rpmsg_drv_addmac(FAR struct netdev_lowerhalf_s *dev, FAR const uint8_t *mac) { struct net_rpmsg_mcast_s msg; /* Add the MAC address to the hardware multicast routing table */ - msg.lnkaddr.length = netdev_lladdrsize(dev); + msg.lnkaddr.length = netdev_lladdrsize(&dev->netdev); memcpy(msg.lnkaddr.addr, mac, msg.lnkaddr.length); return net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_ADDMCAST, sizeof(msg)); } -#endif /**************************************************************************** * Name: net_rpmsg_drv_rmmac @@ -937,15 +846,14 @@ static int net_rpmsg_drv_addmac(FAR struct net_driver_s *dev, * ****************************************************************************/ -#ifdef CONFIG_NET_IGMP -static int net_rpmsg_drv_rmmac(FAR struct net_driver_s *dev, +static int net_rpmsg_drv_rmmac(FAR struct netdev_lowerhalf_s *dev, FAR const uint8_t *mac) { struct net_rpmsg_mcast_s msg; /* Remove the MAC address from the hardware multicast routing table */ - msg.lnkaddr.length = netdev_lladdrsize(dev); + msg.lnkaddr.length = netdev_lladdrsize(&dev->netdev); memcpy(msg.lnkaddr.addr, mac, msg.lnkaddr.length); return net_rpmsg_drv_send_recv(dev, &msg, NET_RPMSG_RMMCAST, sizeof(msg)); } @@ -971,7 +879,7 @@ static int net_rpmsg_drv_rmmac(FAR struct net_driver_s *dev, ****************************************************************************/ #ifdef CONFIG_NETDEV_IOCTL -static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, +static int net_rpmsg_drv_ioctl(FAR struct netdev_lowerhalf_s *dev, int cmd, unsigned long arg) { ssize_t len; @@ -1005,6 +913,93 @@ static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, } #endif +/**************************************************************************** + * Name: net_rpmsg_drv_alloc + ****************************************************************************/ + +static FAR struct net_rpmsg_drv_s * +net_rpmsg_drv_alloc(FAR const char *devname, enum net_lltype_e lltype) +{ + FAR struct net_rpmsg_drv_s *drv = kmm_zalloc(sizeof(*drv)); + FAR struct netdev_lowerhalf_s *netdev; + + if (!drv) + { + return NULL; + } + + netdev = &drv->dev; + netdev->quota[NETPKT_RX] = CONFIG_IOB_NBUFFERS / + NET_RPMSG_DRV_MAX_NIOB / 4; + netdev->quota[NETPKT_TX] = 1; + netdev->ops = &g_net_rpmsg_drv_ops; + + drv->ept.priv = drv; + drv->ept.release_cb = net_rpmsg_drv_ept_release; + drv->ept.ns_bound_cb = net_rpmsg_drv_ns_bound; + + nxsem_init(&drv->wait, 0, 0); + spin_lock_init(&drv->lock); + + /* Init a random MAC address, the caller can override it. */ + + arc4random_buf(&netdev->netdev.d_mac.ether.ether_addr_octet, + sizeof(netdev->netdev.d_mac.ether.ether_addr_octet)); + + strlcpy(netdev->netdev.d_ifname, devname, IFNAMSIZ); + + netdev_lower_register(netdev, lltype); + + return drv; +} + +#ifdef CONFIG_NET_RPMSG_DRV_SERVER +/**************************************************************************** + * Name: net_rpmsg_drv_ns_match + ****************************************************************************/ + +static bool net_rpmsg_drv_ns_match(FAR struct rpmsg_device *rdev, + FAR void *priv, FAR const char *name, + uint32_t dest) +{ + return !strncmp(name, NET_RPMSG_EPT_PREFIX, strlen(NET_RPMSG_EPT_PREFIX)); +} + +/**************************************************************************** + * Name: net_rpmsg_drv_ns_bind + ****************************************************************************/ + +static void net_rpmsg_drv_ns_bind(FAR struct rpmsg_device *rdev, + FAR void *priv_, FAR const char *name, + uint32_t dest) +{ + FAR struct net_rpmsg_drv_s *drv; + FAR struct net_driver_s *dev; + const char *devname = name + strlen(NET_RPMSG_EPT_PREFIX); + + dev = netdev_findbyname(devname); + if (dev) + { + drv = container_of(dev, struct net_rpmsg_drv_s, dev.netdev); + drv->ept.priv = drv; + drv->ept.release_cb = net_rpmsg_drv_ept_release; + drv->ept.ns_bound_cb = net_rpmsg_drv_ns_bound; + } + else + { + drv = net_rpmsg_drv_alloc(devname, NET_LL_ETHERNET); + if (!drv) + { + return; + } + } + + rpmsg_create_ept(&drv->ept, rdev, name, RPMSG_ADDR_ANY, dest, + net_rpmsg_drv_ept_cb, rpmsg_destroy_ept); + rpmsg_post(&drv->ept, &drv->wait); +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -1013,82 +1008,97 @@ static int net_rpmsg_drv_ioctl(FAR struct net_driver_s *dev, int cmd, * Name: net_rpmsg_drv_init * * Description: - * Initialize the net rpmsg driver + * Allocate a new network device instance for the RPMSG network and + * register it with the network device manager. This is the client side of + * the RPMSG driver. The RPMSG driver is the server side of the driver. * * Parameters: - * name - Specify the netdev name - * lltype - Identify the link type + * cpuname - Remote CPU name + * devname - Local and remote network device name + * lltype - Link layer type * * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * Called early in initialization before multi-tasking is initiated. + * A pointer to the allocated network device instance. NULL is returned on + * failure. * ****************************************************************************/ -int net_rpmsg_drv_init(FAR const char *cpuname, - FAR const char *devname, - enum net_lltype_e lltype) +FAR struct netdev_lowerhalf_s * +net_rpmsg_drv_init(FAR const char *cpuname, FAR const char *devname, + enum net_lltype_e lltype) { - FAR struct net_rpmsg_drv_s *priv; - FAR struct net_driver_s *dev; + FAR struct net_rpmsg_drv_s *drv; + FAR struct netdev_lowerhalf_s *dev; int ret; /* Allocate the interface structure */ - priv = kmm_zalloc(sizeof(*priv)); - if (priv == NULL) + if (!devname || !cpuname || + !(drv = net_rpmsg_drv_alloc(devname, lltype))) { - return -ENOMEM; + return NULL; } - dev = &priv->dev; + strlcpy(drv->cpuname, cpuname, RPMSG_NAME_SIZE); - priv->cpuname = cpuname; - priv->devname = devname; - - /* Initialize the driver structure */ - - strlcpy(dev->d_ifname, devname, sizeof(dev->d_ifname)); - dev->d_ifup = net_rpmsg_drv_ifup; /* I/F up (new IP address) callback */ - dev->d_ifdown = net_rpmsg_drv_ifdown; /* I/F down callback */ - dev->d_txavail = net_rpmsg_drv_txavail; /* New TX data callback */ -#ifdef CONFIG_NET_IGMP - dev->d_addmac = net_rpmsg_drv_addmac; /* Add multicast MAC address */ - dev->d_rmmac = net_rpmsg_drv_rmmac; /* Remove multicast MAC address */ -#endif -#ifdef CONFIG_NETDEV_IOCTL - dev->d_ioctl = net_rpmsg_drv_ioctl; /* Handle network IOCTL commands */ -#endif - dev->d_private = priv; /* Used to recover private state from dev */ + dev = &drv->dev; /* Register the device with the openamp */ - ret = rpmsg_register_callback(dev, - net_rpmsg_drv_device_created, - net_rpmsg_drv_device_destroy, - NULL, - NULL); + ret = rpmsg_register_callback(drv, + net_rpmsg_drv_device_created, + net_rpmsg_drv_device_destroy, + NULL, + NULL); if (ret < 0) { - kmm_free(priv); - return ret; + netdev_lower_unregister(dev); + nxsem_destroy(&drv->wait); + kmm_free(drv); + return NULL; } - /* Register the device with the OS so that socket IOCTLs can be performed */ + return dev; +} + +/**************************************************************************** + * Name: net_rpmsg_drv_priv + ****************************************************************************/ - ret = netdev_register(dev, lltype); - if (ret < 0) - { - rpmsg_unregister_callback(dev, - net_rpmsg_drv_device_created, - net_rpmsg_drv_device_destroy, - NULL, - NULL); - kmm_free(priv); - } +FAR void *net_rpmsg_drv_priv(FAR struct netdev_lowerhalf_s *dev) +{ + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); - return ret; + return drv->priv; +} + +/**************************************************************************** + * Name: net_rpmsg_drv_set_callback + ****************************************************************************/ + +void net_rpmsg_drv_set_callback(FAR struct netdev_lowerhalf_s *dev, + net_rpmsg_drv_cb_t cb, FAR void *priv) +{ + FAR struct net_rpmsg_drv_s *drv = + container_of(dev, struct net_rpmsg_drv_s, dev); + + drv->cb = cb; + drv->priv = priv; } + +#ifdef CONFIG_NET_RPMSG_DRV_SERVER +/**************************************************************************** + * Name: net_rpmsg_drv_server_init + ****************************************************************************/ + +int net_rpmsg_drv_server_init(void) +{ + return rpmsg_register_callback(NULL, + NULL, + NULL, + net_rpmsg_drv_ns_match, + net_rpmsg_drv_ns_bind); +} +#endif diff --git a/drivers/net/wifi_sim.c b/drivers/net/wifi_sim.c index 4f5168fa738a8..70ef054593bd9 100644 --- a/drivers/net/wifi_sim.c +++ b/drivers/net/wifi_sim.c @@ -146,6 +146,7 @@ enum WLAN_STA_STATE_E WLAN_STA_STATE_INIT, WLAN_STA_STATE_CONNECTING, WLAN_STA_STATE_CONNECTED, + WLAN_STA_STATE_DISCONNECTED, }; enum WLAN_STA_CONNERR_E @@ -915,6 +916,8 @@ static int wifidriver_start_disconnect(FAR struct wifi_sim_s *wifidev) { if (wifidev->state == WLAN_STA_STATE_CONNECTED) { + wifidev->state = WLAN_STA_STATE_DISCONNECTED; + /* free the connected_ap */ free(wifidev->connected_ap); @@ -1974,6 +1977,8 @@ int wifi_sim_init(FAR struct wifi_sim_lowerhalf_s *netdev) priv->lower = &netdev->lower; netdev->wifi = priv; + priv->mode = IW_MODE_AUTO; + return OK; } @@ -1993,3 +1998,23 @@ void wifi_sim_remove(FAR struct wifi_sim_lowerhalf_s *netdev) kmm_free(netdev->wifi); } +/**************************************************************************** + * Name: wifi_sim_connected + ****************************************************************************/ + +bool wifi_sim_connected(FAR struct wifi_sim_lowerhalf_s *dev) +{ + FAR struct wifi_sim_s *wifidev = (FAR struct wifi_sim_s *)dev->wifi; + + if (wifidev->mode == IW_MODE_MASTER) + { + return true; + } + else if (wifidev->mode == IW_MODE_INFRA) + { + return wifidev->state == WLAN_STA_STATE_CONNECTED; + } + + return false; +} + diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 42860eb325cfe..694ce7f372daa 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -687,7 +687,8 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, FAR struct pci_resource_s *mem_pref) { int bar; - uint32_t orig; + uint32_t orig0; + uint32_t orig1; uint32_t mask; uint64_t orig64; uint64_t size64; @@ -711,10 +712,9 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, FAR struct pci_resource_s *res; unsigned int flags; - pci_read_config_dword(dev, base_address_0, &orig); - pci_write_config_dword(dev, base_address_0, 0xfffffffe); + pci_read_config_dword(dev, base_address_0, &orig0); + pci_write_config_dword(dev, base_address_0, 0xffffffff); pci_read_config_dword(dev, base_address_0, &mask); - pci_write_config_dword(dev, base_address_0, orig); if (mask == 0 || mask == 0xffffffff) { @@ -770,21 +770,22 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, res = mem; } - orig64 = orig; + orig64 = orig0; maxbase = mask; if (mask & PCI_BASE_ADDRESS_MEM_TYPE_64) { uint32_t masktmp; - pci_read_config_dword(dev, base_address_1, &orig); + pci_read_config_dword(dev, base_address_1, &orig1); pci_write_config_dword(dev, base_address_1, 0xffffffff); pci_read_config_dword(dev, base_address_1, &masktmp); - pci_write_config_dword(dev, base_address_1, orig); + pci_write_config_dword(dev, base_address_1, orig1); mask64 |= (uint64_t)masktmp << 32; - orig64 |= (uint64_t)orig << 32; + orig64 |= (uint64_t)orig1 << 32; maxbase |= (uint64_t)masktmp << 32; } + pci_write_config_dword(dev, base_address_0, orig0); size64 = pci_size(orig64, maxbase, mask64); if (size64 == 0) { @@ -840,12 +841,12 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, } } - pci_read_config_dword(dev, rom_addr, &orig); + pci_read_config_dword(dev, rom_addr, &orig0); pci_write_config_dword(dev, rom_addr, ~PCI_ROM_ADDRESS_ENABLE); pci_read_config_dword(dev, rom_addr, &mask); - pci_write_config_dword(dev, rom_addr, orig); - start = PCI_ROM_ADDR(orig); + pci_write_config_dword(dev, rom_addr, orig0); + start = PCI_ROM_ADDR(orig0); size64 = PCI_ROM_SIZE(mask); if (start != 0 && size64 != 0) { diff --git a/drivers/rpmsg/rpmsg.c b/drivers/rpmsg/rpmsg.c index cb6a0960ad12b..311e22211a165 100644 --- a/drivers/rpmsg/rpmsg.c +++ b/drivers/rpmsg/rpmsg.c @@ -32,8 +32,10 @@ #include #include #include +#include #include "rpmsg_ping.h" +#include "rpmsg_router.h" #include "rpmsg_test.h" /**************************************************************************** @@ -220,17 +222,7 @@ int rpmsg_get_signals(FAR struct rpmsg_device *rdev) { FAR struct rpmsg_s *rpmsg = rpmsg_get_by_rdev(rdev); - if (rpmsg == NULL) - { - return -EINVAL; - } - - if (rpmsg->ops->get_signals != NULL) - { - return rpmsg->ops->get_signals(rpmsg); - } - - return 0; + return atomic_read(&rpmsg->signals); } int rpmsg_register_callback(FAR void *priv, @@ -528,6 +520,7 @@ int rpmsg_register(FAR const char *path, FAR struct rpmsg_s *rpmsg, metal_list_init(&rpmsg->bind); nxrmutex_init(&rpmsg->lock); rpmsg->ops = ops; + atomic_store(&rpmsg->signals, RPMSG_SIGNAL_RUNNING); /* Add priv to list */ @@ -592,3 +585,40 @@ void rpmsg_dump_all(void) { rpmsg_ioctl(NULL, RPMSGIOC_DUMP, 0); } + +void rpmsg_modify_signals(FAR struct rpmsg_s *rpmsg, + int setflags, int clrflags) +{ + FAR struct rpmsg_device *rdev = rpmsg->rdev; + FAR struct rpmsg_endpoint *ept; + FAR struct metal_list *node; + bool needlock; + + atomic_fetch_and(&rpmsg->signals, ~clrflags); + atomic_fetch_or(&rpmsg->signals, setflags); + + /* Send signal to Router Hub */ + + needlock = !up_interrupt_context() && !sched_idletask(); + if (needlock) + { + metal_mutex_acquire(&rdev->lock); + } + + metal_list_for_each(&rdev->endpoints, node) + { + ept = metal_container_of(node, struct rpmsg_endpoint, node); + if (!strncmp(ept->name, RPMSG_ROUTER_NAME, + RPMSG_ROUTER_NAME_LEN)) + { + rpmsg_ept_incref(ept); + ept->cb(ept, NULL, 0, RPMSG_ADDR_ANY, NULL); + rpmsg_ept_decref(ept); + } + } + + if (needlock) + { + metal_mutex_release(&rdev->lock); + } +} diff --git a/drivers/rpmsg/rpmsg_port.c b/drivers/rpmsg/rpmsg_port.c index 161398e689c56..391786af1c9c9 100644 --- a/drivers/rpmsg/rpmsg_port.c +++ b/drivers/rpmsg/rpmsg_port.c @@ -51,7 +51,6 @@ static FAR const char * rpmsg_port_get_local_cpuname(FAR struct rpmsg_s *rpmsg); static FAR const char *rpmsg_port_get_cpuname(FAR struct rpmsg_s *rpmsg); static void rpmsg_port_dump(FAR struct rpmsg_s *rpmsg); -static int rpmsg_port_get_signals(FAR struct rpmsg_s *rpmsg); /**************************************************************************** * Private Data @@ -66,7 +65,6 @@ static const struct rpmsg_ops_s g_rpmsg_port_ops = rpmsg_port_dump, rpmsg_port_get_local_cpuname, rpmsg_port_get_cpuname, - rpmsg_port_get_signals, }; /**************************************************************************** @@ -566,17 +564,6 @@ static FAR const char *rpmsg_port_get_cpuname(FAR struct rpmsg_s *rpmsg) return port->cpuname; } -/**************************************************************************** - * Name: rpmsg_port_get_signals - ****************************************************************************/ - -static int rpmsg_port_get_signals(FAR struct rpmsg_s *rpmsg) -{ - FAR struct rpmsg_port_s *port = (FAR struct rpmsg_port_s *)rpmsg; - - return atomic_read(&port->signals); -} - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -769,7 +756,6 @@ int rpmsg_port_register(FAR struct rpmsg_port_s *port, return ret; } - atomic_fetch_or(&port->signals, RPMSG_SIGNAL_RUNNING); rpmsg_register_endpoint(&port->rdev, &port->rdev.ns_ept, "NS", RPMSG_NS_EPT_ADDR, RPMSG_NS_EPT_ADDR, rpmsg_port_ns_callback, NULL, port); diff --git a/drivers/rpmsg/rpmsg_port.h b/drivers/rpmsg/rpmsg_port.h index 220a5eddeaac5..647a7afb21ee2 100644 --- a/drivers/rpmsg/rpmsg_port.h +++ b/drivers/rpmsg/rpmsg_port.h @@ -29,8 +29,6 @@ #include -#include - #include #include #include @@ -131,10 +129,6 @@ struct rpmsg_port_s char cpuname[RPMSG_NAME_SIZE]; - /* Remote cpu status */ - - atomic_t signals; - /* Ops need implemented by drivers under port layer */ const FAR struct rpmsg_port_ops_s *ops; diff --git a/drivers/rpmsg/rpmsg_port_spi.c b/drivers/rpmsg/rpmsg_port_spi.c index 7112f25d69b17..3c6ebf581a0b5 100644 --- a/drivers/rpmsg/rpmsg_port_spi.c +++ b/drivers/rpmsg/rpmsg_port_spi.c @@ -321,11 +321,11 @@ static void rpmsg_port_spi_complete_handler(FAR void *arg) if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_SUSPEND) { - atomic_fetch_and(&rpspi->port.signals, ~RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpspi->port.rpmsg, 0, RPMSG_SIGNAL_RUNNING); } else if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_RESUME) { - atomic_fetch_or(&rpspi->port.signals, RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpspi->port.rpmsg, RPMSG_SIGNAL_RUNNING, 0); } else if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_AVAIL) { diff --git a/drivers/rpmsg/rpmsg_port_spi_slave.c b/drivers/rpmsg/rpmsg_port_spi_slave.c index 5591962941d63..c5fe29635c981 100644 --- a/drivers/rpmsg/rpmsg_port_spi_slave.c +++ b/drivers/rpmsg/rpmsg_port_spi_slave.c @@ -382,11 +382,11 @@ static void rpmsg_port_spi_slave_notify(FAR struct spi_slave_dev_s *dev, if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_SUSPEND) { - atomic_fetch_and(&rpspi->port.signals, ~RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpspi->port.rpmsg, 0, RPMSG_SIGNAL_RUNNING); } else if (rpspi->rxhdr->cmd == RPMSG_PORT_SPI_CMD_RESUME) { - atomic_fetch_or(&rpspi->port.signals, RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpspi->port.rpmsg, RPMSG_SIGNAL_RUNNING, 0); } else if (rpspi->rxhdr->cmd != RPMSG_PORT_SPI_CMD_AVAIL) { diff --git a/drivers/rpmsg/rpmsg_port_uart.c b/drivers/rpmsg/rpmsg_port_uart.c index 217090692c0ee..fa77627830eac 100644 --- a/drivers/rpmsg/rpmsg_port_uart.c +++ b/drivers/rpmsg/rpmsg_port_uart.c @@ -379,14 +379,16 @@ static int rpmsg_port_uart_rx_thread(int argc, FAR char *argv[]) else if (buf[i] == RPMSG_PORT_UART_SUSPEND) { rpmsgdbg("Received suspend command\n"); - atomic_fetch_and(&rpuart->port.signals, ~RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpuart->port.rpmsg, + 0, RPMSG_SIGNAL_RUNNING); nxsem_wait(&rpuart->wake); continue; } else if (buf[i] == RPMSG_PORT_UART_RESUME) { rpmsgdbg("Received resume command\n"); - atomic_fetch_or(&rpuart->port.signals, RPMSG_SIGNAL_RUNNING); + rpmsg_modify_signals(&rpuart->port.rpmsg, + RPMSG_SIGNAL_RUNNING, 0); nxsem_post(&rpuart->wake); continue; } diff --git a/drivers/rpmsg/rpmsg_router.h b/drivers/rpmsg/rpmsg_router.h index 8f7547f9ce5b7..cb799cd253b60 100644 --- a/drivers/rpmsg/rpmsg_router.h +++ b/drivers/rpmsg/rpmsg_router.h @@ -29,8 +29,6 @@ #include -#ifdef CONFIG_RPMSG_ROUTER - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -43,6 +41,10 @@ #define RPMSG_ROUTER_CREATE 1 #define RPMSG_ROUTER_DESTROY 2 +#define RPMSG_ROUTER_SUSPEND 3 +#define RPMSG_ROUTER_RESUME 4 + +#ifdef CONFIG_RPMSG_ROUTER /**************************************************************************** * Public Types diff --git a/drivers/rpmsg/rpmsg_router_edge.c b/drivers/rpmsg/rpmsg_router_edge.c index 294d008959b76..3bdfbc8c40695 100644 --- a/drivers/rpmsg/rpmsg_router_edge.c +++ b/drivers/rpmsg/rpmsg_router_edge.c @@ -683,15 +683,34 @@ static int rpmsg_router_cb(FAR struct rpmsg_endpoint *ept, if (msg->cmd == RPMSG_ROUTER_DESTROY) { edge = ept->priv; + if (edge == NULL) + { + return -EINVAL; + } + + rpmsg_router_edge_destroy(edge); + ept->priv = NULL; + return 0; + } + else if (msg->cmd == RPMSG_ROUTER_SUSPEND || + msg->cmd == RPMSG_ROUTER_RESUME) + { + edge = ept->priv; + if (edge == NULL) + { + return -EINVAL; + } - if (edge) + if (msg->cmd == RPMSG_ROUTER_SUSPEND) { - rpmsg_router_edge_destroy(edge); - ept->priv = NULL; - return 0; + rpmsg_modify_signals(&edge->rpmsg, 0, RPMSG_SIGNAL_RUNNING); + } + else + { + rpmsg_modify_signals(&edge->rpmsg, RPMSG_SIGNAL_RUNNING, 0); } - return -EINVAL; + return 0; } /* Create the router edge device */ diff --git a/drivers/rpmsg/rpmsg_router_hub.c b/drivers/rpmsg/rpmsg_router_hub.c index 5aad21480c58d..6f872d90abf11 100644 --- a/drivers/rpmsg/rpmsg_router_hub.c +++ b/drivers/rpmsg/rpmsg_router_hub.c @@ -35,6 +35,7 @@ #include #include +#include #include #include "rpmsg_router.h" @@ -59,6 +60,7 @@ struct rpmsg_router_hub_s { struct rpmsg_endpoint ept[2]; + struct work_s work; char cpuname[2][RPMSG_ROUTER_CPUNAME_LEN]; mutex_t lock; }; @@ -359,6 +361,31 @@ static void rpmsg_router_bound(FAR struct rpmsg_endpoint *ept) } } +/**************************************************************************** + * Name: rpmsg_router_notify_edge + ****************************************************************************/ + +static void rpmsg_router_notify_edge(FAR void *arg) +{ + FAR struct rpmsg_endpoint *ept = arg; + FAR struct rpmsg_router_hub_s *hub = ept->priv; + struct rpmsg_router_s msg; + int i; + + msg.cmd = rpmsg_is_running(ept->rdev) ? + RPMSG_ROUTER_RESUME : RPMSG_ROUTER_SUSPEND; + for (i = 0; i < 2; i++) + { + if (strcmp(rpmsg_get_cpuname(ept->rdev), hub->cpuname[i])) + { + rpmsg_send(&hub->ept[i], &msg, sizeof(msg)); + } + } + + rpmsg_ept_decref(&hub->ept[0]); + rpmsg_ept_decref(&hub->ept[1]); +} + /**************************************************************************** * Name: rpmsg_router_cb ****************************************************************************/ @@ -366,6 +393,17 @@ static void rpmsg_router_bound(FAR struct rpmsg_endpoint *ept) static int rpmsg_router_cb(FAR struct rpmsg_endpoint *ept, FAR void *data, size_t len, uint32_t src, FAR void *priv) { + FAR struct rpmsg_router_hub_s *hub = ept->priv; + + /* Send pm signal to the other edge core */ + + if (data == NULL) + { + rpmsg_ept_incref(&hub->ept[0]); + rpmsg_ept_incref(&hub->ept[1]); + work_queue(HPWORK, &hub->work, rpmsg_router_notify_edge, ept, 0); + } + return 0; } diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index c75577743b1c2..587c75ee6353c 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -74,7 +74,6 @@ config SENSORS_WTGAHRS2 config SENSORS_FAKESENSOR bool "Fake Sensor Support" - depends on SENSORS_GNSS default n ---help--- Simulate physical sensor by reading data from csv file. diff --git a/drivers/sensors/fakesensor_uorb.c b/drivers/sensors/fakesensor_uorb.c index 6077cf9e32c80..9f3bcc976deaa 100644 --- a/drivers/sensors/fakesensor_uorb.c +++ b/drivers/sensors/fakesensor_uorb.c @@ -39,10 +39,13 @@ #include #include #include -#include #include #include +#ifdef CONFIG_SENSORS_GNSS +#include +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -52,7 +55,9 @@ struct fakesensor_s union { struct sensor_lowerhalf_s lower; +#ifdef CONFIG_SENSORS_GNSS struct gnss_lowerhalf_s gnss; +#endif }; int type; @@ -77,14 +82,17 @@ static int fakesensor_set_interval(FAR struct sensor_lowerhalf_s *lower, static int fakesensor_batch(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, FAR uint32_t *latency_us); +static void fakesensor_push_event(FAR struct fakesensor_s *sensor, + uint64_t event_timestamp); +static int fakesensor_thread(int argc, char** argv); + +#ifdef CONFIG_SENSORS_GNSS static int fakegnss_activate(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, bool sw); static int fakegnss_set_interval(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, FAR uint32_t *period_us); -static void fakesensor_push_event(FAR struct fakesensor_s *sensor, - uint64_t event_timestamp); -static int fakesensor_thread(int argc, char** argv); +#endif /**************************************************************************** * Private Data @@ -97,11 +105,13 @@ static struct sensor_ops_s g_fakesensor_ops = .batch = fakesensor_batch, }; +#ifdef CONFIG_SENSORS_GNSS static struct gnss_ops_s g_fakegnss_ops = { .activate = fakegnss_activate, .set_interval = fakegnss_set_interval, }; +#endif /**************************************************************************** * Private Functions @@ -211,6 +221,7 @@ static inline void fakesensor_read_baro(FAR struct fakesensor_s *sensor, sizeof(struct sensor_baro)); } +#ifdef CONFIG_SENSORS_GNSS static inline void fakesensor_read_gnss(FAR struct fakesensor_s *sensor) { char raw[150]; @@ -227,6 +238,7 @@ static inline void fakesensor_read_gnss(FAR struct fakesensor_s *sensor) } } } +#endif static int fakesensor_activate(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, bool enable) @@ -249,11 +261,13 @@ static int fakesensor_activate(FAR struct sensor_lowerhalf_s *lower, return OK; } +#ifdef CONFIG_SENSORS_GNSS static int fakegnss_activate(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, bool enable) { return fakesensor_activate((FAR void *)lower, filep, enable); } +#endif static int fakesensor_set_interval(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, @@ -265,12 +279,14 @@ static int fakesensor_set_interval(FAR struct sensor_lowerhalf_s *lower, return OK; } +#ifdef CONFIG_SENSORS_GNSS static int fakegnss_set_interval(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, FAR uint32_t *period_us) { return fakesensor_set_interval((FAR void *)lower, filep, period_us); } +#endif static int fakesensor_batch(FAR struct sensor_lowerhalf_s *lower, FAR struct file *filep, @@ -313,10 +329,12 @@ void fakesensor_push_event(FAR struct fakesensor_s *sensor, fakesensor_read_baro(sensor, event_timestamp); break; +#ifdef CONFIG_SENSORS_GNSS case SENSOR_TYPE_GNSS: case SENSOR_TYPE_GNSS_SATELLITE: fakesensor_read_gnss(sensor); break; +#endif default: snerr("fakesensor: unsupported type sensor type\n"); @@ -420,6 +438,7 @@ int fakesensor_init(int type, FAR const char *file_name, FAR struct fakesensor_s *sensor; FAR char *argv[2]; char arg1[32]; +#ifdef CONFIG_SENSORS_GNSS uint32_t nbuffer[] = { [SENSOR_GNSS_IDX_GNSS] = batch_number, [SENSOR_GNSS_IDX_GNSS_SATELLITE] = batch_number, @@ -427,6 +446,7 @@ int fakesensor_init(int type, FAR const char *file_name, [SENSOR_GNSS_IDX_GNSS_CLOCK] = batch_number, [SENSOR_GNSS_IDX_GNSS_GEOFENCE] = batch_number, }; +#endif int ret; @@ -460,12 +480,14 @@ int fakesensor_init(int type, FAR const char *file_name, /* Register sensor */ +#ifdef CONFIG_SENSORS_GNSS if (type == SENSOR_TYPE_GNSS || type == SENSOR_TYPE_GNSS_SATELLITE) { sensor->gnss.ops = &g_fakegnss_ops; gnss_register(&sensor->gnss, devno, nbuffer, nitems(nbuffer)); } else +#endif { sensor->lower.type = type; sensor->lower.ops = &g_fakesensor_ops; diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c index 1e8aa6e127ec7..5bfdaba006356 100644 --- a/drivers/sensors/sensor.c +++ b/drivers/sensors/sensor.c @@ -218,6 +218,7 @@ static const struct sensor_meta_s g_sensor_meta[] = {sizeof(struct sensor_pm25), "pm25"}, {sizeof(struct sensor_pm10), "pm10"}, {sizeof(struct sensor_uv), "uv"}, + {sizeof(struct sensor_eng), "eng"}, }; static const struct file_operations g_sensor_fops = diff --git a/drivers/timers/arch_alarm.c b/drivers/timers/arch_alarm.c index 4f04e0d44b66b..98a49a8e2d417 100644 --- a/drivers/timers/arch_alarm.c +++ b/drivers/timers/arch_alarm.c @@ -26,6 +26,8 @@ #include +#include + #include #include #include @@ -34,6 +36,10 @@ * Pre-processor Definitions ****************************************************************************/ +#ifndef CONFIG_BOARD_LOOPSPERMSEC +# define CONFIG_BOARD_LOOPSPERMSEC 0 +#endif + #define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) #define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) #define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) @@ -56,6 +62,8 @@ static void udelay_coarse(useconds_t microseconds) { volatile int i; + DEBUGASSERT(CONFIG_BOARD_LOOPSPERMSEC != 0); + /* We'll do this a little at a time because we expect that the * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in * the divisions of its calculation. We'll use the largest values that @@ -119,7 +127,7 @@ static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower, FAR void *arg) { #ifdef CONFIG_SCHED_TICKLESS - nxsched_timer_expiration(); + nxsched_process_timer(); #else clock_t now; @@ -301,7 +309,7 @@ int weak_function up_timer_gettime(struct timespec *ts) * Description: * Cancel the alarm and return the time of cancellation of the alarm. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the alarm is + * nxsched_process_timer() will not be called unless the alarm is * restarted with up_alarm_start(). * * If, as a race condition, the alarm has already expired when this @@ -360,14 +368,14 @@ int weak_function up_alarm_tick_cancel(FAR clock_t *ticks) * Name: up_alarm_start * * Description: - * Start the alarm. nxsched_timer_expiration() will be called when the + * Start the alarm. nxsched_process_timer() will be called when the * alarm occurs (unless up_alaram_cancel is called to stop it). * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: * ts - The time in the future at the alarm is expected to occur. When the - * alarm occurs the timer logic will call nxsched_timer_expiration(). + * alarm occurs the timer logic will call nxsched_process_timer(). * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on diff --git a/drivers/timers/arch_timer.c b/drivers/timers/arch_timer.c index a6caacb59b3e4..da4bf6a486dac 100644 --- a/drivers/timers/arch_timer.c +++ b/drivers/timers/arch_timer.c @@ -26,6 +26,8 @@ #include +#include + #include #include #include @@ -34,8 +36,8 @@ * Pre-processor Definitions ****************************************************************************/ -#if defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM) -# error CONFIG_SCHED_TICKLESS_ALARM must be unset to use the arch timer +#ifndef CONFIG_BOARD_LOOPSPERMSEC +# define CONFIG_BOARD_LOOPSPERMSEC 0 #endif #define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) @@ -122,6 +124,8 @@ static void udelay_coarse(useconds_t microseconds) { volatile int i; + DEBUGASSERT(CONFIG_BOARD_LOOPSPERMSEC != 0); + /* We'll do this a little at a time because we expect that the * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in * the divisions of its calculation. We'll use the largest values that @@ -174,7 +178,7 @@ static bool timer_callback(FAR uint32_t *next_interval, FAR void *arg) g_timer.timebase += *next_interval; temp_interval = g_oneshot_maxticks; g_timer.next_interval = &temp_interval; - nxsched_timer_expiration(); + nxsched_process_timer(); g_timer.next_interval = NULL; TIMER_TICK_GETSTATUS(g_timer.lower, &status); @@ -295,7 +299,7 @@ int weak_function up_timer_gettime(struct timespec *ts) * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -344,14 +348,14 @@ int weak_function up_timer_tick_cancel(FAR clock_t *ticks) * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be called at + * Start the interval timer. nxsched_process_timer() will be called at * the completion of the timeout (unless up_timer_cancel is called to stop * the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: diff --git a/drivers/virtio/virtio-net.c b/drivers/virtio/virtio-net.c index 1c3909937b832..b289fc7dc877d 100644 --- a/drivers/virtio/virtio-net.c +++ b/drivers/virtio/virtio-net.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -624,20 +625,8 @@ static void virtio_net_set_macaddr(FAR struct virtio_net_priv_s *priv) * conflicts with something else on the network. */ - srand(time(NULL) + -#ifdef CONFIG_NETDEV_IFINDEX - dev->d_ifindex -#else - (uintptr_t)dev % 256 -#endif - ); - mac[0] = 0x42; - mac[1] = rand() % 256; - mac[2] = rand() % 256; - mac[3] = rand() % 256; - mac[4] = rand() % 256; - mac[5] = rand() % 256; + arc4random_buf(mac + 1, 5); } } diff --git a/fs/driver/fs_blockproxy.c b/fs/driver/fs_blockproxy.c index 5e2858a1155ea..1227e269dc5f1 100644 --- a/fs/driver/fs_blockproxy.c +++ b/fs/driver/fs_blockproxy.c @@ -69,19 +69,17 @@ static mutex_t g_devno_lock = NXMUTEX_INITIALIZER; * attempt to open() the file. * * Input Parameters: - * None + * devbuf - Buffer to store the generated device name + * len - Length of the buffer * * Returned Value: - * The allocated path to the device. This must be released by the caller - * to prevent memory links. NULL will be returned only the case where - * we fail to allocate memory. + * Zero (OK) on success; a negated errno value on failure. * ****************************************************************************/ -static FAR char *unique_chardev(void) +static int unique_chardev(FAR char *devbuf, size_t len) { struct stat statbuf; - char devbuf[16]; uint32_t devno; int ret; @@ -95,7 +93,7 @@ static FAR char *unique_chardev(void) if (ret < 0) { ferr("ERROR: nxmutex_lock failed: %d\n", ret); - return NULL; + return ret; } /* Get the next device number and release the semaphore */ @@ -106,8 +104,7 @@ static FAR char *unique_chardev(void) /* Construct the full device number */ devno &= 0xffffff; - snprintf(devbuf, sizeof(devbuf), "/dev/tmpc%06lx", - (unsigned long)devno); + snprintf(devbuf, len, "/dev/tmpc%06lx", (unsigned long)devno); /* Make sure that file name is not in use */ @@ -115,7 +112,7 @@ static FAR char *unique_chardev(void) if (ret < 0) { DEBUGASSERT(ret == -ENOENT); - return fs_heap_strdup(devbuf); + return OK; } /* It is in use, try again */ @@ -147,19 +144,19 @@ static FAR char *unique_chardev(void) int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) { + char chardev[16]; struct file temp; - FAR char *chardev; int ret; DEBUGASSERT(blkdev); /* Create a unique temporary file name for the character device */ - chardev = unique_chardev(); - if (chardev == NULL) + ret = unique_chardev(chardev, sizeof(chardev)); + if (ret != OK) { ferr("ERROR: Failed to create temporary device name\n"); - return -ENOMEM; + return ret; } /* Wrap the block driver with an instance of the BCH driver */ @@ -169,8 +166,7 @@ int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) { ferr("ERROR: bchdev_register(%s, %s) failed: %d\n", blkdev, chardev, ret); - - goto errout_with_chardev; + return ret; } /* Open the newly created character driver */ @@ -180,7 +176,8 @@ int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) if (ret < 0) { ferr("ERROR: Failed to open %s: %d\n", chardev, ret); - goto errout_with_bchdev; + nx_unlink(chardev); + return ret; } ret = file_dup2(&temp, filep); @@ -188,7 +185,8 @@ int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) if (ret < 0) { ferr("ERROR: Failed to dup2%s: %d\n", chardev, ret); - goto errout_with_bchdev; + nx_unlink(chardev); + return ret; } /* Unlink the character device name. The driver instance will persist, @@ -200,19 +198,8 @@ int block_proxy(FAR struct file *filep, FAR const char *blkdev, int oflags) if (ret < 0) { ferr("ERROR: Failed to unlink %s: %d\n", chardev, ret); - goto errout_with_chardev; } - /* Free the allocated character driver name. */ - - fs_heap_free(chardev); - return OK; - -errout_with_bchdev: - nx_unlink(chardev); - -errout_with_chardev: - fs_heap_free(chardev); return ret; } diff --git a/fs/driver/fs_mtdproxy.c b/fs/driver/fs_mtdproxy.c index 44f9bc84e5137..93865d225b17c 100644 --- a/fs/driver/fs_mtdproxy.c +++ b/fs/driver/fs_mtdproxy.c @@ -40,7 +40,6 @@ #include #include "driver/driver.h" -#include "fs_heap.h" /**************************************************************************** * Private Data @@ -62,19 +61,17 @@ static mutex_t g_devno_lock = NXMUTEX_INITIALIZER; * attempt to open() the file. * * Input Parameters: - * None + * devbuf - Buffer to store the generated device name + * len - Length of the buffer * * Returned Value: - * The allocated path to the device. This must be released by the caller - * to prevent memory links. NULL will be returned only the case where - * we fail to allocate memory. + * Zero (OK) on success; a negated errno value on failure. * ****************************************************************************/ -static FAR char *unique_blkdev(void) +static int unique_blkdev(FAR char *devbuf, size_t len) { struct stat statbuf; - char devbuf[16]; uint32_t devno; int ret; @@ -88,7 +85,7 @@ static FAR char *unique_blkdev(void) if (ret < 0) { ferr("ERROR: nxmutex_lock failed: %d\n", ret); - return NULL; + return ret; } /* Get the next device number and release the semaphore */ @@ -99,8 +96,7 @@ static FAR char *unique_blkdev(void) /* Construct the full device number */ devno &= 0xffffff; - snprintf(devbuf, sizeof(devbuf), "/dev/tmpb%06lx", - (unsigned long)devno); + snprintf(devbuf, len, "/dev/tmpb%06lx", (unsigned long)devno); /* Make sure that file name is not in use */ @@ -108,7 +104,7 @@ static FAR char *unique_blkdev(void) if (ret < 0) { DEBUGASSERT(ret == -ENOENT); - return fs_heap_strdup(devbuf); + return OK; } /* It is in use, try again */ @@ -143,17 +139,17 @@ static FAR char *unique_blkdev(void) int mtd_proxy(FAR const char *mtddev, int mountflags, FAR struct inode **ppinode) { + char blkdev[16]; FAR struct inode *mtd; - FAR char *blkdev; int ret; /* Create a unique temporary file name for the block device */ - blkdev = unique_blkdev(); - if (blkdev == NULL) + ret = unique_blkdev(blkdev, sizeof(blkdev)); + if (ret != OK) { ferr("ERROR: Failed to create temporary device name\n"); - return -ENOMEM; + return ret; } /* Wrap the mtd driver with an instance of the ftl driver */ @@ -162,7 +158,7 @@ int mtd_proxy(FAR const char *mtddev, int mountflags, if (ret < 0) { ferr("ERROR: Failed to find %s mtd driver\n", mtddev); - goto out_with_blkdev; + return ret; } ret = ftl_initialize_by_path(blkdev, mtd->u.i_mtd, mountflags); @@ -171,7 +167,7 @@ int mtd_proxy(FAR const char *mtddev, int mountflags, { ferr("ERROR: ftl_initialize_by_path(%s, %s) failed: %d\n", mtddev, blkdev, ret); - goto out_with_blkdev; + return ret; } /* Open the newly created block driver */ @@ -180,7 +176,8 @@ int mtd_proxy(FAR const char *mtddev, int mountflags, if (ret < 0) { ferr("ERROR: Failed to open %s: %d\n", blkdev, ret); - goto out_with_fltdev; + nx_unlink(blkdev); + return ret; } /* Unlink and free the block device name. The driver instance will @@ -188,9 +185,11 @@ int mtd_proxy(FAR const char *mtddev, int mountflags, * we have a problem here!) */ -out_with_fltdev: - nx_unlink(blkdev); -out_with_blkdev: - fs_heap_free(blkdev); + ret = nx_unlink(blkdev); + if (ret < 0) + { + ferr("ERROR: Failed to unlink %s: %d\n", blkdev, ret); + } + return ret; } diff --git a/include/crypto/cryptodev.h b/include/crypto/cryptodev.h index a9c231dfd4fb7..d180e6a12a427 100644 --- a/include/crypto/cryptodev.h +++ b/include/crypto/cryptodev.h @@ -103,38 +103,40 @@ #define CRYPTO_MD5_HMAC 4 #define CRYPTO_SHA1_HMAC 5 #define CRYPTO_RIPEMD160_HMAC 6 -#define CRYPTO_RIJNDAEL128_CBC 7 /* 128 bit blocksize */ -#define CRYPTO_AES_CBC 7 /* 128 bit blocksize -- the same as above */ -#define CRYPTO_DEFLATE_COMP 8 /* Deflate compression algorithm */ -#define CRYPTO_NULL 9 -#define CRYPTO_SHA2_256_HMAC 11 -#define CRYPTO_SHA2_384_HMAC 12 -#define CRYPTO_SHA2_512_HMAC 13 -#define CRYPTO_AES_CTR 14 -#define CRYPTO_AES_XTS 15 -#define CRYPTO_AES_GCM_16 16 -#define CRYPTO_AES_128_GMAC 17 -#define CRYPTO_AES_192_GMAC 18 -#define CRYPTO_AES_256_GMAC 19 -#define CRYPTO_AES_GMAC 20 -#define CRYPTO_AES_OFB 21 -#define CRYPTO_AES_CFB_8 22 -#define CRYPTO_AES_CFB_128 23 -#define CRYPTO_CHACHA20_POLY1305 24 -#define CRYPTO_CHACHA20_POLY1305_MAC 25 -#define CRYPTO_MD5 26 -#define CRYPTO_POLY1305 27 -#define CRYPTO_RIPEMD160 28 -#define CRYPTO_SHA1 29 -#define CRYPTO_SHA2_224 30 -#define CRYPTO_SHA2_256 31 -#define CRYPTO_SHA2_384 32 -#define CRYPTO_SHA2_512 33 -#define CRYPTO_CRC32 34 -#define CRYPTO_AES_CMAC 35 -#define CRYPTO_AES_128_CMAC 36 -#define CRYPTO_ESN 37 /* Support for Extended Sequence Numbers */ -#define CRYPTO_ALGORITHM_MAX 37 /* Keep updated */ +#define CRYPTO_RIJNDAEL128_CBC 7 /* 128 bit blocksize */ +#define CRYPTO_AES_CBC 7 /* 128 bit blocksize -- the same as above */ +#define CRYPTO_AES_192_CBC 8 /* 192 bit keysize */ +#define CRYPTO_AES_256_CBC 9 /* 256 bit keysize */ +#define CRYPTO_DEFLATE_COMP 10 /* Deflate compression algorithm */ +#define CRYPTO_NULL 11 +#define CRYPTO_SHA2_256_HMAC 12 +#define CRYPTO_SHA2_384_HMAC 13 +#define CRYPTO_SHA2_512_HMAC 14 +#define CRYPTO_AES_CTR 15 +#define CRYPTO_AES_XTS 16 +#define CRYPTO_AES_GCM_16 17 +#define CRYPTO_AES_128_GMAC 18 +#define CRYPTO_AES_192_GMAC 19 +#define CRYPTO_AES_256_GMAC 20 +#define CRYPTO_AES_GMAC 21 +#define CRYPTO_AES_OFB 22 +#define CRYPTO_AES_CFB_8 23 +#define CRYPTO_AES_CFB_128 24 +#define CRYPTO_CHACHA20_POLY1305 25 +#define CRYPTO_CHACHA20_POLY1305_MAC 26 +#define CRYPTO_MD5 27 +#define CRYPTO_POLY1305 28 +#define CRYPTO_RIPEMD160 29 +#define CRYPTO_SHA1 30 +#define CRYPTO_SHA2_224 31 +#define CRYPTO_SHA2_256 32 +#define CRYPTO_SHA2_384 33 +#define CRYPTO_SHA2_512 34 +#define CRYPTO_CRC32 35 +#define CRYPTO_AES_CMAC 36 +#define CRYPTO_AES_128_CMAC 37 +#define CRYPTO_ESN 38 /* Support for Extended Sequence Numbers */ +#define CRYPTO_ALGORITHM_MAX 38 /* Keep updated */ /* Algorithm flags */ diff --git a/include/fcntl.h b/include/fcntl.h index 5be8390ecec86..49fa89a9eb65c 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -67,7 +67,7 @@ /* Unsupported, but required open flags */ -#define O_RSYNC 0 /* Synchronize input on read */ +#define O_RSYNC O_SYNC /* Synchronize input on read */ #define O_ACCMODE O_RDWR /* Mask for access mode */ #define O_NOCTTY 0 /* Required by POSIX */ #define O_BINARY 0 /* Open the file in binary (untranslated) mode. */ @@ -160,13 +160,6 @@ #define F_SEAL_WRITE 0x0008 /* Prevent writes */ #define F_SEAL_FUTURE_WRITE 0x0010 /* Prevent future writes while mapped */ -/* int creat(const char *path, mode_t mode); - * - * is equivalent to open with O_WRONLY|O_CREAT|O_TRUNC. - */ - -#define creat(path, mode) open(path, O_WRONLY|O_CREAT|O_TRUNC, mode) - #if defined(CONFIG_FS_LARGEFILE) # define F_GETLK64 F_GETLK # define F_SETLK64 F_SETLK @@ -215,6 +208,7 @@ extern "C" /* POSIX-like File System Interfaces */ +int creat(FAR const char *pathname, mode_t mode); int open(FAR const char *path, int oflag, ...); int openat(int dirfd, FAR const char *path, int oflag, ...); int fcntl(int fd, int cmd, ...); diff --git a/include/limits.h b/include/limits.h index 4d9a65d07c8e4..4cf2644161443 100644 --- a/include/limits.h +++ b/include/limits.h @@ -314,6 +314,12 @@ #define SEM_NSEMS_MAX _POSIX_SEM_NSEMS_MAX #define SEM_VALUE_MAX _POSIX_SEM_VALUE_MAX +/* Required for POSIX pthread management */ + +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 +#define _POSIX_THREAD_KEYS_MAX CONFIG_TLS_NELEM +#define _POSIX_THREAD_THREADS_MAX 64 + /* Required for readv() and writev() */ /* There really is no upper limit on the number of vectors */ diff --git a/include/netinet/if_ether.h b/include/netinet/if_ether.h index 01da882ab35c6..db35a1c43a9e4 100644 --- a/include/netinet/if_ether.h +++ b/include/netinet/if_ether.h @@ -50,6 +50,7 @@ #define ETH_P_IP ETHERTYPE_IP #define ETH_P_IPV6 ETHERTYPE_IPV6 #define ETH_P_ARP ETHERTYPE_ARP +#define ETH_P_TSN 0x22F0 /* TSN (IEEE 1722) packet */ /**************************************************************************** * Public Type Definitions diff --git a/include/netinet/in.h b/include/netinet/in.h index 33d35a7a1d8ce..9647922d66277 100644 --- a/include/netinet/in.h +++ b/include/netinet/in.h @@ -287,7 +287,7 @@ struct ip_mreq struct ip_mreqn { struct in_addr imr_multiaddr; /* IPv4 multicast address of group */ - struct in_addr imr_interface; /* Local IPv4 address of interface */ + struct in_addr imr_address; /* Local IPv4 address of interface */ unsigned int imr_ifindex; /* Local interface index */ }; diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 788b4219909fb..132c7e5f43df0 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -92,6 +92,12 @@ * Pre-processor definitions ****************************************************************************/ +#define IRQ_RISING_EDGE 0x00 +#define IRQ_FALLING_EDGE 0x01 +#define IRQ_BOTH_EDGE 0x02 +#define IRQ_HIGH_LEVEL 0x03 +#define IRQ_LOW_LEVEL 0x04 + #define DEBUGPOINT_NONE 0x00 #define DEBUGPOINT_WATCHPOINT_RO 0x01 #define DEBUGPOINT_WATCHPOINT_WO 0x02 @@ -1821,6 +1827,18 @@ void up_affinity_irq(int irq, cpu_set_t cpuset); void up_trigger_irq(int irq, cpu_set_t cpuset); #endif +/**************************************************************************** + * Name: up_set_irq_type + * + * Description: + * Config an IRQ trigger type. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_NOINTC +int up_set_irq_type(int irq, int mode); +#endif + /**************************************************************************** * Name: up_prioritize_irq * @@ -1925,7 +1943,7 @@ void up_timer_initialize(void); * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: * - * void nxsched_timer_expiration(void): Called by the platform-specific + * void nxsched_process_timer(void): Called by the platform-specific * logic when the interval timer expires. * ****************************************************************************/ @@ -1973,7 +1991,7 @@ void up_timer_getmask(FAR clock_t *mask); * Description: * Cancel the alarm and return the time of cancellation of the alarm. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the alarm is + * nxsched_process_timer() will not be called unless the alarm is * restarted with up_alarm_start(). * * If, as a race condition, the alarm has already expired when this @@ -2010,7 +2028,7 @@ int up_alarm_tick_cancel(FAR clock_t *ticks); * Name: up_alarm_start * * Description: - * Start the alarm. nxsched_timer_expiration() will be called when the + * Start the alarm. nxsched_process_timer() will be called when the * alarm occurs (unless up_alaram_cancel is called to stop it). * * Provided by platform-specific code and called from the RTOS base code. @@ -2018,7 +2036,7 @@ int up_alarm_tick_cancel(FAR clock_t *ticks); * Input Parameters: * ts - The time in the future at the alarm is expected to occur. When * the alarm occurs the timer logic will call - * nxsched_timer_expiration(). + * nxsched_process_timer(). * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -2042,7 +2060,7 @@ int up_alarm_tick_start(clock_t ticks); * Description: * Cancel the interval timer and return the time remaining on the timer. * These two steps need to be as nearly atomic as possible. - * nxsched_timer_expiration() will not be called unless the timer is + * nxsched_process_timer() will not be called unless the timer is * restarted with up_timer_start(). * * If, as a race condition, the timer has already expired when this @@ -2081,14 +2099,14 @@ int up_timer_tick_cancel(FAR clock_t *ticks); * Name: up_timer_start * * Description: - * Start the interval timer. nxsched_timer_expiration() will be called at + * Start the interval timer. nxsched_process_timer() will be called at * the completion of the timeout (unless up_timer_cancel is called to stop * the timing. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * ts - Provides the time interval until nxsched_timer_expiration() is + * ts - Provides the time interval until nxsched_process_timer() is * called. * * Returned Value: @@ -2461,33 +2479,7 @@ void up_ndelay(unsigned long nanoseconds); * ****************************************************************************/ -#ifndef CONFIG_SCHED_TICKLESS void nxsched_process_timer(void); -#endif - -/**************************************************************************** - * Name: nxsched_timer_expiration - * - * Description: - * If CONFIG_SCHED_TICKLESS is defined, then this function is provided by - * the RTOS base code and called from platform-specific code when the - * interval timer used to implement the tick-less OS expires. - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * Base code implementation assumes that this function is called from - * interrupt handling logic with interrupts disabled. - * - ****************************************************************************/ - -#if defined(CONFIG_SCHED_TICKLESS) -void nxsched_timer_expiration(void); -#endif /**************************************************************************** * Name: nxsched_get_next_expired @@ -2939,6 +2931,16 @@ bool up_fpucmp(FAR const void *saveregs1, FAR const void *saveregs2); #define up_fpucmp(r1, r2) (true) #endif +/**************************************************************************** + * Name: up_regs_memcpy + ****************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_REGCPY +void up_regs_memcpy(FAR void *dest, FAR void *src, size_t count); +#else +#define up_regs_memcpy(dest, src, count) memcpy(dest, src, count) +#endif + #ifdef CONFIG_ARCH_HAVE_DEBUG /**************************************************************************** diff --git a/include/nuttx/hrtimer.h b/include/nuttx/hrtimer.h index e6c617b6b2937..350776889d88e 100644 --- a/include/nuttx/hrtimer.h +++ b/include/nuttx/hrtimer.h @@ -54,10 +54,6 @@ enum hrtimer_mode_e /* Forward declarations */ struct hrtimer_s; -struct hrtimer_node_s; - -typedef struct hrtimer_s hrtimer_t; -typedef struct hrtimer_node_s hrtimer_node_t; /* Callback type for high-resolution timer expiration * @@ -65,15 +61,15 @@ typedef struct hrtimer_node_s hrtimer_node_t; * timer context and must not block. */ -typedef CODE uint64_t (*hrtimer_entry_t)(FAR const hrtimer_t *hrtimer, +typedef CODE uint64_t (*hrtimer_entry_t)(FAR const struct hrtimer_s *hrtimer, uint64_t expired); /* Red-black tree node used to order hrtimers by expiration time */ -struct hrtimer_node_s +typedef struct hrtimer_node_s { RB_ENTRY(hrtimer_node_s) entry; /* RB-tree linkage */ -}; +} hrtimer_node_t; /* High-resolution timer object * @@ -82,12 +78,12 @@ struct hrtimer_node_s * directly by users except through the provided APIs. */ -struct hrtimer_s +typedef struct hrtimer_s { hrtimer_node_t node; /* RB-tree node for sorted insertion */ hrtimer_entry_t func; /* Expiration callback function */ uint64_t expired; /* Absolute expiration time (ns) */ -}; +} hrtimer_t; /**************************************************************************** * Public Function Prototypes @@ -118,12 +114,7 @@ extern "C" * None ****************************************************************************/ -static inline_function -void hrtimer_init(FAR hrtimer_t *hrtimer, hrtimer_cb func) -{ - memset(hrtimer, 0, sizeof(hrtimer_t)); - hrtimer->func = func; -} +#define hrtimer_init(hrtimer) memset(hrtimer, 0, sizeof(hrtimer_t)) /**************************************************************************** * Name: hrtimer_cancel @@ -184,6 +175,7 @@ int hrtimer_cancel_sync(FAR hrtimer_t *hrtimer); * * Input Parameters: * hrtimer - Timer instance to start + * func - Expiration callback function * expired - Expiration time in nanoseconds * mode - HRTIMER_MODE_ABS or HRTIMER_MODE_REL * @@ -191,7 +183,7 @@ int hrtimer_cancel_sync(FAR hrtimer_t *hrtimer); * OK on success; a negated errno value on failure. ****************************************************************************/ -int hrtimer_start(FAR hrtimer_t *hrtimer, +int hrtimer_start(FAR hrtimer_t *hrtimer, hrtimer_entry_t func, uint64_t expired, enum hrtimer_mode_e mode); diff --git a/include/nuttx/ioexpander/ioexpander.h b/include/nuttx/ioexpander/ioexpander.h index b2df1e4b31f46..218bd3c34a678 100644 --- a/include/nuttx/ioexpander/ioexpander.h +++ b/include/nuttx/ioexpander/ioexpander.h @@ -83,7 +83,11 @@ #define IOEXPANDER_WAKEUP_DISABLE 0 /* Do not cfg the pin as wake up source */ #define IOEXPANDER_WAKEUP_ENABLE 1 /* Cfg the pin as wake up source */ #define IOEXPANDER_OPTION_SETDEBOUNCE 6 /* Configure debounce duration */ +# define IOEXPANDER_DEBOUNCE_DISABLE 0 /* Disable debounce */ +# define IOEXPANDER_DEBOUNCE_ENABLE 1 /* Enable debounce */ #define IOEXPANDER_OPTION_SETMASK 7 /* Mask the interrupter */ +# define IOEXPANDER_MASK_DISABLE 0 /* Unmask the interrupter */ +# define IOEXPANDER_MASK_ENABLE 1 /* Mask the interrupter */ /* Access macros ************************************************************/ diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index a77546dc2d706..2fcdf612aeb7d 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -1504,6 +1504,41 @@ void netdev_lock(FAR struct net_driver_s *dev); void netdev_unlock(FAR struct net_driver_s *dev); +/**************************************************************************** + * Name: netdev_findbyname + * + * Description: + * Find a previously registered network device using its assigned + * network interface name + * + * Input Parameters: + * ifname The interface name of the device of interest + * + * Returned Value: + * Pointer to driver on success; null on failure + * + ****************************************************************************/ + +FAR struct net_driver_s *netdev_findbyname(FAR const char *ifname); + +/**************************************************************************** + * Name: netdev_findbyindex + * + * Description: + * Find a previously registered network device by assigned interface index. + * + * Input Parameters: + * ifindex - The interface index. This is a one-based index and must be + * greater than zero. + * + * Returned Value: + * Pointer to driver on success; NULL on failure. This function will return + * NULL only if there is no device corresponding to the provided index. + * + ****************************************************************************/ + +FAR struct net_driver_s *netdev_findbyindex(int ifindex); + #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/net/rpmsg.h b/include/nuttx/net/rpmsg.h index ff9137bb403eb..8f18b9ffe153d 100644 --- a/include/nuttx/net/rpmsg.h +++ b/include/nuttx/net/rpmsg.h @@ -33,7 +33,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define NET_RPMSG_EPT_NAME "rpmsg-%s" +#define NET_RPMSG_EPT_PREFIX "rpmsg-net-" #define NET_RPMSG_IFUP 0 /* IP-->LINK */ #define NET_RPMSG_IFDOWN 1 /* IP-->LINK */ @@ -43,6 +43,10 @@ #define NET_RPMSG_SOCKIOCTL 5 /* IP<--LINK */ #define NET_RPMSG_TRANSFER 6 /* IP<->LINK */ +#define NET_RPMSG_RESPONSE (1 << 31) +#define NET_RPMSG_IS_RESPONSE(cmd) (!!((cmd) & NET_RPMSG_RESPONSE)) +#define NET_RPMSG_GET_COMMAND(cmd) ((cmd) & ~NET_RPMSG_RESPONSE) + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/include/nuttx/net/rpmsgdrv.h b/include/nuttx/net/rpmsgdrv.h index 061c0191b2526..ff36c04e21fbc 100644 --- a/include/nuttx/net/rpmsgdrv.h +++ b/include/nuttx/net/rpmsgdrv.h @@ -28,18 +28,106 @@ ****************************************************************************/ #include -#include +#include /**************************************************************************** - * Public Function Prototypes + * Pre-processor Definitions ****************************************************************************/ #ifdef CONFIG_NET_RPMSG_DRV -int net_rpmsg_drv_init(FAR const char *cpuname, - FAR const char *devname, - enum net_lltype_e lltype); + +#define NET_RPMSG_EVENT_IF_UP 1 +#define NET_RPMSG_EVENT_IF_DOWN 2 +#define NET_RPMSG_EVENT_CARRIER_ON 3 +#define NET_RPMSG_EVENT_CARRIER_OFF 4 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef CODE void (*net_rpmsg_drv_cb_t)(FAR struct netdev_lowerhalf_s *dev, + int event); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ #else -#define net_rpmsg_drv_init(cpuname, devname, lltye) +#define EXTERN extern #endif +/**************************************************************************** + * Name: net_rpmsg_drv_init + * + * Description: + * Allocate a new network device instance for the RPMSG network and + * register it with the network device manager. This is the client side of + * the RPMSG driver. The RPMSG driver is the server side of the driver. + * + * Input Parameters: + * cpuname - Remote CPU name + * devname - Local and remote network device name + * lltype - Link layer type + * priv - Reference to the caller's private data + * + * Returned Value: + * A pointer to the allocated network device instance. NULL is returned on + * failure. + * + ****************************************************************************/ + +FAR struct netdev_lowerhalf_s * +net_rpmsg_drv_init(FAR const char *cpuname, FAR const char *devname, + enum net_lltype_e lltype); + +/**************************************************************************** + * Name: net_rpmsg_drv_priv + * + * Description: + * Get the private data associated with the network device instance. + * + * Input Parameters: + * dev - Reference to the network device instance. + * + ****************************************************************************/ + +FAR void *net_rpmsg_drv_priv(FAR struct netdev_lowerhalf_s *dev); + +/**************************************************************************** + * Name: net_rpmsg_drv_set_callback + * + * Description: + * Set the callback function for the network device instance. + * + * Input Parameters: + * dev - Reference to the network device instance. + * cb - Callback function to be set. + * + ****************************************************************************/ + +void net_rpmsg_drv_set_callback(FAR struct netdev_lowerhalf_s *dev, + net_rpmsg_drv_cb_t cb, FAR void *priv); + +/**************************************************************************** + * Name: net_rpmsg_drv_server_init + * + * Description: + * Initialize the RPMSG network (for server side). + * + ****************************************************************************/ + +#ifdef CONFIG_NET_RPMSG_DRV_SERVER +int net_rpmsg_drv_server_init(void); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif #endif /* __INCLUDE_NUTTX_NET_RPMSGDRV_H */ diff --git a/include/nuttx/net/wifi_sim.h b/include/nuttx/net/wifi_sim.h index 1b3d473a6e6fe..8fb707bbe2838 100644 --- a/include/nuttx/net/wifi_sim.h +++ b/include/nuttx/net/wifi_sim.h @@ -64,6 +64,7 @@ struct wifi_sim_lowerhalf_s int wifi_sim_init(FAR struct wifi_sim_lowerhalf_s *netdev); void wifi_sim_remove(FAR struct wifi_sim_lowerhalf_s *netdev); +bool wifi_sim_connected(FAR struct wifi_sim_lowerhalf_s *dev); #undef EXTERN #ifdef __cplusplus diff --git a/include/nuttx/notifier.h b/include/nuttx/notifier.h index 7fdbdbdb79fad..9afe8457f39c2 100644 --- a/include/nuttx/notifier.h +++ b/include/nuttx/notifier.h @@ -41,7 +41,7 @@ * Pre-processor Definitions ****************************************************************************/ -#define ATOMIC_NOTIFIER_INIT(name) {NULL} +#define ATOMIC_NOTIFIER_INIT(name) {NULL, RSPINLOCK_INITIALIZER} #define ATOMIC_NOTIFIER_HEAD(name) \ struct atomic_notifier_head name = ATOMIC_NOTIFIER_INIT(name) @@ -81,6 +81,7 @@ struct notifier_block struct atomic_notifier_head { FAR struct notifier_block *head; + rspinlock_t lock; }; struct blocking_notifier_head @@ -179,9 +180,9 @@ extern "C" { \ FAR struct atomic_notifier_head *nh = (nhead); \ irqstate_t flags; \ - flags = enter_critical_section(); \ + flags = rspin_lock_irqsave_nopreempt(&nh->lock); \ notifier_chain_register(nh->head, (nb), false); \ - leave_critical_section(flags); \ + rspin_unlock_irqrestore_nopreempt(&nh->lock, flags); \ } \ while(0) @@ -190,9 +191,9 @@ extern "C" { \ FAR struct atomic_notifier_head *nh = (nhead); \ irqstate_t flags; \ - flags = enter_critical_section(); \ + flags = rspin_lock_irqsave_nopreempt(&nh->lock); \ notifier_chain_register(nh->head, (nb), true); \ - leave_critical_section(flags); \ + rspin_unlock_irqrestore_nopreempt(&nh->lock, flags); \ } \ while(0) @@ -201,9 +202,9 @@ extern "C" { \ FAR struct atomic_notifier_head *nh = (nhead); \ irqstate_t flags; \ - flags = enter_critical_section(); \ + flags = rspin_lock_irqsave_nopreempt(&nh->lock); \ notifier_chain_unregister(nh->head, (nb)); \ - leave_critical_section(flags); \ + rspin_unlock_irqrestore_nopreempt(&nh->lock, flags); \ } \ while(0) @@ -212,9 +213,9 @@ extern "C" { \ FAR struct atomic_notifier_head *nh = (nhead); \ irqstate_t flags; \ - flags = enter_critical_section(); \ + flags = rspin_lock_irqsave_nopreempt(&nh->lock); \ notifier_call_chain(nh->head, (val), (v), -1, NULL); \ - leave_critical_section(flags); \ + rspin_unlock_irqrestore_nopreempt(&nh->lock, flags); \ } \ while(0) diff --git a/include/nuttx/rpmsg/rpmsg.h b/include/nuttx/rpmsg/rpmsg.h index b31b56e299879..06f0be0193a9c 100644 --- a/include/nuttx/rpmsg/rpmsg.h +++ b/include/nuttx/rpmsg/rpmsg.h @@ -31,6 +31,7 @@ #ifdef CONFIG_RPMSG +#include #include #include #include @@ -63,6 +64,7 @@ struct rpmsg_s #ifdef CONFIG_RPMSG_TEST struct rpmsg_endpoint test; #endif + atomic_int signals; struct rpmsg_device rdev[0]; }; @@ -82,7 +84,6 @@ struct rpmsg_ops_s CODE void (*dump)(FAR struct rpmsg_s *rpmsg); CODE FAR const char *(*get_local_cpuname)(FAR struct rpmsg_s *rpmsg); CODE FAR const char *(*get_cpuname)(FAR struct rpmsg_s *rpmsg); - CODE int (*get_signals)(FAR struct rpmsg_s *rpmsg); }; CODE typedef void (*rpmsg_dev_cb_t)(FAR struct rpmsg_device *rdev, @@ -112,6 +113,8 @@ int rpmsg_post(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem); FAR const char *rpmsg_get_local_cpuname(FAR struct rpmsg_device *rdev); FAR const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev); int rpmsg_get_signals(FAR struct rpmsg_device *rdev); +void rpmsg_modify_signals(FAR struct rpmsg_s *rpmsg, + int setflags, int clrflags); static inline_function bool rpmsg_is_running(FAR struct rpmsg_device *rdev) { diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h index 4646ba5cef18f..4159035d00006 100644 --- a/include/nuttx/tls.h +++ b/include/nuttx/tls.h @@ -199,7 +199,7 @@ struct tls_cleanup_s struct tls_info_s { - FAR struct task_info_s * tl_task; + FAR struct task_info_s *tl_task; #if defined(CONFIG_TLS_NELEM) && CONFIG_TLS_NELEM > 0 uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */ @@ -224,6 +224,7 @@ struct tls_info_s uint16_t tl_size; /* Actual size with alignments */ int tl_errno; /* Per-thread error number */ pid_t tl_tid; /* Thread ID */ + FAR char **tl_argv; /* Arguments first string */ }; /**************************************************************************** diff --git a/include/nuttx/uorb.h b/include/nuttx/uorb.h index 4b74ddfbedb68..067e997d5dba5 100644 --- a/include/nuttx/uorb.h +++ b/include/nuttx/uorb.h @@ -475,7 +475,6 @@ /* GNSS Geofence */ #define SENSOR_TYPE_GNSS_GEOFENCE 52 - /* Velocity Sensor * A sensor of this type measures the velocity as it is moving. * The default unit velocity is meter by seconds m/s (SI). @@ -511,11 +510,20 @@ #define SENSOR_TYPE_ULTRAVIOLET 57 +/* ENG (Electroneurography) + * A sensor of this type measures the electrical activity of peripheral + * nerves. This neural electrical signal, generated by nerve impulses + * traveling through axons and captured by electrodes, provides valuable + * information about nervous system and muscle-nerve communication. + */ + +#define SENSOR_TYPE_ENG 58 + /* The total number of sensor * please increase it if you added a new sensor type! */ -#define SENSOR_TYPE_COUNT 58 +#define SENSOR_TYPE_COUNT 59 /* The additional sensor open flags */ @@ -902,6 +910,13 @@ struct sensor_cap /* Type: Capacitance */ int32_t rawdata[4]; /* in SI units pF */ }; +struct sensor_eng /* Type: ENG */ +{ + uint64_t timestamp; /* Unit is microseconds */ + float voltage[4]; /* Voltage unit in mV */ + uint32_t stat; /* Status. bit3:0 - value 3:0 is valid or not */ +}; + struct sensor_gnss /* Type: GNSS */ { uint64_t timestamp; /* Time since system start, Units is microseconds */ diff --git a/include/pthread.h b/include/pthread.h index 4d3d90dc698e8..50ea4fbb80a00 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -604,7 +604,7 @@ pid_t pthread_gettid_np(pthread_t thread); /* Compare two thread IDs. */ -#define pthread_equal(t1,t2) ((t1) == (t2)) +int pthread_equal(pthread_t t1, pthread_t t2); /* Thread scheduling parameters */ @@ -774,11 +774,6 @@ int pthread_rwlock_clockwrlock(FAR pthread_rwlock_t *lock, int pthread_rwlock_trywrlock(FAR pthread_rwlock_t *lock); int pthread_rwlock_unlock(FAR pthread_rwlock_t *lock); -/* Pthread signal management APIs */ - -int pthread_kill(pthread_t thread, int sig); -int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset); - #ifdef CONFIG_PTHREAD_SPINLOCKS /* Pthread spinlocks */ @@ -820,50 +815,11 @@ int pthread_atfork(CODE void (*prepare)(void), * available in any inclusion ordering. */ -#ifndef __PTHREAD_KEY_T_DEFINED -typedef int pthread_key_t; -# define __PTHREAD_KEY_T_DEFINED 1 -#endif - #ifndef __PTHREAD_ADDR_T_DEFINED typedef FAR void *pthread_addr_t; # define __PTHREAD_ADDR_T_DEFINED 1 #endif -#ifndef __PTHREAD_ATTR_T_DEFINED -struct pthread_attr_s; -typedef struct pthread_attr_s pthread_attr_t; -# define __PTHREAD_ATTR_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_T_DEFINED -typedef pid_t pthread_t; -# define __PTHREAD_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_CONDATTR_T_DEFINED -typedef struct pthread_condattr_s pthread_condattr_t; -# define __PTHREAD_CONDATTR_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_COND_T_DEFINED -struct pthread_cond_s; -typedef struct pthread_cond_s pthread_cond_t; -# define __PTHREAD_COND_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_MUTEXATTR_T_DEFINED -struct pthread_mutexattr_s; -typedef struct pthread_mutexattr_s pthread_mutexattr_t; -# define __PTHREAD_MUTEXATTR_T_DEFINED 1 -#endif - -#ifndef __PTHREAD_MUTEX_T_DEFINED -struct pthread_mutex_s; -typedef struct pthread_mutex_s pthread_mutex_t; -# define __PTHREAD_MUTEX_T_DEFINED 1 -#endif - #ifndef __PTHREAD_BARRIERATTR_T_DEFINED struct pthread_barrierattr_s; typedef struct pthread_barrierattr_s pthread_barrierattr_t; @@ -896,10 +852,4 @@ typedef struct pthread_spinlock_s pthread_spinlock_t; # endif #endif /* CONFIG_PTHREAD_SPINLOCKS */ -#ifndef __PTHREAD_ONCE_T_DEFINED -struct pthread_once_s; -typedef struct pthread_once_s pthread_once_t; -# define __PTHREAD_ONCE_T_DEFINED 1 -#endif - #endif /* __INCLUDE_PTHREAD_H */ diff --git a/include/signal.h b/include/signal.h index b63d77aa99946..f3d9ccd165eff 100644 --- a/include/signal.h +++ b/include/signal.h @@ -486,6 +486,11 @@ int sigwaitinfo(FAR const sigset_t *set, FAR struct siginfo *value); int sigaltstack(FAR const stack_t *ss, FAR stack_t *oss); int siginterrupt(int signo, int flag); +/* Pthread signal management APIs */ + +int pthread_kill(pthread_t thread, int sig); +int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset); + #undef EXTERN #ifdef __cplusplus } diff --git a/include/stddef.h b/include/stddef.h index 85d5da51bd42c..afe88c6d7f1e2 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -37,6 +37,8 @@ * Type Definitions ****************************************************************************/ +#ifndef __ASSEMBLY__ + /* The header shall define the following types: * * ptrdiff_t @@ -84,4 +86,6 @@ typedef struct #endif } max_align_t; +#endif /* __ASSEMBLY__ */ + #endif /* __INCLUDE_STDDEF_H */ diff --git a/include/stdint.h b/include/stdint.h index e14610ea146c2..0feaf403da69f 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -156,6 +156,8 @@ * Public Types ****************************************************************************/ +#ifndef __ASSEMBLY__ + /* Exact-width integer types. NOTE that these types are defined in * architecture-specific logic with leading underscore character. This file * typedef's these to the final name without the underscore character. This @@ -254,5 +256,7 @@ typedef _uint_farptr_t uint_farptr_t; typedef _intmax_t intmax_t; typedef _uintmax_t uintmax_t; +#endif /* __ASSEMBLY__ */ + #endif /* CONFIG_ARCH_STDINT_H */ #endif /* __INCLUDE_STDINT_H */ diff --git a/include/stdio.h b/include/stdio.h index 65b11586964c1..1aa4e6691b5c8 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -87,7 +87,7 @@ /* The maximum number of unique temporary file names that can be generated */ -#define TMP_MAX 56800235584ull +#define TMP_MAX 308915776 #if defined(CONFIG_FS_LARGEFILE) # define tmpfile64 tmpfile @@ -163,7 +163,7 @@ int fscanf(FAR FILE *stream, FAR const IPTR char *fmt, ...) scanf_like(2, 3); int fseek(FAR FILE *stream, long int offset, int whence); int fseeko(FAR FILE *stream, off_t offset, int whence); -int fsetpos(FAR FILE *stream, FAR fpos_t *pos); +int fsetpos(FAR FILE *stream, FAR const fpos_t *pos); long ftell(FAR FILE *stream); off_t ftello(FAR FILE *stream); size_t fwrite(FAR const void *ptr, size_t size, size_t n_items, diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h index 61eaf31f2d1d1..6483935ac451c 100644 --- a/include/sys/ioctl.h +++ b/include/sys/ioctl.h @@ -68,6 +68,13 @@ * Pre-processor Definitions ****************************************************************************/ +/* The compatibility IOCTL definitions */ + +#define _IO(type,nr) _IOC((type),(nr)) + +#define FS_IOC_GETFLAGS FIOC_GETFLAGS +#define FS_IOC_SETFLAGS FIOC_SETFLAGS + #undef EXTERN #if defined(__cplusplus) #define EXTERN extern "C" diff --git a/include/sys/resource.h b/include/sys/resource.h index 6bb4cf00f78b7..55b8164efebdf 100644 --- a/include/sys/resource.h +++ b/include/sys/resource.h @@ -67,6 +67,8 @@ #define RLIMIT_RTPRIO 14 /* Limit on RT tasks priority */ #define RLIMIT_RTTIME 15 /* Limit on timeout for RT tasks (us) */ +#define RLIM_NLIMITS 16 /* Limits of all supported kinds */ + #if defined(CONFIG_FS_LARGEFILE) # define RLIM_INFINITY UINT64_MAX /* No limit */ # define RLIM_SAVED_MAX UINT64_MAX /* Unrepresentable saved hard limit */ diff --git a/include/sys/types.h b/include/sys/types.h index e059ef20ab6af..51b190ae322dd 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -317,12 +317,61 @@ typedef CODE int (*main_t)(int argc, FAR char *argv[]); /* POSIX-like OS return values: */ +#ifdef OK +# undef OK +#endif + enum { ERROR = -1, OK = 0 }; +#ifndef __PTHREAD_ATTR_T_DEFINED +struct pthread_attr_s; +typedef struct pthread_attr_s pthread_attr_t; +# define __PTHREAD_ATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_COND_T_DEFINED +struct pthread_cond_s; +typedef struct pthread_cond_s pthread_cond_t; +# define __PTHREAD_COND_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_CONDATTR_T_DEFINED +typedef struct pthread_condattr_s pthread_condattr_t; +# define __PTHREAD_CONDATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_KEY_T_DEFINED +typedef int pthread_key_t; +# define __PTHREAD_KEY_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_MUTEX_T_DEFINED +struct pthread_mutex_s; +typedef struct pthread_mutex_s pthread_mutex_t; +# define __PTHREAD_MUTEX_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_MUTEXATTR_T_DEFINED +struct pthread_mutexattr_s; +typedef struct pthread_mutexattr_s pthread_mutexattr_t; +# define __PTHREAD_MUTEXATTR_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_T_DEFINED +typedef pid_t pthread_t; +# define __PTHREAD_T_DEFINED 1 +#endif + +#ifndef __PTHREAD_ONCE_T_DEFINED +struct pthread_once_s; +typedef struct pthread_once_s pthread_once_t; +# define __PTHREAD_ONCE_T_DEFINED 1 +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/include/sys/wait.h b/include/sys/wait.h index 658a236d553b6..4f653a8fbe426 100644 --- a/include/sys/wait.h +++ b/include/sys/wait.h @@ -46,11 +46,12 @@ #define WEXITSTATUS(s) (((s) >> 8) & 0xff) /* Return exit status */ #define WIFEXITED(s) (((s) & 0xff) == 0) /* True: Child exited normally */ -#define WIFCONTINUED(s) (false) /* True: Child has been continued */ -#define WIFSIGNALED(s) (false) /* True: Child exited due to uncaught signal */ -#define WIFSTOPPED(s) (false) /* True: Child is currently stopped */ -#define WSTOPSIG(s) (false) /* Return signal number that caused process to stop */ -#define WTERMSIG(s) (false) /* Return signal number that caused process to terminate */ +#define WIFCONTINUED(s) (false) /* True: Child has been continued */ +#define WIFSIGNALED(s) (false) /* True: Child exited due to uncaught signal */ +#define WIFSTOPPED(s) (false) /* True: Child is currently stopped */ +#define WSTOPSIG(s) (false) /* Return signal number that caused process to stop */ +#define WTERMSIG(s) (((s) >> 8) & 0x7f) /* Return signal number that caused process to terminate */ +#define WCOREDUMP(s) (((s) >> 8) & 0x80) /* True: Child has produced a core dump */ /* The following symbolic constants are possible values for the options * argument to waitpid() (1) and/or waitid() (2), diff --git a/include/ulimit.h b/include/ulimit.h new file mode 100644 index 0000000000000..2260cd69b7ab6 --- /dev/null +++ b/include/ulimit.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * include/ulimit.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_ULIMIT_H +#define __INCLUDE_ULIMIT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get limit on the size of a file, in units of 512 bytes */ + +#define UL_GETFSIZE 1 + +/* Set limit on the size of a file */ + +#define UL_SETFSIZE 2 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +long int ulimit(int cmd, long newlimit); + +#endif /* __INCLUDE_ULIMIT_H */ diff --git a/include/unistd.h b/include/unistd.h index a4626136f1ef7..4948ae82834f1 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -97,7 +97,7 @@ #define _POSIX_SYNC_IO 1 #undef _POSIX_ASYNC_IO -#undef _POSIX_PRIO_IO +#define _POSIX_PRIO_IO 1 #define _XOPEN_UNIX 1 #define _XOPEN_VERSION 700L diff --git a/libs/libc/gdbstub/lib_gdbstub.c b/libs/libc/gdbstub/lib_gdbstub.c index 362735fe5dbf0..4467ee00b090a 100644 --- a/libs/libc/gdbstub/lib_gdbstub.c +++ b/libs/libc/gdbstub/lib_gdbstub.c @@ -116,6 +116,10 @@ static const struct memory_region_s g_memory_region[] = }; #endif +#if defined(CONFIG_SMP) && defined(CONFIG_ARCH_HAVE_DEBUG) +static struct smp_call_data_s g_call_data; +#endif + /**************************************************************************** * Private Functions Prototypes ****************************************************************************/ @@ -1889,8 +1893,9 @@ int gdb_debugpoint_add(int type, FAR void *addr, size_t size, point.size = size; point.callback = callback; point.arg = arg; - return nxsched_smp_call((1 << CONFIG_SMP_NCPUS) - 1, - gdb_smp_debugpoint_add, &point); + + nxsched_smp_call_init(&g_call_data, gdb_smp_debugpoint_add, &point); + return nxsched_smp_call_async((1 << CONFIG_SMP_NCPUS) - 1, &g_call_data); #else return up_debugpoint_add(type, addr, size, callback, arg); #endif @@ -1908,8 +1913,8 @@ int gdb_debugpoint_remove(int type, FAR void *addr, size_t size) point.addr = addr; point.size = size; - return nxsched_smp_call((1 << CONFIG_SMP_NCPUS) - 1, - gdb_smp_debugpoint_remove, &point); + nxsched_smp_call_init(&g_call_data, gdb_smp_debugpoint_remove, &point); + return nxsched_smp_call_async((1 << CONFIG_SMP_NCPUS) - 1, &g_call_data); #else return up_debugpoint_remove(type, addr, size); #endif diff --git a/libs/libc/machine/arm/armv7-m/arch_memchr.S b/libs/libc/machine/arm/armv7-m/arch_memchr.S index f8922711b3a22..ce01481fcee5d 100644 --- a/libs/libc/machine/arm/armv7-m/arch_memchr.S +++ b/libs/libc/machine/arm/armv7-m/arch_memchr.S @@ -136,7 +136,7 @@ */ .text - .section .text.memchr + .section .text.memchr, "ax" .thumb_func .align 4 .p2align 4,,15 diff --git a/libs/libc/machine/arm/armv7-m/arch_memcpy.S b/libs/libc/machine/arm/armv7-m/arch_memcpy.S index c05eda88b8c1a..1b298ddbeaff2 100644 --- a/libs/libc/machine/arm/armv7-m/arch_memcpy.S +++ b/libs/libc/machine/arm/armv7-m/arch_memcpy.S @@ -94,7 +94,7 @@ .syntax unified .text - .section .text.memcpy + .section .text.memcpy, "ax" .align 2 .global ARCH_LIBCFUN(memcpy) .thumb diff --git a/libs/libc/machine/arm/armv7-m/arch_strcmp.S b/libs/libc/machine/arm/armv7-m/arch_strcmp.S index 1fb87bc1269b5..6e57b8d77f3b3 100644 --- a/libs/libc/machine/arm/armv7-m/arch_strcmp.S +++ b/libs/libc/machine/arm/armv7-m/arch_strcmp.S @@ -72,7 +72,7 @@ .macro def_fn f p2align=0 .text - .section .text.strcmp + .section .text.strcmp, "ax" .p2align \p2align .global \f .type \f, %function diff --git a/libs/libc/machine/arm/armv7-m/arch_strcpy.S b/libs/libc/machine/arm/armv7-m/arch_strcpy.S index b81c5ed3a3505..9d450d6b08159 100644 --- a/libs/libc/machine/arm/armv7-m/arch_strcpy.S +++ b/libs/libc/machine/arm/armv7-m/arch_strcpy.S @@ -60,7 +60,7 @@ .syntax unified .text - .section .text.strcpy + .section .text.strcpy, "ax" .align 2 .global ARCH_LIBCFUN(strcpy) .thumb diff --git a/libs/libc/machine/arm/armv7-m/arch_strlen.S b/libs/libc/machine/arm/armv7-m/arch_strlen.S index d5c6ea5adaa7c..f13bd749ca0c0 100644 --- a/libs/libc/machine/arm/armv7-m/arch_strlen.S +++ b/libs/libc/machine/arm/armv7-m/arch_strlen.S @@ -70,7 +70,7 @@ .macro def_fn f p2align=0 .text - .section .text.strlen + .section .text.strlen, "ax" .p2align \p2align .global \f .type \f, %function diff --git a/libs/libc/misc/CMakeLists.txt b/libs/libc/misc/CMakeLists.txt index fc032f5de3baf..5ca89843e398d 100644 --- a/libs/libc/misc/CMakeLists.txt +++ b/libs/libc/misc/CMakeLists.txt @@ -28,6 +28,7 @@ list( SRCS lib_bitmap.c lib_circbuf.c + lib_creat.c lib_mknod.c lib_umask.c lib_utsname.c diff --git a/libs/libc/misc/Make.defs b/libs/libc/misc/Make.defs index a901639e9a7db..091fc7306c51c 100644 --- a/libs/libc/misc/Make.defs +++ b/libs/libc/misc/Make.defs @@ -22,11 +22,11 @@ # Add the internal C files to the build -CSRCS += lib_bitmap.c lib_circbuf.c lib_mknod.c lib_umask.c lib_utsname.c -CSRCS += lib_getrandom.c lib_xorshift128.c lib_tea_encrypt.c lib_tea_decrypt.c -CSRCS += lib_cxx_initialize.c lib_impure.c lib_memfd.c lib_mutex.c -CSRCS += lib_fchmodat.c lib_fstatat.c lib_getfullpath.c lib_openat.c -CSRCS += lib_mkdirat.c lib_utimensat.c lib_mallopt.c +CSRCS += lib_bitmap.c lib_circbuf.c lib_creat.c lib_mknod.c lib_umask.c +CSRCS += lib_utsname.c lib_getrandom.c lib_xorshift128.c lib_tea_encrypt.c +CSRCS += lib_tea_decrypt.c lib_cxx_initialize.c lib_impure.c lib_memfd.c +CSRCS += lib_mutex.c lib_fchmodat.c lib_fstatat.c lib_getfullpath.c +CSRCS += lib_openat.c lib_mkdirat.c lib_utimensat.c lib_mallopt.c CSRCS += lib_idr.c lib_getnprocs.c ifeq ($(CONFIG_LIBC_TEMPBUFFER),y) diff --git a/libs/libc/misc/lib_creat.c b/libs/libc/misc/lib_creat.c new file mode 100644 index 0000000000000..56683adbde3e7 --- /dev/null +++ b/libs/libc/misc/lib_creat.c @@ -0,0 +1,52 @@ +/**************************************************************************** + * libs/libc/misc/lib_creat.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: creat + * + * Description: + * The creat() function is just a simple wrapper of open() function + * + * Input Parameters: + * path - The path for the file to create on + * mode - the access mode + * + * Returned Value: + * Return a file descriptor of the file that created success, + * return -1 if error occurd on creat new file, and errno is setup + * + ****************************************************************************/ + +int creat(FAR const char *path, mode_t mode) +{ + return open(path, O_WRONLY | O_CREAT | O_TRUNC, mode); +} diff --git a/libs/libc/misc/lib_ftok.c b/libs/libc/misc/lib_ftok.c index ed35966a29802..56cb7b4e80d7e 100644 --- a/libs/libc/misc/lib_ftok.c +++ b/libs/libc/misc/lib_ftok.c @@ -72,7 +72,7 @@ key_t ftok(FAR const char *pathname, int proj_id) snprintf(fullpath, PATH_MAX, "%s/", CONFIG_LIBC_FTOK_VFS_PATH); - strlcat(fullpath, pathname, sizeof(fullpath)); + strlcat(fullpath, pathname, PATH_MAX); if (stat(fullpath, &st) < 0 && get_errno() == ENOENT) { /* Directory not exist, let's create one for caller */ diff --git a/libs/libc/netdb/lib_dnsaddserver.c b/libs/libc/netdb/lib_dnsaddserver.c index b32d17ad4d4d7..4827ac0aa031c 100644 --- a/libs/libc/netdb/lib_dnsaddserver.c +++ b/libs/libc/netdb/lib_dnsaddserver.c @@ -227,7 +227,9 @@ int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) ret = OK; } - goto errout; + dns_unlock(); + fclose(stream); + return ret; } #if CONFIG_NETDB_DNSSERVER_NAMESERVERS > 1 diff --git a/libs/libc/pthread/CMakeLists.txt b/libs/libc/pthread/CMakeLists.txt index 415b2cecb6de7..72ddf8fa5bd06 100644 --- a/libs/libc/pthread/CMakeLists.txt +++ b/libs/libc/pthread/CMakeLists.txt @@ -70,6 +70,7 @@ if(NOT CONFIG_DISABLE_PTHREAD) pthread_conddestroy.c pthread_condtimedwait.c pthread_create.c + pthread_equal.c pthread_exit.c pthread_kill.c pthread_setname_np.c diff --git a/libs/libc/pthread/Make.defs b/libs/libc/pthread/Make.defs index 1e9476a82247e..fff7b1356df96 100644 --- a/libs/libc/pthread/Make.defs +++ b/libs/libc/pthread/Make.defs @@ -46,7 +46,7 @@ CSRCS += pthread_condattr_init.c pthread_condattr_destroy.c CSRCS += pthread_condattr_getpshared.c pthread_condattr_setpshared.c CSRCS += pthread_condattr_setclock.c pthread_condattr_getclock.c CSRCS += pthread_condinit.c pthread_conddestroy.c pthread_condtimedwait.c -CSRCS += pthread_create.c pthread_exit.c pthread_kill.c +CSRCS += pthread_create.c pthread_equal.c pthread_exit.c pthread_kill.c CSRCS += pthread_setname_np.c pthread_getname_np.c CSRCS += pthread_get_stackaddr_np.c pthread_get_stacksize_np.c CSRCS += pthread_mutexattr_init.c pthread_mutexattr_destroy.c diff --git a/libs/libc/pthread/pthread_equal.c b/libs/libc/pthread/pthread_equal.c new file mode 100644 index 0000000000000..f6851511f4e87 --- /dev/null +++ b/libs/libc/pthread/pthread_equal.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * libs/libc/pthread/pthread_equal.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pthread_equal + * + * Description: + * Detect whether the two pthreads is equal or not + * + * Input Parameters: + * t1 - the first pthread to compare + * t2 - the another pthread to compare + * + * Returned Value: + * 1 (TRUE) if the two pthreads are equal, 0 (FALSE) otherwise. + * + * Assumptions: + * + ****************************************************************************/ + +int pthread_equal(pthread_t t1, pthread_t t2) +{ + return t1 == t2; +} diff --git a/libs/libc/stdio/lib_freopen.c b/libs/libc/stdio/lib_freopen.c index 2297bfbdc06fd..8489b9b6fb26b 100644 --- a/libs/libc/stdio/lib_freopen.c +++ b/libs/libc/stdio/lib_freopen.c @@ -31,6 +31,10 @@ #include #include +#ifdef CONFIG_FDSAN +# include +#endif + #include "libc.h" /**************************************************************************** @@ -97,12 +101,6 @@ FAR FILE *freopen(FAR const char *path, FAR const char *mode, return NULL; } - fd = open(path, oflags, 0666); - if (fd < 0) - { - return NULL; - } - /* Make sure that we have exclusive access to the stream */ flockfile(stream); @@ -117,11 +115,31 @@ FAR FILE *freopen(FAR const char *path, FAR const char *mode, funlockfile(stream); - /* Duplicate the new fd to the stream. */ + /* close the old fd */ - ret = dup2(fd, fileno(stream)); - close(fd); - if (ret < 0) +#ifdef CONFIG_FDSAN + android_fdsan_close_with_tag(fileno(stream), + android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_FILE, + (uintptr_t)stream)); +#else + close(fileno(stream)); +#endif + + /* Open the new file and reused the fd */ + + fd = open(path, oflags, 0666); +#ifdef CONFIG_FDSAN + android_fdsan_exchange_owner_tag(fd, 0, + android_fdsan_create_owner_tag(ANDROID_FDSAN_OWNER_TYPE_FILE, + (uintptr_t)stream)); +#endif + flockfile(stream); + stream->fs_cookie = (FAR void *)(intptr_t)fd; + funlockfile(stream); + + /* To clear the stale fd */ + + if (fd < 0) { return NULL; } diff --git a/libs/libc/stdio/lib_fsetpos.c b/libs/libc/stdio/lib_fsetpos.c index a0ac40ffc09a8..c42b8e07fc18b 100644 --- a/libs/libc/stdio/lib_fsetpos.c +++ b/libs/libc/stdio/lib_fsetpos.c @@ -53,7 +53,7 @@ * ****************************************************************************/ -int fsetpos(FAR FILE *stream, FAR fpos_t *pos) +int fsetpos(FAR FILE *stream, FAR const fpos_t *pos) { #ifdef CONFIG_DEBUG_FEATURES if (!stream || !pos) diff --git a/libs/libc/unistd/CMakeLists.txt b/libs/libc/unistd/CMakeLists.txt index 792c1ac4a7459..0cef734cc7a9d 100644 --- a/libs/libc/unistd/CMakeLists.txt +++ b/libs/libc/unistd/CMakeLists.txt @@ -69,7 +69,8 @@ set(SRCS lib_getpass.c lib_chdir.c lib_fchdir.c - lib_confstr.c) + lib_confstr.c + lib_ulimit.c) if(NOT CONFIG_SCHED_USER_IDENTITY) list( diff --git a/libs/libc/unistd/Make.defs b/libs/libc/unistd/Make.defs index 1ce751bd868d8..e5d8d248f6014 100644 --- a/libs/libc/unistd/Make.defs +++ b/libs/libc/unistd/Make.defs @@ -33,7 +33,7 @@ CSRCS += lib_futimes.c lib_lutimes.c lib_gethostname.c lib_sethostname.c CSRCS += lib_fchownat.c lib_linkat.c lib_readlinkat.c lib_symlinkat.c CSRCS += lib_unlinkat.c lib_usleep.c lib_getpgrp.c lib_getpgid.c CSRCS += lib_lockf.c lib_flock.c lib_getpass.c -CSRCS += lib_chdir.c lib_fchdir.c lib_confstr.c +CSRCS += lib_chdir.c lib_fchdir.c lib_confstr.c lib_ulimit.c ifneq ($(CONFIG_SCHED_USER_IDENTITY),y) CSRCS += lib_setuid.c lib_setgid.c lib_getuid.c lib_getgid.c diff --git a/libs/libc/unistd/lib_pathconf.c b/libs/libc/unistd/lib_pathconf.c index 69d750a62f5a4..d5630f8953ad5 100644 --- a/libs/libc/unistd/lib_pathconf.c +++ b/libs/libc/unistd/lib_pathconf.c @@ -136,6 +136,9 @@ long fpathconf(int fildes, int name) case _PC_MAX_INPUT: return _POSIX_MAX_INPUT; + case _PC_PRIO_IO: + return _POSIX_PRIO_IO; + default: /* Assume valid but not implemented for the time being */ diff --git a/libs/libc/unistd/lib_sysconf.c b/libs/libc/unistd/lib_sysconf.c index 8683350a9a1b2..dc6bfb8cba186 100644 --- a/libs/libc/unistd/lib_sysconf.c +++ b/libs/libc/unistd/lib_sysconf.c @@ -57,133 +57,133 @@ * symbolic constants defined in that are the corresponding * values used for name. * - * Variable Value of Name + * Variable Value of Name * - * {AIO_LISTIO_MAX} _SC_AIO_LISTIO_MAX - * {AIO_MAX} _SC_AIO_MAX - * {AIO_PRIO_DELTA_MAX} _SC_AIO_PRIO_DELTA_MAX - * {ARG_MAX} _SC_ARG_MAX - * {ATEXIT_MAX} _SC_ATEXIT_MAX - * {BC_BASE_MAX} _SC_BC_BASE_MAX - * {BC_DIM_MAX} _SC_BC_DIM_MAX - * {BC_SCALE_MAX} _SC_BC_SCALE_MAX - * {BC_STRING_MAX} _SC_BC_STRING_MAX - * {CHILD_MAX} _SC_CHILD_MAX - * Clock ticks/second _SC_CLK_TCK - * {COLL_WEIGHTS_MAX} _SC_COLL_WEIGHTS_MAX - * {DELAYTIMER_MAX} _SC_DELAYTIMER_MAX - * {EXPR_NEST_MAX} _SC_EXPR_NEST_MAX - * {HOST_NAME_MAX} _SC_HOST_NAME_MAX - * {IOV_MAX} _SC_IOV_MAX - * {LINE_MAX} _SC_LINE_MAX - * {LOGIN_NAME_MAX} _SC_LOGIN_NAME_MAX - * {NGROUPS_MAX} _SC_NGROUPS_MAX - * Maximum size of getgrgid_r() and _SC_GETGR_R_SIZE_MAX + * {AIO_LISTIO_MAX} _SC_AIO_LISTIO_MAX + * {AIO_MAX} _SC_AIO_MAX + * {AIO_PRIO_DELTA_MAX} _SC_AIO_PRIO_DELTA_MAX + * {ARG_MAX} _SC_ARG_MAX + * {ATEXIT_MAX} _SC_ATEXIT_MAX + * {BC_BASE_MAX} _SC_BC_BASE_MAX + * {BC_DIM_MAX} _SC_BC_DIM_MAX + * {BC_SCALE_MAX} _SC_BC_SCALE_MAX + * {BC_STRING_MAX} _SC_BC_STRING_MAX + * {CHILD_MAX} _SC_CHILD_MAX + * Clock ticks/second _SC_CLK_TCK + * {COLL_WEIGHTS_MAX} _SC_COLL_WEIGHTS_MAX + * {DELAYTIMER_MAX} _SC_DELAYTIMER_MAX + * {EXPR_NEST_MAX} _SC_EXPR_NEST_MAX + * {HOST_NAME_MAX} _SC_HOST_NAME_MAX + * {IOV_MAX} _SC_IOV_MAX + * {LINE_MAX} _SC_LINE_MAX + * {LOGIN_NAME_MAX} _SC_LOGIN_NAME_MAX + * {NGROUPS_MAX} _SC_NGROUPS_MAX + * Maximum size of getgrgid_r() and _SC_GETGR_R_SIZE_MAX * getgrnam_r() data buffers - * Maximum size of getpwuid_r() and _SC_GETPW_R_SIZE_MAX + * Maximum size of getpwuid_r() and _SC_GETPW_R_SIZE_MAX * getpwnam_r() data buffers - * {MQ_OPEN_MAX} _SC_MQ_OPEN_MAX - * {MQ_PRIO_MAX} _SC_MQ_PRIO_MAX - * {OPEN_MAX} _SC_OPEN_MAX - * _POSIX_ADVISORY_INFO _SC_ADVISORY_INFO - * _POSIX_BARRIERS _SC_BARRIERS - * _POSIX_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO - * _POSIX_CLOCK_SELECTION _SC_CLOCK_SELECTION - * _POSIX_CPUTIME _SC_CPUTIME - * _POSIX_FSYNC _SC_FSYNC - * _POSIX_IPV6 _SC_IPV6 - * _POSIX_JOB_CONTROL _SC_JOB_CONTROL - * _POSIX_MAPPED_FILES _SC_MAPPED_FILES - * _POSIX_MEMLOCK _SC_MEMLOCK - * _POSIX_MEMLOCK_RANGE _SC_MEMLOCK_RANGE - * _POSIX_MEMORY_PROTECTION _SC_MEMORY_PROTECTION - * _POSIX_MESSAGE_PASSING _SC_MESSAGE_PASSING - * _POSIX_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK - * _POSIX_PRIORITIZED_IO _SC_PRIORITIZED_IO - * _POSIX_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING - * _POSIX_RAW_SOCKETS _SC_RAW_SOCKETS - * _POSIX_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS - * _POSIX_REALTIME_SIGNALS _SC_REALTIME_SIGNALS - * _POSIX_REGEXP _SC_REGEXP - * _POSIX_SAVED_IDS _SC_SAVED_IDS - * _POSIX_SEMAPHORES _SC_SEMAPHORES - * _POSIX_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS - * _POSIX_SHELL _SC_SHELL - * _POSIX_SPAWN _SC_SPAWN - * _POSIX_SPIN_LOCKS _SC_SPIN_LOCKS - * _POSIX_SPORADIC_SERVER _SC_SPORADIC_SERVER - * _POSIX_SS_REPL_MAX _SC_SS_REPL_MAX - * _POSIX_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO - * _POSIX_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR - * _POSIX_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE - * _POSIX_THREAD_CPUTIME _SC_THREAD_CPUTIME - * _POSIX_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT - * _POSIX_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT - * _POSIX_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING - * _POSIX_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED - * _POSIX_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS - * _POSIX_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER - * _POSIX_THREADS _SC_THREADS - * _POSIX_TIMEOUTS _SC_TIMEOUTS - * _POSIX_TIMERS _SC_TIMERS - * _POSIX_TRACE _SC_TRACE - * _POSIX_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER - * _POSIX_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX - * _POSIX_TRACE_INHERIT _SC_TRACE_INHERIT - * _POSIX_TRACE_LOG _SC_TRACE_LOG - * _POSIX_TRACE_NAME_MAX _SC_TRACE_NAME_MAX - * _POSIX_TRACE_SYS_MAX _SC_TRACE_SYS_MAX - * _POSIX_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX - * _POSIX_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS - * _POSIX_VERSION _SC_VERSION - * _POSIX_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32 - * _POSIX_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG - * _POSIX_V6_LP64_OFF64 _SC_V6_LP64_OFF64 - * _POSIX_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG - * _POSIX2_C_BIND _SC_2_C_BIND - * _POSIX2_C_DEV _SC_2_C_DEV - * _POSIX2_CHAR_TERM _SC_2_CHAR_TERM - * _POSIX2_FORT_DEV _SC_2_FORT_DEV - * _POSIX2_FORT_RUN _SC_2_FORT_RUN - * _POSIX2_LOCALEDEF _SC_2_LOCALEDEF - * _POSIX2_PBS _SC_2_PBS - * _POSIX2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING - * _POSIX2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT - * _POSIX2_PBS_LOCATE _SC_2_PBS_LOCATE - * _POSIX2_PBS_MESSAGE _SC_2_PBS_MESSAGE - * _POSIX2_PBS_TRACK _SC_2_PBS_TRACK - * _POSIX2_SW_DEV _SC_2_SW_DEV - * _POSIX2_UPE _SC_2_UPE - * _POSIX2_VERSION _SC_2_VERSION - * {PAGE_SIZE} _SC_PAGE_SIZE - * {PAGESIZE} _SC_PAGESIZE - * {PTHREAD_DESTRUCTOR_ITERATIONS} _SC_THREAD_DESTRUCTOR_ITERATIONS - * {PTHREAD_KEYS_MAX} _SC_THREAD_KEYS_MAX - * {PTHREAD_STACK_MIN} _SC_THREAD_STACK_MIN - * {PTHREAD_THREADS_MAX} _SC_THREAD_THREADS_MAX - * {RE_DUP_MAX} _SC_RE_DUP_MAX - * {RTSIG_MAX} _SC_RTSIG_MAX - * {SEM_NSEMS_MAX} _SC_SEM_NSEMS_MAX - * {SEM_VALUE_MAX} _SC_SEM_VALUE_MAX - * {SIGQUEUE_MAX} _SC_SIGQUEUE_MAX - * {STREAM_MAX} _SC_STREAM_MAX - * {SYMLOOP_MAX} _SC_SYMLOOP_MAX - * {TIMER_MAX} _SC_TIMER_MAX - * {TTY_NAME_MAX} _SC_TTY_NAME_MAX - * {TZNAME_MAX} _SC_TZNAME_MAX - * _XBS5_ILP32_OFF32 (LEGACY) _SC_XBS5_ILP32_OFF32 (LEGACY) - * _XBS5_ILP32_OFFBIG (LEGACY) _SC_XBS5_ILP32_OFFBIG (LEGACY) - * _XBS5_LP64_OFF64 (LEGACY) _SC_XBS5_LP64_OFF64 (LEGACY) - * _XBS5_LPBIG_OFFBIG (LEGACY) _SC_XBS5_LPBIG_OFFBIG (LEGACY) - * _XOPEN_CRYPT _SC_XOPEN_CRYPT - * _XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N - * _XOPEN_LEGACY _SC_XOPEN_LEGACY - * _XOPEN_REALTIME _SC_XOPEN_REALTIME - * _XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS - * _XOPEN_SHM _SC_XOPEN_SHM - * _XOPEN_STREAMS _SC_XOPEN_STREAMS - * _XOPEN_UNIX _SC_XOPEN_UNIX - * _XOPEN_VERSION _SC_XOPEN_VERSION + * {MQ_OPEN_MAX} _SC_MQ_OPEN_MAX + * {MQ_PRIO_MAX} _SC_MQ_PRIO_MAX + * {OPEN_MAX} _SC_OPEN_MAX + * _POSIX_ADVISORY_INFO _SC_ADVISORY_INFO + * _POSIX_BARRIERS _SC_BARRIERS + * _POSIX_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO + * _POSIX_CLOCK_SELECTION _SC_CLOCK_SELECTION + * _POSIX_CPUTIME _SC_CPUTIME + * _POSIX_FSYNC _SC_FSYNC + * _POSIX_IPV6 _SC_IPV6 + * _POSIX_JOB_CONTROL _SC_JOB_CONTROL + * _POSIX_MAPPED_FILES _SC_MAPPED_FILES + * _POSIX_MEMLOCK _SC_MEMLOCK + * _POSIX_MEMLOCK_RANGE _SC_MEMLOCK_RANGE + * _POSIX_MEMORY_PROTECTION _SC_MEMORY_PROTECTION + * _POSIX_MESSAGE_PASSING _SC_MESSAGE_PASSING + * _POSIX_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK + * _POSIX_PRIORITIZED_IO _SC_PRIORITIZED_IO + * _POSIX_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING + * _POSIX_RAW_SOCKETS _SC_RAW_SOCKETS + * _POSIX_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS + * _POSIX_REALTIME_SIGNALS _SC_REALTIME_SIGNALS + * _POSIX_REGEXP _SC_REGEXP + * _POSIX_SAVED_IDS _SC_SAVED_IDS + * _POSIX_SEMAPHORES _SC_SEMAPHORES + * _POSIX_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS + * _POSIX_SHELL _SC_SHELL + * _POSIX_SPAWN _SC_SPAWN + * _POSIX_SPIN_LOCKS _SC_SPIN_LOCKS + * _POSIX_SPORADIC_SERVER _SC_SPORADIC_SERVER + * _POSIX_SS_REPL_MAX _SC_SS_REPL_MAX + * _POSIX_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO + * _POSIX_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR + * _POSIX_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE + * _POSIX_THREAD_CPUTIME _SC_THREAD_CPUTIME + * _POSIX_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT + * _POSIX_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT + * _POSIX_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING + * _POSIX_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED + * _POSIX_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS + * _POSIX_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER + * _POSIX_THREADS _SC_THREADS + * _POSIX_TIMEOUTS _SC_TIMEOUTS + * _POSIX_TIMERS _SC_TIMERS + * _POSIX_TRACE _SC_TRACE + * _POSIX_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER + * _POSIX_TRACE_EVENT_NAME_MAX _SC_TRACE_EVENT_NAME_MAX + * _POSIX_TRACE_INHERIT _SC_TRACE_INHERIT + * _POSIX_TRACE_LOG _SC_TRACE_LOG + * _POSIX_TRACE_NAME_MAX _SC_TRACE_NAME_MAX + * _POSIX_TRACE_SYS_MAX _SC_TRACE_SYS_MAX + * _POSIX_TRACE_USER_EVENT_MAX _SC_TRACE_USER_EVENT_MAX + * _POSIX_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS + * _POSIX_VERSION _SC_VERSION + * _POSIX_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32 + * _POSIX_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG + * _POSIX_V6_LP64_OFF64 _SC_V6_LP64_OFF64 + * _POSIX_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG + * _POSIX2_C_BIND _SC_2_C_BIND + * _POSIX2_C_DEV _SC_2_C_DEV + * _POSIX2_CHAR_TERM _SC_2_CHAR_TERM + * _POSIX2_FORT_DEV _SC_2_FORT_DEV + * _POSIX2_FORT_RUN _SC_2_FORT_RUN + * _POSIX2_LOCALEDEF _SC_2_LOCALEDEF + * _POSIX2_PBS _SC_2_PBS + * _POSIX2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING + * _POSIX2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT + * _POSIX2_PBS_LOCATE _SC_2_PBS_LOCATE + * _POSIX2_PBS_MESSAGE _SC_2_PBS_MESSAGE + * _POSIX2_PBS_TRACK _SC_2_PBS_TRACK + * _POSIX2_SW_DEV _SC_2_SW_DEV + * _POSIX2_UPE _SC_2_UPE + * _POSIX2_VERSION _SC_2_VERSION + * {PAGE_SIZE} _SC_PAGE_SIZE + * {PAGESIZE} _SC_PAGESIZE + * _POSIX_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS + * _POSIX_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX + * {PTHREAD_STACK_MIN} _SC_THREAD_STACK_MIN + * _POSIX_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX + * {RE_DUP_MAX} _SC_RE_DUP_MAX + * {RTSIG_MAX} _SC_RTSIG_MAX + * {SEM_NSEMS_MAX} _SC_SEM_NSEMS_MAX + * {SEM_VALUE_MAX} _SC_SEM_VALUE_MAX + * {SIGQUEUE_MAX} _SC_SIGQUEUE_MAX + * {STREAM_MAX} _SC_STREAM_MAX + * {SYMLOOP_MAX} _SC_SYMLOOP_MAX + * {TIMER_MAX} _SC_TIMER_MAX + * {TTY_NAME_MAX} _SC_TTY_NAME_MAX + * {TZNAME_MAX} _SC_TZNAME_MAX + * _XBS5_ILP32_OFF32 (LEGACY) _SC_XBS5_ILP32_OFF32 (LEGACY) + * _XBS5_ILP32_OFFBIG (LEGACY) _SC_XBS5_ILP32_OFFBIG (LEGACY) + * _XBS5_LP64_OFF64 (LEGACY) _SC_XBS5_LP64_OFF64 (LEGACY) + * _XBS5_LPBIG_OFFBIG (LEGACY) _SC_XBS5_LPBIG_OFFBIG (LEGACY) + * _XOPEN_CRYPT _SC_XOPEN_CRYPT + * _XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N + * _XOPEN_LEGACY _SC_XOPEN_LEGACY + * _XOPEN_REALTIME _SC_XOPEN_REALTIME + * _XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS + * _XOPEN_SHM _SC_XOPEN_SHM + * _XOPEN_STREAMS _SC_XOPEN_STREAMS + * _XOPEN_UNIX _SC_XOPEN_UNIX + * _XOPEN_VERSION _SC_XOPEN_VERSION * * Returned Value: * If name is an invalid value, sysconf() will return -1 and set errno to diff --git a/libs/libc/unistd/lib_ulimit.c b/libs/libc/unistd/lib_ulimit.c new file mode 100644 index 0000000000000..ddf56b4a4e986 --- /dev/null +++ b/libs/libc/unistd/lib_ulimit.c @@ -0,0 +1,76 @@ +/**************************************************************************** + * libs/libc/unistd/lib_ulimit.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ulimit + * + * Description: + * The ulimit will make calls to getrlimit() and setrlimit() to perform + * get and set resource limits respectively. + * + * Returned value: + * On success, return a non-negative value. + * On failure, return -1 and set the errno value. + * + ****************************************************************************/ + +long ulimit(int cmd, long newlimit) +{ + long ret = ERROR; + + switch (cmd) + { + case UL_GETFSIZE: + { + struct rlimit rlp; + getrlimit(RLIMIT_FSIZE, &rlp); + ret = rlp.rlim_cur / 512UL; + } + break; + case UL_SETFSIZE: + { + struct rlimit rlp; + rlp.rlim_max = RLIM_INFINITY; + rlp.rlim_cur = newlimit * 512UL; + ret = setrlimit(RLIMIT_FSIZE, &rlp); + } + break; + default: + set_errno(EINVAL); + break; + } + + return ret; +} diff --git a/libs/libc/wqueue/CMakeLists.txt b/libs/libc/wqueue/CMakeLists.txt index 520547b6f4f87..e89e6757ec811 100644 --- a/libs/libc/wqueue/CMakeLists.txt +++ b/libs/libc/wqueue/CMakeLists.txt @@ -20,6 +20,6 @@ # # ############################################################################## -if(CONFIG_LIB_USRWORK) +if(CONFIG_LIBC_USRWORK) target_sources(c PRIVATE work_usrthread.c work_queue.c work_cancel.c) endif() diff --git a/libs/libm/libm/lib_atanf.c b/libs/libm/libm/lib_atanf.c index 08547152c4658..65376153f7915 100644 --- a/libs/libm/libm/lib_atanf.c +++ b/libs/libm/libm/lib_atanf.c @@ -31,12 +31,15 @@ #include #include #include +#include /**************************************************************************** * Public Functions ****************************************************************************/ +#define ABS(a) ((a) > 0 ? (a) : -(a)) + float atanf(float x) { - return asinf(x / sqrtf(x * x + 1.0F)); + return asinf(x / MAX(ABS(x), sqrtf(x * x + 1.0F))); } diff --git a/libs/libxx/Kconfig b/libs/libxx/Kconfig index 2dc1cdefaf1e8..80b9ca0f94e8f 100644 --- a/libs/libxx/Kconfig +++ b/libs/libxx/Kconfig @@ -29,7 +29,6 @@ choice config LIBCXXTOOLCHAIN bool "Toolchain C++ support" select HAVE_CXXINITIALIZE - select LIBC_LOCALE ---help--- Use Standard C++ library from toolchain. @@ -75,6 +74,7 @@ choice config LIBCXXABI bool "LLVM low level C++ Library" + select SCHED_THREAD_LOCAL ---help--- LLVM "libc++abi" C++ Standard Library https://libcxxabi.llvm.org/ @@ -100,10 +100,11 @@ config LIBCXXABI_VERSION string "Select libcxxabi version" depends on LIBCXXABI default LIBCXX_VERSION if LIBCXX - default "21.1.8" if !LIBCXX + default "19.1.7" if !LIBCXX config CXX_STANDARD string "Language standard" + default "c++14" if TRICORE_TOOLCHAIN_TASKING default "gnu++23" if LIBCXX default "gnu++17" if !LIBCXX ---help--- @@ -119,10 +120,22 @@ config CXX_RTTI config CXX_WCHAR bool "Enable Wide Character Support" +choice + prompt "C++ Locale and Stream select" + default CXX_NO_LOCALIZATION + +config CXX_NO_LOCALIZATION + bool "No Locale and Stream Support" + +config CXX_MINI_LOCALIZATION + bool "Enable mini Locale and Stream Support" + config CXX_LOCALIZATION bool "Enable Locale and Stream Support" depends on LIBC_LOCALE +endchoice + if UCLIBCXX config UCLIBCXX_BUFSIZE @@ -134,6 +147,11 @@ endif config LIBCXX_VERSION string "Select libcxx version" depends on LIBCXX - default "21.1.8" + default "19.1.7" + +config LIBCXX_TEST + bool "LLVM Libcxx Library Test" + depends on LIBCXX && CXX_EXCEPTION + default n endif diff --git a/libs/libxx/__assertion_handler b/libs/libxx/__assertion_handler new file mode 100644 index 0000000000000..41969decc8447 --- /dev/null +++ b/libs/libxx/__assertion_handler @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ASSERTION_HANDLER +#define _LIBCPP___ASSERTION_HANDLER + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#define _LIBCPP_ASSERTION_HANDLER(message) ((void)(message), __builtin_trap()) + +#endif // _LIBCPP___ASSERTION_HANDLER diff --git a/libs/libxx/__config_site b/libs/libxx/__config_site index e5fde40902cb8..3be0c26adf10a 100644 --- a/libs/libxx/__config_site +++ b/libs/libxx/__config_site @@ -16,51 +16,45 @@ /* #undef _LIBCPP_ABI_FORCE_ITANIUM */ /* #undef _LIBCPP_ABI_FORCE_MICROSOFT */ /* #undef _LIBCPP_HAS_NO_THREADS */ -#define _LIBCPP_HAS_THREADS 1 -#define _LIBCPP_HAS_THREAD_API_PTHREAD 1 /* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */ -#define _LIBCPP_HAS_MONOTONIC_CLOCK 1 -#define _LIBCPP_HAS_TIME_ZONE_DATABASE 0 /* #undef _LIBCPP_HAS_MUSL_LIBC */ +#define _LIBCPP_HAS_THREAD_API_PTHREAD 1 /* #undef _LIBCPP_HAS_THREAD_API_EXTERNAL */ /* #undef _LIBCPP_HAS_THREAD_API_WIN32 */ -/* #undef _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS */ +#define _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS 1 #define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS /* #undef _LIBCPP_NO_VCRUNTIME */ /* #undef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION */ /* #undef _LIBCPP_HAS_NO_FILESYSTEM */ -#define _LIBCPP_HAS_FILESYSTEM 1 /* #undef _LIBCPP_HAS_NO_RANDOM_DEVICE */ -#define _LIBCPP_HAS_RANDOM_DEVICE 0 -#ifdef CONFIG_CXX_LOCALIZATION -#define _LIBCPP_HAS_LOCALIZATION 1 -#else +#if defined(CONFIG_CXX_NO_LOCALIZATION) #define _LIBCPP_HAS_NO_LOCALIZATION -#define _LIBCPP_HAS_LOCALIZATION 0 +#elif defined(CONFIG_CXX_MINI_LOCALIZATION) +#define _LIBCPP_HAS_MINI_LOCALIZATION #endif -#ifdef CONFIG_CXX_WCHAR -#define _LIBCPP_HAS_WIDE_CHARACTERS 1 -#else +#ifndef CONFIG_CXX_WCHAR #define _LIBCPP_HAS_NO_WIDE_CHARACTERS -#define _LIBCPP_HAS_WIDE_CHARACTERS 0 #endif #define _LIBCPP_ENABLE_ASSERTIONS_DEFAULT 0 -// Define assertion macros for libcxx 21.x -#define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(...) ((void)0) - // PSTL backends #define _LIBCPP_PSTL_BACKEND_SERIAL -/* #undef _LIBCPP_PSTL_BACKEND_STD_THREAD */ -/* #undef _LIBCPP_PSTL_BACKEND_LIBDISPATCH */ +#define _LIBCPP_PSTL_CPU_BACKEND_SERIAL +/* #undef _LIBCPP_PSTL_CPU_BACKEND_THREAD */ +/* #undef _LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH */ + +// Force each translation unit to emit the necessary basic_string +// specializations (avoids missing wide-character dtor symbols). +#define _LIBCPP_DISABLE_EXTERN_TEMPLATE 1 + +// Type traits tuning. +#define _LIBCPP_DISABLE_DECAY_BUILTIN 1 // Hardening. -#ifndef NDEBUG -#define _LIBCPP_HARDENING_MODE_DEFAULT _LIBCPP_HARDENING_MODE_EXTENSIVE -#else +#define _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT 0 +#define _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT 0 #define _LIBCPP_HARDENING_MODE_DEFAULT _LIBCPP_HARDENING_MODE_FAST -#endif -#define _LIBCPP_ENABLE_ASSERTIONS_DEFAULT 0 +#define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT #define _LIBCPP_DISABLE_DEPRECATION_WARNINGS 1 #define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT 1 diff --git a/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC__.patch b/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC__.patch index 95d6ee09dff05..1fda8077e4579 100644 --- a/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC__.patch +++ b/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC__.patch @@ -1,17 +1,13 @@ -diff --git libcxx/src/locale.cpp libcxx/src/locale.cpp --- libcxx/src/locale.cpp +++ libcxx/src/locale.cpp -@@ -41,6 +41,10 @@ +@@ -40,6 +40,10 @@ + #include "include/atomic_support.h" #include "include/sso_allocator.h" - +#if defined(__NuttX__) && defined(__GLIBC__) -+# undef __GLIBC__ ++# undef __GLIBC__ +#endif + + // On Linux, wint_t and wchar_t have different signed-ness, and this causes // lots of noise in the build log, but no bugs that I know of. - _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion") --- -2.34.1 - diff --git a/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch b/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch deleted file mode 100644 index c9d61883643a7..0000000000000 --- a/libs/libxx/libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/src/locale.cpp -+++ b/src/locale.cpp -@@ -37,6 +37,10 @@ - #include "include/atomic_support.h" - #include "include/sso_allocator.h" - -+#if defined(__NuttX__) && defined(__GLIBC__) -+# undef __GLIBC__ -+#endif -+ - // On Linux, wint_t and wchar_t have different signed-ness, and this causes - // lots of noise in the build log, but no bugs that I know of. - _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion") diff --git a/libs/libxx/libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch b/libs/libxx/libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch deleted file mode 100644 index b2f777338f699..0000000000000 --- a/libs/libxx/libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- libcxx/src/exception.cpp.orig 2025-01-10 00:00:00.000000000 +0000 -+++ libcxx/src/exception.cpp 2025-01-10 00:00:00.000000000 +0000 -@@ -22,6 +22,9 @@ - #if defined(_LIBCPP_ABI_MICROSOFT) - # include "support/runtime/exception_msvc.ipp" - # include "support/runtime/exception_pointer_msvc.ipp" -+#elif defined(LIBCXX_BUILDING_LIBCXXABI) && defined(_LIBCPP_HAS_NO_EXCEPTIONS) -+# include "include/atomic_support.h" -+# include "support/runtime/exception_pointer_unimplemented.ipp" - #elif defined(_LIBCPPABI_VERSION) - # include "support/runtime/exception_libcxxabi.ipp" - # include "support/runtime/exception_pointer_cxxabi.ipp" diff --git a/libs/libxx/libcxx/0001-libcxx-fix-ld-errors.patch b/libs/libxx/libcxx/0001-libcxx-fix-ld-errors.patch index 8bfbe4528c264..5b4d09082b08d 100644 --- a/libs/libxx/libcxx/0001-libcxx-fix-ld-errors.patch +++ b/libs/libxx/libcxx/0001-libcxx-fix-ld-errors.patch @@ -1,28 +1,27 @@ -diff --git libcxx/include/ostream libcxx/include/ostream ---- libcxx/include/ostream -+++ libcxx/include/ostream -@@ -320,7 +320,10 @@ template - basic_ostream<_CharT, _Traits>::sentry::~sentry() - { - if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) -- && !uncaught_exception()) +--- libcxx/include/__ostream/basic_ostream.h ++++ libcxx/include/__ostream/basic_ostream.h +@@ -152,7 +152,11 @@ + + template + basic_ostream<_CharT, _Traits>::sentry::~sentry() { +- if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && !uncaught_exception()) { ++ if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) +#ifndef _LIBCPP_HAS_NO_EXCEPTIONS -+ && !uncaught_exception() ++ && !uncaught_exception() +#endif -+ ) - { ++ ) { #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try -diff --git libcxx/src/exception.cpp libcxx/src/exception.cpp + try { + #endif // _LIBCPP_HAS_NO_EXCEPTIONS --- libcxx/src/exception.cpp +++ libcxx/src/exception.cpp @@ -19,6 +19,9 @@ #if defined(_LIBCPP_ABI_MICROSOFT) - #include "support/runtime/exception_msvc.ipp" - #include "support/runtime/exception_pointer_msvc.ipp" + # include "support/runtime/exception_msvc.ipp" + # include "support/runtime/exception_pointer_msvc.ipp" +#elif defined(_LIBCPPABI_VERSION) && defined(_LIBCPP_HAS_NO_EXCEPTIONS) -+#include "include/atomic_support.h" -+#include "support/runtime/exception_pointer_unimplemented.ipp" ++# include "include/atomic_support.h" ++# include "support/runtime/exception_pointer_unimplemented.ipp" #elif defined(_LIBCPPABI_VERSION) - #include "support/runtime/exception_libcxxabi.ipp" - #include "support/runtime/exception_pointer_cxxabi.ipp" + # include "support/runtime/exception_libcxxabi.ipp" + # include "support/runtime/exception_pointer_cxxabi.ipp" diff --git a/libs/libxx/libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch b/libs/libxx/libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch deleted file mode 100644 index b7a9ce5362dd2..0000000000000 --- a/libs/libxx/libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/include/__ostream/basic_ostream.h -+++ b/include/__ostream/basic_ostream.h -@@ -207,7 +207,12 @@ - - template - basic_ostream<_CharT, _Traits>::sentry::~sentry() { -- if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) && uncaught_exceptions() == 0) { -+ if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) -+# if _LIBCPP_HAS_EXCEPTIONS -+ && uncaught_exceptions() == 0 -+# endif -+ ) { -+ - # if _LIBCPP_HAS_EXCEPTIONS - try { - # endif // _LIBCPP_HAS_EXCEPTIONS diff --git a/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h.patch b/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h.patch index 7019bc6d563be..30e4d101361b7 100644 --- a/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h.patch +++ b/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h.patch @@ -1,11 +1,11 @@ --- libcxx/src/chrono.cpp +++ libcxx/src/chrono.cpp -@@ -48,10 +48,6 @@ +@@ -50,10 +50,6 @@ # include #endif - + -#if __has_include() --# include +-# include -#endif - #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) diff --git a/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch b/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch deleted file mode 100644 index e65e530c3d011..0000000000000 --- a/libs/libxx/libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/src/chrono.cpp -+++ b/src/chrono.cpp -@@ -54,10 +54,6 @@ - # include - #endif - --#if __has_include() --# include --#endif -- - #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) - # pragma comment(lib, "rt") - #endif diff --git a/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef.patch b/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef.patch index 56ae62c402361..9b3d56f113489 100644 --- a/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef.patch +++ b/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef.patch @@ -1,11 +1,11 @@ ---- libcxx/include/stdatomic.h.old 2023-12-06 21:01:46.168049453 +0800 -+++ libcxx/include/stdatomic.h 2023-12-06 21:01:55.056057032 +0800 +--- libcxx/include/stdatomic.h ++++ libcxx/include/stdatomic.h @@ -220,7 +220,7 @@ using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS; using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS; - + -#elif defined(_LIBCPP_COMPILER_CLANG_BASED) +#else - + // Before C++23, we include the next on the path to avoid hijacking // the header. We do this because Clang has historically shipped a diff --git a/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch b/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch deleted file mode 100644 index ca17ef6e6c087..0000000000000 --- a/libs/libxx/libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/include/stdatomic.h -+++ b/include/stdatomic.h -@@ -231,7 +231,7 @@ - using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS; - using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS; - --# elif defined(_LIBCPP_COMPILER_CLANG_BASED) -+# else - - // Before C++23, we include the next on the path to avoid hijacking - // the header. We do this because Clang has historically shipped a diff --git a/libs/libxx/libcxx/0002-libcxx-decay-and-tzdb-fixes.patch b/libs/libxx/libcxx/0002-libcxx-decay-and-tzdb-fixes.patch new file mode 100644 index 0000000000000..90f5a293fc36d --- /dev/null +++ b/libs/libxx/libcxx/0002-libcxx-decay-and-tzdb-fixes.patch @@ -0,0 +1,49 @@ +--- libcxx/include/__type_traits/decay.h ++++ libcxx/include/__type_traits/decay.h +@@ -25,7 +25,7 @@ + + _LIBCPP_BEGIN_NAMESPACE_STD + +-#if __has_builtin(__decay) ++#if __has_builtin(__decay) && !defined(_LIBCPP_DISABLE_DECAY_BUILTIN) + template + using __decay_t _LIBCPP_NODEBUG = __decay(_Tp); + +--- libcxx/src/experimental/tzdb.cpp ++++ libcxx/src/experimental/tzdb.cpp +@@ -50,6 +50,8 @@ + _LIBCPP_WEAK string_view __libcpp_tzdb_directory() { + #if defined(__linux__) + return "/usr/share/zoneinfo/"; ++#elif defined(CONFIG_LIBC_TZDIR) ++ return CONFIG_LIBC_TZDIR "/"; + #else +-# error "unknown path to the IANA Time Zone Database" ++ return string_view{}; + #endif + +--- libcxx/src/include/overridable_function.h ++++ libcxx/src/include/overridable_function.h +@@ -96,7 +96,7 @@ + } + _LIBCPP_END_NAMESPACE_STD + +-#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) ++#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) && !defined(CONFIG_ESPRESSIF_CHIP_SERIES) + + # define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1 + # define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE __attribute__((__section__("__lcxx_override"))) +@@ -121,6 +121,13 @@ + + #else + ++# ifdef CONFIG_ESPRESSIF_CHIP_SERIES ++// esptool requires every loadable segment to be 4-byte aligned, but the ++// __lcxx_override section can end up with compressed instructions that don't ++// satisfy that constraint on Espressif parts. Skip the detection machinery on ++// those targets and fall back to the generic implementation. ++# endif ++ + # define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 0 + # define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE /* nothing */ + diff --git a/libs/libxx/libcxx/0007-libcxx-fix-locale-instantiations_21.1.8.patch b/libs/libxx/libcxx/0007-libcxx-fix-locale-instantiations_21.1.8.patch deleted file mode 100644 index 3002bb169b2e8..0000000000000 --- a/libs/libxx/libcxx/0007-libcxx-fix-locale-instantiations_21.1.8.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- libcxx/src/locale.cpp.orig -+++ libcxx/src/locale.cpp -@@ -5605,6 +5605,7 @@ - - // explicit instantiation - -+#ifndef _LIBCPP_HAS_NO_LOCALIZATION - template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; - template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate_byname; - template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; -@@ -5645,6 +5646,7 @@ - template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate_byname; - template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; - #endif -+#endif // _LIBCPP_HAS_NO_LOCALIZATION - - // FIXME: These explicit instantiations seem wrong since it depends on localization support which can be disabled - _LIBCPP_SUPPRESS_DEPRECATED_PUSH diff --git a/libs/libxx/libcxx/0008-libcxx-remove-invalid-locale-instantiations_21.1.8.patch b/libs/libxx/libcxx/0008-libcxx-remove-invalid-locale-instantiations_21.1.8.patch deleted file mode 100644 index c32a33d312a6e..0000000000000 --- a/libs/libxx/libcxx/0008-libcxx-remove-invalid-locale-instantiations_21.1.8.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- a/src/locale.cpp -+++ b/src/locale.cpp -@@ -5607,42 +5607,6 @@ - return __mb_cur_max_l((locale_t)__l); - } - --// explicit instantiation -- --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; --# if _LIBCPP_HAS_WIDE_CHARACTERS --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS -- codecvt_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS -- codecvt_byname; --# endif --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; -- --# if _LIBCPP_HAS_WIDE_CHARACTERS --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname; --template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; --# endif -- - // FIXME: These explicit instantiations seem wrong since it depends on localization support which can be disabled - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname; diff --git a/libs/libxx/libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch b/libs/libxx/libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch deleted file mode 100644 index 325e8a690e272..0000000000000 --- a/libs/libxx/libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/src/string.cpp 2026-01-10 09:53:40.035509375 +0100 -+++ b/src/string.cpp 2026-01-10 09:53:40.045300744 +0100 -@@ -382,4 +382,13 @@ - wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string()(), L"%Lf", val); } - #endif - -+// Explicit template instantiations for embedded systems -+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string; -+#if _LIBCPP_HAS_WIDE_CHARACTERS -+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string; -+#endif -+#ifndef _LIBCPP_HAS_NO_CHAR8_T -+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string; -+#endif -+ - _LIBCPP_END_NAMESPACE_STD diff --git a/libs/libxx/libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch b/libs/libxx/libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch deleted file mode 100644 index 28f47e580a2d8..0000000000000 --- a/libs/libxx/libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/src/locale.cpp -+++ b/src/locale.cpp -@@ -589,8 +589,22 @@ - constinit int32_t locale::id::__next_id = 0; - - long locale::id::__get() { -+#ifdef _LIBCPP_HAS_NO_THREADS -+ // Interrupt-safe ID assignment: Read current ID first to minimize race window -+ // Even if interrupted between read and write, atomic_add ensures unique IDs -+ int32_t current = __id_; -+ if (current == 0) { -+ // Generate unique ID atomically - each call gets different value -+ int32_t new_id = __libcpp_atomic_add(&__next_id, 1) + 1; -+ // Write back - safe because atomic_add guarantees uniqueness -+ __id_ = new_id; -+ current = new_id; -+ } -+ return current - 1; -+#else - call_once(__flag_, [&] { __id_ = __libcpp_atomic_add(&__next_id, 1); }); - return __id_ - 1; -+#endif - } - - // template <> class collate_byname diff --git a/libs/libxx/libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch b/libs/libxx/libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch deleted file mode 100644 index e50761c611df6..0000000000000 --- a/libs/libxx/libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/src/exception.cpp -+++ b/src/exception.cpp -@@ -7,7 +7,6 @@ - //===----------------------------------------------------------------------===// - - #define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION --#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS - - #include - #include diff --git a/libs/libxx/libcxx/CMakeLists.txt b/libs/libxx/libcxx/CMakeLists.txt index 78b9374f57b33..cc43f9ffb65de 100644 --- a/libs/libxx/libcxx/CMakeLists.txt +++ b/libs/libxx/libcxx/CMakeLists.txt @@ -25,41 +25,6 @@ if(CONFIG_LIBCXX) set(LIBCXX_VERSION ${CONFIG_LIBCXX_VERSION}) - # Build patch command conditionally - set(LIBCXX_PATCH_COMMAND - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/mbstate_t_21.1.8.patch && patch -p1 -d - ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-remove-mach-time-h_21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-exception-no-rtti_21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC___21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch - ) - - # Add architecture-specific patch for ARM, ARM64, and RISC-V - if(CONFIG_ARCH_ARM - OR CONFIG_ARCH_ARM64 - OR CONFIG_ARCH_RISCV) - set(LIBCXX_PATCH_COMMAND - ${LIBCXX_PATCH_COMMAND} && patch -p1 -d - ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0009-libcxx-add-string-template-instantiations_21.1.8.patch - ) - endif() - - set(LIBCXX_PATCH_COMMAND - ${LIBCXX_PATCH_COMMAND} && patch -p1 -d - ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < - ${CMAKE_CURRENT_LIST_DIR}/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch - ) - FetchContent_Declare( libcxx DOWNLOAD_NAME "libcxx-${LIBCXX_VERSION}.src.tar.xz" @@ -77,7 +42,19 @@ if(CONFIG_LIBCXX) "" TEST_COMMAND "" - PATCH_COMMAND ${LIBCXX_PATCH_COMMAND} + PATCH_COMMAND + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001_fix_stdatomic_h_miss_typedef.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-remove-mach-time-h.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxx-fix-ld-errors.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0001-Fix-build-error-about-__GLIBC__.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/0002-libcxx-decay-and-tzdb-fixes.patch && + patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxx < + ${CMAKE_CURRENT_LIST_DIR}/mbstate_t.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -89,25 +66,24 @@ if(CONFIG_LIBCXX) endif() + configure_file(${CMAKE_CURRENT_LIST_DIR}/../__assertion_handler + ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__assertion_handler + COPYONLY) + nuttx_create_symlink(${CMAKE_CURRENT_LIST_DIR}/libcxx/include ${CMAKE_BINARY_DIR}/include/libcxx) - # Copy config files to the libcxx source include directory before symlinking - # Remove existing files first to allow reconfiguration - file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__config_site) - configure_file( - ${CMAKE_CURRENT_LIST_DIR}/../__config_site - ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__config_site COPYONLY) - - file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__assertion_handler) - configure_file( - ${CMAKE_CURRENT_LIST_DIR}/__assertion_handler - ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__assertion_handler COPYONLY) + nuttx_create_symlink(${CMAKE_CURRENT_LIST_DIR}/../__config_site + ${CMAKE_BINARY_DIR}/include/libcxx_config/__config_site) set_property( TARGET nuttx APPEND - PROPERTY NUTTX_CXX_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/include/libcxx) + PROPERTY NUTTX_CXX_INCLUDE_DIRECTORIES + ${CMAKE_BINARY_DIR}/include/libcxx + ${CMAKE_BINARY_DIR}/include/libcxx_config + ${CMAKE_CURRENT_LIST_DIR}/libcxx/test/support + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src) add_compile_definitions(_LIBCPP_BUILDING_LIBRARY) if(CONFIG_LIBSUPCXX_TOOLCHAIN) @@ -123,47 +99,54 @@ if(CONFIG_LIBCXX) endif() file(GLOB SRCS ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/*.cpp) - file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/*.cpp) - list(APPEND SRCS ${SRCSTMP}) - file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/filesystem/*.cpp) - list(APPEND SRCS ${SRCSTMP}) - file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ryu/*.cpp) - list(APPEND SRCS ${SRCSTMP}) - - # Always exclude C++20 barrier (has additional dependencies not available in - # NuttX) - file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/barrier.cpp) - list(REMOVE_ITEM SRCS ${SRCSTMP}) - - # Exclude files with embedded-incompatible dependencies - file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/charconv.cpp) - list(REMOVE_ITEM SRCS ${SRCSTMP}) - - if(NOT CONFIG_CXX_LOCALIZATION) + list(APPEND SRCS ${CMAKE_CURRENT_LIST_DIR}/nuttx_string_instantiations.cpp) + + string(REGEX MATCH "[0-9]+$" CPP_STD_VER "${CONFIG_CXX_STANDARD}") + if(${CPP_STD_VER} GREATER_EQUAL 20) + file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/*.cpp) + list(APPEND SRCS ${SRCSTMP}) + file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/filesystem/*.cpp) + list(APPEND SRCS ${SRCSTMP}) + file(GLOB SRCSTMP ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ryu/*.cpp) + list(APPEND SRCS ${SRCSTMP}) + endif() + + if(${CPP_STD_VER} LESS_EQUAL 14) file( GLOB SRCSTMP + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/any.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/variant.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/optional.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/memory_resource.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/pstl/*.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/legacy_debug_handler.cpp) + list(REMOVE_ITEM SRCS ${SRCSTMP}) + endif() + + if(CONFIG_CXX_NO_LOCALIZATION) + file( + GLOB + SRCSTMP + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/fstream.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ios.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ios.instantiations.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/iostream.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/locale.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/ostream.cpp ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/regex.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/strstream.cpp) + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/strstream.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/chrono_exception.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/time_zone.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/tzdb.cpp + ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/tzdb_list.cpp) list(REMOVE_ITEM SRCS ${SRCSTMP}) endif() - # Exclude files with embedded-incompatible dependencies - file( - GLOB - SRCSTMP - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/atomic.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/charconv.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/random.cpp - ${CMAKE_CURRENT_LIST_DIR}/libcxx/src/experimental/*.cpp) - list(REMOVE_ITEM SRCS ${SRCSTMP}) - - set(FLAGS -Wno-attributes -Wno-deprecated-declarations -Wno-shadow - -Wno-sign-compare -Wno-cpp) + if(NOT CONFIG_TRICORE_TOOLCHAIN_TASKING) + set(FLAGS -Wno-attributes -Wno-deprecated-declarations -Wno-shadow + -Wno-sign-compare -Wno-cpp) + endif() if(GCCVER GREATER_EQUAL 12) list(APPEND FLAGS -Wno-maybe-uninitialized -Wno-alloc-size-larger-than) @@ -174,4 +157,190 @@ if(CONFIG_LIBCXX) target_compile_options(libcxx PRIVATE ${FLAGS}) target_include_directories(libcxx BEFORE PRIVATE ${CMAKE_CURRENT_LIST_DIR}/libcxx/src) + + if(CONFIG_LIBCXX_TEST) + list( + APPEND + FLAGS + -Wno-array-bounds + -Wno-permissive + -Wno-unused-variable + -Wno-unused-but-set-variable + -Wno-psabi + -Wno-unused-local-typedefs + -Wno-unused-result + -Wno-unused-function + -Wno-undef + -Wno-return-type + -Wno-self-move + -Wno-class-memaccess + -Wno-tautological-compare + -Wno-narrowing + -Wno-use-after-free + -Wno-invalid-memory-model + -Wno-mismatched-new-delete) + add_compile_options(-UNDEBUG) + add_compile_definitions( + DISABLE_NEW_COUNT + _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE + _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS + _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR + _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS + _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS + _LIBCPP_DISABLE_DEPRECATION_WARNINGS) + + set(i 0) + set(TEST_DIR "${CMAKE_CURRENT_LIST_DIR}/libcxx/test") + file(GLOB_RECURSE TESTS "${TEST_DIR}/*.pass.cpp") + file( + GLOB + UNSUPPORTED_TESTS + # error: ‘_wremove’ was not declared in this scope + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/ifstream.members/open_wchar_pointer.pass.cpp + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/ofstream.members/open_wchar_pointer.pass.cpp + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/ofstream.cons/wchar_pointer.pass.cpp + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/fstream.members/open_wchar_pointer.pass.cpp + ${TEST_DIR}/libcxx/input.output/file.streams/fstreams/fstream.cons/wchar_pointer.pass.cpp + # error: ‘x’ in ‘struct Foo’ does not name a type + ${TEST_DIR}/libcxx/selftest/compile.pass.cpp/compile-error.compile.pass.cpp + ${TEST_DIR}/libcxx/selftest/pass.cpp/compile-error.pass.cpp + ${TEST_DIR}/libcxx/selftest/link.pass.cpp/compile-error.link.pass.cpp + # error: ‘__sanitizer_verify_contiguous_container’ was not declared in + # this scope + ${TEST_DIR}/libcxx/containers/sequences/vector/asan.pass.cpp + # error: attributes are not allowed on a function-definition + ${TEST_DIR}/libcxx/thread/thread.mutex/thread_safety_requires_capability.pass.cpp + # fatal error: Block.h: No such file or directory + ${TEST_DIR}/libcxx/utilities/function.objects/func.blocks.pass.cpp + # link error + ${TEST_DIR}/libcxx/selftest/compile.pass.cpp/link-error.compile.pass.cpp + ${TEST_DIR}/libcxx/selftest/link.pass.cpp/link-error.link.pass.cpp + ${TEST_DIR}/libcxx/selftest/pass.cpp/link-error.pass.cpp + # std::views::join + ${TEST_DIR}/std/ranges/range.adaptors/range.join.view/adaptor.pass.cpp + ${TEST_DIR}/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp + ${TEST_DIR}/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp + ${TEST_DIR}/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp + # no build __partition_chunks + ${TEST_DIR}/libcxx/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp + # REQUIRES: c++98 || c++03 || c++11 || c++14 + ${TEST_DIR}/std/containers/associative/multimap/multimap.value_compare/types.pass.cpp + ${TEST_DIR}/std/containers/associative/map/map.value_compare/types.pass.cpp + # std::result_of + ${TEST_DIR}/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp + ${TEST_DIR}/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.invoke/invoke.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.invoke/invoke_constexpr.pass.cpp + # WINT_MIN undef + ${TEST_DIR}/std/language.support/cstdint/cstdint.syn/cstdint.pass.cpp + ${TEST_DIR}/std/input.output/file.streams/c.files/cinttypes.pass.cpp + # static assertion failed + ${TEST_DIR}/std/language.support/support.runtime/cstdlib.pass.cpp + # error: static assertion failed: Types differ unexpectedly + ${TEST_DIR}/std/strings/c.strings/cstring.pass.cpp + ${TEST_DIR}/std/strings/c.strings/cwchar.pass.cpp + # error: ‘is_literal_type_v’ is not a member of ‘std’ + ${TEST_DIR}/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp + ${TEST_DIR}/libcxx/containers/sequences/vector/asan.pass.cpp + # error: static assertion failed + ${TEST_DIR}/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp + # unsport c++20 + ${TEST_DIR}/std/utilities/memory/default.allocator/allocator_types.void.compile.pass.cpp + ${TEST_DIR}/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp + ${TEST_DIR}/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/auto_ptr_Y.pass.cpp + ${TEST_DIR}/std/utilities/utility/pairs/pairs.pair/assign_pair_cxx03.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.require/binary_function.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.require/unary_function.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/refwrap/weak_result.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/refwrap/binder_typedefs.compile.pass.cpp + ${TEST_DIR}/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array11.pass.cpp + ${TEST_DIR}/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp + # arm build error + ${TEST_DIR}/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp + ${TEST_DIR}/std/utilities/format/format.formatter/format.formatter.spec/formatter.floating_point.pass.cpp + ${TEST_DIR}/std/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp + ) + + file( + GLOB_RECURSE + SKIP_TESTS + ${TEST_DIR}/libcxx/containers/views/mdspan/*.pass.cpp + ${TEST_DIR}/libcxx/input.output/iostream.format/print.fun/*.pass.cpp + ${TEST_DIR}/libcxx/ranges/range.factories/range.repeat.view/*.pass.cpp + ${TEST_DIR}/libcxx/utilities/expected/*.pass.cpp + # skip deprecated test + ${TEST_DIR}/libcxx/depr/*.pass.cpp + ${TEST_DIR}/std/depr/*.pass.cpp + ${TEST_DIR}/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/*.pass.cpp + # arm atomic undef + ${TEST_DIR}/std/atomics/atomics.types.operations/atomics.types.operations.req/*.pass.cpp + ${TEST_DIR}/std/atomics/atomics.types.operations/atomics.types.operations.wait/*.pass.cpp + ) + list(REMOVE_ITEM TESTS ${UNSUPPORTED_TESTS} ${SKIP_TESTS}) + foreach(TEST ${TESTS}) + if(EXISTS ${TEST}) + set(GREP_PATTERNS + "UNSUPPORTED: c++03, c++11, c++14, c++17, c++20" + "TEST_LIBCPP_ASSERT_FAILURE" + "static_assert(test" + "UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME" + "UNSUPPORTED: gcc" + "include " + "std::ranges::join_view" + "std::binary_function" + "std::unary_function" + "std::binary_negate" + "std::not1" + "std::not2" + "std::unary_negate" + "std::raw_storage_iterator" + "void operator delete" + "filesystem_test_helper.h" + "asan_testing.h") + + set(SKIP_TEST FALSE) + + foreach(PATTERN IN LISTS GREP_PATTERNS) + execute_process(COMMAND grep -q "${PATTERN}" ${TEST} + RESULT_VARIABLE grep_result) + + if(grep_result EQUAL 0) + set(SKIP_TEST TRUE) + break() + endif() + endforeach() + + if(SKIP_TEST) + continue() + endif() + + execute_process(COMMAND grep -q "int main" ${TEST} + RESULT_VARIABLE grep_result) + if(NOT grep_result EQUAL 0) + continue() + endif() + + get_filename_component(TEST_NAME ${TEST} NAME_WE) + foreach(CHARACTER "+" "-" "=" "[]") + string(REPLACE "${CHARACTER}" "_" TEST_NAME "${TEST_NAME}") + endforeach() + + nuttx_add_application( + NAME + ${TEST_NAME}_${i} + SRCS + ${TEST} + STACKSIZE + 102400 + COMPILE_FLAGS + ${FLAGS}) + set_source_files_properties( + ${TEST_DIR}/libcxx/containers/sequences/vector/exception_safety_exceptions_disabled.pass.cpp + PROPERTIES COMPILE_FLAGS -fno-exceptions) + math(EXPR i "${i}+1") + endif() + endforeach() + endif() + endif() diff --git a/libs/libxx/libcxx/Make.defs b/libs/libxx/libcxx/Make.defs index 0ef0bc38365b9..19fa8dae78f43 100644 --- a/libs/libxx/libcxx/Make.defs +++ b/libs/libxx/libcxx/Make.defs @@ -31,30 +31,19 @@ libcxx/libcxx: libcxx-$(LIBCXX_VERSION).src.tar.xz $(Q) tar -xf $< \ --exclude libcxx-$(LIBCXX_VERSION).src/test/std/pstl $(Q) mv libcxx-$(LIBCXX_VERSION).src $@ - $(Q) patch -p1 < libcxx/0001_fix_stdatomic_h_miss_typedef_21.1.8.patch -d libcxx/libcxx - $(Q) patch -p1 < libcxx/mbstate_t_21.1.8.patch -d libcxx/libcxx - $(Q) patch -p1 < libcxx/0001-libcxx-remove-mach-time-h_21.1.8.patch -d libcxx/libcxx - $(Q) patch -p1 < libcxx/0001-libcxx-fix-exception-no-rtti_21.1.8.patch -d libcxx/libcxx - $(Q) patch -p1 < libcxx/0001-Fix-build-error-about-__GLIBC___21.1.8.patch -d libcxx/libcxx - $(Q) patch -p1 < libcxx/0001-libcxx-fix-ostream-no-exceptions_21.1.8.patch -d libcxx/libcxx -ifdef CONFIG_ARCH_ARM - $(Q) patch -p1 < libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch -d libcxx/libcxx -endif -ifdef CONFIG_ARCH_ARM64 - $(Q) patch -p1 < libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch -d libcxx/libcxx -endif -ifdef CONFIG_ARCH_RISCV - $(Q) patch -p1 < libcxx/0009-libcxx-add-string-template-instantiations_21.1.8.patch -d libcxx/libcxx -endif - $(Q) patch -p1 < libcxx/0010-libcxx-fix-locale-call-once-no-threads_21.1.8.patch -d libcxx/libcxx - $(Q) patch -p1 < libcxx/0011-libcxx-fix-deprecation-warnings-redefinition_21.1.8.patch -d libcxx/libcxx + $(Q) patch -p0 < libcxx/0001_fix_stdatomic_h_miss_typedef.patch -d libcxx + $(Q) patch -p0 < libcxx/0001-libcxx-remove-mach-time-h.patch -d libcxx + $(Q) patch -p0 < libcxx/0001-libcxx-fix-ld-errors.patch -d libcxx + $(Q) patch -p0 < libcxx/0001-Fix-build-error-about-__GLIBC__.patch -d libcxx + $(Q) patch -p0 < libcxx/0002-libcxx-decay-and-tzdb-fixes.patch -d libcxx + $(Q) patch -p0 < libcxx/mbstate_t.patch -d libcxx + $(Q) cp $(CURDIR)/__assertion_handler libcxx/libcxx/include/__assertion_handler endif $(TOPDIR)/include/libcxx: libcxx/libcxx $(Q) $(DIRLINK) $(CURDIR)/$= 12), 1) endif CPPSRCS += $(wildcard libcxx/libcxx/src/*.cpp) -CPPSRCS += $(wildcard libcxx/libcxx/src/filesystem/*.cpp) -CPPSRCS += $(wildcard libcxx/libcxx/src/ryu/*.cpp) - -# Always exclude C++20 barrier (has additional dependencies not available in NuttX) -CPPSRCS := $(filter-out libcxx/libcxx/src/barrier.cpp, $(CPPSRCS)) +CPPSRCS += libcxx/nuttx_string_instantiations.cpp +CPP_STD_VER := $(shell echo $(CONFIG_CXX_STANDARD) | sed -E 's/.*\+\+([0-9]+)$$/\1/') +ifeq ($(shell [ $(CPP_STD_VER) -ge 20 ] && echo true),true) + CPPSRCS += $(wildcard libcxx/libcxx/src/experimental/*.cpp) + CPPSRCS += $(wildcard libcxx/libcxx/src/filesystem/*.cpp) + CPPSRCS += $(wildcard libcxx/libcxx/src/ryu/*.cpp) +endif -# Exclude files with embedded-incompatible dependencies -INCOMPATIBLE_CPPSRCS := libcxx/libcxx/src/charconv.cpp -INCOMPATIBLE_CPPSRCS += libcxx/libcxx/src/random.cpp -CPPSRCS := $(filter-out $(INCOMPATIBLE_CPPSRCS), $(CPPSRCS)) +ifeq ($(shell [ $(CPP_STD_VER) -le 14 ] && echo true),true) + EXCLUDE_CPP := libcxx/libcxx/src/any.cpp + EXCLUDE_CPP += libcxx/libcxx/src/variant.cpp + EXCLUDE_CPP += libcxx/libcxx/src/optional.cpp + EXCLUDE_CPP += libcxx/libcxx/src/memory_resource.cpp + EXCLUDE_CPP += libcxx/libcxx/src/legacy_debug_handler.cpp + EXCLUDE_CPP += $(wildcard libcxx/libcxx/src/pstl/*.cpp) + CPPSRCS := $(filter-out $(EXCLUDE_FILES), $(CPPSRCS)) +endif -ifeq ($(CONFIG_CXX_LOCALIZATION),) +ifeq ($(CONFIG_CXX_NO_LOCALIZATION),y) LOCALE_CPPSRCS := libcxx/libcxx/src/ios.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/ios.instantiations.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/iostream.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/locale.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/regex.cpp LOCALE_CPPSRCS += libcxx/libcxx/src/strstream.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/fstream.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/ostream.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/experimental/chrono_exception.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/experimental/time_zone.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/experimental/tzdb.cpp + LOCALE_CPPSRCS += libcxx/libcxx/src/experimental/tzdb_list.cpp CPPSRCS := $(filter-out $(LOCALE_CPPSRCS), $(CPPSRCS)) endif diff --git a/libs/libxx/libcxx/__assertion_handler b/libs/libxx/libcxx/__assertion_handler deleted file mode 100644 index 147c71318d690..0000000000000 --- a/libs/libxx/libcxx/__assertion_handler +++ /dev/null @@ -1,30 +0,0 @@ -// __assertion_handler for libcxx 21.x -// This file provides the assertion handler for libcxx when -// _LIBCPP_ENABLE_ASSERTIONS is enabled. - -#ifndef _LIBCPP_ASSERTION_HANDLER_H -#define _LIBCPP_ASSERTION_HANDLER_H - -#include <__config> - -_LIBCPP_BEGIN_NAMESPACE_STD - -// Forward declare the verbose abort function from libcxx with proper attributes -[[noreturn]] _LIBCPP_EXPORTED_FROM_ABI void -__libcpp_verbose_abort(const char *, ...) _NOEXCEPT; - -// Default assertion handler that uses verbose abort directly -[[noreturn]] inline void __libcpp_assertion_handler(char const *format, ...) { - // Simply pass format string to verbose abort - no formatting to avoid stdio - // dependency - __libcpp_verbose_abort(format); -} - -_LIBCPP_END_NAMESPACE_STD - -// Define the assertion handler macro -// Cast to void to make it work with exceptions disabled -#define _LIBCPP_ASSERTION_HANDLER(...) \ - (::std::__libcpp_assertion_handler(__VA_ARGS__), static_cast(0)) - -#endif // _LIBCPP_ASSERTION_HANDLER_H diff --git a/libs/libxx/libcxx/mbstate_t.patch b/libs/libxx/libcxx/mbstate_t.patch index 1aee59bde04de..1ad88535bf20e 100644 --- a/libs/libxx/libcxx/mbstate_t.patch +++ b/libs/libxx/libcxx/mbstate_t.patch @@ -1,17 +1,11 @@ ---- libs/libxx/libcxx/include/__mbstate_t.h 2023-11-28 09:52:28.000000000 +0100 -+++ libs/libxx/libcxx/include/__mbstate_t.h 2023-12-05 16:14:46.523689408 +0100 -@@ -39,12 +39,12 @@ - # define __NEED_mbstate_t - # include - # undef __NEED_mbstate_t -+#elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next() -+# include_next // fall back to the C standard provider of mbstate_t - #elif __has_include() - # include // works on most Unixes - #elif __has_include() - # include // works on Darwin --#elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next() --# include_next // fall back to the C standard provider of mbstate_t +--- libcxx/include/__mbstate_t.h ++++ libcxx/include/__mbstate_t.h +@@ -45,6 +45,8 @@ + # include // works on Darwin + #elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next() + # include_next // fall back to the C standard provider of mbstate_t ++#elif defined(__NuttX__) && __has_include_next() ++# include_next // NuttX always exposes mbstate_t through #elif __has_include_next() - # include_next // is also required to make mbstate_t visible + # include_next // is also required to make mbstate_t visible #else diff --git a/libs/libxx/libcxx/mbstate_t_21.1.8.patch b/libs/libxx/libcxx/mbstate_t_21.1.8.patch deleted file mode 100644 index 2920e517365c3..0000000000000 --- a/libs/libxx/libcxx/mbstate_t_21.1.8.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/include/__mbstate_t.h -+++ b/include/__mbstate_t.h -@@ -39,12 +39,12 @@ - # define __NEED_mbstate_t - # include - # undef __NEED_mbstate_t -+#elif __has_include_next() -+# include_next // use the C standard provider of mbstate_t if present - #elif __has_include() - # include // works on most Unixes - #elif __has_include() - # include // works on Darwin --#elif __has_include_next() --# include_next // use the C standard provider of mbstate_t if present - #elif __has_include_next() - # include_next // Try in absence of for mbstate_t - #else diff --git a/libs/libxx/libcxx/nuttx_string_instantiations.cpp b/libs/libxx/libcxx/nuttx_string_instantiations.cpp new file mode 100644 index 0000000000000..0430cd49d283b --- /dev/null +++ b/libs/libxx/libcxx/nuttx_string_instantiations.cpp @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Force emission of the std::__1::basic_string destructors for the +// character sets that NuttX enables. The upstream libc++ headers declare +// the relevant template instantiations as "extern", so without providing +// explicit definitions the linker cannot resolve references coming from +// locale-heavy translation units such as locale.cpp. + +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Emit the full char specialization so all key functions (including dtors) +// are visible from libxx.a instead of remaining TU-local. +template class _LIBCPP_EXPORTED_FROM_ABI basic_string; + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +// Emit the wchar_t specialization to satisfy localization-widechar users. +template class _LIBCPP_EXPORTED_FROM_ABI basic_string; +#endif + +_LIBCPP_END_NAMESPACE_STD diff --git a/libs/libxx/libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch b/libs/libxx/libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch deleted file mode 100644 index 47fc0014846fb..0000000000000 --- a/libs/libxx/libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- src/cxa_exception.cpp.orig 2026-01-10 08:23:14.212626633 +0100 -+++ src/cxa_exception.cpp 2026-01-10 08:23:14.510070337 +0100 -@@ -215,8 +215,16 @@ - #endif - __cxa_exception* exception_header = cxa_exception_from_thrown_object(object); - exception_header->referenceCount = 0; -- exception_header->unexpectedHandler = std::get_unexpected(); -- exception_header->terminateHandler = std::get_terminate(); -+ // Use libcxxabi's handlers directly instead of std::get_terminate() -+ // to avoid issues with uninitialized libcxx fallback handlers when -+ // both libcxx and libcxxabi are linked together -+ extern std::terminate_handler __cxa_terminate_handler; -+ extern std::unexpected_handler __cxa_unexpected_handler; -+ exception_header->unexpectedHandler = __cxa_unexpected_handler; -+ exception_header->terminateHandler = __cxa_terminate_handler; -+#if defined(_LIBCXXABI_ARM_EHABI) -+ exception_header->propagationCount = 0; -+#endif - exception_header->exceptionType = tinfo; - exception_header->exceptionDestructor = dest; - setOurExceptionClass(&exception_header->unwindHeader); diff --git a/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch b/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch deleted file mode 100644 index c989a8f8bff83..0000000000000 --- a/libs/libxx/libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- libcxxabi.orig/src/cxa_guard_impl.h 2026-01-10 14:08:51.808835600 +0100 -+++ libcxxabi/src/cxa_guard_impl.h 2026-01-10 14:08:51.819473598 +0100 -@@ -665,7 +665,7 @@ - // TODO(EricWF): We should prefer the futex implementation when available. But - // it should be done in a separate step from adding the implementation. - constexpr Implementation CurrentImplementation = --#if defined(_LIBCXXABI_HAS_NO_THREADS) -+#if defined(_LIBCXXABI_HAS_NO_THREADS) || defined(_LIBCPP_HAS_NO_THREADS) - Implementation::NoThreads; - #elif defined(_LIBCXXABI_USE_FUTEX) - Implementation::Futex; - diff --git a/libs/libxx/libcxxabi/CMakeLists.txt b/libs/libxx/libcxxabi/CMakeLists.txt index 1744270d0a049..7a2ccf24e123c 100644 --- a/libs/libxx/libcxxabi/CMakeLists.txt +++ b/libs/libxx/libcxxabi/CMakeLists.txt @@ -42,14 +42,10 @@ if(CONFIG_LIBCXXABI) TEST_COMMAND "" PATCH_COMMAND - patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < - ${CMAKE_CURRENT_LIST_DIR}/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < - ${CMAKE_CURRENT_LIST_DIR}/0002-libcxxabi-fix-compilation-errors.patch && - patch -p0 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < - ${CMAKE_CURRENT_LIST_DIR}/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch - && patch -p1 -d ${CMAKE_CURRENT_LIST_DIR}/libcxxabi < - ${CMAKE_CURRENT_LIST_DIR}/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch + patch -p0 -d ${CMAKE_CURRENT_LIST_DIR} < + ${CMAKE_CURRENT_LIST_DIR}/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch && + patch -p0 -d ${CMAKE_CURRENT_LIST_DIR} < + ${CMAKE_CURRENT_LIST_DIR}/0002-libcxxabi-fix-compilation-errors.patch DOWNLOAD_NO_PROGRESS true TIMEOUT 30) @@ -78,39 +74,28 @@ if(CONFIG_LIBCXXABI) cxa_aux_runtime.cpp cxa_default_handlers.cpp cxa_demangle.cpp + cxa_exception_storage.cpp cxa_guard.cpp cxa_handlers.cpp + cxa_thread_atexit.cpp cxa_vector.cpp cxa_virtual.cpp) - # Excluded: cxa_exception_storage.cpp (uses thread-local storage - # __aeabi_read_tp) Excluded threading-dependent files: cxa_thread_atexit.cpp add_compile_definitions(_LIBCPP_BUILDING_LIBRARY) - if(CONFIG_LIBSUPCXX_TOOLCHAIN) - add_compile_definitions(__GLIBCXX__) - endif() + add_compile_definitions(LIBCXXABI_BAREMETAL) - if(CONFIG_LIBSUPCXX) - add_compile_definitions(__GLIBCXX__) - endif() # C++ STL files list(APPEND SRCS stdlib_exception.cpp stdlib_new_delete.cpp - stdlib_stdexcept.cpp stdlib_typeinfo.cpp) - - # Internal files and stub implementations (no threading, no TLS) - list(APPEND SRCS abort_message.cpp private_typeinfo.cpp) - - # Add stub files from libs/libxx/libcxxabi/src/ (not from libcxxabi/src/) - list(APPEND STUB_SRCS - ${CMAKE_CURRENT_LIST_DIR}/src/cxa_exception_storage_stub.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/fallback_malloc_stub.cpp) - - # Exclude threading-dependent files when _LIBCPP_HAS_NO_THREADS is defined - # These files use __libcpp_mutex_t, __libcpp_condvar_t, __libcpp_tls_key which - # are not available without threading list(APPEND SRCS cxa_guard.cpp - # cxa_thread_atexit.cpp) + stdlib_stdexcept.cpp) + # Internal files + list(APPEND SRCS abort_message.cpp fallback_malloc.cpp) if(CONFIG_CXX_EXCEPTION) - list(APPEND SRCS cxa_exception.cpp cxa_personality.cpp) + list(APPEND SRCS cxa_exception.cpp cxa_exception_storage.cpp + cxa_personality.cpp) + endif() + + if(CONFIG_CXX_RTTI) + list(APPEND SRCS private_typeinfo.cpp stdlib_typeinfo.cpp) endif() if(CONFIG_LIBCXXABI) @@ -122,20 +107,6 @@ if(CONFIG_LIBCXXABI) list(APPEND TARGET_SRCS ${src}) endforeach() - # RTTI is required for building the libcxxabi library - target_compile_options(libcxxabi PRIVATE -frtti) - - # Fix ARM unwinder enum type conversion warnings without disabling all type - # safety - if(CONFIG_ARCH_ARM) - target_compile_options(libcxxabi PRIVATE -Wno-error=conversion - -Wno-error=enum-conversion) - endif() - - # Disable threading support to match libcxx configuration Note: - # _LIBCPP_HAS_NO_THREADS is already defined in __config_site - target_compile_definitions(libcxxabi PRIVATE _LIBCXXABI_HAS_NO_THREADS) - if(CONFIG_SIM_UBSAN OR CONFIG_MM_UBSAN) target_compile_options(libcxxabi PRIVATE -fno-sanitize=vptr) endif() @@ -143,9 +114,7 @@ if(CONFIG_LIBCXXABI) # Fix compilation error on ARM32:libcxxabi/src/cxa_personality.cpp:594:22: # error: '_URC_FATAL_PHASE1_ERROR' was not declared in this scope 594 | # results.reason = _URC_FATAL_PHASE1_ERROR; - if(CONFIG_ARCH_ARM) - # Enable bare-metal mode for correct TARGET2 relocation handling - target_compile_definitions(libcxxabi PRIVATE LIBCXXABI_BAREMETAL) + if(CONFIG_ARCH_ARM AND NOT CONFIG_ARCH_TOOLCHAIN_CLANG) target_compile_definitions(libcxxabi PRIVATE _URC_FATAL_PHASE2_ERROR=_URC_FAILURE) target_compile_definitions(libcxxabi @@ -155,7 +124,7 @@ if(CONFIG_LIBCXXABI) target_compile_definitions(libcxxabi PRIVATE LIBCXXABI_NON_DEMANGLING_TERMINATE) - target_sources(libcxxabi PRIVATE ${TARGET_SRCS} ${STUB_SRCS}) + target_sources(libcxxabi PRIVATE ${TARGET_SRCS}) target_include_directories( libcxxabi BEFORE PRIVATE ${NUTTX_DIR}/libs/libxx/libcxx/libcxx/src ${CMAKE_CURRENT_LIST_DIR}/libcxxabi/include) diff --git a/libs/libxx/libcxxabi/Make.defs b/libs/libxx/libcxxabi/Make.defs index e9d5a3111fa92..f50918a8836f7 100644 --- a/libs/libxx/libcxxabi/Make.defs +++ b/libs/libxx/libcxxabi/Make.defs @@ -30,10 +30,8 @@ libcxxabi-$(LIBCXXABI_VERSION).src.tar.xz: libcxxabi/libcxxabi: libcxxabi-$(LIBCXXABI_VERSION).src.tar.xz $(Q) tar -xf $< $(Q) mv libcxxabi-$(LIBCXXABI_VERSION).src $@ - $(Q) patch -p1 < libcxxabi/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch -d libcxxabi/libcxxabi - $(Q) patch -p1 < libcxxabi/0002-libcxxabi-fix-compilation-errors.patch -d libcxxabi/libcxxabi - $(Q) patch -p0 < libcxxabi/0003-libcxxabi-fix-exception-handler-init_21.1.8.patch -d libcxxabi/libcxxabi - $(Q) patch -p1 < libcxxabi/0004-libcxxabi-disable-threading-in-cxa-guard_21.1.8.patch -d libcxxabi/libcxxabi + $(Q) patch -p0 < libcxxabi/0001-libcxxabi-Fix-build-warnings-generated-by-CMake-comp.patch -d libcxxabi + $(Q) patch -p0 < libcxxabi/0002-libcxxabi-fix-compilation-errors.patch -d libcxxabi endif $(TOPDIR)/include/libcxxabi: libcxxabi/libcxxabi @@ -45,7 +43,7 @@ context:: $(TOPDIR)/include/libcxxabi distclean:: $(Q) $(DIRUNLINK) $(TOPDIR)/include/libcxxabi ifeq ($(wildcard libcxxabi/libcxxabi/.git),) - $(Q) $(DELFILE) libcxxabi-$(LIBCXX_VERSION).src.tar.xz + $(Q) $(DELFILE) libcxxabi-$(LIBCXXABI_VERSION).src.tar.xz $(call DELDIR, libcxxabi/libcxxabi) endif @@ -64,34 +62,31 @@ endif # C++ABI files CPPSRCS += cxa_aux_runtime.cpp cxa_default_handlers.cpp cxa_demangle.cpp -CPPSRCS += cxa_guard.cpp cxa_handlers.cpp cxa_vector.cpp cxa_virtual.cpp +CPPSRCS += cxa_guard.cpp cxa_handlers.cpp cxa_thread_atexit.cpp cxa_vector.cpp cxa_virtual.cpp # C++ STL files -CPPSRCS += stdlib_exception.cpp stdlib_new_delete.cpp stdlib_stdexcept.cpp stdlib_typeinfo.cpp +CPPSRCS += stdlib_exception.cpp stdlib_new_delete.cpp stdlib_stdexcept.cpp # Internal files -CPPSRCS += abort_message.cpp private_typeinfo.cpp - -# Use stub files instead of originals (no threading, no TLS) -CPPSRCS += cxa_exception_storage_stub.cpp fallback_malloc_stub.cpp +CPPSRCS += abort_message.cpp fallback_malloc.cpp ifeq ($(CONFIG_CXX_EXCEPTION),y) -CPPSRCS += cxa_exception.cpp cxa_personality.cpp +CPPSRCS += cxa_exception.cpp cxa_personality.cpp cxa_exception_storage.cpp +endif + +ifeq ($(CONFIG_CXX_RTTI),y) +CPPSRCS += private_typeinfo.cpp stdlib_typeinfo.cpp endif # Fix compilation error on ARM32: # libcxxabi/src/cxa_personality.cpp:594:22: error: '_URC_FATAL_PHASE1_ERROR' was not declared in this scope # 594 | results.reason = _URC_FATAL_PHASE1_ERROR; ifeq ($(CONFIG_ARCH_ARM),y) -# Enable bare-metal mode for correct TARGET2 relocation handling -CXXFLAGS += -DLIBCXXABI_BAREMETAL -CXXFLAGS += -D_URC_FATAL_PHASE2_ERROR=_URC_FAILURE -D_URC_FATAL_PHASE1_ERROR=_URC_FAILURE + ifeq ($(CONFIG_ARCH_TOOLCHAIN_CLANG),) + CXXFLAGS += -D_URC_FATAL_PHASE2_ERROR=_URC_FAILURE -D_URC_FATAL_PHASE1_ERROR=_URC_FAILURE + endif endif CXXFLAGS += -DLIBCXXABI_NON_DEMANGLING_TERMINATE - -# RTTI is required for building the libcxxabi library -CXXFLAGS += -frtti +CXXFLAGS += -DLIBCXXABI_BAREMETAL DEPPATH += --dep-path libcxxabi/libcxxabi/src -DEPPATH += --dep-path libcxxabi/src VPATH += libcxxabi/libcxxabi/src -VPATH += libcxxabi/src diff --git a/libs/libxx/libcxxabi/__config_site b/libs/libxx/libcxxabi/__config_site new file mode 100644 index 0000000000000..a1b448d265167 --- /dev/null +++ b/libs/libxx/libcxxabi/__config_site @@ -0,0 +1,14 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCXXABI___CONFIG_SITE +#define _LIBCXXABI___CONFIG_SITE + +#include + +#endif // _LIBCXXABI___CONFIG_SITE diff --git a/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp b/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp deleted file mode 100644 index f73f72f292867..0000000000000 --- a/libs/libxx/libcxxabi/src/cxa_exception_storage_stub.cpp +++ /dev/null @@ -1,102 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// ============================================================================ -// THREAD-SAFE EXCEPTION STORAGE FOR NUTTX -// ============================================================================ -// -// This implementation provides per-thread exception storage using pthread -// thread-local storage (TLS). It is THREAD-SAFE and works correctly with: -// -// 1. Multi-threaded execution with NuttX RTOS task switching -// 2. Concurrent exception handling across different threads -// 3. Nested exceptions within the same thread -// 4. Proper cleanup when threads exit -// -// SAFETY FEATURES: -// - Uses pthread_key_create with destructor for automatic cleanup -// - Thread-safe initialization using pthread_once -// - Per-thread exception state isolation -// - No shared mutable state between threads -// -// NOTE: This implementation requires pthread support to be enabled in NuttX -// (CONFIG_PTHREAD=y) -// ============================================================================ - -#include "../libcxxabi/src/cxa_exception.h" -#include -#include -#include -#include - -namespace __cxxabiv1 { - -// pthread key for per-thread exception storage -static pthread_key_t exception_storage_key; -static pthread_once_t key_init_once = PTHREAD_ONCE_INIT; - -// Destructor called when thread exits - frees the exception storage -static void exception_storage_destructor(void *ptr) { - if (ptr) { - free(ptr); - } -} - -// Initialize pthread key once (thread-safe) -static void init_exception_storage_key() { - int result = - pthread_key_create(&exception_storage_key, exception_storage_destructor); - assert(result == 0 && "Failed to create pthread key for exception storage"); - (void)result; // Suppress unused variable warning in release builds -} - -extern "C" { - -// Get per-thread exception globals, allocating if necessary -__cxa_eh_globals *__cxa_get_globals() { - // Ensure pthread key is initialized (thread-safe, happens only once) - pthread_once(&key_init_once, init_exception_storage_key); - - // Get per-thread exception state from pthread TLS - __cxa_eh_globals *eh = static_cast<__cxa_eh_globals *>( - pthread_getspecific(exception_storage_key)); - - if (!eh) { - // First exception in this thread - allocate storage - eh = static_cast<__cxa_eh_globals *>(malloc(sizeof(__cxa_eh_globals))); - if (!eh) { - // Out of memory - this is fatal for exception handling - assert(false && "Out of memory allocating exception state"); - return nullptr; - } - - // Initialize to zero - memset(eh, 0, sizeof(__cxa_eh_globals)); - - // Store in pthread TLS for this thread - int result = pthread_setspecific(exception_storage_key, eh); - assert(result == 0 && "Failed to set pthread-specific exception storage"); - (void)result; - } - - return eh; -} - -// Fast version - assumes __cxa_get_globals() has been called at least once -__cxa_eh_globals *__cxa_get_globals_fast() { - // Ensure pthread key is initialized - pthread_once(&key_init_once, init_exception_storage_key); - - // Get per-thread exception state (may be nullptr if not yet initialized) - return static_cast<__cxa_eh_globals *>( - pthread_getspecific(exception_storage_key)); -} - -} // extern "C" - -} // namespace __cxxabiv1 diff --git a/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp b/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp deleted file mode 100644 index 53f78fe7d7c04..0000000000000 --- a/libs/libxx/libcxxabi/src/fallback_malloc_stub.cpp +++ /dev/null @@ -1,155 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include - -namespace __cxxabiv1 { - -// Simple malloc wrapper for fallback allocation -void *__aligned_malloc_with_fallback(size_t size) { return malloc(size); } - -// Proper aligned allocation for embedded systems -// SAFETY: Alignment requirements are critical for ARM/RISC-V architectures -// CRITICAL SAFETY CHECKS: -// 1. Integer overflow protection on size calculations -// 2. Alignment validation (must be power of 2) -// 3. NULL pointer checks on all allocations -// 4. Bounds validation before pointer arithmetic -void *__aligned_malloc_with_fallback(size_t alignment, size_t size) { - // SAFETY: Validate alignment is power of 2 and non-zero - assert(alignment > 0 && (alignment & (alignment - 1)) == 0); - - // SAFETY: Reject zero-size allocations explicitly - if (size == 0) { - return nullptr; - } - - // For small alignments that malloc already provides, use malloc directly - if (alignment <= alignof(max_align_t)) { - void *ptr = malloc(size); - // SAFETY: Check malloc success - if (!ptr) { - return nullptr; - } - return ptr; - } - - // CRITICAL SAFETY CHECK: Prevent integer overflow in size calculation - // total_size = size + alignment + sizeof(void*) - // Check: size <= SIZE_MAX - alignment - sizeof(void*) - if (size > SIZE_MAX - alignment - sizeof(void *)) { - // Integer overflow would occur - MUST reject to prevent buffer overflow - return nullptr; - } - - size_t total_size = size + alignment + sizeof(void *); - - // SAFETY: Additional sanity check that total_size is reasonable - assert(total_size > size && "Integer overflow detected"); - - void *raw_ptr = malloc(total_size); - - // SAFETY: Check malloc failure - if (!raw_ptr) { - return nullptr; - } - - // Calculate aligned address - uintptr_t raw_addr = reinterpret_cast(raw_ptr); - uintptr_t offset = alignment - (raw_addr % alignment); - - // Ensure we have space to store the original pointer - if (offset < sizeof(void *)) { - offset += alignment; - } - - // SAFETY: Verify offset is within allocated bounds - assert(offset <= total_size - size && "Alignment calculation error"); - - void *aligned_ptr = reinterpret_cast(raw_addr + offset); - - // Store original pointer just before the aligned pointer - void **ptr_storage = reinterpret_cast(aligned_ptr) - 1; - - // SAFETY: Verify pointer storage location is within allocated memory - assert(reinterpret_cast(ptr_storage) >= raw_addr && - reinterpret_cast(ptr_storage) < raw_addr + total_size && - "Pointer storage out of bounds"); - - *ptr_storage = raw_ptr; - - // SAFETY: Final verification that aligned pointer meets alignment requirement - assert((reinterpret_cast(aligned_ptr) & (alignment - 1)) == 0 && - "Alignment requirement not met"); - - return aligned_ptr; -} - -// Allocate zero-initialized memory with overflow protection -// SAFETY: calloc checks for overflow internally, but we add explicit validation -void *__calloc_with_fallback(size_t count, size_t size) { - // SAFETY: Check for multiplication overflow before calling calloc - // Many implementations check this, but we verify explicitly for safety - if (count != 0 && size > SIZE_MAX / count) { - // Overflow would occur - reject allocation - return nullptr; - } - - void *ptr = calloc(count, size); - - // SAFETY: Check allocation success - if (!ptr && count > 0 && size > 0) { - // Allocation failed - return nullptr - return nullptr; - } - - return ptr; -} - -// Free properly aligned memory with safety validation -// SAFETY: Validates pointer before freeing to prevent corruption -// NOTE: For single-argument __aligned_malloc_with_fallback(size), we just use -// malloc/free directly For two-argument version with alignment, we store the -// original pointer before the aligned address -void __aligned_free_with_fallback(void *ptr) { - // SAFETY: NULL pointer is valid to free (no-op) - if (!ptr) { - return; - } - - // Check if this pointer has the alignment metadata - // If alignment was requested, the original pointer is stored at ptr - - // sizeof(void*) For simple malloc (no alignment), we just free directly - void **ptr_storage = reinterpret_cast(ptr) - 1; - void *original_ptr = *ptr_storage; - - // Heuristic: If the stored "pointer" value looks invalid (not aligned, or - // points way before current ptr), assume this was allocated with malloc(size) - // directly and just free it. Otherwise, use the stored original pointer. - uintptr_t ptr_addr = reinterpret_cast(ptr); - uintptr_t orig_addr = reinterpret_cast(original_ptr); - - // Check if original_ptr looks valid: - // 1. Not NULL - // 2. Points before or at aligned ptr - // 3. Within reasonable distance (< 1MB offset indicates alignment padding, - // not corruption) - if (original_ptr != nullptr && orig_addr <= ptr_addr && - (ptr_addr - orig_addr) < (1024 * 1024)) { - // Looks like aligned allocation with stored pointer - free(original_ptr); - } else { - // Looks like simple malloc allocation without alignment metadata - free(ptr); - } -} - -} // namespace __cxxabiv1 diff --git a/net/devif/ipv4_input.c b/net/devif/ipv4_input.c index 5ea71232e6b4a..7fbf8d003becd 100644 --- a/net/devif/ipv4_input.c +++ b/net/devif/ipv4_input.c @@ -94,6 +94,7 @@ #include #include #include +#include #include "arp/arp.h" #include "inet/inet.h" @@ -118,6 +119,53 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: ipv4_check_opt + * + * Description: + * Check the IP options length. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +static int ipv4_check_opt(FAR struct ipv4_hdr_s *ipv4) +{ + FAR uint8_t *opt = (FAR uint8_t *)(ipv4 + 1); + int optlen; + + optlen = ((ipv4->vhl & IPv4_HLMASK) << 2) - IPv4_HDRLEN; + while (optlen > 0) + { + if (opt[0] == IPOPT_END_TYPE) + { + break; + } + else if (opt[0] == IPOPT_NOOP_TYPE) + { + opt++; + optlen--; + } + else if (optlen > 1) + { + int len = opt[1]; + if (len > optlen) + { + return -EINVAL; + } + + opt += len; + optlen -= len; + } + else + { + return -EINVAL; + } + } + + return OK; +} +#endif + /**************************************************************************** * Name: ipv4_in * @@ -189,7 +237,7 @@ static int ipv4_in(FAR struct net_driver_s *dev) dev->d_len -= NET_LL_HDRLEN(dev); - if (IPv4_HDRLEN > dev->d_len) + if (((ipv4->vhl & IPv4_HLMASK) << 2) > dev->d_len) { nwarn("WARNING: Packet shorter than IPv4 header\n"); goto drop; @@ -242,6 +290,17 @@ static int ipv4_in(FAR struct net_driver_s *dev) goto drop; } +#ifdef CONFIG_DEBUG_FEATURES + if (ipv4_check_opt(ipv4) != OK) + { +#ifdef CONFIG_NET_STATISTICS + g_netstats.ipv4.drop++; +#endif + nwarn("WARNING: IP options error\n"); + goto drop; + } +#endif + #ifdef CONFIG_NET_NAT44 /* Try NAT inbound, rule matching will be performed in NAT module. */ diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index 1121807f01cd9..70a7dd09fece7 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -189,6 +189,13 @@ static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise) struct icmpv6_router_s state; int ret; + /* Check whether the link-local address has been overwritten. */ + + if (netdev_ipv6_lladdr(dev) == NULL) + { + return -EADDRNOTAVAIL; + } + /* Initialize the state structure with the network locked. */ nxsem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */ diff --git a/net/inet/ipv4_setsockopt.c b/net/inet/ipv4_setsockopt.c index cd0a6bd97f6e1..ddc60352915ec 100644 --- a/net/inet/ipv4_setsockopt.c +++ b/net/inet/ipv4_setsockopt.c @@ -267,7 +267,7 @@ int ipv4_setsockopt(FAR struct socket *psock, int option, { if (net_ipv4addr_cmp(mreq.imr_multiaddr.s_addr, INADDR_ANY)) { - conn->mreq.imr_interface.s_addr = 0; + conn->mreq.imr_address.s_addr = 0; conn->mreq.imr_ifindex = 0; ret = OK; break; @@ -299,7 +299,7 @@ int ipv4_setsockopt(FAR struct socket *psock, int option, } #endif - conn->mreq.imr_interface.s_addr = mreq.imr_multiaddr.s_addr; + conn->mreq.imr_address.s_addr = mreq.imr_multiaddr.s_addr; conn->mreq.imr_ifindex = mreq.imr_ifindex; ret = OK; break; diff --git a/net/ipfrag/ipv4_frag.c b/net/ipfrag/ipv4_frag.c index d62d09ee913c5..2c15267f45a16 100644 --- a/net/ipfrag/ipv4_frag.c +++ b/net/ipfrag/ipv4_frag.c @@ -309,7 +309,7 @@ int32_t ipv4_fragin(FAR struct net_driver_s *dev) */ ipv4_fragin_reassemble(node); - netdev_iob_replace(dev, node->outgoframe); + netdev_iob_replace_l2(dev, node->outgoframe); /* Free the memory of node */ diff --git a/net/ipfrag/ipv6_frag.c b/net/ipfrag/ipv6_frag.c index ffae571ef4864..0a86c26ce2c2b 100644 --- a/net/ipfrag/ipv6_frag.c +++ b/net/ipfrag/ipv6_frag.c @@ -515,7 +515,7 @@ int32_t ipv6_fragin(FAR struct net_driver_s *dev) */ ipv6_fragin_reassemble(node); - netdev_iob_replace(dev, node->outgoframe); + netdev_iob_replace_l2(dev, node->outgoframe); /* Free the memory of node */ diff --git a/net/neighbor/neighbor_ethernet_out.c b/net/neighbor/neighbor_ethernet_out.c index 1e753a76785da..143369c9da60a 100644 --- a/net/neighbor/neighbor_ethernet_out.c +++ b/net/neighbor/neighbor_ethernet_out.c @@ -155,7 +155,7 @@ void neighbor_ethernet_out(FAR struct net_driver_s *dev) if (neighbor_lookup(ipaddr, &laddr) < 0) { -#ifdef CONFIG_NET_ICMPv6 +#ifdef NET_ICMPv6_HAVE_STACK /* No ARP packet if this device do not support ARP */ if (IFF_IS_NOARP(dev->d_flags)) @@ -163,7 +163,7 @@ void neighbor_ethernet_out(FAR struct net_driver_s *dev) return; } - ninfo("IPv6 Neighbor solicitation for IPv6\n"); + ninfo("IPv6 Neighbor solicitation for IPv6\n"); /* The destination address was not in our Neighbor Table, so we * overwrite the IPv6 packet with an ICMPv6 Neighbor Solicitation diff --git a/net/netdev/netdev.h b/net/netdev/netdev.h index 1e3003de02d35..5f50d6dad4cd7 100644 --- a/net/netdev/netdev.h +++ b/net/netdev/netdev.h @@ -106,23 +106,6 @@ typedef int (*netdev_callback_t)(FAR struct net_driver_s *dev, bool netdev_verify(FAR struct net_driver_s *dev); -/**************************************************************************** - * Name: netdev_findbyname - * - * Description: - * Find a previously registered network device using its assigned - * network interface name - * - * Input Parameters: - * ifname The interface name of the device of interest - * - * Returned Value: - * Pointer to driver on success; null on failure - * - ****************************************************************************/ - -FAR struct net_driver_s *netdev_findbyname(FAR const char *ifname); - /**************************************************************************** * Name: netdev_foreach * @@ -241,24 +224,6 @@ FAR struct net_driver_s *netdev_findby_ripv6addr( const net_ipv6addr_t ripaddr); #endif -/**************************************************************************** - * Name: netdev_findbyindex - * - * Description: - * Find a previously registered network device by assigned interface index. - * - * Input Parameters: - * ifindex - The interface index. This is a one-based index and must be - * greater than zero. - * - * Returned Value: - * Pointer to driver on success; NULL on failure. This function will return - * NULL only if there is no device corresponding to the provided index. - * - ****************************************************************************/ - -FAR struct net_driver_s *netdev_findbyindex(int ifindex); - /**************************************************************************** * Name: netdev_nextindex * diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 39217a0e9b48b..3b7ccb27731b0 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -394,11 +394,11 @@ static int netdev_bluetooth_ioctl(FAR struct socket *psock, int cmd, { FAR struct net_driver_s *dev; FAR char *ifname; - int ret = -EINVAL; + int ret = -ENOTTY; - if (arg != 0ul) + if (_BLUETOOTHIOCVALID(cmd)) { - if (_BLUETOOTHIOCVALID(cmd)) + if (arg != 0ul) { /* Get the name of the Bluetooth device to receive the IOCTL * command @@ -411,9 +411,9 @@ static int netdev_bluetooth_ioctl(FAR struct socket *psock, int cmd, } else { - /* Not a Bluetooth IOCTL command */ + /* Argument is invalid */ - return -ENOTTY; + return -EINVAL; } /* Find the device with this name */ @@ -459,9 +459,9 @@ static int netdev_iee802154_ioctl(FAR struct socket *psock, int cmd, FAR char *ifname; int ret = -ENOTTY; - if (arg != 0ul) + if (_MAC802154IOCVALID(cmd)) { - if (_MAC802154IOCVALID(cmd)) + if (arg != 0ul) { /* Get the IEEE802.15.4 MAC device to receive the radio IOCTL * command @@ -474,9 +474,9 @@ static int netdev_iee802154_ioctl(FAR struct socket *psock, int cmd, } else { - /* Not an EEE802.15.4 MAC IOCTL command */ + /* Argument is invalid */ - return -ENOTTY; + return -EINVAL; } /* Find the device with this name */ @@ -520,9 +520,9 @@ static int netdev_pktradio_ioctl(FAR struct socket *psock, int cmd, FAR char *ifname; int ret = -ENOTTY; - if (arg != 0ul) + if (_PKRADIOIOCVALID(cmd)) { - if (_PKRADIOIOCVALID(cmd)) + if (arg != 0ul) { /* Get the packet radio device to receive the radio IOCTL * command @@ -535,10 +535,9 @@ static int netdev_pktradio_ioctl(FAR struct socket *psock, int cmd, } else { - /* Not a packet radio IOCTL command */ + /* Argument is invalid */ - nwarn("WARNING: Not a packet radio IOCTL command: %d\n", cmd); - return -ENOTTY; + return -EINVAL; } /* Find the device with this name */ diff --git a/net/route/net_add_ramroute.c b/net/route/net_add_ramroute.c index e0c95943d51ae..140a21f2bbfeb 100644 --- a/net/route/net_add_ramroute.c +++ b/net/route/net_add_ramroute.c @@ -82,13 +82,13 @@ int net_addroute_ipv4(in_addr_t target, in_addr_t netmask, in_addr_t router) /* Get exclusive address to the networking data structures */ - net_lock(); + net_lockroute_ipv4(); /* Then add the new entry to the table */ ramroute_ipv4_addlast((FAR struct net_route_ipv4_entry_s *)route, &g_ipv4_routes); - net_unlock(); + net_unlockroute_ipv4(); netlink_route_notify(route, RTM_NEWROUTE, AF_INET); return OK; @@ -119,13 +119,11 @@ int net_addroute_ipv6(net_ipv6addr_t target, net_ipv6addr_t netmask, /* Get exclusive address to the networking data structures */ - net_lock(); - - /* Then add the new entry to the table */ + net_lockroute_ipv6(); ramroute_ipv6_addlast((FAR struct net_route_ipv6_entry_s *)route, &g_ipv6_routes); - net_unlock(); + net_unlockroute_ipv6(); netlink_route_notify(route, RTM_NEWROUTE, AF_INET6); return OK; diff --git a/net/route/net_alloc_ramroute.c b/net/route/net_alloc_ramroute.c index e5ec79ece31d9..2f4c62617fa00 100644 --- a/net/route/net_alloc_ramroute.c +++ b/net/route/net_alloc_ramroute.c @@ -33,6 +33,7 @@ #include #include +#include "utils/utils.h" #include "route/ramroute.h" #include "route/route.h" @@ -58,80 +59,22 @@ FAR struct net_route_ipv6_queue_s g_ipv6_routes; * Private Data ****************************************************************************/ -/* These are lists of free routing table entries */ +/* The array containing all routing table entries. */ #ifdef CONFIG_ROUTE_IPv4_RAMROUTE -static struct net_route_ipv4_queue_s g_free_ipv4routes; +NET_BUFPOOL_DECLARE(g_ipv4routes, sizeof(struct net_route_ipv4_entry_s), + CONFIG_ROUTE_MAX_IPv4_RAMROUTES, 0, 0); #endif #ifdef CONFIG_ROUTE_IPv6_RAMROUTE -static struct net_route_ipv6_queue_s g_free_ipv6routes; -#endif - -/* These are arrays of pre-allocated network routes */ - -#ifdef CONFIG_ROUTE_IPv4_RAMROUTE -static struct net_route_ipv4_entry_s - g_prealloc_ipv4routes[CONFIG_ROUTE_MAX_IPv4_RAMROUTES]; -#endif - -#ifdef CONFIG_ROUTE_IPv6_RAMROUTE -static struct net_route_ipv6_entry_s - g_prealloc_ipv6routes[CONFIG_ROUTE_MAX_IPv6_RAMROUTES]; +NET_BUFPOOL_DECLARE(g_ipv6routes, sizeof(struct net_route_ipv6_entry_s), + CONFIG_ROUTE_MAX_IPv6_RAMROUTES, 0, 0); #endif /**************************************************************************** * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: net_init_ramroute - * - * Description: - * Initialize the in-memory, RAM routing table - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions: - * Called early in initialization so that no special protection is needed. - * - ****************************************************************************/ - -void net_init_ramroute(void) -{ - int i; - - /* Initialize the routing table and the free list */ - -#ifdef CONFIG_ROUTE_IPv4_RAMROUTE - ramroute_init(&g_ipv4_routes); - ramroute_init(&g_free_ipv4routes); - - /* Add all of the pre-allocated routing table entries to a free list */ - - for (i = 0; i < CONFIG_ROUTE_MAX_IPv4_RAMROUTES; i++) - { - ramroute_ipv4_addlast(&g_prealloc_ipv4routes[i], &g_free_ipv4routes); - } -#endif - -#ifdef CONFIG_ROUTE_IPv6_RAMROUTE - ramroute_init(&g_ipv6_routes); - ramroute_init(&g_free_ipv6routes); - - /* Add all of the pre-allocated routing table entries to a free list */ - - for (i = 0; i < CONFIG_ROUTE_MAX_IPv6_RAMROUTES; i++) - { - ramroute_ipv6_addlast(&g_prealloc_ipv6routes[i], &g_free_ipv6routes); - } -#endif -} - /**************************************************************************** * Name: net_allocroute_ipv4 and net_allocroute_ipv6 * @@ -152,15 +95,11 @@ FAR struct net_route_ipv4_s *net_allocroute_ipv4(void) { FAR struct net_route_ipv4_entry_s *route; - /* Get exclusive address to the networking data structures */ - - net_lock(); - - /* Then add the remove the first entry from the table */ - - route = ramroute_ipv4_remfirst(&g_free_ipv4routes); + /* Get exclusive address to the networking data structures and + * then remove the first entry from the g_ipv4routes pool + */ - net_unlock(); + route = NET_BUFPOOL_TRYALLOC(g_ipv4routes); if (!route) { return NULL; @@ -175,15 +114,11 @@ FAR struct net_route_ipv6_s *net_allocroute_ipv6(void) { FAR struct net_route_ipv6_entry_s *route; - /* Get exclusive address to the networking data structures */ + /* Get exclusive address to the networking data structures and + * then remove the first entry from the g_ipv6routes pool + */ - net_lock(); - - /* Then add the remove the first entry from the table */ - - route = ramroute_ipv6_remfirst(&g_free_ipv6routes); - - net_unlock(); + route = NET_BUFPOOL_TRYALLOC(g_ipv6routes); if (!route) { return NULL; @@ -212,15 +147,9 @@ void net_freeroute_ipv4(FAR struct net_route_ipv4_s *route) { DEBUGASSERT(route); - /* Get exclusive address to the networking data structures */ - - net_lock(); + /* Add the new entry to the g_ipv4routes pool */ - /* Then add the new entry to the table */ - - ramroute_ipv4_addlast((FAR struct net_route_ipv4_entry_s *)route, - &g_free_ipv4routes); - net_unlock(); + NET_BUFPOOL_FREE(g_ipv4routes, (FAR struct net_route_ipv4_entry_s *)route); } #endif @@ -229,15 +158,49 @@ void net_freeroute_ipv6(FAR struct net_route_ipv6_s *route) { DEBUGASSERT(route); - /* Get exclusive address to the networking data structures */ + /* Add the new entry to the g_ipv6routes pool */ + + NET_BUFPOOL_FREE(g_ipv6routes, (FAR struct net_route_ipv6_entry_s *)route); +} +#endif + +/**************************************************************************** + * Name: net_lockroute_ipv4 and net_unlockroute_ipv4 + * + * Description: + * Lock and unlock the g_ipv4routes pool + * + ****************************************************************************/ + +#ifdef CONFIG_ROUTE_IPv4_RAMROUTE +void net_lockroute_ipv4(void) +{ + NET_BUFPOOL_LOCK(g_ipv4routes); +} + +void net_unlockroute_ipv4(void) +{ + NET_BUFPOOL_UNLOCK(g_ipv4routes); +} +#endif - net_lock(); +/**************************************************************************** + * Name: net_lockroute_ipv6 and net_unlockroute_ipv6 + * + * Description: + * Lock and unlock the g_ipv6routes pool + * + ****************************************************************************/ - /* Then add the new entry to the table */ +#ifdef CONFIG_ROUTE_IPv6_RAMROUTE +void net_lockroute_ipv6(void) +{ + NET_BUFPOOL_LOCK(g_ipv6routes); +} - ramroute_ipv6_addlast((FAR struct net_route_ipv6_entry_s *)route, - &g_free_ipv6routes); - net_unlock(); +void net_unlockroute_ipv6(void) +{ + NET_BUFPOOL_UNLOCK(g_ipv6routes); } #endif diff --git a/net/route/net_foreach_ramroute.c b/net/route/net_foreach_ramroute.c index 97b2fcfe0930c..90f5959f0a63e 100644 --- a/net/route/net_foreach_ramroute.c +++ b/net/route/net_foreach_ramroute.c @@ -68,7 +68,7 @@ int net_foreachroute_ipv4(route_handler_ipv4_t handler, FAR void *arg) /* Prevent concurrent access to the routing table */ - net_lock(); + net_lockroute_ipv4(); /* Visit each entry in the routing table */ @@ -82,9 +82,9 @@ int net_foreachroute_ipv4(route_handler_ipv4_t handler, FAR void *arg) ret = handler(&route->entry, arg); } - /* Unlock the network */ + /* Unlock the g_ipv4_routes */ - net_unlock(); + net_unlockroute_ipv4(); return ret; } #endif @@ -98,7 +98,7 @@ int net_foreachroute_ipv6(route_handler_ipv6_t handler, FAR void *arg) /* Prevent concurrent access to the routing table */ - net_lock(); + net_lockroute_ipv6(); /* Visit each entry in the routing table */ @@ -112,9 +112,9 @@ int net_foreachroute_ipv6(route_handler_ipv6_t handler, FAR void *arg) ret = handler(&route->entry, arg); } - /* Unlock the network */ + /* Unlock the g_ipv6_routes */ - net_unlock(); + net_unlockroute_ipv6(); return ret; } #endif diff --git a/net/route/net_initroute.c b/net/route/net_initroute.c index aedaa758bacee..ac4a1fa50d943 100644 --- a/net/route/net_initroute.c +++ b/net/route/net_initroute.c @@ -52,10 +52,6 @@ void net_init_route(void) { -#if defined(CONFIG_ROUTE_IPv4_RAMROUTE) || defined(CONFIG_ROUTE_IPv6_RAMROUTE) - net_init_ramroute(); -#endif - #if defined(CONFIG_ROUTE_IPv4_CACHEROUTE) || defined(CONFIG_ROUTE_IPv6_CACHEROUTE) net_init_cacheroute(); #endif diff --git a/net/route/ramroute.h b/net/route/ramroute.h index 74aff0c0c67be..b3c9cf0f6af48 100644 --- a/net/route/ramroute.h +++ b/net/route/ramroute.h @@ -119,25 +119,6 @@ extern struct net_route_ipv6_queue_s g_ipv6_routes; * Public Function Prototypes ****************************************************************************/ -/**************************************************************************** - * Name: net_init_ramroute - * - * Description: - * Initialize the in-memory, RAM routing table - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions: - * Called early in initialization so that no special protection is needed. - * - ****************************************************************************/ - -void net_init_ramroute(void); - /**************************************************************************** * Name: net_allocroute_ipv4 and net_allocroute_ipv6 * @@ -183,6 +164,32 @@ void net_freeroute_ipv4(FAR struct net_route_ipv4_s *route); void net_freeroute_ipv6(FAR struct net_route_ipv6_s *route); #endif +/**************************************************************************** + * Name: net_lockroute_ipv4 and net_unlockroute_ipv4 + * + * Description: + * Lock and unlock the g_ipv4routes pool + * + ****************************************************************************/ + +#ifdef CONFIG_ROUTE_IPv4_RAMROUTE +void net_lockroute_ipv4(void); +void net_unlockroute_ipv4(void); +#endif + +/**************************************************************************** + * Name: net_lockroute_ipv6 and net_unlockroute_ipv6 + * + * Description: + * Lock and unlock the g_ipv6routes pool + * + ****************************************************************************/ + +#ifdef CONFIG_ROUTE_IPv6_RAMROUTE +void net_lockroute_ipv6(void); +void net_unlockroute_ipv6(void); +#endif + /**************************************************************************** * Name: (various low-level list operations) * diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 74c8d53651d1b..54cbd2e73d851 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -1600,33 +1600,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain, } #else /* CONFIG_NET_TCPURGDATA */ - /* Check the URG flag. If this is set, We must gracefully ignore - * and discard the urgent data. - */ - - if ((tcp->flags & TCP_URG) != 0) - { - uint16_t urglen = (tcp->urgp[0] << 8) | tcp->urgp[1]; - if (urglen > dev->d_len) - { - /* There is more urgent data in the next segment to come. */ - - urglen = dev->d_len; - } - - /* The d_len field contains the length of the incoming data; - * The d_appdata field points to the any "normal" data that - * may follow the urgent data. - * - * NOTE: If the urgent data continues in the next packet, then - * d_len will be zero and d_appdata will point past the end of - * the payload (which is OK). - */ - - net_incr32(conn->rcvseq, urglen); - dev->d_len -= urglen; - dev->d_appdata += urglen; - } + /* Urgent data needs to be treated as normal data */ #endif /* CONFIG_NET_TCPURGDATA */ #ifdef CONFIG_NET_TCP_KEEPALIVE diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index 368a3379b2076..33c70aff0f5be 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -695,7 +695,15 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn) devif_conn_event(conn->dev, TCP_ABORT, conn->sconn.list); - tcp_stop_monitor(conn, TCP_ABORT); + + /* We also send a reset packet to the remote host. */ + + tcp_send(dev, conn, TCP_RST | TCP_ACK, hdrlen); + + /* Stop the timer work */ + + conn->keeptimer = 0; + conn->timer = 0; } else { diff --git a/sched/Kconfig b/sched/Kconfig index 5339e2b75077a..7c3d8092533df 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -1671,6 +1671,15 @@ config SIG_SIGPOLL_ACTION Backward compatible behavior would require that the application use sigaction() to ignore SIGPOLL. +config SIG_SIGURG_ACTION + bool "SIGURG" + default n + ---help--- + Enable the default action for SIGURG (ignore the signal) + Make sure that your applications are expecting this POSIX behavior. + Backward compatible behavior would require that the application use + sigaction() to ignore SIGURG. + endif # SIG_DEFAULT endmenu # Signal Configuration @@ -2008,6 +2017,5 @@ config HRTIMER bool "High resolution timer support" depends on SYSTEM_TIME64 default n - depends on SYSTEM_TIME64 ---help--- Enable to support high resolution timer diff --git a/sched/hrtimer/hrtimer.h b/sched/hrtimer/hrtimer.h index 99858415d2948..92e932ac947c3 100644 --- a/sched/hrtimer/hrtimer.h +++ b/sched/hrtimer/hrtimer.h @@ -198,10 +198,7 @@ RB_PROTOTYPE(hrtimer_tree_s, hrtimer_node_s, entry, hrtimer_compare); static inline_function bool hrtimer_is_armed(FAR hrtimer_t *hrtimer) { - /* RB-tree root has NULL parent, so root must be checked explicitly */ - - return RB_PARENT(&hrtimer->node, entry) != NULL || - RB_ROOT(&g_hrtimer_tree) == &hrtimer->node; + return hrtimer->func != NULL; } /**************************************************************************** @@ -217,7 +214,7 @@ static inline_function void hrtimer_remove(FAR hrtimer_t *hrtimer) /* Explicitly clear parent to mark the timer as unarmed */ - RB_PARENT(&hrtimer->node, entry) = NULL; + hrtimer->func = NULL; } /**************************************************************************** diff --git a/sched/hrtimer/hrtimer_process.c b/sched/hrtimer/hrtimer_process.c index f94f699aa9edd..c7a40fd25111b 100644 --- a/sched/hrtimer/hrtimer_process.c +++ b/sched/hrtimer/hrtimer_process.c @@ -139,6 +139,7 @@ void hrtimer_process(uint64_t now) DEBUGASSERT(hrtimer->expired > period); + hrtimer->func = func; hrtimer_insert(hrtimer); } diff --git a/sched/hrtimer/hrtimer_start.c b/sched/hrtimer/hrtimer_start.c index caba6fc50f8dc..0f24e0952c9da 100644 --- a/sched/hrtimer/hrtimer_start.c +++ b/sched/hrtimer/hrtimer_start.c @@ -44,6 +44,7 @@ * * Input Parameters: * hrtimer - Pointer to the hrtimer structure. + * func - Expiration callback function. * expired - Expiration time in nanoseconds. Interpretation * depends on mode. * mode - Timer mode (HRTIMER_MODE_ABS or HRTIMER_MODE_REL). @@ -59,7 +60,7 @@ * nanoseconds from the current time. ****************************************************************************/ -int hrtimer_start(FAR hrtimer_t *hrtimer, +int hrtimer_start(FAR hrtimer_t *hrtimer, hrtimer_entry_t func, uint64_t expired, enum hrtimer_mode_e mode) { @@ -77,6 +78,8 @@ int hrtimer_start(FAR hrtimer_t *hrtimer, hrtimer_remove(hrtimer); } + hrtimer->func = func; + /* Compute absolute expiration time */ if (mode == HRTIMER_MODE_ABS) diff --git a/sched/misc/assert.c b/sched/misc/assert.c index 0c89d62a7dfe6..a5cd333d697e1 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -611,7 +611,8 @@ static void dump_deadlock(void) static noreturn_function int pause_cpu_handler(FAR void *arg) { - memcpy(g_last_regs[this_cpu()], running_regs(), sizeof(g_last_regs[0])); + up_regs_memcpy(g_last_regs[this_cpu()], running_regs(), + sizeof(g_last_regs[0])); g_cpu_paused[this_cpu()] = true; up_flush_dcache_all(); while (1); @@ -877,7 +878,8 @@ void _assert(FAR const char *filename, int linenum, } else { - memcpy(g_last_regs[this_cpu()], regs, sizeof(g_last_regs[0])); + up_regs_memcpy(g_last_regs[this_cpu()], regs, sizeof(g_last_regs[0])); + regs = g_last_regs[this_cpu()]; } notifier_data.rtcb = rtcb; diff --git a/sched/sched/sched_get_tls.c b/sched/sched/sched_get_tls.c index db178095d7246..4fb5ce7142864 100644 --- a/sched/sched/sched_get_tls.c +++ b/sched/sched/sched_get_tls.c @@ -75,6 +75,5 @@ FAR char **nxsched_get_stackargs(FAR struct tcb_s *tcb) { /* The args data follows the TLS data */ - return (FAR char**)((FAR char *)tcb->stack_alloc_ptr + - nxsched_get_tls(tcb)->tl_size); + return nxsched_get_tls(tcb)->tl_argv; } diff --git a/sched/sched/sched_processtimer.c b/sched/sched/sched_processtimer.c index 6dbf2d155095f..46d2bce0b2f3b 100644 --- a/sched/sched/sched_processtimer.c +++ b/sched/sched/sched_processtimer.c @@ -49,6 +49,7 @@ * Private Functions ****************************************************************************/ +#ifndef CONFIG_SCHED_TICKLESS /**************************************************************************** * Name: nxsched_cpu_scheduler * @@ -144,18 +145,6 @@ static inline void nxsched_process_scheduler(void) # define nxsched_process_scheduler() #endif -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * System Timer Hooks - * - * These are standard interfaces that are exported by the OS - * for use by the architecture specific logic - * - ****************************************************************************/ - /**************************************************************************** * Name: nxsched_process_timer * @@ -165,6 +154,8 @@ static inline void nxsched_process_scheduler(void) * architecture specific code, but must call the following OS * function periodically -- the calling interval must be * USEC_PER_TICK + * These are standard interfaces that are exported by the OS + * for use by the architecture specific logic * * Input Parameters: * None @@ -204,3 +195,4 @@ void nxsched_process_timer(void) board_timerhook(); #endif } +#endif diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index 1c1785e6d4b8c..cf9f0ff050252 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -92,7 +92,7 @@ static clock_t nxsched_timer_start(clock_t ticks, clock_t interval); static clock_t g_timer_tick; /* This is the duration of the currently active timer or, when - * nxsched_timer_expiration() is called, the duration of interval timer + * nxsched_process_timer() is called, the duration of interval timer * that just expired. The value zero means that no timer was active. */ @@ -373,7 +373,7 @@ static clock_t nxsched_timer_start(clock_t ticks, clock_t interval) ****************************************************************************/ /**************************************************************************** - * Name: nxsched_timer_expiration + * Name: nxsched_process_timer * * Description: * if CONFIG_SCHED_TICKLESS is defined, then this function is provided by @@ -388,7 +388,7 @@ static clock_t nxsched_timer_start(clock_t ticks, clock_t interval) * ****************************************************************************/ -void nxsched_timer_expiration(void) +void nxsched_process_timer(void) { irqstate_t flags; clock_t ticks; diff --git a/sched/signal/sig_default.c b/sched/signal/sig_default.c index 957ce3b2dca22..1d02736232440 100644 --- a/sched/signal/sig_default.c +++ b/sched/signal/sig_default.c @@ -149,6 +149,9 @@ static const struct nxsig_defaction_s g_defactions[] = #ifdef CONFIG_SIG_SIGPOLL_ACTION { SIGPOLL, 0, nxsig_abnormal_termination }, #endif +#ifdef CONFIG_SIG_SIGURG_ACTION + { SIGURG, 0, nxsig_null_action }, +#endif }; #define NACTIONS (sizeof(g_defactions) / sizeof(struct nxsig_defaction_s)) diff --git a/sched/task/task_argvstr.c b/sched/task/task_argvstr.c index a835835ef2647..d4854b7829868 100644 --- a/sched/task/task_argvstr.c +++ b/sched/task/task_argvstr.c @@ -89,11 +89,14 @@ size_t nxtask_argvstr(FAR struct tcb_s *tcb, FAR char *args, size_t size) else #endif { - FAR char **argv = nxsched_get_stackargs(tcb) + 1; + FAR char **argv = nxsched_get_stackargs(tcb); - while (*argv != NULL && n < size) + if (argv++) { - n += snprintf(args + n, size - n, " %s", *argv++); + while (*argv != NULL && n < size) + { + n += snprintf(args + n, size - n, " %s", *argv++); + } } } diff --git a/sched/task/task_setup.c b/sched/task/task_setup.c index c226bdbc27db1..6748392401d13 100644 --- a/sched/task/task_setup.c +++ b/sched/task/task_setup.c @@ -630,6 +630,9 @@ int nxtask_setup_stackargs(FAR struct tcb_s *tcb, stackargv[argc + 1] = NULL; + /* Initialize argv last to avoid accessing the partial initialized fields */ + + nxsched_get_tls(tcb)->tl_argv = stackargv; return OK; } diff --git a/sched/tls/tls_dupinfo.c b/sched/tls/tls_dupinfo.c index de7a4022c090b..0987e9d61703e 100644 --- a/sched/tls/tls_dupinfo.c +++ b/sched/tls/tls_dupinfo.c @@ -70,5 +70,12 @@ int tls_dup_info(FAR struct tcb_s *dst, FAR struct tcb_s *src) /* Attach per-task info in group to TLS */ info->tl_task = dst->group->tg_info; + + /* Initialize the starting address of argv to NULL to prevent + * it from being misused. + */ + + info->tl_argv = NULL; + return OK; } diff --git a/sched/tls/tls_initinfo.c b/sched/tls/tls_initinfo.c index bf7227fd1a519..c38704a19cf93 100644 --- a/sched/tls/tls_initinfo.c +++ b/sched/tls/tls_initinfo.c @@ -78,5 +78,11 @@ int tls_init_info(FAR struct tcb_s *tcb) info->tl_tid = tcb->pid; + /* Initialize the starting address of argv to NULL to prevent + * it from being misused. + */ + + info->tl_argv = NULL; + return OK; } diff --git a/tools/checkkconfig.py b/tools/checkkconfig.py new file mode 100755 index 0000000000000..74c5c0415c42c --- /dev/null +++ b/tools/checkkconfig.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python3 +# tools/checkkconfig.py +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +# +# [checkkconfig.py] is a tool that simulates the effects of modifying a CONFIG item, +# Can be used to check whether my config changes are what I expected. +# +# usage: checkkconfig.py [-h] -f FILE (-s CONFIG VALUE | -d DIFF) +# +# optional arguments: +# -h, --help show this help message and exit +# -f FILE, --file FILE Path to the input defconfig file +# -s CONFIG_XXX VALUE, --single CONFIG VALUE +# Analyze single change: CONFIG_NAME y/m/n +# -d DIFF, --diff DIFF Analyze changes from diff file +# +# example: ./tools/checkkconfig.py -f defconfig -s ELF n +# +# outputs: +# Change report for ELF=n +# Config Option Old New +# ---------------------------------------------------------------------- +# BINFMT_LOADABLE y n +# ELF y n +# ELF_STACKSIZE 8192 +# LIBC_ARCH_ELF y n +# LIBC_MODLIB y n +# MODLIB_ALIGN_LOG2 2 +# MODLIB_BUFFERINCR 32 +# MODLIB_BUFFERSIZE 32 +# MODLIB_MAXDEPEND 2 +# MODLIB_RELOCATION_BUFFERCOUNT 256 +# MODLIB_SYMBOL_CACHECOUNT 256 +# +# As we can see, we can clearly know that +# if I turn off ELF in defconfig at this time, +# it will bring about the following configuration linkage changes +# +# It can also parse diff files, which can be used to check the changes of multiple configs. +# diff file example: +# diff --git a/boards/demo/configs/nsh/defconfig b/boards/demo/configs/nsh/defconfig +# index cf7d07c..5de20d4 100644 +# --- a/boards/demo/configs/nsh/defconfig +# +++ b/boards/demo/configs/nsh/defconfig +# @@ -51,7 +51,6 @@ CONFIG_ARMV7A_STRING_FUNCTION=y +# CONFIG_ARM_PSCI=y +# CONFIG_ARM_SEMIHOSTING_HOSTFS=y +# CONFIG_ARM_THUMB=y +# -CONFIG_AUDIO=y +# CONFIG_BCH=y +# CONFIG_BINFMT_ELF_EXECUTABLE=y +# CONFIG_BLUETOOTH=y +# @@ -104,7 +103,6 @@ CONFIG_DRIVERS_VIRTIO_SERIAL=y +# CONFIG_DRIVERS_VIRTIO_SOUND=y +# CONFIG_DRIVERS_WIFI_SIM=y +# CONFIG_DRIVERS_WIRELESS=y +# -CONFIG_ELF=y +# CONFIG_ETC_ROMFS=y +# CONFIG_EVENT_FD=y +# CONFIG_EXAMPLES_FB=y +# +# example: ./tools/checkkconfig.py -f defconfig -d changes.diff +# +# outputs: +# Change report for diff: changes.diff +# Config Option Old New +# ---------------------------------------------------------------------- +# AUDIO y n +# AUDIO_BUFFER_NUMBYTES 8192 +# AUDIO_EXCLUDE_EQUALIZER y n +# AUDIO_EXCLUDE_REWIND y n +# AUDIO_FORMAT_AMR y n +# AUDIO_FORMAT_MP3 y n +# AUDIO_FORMAT_OPUS y n +# AUDIO_FORMAT_PCM y n +# AUDIO_FORMAT_SBC y n +# AUDIO_NUM_BUFFERS 2 +# BINFMT_LOADABLE y n +# ELF y n +# ELF_STACKSIZE 8192 +# LIBC_ARCH_ELF y n +# LIBC_MODLIB y n +# MODLIB_ALIGN_LOG2 2 +# MODLIB_BUFFERINCR 32 +# MODLIB_BUFFERSIZE 32 +# MODLIB_MAXDEPEND 2 +# MODLIB_RELOCATION_BUFFERCOUNT 256 +# MODLIB_SYMBOL_CACHECOUNT 256 +# NXPLAYER_COMMAND_LINE y n +# NXPLAYER_DEFAULT_MEDIADIR /music +# NXPLAYER_FMT_FROM_EXT y n +# NXPLAYER_INCLUDE_DEVICE_SEARCH y n +# NXPLAYER_INCLUDE_HELP y n +# NXPLAYER_INCLUDE_MEDIADIR y n +# NXPLAYER_INCLUDE_PREFERRED_DEVICE y n +# NXPLAYER_MAINTHREAD_STACKSIZE 8192 +# NXPLAYER_PLAYTHREAD_STACKSIZE 8192 +# NXRECORDER_COMMAND_LINE y n +# NXRECORDER_FMT_FROM_EXT y n +# NXRECORDER_INCLUDE_HELP y n +# NXRECORDER_MAINTHREAD_STACKSIZE 8192 +# NXRECORDER_RECORDTHREAD_STACKSIZE 8192 +# SYSTEM_NXPLAYER y n +# SYSTEM_NXRECORDER y n +# +# +# RECAUTION: +# Because NuttX apps Kconfig of menu is generated by build system, +# and arch/board bridge Kconfig is symlink to real arch board dir. +# So it is best to check the defconfig that has been configured. +# If the environment does not generate Kconfig menu, etc. +# the tool will execute `configure.sh` and distclean at the end. +# + +import argparse +import os +import re +import subprocess +import sys +from pathlib import Path + +try: + from kconfiglib import Kconfig +except ImportError: + print( + "ERROR: checkkconfig tool depends on kconfiglib for parse Kconfig tree.\nplease install it.\npip install kconfiglib", + file=sys.stderr, + ) + sys.exit(1) + +TOPDIR = Path(__file__).resolve().parent.parent +DPATH = Path("defconfig") +NEED_RESET = False + + +# Prepare environment for Kconfig +def prepare_env(): + global NEED_RESET + # check if we are in the configured Kconfig environment + full_config_file = TOPDIR / Path(".config") + if not full_config_file.exists(): + print("apps preconfig do not generate yet \nrun configure.sh first") + result = subprocess.run( + [f"{TOPDIR}/tools/configure.sh", "-e", f"{str(DPATH.parent)}"], + capture_output=True, + text=True, + ) + if result.returncode != 0: + print( + f"ERROR: {TOPDIR}/tools/configure.sh run fail\n configure path: {str(DPATH.parent)}", + file=sys.stderr, + ) + print(f"STDERROR:{result.stderr}", file=sys.stderr) + sys.exit(1) + NEED_RESET = True + os.environ["APPSDIR"] = "../apps" + os.environ["APPSBINDIR"] = "../apps" + os.environ["EXTERNALDIR"] = "dummy" + os.environ["BINDIR"] = str(TOPDIR) + os.environ["KCONFIG_CONFIG"] = str(DPATH) + + +# Reset environment to previous +def reset_env(): + os.environ.pop("APPSDIR", None) + os.environ.pop("APPSBINDIR", None) + os.environ.pop("EXTERNALDIR", None) + os.environ.pop("BINDIR", None) + os.environ.pop("KCONFIG_CONFIG", None) + if NEED_RESET: + result = subprocess.run( + ["make", "distclean"], cwd=TOPDIR, capture_output=True, text=True + ) + print(result.stdout) + if result.returncode != 0: + print( + "ERROR: distclean error please clean up your workspace manually", + file=sys.stderr, + ) + print(f"STDERROR:{result.stderr}", file=sys.stderr) + + +# Parse a diff file and return a dict of changes +def parse_diff(diff_path): + changes = {} + diff_pattern = re.compile(r"^([+-])CONFIG_(\w+)=([ymn])$") + with open(diff_path, "r") as f: + for line in f: + line = line.strip() + + match = diff_pattern.match(line) + if not match: + continue + + op, name, value = match.groups() + full_name = f"{name}" + + if op == "-": + changes[full_name] = "n" + elif op == "+": + changes[full_name] = value.lower() + return changes + + +# Apply a set of changes to a Kconfig tree and return a list of changed symbols +def apply_changes(kconf, changes): + + # step 1: keep track of original values + orig_state = {sym.name: sym.str_value for sym in kconf.defined_syms} + + # step 2: apply the config settings + value_map = {"n": 0, "m": 1, "y": 2} + for target, value in changes.items(): + sym = kconf.syms.get(target) + if not sym: + print(f"Warning: {target} not found, skipped") + continue + if value not in value_map: + print(f"Invalid value {value} for {target}, skipped") + continue + sym.set_value(value_map[value]) + + # step 3: check for changes + changed = [] + for sym in kconf.defined_syms: + orig = orig_state.get(sym.name, "") + curr = sym.str_value + if orig != curr: + changed.append((sym.name, orig, curr)) + + return changed + + +def track_single_change(target, value): + kconf = Kconfig() + kconf.load_config() + return apply_changes(kconf, {target: value}) + + +def track_diff_changes(diff_path): + kconf = Kconfig() + kconf.load_config() + changes = parse_diff(diff_path) + return apply_changes(kconf, changes) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "-f", "--file", required=True, help="Path to the input defconfig file" + ) + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument( + "-s", + "--single", + nargs=2, + metavar=("CONFIG", "VALUE"), + help="Analyze single change: CONFIG_NAME y/m/n", + ) + group.add_argument("-d", "--diff", help="Analyze changes from diff file") + + args = parser.parse_args() + + DPATH = Path(args.file) + + if not DPATH.is_absolute(): + DPATH = TOPDIR / DPATH + + if not DPATH.exists: + print("ERROR: defconfig file DO NOT exist", file=sys.stderr) + sys.exit(1) + + prepare_env() + + if args.single: + target, value = args.single + changes = track_single_change(target, value.lower()) + title = f"Change report for {target}={value}" + elif args.diff: + changes = track_diff_changes(args.diff) + title = f"Change report for diff: {args.diff}" + + reset_env() + + print(f"\n{title}") + print(f"{'Config Option':<40} {'Old':<20} {'New':<20}") + print("-" * 70) + for name, old, new in sorted(changes, key=lambda x: x[0]): + print(f"{name:<40} {old or '':<20} {new or '':<20}") diff --git a/tools/nxstyle.c b/tools/nxstyle.c index 58094557a1e03..b6b9c81ebf6a6 100644 --- a/tools/nxstyle.c +++ b/tools/nxstyle.c @@ -223,6 +223,10 @@ static const char *g_white_prefix[] = "Http", /* Ref: apps/netutils/xedge/BAS/examples/xedge/src/xedge.h */ "Disk", /* Ref: apps/netutils/xedge/BAS/examples/xedge/src/xedge.h */ "Xedge", /* Ref: apps/netutils/xedge/BAS/examples/xedge/src/xedge.h */ + "tAddr", /* Ref: arch/tricore/src */ + "tClass", /* Ref: arch/tricore/src */ + "tCpu", /* Ref: arch/tricore/src */ + "tId", /* Ref: arch/tricore/src */ NULL }; diff --git a/tools/process_config.py b/tools/process_config.py old mode 100644 new mode 100755 index dc2894f21d953..4ba405049abc5 --- a/tools/process_config.py +++ b/tools/process_config.py @@ -19,52 +19,157 @@ # under the License. # +import json +import os import re +import shutil import sys +from collections import OrderedDict from pathlib import Path -def expand_file(input_path, include_paths, processed=None): +def parse_config_line(line): """ - Recursively expand the file, returning its contents in order as a list of lines. + Parse a configuration line and return the key and value. + + Args: + line (str): A line from a configuration file + + Returns: + tuple: (key, value) if the line contains a configuration, (None, None) otherwise + + Handles two formats: + 1. "# CONFIG_XXX is not set" -> returns (CONFIG_XXX, 'n') + 2. "CONFIG_XXX=value" -> returns (CONFIG_XXX, value) + """ + line = line.strip() + if not line: + return None, None + + # Handle "# CONFIG_XXX is not set" format + if line.startswith("# ") and line.endswith(" is not set"): + config_name = line.split()[1] + return config_name, "n" + + # Handle "CONFIG_XXX=value" format + if "=" in line: + key, value = line.split("=", 1) + return key, value + + return None, None + + +def opposite(value): + if value == "n": + return "y" + else: + return "n" + + +def expand_file(input_path, include_paths, processed=None, tree_node=None): + """ + Recursively expand a configuration file with #include directives. + + Args: + input_path (str): Path to the input configuration file + include_paths (list): List of directories to search for included files + processed (set, optional): Set of already processed files to avoid circular includes + tree_node (dict, optional): Node in the configuration tree being built + + Returns: + tuple: (list of expanded lines, tree structure node) + + This function: + 1. Reads the input file line by line + 2. Processes #include directives by recursively expanding included files + 3. Parses configuration lines to build a configuration dictionary + 4. Builds a tree structure representing the file inclusion hierarchy + 5. Returns the expanded content and the tree structure """ if processed is None: processed = set() + if tree_node is None: + tree_node = { + "file": str(input_path), + "includes": [], + "configs": OrderedDict(), + "include_lines": [], + "raw_content": [], # Store original content for postprocessing + } input_path = Path(input_path).resolve() if input_path in processed: - return [] # Already processed, avoid duplicate includes + return [], tree_node processed.add(input_path) expanded_lines = [] + current_configs = OrderedDict() with input_path.open("r", encoding="utf-8") as f: lines = f.readlines() + # Save original content for postprocessing + tree_node["raw_content"] = [line.rstrip("\n") for line in lines] + for line in lines: line_strip = line.strip() - match = re.match(r'#include\s*[<"]([^">]+)[">]', line_strip) + match = re.match(r"#include\s*[<\"]([^\">]+)[\">]", line_strip) if match: include_file = match.group(1) found = False - # Check the current directory first + # Record original include line for postprocessing + tree_node["include_lines"].append(line.rstrip("\n")) + # Check current directory first direct_path = input_path.parent / include_file if direct_path.exists(): - expanded_lines.extend( - expand_file(direct_path, include_paths, processed) + include_node = { + "file": str(direct_path), + "includes": [], + "configs": OrderedDict(), + "include_lines": [], + "raw_content": [], + } + tree_node["includes"].append(include_node) + + # Recursively expand the included file + included_lines, include_node = expand_file( + direct_path, include_paths, processed, include_node ) + expanded_lines.extend(included_lines) + + # Merge configurations (later configurations override earlier ones) + for key, value in include_node["configs"].items(): + current_configs[key] = value + tree_node["configs"][key] = value + found = True else: - # Then check in the include paths - + # Check include paths for path in include_paths: candidate = Path(path) / include_file if candidate.exists(): - expanded_lines.extend( - expand_file(candidate, include_paths, processed) + include_node = { + "file": str(candidate), + "includes": [], + "configs": OrderedDict(), + "include_lines": [], + "raw_content": [], + } + tree_node["includes"].append(include_node) + + # Recursively expand the included file + included_lines, include_node = expand_file( + candidate, include_paths, processed, include_node ) + expanded_lines.extend(included_lines) + + # Merge configurations + for key, value in include_node["configs"].items(): + current_configs[key] = value + tree_node["configs"][key] = value + found = True break @@ -75,31 +180,352 @@ def expand_file(input_path, include_paths, processed=None): ) sys.exit(1) else: + # Parse configuration line + key, value = parse_config_line(line) + if key is not None: + current_configs[key] = value + tree_node["configs"][key] = value expanded_lines.append(line) - expanded_lines.append("\n") # Keep separation between files - return expanded_lines + expanded_lines.append("\n") # Maintain separation between files + return expanded_lines, tree_node + + +def preprocess(output_path, input_path, include_paths, tree_output_path=None): + """ + Process a configuration file with #include directives. + + Args: + output_path (str): Path to write the expanded configuration + input_path (str): Path to the input configuration file + include_paths (list): List of directories to search for included files + tree_output_path (str, optional): Path to write the tree structure + This function: + 1. Expands the input file by processing #include directives + 2. Writes the expanded configuration to output_path + 3. Optionally writes the tree structure to tree_output_path for postprocessing + """ + lines, tree = expand_file(input_path, include_paths) -def process_file(output_path, input_path, include_paths): - lines = expand_file(input_path, include_paths) + # Write expanded configuration with open(output_path, "w", encoding="utf-8") as out: out.writelines(lines) + # Write tree structure if requested + if tree_output_path and tree["includes"]: + with open(tree_output_path, "w", encoding="utf-8") as f: + json.dump(tree, f, indent=2, ensure_ascii=False) + + +def get_all_included_configs(tree): + """ + Extract all configuration options from included files. + + Args: + tree (dict): The configuration tree structure + + Returns: + OrderedDict: Dictionary of configuration options from all included files + + This function recursively traverses the tree to collect all configurations + from files included via #include directives. + """ + included_configs = OrderedDict() + + def collect_configs(node): + for include in node.get("includes", []): + collect_configs(include) + for key, value in node.get("configs", {}).items(): + included_configs[key] = value + + # Collect configurations from included files only (not the main file) + for include in tree.get("includes", []): + collect_configs(include) + + return included_configs + + +def get_main_configs(tree): + """ + Extract configuration options from the main file (excluding #include directives). + + Args: + tree (dict): The configuration tree structure + + Returns: + OrderedDict: Dictionary of configuration options from the main file + """ + main_configs = OrderedDict() + for line in tree["raw_content"]: + key, value = parse_config_line(line) + if key is not None: + main_configs[key] = value + return main_configs + + +def get_current_configs(config_path): + """ + Parse the current full configuration file. + + Args: + config_path (str): Path to the current configuration file + + Returns: + OrderedDict: Dictionary of configuration options from the current file + """ + configs = OrderedDict() + with open(config_path, "r", encoding="utf-8") as f: + for line in f: + key, value = parse_config_line(line) + if key is not None: + configs[key] = value + return configs + + +def postprocess_inner(tree_path, added, changed, removed, output_path): + """ + Postprocess configuration changes to generate a defconfig with #include directives. + + This function takes the specific changes (added, changed, removed) calculated + by postprocess and applies them to the original defconfig structure + represented by the tree, producing a new defconfig file. + + Args: + tree_path (str): Path to the config_tree.json generated during preprocessing of the ORIGINAL defconfig. + added (dict): {key: value} - Configurations added by the user. + changed (dict): {key: (old_value, new_value)} - Configurations changed by the user. + removed (dict): {key: old_value} - Configurations removed by the user. + output_path (str): Path where the new defconfig should be written. + """ + # 1. Load the original tree structure (this represents the structure of the ORIGINAL defconfig) + with open(tree_path, "r", encoding="utf-8") as f: + original_tree = json.load(f, object_pairs_hook=OrderedDict) + + # 2. Get the original configuration sets from the tree + original_included_configs = get_all_included_configs(original_tree) + original_main_configs = get_main_configs(original_tree) + + # 3. Dictionary to store the final configurations that will go into the main defconfig file + final_main_configs = OrderedDict() + + # --- Logic to determine final content of the main defconfig file --- + + # a. Handle configurations that were originally in included files + # We only place them in the main defconfig if they were explicitly added/changed/removed. + # If untouched, they remain in their included files implicitly. + for key in original_included_configs: + if key in added: + # User added/changed a config that was originally in an included file. + # It must now be explicitly set in the main defconfig to override the included value. + final_main_configs[key] = added[key] + elif key in changed: + # User changed a config that was originally in an included file. + final_main_configs[key] = changed[key][1] # Use the new value + elif key in removed: + # User removed a config that was originally in an included file. + # To "remove" it, we explicitly set it to opposite orig value in the main defconfig. + # This overrides the value from the included file. + final_main_configs[key] = opposite(removed[key]) + + # b. Handle configurations that were originally in the main file + # They should generally stay represented in the main file output. + for key in original_main_configs: + if key in added: + # User added/changed a config that was already in the main file. + final_main_configs[key] = added[key] + elif key in changed: + # User changed a config that was in the main file. + final_main_configs[key] = changed[key][1] # Use the new value + elif key in removed: + # User removed a config that was in the main file. + # Explicitly set to opposite orig value to override its previous state. + final_main_configs[key] = opposite(removed[key]) + else: + # Config was in the original main file and user did NOT touch it. + # According to the new logic, we should PRESERVE these in the output main defconfig + # to maintain the structure and non-default values from the original main file. + # This prevents the output from becoming sparse if the user only made minor changes. + final_main_configs[key] = original_main_configs[key] + + # c. Handle configurations that are entirely new (not present in original main or included) + # These must go into the main defconfig file. + for key, value in added.items(): + if key not in original_main_configs and key not in original_included_configs: + final_main_configs[key] = value + + # 4. Write the final output defconfig file + with open(output_path, "w", encoding="utf-8") as f: + # Write the original #include directives to preserve the structure + for include_line in original_tree.get("include_lines", []): + f.write(include_line + "\n") + + # Add a newline for separation if there were includes + if original_tree.get("include_lines"): + f.write("\n") + + # Write the final configurations for the main file in sorted order + final_write_list = [] + for key, value in final_main_configs.items(): + if value == "n": + final_write_list.append(f"# {key} is not set\n") + else: + final_write_list.append(f"{key}={value}\n") + + # Sort configurations for consistent and readable output + final_write_list.sort() + for write_line in final_write_list: + f.write(write_line) + + +def get_config_diff(old_config, new_config): + """ + Compare two config dictionaries and return the differences. + + Args: + old_config (dict): The original configuration. + new_config (dict): The modified configuration. + + Returns: + tuple: (added, changed, removed) + added (dict): Items in new_config but not in old_config. + changed (dict): Items with different values. {key: (old_value, new_value)}. + removed (dict): Items in old_config but not in new_config. + """ + added = {} + changed = {} + removed = {} + + # Find added and changed items + for key, new_value in new_config.items(): + if key not in old_config: + added[key] = new_value + elif old_config[key] != new_value: + changed[key] = (old_config[key], new_value) # (old_value, new_value) + + # Find removed items + for key in old_config: + if key not in new_config: + removed[key] = old_config[key] + + return added, changed, removed + + +def load_config_file(filepath): + """ + Load a .config or defconfig file into an OrderedDict. + """ + config = OrderedDict() + try: + with open(filepath, "r") as f: + for line in f: + key, value = parse_config_line(line) + if key is not None: + config[key] = value + except FileNotFoundError: + print( + f"Warning: Config file {filepath} not found. Treating as empty.", + file=sys.stderr, + ) + return config + + +def postprocess( + tree_path, original_defconfig_path, modified_defconfig_path, output_defconfig_path +): + """ + An improved postprocess that compares defconfig files before and after modification. + + This function addresses the issue where Kconfig's savedefconfig omits default values, + making it hard to distinguish user deletions from optimizations. + + Args: + tree_path (str): Path to the config_tree.json generated during preprocessing. + original_defconfig_path (str): Path to the defconfig file BEFORE user modification. + modified_defconfig_path (str): Path to the defconfig file AFTER user modification. + output_defconfig_path (str): Path where the updated defconfig should be written. + """ + # 1. Load the defconfig files + defconfig_original = load_config_file(original_defconfig_path) + defconfig_modified = load_config_file(modified_defconfig_path) + + # 2. Compare the defconfig files to find the actual user changes + added, changed, removed = get_config_diff(defconfig_original, defconfig_modified) + + # 3. Use the new postprocess_inner function to generate the final defconfig + # Pass the calculated differences (added, changed, removed) and the original tree. + postprocess_inner(tree_path, added, changed, removed, output_defconfig_path) + if __name__ == "__main__": if len(sys.argv) < 3: print( - "Usage: process_includes.py [include_paths...]", + "Usage: process_config.py [options]", + file=sys.stderr, + ) + print("Modes:", file=sys.stderr) + print( + " preprocess [include_paths...] [--tree ]", + file=sys.stderr, + ) + print( + " postprocess ", file=sys.stderr, ) sys.exit(1) - output_file = Path(sys.argv[1]) - input_file = sys.argv[2] - include_dirs = sys.argv[3:] + mode = sys.argv[1] - if output_file.exists(): - output_file.unlink() + if mode == "preprocess": + if len(sys.argv) < 4: + print( + "Usage: preprocess [include_paths...] [--tree ]", + file=sys.stderr, + ) + sys.exit(1) + + output_file = Path(sys.argv[2]) + input_file = sys.argv[3] + include_dirs = [] + tree_file = None + + # Parse arguments + i = 4 + while i < len(sys.argv): + if sys.argv[i] == "--tree" and i + 1 < len(sys.argv): + tree_file = sys.argv[i + 1] + i += 2 + else: + include_dirs.append(sys.argv[i]) + i += 1 - process_file(output_file, input_file, include_dirs) + if output_file.exists(): + output_file.unlink() + + preprocess(output_file, input_file, include_dirs, tree_file) + + elif mode == "postprocess": + if len(sys.argv) < 6: + print( + "Usage: postprocess ", + file=sys.stderr, + ) + sys.exit(1) + + tree_file = sys.argv[2] + original_defconfig = sys.argv[3] + modified_defconfig = sys.argv[4] + output_defconfig = sys.argv[5] + if Path(tree_file).is_file(): + post_defconfig = output_defconfig + "tmp" + postprocess( + tree_file, original_defconfig, modified_defconfig, post_defconfig + ) + shutil.copy2(post_defconfig, output_defconfig) + os.remove(post_defconfig) + else: + shutil.copy2(modified_defconfig, output_defconfig) + + else: + print(f"Unknown mode: {mode}", file=sys.stderr) + sys.exit(1)