Build: Introduce MCUBOOT_IMAGE_NUMBER switch

Add the MCUBOOT_IMAGE_NUMBER compile time switch to the build system to
be able to specify the number of separately updatable firmware images.
It can be set in the MCUBootConfig.cmake configuration file or include
this macro definition in the command line at build time.

Change-Id: Iefe26e2029ce68352ec2ed6c0d7b2b086e2afec0
Signed-off-by: David Vincze <david.vincze@arm.com>
diff --git a/CommonConfig.cmake b/CommonConfig.cmake
index a1cd01d..58cabd1 100644
--- a/CommonConfig.cmake
+++ b/CommonConfig.cmake
@@ -258,6 +258,9 @@
 endif()
 
 if (BL2)
+	# Add MCUBOOT_IMAGE_NUMBER definition to the compiler command line.
+	add_definitions(-DMCUBOOT_IMAGE_NUMBER=${MCUBOOT_IMAGE_NUMBER})
+
 	if (${MCUBOOT_UPGRADE_STRATEGY} STREQUAL "NO_SWAP")
 		set(LINK_TO_BOTH_MEMORY_REGION ON)
 	endif()
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index a4c2f4a..76872e5 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -289,7 +289,8 @@
 
 	#Set BL2 specific settings.
 	if (BL2)
-		embedded_set_target_link_defines(TARGET ${EXE_NAME} DEFINES "BL2")
+		#Add BL2 and MCUBOOT_IMAGE_NUMBER defines to linker to resolve symbols in region_defs.h and flash_layout.h
+		embedded_set_target_link_defines(TARGET ${EXE_NAME} DEFINES "BL2" "MCUBOOT_IMAGE_NUMBER=${MCUBOOT_IMAGE_NUMBER}")
 	endif()
 
 	#We depend on the non secure tests. See if the library target is available.
diff --git a/bl2/ext/mcuboot/CMakeLists.txt b/bl2/ext/mcuboot/CMakeLists.txt
index c7c6a1c..cac109d 100644
--- a/bl2/ext/mcuboot/CMakeLists.txt
+++ b/bl2/ext/mcuboot/CMakeLists.txt
@@ -106,8 +106,8 @@
 config_setting_shared_compiler_flags(${PROJECT_NAME})
 config_setting_shared_linker_flags(${PROJECT_NAME})
 
-#Add BL2 define to linker to resolve symbols in region_defs.h
-embedded_set_target_link_defines(TARGET ${PROJECT_NAME} DEFINES "BL2")
+#Add BL2 and MCUBOOT_IMAGE_NUMBER defines to linker to resolve symbols in region_defs.h and flash_layout.h
+embedded_set_target_link_defines(TARGET ${PROJECT_NAME} DEFINES "BL2" "MCUBOOT_IMAGE_NUMBER=${MCUBOOT_IMAGE_NUMBER}")
 
 if(NOT DEFINED TEST_FRAMEWORK_S)
 	message(FATAL_ERROR "Incomplete build configuration: TEST_FRAMEWORK_S is undefined.")
@@ -128,6 +128,7 @@
 #Generate binary file from axf
 compiler_generate_binary_output(${PROJECT_NAME})
 
+message(STATUS "MCUBOOT_IMAGE_NUMBER is set to: '${MCUBOOT_IMAGE_NUMBER}'.")
 message(STATUS "MCUBOOT_UPGRADE_STRATEGY is set to: '${MCUBOOT_UPGRADE_STRATEGY}'.")
 message(STATUS "MCUBOOT_SIGNATURE_TYPE is set to: '${MCUBOOT_SIGNATURE_TYPE}'.")
 
diff --git a/bl2/ext/mcuboot/MCUBoot.cmake b/bl2/ext/mcuboot/MCUBoot.cmake
index 5187694..621c9ba 100644
--- a/bl2/ext/mcuboot/MCUBoot.cmake
+++ b/bl2/ext/mcuboot/MCUBoot.cmake
@@ -86,7 +86,8 @@
 	compiler_preprocess_file(SRC ${FILE_TO_PREPROCESS}
 							DST ${PREPROCESSED_FILE}
 							BEFORE_TARGET ${_MY_PARAMS_NS_BIN}
-							TARGET_PREFIX ${_MY_PARAMS_NS_BIN})
+							TARGET_PREFIX ${_MY_PARAMS_NS_BIN}
+							DEFINES "MCUBOOT_IMAGE_NUMBER=${MCUBOOT_IMAGE_NUMBER}")
 
 	add_custom_command(TARGET ${_MY_PARAMS_NS_BIN}
 						POST_BUILD
@@ -133,3 +134,37 @@
 			RENAME ${TFM_SIGN_NAME}${_MY_PARAMS_POSTFIX}.bin
 			DESTINATION outputs/fvp/)
 endfunction()
+
+#Validate and override the upgrade strategy to be used by the bootloader.
+#
+# If the given upgrade strategy is not supported with the current value
+# of the MCUBOOT_IMAGE_NUMBER variable then the function will override its
+# previously set value.
+#
+#Examples:
+#  mcuboot_override_upgrade_strategy("SWAP")
+#
+#INPUTS:
+#  strategy - (mandatory) - Upgrade strategy to be used.
+#
+#OUTPUTS:
+#  MCUBOOT_UPGRADE_STRATEGY variable is set to the new strategy.
+#
+function(mcuboot_override_upgrade_strategy strategy)
+	if ((${strategy} STREQUAL "NO_SWAP" OR
+		 ${strategy} STREQUAL "RAM_LOADING") AND
+		NOT (MCUBOOT_IMAGE_NUMBER EQUAL 1))
+		message(WARNING "The number of separately updatable images with the NO_SWAP or the RAM_LOADING"
+			" upgrade strategy can be only '1'. Your choice was overriden.")
+		set(MCUBOOT_IMAGE_NUMBER 1 PARENT_SCOPE)
+	endif()
+	get_property(_validation_list CACHE MCUBOOT_UPGRADE_STRATEGY PROPERTY STRINGS)
+	#Check if validation list is set.
+	if (NOT _validation_list)
+		#Set the default upgrade strategy if the CACHE variable has not been set yet.
+		set(MCUBOOT_UPGRADE_STRATEGY "OVERWRITE_ONLY" CACHE STRING "Configure BL2 which upgrade strategy to use")
+		set_property(CACHE MCUBOOT_UPGRADE_STRATEGY PROPERTY STRINGS "OVERWRITE_ONLY;SWAP;NO_SWAP;RAM_LOADING")
+	endif()
+	set(MCUBOOT_UPGRADE_STRATEGY ${strategy} PARENT_SCOPE)
+	validate_cache_value(MCUBOOT_UPGRADE_STRATEGY STRINGS)
+endfunction()
diff --git a/bl2/ext/mcuboot/MCUBootConfig.cmake b/bl2/ext/mcuboot/MCUBootConfig.cmake
index 406d214..2aa6112 100644
--- a/bl2/ext/mcuboot/MCUBootConfig.cmake
+++ b/bl2/ext/mcuboot/MCUBootConfig.cmake
@@ -5,11 +5,18 @@
 #
 #-------------------------------------------------------------------------------
 
+#Include BL2 bootloader related functions
+include("${CMAKE_CURRENT_LIST_DIR}/MCUBoot.cmake")
+
 set(BL2 True CACHE BOOL "Configure TF-M to use BL2 and enable building BL2")
 
 if (BL2)
 	add_definitions(-DBL2)
 
+	set(MCUBOOT_IMAGE_NUMBER 1 CACHE STRING "Configure the number of separately updatable firmware images")
+	set_property(CACHE MCUBOOT_IMAGE_NUMBER PROPERTY STRINGS "1")
+	validate_cache_value(MCUBOOT_IMAGE_NUMBER STRINGS)
+
 	set(MCUBOOT_UPGRADE_STRATEGY "OVERWRITE_ONLY" CACHE STRING "Configure BL2 which upgrade strategy to use")
 	set_property(CACHE MCUBOOT_UPGRADE_STRATEGY PROPERTY STRINGS "OVERWRITE_ONLY;SWAP;NO_SWAP;RAM_LOADING")
 	validate_cache_value(MCUBOOT_UPGRADE_STRATEGY)
@@ -18,10 +25,21 @@
 	set_property(CACHE MCUBOOT_SIGNATURE_TYPE PROPERTY STRINGS "RSA-3072;RSA-2048")
 	validate_cache_value(MCUBOOT_SIGNATURE_TYPE)
 
+	if ((${MCUBOOT_UPGRADE_STRATEGY} STREQUAL "NO_SWAP" OR
+		 ${MCUBOOT_UPGRADE_STRATEGY} STREQUAL "RAM_LOADING") AND
+		NOT (MCUBOOT_IMAGE_NUMBER EQUAL 1))
+		message(WARNING "The number of separately updatable images with the NO_SWAP or the RAM_LOADING"
+			" upgrade strategy can be only '1'. Your choice was overriden.")
+		set(MCUBOOT_IMAGE_NUMBER 1)
+	endif()
+
 else() #BL2 is turned off
-	if (DEFINED MCUBOOT_UPGRADE_STRATEGY OR
+
+	if (DEFINED MCUBOOT_IMAGE_NUMBER OR
+		DEFINED MCUBOOT_UPGRADE_STRATEGY OR
 		DEFINED MCUBOOT_SIGNATURE_TYPE)
 		message(WARNING "Ignoring the values of MCUBOOT_* variables as BL2 option is set to False.")
+		set(MCUBOOT_IMAGE_NUMBER "")
 		set(MCUBOOT_UPGRADE_STRATEGY "")
 		set(MCUBOOT_SIGNATURE_TYPE "")
 	endif()
diff --git a/platform/ext/Mps3AN524.cmake b/platform/ext/Mps3AN524.cmake
index 419c9bc..3e57cc9 100644
--- a/platform/ext/Mps3AN524.cmake
+++ b/platform/ext/Mps3AN524.cmake
@@ -47,7 +47,7 @@
     set (BL2_LINKER_CONFIG ${BL2_SCATTER_FILE_NAME})
     if (NOT ${MCUBOOT_UPGRADE_STRATEGY} STREQUAL "NO_SWAP")
         message(WARNING "NO_SWAP upgrade strategy is mandatory on target '${TARGET_PLATFORM}'. Your choice was overriden.")
-        set(MCUBOOT_UPGRADE_STRATEGY "NO_SWAP")
+        mcuboot_override_upgrade_strategy("NO_SWAP")
     endif()
 endif()
 
diff --git a/platform/ext/musca_a.cmake b/platform/ext/musca_a.cmake
index b818c06..a93297e 100644
--- a/platform/ext/musca_a.cmake
+++ b/platform/ext/musca_a.cmake
@@ -175,14 +175,15 @@
     message(WARNING "BL2 is mandatory on target '${TARGET_PLATFORM}'. Your choice was overriden.")
     add_definitions(-DBL2)
     set(BL2 True)
-    set(MCUBOOT_UPGRADE_STRATEGY "RAM_LOADING")
+    set(MCUBOOT_IMAGE_NUMBER 1)
+    mcuboot_override_upgrade_strategy("RAM_LOADING")
     message(STATUS "MCUBOOT_UPGRADE_STRATEGY was not set, using the mandatory value for '${TARGET_PLATFORM}': ${MCUBOOT_UPGRADE_STRATEGY}.")
     set(MCUBOOT_SIGNATURE_TYPE "RSA-3072")
     message(STATUS "MCUBOOT_SIGNATURE_TYPE was not set, using default value: ${MCUBOOT_SIGNATURE_TYPE}.")
 else() #BL2 is True
     if (NOT ${MCUBOOT_UPGRADE_STRATEGY} STREQUAL "RAM_LOADING")
         message(WARNING "RAM_LOADING upgrade strategy is mandatory on target '${TARGET_PLATFORM}'. Your choice was overriden.")
-        set(MCUBOOT_UPGRADE_STRATEGY "RAM_LOADING")
+        mcuboot_override_upgrade_strategy("RAM_LOADING")
     endif()
 endif()
 
diff --git a/platform/ext/musca_b1.cmake b/platform/ext/musca_b1.cmake
index 77b51f6..3133189 100644
--- a/platform/ext/musca_b1.cmake
+++ b/platform/ext/musca_b1.cmake
@@ -39,7 +39,7 @@
     set(BL2_LINKER_CONFIG ${BL2_SCATTER_FILE_NAME})
     if (NOT ${MCUBOOT_UPGRADE_STRATEGY} STREQUAL "NO_SWAP")
         message(WARNING "NO_SWAP upgrade strategy is mandatory on target '${TARGET_PLATFORM}'. Your choice was overriden.")
-        set(MCUBOOT_UPGRADE_STRATEGY "NO_SWAP")
+        mcuboot_override_upgrade_strategy("NO_SWAP")
     endif()
 endif()
 
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index f6a8e53..79ff767 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -239,7 +239,8 @@
 	if (NOT DEFINED BL2)
 		message(FATAL_ERROR "Incomplete build configuration: BL2 is undefined. ")
 	elseif (BL2)
-		embedded_set_target_link_defines(TARGET ${EXE_NAME} DEFINES "BL2")
+		#Add BL2 and MCUBOOT_IMAGE_NUMBER defines to linker to resolve symbols in region_defs.h and flash_layout.h
+		embedded_set_target_link_defines(TARGET ${EXE_NAME} DEFINES "BL2" "MCUBOOT_IMAGE_NUMBER=${MCUBOOT_IMAGE_NUMBER}")
 	endif()
 
 	if (NOT DEFINED TFM_PSA_API)