@@ -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 reset_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
@@ -1054,13 +1129,19 @@ boot_validated_swap_type(struct boot_loader_state *state,
10541129 */
10551130 NSIB_OWNED_UNSET (BOOT_CURR_IMG (state ));
10561131
1132+ #if defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_LOAD_ADDRESS ) || \
1133+ defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_RESET_VECTOR )
10571134 if (hdr -> ih_magic == IMAGE_MAGIC ) {
1135+ #ifdef CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_LOAD_ADDRESS
1136+ reset_addr = hdr -> ih_load_addr ;
1137+ #else
10581138 rc = flash_area_read (secondary_fa , hdr -> ih_hdr_size +
10591139 sizeof (uint32_t ), & reset_addr ,
10601140 sizeof (reset_addr ));
10611141 if (rc != 0 ) {
10621142 return BOOT_SWAP_TYPE_FAIL ;
10631143 }
1144+ #endif
10641145
10651146 sec_slot_touch (state );
10661147
@@ -1110,7 +1191,62 @@ boot_validated_swap_type(struct boot_loader_state *state,
11101191 sec_slot_mark_assigned (state );
11111192 }
11121193
1113- #endif /* MCUBOOT_IS_SECOND_STAGE || CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 */
1194+ #elif defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID )
1195+ if (hdr -> ih_magic == IMAGE_MAGIC ) {
1196+ rc = read_image_uuid_tlv (secondary_fa , hdr , IMAGE_TLV_UUID_CID , & img_uuid_cid );
1197+ if (rc != 0 ) {
1198+ return BOOT_SWAP_TYPE_NONE ;
1199+ }
1200+ #ifdef MCUBOOT_UUID_VID
1201+ rc = read_image_uuid_tlv (secondary_fa , hdr , IMAGE_TLV_UUID_VID , & img_uuid_vid );
1202+ if (rc != 0 ) {
1203+ return BOOT_SWAP_TYPE_NONE ;
1204+ }
1205+ #endif
1206+
1207+ sec_slot_touch (state );
1208+
1209+ rc = boot_uuid_find_image (& img_uuid_cid ,
1210+ #ifdef MCUBOOT_UUID_VID
1211+ & img_uuid_vid ,
1212+ #else
1213+ NULL ,
1214+ #endif
1215+ & target_image , & target_partition );
1216+ if (rc != 0 ) {
1217+ /* Unable to find a matching image index. */
1218+ BOOT_LOG_ERR ("Image in slot does not match any known UUID" );
1219+ flash_area_erase (secondary_fa , 0 , secondary_fa -> fa_size );
1220+ sec_slot_untouch (state );
1221+ BOOT_LOG_ERR ("Cleaned-up secondary slot of image %d" , BOOT_CURR_IMG (state ));
1222+ return BOOT_SWAP_TYPE_FAIL ;
1223+ }
1224+
1225+ if (target_image == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER ) {
1226+ /* This is a valid network core update candidate. */
1227+ #ifdef MCUBOOT_IS_SECOND_STAGE
1228+ } else if ((target_image == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER ) &&
1229+ (target_partition == MCUBOOT_INACTIVE_PARTITION_INDEX )) {
1230+ /* This is a valid MCUboot update candidate. */
1231+ NSIB_OWNED_SET (BOOT_CURR_IMG (state ));
1232+ } else if ((target_image == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER ) &&
1233+ (target_partition == MCUBOOT_ACTIVE_PARTITION_INDEX )) {
1234+ /* NSIB upgrade but for the wrong slot, must be erased */
1235+ BOOT_LOG_ERR ("Image in slot is for wrong s0/s1 image" );
1236+ flash_area_erase (secondary_fa , 0 , secondary_fa -> fa_size );
1237+ sec_slot_untouch (state );
1238+ BOOT_LOG_ERR ("Cleaned-up secondary slot of image %d" , BOOT_CURR_IMG (state ));
1239+ return BOOT_SWAP_TYPE_FAIL ;
1240+ #endif /* MCUBOOT_IS_SECOND_STAGE */
1241+ } else {
1242+ /* The image in the secondary slot is not intended for any */
1243+ return BOOT_SWAP_TYPE_NONE ;
1244+ }
1245+
1246+ sec_slot_mark_assigned (state );
1247+ }
1248+ #endif /* CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID */
1249+ #endif /* defined(MCUBOOT_IS_SECOND_STAGE) || CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 */
11141250
11151251 swap_type = boot_swap_type_multi (BOOT_CURR_IMG (state ));
11161252 if (BOOT_IS_UPGRADE (swap_type )) {
@@ -1124,8 +1260,11 @@ boot_validated_swap_type(struct boot_loader_state *state,
11241260 } else {
11251261 swap_type = BOOT_SWAP_TYPE_FAIL ;
11261262 }
1263+ #if CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 \
1264+ && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE ) && defined(CONFIG_PCD_APP )
11271265 } else {
11281266 upgrade_valid = true;
1267+ #endif
11291268 }
11301269
11311270#if CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 \
@@ -1134,8 +1273,16 @@ boot_validated_swap_type(struct boot_loader_state *state,
11341273 * update and indicate to the caller of this function that no update is
11351274 * available
11361275 */
1137- if (upgrade_valid && reset_addr >= NETCPU_APP_SLOT_OFFSET &&
1138- reset_addr < NETCPU_APP_SLOT_END ) {
1276+ if (upgrade_valid
1277+ #if defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_LOAD_ADDRESS ) || \
1278+ defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_RESET_VECTOR )
1279+ & & reset_addr >= NETCPU_APP_SLOT_OFFSET && reset_addr < NETCPU_APP_SLOT_END
1280+ #elif defined(CONFIG_NCS_MCUBOOT_SECONDARY_SLOT_IMAGE_RESOLVE_UUID )
1281+ & & (target_image == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER )
1282+ #else
1283+ #error Unable to detect radio image update candidate.
1284+ #endif
1285+ ) {
11391286 struct image_header * hdr = (struct image_header * )secondary_fa -> fa_off ;
11401287 uint32_t vtable_addr = (uint32_t )hdr + hdr -> ih_hdr_size ;
11411288 uint32_t * net_core_fw_addr = (uint32_t * )(vtable_addr );
0 commit comments