@@ -92,6 +92,18 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr);
9292#include <load_ironside_se_conf.h>
9393#endif
9494
95+ #if defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID )
96+ #include "bootutil/mcuboot_uuid.h"
97+
98+ #ifdef SECOND_STAGE_MCUBOOT_RUNNING_FROM_S0
99+ #define MCUBOOT_INACTIVE_PARTITION_INDEX 1
100+ #define MCUBOOT_ACTIVE_PARTITION_INDEX 0
101+ #else
102+ #define MCUBOOT_INACTIVE_PARTITION_INDEX 0
103+ #define MCUBOOT_ACTIVE_PARTITION_INDEX 1
104+ #endif
105+ #endif
106+
95107#ifdef CONFIG_SOC_EARLY_RESET_HOOK
96108void s2ram_designate_slot (uint8_t slot );
97109#endif
@@ -1024,6 +1036,56 @@ static inline void sec_slot_cleanup_if_unusable(void)
10241036#endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\
10251037 defined(MCUBOOT_IS_SECOND_STAGE) || defined(CONFIG_SOC_NRF5340_CPUAPP) */
10261038
1039+ #ifdef CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID
1040+ /**
1041+ * Read the image UUID from the TLV.
1042+ *
1043+ * @param[in] fap Pointer to the flash area structure.
1044+ * @param[in] hdr Pointer to the image header structure.
1045+ * @param[in] tlv_type The type of the TLV to read.
1046+ * @param[out] uuid Pointer to the image UUID structure.
1047+ *
1048+ * @return 0 on success,
1049+ * @retval -EINVAL if the input parameters are invalid.
1050+ * @retval -EIO if the TLV cannot be read.
1051+ * @retval -ENOENT if the TLV cannot be found.
1052+ */
1053+ int read_image_uuid_tlv (const struct flash_area * fap ,
1054+ const struct image_header * hdr ,
1055+ uint16_t tlv_type ,
1056+ struct image_uuid * uuid )
1057+ {
1058+ struct image_tlv_iter it ;
1059+ uint32_t off ;
1060+ uint16_t len ;
1061+ int rc ;
1062+
1063+ if ((fap == NULL ) || (hdr == NULL ) || (uuid == NULL )) {
1064+ return - EINVAL ;
1065+ }
1066+
1067+ rc = bootutil_tlv_iter_begin (& it , hdr , fap , tlv_type , false);
1068+ if (rc != 0 ) {
1069+ return - ENOENT ;
1070+ }
1071+
1072+ rc = bootutil_tlv_iter_next (& it , & off , & len , NULL );
1073+ if (rc != 0 ) {
1074+ return - ENOENT ;
1075+ }
1076+
1077+ if (len != sizeof (uuid -> raw )) {
1078+ return - EINVAL ;
1079+ }
1080+
1081+ if (flash_area_read (fap , off , uuid -> raw , len ) != 0 ) {
1082+ return - EIO ;
1083+ }
1084+
1085+ return 0 ;
1086+ }
1087+ #endif /* CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID */
1088+
10271089/**
10281090 * Determines which swap operation to perform, if any. If it is determined
10291091 * that a swap operation is required, the image in the secondary slot is checked
@@ -1038,12 +1100,25 @@ boot_validated_swap_type(struct boot_loader_state *state,
10381100{
10391101 int swap_type ;
10401102 FIH_DECLARE (fih_rc , FIH_FAILURE );
1103+ #if CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 \
1104+ && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE ) && defined(CONFIG_PCD_APP )
10411105 bool upgrade_valid = false;
1106+ #endif
10421107
10431108#if defined(MCUBOOT_IS_SECOND_STAGE ) || CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1
10441109 const struct flash_area * secondary_fa = BOOT_IMG_AREA (state , BOOT_SLOT_SECONDARY );
10451110 struct image_header * hdr = boot_img_hdr (state , BOOT_SLOT_SECONDARY );
1111+ #if defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_LOAD_ADDRESS ) || \
1112+ defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_RESET_VECTOR )
10461113 uint32_t internal_img_addr = 0 ;
1114+ #elif defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID )
1115+ struct image_uuid img_uuid_cid ;
1116+ #ifdef MCUBOOT_UUID_VID
1117+ struct image_uuid img_uuid_vid ;
1118+ #endif
1119+ size_t target_image = 0 ;
1120+ size_t target_partition = 0 ;
1121+ #endif
10471122 int rc = 0 ;
10481123 /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other
10491124 * B1 slot S0 or S1) share the same secondary slot, we need to check
@@ -1055,8 +1130,10 @@ boot_validated_swap_type(struct boot_loader_state *state,
10551130 */
10561131 NSIB_OWNED_UNSET (BOOT_CURR_IMG (state ));
10571132
1133+ #if defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_LOAD_ADDRESS ) || \
1134+ defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_RESET_VECTOR )
10581135 if (hdr -> ih_magic == IMAGE_MAGIC ) {
1059- #ifdef MCUBOOT_CHECK_HEADER_LOAD_ADDRESS
1136+ #ifdef CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_LOAD_ADDRESS
10601137 internal_img_addr = hdr -> ih_load_addr ;
10611138#else
10621139 rc = flash_area_read (secondary_fa , hdr -> ih_hdr_size + RESET_OFFSET ,
@@ -1124,7 +1201,62 @@ boot_validated_swap_type(struct boot_loader_state *state,
11241201 sec_slot_mark_assigned (state );
11251202 }
11261203
1127- #endif /* MCUBOOT_IS_SECOND_STAGE || CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 */
1204+ #elif defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID )
1205+ if (hdr -> ih_magic == IMAGE_MAGIC ) {
1206+ rc = read_image_uuid_tlv (secondary_fa , hdr , IMAGE_TLV_UUID_CID , & img_uuid_cid );
1207+ if (rc != 0 ) {
1208+ return BOOT_SWAP_TYPE_NONE ;
1209+ }
1210+ #ifdef MCUBOOT_UUID_VID
1211+ rc = read_image_uuid_tlv (secondary_fa , hdr , IMAGE_TLV_UUID_VID , & img_uuid_vid );
1212+ if (rc != 0 ) {
1213+ return BOOT_SWAP_TYPE_NONE ;
1214+ }
1215+ #endif
1216+
1217+ sec_slot_touch (state );
1218+
1219+ rc = boot_uuid_find_image (& img_uuid_cid ,
1220+ #ifdef MCUBOOT_UUID_VID
1221+ & img_uuid_vid ,
1222+ #else
1223+ NULL ,
1224+ #endif
1225+ & target_image , & target_partition );
1226+ if (rc != 0 ) {
1227+ /* Unable to find a matching image index. */
1228+ BOOT_LOG_ERR ("Image in slot does not match any known UUID" );
1229+ flash_area_erase (secondary_fa , 0 , secondary_fa -> fa_size );
1230+ sec_slot_untouch (state );
1231+ BOOT_LOG_ERR ("Cleaned-up secondary slot of image %d" , BOOT_CURR_IMG (state ));
1232+ return BOOT_SWAP_TYPE_FAIL ;
1233+ }
1234+
1235+ if (target_image == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER ) {
1236+ /* This is a valid network core update candidate. */
1237+ #ifdef MCUBOOT_IS_SECOND_STAGE
1238+ } else if ((target_image == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER ) &&
1239+ (target_partition == MCUBOOT_INACTIVE_PARTITION_INDEX )) {
1240+ /* This is a valid MCUboot update candidate. */
1241+ NSIB_OWNED_SET (BOOT_CURR_IMG (state ));
1242+ } else if ((target_image == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER ) &&
1243+ (target_partition == MCUBOOT_ACTIVE_PARTITION_INDEX )) {
1244+ /* NSIB upgrade but for the wrong slot, must be erased */
1245+ BOOT_LOG_ERR ("Image in slot is for wrong s0/s1 image" );
1246+ flash_area_erase (secondary_fa , 0 , secondary_fa -> fa_size );
1247+ sec_slot_untouch (state );
1248+ BOOT_LOG_ERR ("Cleaned-up secondary slot of image %d" , BOOT_CURR_IMG (state ));
1249+ return BOOT_SWAP_TYPE_FAIL ;
1250+ #endif /* MCUBOOT_IS_SECOND_STAGE */
1251+ } else {
1252+ /* The image in the secondary slot is not intended for any */
1253+ return BOOT_SWAP_TYPE_NONE ;
1254+ }
1255+
1256+ sec_slot_mark_assigned (state );
1257+ }
1258+ #endif /* CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID */
1259+ #endif /* defined(MCUBOOT_IS_SECOND_STAGE) || CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 */
11281260
11291261 swap_type = boot_swap_type_multi (BOOT_CURR_IMG (state ));
11301262 if (BOOT_IS_UPGRADE (swap_type )) {
@@ -1138,8 +1270,11 @@ boot_validated_swap_type(struct boot_loader_state *state,
11381270 } else {
11391271 swap_type = BOOT_SWAP_TYPE_FAIL ;
11401272 }
1273+ #if CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 \
1274+ && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE ) && defined(CONFIG_PCD_APP )
11411275 } else {
11421276 upgrade_valid = true;
1277+ #endif
11431278 }
11441279
11451280#if CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 \
@@ -1148,8 +1283,17 @@ boot_validated_swap_type(struct boot_loader_state *state,
11481283 * update and indicate to the caller of this function that no update is
11491284 * available
11501285 */
1151- if (upgrade_valid && internal_img_addr >= NETCPU_APP_SLOT_OFFSET &&
1152- internal_img_addr < NETCPU_APP_SLOT_END ) {
1286+ if (upgrade_valid
1287+ #if defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_LOAD_ADDRESS ) || \
1288+ defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_RESET_VECTOR )
1289+ & & (internal_img_addr >= NETCPU_APP_SLOT_OFFSET )
1290+ && (internal_img_addr < NETCPU_APP_SLOT_END )
1291+ #elif defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID )
1292+ & & (target_image == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER )
1293+ #else
1294+ #error Unable to detect radio image update candidate.
1295+ #endif
1296+ ) {
11531297 struct image_header * hdr = (struct image_header * )secondary_fa -> fa_off ;
11541298 uint32_t vtable_addr = (uint32_t )hdr + hdr -> ih_hdr_size ;
11551299 uint32_t * net_core_fw_addr = (uint32_t * )(vtable_addr );
0 commit comments