diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f3895a22cc..64c0f1f8ef5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1617,10 +1617,9 @@ list(APPEND ) list(APPEND post_build_byproducts ${KERNEL_MAP_NAME}) -if(NOT CONFIG_BUILD_NO_GAP_FILL) - # Use ';' as separator to get proper space in resulting command. - set(GAP_FILL "$0xff") -endif() +# Use ';' as separator to get proper space in resulting command. +set(gap_fill_prop "$") +set(gap_fill "$<$:${gap_fill_prop}${CONFIG_BUILD_GAP_FILL_PATTERN}>") if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE) target_link_libraries(${logical_target_for_zephyr_elf} $) @@ -1681,7 +1680,7 @@ if(CONFIG_BUILD_OUTPUT_HEX OR BOARD_FLASH_RUNNER STREQUAL openocd) post_build_commands COMMAND $ $ - ${GAP_FILL} + $<$:${gap_fill}> $ihex ${remove_sections_argument_list} $${KERNEL_ELF_NAME} @@ -1703,7 +1702,7 @@ if(CONFIG_BUILD_OUTPUT_BIN) post_build_commands COMMAND $ $ - ${GAP_FILL} + ${gap_fill} $binary ${remove_sections_argument_list} $${KERNEL_ELF_NAME} @@ -1790,7 +1789,7 @@ if(CONFIG_BUILD_OUTPUT_S19) post_build_commands COMMAND $ $ - ${GAP_FILL} + $<$:${gap_fill}> $srec $1 $${KERNEL_ELF_NAME} @@ -2233,6 +2232,8 @@ add_subdirectory_ifdef( cmake/makefile_exports ) +toolchain_linker_finalize() + yaml_context(EXISTS NAME build_info result) if(result) build_info(zephyr version VALUE ${PROJECT_VERSION_STR}) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 68abf89b42f..510769d8aa7 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -706,8 +706,21 @@ config CLEANUP_INTERMEDIATE_FILES from the build process. Note this breaks incremental builds, west spdx (Software Bill of Material generation), and maybe others. +config BUILD_GAP_FILL_PATTERN + hex "Gap fill pattern" + default 0xFF + help + Pattern used for gap filling of output files. + This value should be set to the value of a clean flash as this can + significantly reduce flash write times. + This setting only defines the gap fill pattern and doesn't enable gap + filling. + Note: binary files are always gap filled as they contain no address + information. + config BUILD_NO_GAP_FILL - bool "Don't fill gaps in generated hex/bin/s19 files." + bool "Don't fill gaps in generated hex/s19 files [DEPRECATED]." + select DEPRECATED config BUILD_OUTPUT_HEX bool "Build a binary in HEX format" @@ -715,6 +728,12 @@ config BUILD_OUTPUT_HEX Build an Intel HEX binary zephyr/zephyr.hex in the build directory. The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. +config BUILD_OUTPUT_HEX_GAP_FILL + bool "Fill gaps in hex files" + depends on !BUILD_NO_GAP_FILL + help + Fill gaps in hex based files. + config BUILD_OUTPUT_BIN bool "Build a binary in BIN format" default y @@ -749,6 +768,12 @@ config BUILD_OUTPUT_S19 Build an S19 binary zephyr/zephyr.s19 in the build directory. The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. +config BUILD_OUTPUT_S19_GAP_FILL + bool "Fill gaps in s19 files" + depends on !BUILD_NO_GAP_FILL + help + Fill gaps in s19 based files. + config BUILD_OUTPUT_UF2 bool "Build a binary in UF2 format" depends on BUILD_OUTPUT_BIN diff --git a/cmake/bintools/llvm/target_bintools.cmake b/cmake/bintools/llvm/target_bintools.cmake index cd3d55342b5..f310d57bf2b 100644 --- a/cmake/bintools/llvm/target_bintools.cmake +++ b/cmake/bintools/llvm/target_bintools.cmake @@ -44,11 +44,8 @@ set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "--remove-s set_property(TARGET bintools PROPERTY elfconvert_flag_section_only "--only-section=") set_property(TARGET bintools PROPERTY elfconvert_flag_section_rename "--rename-section;") -# Note, placing a ';' at the end results in the following param to be a list, -# and hence space separated. -# Thus the command line argument becomes: -# `--gap-file ` instead of `--gap-fill` (The latter would result in an error) -set_property(TARGET bintools PROPERTY elfconvert_flag_gapfill "--gap-fill;") +# llvm-objcopy doesn't support gap fill argument. +set_property(TARGET bintools PROPERTY elfconvert_flag_gapfill "") set_property(TARGET bintools PROPERTY elfconvert_flag_srec_len "--srec-len=") set_property(TARGET bintools PROPERTY elfconvert_flag_infile "") diff --git a/cmake/compiler/clang/compiler_flags.cmake b/cmake/compiler/clang/compiler_flags.cmake index acc9b629171..a64150eb58c 100644 --- a/cmake/compiler/clang/compiler_flags.cmake +++ b/cmake/compiler/clang/compiler_flags.cmake @@ -125,3 +125,5 @@ set_compiler_property(PROPERTY warning_error_coding_guideline ) set_compiler_property(PROPERTY no_global_merge "-mno-global-merge") + +set_compiler_property(PROPERTY specs) diff --git a/cmake/compiler/clang/target.cmake b/cmake/compiler/clang/target.cmake index 30e5da399af..62c39b0ec6f 100644 --- a/cmake/compiler/clang/target.cmake +++ b/cmake/compiler/clang/target.cmake @@ -64,6 +64,42 @@ if(NOT "${ARCH}" STREQUAL "posix") endif() endif() + # LLVM will use a default sysroot for selection of the C library. The default + # C library sysroot was defined at built time of clang/LLVM. + # + # For example, LLVM for Arm comes pre-built with Picolibc, and thus no flags + # are required for selecting Picolibc. + # + # Other clang/LLVM distributions may come with other pre-built C libraries. + # clang/LLVM supports using an alternative C library, either by direct linking, + # or by specifying '--sysroot '. + # + # LLVM for Arm provides a 'newlib.cfg' file for newlib C selection. + # Let us support this principle by looking for a dedicated 'newlib.cfg' or + # 'picolibc.cfg' and specify '--config .cfg' if such a file is found. + # If no cfg-file matching the chosen C implementation, then we assume that the + # chosen C implementation is identical to the default C library used be the + # toolchain. + if(CONFIG_NEWLIB_LIBC) + file(GLOB_RECURSE newlib_cfg ${LLVM_TOOLCHAIN_PATH}/newlib.cfg) + if(newlib_cfg) + list(GET newlib_cfg 0 newlib_cfg) + set_linker_property(PROPERTY c_library "--config=${newlib_cfg};-lc") + list(APPEND CMAKE_REQUIRED_FLAGS --config=${newlib_cfg}) + list(APPEND TOOLCHAIN_C_FLAGS --config=${newlib_cfg}) + endif() + endif() + + if(CONFIG_PICOLIBC) + file(GLOB_RECURSE picolibc_cfg ${LLVM_TOOLCHAIN_PATH}/picolibc.cfg) + if(picolibc_cfg) + list(GET picolibc_cfg 0 picolibc_cfg) + set_linker_property(PROPERTY c_library "--config=${picolibc_cfg};-lc") + list(APPEND CMAKE_REQUIRED_FLAGS --config=${picolibc_cfg}) + list(APPEND TOOLCHAIN_C_FLAGS --config=${picolibc_cfg}) + endif() + endif() + # This libgcc code is partially duplicated in compiler/*/target.cmake execute_process( COMMAND ${CMAKE_C_COMPILER} ${clang_target_flag} ${TOOLCHAIN_C_FLAGS} @@ -76,8 +112,8 @@ if(NOT "${ARCH}" STREQUAL "posix") get_filename_component(RTLIB_NAME_WITH_PREFIX ${RTLIB_FILE_NAME} NAME_WLE) string(REPLACE lib "" RTLIB_NAME ${RTLIB_NAME_WITH_PREFIX}) - list(APPEND LIB_INCLUDE_DIR -L${RTLIB_DIR}) - list(APPEND TOOLCHAIN_LIBS ${RTLIB_NAME}) + set_property(TARGET linker PROPERTY lib_include_dir "-L${RTLIB_DIR}") + set_property(TARGET linker PROPERTY rt_library "-l${RTLIB_NAME}") list(APPEND CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags}) string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") diff --git a/cmake/compiler/compiler_flags_template.cmake b/cmake/compiler/compiler_flags_template.cmake index c72e9b70f5d..5a4386f49be 100644 --- a/cmake/compiler/compiler_flags_template.cmake +++ b/cmake/compiler/compiler_flags_template.cmake @@ -139,3 +139,7 @@ set_compiler_property(PROPERTY warning_shadow_variables) # Compiler flags to avoid recognizing built-in functions set_compiler_property(PROPERTY no_builtin) set_compiler_property(PROPERTY no_builtin_malloc) + +# Compiler flag for defining specs. Used only by gcc, other compilers may keep +# this undefined. +set_compiler_property(PROPERTY specs) diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake index e982f75aa78..c346a750af4 100644 --- a/cmake/compiler/gcc/compiler_flags.cmake +++ b/cmake/compiler/gcc/compiler_flags.cmake @@ -241,3 +241,5 @@ set_compiler_property(PROPERTY warning_shadow_variables -Wshadow) set_compiler_property(PROPERTY no_builtin -fno-builtin) set_compiler_property(PROPERTY no_builtin_malloc -fno-builtin-malloc) + +set_compiler_property(PROPERTY specs -specs=) diff --git a/cmake/compiler/gcc/target.cmake b/cmake/compiler/gcc/target.cmake index 5b1e5db1218..7e8ffc48173 100644 --- a/cmake/compiler/gcc/target.cmake +++ b/cmake/compiler/gcc/target.cmake @@ -109,8 +109,7 @@ get_filename_component(LIBGCC_DIR ${LIBGCC_FILE_NAME} DIRECTORY) assert_exists(LIBGCC_DIR) -LIST(APPEND LIB_INCLUDE_DIR "-L\"${LIBGCC_DIR}\"") -LIST(APPEND TOOLCHAIN_LIBS gcc) +set_linker_property(PROPERTY lib_include_dir "-L\"${LIBGCC_DIR}\"") # For CMake to be able to test if a compiler flag is supported by the # toolchain we need to give CMake the necessary flags to compile and diff --git a/cmake/linker/armlink/linker_flags.cmake b/cmake/linker/armlink/linker_flags.cmake deleted file mode 100644 index b0f93a7b9e7..00000000000 --- a/cmake/linker/armlink/linker_flags.cmake +++ /dev/null @@ -1,6 +0,0 @@ -# The ARMClang linker, armlink, requires a dedicated linking signature in -# order for Zephyr to control the map file. - -set(CMAKE_C_LINK_EXECUTABLE " -o ") -set(CMAKE_CXX_LINK_EXECUTABLE " -o ") -set(CMAKE_ASM_LINK_EXECUTABLE " -o ") diff --git a/cmake/linker/armlink/linker_libraries.cmake b/cmake/linker/armlink/linker_libraries.cmake new file mode 100644 index 00000000000..8374e7c3cd2 --- /dev/null +++ b/cmake/linker/armlink/linker_libraries.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# Per default armclang (Arm Compiler 6) doesn't need explicit C library linking +# so we only need to set link order linking in case a custom C library is linked +# in, such as picolibc. +set_property(TARGET linker APPEND PROPERTY link_order_library "c;rt") diff --git a/cmake/linker/armlink/target.cmake b/cmake/linker/armlink/target.cmake index 9aa32ad0e6f..b2e1e867f90 100644 --- a/cmake/linker/armlink/target.cmake +++ b/cmake/linker/armlink/target.cmake @@ -108,5 +108,23 @@ function(toolchain_ld_link_elf) ) endfunction(toolchain_ld_link_elf) +# This function will generate the correct CMAKE_C_LINK_EXECUTABLE / CMAKE_CXX_LINK_EXECUTABLE +# rule to ensure that standard c and runtime libraries are correctly placed +# and the end of link invocation and doesn't appear in the middle of the link +# command invocation. +macro(toolchain_linker_finalize) + set(zephyr_std_libs) + get_property(link_order TARGET linker PROPERTY link_order_library) + foreach(lib ${link_order}) + get_property(link_flag TARGET linker PROPERTY ${lib}_library) + set(zephyr_std_libs "${zephyr_std_libs} ${link_flag}") + endforeach() + + set(common_link " ${zephyr_std_libs} -o ") + set(CMAKE_C_LINK_EXECUTABLE " ${common_link}") + set(CMAKE_CXX_LINK_EXECUTABLE " ${common_link}") + set(CMAKE_ASM_LINK_EXECUTABLE " ${common_link}") +endmacro() + include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake) include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake) diff --git a/cmake/linker/ld/gcc/linker_flags.cmake b/cmake/linker/ld/gcc/linker_flags.cmake index 4cde7d96ff3..c442c9c8921 100644 --- a/cmake/linker/ld/gcc/linker_flags.cmake +++ b/cmake/linker/ld/gcc/linker_flags.cmake @@ -15,3 +15,5 @@ add_link_options(-gdwarf-4) # Extra warnings options for twister run set_property(TARGET linker PROPERTY warnings_as_errors -Wl,--fatal-warnings) + +set_linker_property(PROPERTY specs -specs=) diff --git a/cmake/linker/ld/linker_flags.cmake b/cmake/linker/ld/linker_flags.cmake index 49bba260d3a..5063ddb46fb 100644 --- a/cmake/linker/ld/linker_flags.cmake +++ b/cmake/linker/ld/linker_flags.cmake @@ -7,10 +7,6 @@ check_set_linker_property(TARGET linker PROPERTY base ${LINKERFLAGPREFIX},--build-id=none ) -if(NOT CONFIG_MINIMAL_LIBCPP AND NOT CONFIG_NATIVE_LIBRARY AND NOT CONFIG_EXTERNAL_MODULE_LIBCPP) - set_property(TARGET linker PROPERTY cpp_base -lstdc++) -endif() - check_set_linker_property(TARGET linker PROPERTY baremetal -nostdlib -static diff --git a/cmake/linker/ld/linker_libraries.cmake b/cmake/linker/ld/linker_libraries.cmake new file mode 100644 index 00000000000..1305d682ab5 --- /dev/null +++ b/cmake/linker/ld/linker_libraries.cmake @@ -0,0 +1,38 @@ +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# Do not specify default link libraries when targeting host (native build). +if(NOT CONFIG_NATIVE_BUILD) + set_linker_property(NO_CREATE PROPERTY c_library "-lc") + set_linker_property(NO_CREATE PROPERTY rt_library "-lgcc") + set_linker_property(NO_CREATE PROPERTY c++_library "-lstdc++") + set_linker_property(NO_CREATE PROPERTY math_library "-lm") + # Keeping default include dir empty. The linker will then select libraries + # from its default search path. The toolchain may adjust the value to a + # specific location, for example gcc infrastructure will set the value based + # on output from --print-libgcc-file-name. + set_linker_property(NO_CREATE PROPERTY lib_include_dir "") +endif() + +if(CONFIG_CPP + AND NOT CONFIG_MINIMAL_LIBCPP + AND NOT CONFIG_NATIVE_LIBRARY + # When new link principle is fully introduced, then the below condition can + # be removed, and instead the external module c++ should use: + # set_property(TARGET linker PROPERTY c++_library "") + AND NOT CONFIG_EXTERNAL_MODULE_LIBCPP +) + set_property(TARGET linker PROPERTY link_order_library "c++") +endif() + + +if(CONFIG_NEWLIB_LIBC AND CMAKE_C_COMPILER_ID STREQUAL "GNU") + # We are using c;rt;c (expands to '-lc -lgcc -lc') in code below. + # This is needed because when linking with newlib on aarch64, then libgcc has a + # link dependency to libc (strchr), but libc also has dependencies to libgcc. + # Lib C depends on libgcc. e.g. libc.a(lib_a-fvwrite.o) references __aeabi_idiv + set_property(TARGET linker APPEND PROPERTY link_order_library "math;c;rt;c") +else() + set_property(TARGET linker APPEND PROPERTY link_order_library "c;rt") +endif() diff --git a/cmake/linker/ld/target.cmake b/cmake/linker/ld/target.cmake index ed29e88aa16..c941d8ee89e 100644 --- a/cmake/linker/ld/target.cmake +++ b/cmake/linker/ld/target.cmake @@ -6,16 +6,12 @@ set(CMAKE_LINKER ${GNULD_LINKER}) set_ifndef(LINKERFLAGPREFIX -Wl) -if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host") - if(CONFIG_CPP_EXCEPTIONS AND LIBGCC_DIR) - # When building with C++ Exceptions, it is important that crtbegin and crtend - # are linked at specific locations. - # The location is so important that we cannot let this be controlled by normal - # link libraries, instead we must control the link command specifically as - # part of toolchain. - set(CMAKE_CXX_LINK_EXECUTABLE - " ${LIBGCC_DIR}/crtbegin.o -o ${LIBGCC_DIR}/crtend.o") - endif() +if((${CMAKE_LINKER} STREQUAL "${CROSS_COMPILE}ld.bfd") OR + ${GNULD_LINKER_IS_BFD}) + # ld.bfd was found so let's explicitly use that for linking, see #32237 + list(APPEND TOOLCHAIN_LD_FLAGS -fuse-ld=bfd) + list(APPEND CMAKE_REQUIRED_FLAGS -fuse-ld=bfd) + string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") endif() # Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen} @@ -118,16 +114,9 @@ function(toolchain_ld_link_elf) ${ARGN} # input args to parse ) - if((${CMAKE_LINKER} STREQUAL "${CROSS_COMPILE}ld.bfd") OR - ${GNULD_LINKER_IS_BFD}) - # ld.bfd was found so let's explicitly use that for linking, see #32237 - set(use_linker "-fuse-ld=bfd") - endif() - target_link_libraries( ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} - ${use_linker} ${TOPT} ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} @@ -138,14 +127,44 @@ function(toolchain_ld_link_elf) ${LINKERFLAGPREFIX},--no-whole-archive ${NO_WHOLE_ARCHIVE_LIBS} $ - ${LIB_INCLUDE_DIR} -L${PROJECT_BINARY_DIR} - ${TOOLCHAIN_LIBS} ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} ) endfunction(toolchain_ld_link_elf) +# Function for finalizing link setup after Zephyr configuration has completed. +# +# This function will generate the correct CMAKE_C_LINK_EXECUTABLE / CMAKE_CXX_LINK_EXECUTABLE +# rule to ensure that standard c and runtime libraries are correctly placed +# and the end of link invocation and doesn't appear in the middle of the link +# command invocation. +macro(toolchain_linker_finalize) + get_property(zephyr_std_libs TARGET linker PROPERTY lib_include_dir) + get_property(link_order TARGET linker PROPERTY link_order_library) + foreach(lib ${link_order}) + get_property(link_flag TARGET linker PROPERTY ${lib}_library) + list(APPEND zephyr_std_libs "${link_flag}") + endforeach() + string(REPLACE ";" " " zephyr_std_libs "${zephyr_std_libs}") + + set(link_libraries " -o ${zephyr_std_libs}") + set(common_link " ${link_libraries}") + + set(CMAKE_ASM_LINK_EXECUTABLE " ${common_link}") + set(CMAKE_C_LINK_EXECUTABLE " ${common_link}") + + set(cpp_link "${common_link}") + if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host") + if(CONFIG_CPP_EXCEPTIONS AND LIBGCC_DIR) + # When building with C++ Exceptions, it is important that crtbegin and crtend + # are linked at specific locations. + set(cpp_link " ${LIBGCC_DIR}/crtbegin.o ${link_libraries} ${LIBGCC_DIR}/crtend.o") + endif() + endif() + set(CMAKE_CXX_LINK_EXECUTABLE " ${cpp_link}") +endmacro() + # Load toolchain_ld-family macros include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_relocation.cmake) include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake) diff --git a/cmake/linker/linker_flags_template.cmake b/cmake/linker/linker_flags_template.cmake index 870c597be24..8b0b948b028 100644 --- a/cmake/linker/linker_flags_template.cmake +++ b/cmake/linker/linker_flags_template.cmake @@ -49,3 +49,7 @@ set_property(TARGET linker PROPERTY no_relax) # Linker flag for enabling relaxation of address optimization for jump calls. set_property(TARGET linker PROPERTY relax) + +# Linker flag for defining specs. Defined only by gcc, when gcc is used as +# front-end for ld. +set_compiler_property(PROPERTY specs) diff --git a/cmake/linker/linker_libraries_template.cmake b/cmake/linker/linker_libraries_template.cmake new file mode 100644 index 00000000000..481ee5c473e --- /dev/null +++ b/cmake/linker/linker_libraries_template.cmake @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# Linker flags for fixed linking with standard libraries, such as the C and runtime libraries. +# It is the responsibility of the linker infrastructure to use those properties to specify the +# correct placement of those libraries for correct link order. +# For example, GCC usually has the order: -lc -lgcc +# It is also possible to define extra libraries of the form `_library`, and then include +# Fixed library search path can be defined in the `lib_include_dir` property if needed. +# in the link_order_property. +# Usage example: +# set_linker_property(PROPERTY lib_include_dir "-L/path/to/libs") +# set_linker_property(PROPERTY c_library "-lc") +# set_linker_property(PROPERTY rt_library "-lgcc") +# set_linker_property(PROPERTY link_order_library "c;rt") diff --git a/cmake/linker/lld/linker_flags.cmake b/cmake/linker/lld/linker_flags.cmake index f6e873ad631..f11139aa1e2 100644 --- a/cmake/linker/lld/linker_flags.cmake +++ b/cmake/linker/lld/linker_flags.cmake @@ -1,4 +1,6 @@ # Copyright (c) 2022 Google LLC +# Copyright (c) 2024 Nordic Semiconductor +# # SPDX-License-Identifier: Apache-2.0 # Since lld is a drop in replacement for ld, we can just use ld's flags as a base @@ -6,7 +8,7 @@ include(${ZEPHYR_BASE}/cmake/linker/ld/linker_flags.cmake OPTIONAL) if(NOT CONFIG_MINIMAL_LIBCPP AND NOT CONFIG_NATIVE_LIBRARY AND NOT CONFIG_EXTERNAL_MODULE_LIBCPP) - set_property(TARGET linker PROPERTY cpp_base -lc++ ${LINKERFLAGPREFIX},-z,norelro) + set_property(TARGET linker PROPERTY cpp_base ${LINKERFLAGPREFIX},-z,norelro) endif() # Force LLVM to use built-in lld linker diff --git a/cmake/linker/lld/linker_libraries.cmake b/cmake/linker/lld/linker_libraries.cmake new file mode 100644 index 00000000000..2347898ad64 --- /dev/null +++ b/cmake/linker/lld/linker_libraries.cmake @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +set_linker_property(NO_CREATE TARGET linker PROPERTY c_library "-lc") +# Default per standard, will be populated by clang/target.cmake based on clang output. +set_linker_property(NO_CREATE TARGET linker PROPERTY rt_library "") +set_linker_property(TARGET linker PROPERTY c++_library "-lc++;-lc++abi") + +if(CONFIG_CPP + AND NOT CONFIG_MINIMAL_LIBCPP + AND NOT CONFIG_NATIVE_LIBRARY + # When new link principle is fully introduced, then the below condition can + # be removed, and instead the external module c++ should use: + # set_property(TARGET linker PROPERTY c++_library "") + AND NOT CONFIG_EXTERNAL_MODULE_LIBCPP +) + set_property(TARGET linker PROPERTY link_order_library "c++") +endif() + +set_property(TARGET linker APPEND PROPERTY link_order_library "c;rt") diff --git a/cmake/linker/lld/target.cmake b/cmake/linker/lld/target.cmake index a16529eeef7..b6b96525e70 100644 --- a/cmake/linker/lld/target.cmake +++ b/cmake/linker/lld/target.cmake @@ -6,6 +6,10 @@ set(CMAKE_LINKER ${LLVMLLD_LINKER}) set_ifndef(LINKERFLAGPREFIX -Wl) +list(APPEND TOOLCHAIN_LD_FLAGS -fuse-ld=lld) +list(APPEND CMAKE_REQUIRED_FLAGS -fuse-ld=lld) +string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + # Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen} # NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time macro(configure_linker_script linker_script_gen linker_pass_define) @@ -97,14 +101,32 @@ function(toolchain_ld_link_elf) ${LINKERFLAGPREFIX},--no-whole-archive ${NO_WHOLE_ARCHIVE_LIBS} $ - ${LIB_INCLUDE_DIR} -L${PROJECT_BINARY_DIR} - ${TOOLCHAIN_LIBS} ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} ) endfunction(toolchain_ld_link_elf) +# Function for finalizing link setup after Zephyr configuration has completed. +# +# This function will generate the correct CMAKE_C_LINK_EXECUTABLE / CMAKE_CXX_LINK_EXECUTABLE +# signature to ensure that standard c and runtime libraries are correctly placed +# and the end of link invocation and doesn't appear in the middle of the link +# command invocation. +macro(toolchain_linker_finalize) + get_property(zephyr_std_libs TARGET linker PROPERTY lib_include_dir) + get_property(link_order TARGET linker PROPERTY link_order_library) + foreach(lib ${link_order}) + get_property(link_flag TARGET linker PROPERTY ${lib}_library) + list(APPEND zephyr_std_libs "${link_flag}") + endforeach() + string(REPLACE ";" " " zephyr_std_libs "${zephyr_std_libs}") + + set(common_link " -o ${zephyr_std_libs}") + set(CMAKE_ASM_LINK_EXECUTABLE " ${common_link}") + set(CMAKE_C_LINK_EXECUTABLE " ${common_link}") + set(CMAKE_CXX_LINK_EXECUTABLE " ${common_link}") +endmacro() # Load toolchain_ld-family macros include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake) diff --git a/cmake/linker/target_template.cmake b/cmake/linker/target_template.cmake new file mode 100644 index 00000000000..efa27de6fb4 --- /dev/null +++ b/cmake/linker/target_template.cmake @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024, Nordic Semiconductor ASA + +# Template file for optional Zephyr linker macros. +# +# This file will define optional linker macros for toolchains that are not +# defining these macros themselves. + +if(NOT COMMAND toolchain_linker_finalize) + macro(toolchain_linker_finalize) + endmacro() +endif() diff --git a/cmake/linker/xt-ld/target.cmake b/cmake/linker/xt-ld/target.cmake index 4f8e4fcfbdb..3546881cc71 100644 --- a/cmake/linker/xt-ld/target.cmake +++ b/cmake/linker/xt-ld/target.cmake @@ -129,7 +129,6 @@ function(toolchain_ld_link_elf) ${LINKERFLAGPREFIX},--no-whole-archive ${NO_WHOLE_ARCHIVE_LIBS} $ - ${LIB_INCLUDE_DIR} -L${PROJECT_BINARY_DIR} ${TOOLCHAIN_LIBS} @@ -137,6 +136,27 @@ function(toolchain_ld_link_elf) ) endfunction(toolchain_ld_link_elf) +# Function for finalizing link setup after Zephyr configuration has completed. +# +# This function will generate the correct CMAKE_C_LINK_EXECUTABLE / CMAKE_CXX_LINK_EXECUTABLE +# rule to ensure that standard c and runtime libraries are correctly placed +# and the end of link invocation and doesn't appear in the middle of the link +# command invocation. +macro(toolchain_linker_finalize) + get_property(zephyr_std_libs TARGET linker PROPERTY lib_include_dir) + get_property(link_order TARGET linker PROPERTY link_order_library) + foreach(lib ${link_order}) + get_property(link_flag TARGET linker PROPERTY ${lib}_library) + list(APPEND zephyr_std_libs "${link_flag}") + endforeach() + string(REPLACE ";" " " zephyr_std_libs "${zephyr_std_libs}") + + set(common_link " -o ${zephyr_std_libs}") + set(CMAKE_ASM_LINK_EXECUTABLE " ${common_link}") + set(CMAKE_C_LINK_EXECUTABLE " ${common_link}") + set(CMAKE_CXX_LINK_EXECUTABLE " ${common_link}") +endmacro() + # xt-ld is Xtensa's own version of binutils' ld. # So we can reuse most of the ld configurations. include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake) diff --git a/cmake/modules/FindTargetTools.cmake b/cmake/modules/FindTargetTools.cmake index a1fa4bf5c67..e35f577d697 100644 --- a/cmake/modules/FindTargetTools.cmake +++ b/cmake/modules/FindTargetTools.cmake @@ -105,5 +105,7 @@ include(${TOOLCHAIN_ROOT}/cmake/linker/${LINKER}/target.cmake OPTIONAL) include(${ZEPHYR_BASE}/cmake/bintools/bintools_template.cmake) include(${TOOLCHAIN_ROOT}/cmake/bintools/${BINTOOLS}/target.cmake OPTIONAL) +include(${TOOLCHAIN_ROOT}/cmake/linker/target_template.cmake) + set(TargetTools_FOUND TRUE) set(TARGETTOOLS_FOUND TRUE) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 23c30789b73..921a457067d 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -109,16 +109,37 @@ endfunction() # https://cmake.org/cmake/help/latest/command/target_compile_options.html function(zephyr_compile_options) - target_compile_options(zephyr_interface INTERFACE ${ARGV}) + if(ARGV0 STREQUAL "PROPERTY") + set(property $) + set(property_defined $) + if(ARGC GREATER 3) + message(FATAL_ERROR "zephyr_compile_options(PROPERTY []) " + "called with too many arguments." + ) + elseif(ARGC EQUAL 3) + target_compile_options(zephyr_interface INTERFACE $<${property_defined}:${property}${ARGV2}>) + else() + target_compile_options(zephyr_interface INTERFACE ${property}) + endif() + else() + target_compile_options(zephyr_interface INTERFACE ${ARGV}) + endif() endfunction() # https://cmake.org/cmake/help/latest/command/target_link_libraries.html function(zephyr_link_libraries) if(ARGV0 STREQUAL "PROPERTY") - if(ARGC GREATER 2) - message(FATAL_ERROR "zephyr_link_libraries(PROPERTY ) only allows a single property.") + set(property $) + set(property_defined $) + if(ARGC GREATER 3) + message(FATAL_ERROR "zephyr_link_options(PROPERTY []) " + "called with too many arguments." + ) + elseif(ARGC EQUAL 3) + target_link_libraries(zephyr_interface INTERFACE $<${property_defined}:${property}${ARGV2}>) + else() + target_link_libraries(zephyr_interface INTERFACE ${property}) endif() - target_link_libraries(zephyr_interface INTERFACE $) else() target_link_libraries(zephyr_interface INTERFACE ${ARGV}) endif() @@ -2410,6 +2431,43 @@ function(toolchain_parse_make_rule input_file include_files) set(${include_files} ${result} PARENT_SCOPE) endfunction() +# 'set_linker_property' is a function that sets the property for the linker +# property target used for toolchain abstraction. +# +# This function is similar in nature to the CMake set_property function, but +# with some additional extension flags for improved behavioral control. +# +# NO_CREATE: Flag to indicate that the property should only be set if not already +# defined with a value. +# APPEND: Flag indicated that the property should be appended to the existing +# value list for the property. +# TARGET: Name of target on which to add the property (default: linker) +# PROPERTY: Name of property with the value(s) following immediately after +# property name +function(set_linker_property) + set(options APPEND NO_CREATE) + set(single_args TARGET) + set(multi_args PROPERTY) + cmake_parse_arguments(LINKER_PROPERTY "${options}" "${single_args}" "${multi_args}" ${ARGN}) + + if(LINKER_PROPERTY_APPEND) + set(APPEND "APPEND") + endif() + + if(NOT DEFINED LINKER_PROPERTY_TARGET) + set(LINKER_PROPERTY_TARGET "linker") + endif() + + if(LINKER_PROPERTY_NO_CREATE) + list(GET LINKER_PROPERTY_PROPERTY 0 property_name) + get_target_property(var ${LINKER_PROPERTY_TARGET} ${property_name}) + if(NOT "${var}" STREQUAL "var-NOTFOUND") + return() + endif() + endif() + set_property(TARGET ${LINKER_PROPERTY_TARGET} ${APPEND} PROPERTY ${LINKER_PROPERTY_PROPERTY}) +endfunction() + # 'check_set_linker_property' is a function that check the provided linker # flag and only set the linker property if the check succeeds # @@ -2419,7 +2477,7 @@ endfunction() # # APPEND: Flag indicated that the property should be appended to the existing # value list for the property. -# TARGET: Name of target on which to add the property (commonly: linker) +# TARGET: Name of target on which to add the property (default: linker) # PROPERTY: Name of property with the value(s) following immediately after # property name function(check_set_linker_property) @@ -2432,6 +2490,10 @@ function(check_set_linker_property) set(APPEND "APPEND") endif() + if(NOT DEFINED LINKER_PROPERTY_TARGET) + set(LINKER_PROPERTY_TARGET "linker") + endif() + list(GET LINKER_PROPERTY_PROPERTY 0 property) list(REMOVE_AT LINKER_PROPERTY_PROPERTY 0) diff --git a/cmake/target_toolchain_flags.cmake b/cmake/target_toolchain_flags.cmake index 1df7e5eddc6..716cc8f55e7 100644 --- a/cmake/target_toolchain_flags.cmake +++ b/cmake/target_toolchain_flags.cmake @@ -35,8 +35,10 @@ include(${CMAKE_CURRENT_LIST_DIR}/compiler/compiler_features.cmake) # a new toolchain. include(${CMAKE_CURRENT_LIST_DIR}/compiler/compiler_flags_template.cmake) include(${CMAKE_CURRENT_LIST_DIR}/linker/linker_flags_template.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/linker/linker_libraries_template.cmake) # Configure the toolchain flags based on what toolchain technology is used # (gcc, host-gcc etc.) include(${TOOLCHAIN_ROOT}/cmake/compiler/${COMPILER}/compiler_flags.cmake OPTIONAL) include(${TOOLCHAIN_ROOT}/cmake/linker/${LINKER}/linker_flags.cmake OPTIONAL) +include(${TOOLCHAIN_ROOT}/cmake/linker/${LINKER}/linker_libraries.cmake OPTIONAL) diff --git a/cmake/toolchain/llvm/generic.cmake b/cmake/toolchain/llvm/generic.cmake index 0b138c2868c..f6d7878288d 100644 --- a/cmake/toolchain/llvm/generic.cmake +++ b/cmake/toolchain/llvm/generic.cmake @@ -17,6 +17,28 @@ set(LLVM_TOOLCHAIN_PATH ${CLANG_ROOT_DIR} CACHE PATH "clang install directory") set(COMPILER clang) set(BINTOOLS llvm) -set(TOOLCHAIN_HAS_NEWLIB OFF CACHE BOOL "True if toolchain supports newlib") +# LLVM is flexible, meaning that it can in principle always support newlib or picolibc. +# This is not decided by LLVM itself, but depends on libraries distributed with the installation. +# Also newlib or picolibc may be created as add-ons. Thus always stating that LLVM does not have +# newlib or picolibc would be wrong. Same with stating that LLVM has newlib or Picolibc. +# The best assumption for TOOLCHAIN_HAS_ is to check for the presence of +# '_newlib_version.h' / 'picolibc' and have the default value set accordingly. +# This provides a best effort mechanism to allow developers to have the newlib C / Picolibc library +# selection available in Kconfig. +# Developers can manually indicate library support with '-DTOOLCHAIN_HAS_=' -message(STATUS "Found toolchain: host (clang/ld)") +# Support for newlib is indicated by the presence of '_newlib_version.h' in the toolchain path. +if(NOT LLVM_TOOLCHAIN_PATH STREQUAL "") + file(GLOB_RECURSE newlib_header ${LLVM_TOOLCHAIN_PATH}/_newlib_version.h) + if(newlib_header) + set(TOOLCHAIN_HAS_NEWLIB ON CACHE BOOL "True if toolchain supports newlib") + endif() + + # Support for picolibc is indicated by the presence of 'picolibc.h' in the toolchain path. + file(GLOB_RECURSE picolibc_header ${LLVM_TOOLCHAIN_PATH}/picolibc.h) + if(picolibc_header) + set(TOOLCHAIN_HAS_PICOLIBC ON CACHE BOOL "True if toolchain supports picolibc") + endif() +endif() + +message(STATUS "Found toolchain: llvm (clang/ld)") diff --git a/drivers/retained_mem/Kconfig.nrf b/drivers/retained_mem/Kconfig.nrf index 348361e5f6f..70aef8b504f 100644 --- a/drivers/retained_mem/Kconfig.nrf +++ b/drivers/retained_mem/Kconfig.nrf @@ -13,6 +13,6 @@ config RETAINED_MEM_NRF_RAM_CTRL bool "nRF RAM retention driver" default y depends on DT_HAS_ZEPHYR_RETAINED_RAM_ENABLED && RETAINED_MEM_ZEPHYR_RAM && POWEROFF - depends on SOC_FAMILY_NORDIC_NRF + depends on HAS_NORDIC_RAM_CTRL help Enable driver for Nordic RAM retention. diff --git a/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c b/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c index 8be3d5c35a3..08e777aa6fa 100644 --- a/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c +++ b/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c @@ -6,6 +6,7 @@ #include #include +#include #include @@ -22,7 +23,7 @@ static const struct ret_mem_region ret_mem_regions[] = { DT_FOREACH_STATUS_OKAY(zephyr_retained_ram, _BUILD_MEM_REGION) }; -static int retained_mem_nrf_init(void) +int z_nrf_retained_mem_retention_apply(void) { const struct ret_mem_region *rmr; @@ -33,5 +34,3 @@ static int retained_mem_nrf_init(void) return 0; } - -SYS_INIT(retained_mem_nrf_init, PRE_KERNEL_1, 0); diff --git a/drivers/wifi/nrf_wifi/CMakeLists.txt b/drivers/wifi/nrf_wifi/CMakeLists.txt index e631e930e07..27d8ba8081c 100644 --- a/drivers/wifi/nrf_wifi/CMakeLists.txt +++ b/drivers/wifi/nrf_wifi/CMakeLists.txt @@ -11,7 +11,6 @@ set(FW_BINS_BASE ${ZEPHYR_NRF_WIFI_MODULE_DIR}/zephyr/blobs/wifi_fw_bins) zephyr_include_directories( inc - src/qspi/inc # for net_sprint_ll_addr ${ZEPHYR_BASE}/subsys/net/ip ) @@ -24,12 +23,6 @@ zephyr_library_sources_ifdef(CONFIG_NRF70_SR_COEX src/coex.c ) -zephyr_library_sources( - src/qspi/src/device.c - src/qspi/src/rpu_hw_if.c - src/qspi/src/ficr_prog.c -) - zephyr_library_sources_ifndef(CONFIG_NRF70_OFFLOADED_RAW_TX src/fmac_main.c ) @@ -65,14 +58,6 @@ zephyr_library_sources_ifdef(CONFIG_NRF70_STA_MODE zephyr_library_sources_ifdef(CONFIG_NRF70_STA_MODE src/wpa_supp_if.c) -zephyr_library_sources_ifdef(CONFIG_NRF70_ON_QSPI - src/qspi/src/qspi_if.c -) - -zephyr_library_sources_ifdef(CONFIG_NRF70_ON_SPI - src/qspi/src/spi_if.c -) - zephyr_library_sources_ifdef(CONFIG_NRF70_UTIL src/wifi_util.c ) @@ -88,6 +73,8 @@ zephyr_compile_definitions_ifdef(CONFIG_NRF70_ON_QSPI -DNRF53_ERRATA_159_ENABLE_WORKAROUND=0 ) +target_link_libraries(nrf_wifi PRIVATE nrf70-buslib) + if (CONFIG_NRF_WIFI_BUILD_ONLY_MODE) message(WARNING " ------------------------------------------------------------------------ diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index f0d2c8ead71..45a22b7e7fa 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -11,6 +11,7 @@ menuconfig WIFI_NRF70 select NET_L2_ETHERNET_MGMT if NETWORKING && NET_L2_ETHERNET select WIFI_USE_NATIVE_NETWORKING if NETWORKING select EXPERIMENTAL if !SOC_SERIES_NRF53X && !SOC_SERIES_NRF91X + select NRF70_BUSLIB default y depends on \ DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED || \ @@ -33,16 +34,9 @@ config WIFI_NRF7000 bool default y if DT_HAS_NORDIC_NRF7000_SPI_ENABLED || DT_HAS_NORDIC_NRF7000_QSPI_ENABLED - -module = WIFI_NRF70_BUS -module-dep = LOG -module-str = Log level for Wi-Fi nRF70 bus layers -module-help = Sets log level for Wi-Fi nRF70 bus layers -source "subsys/net/Kconfig.template.log_config.net" - -config WIFI_NRF70_BUS_LOG_LEVEL - # Enable error by default - default 1 +config NRF70_QSPI_LOW_POWER + bool "low power mode in QSPI" + default y if NRF_WIFI_LOW_POWER choice NRF70_OPER_MODES bool "nRF70 operating modes" diff --git a/drivers/wifi/nrf_wifi/src/qspi/inc/ficr_prog.h b/drivers/wifi/nrf_wifi/src/qspi/inc/ficr_prog.h deleted file mode 100644 index 35c4bda1fa3..00000000000 --- a/drivers/wifi/nrf_wifi/src/qspi/inc/ficr_prog.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @brief Header containing address/offets and functions for writing - * the FICR fields of the OTP memory on nRF7002 device - */ - -#ifndef __OTP_PROG_H_ -#define __OTP_PROG_H_ - -#include -#include - -int write_otp_memory(unsigned int otp_addr, unsigned int *write_val); -int read_otp_memory(unsigned int otp_addr, unsigned int *read_val, int len); -unsigned int check_protection(unsigned int *buff, unsigned int off1, unsigned int off2, - unsigned int off3, unsigned int off4); - -#endif /* __OTP_PROG_H_ */ diff --git a/drivers/wifi/nrf_wifi/src/qspi/src/ficr_prog.c b/drivers/wifi/nrf_wifi/src/qspi/src/ficr_prog.c deleted file mode 100644 index 5558b35e837..00000000000 --- a/drivers/wifi/nrf_wifi/src/qspi/src/ficr_prog.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* @file - * @brief NRF Wi-Fi radio FICR programming functions - */ - -#include -#include -#include "rpu_if.h" -#include "rpu_hw_if.h" -#include "ficr_prog.h" - - -LOG_MODULE_DECLARE(otp_prog, CONFIG_WIFI_NRF70_BUS_LOG_LEVEL); - -static void write_word(unsigned int addr, unsigned int data) -{ - rpu_write(addr, &data, 4); -} - -static void read_word(unsigned int addr, unsigned int *data) -{ - rpu_read(addr, data, 4); -} - -unsigned int check_protection(unsigned int *buff, unsigned int off1, unsigned int off2, - unsigned int off3, unsigned int off4) -{ - if ((buff[off1] == OTP_PROGRAMMED) && - (buff[off2] == OTP_PROGRAMMED) && - (buff[off3] == OTP_PROGRAMMED) && - (buff[off4] == OTP_PROGRAMMED)) - return OTP_PROGRAMMED; - else if ((buff[off1] == OTP_FRESH_FROM_FAB) && - (buff[off2] == OTP_FRESH_FROM_FAB) && - (buff[off3] == OTP_FRESH_FROM_FAB) && - (buff[off4] == OTP_FRESH_FROM_FAB)) - return OTP_FRESH_FROM_FAB; - else if ((buff[off1] == OTP_ENABLE_PATTERN) && - (buff[off2] == OTP_ENABLE_PATTERN) && - (buff[off3] == OTP_ENABLE_PATTERN) && - (buff[off4] == OTP_ENABLE_PATTERN)) - return OTP_ENABLE_PATTERN; - else - return OTP_INVALID; -} - - -static void set_otp_timing_reg_40mhz(void) -{ - write_word(OTP_TIMING_REG1_ADDR, OTP_TIMING_REG1_VAL); - write_word(OTP_TIMING_REG2_ADDR, OTP_TIMING_REG2_VAL); -} - -static int poll_otp_ready(void) -{ - int otp_mem_status = 0; - int poll = 0; - - while (poll != 100) { - read_word(OTP_POLL_ADDR, &otp_mem_status); - - if ((otp_mem_status & OTP_READY) == OTP_READY) { - return 0; - } - poll++; - } - LOG_ERR("OTP is not ready"); - return -ENOEXEC; -} - - -static int req_otp_standby_mode(void) -{ - write_word(OTP_RWSBMODE_ADDR, 0x0); - return poll_otp_ready(); -} - - -static int otp_wr_voltage_2V5(void) -{ - int err; - - err = req_otp_standby_mode(); - - if (err) { - LOG_ERR("Failed Setting OTP voltage IOVDD to 2.5V"); - return -ENOEXEC; - } - write_word(OTP_VOLTCTRL_ADDR, OTP_VOLTCTRL_2V5); - return 0; -} - -static int poll_otp_read_valid(void) -{ - int otp_mem_status = 0; - int poll = 0; - - while (poll < 100) { - read_word(OTP_POLL_ADDR, &otp_mem_status); - - if ((otp_mem_status & OTP_READ_VALID) == OTP_READ_VALID) { - return 0; - } - poll++; - } - LOG_ERR("%s: OTP read failed", __func__); - return -ENOEXEC; -} - -static int poll_otp_wrdone(void) -{ - int otp_mem_status = 0; - int poll = 0; - - while (poll < 100) { - read_word(OTP_POLL_ADDR, &otp_mem_status); - - if ((otp_mem_status & OTP_WR_DONE) == OTP_WR_DONE) { - return 0; - } - poll++; - } - LOG_ERR("%s: OTP write done failed", __func__); - return -ENOEXEC; -} - -static int req_otp_read_mode(void) -{ - write_word(OTP_RWSBMODE_ADDR, OTP_READ_MODE); - return poll_otp_ready(); -} - - -static int req_otp_byte_write_mode(void) -{ - write_word(OTP_RWSBMODE_ADDR, OTP_BYTE_WRITE_MODE); - return poll_otp_ready(); -} - -static unsigned int read_otp_location(unsigned int offset, unsigned int *read_val) -{ - int err; - - write_word(OTP_RDENABLE_ADDR, offset); - err = poll_otp_read_valid(); - if (err) { - LOG_ERR("OTP read failed"); - return err; - } - read_word(OTP_READREG_ADDR, read_val); - - return 0; -} - -static int write_otp_location(unsigned int otp_location_offset, unsigned int otp_data) -{ - write_word(OTP_WRENABLE_ADDR, otp_location_offset); - write_word(OTP_WRITEREG_ADDR, otp_data); - - return poll_otp_wrdone(); -} - - -static int otp_rd_voltage_1V8(void) -{ - int err; - - err = req_otp_standby_mode(); - if (err) { - LOG_ERR("error in %s", __func__); - return err; - } - write_word(OTP_VOLTCTRL_ADDR, OTP_VOLTCTRL_1V8); - - return 0; -} - -static int update_mac_addr(unsigned int index, unsigned int *write_val) -{ - int ret = 0; - - for (int i = 0; i < 2; i++) { - ret = write_otp_location(MAC0_ADDR + 2 * index + i, write_val[i]); - if (ret == -ENOEXEC) { - LOG_ERR("FICR: Failed to update MAC ADDR%d", index); - break; - } - LOG_INF("mac addr %d : Reg%d (0x%x) = 0x%04x", - index, (i+1), (MAC0_ADDR + i) << 2, write_val[i]); - } - return ret; -} - -int write_otp_memory(unsigned int otp_addr, unsigned int *write_val) -{ - int err = 0; - int mask_val; - int ret = 0; - int retrim_loc = 0; - - err = poll_otp_ready(); - if (err) { - LOG_ERR("err in otp ready poll"); - return err; - } - - set_otp_timing_reg_40mhz(); - - err = otp_wr_voltage_2V5(); - if (err) { - LOG_ERR("error in write_voltage 2V5"); - goto _exit_otp_write; - } - - err = req_otp_byte_write_mode(); - if (err) { - LOG_ERR("error in OTP byte write mode"); - goto _exit_otp_write; - } - - switch (otp_addr) { - case REGION_PROTECT: - write_otp_location(REGION_PROTECT, write_val[0]); - write_otp_location(REGION_PROTECT+1, write_val[0]); - write_otp_location(REGION_PROTECT+2, write_val[0]); - write_otp_location(REGION_PROTECT+3, write_val[0]); - - LOG_INF("Written REGION_PROTECT0 (0x%x) : 0x%04x", - (REGION_PROTECT << 2), write_val[0]); - LOG_INF("Written REGION_PROTECT1 (0x%x) : 0x%04x", - (REGION_PROTECT+1) << 2, write_val[0]); - LOG_INF("Written REGION_PROTECT2 (0x%x) : 0x%04x", - (REGION_PROTECT+2) << 2, write_val[0]); - LOG_INF("Written REGION_PROTECT3 (0x%x) : 0x%04x", - (REGION_PROTECT+3) << 2, write_val[0]); - break; - case QSPI_KEY: - mask_val = QSPI_KEY_FLAG_MASK; - for (int i = 0; i < QSPI_KEY_LENGTH_BYTES / 4; i++) { - ret = write_otp_location(QSPI_KEY + i, write_val[i]); - if (ret == -ENOEXEC) { - LOG_ERR("FICR: Failed to write QSPI key offset-%d", QSPI_KEY + i); - goto _exit_otp_write; - } - LOG_INF("Written QSPI_KEY0 (0x%x) : 0x%04x", - (QSPI_KEY + i) << 2, write_val[i]); - } - write_otp_location(REGION_DEFAULTS, mask_val); - LOG_INF("Written REGION_DEFAULTS (0x%x) : 0x%04x", - (REGION_DEFAULTS) << 2, mask_val); - break; - case MAC0_ADDR: - mask_val = MAC0_ADDR_FLAG_MASK; - ret = update_mac_addr(0, write_val); - if (ret == -ENOEXEC) { - goto _exit_otp_write; - } - - write_otp_location(REGION_DEFAULTS, mask_val); - LOG_INF("Written MAC address 0"); - LOG_INF("Written REGION_DEFAULTS (0x%x) : 0x%04x", - (REGION_DEFAULTS) << 2, mask_val); - break; - case MAC1_ADDR: - mask_val = MAC1_ADDR_FLAG_MASK; - ret = update_mac_addr(1, write_val); - if (ret == -ENOEXEC) { - goto _exit_otp_write; - } - write_otp_location(REGION_DEFAULTS, mask_val); - LOG_INF("Written MAC address 1"); - LOG_INF("Written REGION_DEFAULTS (0x%x) : 0x%04x", - (REGION_DEFAULTS) << 2, mask_val); - break; - case CALIB_XO: - mask_val = CALIB_XO_FLAG_MASK; - ret = write_otp_location(CALIB_XO, write_val[0]); - - if (ret == -ENOEXEC) { - LOG_ERR("XO_Update Exception"); - goto _exit_otp_write; - } else { - write_otp_location(REGION_DEFAULTS, mask_val); - - LOG_INF("Written CALIB_XO (0x%x) to 0x%04x", - CALIB_XO << 2, write_val[0]); - LOG_INF("Written REGION_DEFAULTS (0x%x) : 0x%04x", - (REGION_DEFAULTS) << 2, mask_val); - } - break; - case PRODRETEST_PROGVERSION: - ret = write_otp_location(PRODRETEST_PROGVERSION, *write_val); - - if (ret == -ENOEXEC) { - LOG_ERR("PRODRETEST.PROGVERSION_Update Exception"); - goto _exit_otp_write; - } else { - LOG_INF("Written PRODRETEST.PROGVERSION 0x%04x", *write_val); - } - break; - case PRODRETEST_TRIM0: - case PRODRETEST_TRIM1: - case PRODRETEST_TRIM2: - case PRODRETEST_TRIM3: - case PRODRETEST_TRIM4: - case PRODRETEST_TRIM5: - case PRODRETEST_TRIM6: - case PRODRETEST_TRIM7: - case PRODRETEST_TRIM8: - case PRODRETEST_TRIM9: - case PRODRETEST_TRIM10: - case PRODRETEST_TRIM11: - case PRODRETEST_TRIM12: - case PRODRETEST_TRIM13: - case PRODRETEST_TRIM14: - retrim_loc = otp_addr - PRODRETEST_TRIM0; - ret = write_otp_location(otp_addr, *write_val); - - if (ret == -ENOEXEC) { - LOG_ERR("PRODRETEST.TRIM_Update Exception"); - goto _exit_otp_write; - } else { - LOG_INF("Written PRODRETEST.TRIM%d 0x%04x", - retrim_loc, *write_val); - } - break; - case REGION_DEFAULTS: - write_otp_location(REGION_DEFAULTS, write_val[0]); - - LOG_INF("Written REGION_DEFAULTS (0x%x) to 0x%04x", - REGION_DEFAULTS << 2, write_val[0]); - break; - default: - LOG_ERR("unknown field received: %d", otp_addr); - - } - return ret; - -_exit_otp_write: - err = req_otp_standby_mode(); - err |= otp_rd_voltage_1V8(); - return err; -} - -int read_otp_memory(unsigned int otp_addr, unsigned int *read_val, int len) -{ - int err; - - err = poll_otp_ready(); - if (err) { - LOG_ERR("err in otp ready poll"); - return -ENOEXEC; - } - - set_otp_timing_reg_40mhz(); - - err = otp_rd_voltage_1V8(); - if (err) { - LOG_ERR("error in read_voltage 1V8"); - return -ENOEXEC; - } - - err = req_otp_read_mode(); - if (err) { - LOG_ERR("error in req_otp_read_mode()"); - return -ENOEXEC; - } - - for (int i = 0; i < len; i++) { - read_otp_location(otp_addr + i, &read_val[i]); - } - - return req_otp_standby_mode(); -} diff --git a/include/zephyr/drivers/retained_mem/nrf_retained_mem.h b/include/zephyr/drivers/retained_mem/nrf_retained_mem.h new file mode 100644 index 00000000000..376673c92d1 --- /dev/null +++ b/include/zephyr/drivers/retained_mem/nrf_retained_mem.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_NRF_RETAINED_MEM_H +#define ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_NRF_RETAINED_MEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if defined(CONFIG_RETAINED_MEM_NRF_RAM_CTRL) || defined(__DOXYGEN__) +/** @brief Apply memory retention settings. + * + * Memory retention settings to apply are derived from devicetree configuration. + * + * @retval 0 if the retention settings were applied successfully. + * @retval -ENOTSUP if retention configuration is not present in devicetree. + */ +int z_nrf_retained_mem_retention_apply(void); +#else +static inline int z_nrf_retained_mem_retention_apply(void) +{ + return -ENOTSUP; +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_NRF_RETAINED_MEM_H */ diff --git a/drivers/wifi/nrf_wifi/src/qspi/inc/qspi_if.h b/include/zephyr/drivers/wifi/nrf_wifi/bus/qspi_if.h similarity index 100% rename from drivers/wifi/nrf_wifi/src/qspi/inc/qspi_if.h rename to include/zephyr/drivers/wifi/nrf_wifi/bus/qspi_if.h diff --git a/drivers/wifi/nrf_wifi/src/qspi/inc/rpu_hw_if.h b/include/zephyr/drivers/wifi/nrf_wifi/bus/rpu_hw_if.h similarity index 100% rename from drivers/wifi/nrf_wifi/src/qspi/inc/rpu_hw_if.h rename to include/zephyr/drivers/wifi/nrf_wifi/bus/rpu_hw_if.h diff --git a/lib/libc/newlib/CMakeLists.txt b/lib/libc/newlib/CMakeLists.txt index de39b8ce213..d3dc448ecca 100644 --- a/lib/libc/newlib/CMakeLists.txt +++ b/lib/libc/newlib/CMakeLists.txt @@ -34,40 +34,12 @@ zephyr_compile_definitions(_ANSI_SOURCE) zephyr_compile_definitions(__LINUX_ERRNO_EXTENSIONS__) if(CMAKE_C_COMPILER_ID STREQUAL "GNU") - # We are using - # - ${CMAKE_C_LINKER_WRAPPER_FLAG}${CMAKE_LINK_LIBRARY_FLAG}c - # - ${CMAKE_C_LINKER_WRAPPER_FLAG}${CMAKE_LINK_LIBRARY_FLAG}gcc - # - c - # in code below. - # This is needed because when linking with newlib on aarch64, then libgcc has a - # link dependency to libc (strchr), but libc also has dependencies to libgcc. - # - # CMake is capable of handling circular link dependencies for CMake defined - # static libraries, which can be further controlled using LINK_INTERFACE_MULTIPLICITY. - # However, libc and libgcc are not regular CMake libraries, and is seen as linker - # flags by CMake, and thus symbol de-duplications will be performed. - # CMake link options cannot be used, as that will place those libs first on the - # linker invocation. -Wl,--start-group is problematic as the placement of -lc - # and -lgcc is not guaranteed in case later libraries are also using - # -lc / -libbgcc as interface linker flags. - # - # Thus, we resort to use `${CMAKE_C_LINKER_WRAPPER_FLAG}${CMAKE_LINK_LIBRARY_FLAG}` - # as this ensures the uniqueness and thus avoids symbol de-duplication which means - # libc will be followed by libgcc, which is finally followed by libc again. - - list(JOIN CMAKE_C_LINKER_WRAPPER_FLAG "" linker_wrapper_string) - zephyr_link_libraries( - m - "${linker_wrapper_string}${CMAKE_LINK_LIBRARY_FLAG}c" ${LIBC_LIBRARY_DIR_FLAG} # NB: Optional $<$:-u_printf_float> $<$:-u_scanf_float> - # Lib C depends on libgcc. e.g. libc.a(lib_a-fvwrite.o) references __aeabi_idiv - "${linker_wrapper_string}${CMAKE_LINK_LIBRARY_FLAG}gcc" ) endif() -zephyr_link_libraries(c) if(CONFIG_NEWLIB_LIBC_NANO) zephyr_link_libraries( diff --git a/lib/libc/picolibc/CMakeLists.txt b/lib/libc/picolibc/CMakeLists.txt index 87fb0d9d8ec..14af66b7b7d 100644 --- a/lib/libc/picolibc/CMakeLists.txt +++ b/lib/libc/picolibc/CMakeLists.txt @@ -15,9 +15,8 @@ if(NOT CONFIG_PICOLIBC_USE_MODULE) # Use picolibc provided with the toolchain. This requires a new enough # toolchain so that the version of picolibc supports auto-detecting a # Zephyr build (via the __ZEPHYR__ macro) to expose the Zephyr C API - - zephyr_compile_options(--specs=picolibc.specs) - zephyr_libc_link_libraries(--specs=picolibc.specs c -lgcc) + zephyr_compile_options(PROPERTY specs picolibc.specs) + zephyr_link_libraries(PROPERTY specs picolibc.specs) if(CONFIG_PICOLIBC_IO_FLOAT) zephyr_compile_definitions(PICOLIBC_DOUBLE_PRINTF_SCANF) zephyr_link_libraries(-DPICOLIBC_DOUBLE_PRINTF_SCANF) diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index 1665c122c9f..81428db0538 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -111,7 +111,7 @@ zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF92X ${MDK_DIR}/system_nrf92.c zephyr_library_sources(nrfx_glue.c) zephyr_library_sources(${HELPERS_DIR}/nrfx_flag32_allocator.c) -zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_NRF_RAM_CTRL ${HELPERS_DIR}/nrfx_ram_ctrl.c) +zephyr_library_sources_ifdef(CONFIG_HAS_NORDIC_RAM_CTRL ${HELPERS_DIR}/nrfx_ram_ctrl.c) zephyr_library_sources_ifdef(CONFIG_NRFX_GPPI ${HELPERS_DIR}/nrfx_gppi_dppi.c) zephyr_library_sources_ifdef(CONFIG_NRFX_PPI ${HELPERS_DIR}/nrfx_gppi_ppi.c) diff --git a/modules/nrf_wifi/CMakeLists.txt b/modules/nrf_wifi/CMakeLists.txt index e3b96f0db7b..982272fce6a 100644 --- a/modules/nrf_wifi/CMakeLists.txt +++ b/modules/nrf_wifi/CMakeLists.txt @@ -1,184 +1,6 @@ -# Copyright (c) 2024 Nordic Semiconductor ASA +# # SPDX-License-Identifier: Apache-2.0 +# -if(NOT CONFIG_WIFI_NRF70) - return() -endif() -zephyr_interface_library_named(nrf-wifi-interface) -zephyr_library() - -set(NRF_WIFI_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) - -# Translate the configuration to the OS agnostic code -target_compile_definitions( - nrf-wifi-interface - INTERFACE - $<$:NRF_WIFI_LOW_POWER> - $<$:NRF_WIFI_RPU_RECOVERY> - $<$:NRF_WIFI_AP_DEAD_DETECT_TIMEOUT=${CONFIG_NRF_WIFI_AP_DEAD_DETECT_TIMEOUT}> - $<$:NRF_WIFI_IFACE_MTU=${CONFIG_NRF_WIFI_IFACE_MTU}> - $<$:NRF70_STA_MODE> - $<$:NRF70_DATA_TX> - $<$:NRF70_RAW_DATA_TX> - $<$:NRF70_RAW_DATA_RX> - $<$:NRF70_PROMISC_DATA_RX> - $<$:NRF70_TX_DONE_WQ_ENABLED> - $<$:NRF70_RX_WQ_ENABLED> - $<$:NRF70_UTIL> - $<$:NRF70_RADIO_TEST> - $<$:NRF70_OFFLOADED_RAW_TX> - $<$:NRF70_TCP_IP_CHECKSUM_OFFLOAD> - $<$:NRF70_RPU_EXTEND_TWT_SP> - $<$:NRF70_SYSTEM_WITH_RAW_MODES> - $<$:NRF70_SCAN_ONLY> - $<$:NRF70_SYSTEM_MODE> - $<$:NRF70_2_4G_ONLY> - $<$:NRF70_LOG_VERBOSE> - $<$:NRF70_AP_MODE> - $<$:NRF_WIFI_MGMT_BUFF_OFFLOAD> - $<$:NRF_WIFI_FEAT_KEEPALIVE> - $<$:NRF_WIFI_KEEPALIVE_PERIOD_S=${CONFIG_NRF_WIFI_KEEPALIVE_PERIOD_S}> - $<$:WIFI_MGMT_RAW_SCAN_RESULTS> - NRF70_RX_NUM_BUFS=${CONFIG_NRF70_RX_NUM_BUFS} - NRF70_MAX_TX_TOKENS=${CONFIG_NRF70_MAX_TX_TOKENS} - NRF70_RX_MAX_DATA_SIZE=${CONFIG_NRF70_RX_MAX_DATA_SIZE} - NRF70_MAX_TX_PENDING_QLEN=${CONFIG_NRF70_MAX_TX_PENDING_QLEN} - NRF70_RPU_PS_IDLE_TIMEOUT_MS=${CONFIG_NRF70_RPU_PS_IDLE_TIMEOUT_MS} - NRF70_REG_DOMAIN=${CONFIG_NRF70_REG_DOMAIN} - NRF70_BAND_2G_LOWER_EDGE_BACKOFF_DSSS=${CONFIG_NRF70_BAND_2G_LOWER_EDGE_BACKOFF_DSSS} - NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_2G_UPPER_EDGE_BACKOFF_DSSS=${CONFIG_NRF70_BAND_2G_UPPER_EDGE_BACKOFF_DSSS} - NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HE} - NRF70_PCB_LOSS_2G=${CONFIG_NRF70_PCB_LOSS_2G} - NRF70_PCB_LOSS_5G_BAND1=${CONFIG_NRF70_PCB_LOSS_5G_BAND1} - NRF70_PCB_LOSS_5G_BAND2=${CONFIG_NRF70_PCB_LOSS_5G_BAND2} - NRF70_PCB_LOSS_5G_BAND3=${CONFIG_NRF70_PCB_LOSS_5G_BAND3} - NRF70_ANT_GAIN_2G=${CONFIG_NRF70_ANT_GAIN_2G} - NRF70_ANT_GAIN_5G_BAND1=${CONFIG_NRF70_ANT_GAIN_5G_BAND1} - NRF70_ANT_GAIN_5G_BAND2=${CONFIG_NRF70_ANT_GAIN_5G_BAND2} - NRF70_ANT_GAIN_5G_BAND3=${CONFIG_NRF70_ANT_GAIN_5G_BAND3} - NRF_WIFI_PS_INT_PS=${CONFIG_NRF_WIFI_PS_INT_PS} - NRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS=${CONFIG_NRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS} -) - -target_include_directories( - nrf-wifi-interface - INTERFACE - ${CMAKE_CURRENT_LIST_DIR} - ${NRF_WIFI_DIR}/utils/inc - ${NRF_WIFI_DIR}/os_if/inc - ${NRF_WIFI_DIR}/bus_if/bus/qspi/inc - ${NRF_WIFI_DIR}/bus_if/bal/inc - ${NRF_WIFI_DIR}/fw_if/umac_if/inc - ${NRF_WIFI_DIR}/fw_load/mips/fw/inc - ${NRF_WIFI_DIR}/hw_if/hal/inc - ${NRF_WIFI_DIR}/hw_if/hal/inc/fw - ${NRF_WIFI_DIR}/fw_if/umac_if/inc/fw -) - -if(CONFIG_NRF70_RADIO_TEST) - target_include_directories(nrf-wifi-interface INTERFACE - ${NRF_WIFI_DIR}/fw_if/umac_if/inc/radio_test - ) -elseif(CONFIG_NRF70_OFFLOADED_RAW_TX) - target_include_directories(nrf-wifi-interface INTERFACE - ${NRF_WIFI_DIR}/fw_if/umac_if/inc/offload_raw_tx - off_raw_tx/inc - ) -else() - target_include_directories(nrf-wifi-interface INTERFACE - ${NRF_WIFI_DIR}/fw_if/umac_if/inc/default - ) -endif() - -zephyr_library_sources( - ${NRF_WIFI_DIR}/os_if/src/osal.c - ${NRF_WIFI_DIR}/utils/src/list.c - ${NRF_WIFI_DIR}/utils/src/queue.c - ${NRF_WIFI_DIR}/utils/src/util.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_api.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_fw_patch_loader.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_interrupt.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_mem.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_reg.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hpqm.c - ${NRF_WIFI_DIR}/hw_if/hal/src/pal.c - ${NRF_WIFI_DIR}/bus_if/bal/src/bal.c - ${NRF_WIFI_DIR}/bus_if/bus/qspi/src/qspi.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/cmd.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/event.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_api_common.c -) - -if(CONFIG_NRF70_RADIO_TEST) - zephyr_library_sources( - ${NRF_WIFI_DIR}/fw_if/umac_if/src/radio_test/fmac_api.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c - ) -elseif(CONFIG_NRF70_OFFLOADED_RAW_TX) - zephyr_library_sources( - ${NRF_WIFI_DIR}/fw_if/umac_if/src/offload_raw_tx/fmac_api.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c - ) -else() - zephyr_library_sources( - ${NRF_WIFI_DIR}/fw_if/umac_if/src/rx.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_vif.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/default/fmac_api.c - ) -endif() - -zephyr_library_sources_ifdef(CONFIG_NRF70_DATA_TX - ${NRF_WIFI_DIR}/fw_if/umac_if/src/tx.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_peer.c -) - -zephyr_library_sources_ifdef(CONFIG_NRF70_STA_MODE - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_peer.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c -) - -zephyr_library_sources_ifdef(CONFIG_NRF70_PROMISC_DATA_RX - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_promisc.c -) - -zephyr_library_sources_ifdef(CONFIG_NRF70_AP_MODE - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_ap.c -) - -# Without WPA supplicant we only support scan -zephyr_library_sources_ifdef(CONFIG_NRF70_STA_MODE - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_peer.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c -) - -zephyr_library_sources( - shim.c - timer.c - work.c -) - -target_link_libraries(zephyr_interface INTERFACE nrf-wifi-interface) +add_subdirectory_ifdef(CONFIG_WIFI_NRF70 os) +add_subdirectory_ifdef(CONFIG_NRF70_BUSLIB bus) diff --git a/modules/nrf_wifi/Kconfig b/modules/nrf_wifi/Kconfig index 9fe8172c68d..655fce838e5 100644 --- a/modules/nrf_wifi/Kconfig +++ b/modules/nrf_wifi/Kconfig @@ -3,3 +3,5 @@ config ZEPHYR_NRF_WIFI_MODULE bool + +source "modules/nrf_wifi/bus/Kconfig" diff --git a/modules/nrf_wifi/bus/CMakeLists.txt b/modules/nrf_wifi/bus/CMakeLists.txt new file mode 100644 index 00000000000..f939ce3287c --- /dev/null +++ b/modules/nrf_wifi/bus/CMakeLists.txt @@ -0,0 +1,27 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Check if ZEPHYR_BASE is set +if(NOT DEFINED ENV{ZEPHYR_BASE}) + message(FATAL_ERROR "ZEPHYR_BASE environment variable is not set. Please set it to the Zephyr base directory.") +endif() + +if (CONFIG_NRF70_BUSLIB) + zephyr_library_named(nrf70-buslib) + zephyr_library_include_directories( + inc + ) + zephyr_library_sources( + rpu_hw_if.c + device.c + ) + zephyr_library_sources_ifdef(CONFIG_NRF70_ON_QSPI + qspi_if.c + ) + zephyr_library_sources_ifdef(CONFIG_NRF70_ON_SPI + spi_if.c + ) +endif() diff --git a/modules/nrf_wifi/bus/Kconfig b/modules/nrf_wifi/bus/Kconfig new file mode 100644 index 00000000000..152904e86b7 --- /dev/null +++ b/modules/nrf_wifi/bus/Kconfig @@ -0,0 +1,46 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# + +DT_COMPAT_NORDIC_NRF7002_QSPI := nordic,nrf7002-qspi +DT_COMPAT_NORDIC_NRF7002_SPI := nordic,nrf7002-spi +DT_COMPAT_NORDIC_NRF7001_QSPI := nordic,nrf7001-qspi +DT_COMPAT_NORDIC_NRF7001_SPI := nordic,nrf7001-spi +DT_COMPAT_NORDIC_NRF7000_QSPI := nordic,nrf7000-qspi +DT_COMPAT_NORDIC_NRF7000_SPI := nordic,nrf7000-spi + +menuconfig NRF70_BUSLIB + bool "NRF70 Bus Library" + help + Enable the NRF70 Bus Library for the nRF7002 Wi-Fi shield. + +if NRF70_BUSLIB + +config NRF70_ON_QSPI + def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF7002_QSPI)) ||\ + $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF7001_QSPI)) ||\ + $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF7000_QSPI)) + select NRFX_QSPI + +config NRF70_ON_SPI + def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF7002_SPI)) ||\ + $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF7001_SPI)) ||\ + $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF7000_SPI)) + select SPI + +module = WIFI_NRF70_BUSLIB +module-dep = LOG +module-str = Log level for Wi-Fi nRF70 bus library +source "${ZEPHYR_BASE}/subsys/logging/Kconfig.template.log_config" + +config WIFI_NRF70_BUSLIB_LOG_LEVEL + # Enable error by default + default 1 + +config NRF70_LOG_VERBOSE + bool "Maintains the verbosity of information in logs" + default y + +endif # NRF70_BUSLIB diff --git a/drivers/wifi/nrf_wifi/src/qspi/src/device.c b/modules/nrf_wifi/bus/device.c similarity index 78% rename from drivers/wifi/nrf_wifi/src/qspi/src/device.c rename to modules/nrf_wifi/bus/device.c index 4acbaf3861f..8cf0b77cd67 100644 --- a/drivers/wifi/nrf_wifi/src/qspi/src/device.c +++ b/modules/nrf_wifi/bus/device.c @@ -12,30 +12,26 @@ #include #include #include +#include #include #include -#include "qspi_if.h" #include "spi_if.h" static struct qspi_config config; #if defined(CONFIG_NRF70_ON_QSPI) -static struct qspi_dev qspi = { - .init = qspi_init, - .deinit = qspi_deinit, - .read = qspi_read, - .write = qspi_write, - .hl_read = qspi_hl_read -}; +static struct qspi_dev qspi = {.init = qspi_init, + .deinit = qspi_deinit, + .read = qspi_read, + .write = qspi_write, + .hl_read = qspi_hl_read}; #else -static struct qspi_dev spim = { - .init = spim_init, - .deinit = spim_deinit, - .read = spim_read, - .write = spim_write, - .hl_read = spim_hl_read -}; +static struct qspi_dev spim = {.init = spim_init, + .deinit = spim_deinit, + .read = spim_read, + .write = spim_write, + .hl_read = spim_hl_read}; #endif struct qspi_config *qspi_defconfig(void) diff --git a/drivers/wifi/nrf_wifi/src/qspi/src/qspi_if.c b/modules/nrf_wifi/bus/qspi_if.c similarity index 99% rename from drivers/wifi/nrf_wifi/src/qspi/src/qspi_if.c rename to modules/nrf_wifi/bus/qspi_if.c index 754fe149713..8c381ff60c5 100644 --- a/drivers/wifi/nrf_wifi/src/qspi/src/qspi_if.c +++ b/modules/nrf_wifi/bus/qspi_if.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -23,7 +24,6 @@ #include #include "spi_nor.h" -#include "qspi_if.h" /* The QSPI bus node which the NRF70 is on */ #define QSPI_IF_BUS_NODE DT_NODELABEL(qspi) @@ -152,7 +152,7 @@ static void qspi_device_uninit(const struct device *dev); #define WORD_SIZE 4 -LOG_MODULE_DECLARE(wifi_nrf_bus, CONFIG_WIFI_NRF70_BUS_LOG_LEVEL); +LOG_MODULE_DECLARE(wifi_nrf_bus, CONFIG_WIFI_NRF70_BUSLIB_LOG_LEVEL); /** * @brief QSPI buffer structure diff --git a/drivers/wifi/nrf_wifi/src/qspi/src/rpu_hw_if.c b/modules/nrf_wifi/bus/rpu_hw_if.c similarity index 96% rename from drivers/wifi/nrf_wifi/src/qspi/src/rpu_hw_if.c rename to modules/nrf_wifi/bus/rpu_hw_if.c index 6fac7412362..8b9393f6f2e 100644 --- a/drivers/wifi/nrf_wifi/src/qspi/src/rpu_hw_if.c +++ b/modules/nrf_wifi/bus/rpu_hw_if.c @@ -17,12 +17,12 @@ #include #include #include +#include +#include -#include "rpu_hw_if.h" -#include "qspi_if.h" #include "spi_if.h" -LOG_MODULE_REGISTER(wifi_nrf_bus, CONFIG_WIFI_NRF70_BUS_LOG_LEVEL); +LOG_MODULE_REGISTER(wifi_nrf_bus, CONFIG_WIFI_NRF70_BUSLIB_LOG_LEVEL); #define NRF7002_NODE DT_NODELABEL(nrf70) @@ -44,7 +44,7 @@ uint32_t rpu_7002_memmap[][3] = { { 0x009000, 0x03FFFF, 2 }, { 0x040000, 0x07FFFF, 1 }, { 0x0C0000, 0x0F0FFF, 0 }, - { 0x080000, 0x092000, 1 }, + { 0x080000, 0x092000, 2 }, { 0x100000, 0x134000, 1 }, { 0x140000, 0x14C000, 1 }, { 0x180000, 0x190000, 1 }, @@ -483,11 +483,16 @@ int rpu_enable(void) goto rpu_pwroff; } +/* TODO: rpu_validate_comms() needs firmware download to be done + * successfully before it can be called. So, disable this for + * nrf70_buslib only usage. + */ +#ifdef CONFIG_WIFI_NRF70 ret = rpu_validate_comms(); if (ret) { goto rpu_pwroff; } - +#endif return 0; rpu_pwroff: rpu_pwroff(); diff --git a/drivers/wifi/nrf_wifi/src/qspi/src/spi_if.c b/modules/nrf_wifi/bus/spi_if.c similarity index 98% rename from drivers/wifi/nrf_wifi/src/qspi/src/spi_if.c rename to modules/nrf_wifi/bus/spi_if.c index 4bf9f464391..fba9f1f00bf 100644 --- a/drivers/wifi/nrf_wifi/src/qspi/src/spi_if.c +++ b/modules/nrf_wifi/bus/spi_if.c @@ -13,11 +13,11 @@ #include #include +#include -#include "qspi_if.h" #include "spi_if.h" -LOG_MODULE_DECLARE(wifi_nrf_bus, CONFIG_WIFI_NRF70_BUS_LOG_LEVEL); +LOG_MODULE_DECLARE(wifi_nrf_bus, CONFIG_WIFI_NRF70_BUSLIB_LOG_LEVEL); #define NRF7002_NODE DT_NODELABEL(nrf70) diff --git a/drivers/wifi/nrf_wifi/src/qspi/inc/spi_if.h b/modules/nrf_wifi/bus/spi_if.h similarity index 100% rename from drivers/wifi/nrf_wifi/src/qspi/inc/spi_if.h rename to modules/nrf_wifi/bus/spi_if.h diff --git a/drivers/wifi/nrf_wifi/src/qspi/inc/spi_nor.h b/modules/nrf_wifi/bus/spi_nor.h similarity index 100% rename from drivers/wifi/nrf_wifi/src/qspi/inc/spi_nor.h rename to modules/nrf_wifi/bus/spi_nor.h diff --git a/modules/nrf_wifi/os/CMakeLists.txt b/modules/nrf_wifi/os/CMakeLists.txt new file mode 100644 index 00000000000..daef05f2098 --- /dev/null +++ b/modules/nrf_wifi/os/CMakeLists.txt @@ -0,0 +1,186 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(NOT CONFIG_WIFI_NRF70) + return() +endif() +zephyr_interface_library_named(nrf-wifi-interface) +zephyr_library() + +set(NRF_WIFI_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) + +# Translate the configuration to the OS agnostic code +target_compile_definitions( + nrf-wifi-interface + INTERFACE + $<$:NRF_WIFI_LOW_POWER> + $<$:NRF_WIFI_RPU_RECOVERY> + $<$:NRF_WIFI_AP_DEAD_DETECT_TIMEOUT=${CONFIG_NRF_WIFI_AP_DEAD_DETECT_TIMEOUT}> + $<$:NRF_WIFI_IFACE_MTU=${CONFIG_NRF_WIFI_IFACE_MTU}> + $<$:NRF70_STA_MODE> + $<$:NRF70_DATA_TX> + $<$:NRF70_RAW_DATA_TX> + $<$:NRF70_RAW_DATA_RX> + $<$:NRF70_PROMISC_DATA_RX> + $<$:NRF70_TX_DONE_WQ_ENABLED> + $<$:NRF70_RX_WQ_ENABLED> + $<$:NRF70_UTIL> + $<$:NRF70_RADIO_TEST> + $<$:NRF70_OFFLOADED_RAW_TX> + $<$:NRF70_TCP_IP_CHECKSUM_OFFLOAD> + $<$:NRF70_RPU_EXTEND_TWT_SP> + $<$:NRF70_SYSTEM_WITH_RAW_MODES> + $<$:NRF70_SCAN_ONLY> + $<$:NRF70_SYSTEM_MODE> + $<$:NRF70_2_4G_ONLY> + $<$:NRF70_LOG_VERBOSE> + $<$:NRF70_AP_MODE> + $<$:NRF_WIFI_MGMT_BUFF_OFFLOAD> + $<$:NRF_WIFI_FEAT_KEEPALIVE> + $<$:NRF_WIFI_KEEPALIVE_PERIOD_S=${CONFIG_NRF_WIFI_KEEPALIVE_PERIOD_S}> + $<$:WIFI_MGMT_RAW_SCAN_RESULTS> + NRF70_RX_NUM_BUFS=${CONFIG_NRF70_RX_NUM_BUFS} + NRF70_MAX_TX_TOKENS=${CONFIG_NRF70_MAX_TX_TOKENS} + NRF70_RX_MAX_DATA_SIZE=${CONFIG_NRF70_RX_MAX_DATA_SIZE} + NRF70_MAX_TX_PENDING_QLEN=${CONFIG_NRF70_MAX_TX_PENDING_QLEN} + NRF70_RPU_PS_IDLE_TIMEOUT_MS=${CONFIG_NRF70_RPU_PS_IDLE_TIMEOUT_MS} + NRF70_REG_DOMAIN=${CONFIG_NRF70_REG_DOMAIN} + NRF70_BAND_2G_LOWER_EDGE_BACKOFF_DSSS=${CONFIG_NRF70_BAND_2G_LOWER_EDGE_BACKOFF_DSSS} + NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HT} + NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HE} + NRF70_BAND_2G_UPPER_EDGE_BACKOFF_DSSS=${CONFIG_NRF70_BAND_2G_UPPER_EDGE_BACKOFF_DSSS} + NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HT} + NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HE} + NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HT} + NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HE} + NRF70_PCB_LOSS_2G=${CONFIG_NRF70_PCB_LOSS_2G} + NRF70_PCB_LOSS_5G_BAND1=${CONFIG_NRF70_PCB_LOSS_5G_BAND1} + NRF70_PCB_LOSS_5G_BAND2=${CONFIG_NRF70_PCB_LOSS_5G_BAND2} + NRF70_PCB_LOSS_5G_BAND3=${CONFIG_NRF70_PCB_LOSS_5G_BAND3} + NRF70_ANT_GAIN_2G=${CONFIG_NRF70_ANT_GAIN_2G} + NRF70_ANT_GAIN_5G_BAND1=${CONFIG_NRF70_ANT_GAIN_5G_BAND1} + NRF70_ANT_GAIN_5G_BAND2=${CONFIG_NRF70_ANT_GAIN_5G_BAND2} + NRF70_ANT_GAIN_5G_BAND3=${CONFIG_NRF70_ANT_GAIN_5G_BAND3} + NRF_WIFI_PS_INT_PS=${CONFIG_NRF_WIFI_PS_INT_PS} + NRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS=${CONFIG_NRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS} +) + +target_include_directories( + nrf-wifi-interface + INTERFACE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../bus + ${NRF_WIFI_DIR}/utils/inc + ${NRF_WIFI_DIR}/os_if/inc + ${NRF_WIFI_DIR}/bus_if/bus/qspi/inc + ${NRF_WIFI_DIR}/bus_if/bal/inc + ${NRF_WIFI_DIR}/fw_if/umac_if/inc + ${NRF_WIFI_DIR}/fw_load/mips/fw/inc + ${NRF_WIFI_DIR}/hw_if/hal/inc + ${NRF_WIFI_DIR}/hw_if/hal/inc/fw + ${NRF_WIFI_DIR}/fw_if/umac_if/inc/fw +) + +if(CONFIG_NRF70_RADIO_TEST) + target_include_directories(nrf-wifi-interface INTERFACE + ${NRF_WIFI_DIR}/fw_if/umac_if/inc/radio_test + ) +elseif(CONFIG_NRF70_OFFLOADED_RAW_TX) + target_include_directories(nrf-wifi-interface INTERFACE + ${NRF_WIFI_DIR}/fw_if/umac_if/inc/offload_raw_tx + off_raw_tx/inc + ) +else() + target_include_directories(nrf-wifi-interface INTERFACE + ${NRF_WIFI_DIR}/fw_if/umac_if/inc/default + ) +endif() + +zephyr_library_sources( + ${NRF_WIFI_DIR}/os_if/src/osal.c + ${NRF_WIFI_DIR}/utils/src/list.c + ${NRF_WIFI_DIR}/utils/src/queue.c + ${NRF_WIFI_DIR}/utils/src/util.c + ${NRF_WIFI_DIR}/hw_if/hal/src/hal_api.c + ${NRF_WIFI_DIR}/hw_if/hal/src/hal_fw_patch_loader.c + ${NRF_WIFI_DIR}/hw_if/hal/src/hal_interrupt.c + ${NRF_WIFI_DIR}/hw_if/hal/src/hal_mem.c + ${NRF_WIFI_DIR}/hw_if/hal/src/hal_reg.c + ${NRF_WIFI_DIR}/hw_if/hal/src/hpqm.c + ${NRF_WIFI_DIR}/hw_if/hal/src/pal.c + ${NRF_WIFI_DIR}/bus_if/bal/src/bal.c + ${NRF_WIFI_DIR}/bus_if/bus/qspi/src/qspi.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/cmd.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/event.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_api_common.c +) + +if(CONFIG_NRF70_RADIO_TEST) + zephyr_library_sources( + ${NRF_WIFI_DIR}/fw_if/umac_if/src/radio_test/fmac_api.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c + ) +elseif(CONFIG_NRF70_OFFLOADED_RAW_TX) + zephyr_library_sources( + ${NRF_WIFI_DIR}/fw_if/umac_if/src/offload_raw_tx/fmac_api.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c + ) +else() + zephyr_library_sources( + ${NRF_WIFI_DIR}/fw_if/umac_if/src/rx.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_vif.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/default/fmac_api.c + ) +endif() + +zephyr_library_sources_ifdef(CONFIG_NRF70_DATA_TX + ${NRF_WIFI_DIR}/fw_if/umac_if/src/tx.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_peer.c +) + +zephyr_library_sources_ifdef(CONFIG_NRF70_STA_MODE + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_peer.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c +) + +zephyr_library_sources_ifdef(CONFIG_NRF70_PROMISC_DATA_RX + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_promisc.c +) + +zephyr_library_sources_ifdef(CONFIG_NRF70_AP_MODE + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_ap.c +) + +# Without WPA supplicant we only support scan +zephyr_library_sources_ifdef(CONFIG_NRF70_STA_MODE + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_peer.c + ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c +) + +zephyr_library_sources( + shim.c + timer.c + work.c +) + +target_link_libraries(zephyr_interface INTERFACE nrf-wifi-interface) +target_link_libraries(nrf_wifi PRIVATE nrf70-buslib) diff --git a/modules/nrf_wifi/shim.c b/modules/nrf_wifi/os/shim.c similarity index 99% rename from modules/nrf_wifi/shim.c rename to modules/nrf_wifi/os/shim.c index 93cafa905c2..ed6acf95846 100644 --- a/modules/nrf_wifi/shim.c +++ b/modules/nrf_wifi/os/shim.c @@ -18,13 +18,13 @@ #include #include #include +#include +#include -#include "rpu_hw_if.h" #include "shim.h" #include "work.h" #include "timer.h" #include "osal_ops.h" -#include "qspi_if.h" LOG_MODULE_REGISTER(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); diff --git a/modules/nrf_wifi/shim.h b/modules/nrf_wifi/os/shim.h similarity index 100% rename from modules/nrf_wifi/shim.h rename to modules/nrf_wifi/os/shim.h diff --git a/modules/nrf_wifi/timer.c b/modules/nrf_wifi/os/timer.c similarity index 100% rename from modules/nrf_wifi/timer.c rename to modules/nrf_wifi/os/timer.c diff --git a/modules/nrf_wifi/timer.h b/modules/nrf_wifi/os/timer.h similarity index 100% rename from modules/nrf_wifi/timer.h rename to modules/nrf_wifi/os/timer.h diff --git a/modules/nrf_wifi/work.c b/modules/nrf_wifi/os/work.c similarity index 100% rename from modules/nrf_wifi/work.c rename to modules/nrf_wifi/os/work.c diff --git a/modules/nrf_wifi/work.h b/modules/nrf_wifi/os/work.h similarity index 100% rename from modules/nrf_wifi/work.h rename to modules/nrf_wifi/os/work.h diff --git a/samples/boards/nordic/system_off/CMakeLists.txt b/samples/boards/nordic/system_off/CMakeLists.txt index 1cff779506b..986fca97f34 100644 --- a/samples/boards/nordic/system_off/CMakeLists.txt +++ b/samples/boards/nordic/system_off/CMakeLists.txt @@ -5,6 +5,6 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(nrf_system_off) target_sources(app PRIVATE src/main.c) -if (CONFIG_APP_USE_NRF_RETENTION OR CONFIG_APP_USE_RETAINED_MEM) +if (CONFIG_APP_USE_RETAINED_MEM) target_sources(app PRIVATE src/retained.c) endif() diff --git a/samples/boards/nordic/system_off/Kconfig b/samples/boards/nordic/system_off/Kconfig index c5a0f492d90..798927205bd 100644 --- a/samples/boards/nordic/system_off/Kconfig +++ b/samples/boards/nordic/system_off/Kconfig @@ -3,23 +3,9 @@ mainmenu "Nordic SYSTEM_OFF demo" -choice - prompt "Use retention" - optional - -config APP_USE_NRF_RETENTION - bool "Use state retention in system off using nRF POWER" - depends on SOC_COMPATIBLE_NRF52X && CRC - help - On some Nordic chips this application supports retaining - memory while in system off using POWER peripheral. - Select this to enable the feature. - config APP_USE_RETAINED_MEM bool "Use state retention in system off using retained_mem driver" - depends on RETAINED_MEM - -endchoice + select RETAINED_MEM config GRTC_WAKEUP_ENABLE bool "Use GRTC to wake up device from system off" diff --git a/samples/boards/nordic/system_off/README.rst b/samples/boards/nordic/system_off/README.rst index 7c98a4e8336..5124d087b77 100644 --- a/samples/boards/nordic/system_off/README.rst +++ b/samples/boards/nordic/system_off/README.rst @@ -13,10 +13,10 @@ deep sleep on Nordic platforms. RAM Retention ============= -This sample can also can demonstrate RAM retention. By selecting -``CONFIG_APP_USE_NRF_RETENTION=y`` or ``CONFIG_APP_USE_RETAINED_MEM=y`` -state related to number of boots, number of times system off was entered, -and total uptime since initial power-on are retained in a checksummed data structure. +This sample can also demonstrate RAM retention. +By selecting ``CONFIG_APP_USE_RETAINED_MEM=y`` state related to number of boots, +number of times system off was entered, and total uptime since initial power-on +are retained in a checksummed data structure. RAM is configured to keep the containing section powered while in system-off mode. Requirements diff --git a/samples/boards/nordic/system_off/boards/nrf52840dk_nrf52840.overlay b/samples/boards/nordic/system_off/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000..c203d90a0a1 --- /dev/null +++ b/samples/boards/nordic/system_off/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,22 @@ +/ { + sram0@2003f000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x2003f000 DT_SIZE_K(4)>; + zephyr,memory-region = "RetainedMem"; + status = "okay"; + + retainedmem0: retainedmem { + compatible = "zephyr,retained-ram"; + status = "okay"; + }; + }; + + aliases { + retainedmemdevice = &retainedmem0; + }; +}; + +&sram0 { + /* Shrink SRAM size to avoid overlap with retained memory region */ + reg = <0x20000000 DT_SIZE_K(252)>; +}; diff --git a/samples/boards/nordic/system_off/boards/nrf52dk_nrf52832.overlay b/samples/boards/nordic/system_off/boards/nrf52dk_nrf52832.overlay new file mode 100644 index 00000000000..13e2e99ddf2 --- /dev/null +++ b/samples/boards/nordic/system_off/boards/nrf52dk_nrf52832.overlay @@ -0,0 +1,22 @@ +/ { + sram0@20007000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20007000 DT_SIZE_K(4)>; + zephyr,memory-region = "RetainedMem"; + status = "okay"; + + retainedmem0: retainedmem { + compatible = "zephyr,retained-ram"; + status = "okay"; + }; + }; + + aliases { + retainedmemdevice = &retainedmem0; + }; +}; + +&sram0 { + /* Shrink SRAM size to avoid overlap with retained memory region */ + reg = <0x20000000 DT_SIZE_K(28)>; +}; diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp_retained_mem.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp.overlay similarity index 100% rename from samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp_retained_mem.overlay rename to samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp.overlay diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp_retained_mem.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp.overlay similarity index 100% rename from samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp_retained_mem.overlay rename to samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp.overlay diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp.overlay similarity index 100% rename from samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay rename to samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp.overlay diff --git a/samples/boards/nordic/system_off/sample.yaml b/samples/boards/nordic/system_off/sample.yaml index 18f629c4e54..fcc96f6c44d 100644 --- a/samples/boards/nordic/system_off/sample.yaml +++ b/samples/boards/nordic/system_off/sample.yaml @@ -22,32 +22,17 @@ tests: - "system off demo" - "Retained data not supported" - "Entering system off; press sw0 to restart" - sample.boards.nrf.system_off.nrf_retained: + sample.boards.nrf.system_off.retained_mem: integration_platforms: - nrf52840dk/nrf52840 platform_allow: - nrf52840dk/nrf52840 - nrf52dk/nrf52832 - extra_configs: - - CONFIG_APP_USE_NRF_RETENTION=y - harness: console - harness_config: - type: multi_line - ordered: true - regex: - - "system off demo" - - "Retained data: INVALID" - - "Boot count: 1" - - "Off count: 0" - - "Active Ticks:" - - "Entering system off; press sw0 to restart" - sample.boards.nrf.system_off.retained_mem: - extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay" - platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54l15dk/nrf54l10/cpuapp + - nrf54l15dk/nrf54l05/cpuapp extra_configs: - CONFIG_APP_USE_RETAINED_MEM=y - - CONFIG_RETAINED_MEM=y harness: console harness_config: type: multi_line @@ -62,6 +47,8 @@ tests: sample.boards.nrf.system_off.grtc_wakeup: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54l15dk/nrf54l10/cpuapp + - nrf54l15dk/nrf54l05/cpuapp extra_configs: - CONFIG_GRTC_WAKEUP_ENABLE=y harness: console @@ -79,13 +66,13 @@ tests: - "Retained data not supported" - "Entering system off; wait 2 seconds to restart" sample.boards.nrf.system_off.retained_mem.grtc_wakeup: - extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay" platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54l15dk/nrf54l10/cpuapp + - nrf54l15dk/nrf54l05/cpuapp extra_configs: - CONFIG_APP_USE_RETAINED_MEM=y - CONFIG_GRTC_WAKEUP_ENABLE=y - - CONFIG_RETAINED_MEM=y harness: console harness_config: type: multi_line diff --git a/samples/boards/nordic/system_off/src/main.c b/samples/boards/nordic/system_off/src/main.c index b40b1ea26da..40c4f2bb7a5 100644 --- a/samples/boards/nordic/system_off/src/main.c +++ b/samples/boards/nordic/system_off/src/main.c @@ -35,7 +35,7 @@ int main(void) printf("\n%s system off demo\n", CONFIG_BOARD); - if (IS_ENABLED(CONFIG_APP_USE_NRF_RETENTION) || IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) { + if (IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) { bool retained_ok = retained_validate(); /* Increment for this boot attempt and update. */ @@ -81,7 +81,7 @@ int main(void) return 0; } - if (IS_ENABLED(CONFIG_APP_USE_NRF_RETENTION) || IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) { + if (IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) { /* Update the retained state */ retained.off_count += 1; retained_update(); diff --git a/samples/boards/nordic/system_off/src/retained.c b/samples/boards/nordic/system_off/src/retained.c index 66f6a353f04..316ec165d62 100644 --- a/samples/boards/nordic/system_off/src/retained.c +++ b/samples/boards/nordic/system_off/src/retained.c @@ -15,147 +15,24 @@ #include #include -#if CONFIG_APP_USE_NRF_RETENTION -#include - -/* nRF52 RAM (really, RAM AHB slaves) are partitioned as: - * * Up to 8 blocks of two 4 KiBy byte "small" sections - * * A 9th block of with 32 KiBy "large" sections - * - * At time of writing the maximum number of large sections is 6, all - * within the first large block. Theoretically there could be more - * sections in the 9th block, and possibly more blocks. - */ - -/* Inclusive address of RAM start */ -#define SRAM_BEGIN (uintptr_t)DT_REG_ADDR(DT_NODELABEL(sram0)) - -/* Exclusive address of RAM end */ -#define SRAM_END (SRAM_BEGIN + (uintptr_t)DT_REG_SIZE(DT_NODELABEL(sram0))) - -/* Size of a controllable RAM section in the small blocks */ -#define SMALL_SECTION_SIZE 4096 - -/* Number of controllable RAM sections in each of the lower blocks */ -#define SMALL_SECTIONS_PER_BLOCK 2 - -/* Span of a small block */ -#define SMALL_BLOCK_SIZE (SMALL_SECTIONS_PER_BLOCK * SMALL_SECTION_SIZE) - -/* Number of small blocks */ -#define SMALL_BLOCK_COUNT 8 - -/* Span of the SRAM area covered by small sections */ -#define SMALL_SECTION_SPAN (SMALL_BLOCK_COUNT * SMALL_BLOCK_SIZE) - -/* Inclusive address of the RAM range covered by large sections */ -#define LARGE_SECTION_BEGIN (SRAM_BEGIN + SMALL_SECTION_SPAN) - -/* Size of a controllable RAM section in large blocks */ -#define LARGE_SECTION_SIZE 32768 - -#elif CONFIG_APP_USE_RETAINED_MEM +#if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(retainedmemdevice)) const static struct device *retained_mem_device = DEVICE_DT_GET(DT_ALIAS(retainedmemdevice)); -#endif - -/* Set or clear RAM retention in SYSTEM_OFF for the provided object. - * - * @param ptr pointer to the start of the retainable object - * - * @param len length of the retainable object - * - * @param enable true to enable retention, false to clear retention - */ -static int ram_range_retain(const void *ptr, - size_t len, - bool enable) -{ - int rc = 0; - -#if CONFIG_APP_USE_NRF_RETENTION - /* This only works for nRF52 with the POWER module. - * The other Nordic chips use a different low-level API, - * which is not currently used by this variant. - */ - uintptr_t addr = (uintptr_t)ptr; - uintptr_t addr_end = addr + len; - - /* Error if the provided range is empty or doesn't lie - * entirely within the SRAM address space. - */ - if ((len == 0U) - || (addr < SRAM_BEGIN) - || (addr > (SRAM_END - len))) { - return -EINVAL; - } - - /* Iterate over each section covered by the range, setting the - * corresponding RAM OFF retention bit in the parent block. - */ - do { - uintptr_t block_base = SRAM_BEGIN; - uint32_t section_size = SMALL_SECTION_SIZE; - uint32_t sections_per_block = SMALL_SECTIONS_PER_BLOCK; - bool is_large = (addr >= LARGE_SECTION_BEGIN); - uint8_t block = 0; - - if (is_large) { - block = 8; - block_base = LARGE_SECTION_BEGIN; - section_size = LARGE_SECTION_SIZE; - - /* RAM[x] supports only 16 sections, each its own bit - * for POWER (0..15) and RETENTION (16..31). We don't - * know directly how many sections are present, so - * assume they all are; the true limit will be - * determined by the SRAM size. - */ - sections_per_block = 16; - } - - uint32_t section = (addr - block_base) / section_size; - - if (section >= sections_per_block) { - block += section / sections_per_block; - section %= sections_per_block; - } - - uint32_t section_mask = - (POWER_RAM_POWERSET_S0RETENTION_On - << (section + POWER_RAM_POWERSET_S0RETENTION_Pos)); - - if (enable) { - nrf_power_rampower_mask_on(NRF_POWER, block, section_mask); - } else { - nrf_power_rampower_mask_off(NRF_POWER, block, section_mask); - } - - /* Move to the first address in the next section. */ - addr += section_size - (addr % section_size); - } while (addr < addr_end); -#elif CONFIG_APP_USE_RETAINED_MEM - /* Retention setting cannot be controlled runtime with retained_mem API */ - (void)enable; - rc = retained_mem_write(retained_mem_device, 0, ptr, len); #else - #error "Unsupported retention setting" +#error "retained_mem region not defined" #endif - return rc; -} - -/* Retained data must be defined in a no-init section to prevent the C - * runtime initialization from zeroing it before anybody can see it. - * It is not necesarry when retained_mem driver is utilized - * as in this case retained data is stored in an area not initialized in runtime. - */ -__noinit struct retained_data retained; +struct retained_data retained; #define RETAINED_CRC_OFFSET offsetof(struct retained_data, crc) #define RETAINED_CHECKED_SIZE (RETAINED_CRC_OFFSET + sizeof(retained.crc)) bool retained_validate(void) { + int rc; + + rc = retained_mem_read(retained_mem_device, 0, (uint8_t *)&retained, sizeof(retained)); + __ASSERT_NO_MSG(rc == 0); + /* The residue of a CRC is what you get from the CRC over the * message catenated with its CRC. This is the post-final-xor * residue for CRC-32 (CRC-32/ISO-HDLC) which Zephyr calls @@ -174,19 +51,13 @@ bool retained_validate(void) /* Reset to accrue runtime from this session. */ retained.uptime_latest = 0; - /* Reconfigure to retain the state during system off, regardless of - * whether validation succeeded. Although these values can sometimes - * be observed to be preserved across System OFF, the product - * specification states they are not retained in that situation, and - * that can also be observed. - */ - (void)ram_range_retain(&retained, RETAINED_CHECKED_SIZE, true); - return valid; } void retained_update(void) { + int rc; + uint64_t now = k_uptime_ticks(); retained.uptime_sum += (now - retained.uptime_latest); @@ -196,4 +67,7 @@ void retained_update(void) RETAINED_CRC_OFFSET); retained.crc = sys_cpu_to_le32(crc); + + rc = retained_mem_write(retained_mem_device, 0, (uint8_t *)&retained, sizeof(retained)); + __ASSERT_NO_MSG(rc == 0); } diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml index 8bbae88d901..33b37512615 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml +++ b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml @@ -13,6 +13,7 @@ tests: - pinnacle_100_dvk - mg100 - nrf54l15dk/nrf54l15/cpuapp + - nrf54l15dk/nrf54l10/cpuapp integration_platforms: - nrf52dk/nrf52832 - nrf52840dk/nrf52840 @@ -114,6 +115,8 @@ tests: - CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54l15dk/nrf54l10/cpuapp + - nrf54l15dk/nrf54l05/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp sample.mcumgr.smp_svr.bt.nrf54l15dk.ext_flash.pure_dts: @@ -125,5 +128,7 @@ tests: - SB_CONFIG_PARTITION_MANAGER=n platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54l15dk/nrf54l10/cpuapp + - nrf54l15dk/nrf54l05/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp diff --git a/soc/nordic/common/Kconfig b/soc/nordic/common/Kconfig index ef32e7403c1..e7e24ca8cf2 100644 --- a/soc/nordic/common/Kconfig +++ b/soc/nordic/common/Kconfig @@ -4,6 +4,9 @@ config HAS_NORDIC_DMM bool +config HAS_NORDIC_RAM_CTRL + bool "nRF RAM control helper support" + config NRF_SYS_EVENT bool "nRF system event support" select NRFX_POWER if !NRF_PLATFORM_HALTIUM diff --git a/soc/nordic/common/poweroff.c b/soc/nordic/common/poweroff.c index b3210da697d..99a2bcfb3d6 100644 --- a/soc/nordic/common/poweroff.c +++ b/soc/nordic/common/poweroff.c @@ -5,6 +5,7 @@ #include #include +#include #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) #include @@ -17,8 +18,45 @@ #include #endif +#if defined(CONFIG_HAS_NORDIC_RAM_CTRL) +#include +#endif + void z_sys_poweroff(void) { +#if defined(CONFIG_HAS_NORDIC_RAM_CTRL) + uint8_t *ram_start; + size_t ram_size; + +#if defined(NRF_MEMORY_RAM_BASE) + ram_start = (uint8_t *)NRF_MEMORY_RAM_BASE; +#else + ram_start = (uint8_t *)NRF_MEMORY_RAM0_BASE; +#endif + + ram_size = 0; +#if defined(NRF_MEMORY_RAM_SIZE) + ram_size += NRF_MEMORY_RAM_SIZE; +#endif +#if defined(NRF_MEMORY_RAM0_SIZE) + ram_size += NRF_MEMORY_RAM0_SIZE; +#endif +#if defined(NRF_MEMORY_RAM1_SIZE) + ram_size += NRF_MEMORY_RAM1_SIZE; +#endif +#if defined(NRF_MEMORY_RAM2_SIZE) + ram_size += NRF_MEMORY_RAM2_SIZE; +#endif + + /* Disable retention for all memory blocks */ + nrfx_ram_ctrl_retention_enable_set(ram_start, ram_size, false); +#endif + +#if defined(CONFIG_RETAINED_MEM_NRF_RAM_CTRL) + /* Restore retention for retained_mem driver regions defined in devicetree */ + (void)z_nrf_retained_mem_retention_apply(); +#endif + #if defined(CONFIG_SOC_SERIES_NRF54LX) nrfx_reset_reason_clear(UINT32_MAX); #endif diff --git a/soc/nordic/nrf52/Kconfig b/soc/nordic/nrf52/Kconfig index adb57916627..edc2b70d667 100644 --- a/soc/nordic/nrf52/Kconfig +++ b/soc/nordic/nrf52/Kconfig @@ -11,6 +11,7 @@ config SOC_SERIES_NRF52X imply XIP select HAS_NRFX select HAS_NORDIC_DRIVERS + select HAS_NORDIC_RAM_CTRL select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_SWO select HAS_POWEROFF diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index 3e46ce83077..7698c26d9f2 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -21,6 +21,7 @@ config SOC_NRF54H20_CPUAPP_COMMON select CPU_HAS_FPU select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS select HAS_NORDIC_DMM + select HAS_NORDIC_RAM_CTRL select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select NRFS_HAS_CLOCK_SERVICE select NRFS_HAS_DVFS_SERVICE @@ -52,6 +53,7 @@ config SOC_NRF54H20_CPURAD_COMMON select NRFS_HAS_TEMP_SERVICE select NRFS_HAS_VBUS_DETECTOR_SERVICE select HAS_NORDIC_DMM + select HAS_NORDIC_RAM_CTRL select HAS_PM select HAS_POWEROFF diff --git a/soc/nordic/nrf54l/Kconfig b/soc/nordic/nrf54l/Kconfig index c4cd8e6aa0f..ab5f1c745b9 100644 --- a/soc/nordic/nrf54l/Kconfig +++ b/soc/nordic/nrf54l/Kconfig @@ -20,6 +20,7 @@ config SOC_NRF54L_CPUAPP_COMMON select CPU_HAS_FPU select HAS_HW_NRF_RADIO_IEEE802154 select HAS_POWEROFF + select HAS_NORDIC_RAM_CTRL config SOC_NRF54L05_CPUAPP select SOC_NRF54L_CPUAPP_COMMON diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 8a62c1fb3ba..a51b9a73787 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1264,6 +1264,11 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) */ switch (old_state) { case BT_CONN_DISCONNECT_COMPLETE: + /* Any previously scheduled deferred work now becomes invalid + * so cancel it here, before we yield to tx thread. + */ + k_work_cancel_delayable(&conn->deferred_work); + bt_conn_tx_notify(conn, true); bt_conn_reset_rx_state(conn); diff --git a/tests/boards/nrf/nrf70/bustest/CMakeLists.txt b/tests/boards/nrf/nrf70/bustest/CMakeLists.txt new file mode 100644 index 00000000000..741d622b119 --- /dev/null +++ b/tests/boards/nrf/nrf70/bustest/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: BSD-3-Clause +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(nrf70_bustest) + +target_sources(app PRIVATE + src/main.c +) + +target_link_libraries(app PUBLIC nrf70-buslib) diff --git a/tests/boards/nrf/nrf70/bustest/Kconfig b/tests/boards/nrf/nrf70/bustest/Kconfig new file mode 100644 index 00000000000..d76ab2cda6c --- /dev/null +++ b/tests/boards/nrf/nrf70/bustest/Kconfig @@ -0,0 +1,15 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# +source "Kconfig.zephyr" + +menu "NRF70 Buslib test sample" + +config NRF70BUS_MEMTEST_LENGTH + int "Memory test length" + default 1024 + help + This option sets the default length for the memory test. +endmenu diff --git a/tests/boards/nrf/nrf70/bustest/prj.conf b/tests/boards/nrf/nrf70/bustest/prj.conf new file mode 100644 index 00000000000..52107957801 --- /dev/null +++ b/tests/boards/nrf/nrf70/bustest/prj.conf @@ -0,0 +1,27 @@ +CONFIG_NRF70_BUSLIB=y +CONFIG_ZTEST=y + +CONFIG_HEAP_MEM_POOL_SIZE=50000 +CONFIG_HEAP_MEM_POOL_IGNORE_MIN=y + +# System settings +CONFIG_ASSERT=y + +CONFIG_INIT_STACKS=y + +# Memories +CONFIG_MAIN_STACK_SIZE=5200 + +# Debugging +CONFIG_STACK_SENTINEL=y +CONFIG_DEBUG_COREDUMP=y +CONFIG_DEBUG_COREDUMP_BACKEND_LOGGING=y +CONFIG_SHELL_CMDS_RESIZE=n +CONFIG_WIFI_NRF70_BUSLIB_LOG_LEVEL_DBG=y + +# Logging +CONFIG_LOG=y +CONFIG_PRINTK=y +# If below config is enabled, printk logs are +# buffered. For unbuffered messages, disable this. +CONFIG_LOG_PRINTK=n diff --git a/tests/boards/nrf/nrf70/bustest/src/main.c b/tests/boards/nrf/nrf70/bustest/src/main.c new file mode 100644 index 00000000000..cf7cdfa4164 --- /dev/null +++ b/tests/boards/nrf/nrf70/bustest/src/main.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief File containing ztests for nrf70 buslib library + */ + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(nrf70_bustest, CONFIG_WIFI_NRF70_BUSLIB_LOG_LEVEL); + +#define DATARAM_ADDR 0x0C0000 +static struct qspi_dev *dev; + +static int wifi_on(void *state) +{ + int ret; + + ARG_UNUSED(state); + + dev = qspi_dev(); + + ret = rpu_init(); + if (ret) { + LOG_ERR("%s: RPU init failed with error %d", __func__, ret); + return -1; + } + + ret = dev->init(qspi_defconfig()); + if (ret) { + LOG_ERR("%s: QSPI device init failed", __func__); + return -1; + } + + ret = rpu_enable(); + if (ret) { + LOG_ERR("%s: RPU enable failed with error %d", __func__, ret); + return -1; + } + k_sleep(K_MSEC(10)); + LOG_INF("Wi-Fi ON done"); + return 0; +} + +static void wifi_off(void *state) +{ + ARG_UNUSED(state); + + int ret; + + ret = rpu_disable(); + if (ret) { + LOG_ERR("%s: RPU disable failed with error %d", __func__, ret); + } + + ret = dev->deinit(); + if (ret) { + LOG_ERR("%s: QSPI device de-init failed", __func__); + } + k_sleep(K_MSEC(10)); + LOG_INF("Wi-Fi OFF done"); +} + + +static int memtest(uint32_t addr, char *memblock_name) +{ + const uint32_t pattern = 0x12345678; + uint32_t offset = 1; + uint32_t *buff, *rxbuff; + int i; + + int err_count; + int32_t rem_words = CONFIG_NRF70BUS_MEMTEST_LENGTH; + uint32_t test_chunk, chunk_no = 0; + int ret = -1; + + buff = k_malloc(CONFIG_NRF70BUS_MEMTEST_LENGTH * 4); + if (buff == NULL) { + LOG_ERR("Failed to allocate memory for buff"); + return -1; + } + + rxbuff = k_malloc(CONFIG_NRF70BUS_MEMTEST_LENGTH * 4); + if (rxbuff == NULL) { + LOG_ERR("Failed to allocate memory for rxbuff"); + k_free(buff); + return -1; + } + + while (rem_words > 0) { + test_chunk = (rem_words < CONFIG_NRF70BUS_MEMTEST_LENGTH) ? + rem_words : CONFIG_NRF70BUS_MEMTEST_LENGTH; + + for (i = 0; i < test_chunk; i++) { + buff[i] = pattern + + (i + chunk_no * CONFIG_NRF70BUS_MEMTEST_LENGTH) * offset; + } + + addr = addr + chunk_no * CONFIG_NRF70BUS_MEMTEST_LENGTH; + + if (rpu_write(addr, buff, test_chunk * 4) || + rpu_read(addr, rxbuff, test_chunk * 4)) { + goto err; + } + + err_count = 0; + for (i = 0; i < test_chunk; i++) { + if (buff[i] != rxbuff[i]) { + err_count++; + LOG_ERR("%s: failed (%d), Expected 0x%x, Read 0x%x", + __func__, i, buff[i], rxbuff[i]); + if (err_count > 4) + goto err; + } + } + if (err_count) { + goto err; + } + rem_words -= CONFIG_NRF70BUS_MEMTEST_LENGTH; + chunk_no++; + } + ret = 0; +err: + k_free(rxbuff); + k_free(buff); + return ret; +} + +static int test_sysbus(void) +{ + int val, i; + /* List of some SYS bus addresses and default values to test bus read + * integrity + */ + const uint32_t addr[] = {0x714, 0x71c, 0x720, + 0x728, 0x734, 0x738}; + const uint32_t val_arr[] = { + 0x000003f3, 0x0110f13f, 0x000003f3, + 0x0003073f, 0x0003073f, 0x03013f8f}; + + for (i = 0; i < ARRAY_SIZE(addr); i++) { + rpu_read(addr[i], &val, 4); + if (val != val_arr[i]) { + LOG_ERR("%s: SYSBUS R/W failed (%d) : read = 0x%x, expected = 0x%x", + __func__, i, val, val_arr[i]); + return -1; + } + } + return 0; +} + +static int test_peripbus(void) +{ + uint32_t val; + int i; + /* Some Perip bus addresses that we can write/read to validate bus access*/ + const uint32_t addr[] = {0x62820, 0x62830, 0x62840, 0x62850, 0x62860, 0x62870}; + + for (i = 0; i < ARRAY_SIZE(addr); i++) { + val = 0xA5A5A5A5; /* Test pattern */ + rpu_write(addr[i], &val, 4); + val = 0; + rpu_read(addr[i], &val, 4); + /* Perip bus is 24-bit and hence LS 8 bits read are invalid, so discard them + * in the check + */ + if (val >> 8 != 0xA5A5A5) { + LOG_ERR("%s: PERIP BUS R/W failed (%d): read = 0x%x", + __func__, i, val >> 8); + return -1; + } + } + return 0; +} + +ZTEST_SUITE(bustest_suite, NULL, (void *)wifi_on, NULL, NULL, wifi_off); + +ZTEST(bustest_suite, test_sysbus) +{ + zassert_equal(0, test_sysbus(), "SYSBUS read validation failed!!!"); +} + +ZTEST(bustest_suite, test_peripbus) +{ + zassert_equal(0, test_peripbus(), "PERIP BUS read/write validation failed!!!"); +} + +ZTEST(bustest_suite, test_dataram) +{ + zassert_equal(0, memtest(DATARAM_ADDR, "DATA RAM"), "DATA RAM memtest failed!!!"); +} diff --git a/tests/boards/nrf/nrf70/bustest/testcase.yaml b/tests/boards/nrf/nrf70/bustest/testcase.yaml new file mode 100644 index 00000000000..29dc054b823 --- /dev/null +++ b/tests/boards/nrf/nrf70/bustest/testcase.yaml @@ -0,0 +1,20 @@ +tests: + nrf_wifi.bustest.nrf7002: + sysbuild: true + build_only: true + integration_platforms: + - nrf7002dk/nrf5340/cpuapp + platform_allow: nrf7002dk/nrf5340/cpuapp + + nrf_wifi.bustest.nrf7002ek: + sysbuild: true + build_only: true + extra_args: SHIELD=nrf7002ek + integration_platforms: + - nrf5340dk/nrf5340/cpuapp + - nrf52840dk/nrf52840 + - nucleo_h723zg + platform_allow: + - nrf5340dk/nrf5340/cpuapp + - nrf52840dk/nrf52840 + - nucleo_h723zg diff --git a/west.yml b/west.yml index 11cd720a905..fadcb7d7daf 100644 --- a/west.yml +++ b/west.yml @@ -318,7 +318,7 @@ manifest: - debug - name: picolibc path: modules/lib/picolibc - revision: 06bde1fd7531b1f788f6e42b6f7b358c0fe4f814 + revision: 27746bbc246841852912fc3bb5b45094cd8a505a - name: segger revision: b011c45b585e097d95d9cf93edf4f2e01588d3cd path: modules/debug/segger