Skip to content

Commit a913cc8

Browse files
committed
cmake: Add function to read partition address
Add a common bootloader_dts_util to read both the relative and absolute address of a fixed sub/partition from DTS. Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent 560d4f7 commit a913cc8

File tree

4 files changed

+114
-17
lines changed

4 files changed

+114
-17
lines changed

cmake/modules/kconfig.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#
66

77
include_guard(GLOBAL)
8+
include(${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/bootloader_dts_utils.cmake)
89

910
if(CONFIG_NCS_IS_VARIANT_IMAGE)
1011
set(AUTOCONF_H ${PROJECT_BINARY_DIR}/include/generated/zephyr/autoconf.h)
@@ -28,7 +29,7 @@ if(CONFIG_NCS_IS_VARIANT_IMAGE)
2829
import_kconfig("CONFIG" ${DOTCONFIG})
2930
else()
3031
dt_chosen(code_partition PROPERTY "zephyr,code-partition")
31-
dt_reg_addr(code_partition_offset PATH "${code_partition}" REQUIRED)
32+
dt_partition_addr(code_partition_offset PATH "${code_partition}" REQUIRED)
3233
dt_reg_size(code_partition_size PATH "${code_partition}" REQUIRED)
3334

3435
set(preload_autoconf_h ${PRELOAD_BINARY_DIR}/zephyr/include/generated/zephyr/autoconf.h)

cmake/sysbuild/bootloader_dts_utils.cmake

Lines changed: 103 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,111 @@
55
# data coming from the devicetree for configurations using
66
# a bootloader.
77

8-
function(get_address_from_dt_partition_nodelabel label address)
9-
dt_nodelabel(partition_node TARGET ${DEFAULT_IMAGE} NODELABEL ${label} REQUIRED)
10-
dt_reg_addr(partition_offset TARGET ${DEFAULT_IMAGE} PATH ${partition_node})
8+
function(_dt_get_parent node)
9+
string(FIND "${${node}}" "/" pos REVERSE)
10+
11+
if(pos EQUAL -1)
12+
message(FATAL_ERROR "Unable to get parent of node: ${${node}}")
13+
endif()
14+
15+
string(SUBSTRING "${${node}}" 0 ${pos} ${node})
16+
set(${node} "${${node}}" PARENT_SCOPE)
17+
endfunction()
18+
19+
# Usage:
20+
# dt_partition_addr(<var> [LABEL <label>|PATH <path>] [TARGET <target>]
21+
# [ABSOLUTE])
22+
#
23+
# Get the partition address, based on the path or label.
24+
# The value will be returned in the <var> parameter.
25+
# The returned address is either relative to the memory controller, or absolute
26+
# if ABSOLUTE is specified.
27+
#
28+
# The <path> value may be any of these:
29+
#
30+
# - absolute path to a node, like '/foo/bar'
31+
# - a node alias, like 'my-alias'
32+
# - a node alias followed by a path to a child node, like 'my-alias/child-node'
33+
#
34+
# Results can be:
35+
# - The base address of the register block
36+
# - <var> will be undefined if node does not exists or does not have a register
37+
# block at the requested index or with the requested name
38+
#
39+
# <var> : Return variable where the address value will be stored
40+
# LABEL <label> : Node label
41+
# PATH <path> : Node path
42+
# TARGET <target>: Optional target to retrieve devicetree information from
43+
# ABSOLUTE : Return absolute address rather than address relative to
44+
# the memory controller
45+
# REQUIRED : Generate a fatal error if the node is not found
46+
function(dt_partition_addr var)
47+
cmake_parse_arguments(DT_PARTITION "ABSOLUTE;REQUIRED" "LABEL;PATH;TARGET" ""
48+
${ARGN})
1149

12-
# Get the parent "two levels up" (../../) of the partition node
13-
# This is the partition flash area node
14-
string(REPLACE "/" ";" partition_node_split ${partition_node})
15-
list(LENGTH partition_node_split child_path_length)
16-
math(EXPR parent_path_length "${child_path_length} - 2")
17-
list(SUBLIST partition_node_split 0 ${parent_path_length} parent_path_split)
18-
string(REPLACE ";" "/" flash_area_node "${parent_path_split}")
50+
if(NOT DT_PARTITION_PATH AND NOT DT_PARTITION_LABEL)
51+
message(FATAL_ERROR "dt_partition_addr: Either PATH or LABEL must be set")
52+
elseif(DT_PARTITION_PATH AND DT_PARTITION_LABEL)
53+
message(FATAL_ERROR "dt_partition_addr: Only one of PATH or LABEL can be set")
54+
elseif(NOT DT_PARTITION_PATH)
55+
dt_nodelabel(DT_PARTITION_PATH NODELABEL ${DT_PARTITION_LABEL} TARGET
56+
${DT_PARTITION_TARGET})
57+
if(NOT DEFINED DT_PARTITION_PATH)
58+
if(DT_PARTITION_REQUIRED)
59+
message(FATAL_ERROR
60+
"dt_partition_addr: Unable to find node with label: ${DT_PARTITION_LABEL}")
61+
else()
62+
set(${var} "" PARENT_SCOPE)
63+
return()
64+
endif()
65+
endif()
66+
else()
67+
dt_node_exists(DT_PARTITION_EXISTS PATH ${DT_PARTITION_PATH} TARGET
68+
${DT_PARTITION_TARGET})
69+
if(NOT DT_PARTITION_EXISTS)
70+
if(DT_PARTITION_REQUIRED)
71+
message(FATAL_ERROR
72+
"dt_partition_addr: Unable to find node with path: ${DT_PARTITION_PATH}")
73+
else()
74+
set(${var} "" PARENT_SCOPE)
75+
return()
76+
endif()
77+
endif()
78+
endif()
1979

20-
dt_reg_addr(flash_area_addr TARGET ${DEFAULT_IMAGE} PATH ${flash_area_node})
80+
# The "fixed-partition" as well as "fixed-subpartition" compatible is not set
81+
# in the CMake DTS nodes. The first node with the compatible property set is
82+
# the NVM driver/controller node.
83+
set(dt_partition_base_addr 0)
84+
set(dt_partition_parent "${DT_PARTITION_PATH}")
85+
dt_prop(compat PATH ${dt_partition_parent} PROPERTY compatible TARGET
86+
${DT_PARTITION_TARGET})
87+
while(DT_PARTITION_ABSOLUTE OR (NOT compat))
88+
# If a node contains <reg> property, child node address is relative to this
89+
# node.
90+
dt_prop(reg PATH ${dt_partition_parent} PROPERTY reg TARGET
91+
${DT_PARTITION_TARGET})
92+
if(reg)
93+
dt_reg_addr(parent_addr PATH ${dt_partition_parent} TARGET
94+
${DT_PARTITION_TARGET})
95+
math(EXPR dt_partition_base_addr
96+
"${dt_partition_base_addr} + ${parent_addr}" OUTPUT_FORMAT HEXADECIMAL)
97+
endif()
2198

22-
math(EXPR ${address} "${flash_area_addr} + ${partition_offset}")
99+
_dt_get_parent(dt_partition_parent)
100+
if("${dt_partition_parent}" STREQUAL "")
101+
break()
102+
endif()
103+
104+
dt_prop(compat PATH ${dt_partition_parent} PROPERTY compatible TARGET
105+
${DT_PARTITION_TARGET})
106+
endwhile()
107+
108+
set(${var} "${dt_partition_base_addr}" PARENT_SCOPE)
109+
endfunction()
110+
111+
function(get_address_from_dt_partition_nodelabel label address)
112+
dt_partition_addr(${address} LABEL ${label} TARGET ${DEFAULT_IMAGE} ABSOLUTE
113+
REQUIRED)
23114
set(${address} ${${address}} PARENT_SCOPE)
24115
endfunction()

cmake/sysbuild/image_signing.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
# Since this file is brought in via include(), we do the work in a
1111
# function to avoid polluting the top-level scope.
1212

13+
include(${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/bootloader_dts_utils.cmake)
14+
1315
function(zephyr_runner_file type path)
1416
# Property magic which makes west flash choose the signed build
1517
# output of a given type.
@@ -87,7 +89,7 @@ function(zephyr_mcuboot_tasks)
8789
set(imgtool_rom_command)
8890
if(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT OR CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP)
8991
dt_chosen(code_partition PROPERTY "zephyr,code-partition")
90-
dt_reg_addr(code_partition_offset PATH "${code_partition}" REQUIRED)
92+
dt_partition_addr(code_partition_offset PATH "${code_partition}" REQUIRED)
9193
set(imgtool_rom_command --rom-fixed ${code_partition_offset})
9294
endif()
9395
set(imgtool_sign ${PYTHON_EXECUTABLE} ${IMGTOOL} sign --version ${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION} --align ${write_block_size} --slot-size ${slot_size} --header-size ${CONFIG_ROM_START_OFFSET} ${imgtool_rom_command})

cmake/sysbuild/sign_nrf54h20.cmake

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#
33
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
44

5+
include(${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/bootloader_dts_utils.cmake)
6+
57
function(merge_images_nrf54h20 output_artifact images)
68
find_program(MERGEHEX mergehex.py HINTS ${ZEPHYR_BASE}/scripts/build/ NAMES
79
mergehex NAMES_PER_DIR)
@@ -177,10 +179,10 @@ function(mcuboot_sign_merged_nrf54h20 merged_hex main_image)
177179
dt_prop(write_block_size TARGET mcuboot PATH "${flash_node}" PROPERTY
178180
"write-block-size")
179181
dt_nodelabel(slot0_path TARGET mcuboot NODELABEL "slot0_partition" REQUIRED)
180-
dt_reg_addr(slot0_addr TARGET mcuboot PATH ${slot0_path})
182+
dt_partition_addr(slot0_addr PATH "${slot0_path}" TARGET mcuboot REQUIRED)
181183
dt_reg_size(slot0_size TARGET mcuboot PATH ${slot0_path})
182184
dt_nodelabel(slot1_path TARGET mcuboot NODELABEL "slot1_partition" REQUIRED)
183-
dt_reg_addr(slot1_addr TARGET mcuboot PATH ${slot1_path})
185+
dt_partition_addr(slot1_addr PATH "${slot1_path}" TARGET mcuboot REQUIRED)
184186
dt_reg_size(slot1_size TARGET mcuboot PATH ${slot1_path})
185187
if(NOT write_block_size)
186188
set(write_block_size 4)
@@ -190,7 +192,8 @@ function(mcuboot_sign_merged_nrf54h20 merged_hex main_image)
190192

191193
# Fetch devicetree details for the active code partition.
192194
dt_chosen(code_flash TARGET ${main_image} PROPERTY "zephyr,code-partition")
193-
dt_reg_addr(code_addr TARGET ${main_image} PATH ${code_flash})
195+
dt_partition_addr(code_addr PATH "${code_flash}" TARGET ${main_image}
196+
REQUIRED)
194197
set(start_offset)
195198
sysbuild_get(start_offset IMAGE ${main_image} VAR CONFIG_ROM_START_OFFSET
196199
KCONFIG)

0 commit comments

Comments
 (0)