diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 0c4ae7baecc..f5ca11da190 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -1301,8 +1301,18 @@ def check_no_undef_outside_kconfig(self, kconf): "FOO_SETTING_1", "FOO_SETTING_2", "GEN_UICR_GENERATE_PERIPHCONF", # Used in specialized build tool, not part of main Kconfig - "GEN_UICR_SECONDARY", # Used in specialized build tool, not part of main Kconfig - "GEN_UICR_SECONDARY_GENERATE_PERIPHCONF", # Used in specialized build tool, not part of main Kconfig + "GEN_UICR_PROTECTEDMEM", + "GEN_UICR_PROTECTEDMEM_SIZE_BYTES", + "GEN_UICR_SECONDARY", + "GEN_UICR_SECONDARY_GENERATE_PERIPHCONF", + "GEN_UICR_SECONDARY_PROCESSOR_VALUE", + "GEN_UICR_SECONDARY_WDTSTART", + "GEN_UICR_SECONDARY_WDTSTART_CRV", + "GEN_UICR_SECONDARY_WDTSTART_INSTANCE_CODE", + "GEN_UICR_SECURESTORAGE", + "GEN_UICR_WDTSTART", + "GEN_UICR_WDTSTART_CRV", + "GEN_UICR_WDTSTART_INSTANCE_CODE", # Used in specialized build tool, not part of main Kconfig "HEAP_MEM_POOL_ADD_SIZE_", # Used as an option matching prefix "HUGETLBFS", # Linux, in boards/xtensa/intel_adsp_cavs25/doc "IAR_BUFFERED_WRITE", diff --git a/soc/nordic/common/uicr/Kconfig b/soc/nordic/common/uicr/Kconfig index 73b5e5cf2d1..37bdd014b7d 100644 --- a/soc/nordic/common/uicr/Kconfig +++ b/soc/nordic/common/uicr/Kconfig @@ -18,3 +18,10 @@ config NRF_PERIPHCONF_GENERATE_ENTRIES help Generate a C file containing PERIPHCONF entries based on the device configuration in the devicetree. + +config IS_IRONSIDE_SE_SECONDARY_IMAGE + bool "Ironside SE secondary image indicator (informative only, do not change)" + help + This Kconfig is set by sysbuild to indicate that this image is a + secondary firmware for Ironside SE. This is used by the UICR generation + system to determine which PERIPHCONF partition to use. diff --git a/soc/nordic/common/uicr/gen_uicr.py b/soc/nordic/common/uicr/gen_uicr.py index ce69cd7e80a..da2938bf05c 100644 --- a/soc/nordic/common/uicr/gen_uicr.py +++ b/soc/nordic/common/uicr/gen_uicr.py @@ -8,7 +8,8 @@ import argparse import ctypes as c import sys -from itertools import groupby +from itertools import groupby, pairwise +from typing import NamedTuple from elftools.elf.elffile import ELFFile from intelhex import IntelHex @@ -25,10 +26,20 @@ ENABLED_VALUE = 0xFFFF_FFFF DISABLED_VALUE = 0xBD23_28A8 +KB_4 = 4096 + class ScriptError(RuntimeError): ... +class PartitionInfo(NamedTuple): + """Information about a partition for secure storage validation.""" + + address: int + size: int + name: str + + class PeriphconfEntry(c.LittleEndianStructure): _pack_ = 1 _fields_ = [ @@ -198,6 +209,105 @@ class Uicr(c.LittleEndianStructure): ] +def validate_secure_storage_partitions(args: argparse.Namespace) -> None: + """ + Validate that secure storage partitions are laid out correctly. + + Args: + args: Parsed command line arguments containing partition information + + Raises: + ScriptError: If validation fails + """ + # Expected order: cpuapp_crypto_partition, cpurad_crypto_partition, + # cpuapp_its_partition, cpurad_its_partition + partitions = [ + PartitionInfo( + args.cpuapp_crypto_address, args.cpuapp_crypto_size, "cpuapp_crypto_partition" + ), + PartitionInfo( + args.cpurad_crypto_address, args.cpurad_crypto_size, "cpurad_crypto_partition" + ), + PartitionInfo(args.cpuapp_its_address, args.cpuapp_its_size, "cpuapp_its_partition"), + PartitionInfo(args.cpurad_its_address, args.cpurad_its_size, "cpurad_its_partition"), + ] + + # Filter out zero-sized partitions (missing partitions) + present_partitions = [p for p in partitions if p.size > 0] + + # Require at least one subpartition to be present + if not present_partitions: + raise ScriptError( + "At least one secure storage subpartition must be defined. " + "Define one or more of: cpuapp_crypto_partition, cpurad_crypto_partition, " + "cpuapp_its_partition, cpurad_its_partition" + ) + + # Check 4KB alignment for secure storage start address + if args.securestorage_address % 4096 != 0: + raise ScriptError( + f"Secure storage address {args.securestorage_address:#x} must be aligned to 4KB " + f"(4096 bytes)" + ) + + # Check 4KB alignment for secure storage size + if args.securestorage_size % 4096 != 0: + raise ScriptError( + f"Secure storage size {args.securestorage_size} bytes must be aligned to 4KB " + f"(4096 bytes)" + ) + + # Check that the first present partition starts at the secure storage address + first_partition = present_partitions[0] + if first_partition.address != args.securestorage_address: + raise ScriptError( + f"First partition {first_partition.name} starts at {first_partition.address:#x}, " + f"but must start at secure storage address {args.securestorage_address:#x}" + ) + + # Check that all present partitions have sizes that are multiples of 1KB + for partition in present_partitions: + if partition.size % 1024 != 0: + raise ScriptError( + f"Partition {partition.name} has size {partition.size} bytes, but must be " + f"a multiple of 1024 bytes (1KB)" + ) + + # Check that partitions are in correct order and don't overlap + for curr_partition, next_partition in pairwise(present_partitions): + # Check order - partitions should be in ascending address order + if curr_partition.address >= next_partition.address: + raise ScriptError( + f"Partition {curr_partition.name} (starts at {curr_partition.address:#x}) " + f"must come before {next_partition.name} (starts at {next_partition.address:#x})" + ) + + # Check for overlap + curr_end = curr_partition.address + curr_partition.size + if curr_end > next_partition.address: + raise ScriptError( + f"Partition {curr_partition.name} (ends at {curr_end:#x}) overlaps with " + f"{next_partition.name} (starts at {next_partition.address:#x})" + ) + + # Check for gaps (should be no gaps between consecutive partitions) + if curr_end < next_partition.address: + gap = next_partition.address - curr_end + raise ScriptError( + f"Gap of {gap} bytes between {curr_partition.name} (ends at {curr_end:#x}) and " + f"{next_partition.name} (starts at {next_partition.address:#x})" + ) + + # Check that combined subpartition sizes equal secure_storage_partition size + total_subpartition_size = sum(p.size for p in present_partitions) + if total_subpartition_size != args.securestorage_size: + raise ScriptError( + f"Combined size of subpartitions ({total_subpartition_size} bytes) does not match " + f"secure_storage_partition size ({args.securestorage_size} bytes). " + f"The definition is not coherent." + ) + + def main() -> None: parser = argparse.ArgumentParser( allow_abbrev=False, @@ -255,6 +365,111 @@ def main() -> None: type=lambda s: int(s, 0), help="Absolute flash address of the UICR region (decimal or 0x-prefixed hex)", ) + parser.add_argument( + "--securestorage", + action="store_true", + help="Enable secure storage support in UICR", + ) + parser.add_argument( + "--securestorage-address", + default=None, + type=lambda s: int(s, 0), + help="Absolute flash address of the secure storage partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--securestorage-size", + default=None, + type=lambda s: int(s, 0), + help="Size in bytes of the secure storage partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--cpuapp-crypto-address", + default=0, + type=lambda s: int(s, 0), + help="Absolute flash address of cpuapp_crypto_partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--cpuapp-crypto-size", + default=0, + type=lambda s: int(s, 0), + help="Size in bytes of cpuapp_crypto_partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--cpurad-crypto-address", + default=0, + type=lambda s: int(s, 0), + help="Absolute flash address of cpurad_crypto_partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--cpurad-crypto-size", + default=0, + type=lambda s: int(s, 0), + help="Size in bytes of cpurad_crypto_partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--cpuapp-its-address", + default=0, + type=lambda s: int(s, 0), + help="Absolute flash address of cpuapp_its_partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--cpuapp-its-size", + default=0, + type=lambda s: int(s, 0), + help="Size in bytes of cpuapp_its_partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--cpurad-its-address", + default=0, + type=lambda s: int(s, 0), + help="Absolute flash address of cpurad_its_partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--cpurad-its-size", + default=0, + type=lambda s: int(s, 0), + help="Size in bytes of cpurad_its_partition (decimal or 0x-prefixed hex)", + ) + parser.add_argument( + "--protectedmem", + action="store_true", + help="Enable protected memory region in UICR", + ) + parser.add_argument( + "--protectedmem-size-bytes", + type=int, + help="Protected memory size in bytes (must be divisible by 4096)", + ) + parser.add_argument( + "--wdtstart", + action="store_true", + help="Enable watchdog timer start in UICR", + ) + parser.add_argument( + "--wdtstart-instance-code", + type=lambda s: int(s, 0), + help="Watchdog timer instance code (0xBD2328A8 for WDT0, 0x1730C77F for WDT1)", + ) + parser.add_argument( + "--wdtstart-crv", + type=int, + help="Initial Counter Reload Value (CRV) for watchdog timer (minimum: 0xF)", + ) + parser.add_argument( + "--secondary-wdtstart", + action="store_true", + help="Enable watchdog timer start in UICR.SECONDARY", + ) + parser.add_argument( + "--secondary-wdtstart-instance-code", + type=lambda s: int(s, 0), + help="Secondary watchdog timer instance code (0xBD2328A8 for WDT0, 0x1730C77F for WDT1)", + ) + parser.add_argument( + "--secondary-wdtstart-crv", + type=int, + help="Secondary initial Counter Reload Value (CRV) for watchdog timer (minimum: 0xF)", + ) parser.add_argument( "--secondary", action="store_true", @@ -266,6 +481,12 @@ def main() -> None: type=lambda s: int(s, 0), help="Absolute flash address of the secondary firmware (decimal or 0x-prefixed hex)", ) + parser.add_argument( + "--secondary-processor", + default=0xBD2328A8, + type=lambda s: int(s, 0), + help="Processor to boot for the secondary firmware ", + ) parser.add_argument( "--secondary-periphconf-address", default=None, @@ -327,12 +548,51 @@ def main() -> None: "--out-secondary-periphconf-hex is used" ) + # Validate secure storage argument dependencies + if args.securestorage: + if args.securestorage_address is None: + raise ScriptError( + "--securestorage-address is required when --securestorage is used" + ) + if args.securestorage_size is None: + raise ScriptError("--securestorage-size is required when --securestorage is used") + + # Validate partition layout + validate_secure_storage_partitions(args) + init_values = DISABLED_VALUE.to_bytes(4, "little") * (c.sizeof(Uicr) // 4) uicr = Uicr.from_buffer_copy(init_values) uicr.VERSION.MAJOR = UICR_FORMAT_VERSION_MAJOR uicr.VERSION.MINOR = UICR_FORMAT_VERSION_MINOR + # Handle secure storage configuration + if args.securestorage: + uicr.SECURESTORAGE.ENABLE = ENABLED_VALUE + uicr.SECURESTORAGE.ADDRESS = args.securestorage_address + + # Set partition sizes in 1KB units + uicr.SECURESTORAGE.CRYPTO.APPLICATIONSIZE1KB = args.cpuapp_crypto_size // 1024 + uicr.SECURESTORAGE.CRYPTO.RADIOCORESIZE1KB = args.cpurad_crypto_size // 1024 + uicr.SECURESTORAGE.ITS.APPLICATIONSIZE1KB = args.cpuapp_its_size // 1024 + uicr.SECURESTORAGE.ITS.RADIOCORESIZE1KB = args.cpurad_its_size // 1024 + + # Handle protected memory configuration + if args.protectedmem: + if args.protectedmem_size_bytes % KB_4 != 0: + raise ScriptError( + f"Protected memory size ({args.protectedmem_size_bytes} bytes) " + f"must be divisible by {KB_4}" + ) + uicr.PROTECTEDMEM.ENABLE = ENABLED_VALUE + uicr.PROTECTEDMEM.SIZE4KB = args.protectedmem_size_bytes // KB_4 + + # Handle WDTSTART configuration + if args.wdtstart: + uicr.WDTSTART.ENABLE = ENABLED_VALUE + uicr.WDTSTART.CRV = args.wdtstart_crv + uicr.WDTSTART.INSTANCE = args.wdtstart_instance_code + # Process periphconf data first and configure UICR completely before creating hex objects periphconf_hex = IntelHex() secondary_periphconf_hex = IntelHex() @@ -366,6 +626,7 @@ def main() -> None: if args.secondary: uicr.SECONDARY.ENABLE = ENABLED_VALUE uicr.SECONDARY.ADDRESS = args.secondary_address + uicr.SECONDARY.PROCESSOR = args.secondary_processor # Handle secondary periphconf if provided if args.out_secondary_periphconf_hex: @@ -400,6 +661,12 @@ def main() -> None: uicr.SECONDARY.PERIPHCONF.MAXCOUNT = args.secondary_periphconf_size // 8 + # Handle secondary WDTSTART configuration + if args.secondary_wdtstart: + uicr.SECONDARY.WDTSTART.ENABLE = ENABLED_VALUE + uicr.SECONDARY.WDTSTART.CRV = args.secondary_wdtstart_crv + uicr.SECONDARY.WDTSTART.INSTANCE = args.secondary_wdtstart_instance_code + # Create UICR hex object with final UICR data uicr_hex = IntelHex() uicr_hex.frombytes(bytes(uicr), offset=args.uicr_address) diff --git a/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt b/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt index 1163ff8e21f..39737888023 100644 --- a/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt +++ b/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt @@ -23,11 +23,19 @@ project(uicr) function(parse_kconfig_value config_file config_name output_var) file(STRINGS ${config_file} config_lines ENCODING "UTF-8") foreach(line ${config_lines}) + # Match quoted strings like CONFIG_FOO="value" if("${line}" MATCHES "^${config_name}=\"(.*)\"$") set(${output_var} "${CMAKE_MATCH_1}" PARENT_SCOPE) return() endif() + # Match unquoted values like CONFIG_FOO=y or CONFIG_FOO=n + if("${line}" MATCHES "^${config_name}=(.*)$") + set(${output_var} "${CMAKE_MATCH_1}" PARENT_SCOPE) + return() + endif() endforeach() + # If not found, return empty (including "# CONFIG_FOO is not set" case) + set(${output_var} "" PARENT_SCOPE) endfunction() # Function to compute partition absolute address and size from devicetree @@ -44,11 +52,32 @@ function(compute_partition_address_and_size partition_nodelabel output_address_v set(${output_size_var} ${partition_size} PARENT_SCOPE) endfunction() +# Function to compute optional partition address and size from devicetree +# If partition doesn't exist, sets both address and size to 0 +function(compute_optional_partition_address_and_size partition_nodelabel output_address_var output_size_var) + # Initialize with default values + set(${output_address_var} 0 PARENT_SCOPE) + set(${output_size_var} 0 PARENT_SCOPE) + + # Check if partition exists + dt_nodelabel(partition_path NODELABEL ${partition_nodelabel} QUIET) + if(partition_path) + # Call nested function with different variable names to avoid naming conflicts + compute_partition_address_and_size(${partition_nodelabel} temp_addr temp_size) + + # Copy the results to the output variables in parent scope + set(${output_address_var} ${temp_addr} PARENT_SCOPE) + set(${output_size_var} ${temp_size} PARENT_SCOPE) + endif() +endfunction() + # Use CMAKE_VERBOSE_MAKEFILE to silence an unused-variable warning. if(CMAKE_VERBOSE_MAKEFILE) endif() +set(protectedmem_args) set(periphconf_args) +set(wdtstart_args) set(periphconf_elfs) set(merged_hex_file ${APPLICATION_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.hex) set(secondary_periphconf_elfs) @@ -60,6 +89,45 @@ set(secondary_periphconf_hex_file ${APPLICATION_BINARY_DIR}/zephyr/secondary_per dt_nodelabel(uicr_path NODELABEL "uicr" REQUIRED) dt_reg_addr(UICR_ADDRESS PATH ${uicr_path} REQUIRED) +# Handle secure storage configuration +set(securestorage_args) +if(CONFIG_GEN_UICR_SECURESTORAGE) + list(APPEND securestorage_args --securestorage) + + # Extract secure storage partition information (required) + compute_partition_address_and_size("secure_storage_partition" SECURE_STORAGE_ADDRESS SECURE_STORAGE_SIZE) + list(APPEND securestorage_args --securestorage-address ${SECURE_STORAGE_ADDRESS}) + list(APPEND securestorage_args --securestorage-size ${SECURE_STORAGE_SIZE}) + + # Extract individual partition information for validation (optional partitions) + compute_optional_partition_address_and_size("cpuapp_crypto_partition" CPUAPP_CRYPTO_ADDRESS CPUAPP_CRYPTO_SIZE) + compute_optional_partition_address_and_size("cpurad_crypto_partition" CPURAD_CRYPTO_ADDRESS CPURAD_CRYPTO_SIZE) + compute_optional_partition_address_and_size("cpuapp_its_partition" CPUAPP_ITS_ADDRESS CPUAPP_ITS_SIZE) + compute_optional_partition_address_and_size("cpurad_its_partition" CPURAD_ITS_ADDRESS CPURAD_ITS_SIZE) + + list(APPEND securestorage_args --cpuapp-crypto-address ${CPUAPP_CRYPTO_ADDRESS}) + list(APPEND securestorage_args --cpuapp-crypto-size ${CPUAPP_CRYPTO_SIZE}) + list(APPEND securestorage_args --cpurad-crypto-address ${CPURAD_CRYPTO_ADDRESS}) + list(APPEND securestorage_args --cpurad-crypto-size ${CPURAD_CRYPTO_SIZE}) + list(APPEND securestorage_args --cpuapp-its-address ${CPUAPP_ITS_ADDRESS}) + list(APPEND securestorage_args --cpuapp-its-size ${CPUAPP_ITS_SIZE}) + list(APPEND securestorage_args --cpurad-its-address ${CPURAD_ITS_ADDRESS}) + list(APPEND securestorage_args --cpurad-its-size ${CPURAD_ITS_SIZE}) +endif(CONFIG_GEN_UICR_SECURESTORAGE) + +# Handle protected memory configuration +if(CONFIG_GEN_UICR_PROTECTEDMEM) + list(APPEND protectedmem_args --protectedmem) + list(APPEND protectedmem_args --protectedmem-size-bytes ${CONFIG_GEN_UICR_PROTECTEDMEM_SIZE_BYTES}) +endif() + +# Handle WDTSTART configuration +if(CONFIG_GEN_UICR_WDTSTART) + list(APPEND wdtstart_args --wdtstart) + list(APPEND wdtstart_args --wdtstart-instance-code ${CONFIG_GEN_UICR_WDTSTART_INSTANCE_CODE}) + list(APPEND wdtstart_args --wdtstart-crv ${CONFIG_GEN_UICR_WDTSTART_CRV}) +endif() + if(CONFIG_GEN_UICR_GENERATE_PERIPHCONF) # gen_uicr.py parses all zephyr.elf files. To find these files (which # have not been built yet) we scan sibling build directories for @@ -79,8 +147,9 @@ if(CONFIG_GEN_UICR_GENERATE_PERIPHCONF) parse_kconfig_value(${_dir}/zephyr/.config CONFIG_KERNEL_BIN_NAME kernel_bin_name) set(kernel_elf_path ${_dir}/zephyr/${kernel_bin_name}.elf) - # Check if this is secondary firmware by looking for the marker file - if(EXISTS ${_dir}/is_secondary_firmware.txt) + # Check if this is secondary firmware by reading the Kconfig from .config + parse_kconfig_value(${_dir}/zephyr/.config CONFIG_IS_IRONSIDE_SE_SECONDARY_IMAGE is_secondary) + if(is_secondary STREQUAL "y") list(APPEND secondary_periphconf_elfs ${kernel_elf_path}) else() list(APPEND periphconf_elfs ${kernel_elf_path}) @@ -109,8 +178,16 @@ if(CONFIG_GEN_UICR_SECONDARY) list(APPEND secondary_args --secondary-address ${SECONDARY_ADDRESS} + --secondary-processor ${CONFIG_GEN_UICR_SECONDARY_PROCESSOR_VALUE} ) + # Handle secondary WDTSTART configuration + if(CONFIG_GEN_UICR_SECONDARY_WDTSTART) + list(APPEND secondary_args --secondary-wdtstart) + list(APPEND secondary_args --secondary-wdtstart-instance-code ${CONFIG_GEN_UICR_SECONDARY_WDTSTART_INSTANCE_CODE}) + list(APPEND secondary_args --secondary-wdtstart-crv ${CONFIG_GEN_UICR_SECONDARY_WDTSTART_CRV}) + endif() + if(CONFIG_GEN_UICR_SECONDARY_GENERATE_PERIPHCONF) # Compute SECONDARY_PERIPHCONF absolute address and size from this image's devicetree compute_partition_address_and_size("secondary_periphconf_partition" SECONDARY_PERIPHCONF_ADDRESS SECONDARY_PERIPHCONF_SIZE) @@ -133,7 +210,10 @@ add_custom_command( --uicr-address ${UICR_ADDRESS} --out-merged-hex ${merged_hex_file} --out-uicr-hex ${uicr_hex_file} + ${wdtstart_args} ${periphconf_args} + ${securestorage_args} + ${protectedmem_args} ${secondary_args} DEPENDS ${periphconf_elfs} ${secondary_periphconf_elfs} WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} diff --git a/soc/nordic/common/uicr/gen_uicr/Kconfig b/soc/nordic/common/uicr/gen_uicr/Kconfig index 41d31db6464..9b630139e64 100644 --- a/soc/nordic/common/uicr/gen_uicr/Kconfig +++ b/soc/nordic/common/uicr/gen_uicr/Kconfig @@ -10,17 +10,164 @@ config GEN_UICR_GENERATE_PERIPHCONF When enabled, the UICR generator will populate the periphconf_partition partition. +config GEN_UICR_SECURESTORAGE + bool "Enable UICR.SECURESTORAGE" + default y + depends on $(dt_nodelabel_enabled,secure_storage_partition) + help + When enabled, the UICR generator will configure the + secure storage region based on device tree partitions. + + The following device tree partitions are used: + - secure_storage_partition: Main secure storage partition (required) + - cpuapp_crypto_partition: Application processor crypto storage (optional) + - cpurad_crypto_partition: Radio core crypto storage (optional) + - cpuapp_its_partition: Application processor internal trusted storage (optional) + - cpurad_its_partition: Radio core internal trusted storage (optional) + + Requirements: + - The secure_storage_partition address and size must be aligned to 4KB + - All subpartitions must be multiples of 1KB and laid out contiguously + without gaps + - At least one subpartition must be defined + - Combined subpartition sizes must equal secure_storage_partition size + +config GEN_UICR_PROTECTEDMEM + bool "Enable UICR.PROTECTEDMEM" + help + When enabled, the UICR generator will configure the + protected memory region. + +config GEN_UICR_PROTECTEDMEM_SIZE_BYTES + int "Protected memory size in bytes" + default 4096 + depends on GEN_UICR_PROTECTEDMEM + help + Size of the protected memory region in bytes. + This value must be divisible by 4096 (4 kiB). + +config GEN_UICR_WDTSTART + bool "Enable UICR.WDTSTART" + help + When enabled, the UICR generator will configure the + watchdog timer to start automatically before the + application core is booted. + +choice GEN_UICR_WDTSTART_INSTANCE + prompt "Watchdog timer instance" + depends on GEN_UICR_WDTSTART + help + Select which watchdog timer instance to use. + +config GEN_UICR_WDTSTART_INSTANCE_WDT0 + bool "WDT0" + help + Use watchdog timer instance 0. + +config GEN_UICR_WDTSTART_INSTANCE_WDT1 + bool "WDT1" + help + Use watchdog timer instance 1. + +endchoice + +config GEN_UICR_WDTSTART_INSTANCE_CODE + hex + default 0xBD2328A8 if GEN_UICR_WDTSTART_INSTANCE_WDT0 + default 0x1730C77F if GEN_UICR_WDTSTART_INSTANCE_WDT1 + depends on GEN_UICR_WDTSTART + +config GEN_UICR_WDTSTART_CRV + int "Initial Counter Reload Value (CRV)" + default 65535 + range 15 4294967295 + depends on GEN_UICR_WDTSTART + help + Initial Counter Reload Value (CRV) for the watchdog timer. + This value determines the watchdog timeout period. + Must be at least 15 (0xF) to ensure proper watchdog operation. + Default value 65535 creates a 2-second timeout. + +config GEN_UICR_SECONDARY_WDTSTART + bool "Enable UICR.SECONDARY.WDTSTART" + depends on GEN_UICR_SECONDARY + help + When enabled, the UICR generator will configure the + watchdog timer to start automatically before the + secondary firmware is booted. + +choice GEN_UICR_SECONDARY_WDTSTART_INSTANCE + prompt "Secondary watchdog timer instance" + depends on GEN_UICR_SECONDARY_WDTSTART + help + Select which watchdog timer instance to use for secondary firmware. + +config GEN_UICR_SECONDARY_WDTSTART_INSTANCE_WDT0 + bool "WDT0" + help + Use watchdog timer instance 0 for secondary firmware. + +config GEN_UICR_SECONDARY_WDTSTART_INSTANCE_WDT1 + bool "WDT1" + help + Use watchdog timer instance 1 for secondary firmware. + +endchoice + +config GEN_UICR_SECONDARY_WDTSTART_INSTANCE_CODE + hex + default 0xBD2328A8 if GEN_UICR_SECONDARY_WDTSTART_INSTANCE_WDT0 + default 0x1730C77F if GEN_UICR_SECONDARY_WDTSTART_INSTANCE_WDT1 + depends on GEN_UICR_SECONDARY_WDTSTART + +config GEN_UICR_SECONDARY_WDTSTART_CRV + int "Secondary initial Counter Reload Value (CRV)" + default 65535 + range 15 4294967295 + depends on GEN_UICR_SECONDARY_WDTSTART + help + Initial Counter Reload Value (CRV) for the secondary watchdog timer. + This value determines the watchdog timeout period. + Must be at least 15 (0xF) to ensure proper watchdog operation. + Default value 65535 creates a 2-second timeout. + config GEN_UICR_SECONDARY bool "Enable UICR.SECONDARY.ENABLE" +if GEN_UICR_SECONDARY + config GEN_UICR_SECONDARY_GENERATE_PERIPHCONF bool "Generate SECONDARY.PERIPHCONF hex alongside UICR" default y - depends on GEN_UICR_SECONDARY help When enabled, the UICR generator will populate the secondary_periphconf_partition partition. +choice GEN_UICR_SECONDARY_PROCESSOR + prompt "Secondary processor selection" + default GEN_UICR_SECONDARY_PROCESSOR_APPLICATION + help + Processor to boot for the secondary firmware. + +config GEN_UICR_SECONDARY_PROCESSOR_APPLICATION + bool "APPLICATION processor" + help + Boot secondary firmware on the APPLICATION processor. + +config GEN_UICR_SECONDARY_PROCESSOR_RADIOCORE + bool "RADIOCORE processor" + help + Boot secondary firmware on the RADIOCORE processor. + +endchoice + +config GEN_UICR_SECONDARY_PROCESSOR_VALUE + hex + default 0xBD2328A8 if GEN_UICR_SECONDARY_PROCESSOR_APPLICATION + default 0x1730C77F if GEN_UICR_SECONDARY_PROCESSOR_RADIOCORE + +endif # GEN_UICR_SECONDARY + endmenu source "Kconfig.zephyr"