Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
/cmake/ @nrfconnect/ncs-co-build-system
/cmake/sysbuild/suit.cmake @nrfconnect/ncs-charon
/cmake/sysbuild/suit_utilities.cmake @nrfconnect/ncs-charon
/cmake/sysbuild/suit_provisioning.cmake @nrfconnect/ncs-charon
/cmake/sysbuild/suit_provisioning_nrf54h20.cmake @nrfconnect/ncs-charon

# All doc related files
/doc/_zoomin/ @nrfconnect/ncs-co-doc @nrfconnect/ncs-doc-leads
Expand Down Expand Up @@ -774,6 +776,8 @@
# Sysbuild
/sysbuild/ @nrfconnect/ncs-co-build-system
/sysbuild/Kconfig.suit @nrfconnect/ncs-charon
/sysbuild/Kconfig.suit_provisioning @nrfconnect/ncs-charon
/sysbuild/suit_provisioning/ @nrfconnect/ncs-charon
/sysbuild/suit.cmake @nrfconnect/ncs-charon

# Tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ CONFIG_EVENT_MANAGER_PROXY_BIND_TIMEOUT_MS=4000

CONFIG_GPIO=y

CONFIG_SUIT_MPI_GENERATE=n

################################################################################
# Debug configuration
CONFIG_LOG=y
Expand Down
25 changes: 9 additions & 16 deletions cmake/sysbuild/suit.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,6 @@ function(suit_create_package)
endif()

# Read SUIT storage addresses, set during MPI generation
sysbuild_get(SUIT_STORAGE_ADDRESS IMAGE ${DEFAULT_IMAGE} VAR SUIT_STORAGE_ADDRESS CACHE)
if(DEFINED SUIT_STORAGE_ADDRESS)
list(APPEND STORAGE_BOOT_ARGS --storage-address ${SUIT_STORAGE_ADDRESS})
else()
Expand All @@ -521,7 +520,7 @@ function(suit_create_package)
--storage-output-directory
"${DEFAULT_BINARY_DIR}/zephyr"
--zephyr-base ${ZEPHYR_BASE}
--config-file "${DEFAULT_BINARY_DIR}/zephyr/.config"
--config-file "${PROJECT_BINARY_DIR}/.config"
${CORE_ARGS}
)
set_property(
Expand Down Expand Up @@ -568,19 +567,13 @@ function(suit_setup_merge)
list(APPEND ARTIFACTS_TO_MERGE ${IMAGE_BINARY_DIR}/zephyr/${IMAGE_BINARY_FILE}.hex)
list(APPEND ARTIFACTS_TO_MERGE ${IMAGE_BINARY_DIR}/zephyr/uicr.hex)

unset(CONFIG_SUIT_ENVELOPE_OUTPUT_MPI_MERGE)
sysbuild_get(CONFIG_SUIT_ENVELOPE_OUTPUT_MPI_MERGE IMAGE ${image} VAR CONFIG_SUIT_ENVELOPE_OUTPUT_MPI_MERGE KCONFIG)
if(CONFIG_SUIT_ENVELOPE_OUTPUT_MPI_MERGE)
list(APPEND ARTIFACTS_TO_MERGE ${BINARY_DIR}/zephyr/suit_mpi_${IMAGE_TARGET_NAME}_merged.hex)
endif()

if(${IMAGE_TARGET_NAME} STREQUAL "application")
# Get a list of files (and their dependencies) which need merging into the uicr merged file
# and add them at the end of the list, allowing for overwriting, this only applies to the
# application core image
get_property(merge_files GLOBAL PROPERTY SUIT_MERGE_FILE)
get_property(merge_dependencies GLOBAL PROPERTY SUIT_MERGE_DEPENDENCIES)
else()
# Get a list of files (and their dependencies) which need merging into the uicr merged file
# and add them at the end of the list, allowing for overwriting
unset(merge_files)
unset(merge_dependencies)
get_property(merge_files GLOBAL PROPERTY SUIT_MERGE_${IMAGE_TARGET_NAME}_FILE)
get_property(merge_dependencies GLOBAL PROPERTY SUIT_MERGE_${IMAGE_TARGET_NAME}_DEPENDENCIES)
if(NOT DEFINED merge_files)
set(merge_files)
set(merge_dependencies)
endif()
Expand All @@ -595,7 +588,7 @@ function(suit_setup_merge)
# fixme: uicr_merged is overwritten by new content, runners_yaml_props_target could be used to define
# what shall be flashed, but not sure where to set this! Remove --overlap if ready!
# example usage: set_property(TARGET runners_yaml_props_target PROPERTY hex_file ${merged_hex_file})
COMMAND ${CMAKE_COMMAND} -E copy ${OUTPUT_HEX_FILE} ${IMAGE_BINARY_DIR}/zephyr/uicr_merged.hex
COMMAND ${CMAKE_COMMAND} -E copy ${OUTPUT_HEX_FILE} ${IMAGE_BINARY_DIR}/zephyr/uicr_merged.hex
)
endforeach()
endfunction()
Expand Down
238 changes: 238 additions & 0 deletions cmake/sysbuild/suit_provisioning.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

set(SUIT_GENERATOR_CLI_SCRIPT "${ZEPHYR_SUIT_GENERATOR_MODULE_DIR}/suit_generator/cli.py")
sysbuild_get(DEFAULT_BINARY_DIR IMAGE ${DEFAULT_IMAGE} VAR APPLICATION_BINARY_DIR CACHE)
set(MPI_BINARY_DIR ${DEFAULT_BINARY_DIR}/zephyr)

# Usage:
# configure_storage_address_cache()
#
# Store the absolute address of the SUIT storage inside CMake cache.
#
function(configure_storage_address_cache)
sysbuild_dt_nodelabel(
suit_storage_dev
IMAGE
${DEFAULT_IMAGE}
NODELABEL
"suit_storage_partition"
)

if(NOT DEFINED suit_storage_dev)
message(WARNING "Unable to read SUIT storage address from DTS - nodes undefined")
return()
endif()

# Calculate SUIT storage address, based on the DTS
sysbuild_dt_reg_addr(
suit_storage_address
IMAGE
${DEFAULT_IMAGE}
PATH
"${suit_storage_dev}"
)

set(SUIT_STORAGE_ADDRESS ${suit_storage_address} CACHE STRING "SUIT storage address")
endfunction()

# Usage:
# generate_mpi_hex(<manifest_role>)
#
# Will generate HEX file for a single manifest role, based on Kconfigs defined by the template.
#
# <manifest_role>: The role that was used to generate a set of Kconfigs, defined by the
# Kconfig.template.manifest_config.
#
# Required Kconfigs:
# - SUIT_MPI_<manifest_role>_VENDOR_NAME
# - SUIT_MPI_<manifest_role>_CLASS_NAME
# - SUIT_MPI_<manifest_role>_OFFSET
# - SUIT_MPI_<manifest_role>_PATH
# - SUIT_MPI_SLOT_SIZE
#
function(generate_mpi_hex manifest_role)
set(generate_args "")
set(descr_args "")

if(NOT DEFINED SB_CONFIG_SUIT_MPI_${manifest_role})
return()
endif()

if((NOT DEFINED SB_CONFIG_SUIT_MPI_${manifest_role}_VENDOR_NAME) OR
(NOT DEFINED SB_CONFIG_SUIT_MPI_${manifest_role}_CLASS_NAME) OR
(NOT DEFINED SB_CONFIG_SUIT_MPI_${manifest_role}_OFFSET) OR
(NOT DEFINED SB_CONFIG_SUIT_MPI_${manifest_role}_PATH) OR
(NOT DEFINED SB_CONFIG_SUIT_MPI_SLOT_SIZE)
)
message(FATAL_ERROR "Malformed configuration for: ${manifest_role}")
return()
endif()

if(SB_CONFIG_SUIT_MPI_${manifest_role}_VENDOR_NAME STREQUAL "nordicsemi.com")
message(WARNING "
-----------------------------------------------------------
--- WARNING: Using default Vendor ID (nordicsemi.com). ---
--- It should not be used for production. ---
--- See SB_CONFIG_SUIT_MPI_${manifest_role}_VENDOR_NAME \t---
--- and SB_CONFIG_SUIT_MPI_${manifest_role}_CLASS_NAME \t---
-----------------------------------------------------------
\n"
)
endif()

MATH(
EXPR
SUIT_MPI_${manifest_role}_ADDRESS
"${SUIT_STORAGE_ADDRESS}
+ ${SB_CONFIG_SUIT_MPI_${manifest_role}_OFFSET}"
OUTPUT_FORMAT HEXADECIMAL
)

list(APPEND generate_args
--vendor-name ${SB_CONFIG_SUIT_MPI_${manifest_role}_VENDOR_NAME}
--class-name ${SB_CONFIG_SUIT_MPI_${manifest_role}_CLASS_NAME}
--address ${SUIT_MPI_${manifest_role}_ADDRESS}
--size ${SB_CONFIG_SUIT_MPI_SLOT_SIZE}
--output-file ${SB_CONFIG_SUIT_MPI_${manifest_role}_PATH}
)

list(APPEND descr_args
${SB_CONFIG_SUIT_MPI_${manifest_role}_PATH}
${SB_CONFIG_SUIT_MPI_${manifest_role}_VENDOR_NAME}
${SB_CONFIG_SUIT_MPI_${manifest_role}_CLASS_NAME}
"address=${SUIT_MPI_${manifest_role}_ADDRESS}"
)

if(DEFINED SB_CONFIG_SUIT_MPI_${manifest_role}_DOWNGRADE_PREVENTION)
list(APPEND generate_args
--downgrade-prevention-enabled
)
list(APPEND descr_args
downgrade-prevention-enabled
)
endif()

if(DEFINED SB_CONFIG_SUIT_MPI_${manifest_role}_INDEPENDENT_UPDATE)
list(APPEND generate_args
--independent-updates
)
list(APPEND descr_args
"independent updates"
)
endif()

if(DEFINED SB_CONFIG_SUIT_MPI_${manifest_role}_SIGNATURE_CHECK_ENABLED_ON_UPDATE)
list(APPEND generate_args
--signature-verification update
)
list(APPEND descr_args
"signed updates"
)
elseif(DEFINED SB_CONFIG_SUIT_MPI_${manifest_role}_SIGNATURE_CHECK_ENABLED_ON_UPDATE_AND_BOOT)
list(APPEND generate_args
--signature-verification update-and-boot
)
list(APPEND descr_args
"signed updates"
"signed boot"
)
endif()

add_custom_target(
create_suit_mpi_${manifest_role}
COMMAND ${PYTHON_EXECUTABLE} ${SUIT_GENERATOR_CLI_SCRIPT}
mpi
generate
${generate_args}
BYPRODUCTS ${SB_CONFIG_SUIT_MPI_${manifest_role}_PATH}
COMMENT "Create SUIT artifacts"
)
message(INFO " Generate MPI for ${manifest_role} manifest (${descr_args})")
endfunction()

# Usage:
# generate_mpi_area(<area_name> [<manifest_role>...])
#
# Will generate HEX file for an MPI area attached to a single domain.
# At the end of the merging process, a digest of the resulting binary will be
# calculated and appended at the end of it.
#
# <area_name>: Name of the area. A valid area must define output file path, address and size.
# <manifest_role>: The role that was used to generate a set of Kconfigs, defined by the
# Kconfig.template.manifest_config.
# Used to extract the HEX file path containing the MPI configuration.
#
# Required Kconfigs:
# - SUIT_MPI_<area_name>_PATH
# - SUIT_MPI_<area_name>_OFFSET
# - SUIT_MPI_<area_name>_SIZE
# - SUIT_MPI_<manifest_role>_PATH
#
function (generate_mpi_area area)
set(merge_args "")
set(dependencies "")

if((NOT DEFINED SB_CONFIG_SUIT_MPI_${area}_PATH) OR
(NOT DEFINED SB_CONFIG_SUIT_MPI_${area}_OFFSET) OR
(NOT DEFINED SB_CONFIG_SUIT_MPI_${area}_SIZE)
)
message(FATAL_ERROR "Malformed configuration for: ${area}")
return()
endif()

# Calculate the absolute address of the MPI area.
MATH(
EXPR
SUIT_MPI_${area}_ADDRESS
"${SUIT_STORAGE_ADDRESS}
+ ${SB_CONFIG_SUIT_MPI_${area}_OFFSET}"
OUTPUT_FORMAT HEXADECIMAL
)

set(output ${MPI_BINARY_DIR}/${SB_CONFIG_SUIT_MPI_${area}_PATH})
set(address ${SUIT_MPI_${area}_ADDRESS})
set(size ${SB_CONFIG_SUIT_MPI_${area}_SIZE})

list(APPEND merge_args
--output-file ${output}
--address ${address}
--size ${size}
)

foreach(role ${ARGN})
if(NOT DEFINED SB_CONFIG_SUIT_MPI_${role}_PATH)
continue()
endif()

list(APPEND merge_args "--file" "${SB_CONFIG_SUIT_MPI_${role}_PATH}")
list(APPEND dependencies "${SB_CONFIG_SUIT_MPI_${role}_PATH}")
endforeach()

add_custom_target(
create_suit_mpi_area_${area}
ALL
COMMAND ${PYTHON_EXECUTABLE} ${SUIT_GENERATOR_CLI_SCRIPT}
mpi
merge
${merge_args}
DEPENDS ${dependencies}
BYPRODUCTS ${output}
COMMENT "Create SUIT artifacts"
)

message(INFO " Generate merged MPI for ${area} (${output})")
endfunction()

if(DEFINED SB_CONFIG_SOC_SERIES_NRF54HX)
configure_storage_address_cache()
endif() # SB_CONFIG_SOC_SERIES_NRF54HX

if(DEFINED SB_CONFIG_SUIT_MPI_GENERATE)
if(DEFINED SB_CONFIG_SUIT_MPI_SOC_NRF54H20)
include(${CMAKE_CURRENT_LIST_DIR}/suit_provisioning_nrf54h20.cmake)
endif() # SB_CONFIG_SUIT_MPI_SOC_NRF54H20
endif() # SB_CONFIG_SUIT_MPI_GENERATE
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
include(${CMAKE_CURRENT_LIST_DIR}/suit_utilities.cmake)

# List all manifest roles.
# The function internally checks if the enabling symbol is defined.
Expand Down Expand Up @@ -31,3 +32,16 @@ generate_mpi_area(
RAD_LOCAL_1
RAD_LOCAL_2
)

if(SB_CONFIG_SUIT_ENVELOPE_OUTPUT_MPI_MERGE)
suit_add_merge_hex_file(
FILES ${MPI_BINARY_DIR}/${SB_CONFIG_SUIT_MPI_APP_AREA_PATH}
DEPENDENCIES ${MPI_BINARY_DIR}/${SB_CONFIG_SUIT_MPI_APP_AREA_PATH}
TARGET "application"
)
suit_add_merge_hex_file(
FILES ${MPI_BINARY_DIR}/${SB_CONFIG_SUIT_MPI_RAD_AREA_PATH}
DEPENDENCIES ${MPI_BINARY_DIR}/${SB_CONFIG_SUIT_MPI_RAD_AREA_PATH}
TARGET "radio"
)
endif()
13 changes: 9 additions & 4 deletions cmake/sysbuild/suit_utilities.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,20 @@ function(suit_create_nordic_cache_partition args output_file)
endfunction()

# Usage:
# suit_add_merge_hex_file(FILES <files> [DEPENDENCIES <dependencies>]
# suit_add_merge_hex_file(FILES <files> [DEPENDENCIES <dependencies>] [TARGET <sysbuild_target>]
#
# Add files which should be merged into the uicr_merged.hex output file, respecting any
# dependencies that need to be generated before hand. This will overwrite existing data if it is
# present in other files
function(suit_add_merge_hex_file)
cmake_parse_arguments(arg "" "" "FILES;DEPENDENCIES" ${ARGN})
cmake_parse_arguments(arg "" "TARGET" "FILES;DEPENDENCIES" ${ARGN})
zephyr_check_arguments_required(${CMAKE_CURRENT_FUNCTION} arg FILES)

set_property(GLOBAL APPEND PROPERTY SUIT_MERGE_FILE ${arg_FILES})
set_property(GLOBAL APPEND PROPERTY SUIT_MERGE_DEPENDENCIES ${arg_DEPENDENCIES})
if(DEFINED arg_TARGET)
set_property(GLOBAL APPEND PROPERTY SUIT_MERGE_${arg_TARGET}_FILE ${arg_FILES})
set_property(GLOBAL APPEND PROPERTY SUIT_MERGE_${arg_TARGET}_DEPENDENCIES ${arg_DEPENDENCIES})
else()
set_property(GLOBAL APPEND PROPERTY SUIT_MERGE_application_FILE ${arg_FILES})
set_property(GLOBAL APPEND PROPERTY SUIT_MERGE_application_DEPENDENCIES ${arg_DEPENDENCIES})
endif()
endfunction()
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{%- set mpi_application_vendor_name = application['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %}
{%- set mpi_application_class_name = application['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_app') %}
{%- set mpi_application_vendor_name = sysbuild['config']['SB_CONFIG_SUIT_MPI_APP_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %}
{%- set mpi_application_class_name = sysbuild['config']['SB_CONFIG_SUIT_MPI_APP_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_app') %}
SUIT_Envelope_Tagged:
suit-authentication-wrapper:
SuitDigest:
Expand Down Expand Up @@ -74,12 +74,7 @@ SUIT_Envelope_Tagged:
suit-current-version: {{ DEFAULT_VERSION }}
{%- endif %}

{%- if application['dt'].label2node['suit_storage_partition'].regs[0].size == 24576 %}
# Application DTS contains larger SUIT storage - use legacy encoding
suit-install-legacy:
{%- else %}
suit-install:
{%- endif %}
- suit-directive-set-component-index: 1
- suit-directive-override-parameters:
{%- if 'CONFIG_SUIT_DFU_CACHE_EXTRACT_IMAGE_URI' in application['config'] and application['config']['CONFIG_SUIT_DFU_CACHE_EXTRACT_IMAGE_URI'] != '' %}
Expand Down
Loading
Loading