Skip to content

Commit 8690dbe

Browse files
committed
[nrf fromlist] soc: nordic: gen_uicr: Support secondary firmware
Add support for secondary firmware in gen_uicr.py. Upstream PR #: 95410 Signed-off-by: Sebastian Bøe <[email protected]>
1 parent 2a4a265 commit 8690dbe

File tree

4 files changed

+150
-8
lines changed

4 files changed

+150
-8
lines changed

boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,5 +166,13 @@
166166
periphconf_partition: partition@1ae000 {
167167
reg = <0x1ae000 DT_SIZE_K(8)>;
168168
};
169+
170+
secondary_partition: partition@1b0000 {
171+
reg = <0x1b0000 DT_SIZE_K(64)>;
172+
};
173+
174+
secondary_periphconf_partition: partition@1c0000 {
175+
reg = <0x1c2000 DT_SIZE_K(8)>;
176+
};
169177
};
170178
};

soc/nordic/common/uicr/gen_uicr.py

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,46 @@ def main() -> None:
255255
type=lambda s: int(s, 0),
256256
help="Absolute flash address of the UICR region (decimal or 0x-prefixed hex)",
257257
)
258+
parser.add_argument(
259+
"--secondary",
260+
action="store_true",
261+
help="Enable secondary firmware support in UICR",
262+
)
263+
parser.add_argument(
264+
"--secondary-address",
265+
default=None,
266+
type=lambda s: int(s, 0),
267+
help="Absolute flash address of the secondary firmware (decimal or 0x-prefixed hex)",
268+
)
269+
parser.add_argument(
270+
"--secondary-periphconf-address",
271+
default=None,
272+
type=lambda s: int(s, 0),
273+
help="Absolute flash address of the secondary PERIPHCONF partition (decimal or 0x-prefixed hex)",
274+
)
275+
parser.add_argument(
276+
"--secondary-periphconf-size",
277+
default=None,
278+
type=lambda s: int(s, 0),
279+
help="Size in bytes of the secondary PERIPHCONF partition (decimal or 0x-prefixed hex)",
280+
)
281+
parser.add_argument(
282+
"--in-secondary-periphconf-elf",
283+
dest="in_secondary_periphconf_elfs",
284+
default=[],
285+
action="append",
286+
type=argparse.FileType("rb"),
287+
help=(
288+
"Path to an ELF file to extract secondary PERIPHCONF data from. Can be provided multiple times. "
289+
"The secondary PERIPHCONF data from each ELF file is combined in a single list which is sorted "
290+
"by ascending address and cleared of duplicate entries."
291+
),
292+
)
293+
parser.add_argument(
294+
"--out-secondary-periphconf-hex",
295+
type=argparse.FileType("w", encoding="utf-8"),
296+
help="Path to write the secondary PERIPHCONF-only HEX file to",
297+
)
258298
args = parser.parse_args()
259299

260300
try:
@@ -267,6 +307,21 @@ def main() -> None:
267307
if args.periphconf_size is None:
268308
raise ScriptError("--periphconf-size is required when --out-periphconf-hex is used")
269309

310+
# Validate secondary argument dependencies
311+
if args.secondary:
312+
if args.secondary_address is None:
313+
raise ScriptError("--secondary-address is required when --secondary is used")
314+
315+
if args.out_secondary_periphconf_hex:
316+
if args.secondary_periphconf_address is None:
317+
raise ScriptError(
318+
"--secondary-periphconf-address is required when --out-secondary-periphconf-hex is used"
319+
)
320+
if args.secondary_periphconf_size is None:
321+
raise ScriptError(
322+
"--secondary-periphconf-size is required when --out-secondary-periphconf-hex is used"
323+
)
324+
270325
init_values = DISABLED_VALUE.to_bytes(4, "little") * (c.sizeof(Uicr) // 4)
271326
uicr = Uicr.from_buffer_copy(init_values)
272327

@@ -275,6 +330,7 @@ def main() -> None:
275330

276331
# Process periphconf data first and configure UICR completely before creating hex objects
277332
periphconf_hex = IntelHex()
333+
secondary_periphconf_hex = IntelHex()
278334

279335
if args.out_periphconf_hex:
280336
periphconf_combined = extract_and_combine_periphconfs(args.in_periphconf_elfs)
@@ -301,6 +357,37 @@ def main() -> None:
301357

302358
uicr.PERIPHCONF.MAXCOUNT = args.periphconf_size // 8
303359

360+
# Handle secondary firmware configuration
361+
if args.secondary:
362+
uicr.SECONDARY.ENABLE = ENABLED_VALUE
363+
uicr.SECONDARY.ADDRESS = args.secondary_address
364+
365+
# Handle secondary periphconf if provided
366+
if args.out_secondary_periphconf_hex:
367+
secondary_periphconf_combined = extract_and_combine_periphconfs(args.in_secondary_periphconf_elfs)
368+
369+
padding_len = args.secondary_periphconf_size - len(secondary_periphconf_combined)
370+
secondary_periphconf_final = secondary_periphconf_combined + bytes([0xFF for _ in range(padding_len)])
371+
372+
# Add secondary periphconf data to secondary periphconf hex object
373+
secondary_periphconf_hex.frombytes(secondary_periphconf_final, offset=args.secondary_periphconf_address)
374+
375+
# Configure UICR with secondary periphconf settings
376+
uicr.SECONDARY.PERIPHCONF.ENABLE = ENABLED_VALUE
377+
uicr.SECONDARY.PERIPHCONF.ADDRESS = args.secondary_periphconf_address
378+
379+
# MAXCOUNT is given in number of 8-byte peripheral
380+
# configuration entries and secondary_periphconf_size is given in
381+
# bytes. When setting MAXCOUNT based on the
382+
# secondary_periphconf_size we must first assert that
383+
# secondary_periphconf_size has not been misconfigured.
384+
if args.secondary_periphconf_size % 8 != 0:
385+
raise ScriptError(
386+
f"args.secondary_periphconf_size was {args.secondary_periphconf_size}, but must be divisible by 8"
387+
)
388+
389+
uicr.SECONDARY.PERIPHCONF.MAXCOUNT = args.secondary_periphconf_size // 8
390+
304391
# Create UICR hex object with final UICR data
305392
uicr_hex = IntelHex()
306393
uicr_hex.frombytes(bytes(uicr), offset=args.uicr_address)
@@ -311,9 +398,12 @@ def main() -> None:
311398

312399
if args.out_periphconf_hex:
313400
periphconf_hex.write_hex_file(args.out_periphconf_hex)
314-
315401
merged_hex.fromdict(periphconf_hex.todict())
316402

403+
if args.out_secondary_periphconf_hex:
404+
secondary_periphconf_hex.write_hex_file(args.out_secondary_periphconf_hex)
405+
merged_hex.fromdict(secondary_periphconf_hex.todict())
406+
317407
merged_hex.write_hex_file(args.out_merged_hex)
318408
uicr_hex.write_hex_file(args.out_uicr_hex)
319409

soc/nordic/common/uicr/gen_uicr/CMakeLists.txt

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ endif()
4040
set(periphconf_args)
4141
set(periphconf_elfs)
4242
set(merged_hex_file ${APPLICATION_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.hex)
43+
set(secondary_periphconf_elfs)
4344
set(uicr_hex_file ${APPLICATION_BINARY_DIR}/zephyr/uicr.hex)
4445
set(periphconf_hex_file ${APPLICATION_BINARY_DIR}/zephyr/periphconf.hex)
46+
set(secondary_periphconf_hex_file ${APPLICATION_BINARY_DIR}/zephyr/secondary_periphconf.hex)
4547

4648
# Get UICR absolute address from this image's devicetree
4749
dt_nodelabel(uicr_path NODELABEL "uicr" REQUIRED)
@@ -62,7 +64,12 @@ if(CONFIG_GEN_UICR_GENERATE_PERIPHCONF)
6264
endif()
6365

6466
if(EXISTS ${_dir}/zephyr/zephyr.dts)
65-
list(APPEND periphconf_elfs ${_dir}/zephyr/zephyr.elf)
67+
# Check if this is secondary firmware by looking for the marker file
68+
if(EXISTS ${_dir}/is_secondary_firmware.txt)
69+
list(APPEND secondary_periphconf_elfs ${_dir}/zephyr/zephyr.elf)
70+
else()
71+
list(APPEND periphconf_elfs ${_dir}/zephyr/zephyr.elf)
72+
endif()
6673
endif()
6774
endforeach()
6875

@@ -79,21 +86,46 @@ if(CONFIG_GEN_UICR_GENERATE_PERIPHCONF)
7986
endforeach()
8087
endif(CONFIG_GEN_UICR_GENERATE_PERIPHCONF)
8188

82-
# Generate hex files (merged, uicr-only, and periphconf-only)
89+
if(CONFIG_GEN_UICR_SECONDARY)
90+
set(secondary_args --secondary)
91+
92+
# Compute SECONDARY partition absolute address from this image's devicetree
93+
compute_partition_address_and_size("secondary_partition" SECONDARY_ADDRESS SECONDARY_SIZE)
94+
95+
list(APPEND secondary_args
96+
--secondary-address ${SECONDARY_ADDRESS}
97+
)
98+
99+
if(CONFIG_GEN_UICR_SECONDARY_GENERATE_PERIPHCONF)
100+
# Compute SECONDARY_PERIPHCONF absolute address and size from this image's devicetree
101+
compute_partition_address_and_size("secondary_periphconf_partition" SECONDARY_PERIPHCONF_ADDRESS SECONDARY_PERIPHCONF_SIZE)
102+
103+
list(APPEND secondary_args --secondary-periphconf-address ${SECONDARY_PERIPHCONF_ADDRESS})
104+
list(APPEND secondary_args --secondary-periphconf-size ${SECONDARY_PERIPHCONF_SIZE})
105+
list(APPEND secondary_args --out-secondary-periphconf-hex ${secondary_periphconf_hex_file})
106+
107+
foreach(elf ${secondary_periphconf_elfs})
108+
list(APPEND secondary_args --in-secondary-periphconf-elf ${elf})
109+
endforeach()
110+
endif()
111+
endif()
112+
113+
# Generate hex files (merged, uicr-only, periphconf-only, and secondary-periphconf-only)
83114
add_custom_command(
84-
OUTPUT ${merged_hex_file} ${uicr_hex_file} ${periphconf_hex_file}
115+
OUTPUT ${merged_hex_file} ${uicr_hex_file} ${periphconf_hex_file} ${secondary_periphconf_hex_file}
85116
COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_BASE}/scripts/dts/python-devicetree/src
86117
${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/soc/nordic/common/uicr/gen_uicr.py
87118
--uicr-address ${UICR_ADDRESS}
88119
--out-merged-hex ${merged_hex_file}
89120
--out-uicr-hex ${uicr_hex_file}
90121
${periphconf_args}
91-
DEPENDS ${periphconf_elfs}
122+
${secondary_args}
123+
DEPENDS ${periphconf_elfs} ${secondary_periphconf_elfs}
92124
WORKING_DIRECTORY ${APPLICATION_BINARY_DIR}
93-
COMMENT "Using gen_uicr.py to generate ${merged_hex_file} from ${periphconf_elfs}"
125+
COMMENT "Using gen_uicr.py to generate ${merged_hex_file}, ${uicr_hex_file}, ${periphconf_hex_file}, and ${secondary_periphconf_hex_file} from ${periphconf_elfs} ${secondary_periphconf_elfs}"
94126
)
95127

96128
# Add zephyr subdirectory to handle flash configuration with correct paths
97129
add_subdirectory(zephyr)
98130

99-
add_custom_target(gen_uicr ALL DEPENDS ${merged_hex_file})
131+
add_custom_target(gen_uicr ALL DEPENDS ${merged_hex_file} ${uicr_hex_file} ${periphconf_hex_file} ${secondary_periphconf_hex_file})

soc/nordic/common/uicr/gen_uicr/Kconfig

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,19 @@ config GEN_UICR_GENERATE_PERIPHCONF
77
bool "Generate PERIPHCONF hex alongside UICR"
88
default y
99
help
10-
When enabled, the UICR generator will emit periphconf.hex in addition to uicr.hex.
10+
When enabled, the UICR generator will populate the
11+
periphconf_partition partition.
12+
13+
config GEN_UICR_SECONDARY
14+
bool "Enable UICR.SECONDARY.ENABLE"
15+
16+
config GEN_UICR_SECONDARY_GENERATE_PERIPHCONF
17+
bool "Generate SECONDARY.PERIPHCONF hex alongside UICR"
18+
default y
19+
depends on GEN_UICR_SECONDARY
20+
help
21+
When enabled, the UICR generator will populate the
22+
secondary_periphconf_partition partition.
1123

1224
endmenu
1325

0 commit comments

Comments
 (0)