SPM: Add FPU support for gnu arm embedded toolchain

1. Enable FP support in SPE by CONFIG_TFM_SPE_FP (0:software, 1:hybird,
   2:hardware) for IPC model.
   It doesn't support LIBRARY model.
2. Enable lazy stacking from SPE by CONFIG_TFM_LAZY_STACKING_SPE (OFF,
   ON).
3. Separate qcbor, t_cose for SPE and NSPE.

Note:
   NSPE is not allowed to use FPU at current stage when FPU is enabled
   for SPE.

Change-Id: I856fdcccbbc403c5ec3689d95df4d082f106ff47
Signed-off-by: Feder Liang <Feder.Liang@arm.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 726f650..1e11999 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,9 +26,6 @@
     include(platform/ext/target/${TFM_PLATFORM}/preload.cmake)
 endif()
 
-if(TFM_SYSTEM_FP)
-    message(FATAL_ERROR "Hardware FPU is currently not supported in TF-M")
-endif()
 if(TFM_SYSTEM_MVE)
     message(FATAL_ERROR "Hardware MVE is currently not supported in TF-M")
 endif()
diff --git a/bl2/CMakeLists.txt b/bl2/CMakeLists.txt
index 3cba7ad..5cfef48 100644
--- a/bl2/CMakeLists.txt
+++ b/bl2/CMakeLists.txt
@@ -36,6 +36,11 @@
         tfm_boot_status
 )
 
+target_compile_options(bl2
+    PRIVATE
+        ${BL2_COMPILER_CP_FLAG}
+)
+
 target_link_options(bl2
     PRIVATE
         $<$<C_COMPILER_ID:GNU>:-Wl,-Map=${CMAKE_BINARY_DIR}/bin/bl2.map>
@@ -110,6 +115,21 @@
         ${MBEDCRYPTO_PATH}/library
 )
 
+target_compile_options(bl2_mbedcrypto
+    PRIVATE
+        ${BL2_COMPILER_CP_FLAG}
+)
+
+target_compile_options(bl2_mbedtls
+    PRIVATE
+        ${BL2_COMPILER_CP_FLAG}
+)
+
+target_compile_options(bl2_mbedx509
+    PRIVATE
+        ${BL2_COMPILER_CP_FLAG}
+)
+
 ############################### CODE SHARING ###################################
 
 if (TFM_CODE_SHARING)
diff --git a/bl2/ext/mcuboot/CMakeLists.txt b/bl2/ext/mcuboot/CMakeLists.txt
index d375c76..be93e65 100644
--- a/bl2/ext/mcuboot/CMakeLists.txt
+++ b/bl2/ext/mcuboot/CMakeLists.txt
@@ -27,6 +27,11 @@
         bl2_mbedcrypto
 )
 
+target_compile_options(bootutil
+    PRIVATE
+        ${BL2_COMPILER_CP_FLAG}
+)
+
 target_compile_definitions(bootutil
     PRIVATE
         $<$<BOOL:${DEFAULT_MCUBOOT_FLASH_MAP}>:DEFAULT_MCUBOOT_FLASH_MAP>
diff --git a/config/check_config.cmake b/config/check_config.cmake
index ffe0457..9feb125 100644
--- a/config/check_config.cmake
+++ b/config/check_config.cmake
@@ -51,6 +51,14 @@
 tfm_invalid_config(TEST_PSA_API STREQUAL "STORAGE" AND NOT TFM_PARTITION_INTERNAL_TRUSTED_STORAGE)
 tfm_invalid_config(TEST_PSA_API STREQUAL "STORAGE" AND NOT TFM_PARTITION_PROTECTED_STORAGE)
 
+########################## FPU ################################################
+
+tfm_invalid_config(CONFIG_TFM_SPE_FP LESS 0 OR CONFIG_TFM_SPE_FP GREATER 2)
+tfm_invalid_config(NOT CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CONFIG_TFM_SPE_FP GREATER 0)
+tfm_invalid_config((NOT CONFIG_TFM_FP_ARCH) AND (CONFIG_TFM_SPE_FP GREATER 0))
+tfm_invalid_config((NOT TFM_PSA_API) AND (CONFIG_TFM_SPE_FP GREATER 0))
+tfm_invalid_config(CONFIG_TFM_SPE_FP STREQUAL "0" AND CONFIG_TFM_LAZY_STACKING_SPE)
+
 ########################## BL2 #################################################
 
 get_property(MCUBOOT_STRATEGY_LIST CACHE MCUBOOT_UPGRADE_STRATEGY PROPERTY STRINGS)
diff --git a/config/config_default.cmake b/config/config_default.cmake
index c7e6170..1baeaac 100755
--- a/config/config_default.cmake
+++ b/config/config_default.cmake
@@ -53,6 +53,9 @@
 
 set(TFM_EXCEPTION_INFO_DUMP             OFF         CACHE BOOL      "On fatal errors in the secure firmware, capture info about the exception. Print the info if the SPM log level is sufficient.")
 
+set(CONFIG_TFM_SPE_FP                   0           CACHE STRING    "FP ABI type in SPE: 0-software, 1-hybird, 2-hardware")
+set(CONFIG_TFM_LAZY_STACKING_SPE        OFF         CACHE BOOL      "Disable lazy stacking from SPE")
+
 ############################ Platform ##########################################
 
 set(TFM_MULTI_CORE_TOPOLOGY             OFF         CACHE BOOL      "Whether to build for a dual-cpu architecture")
@@ -161,3 +164,7 @@
 ########################## FIH #################################################
 
 set_property(CACHE TFM_FIH_PROFILE PROPERTY STRINGS "OFF;LOW;MEDIUM;HIGH")
+
+########################## FP #################################################
+
+set_property(CACHE CONFIG_TFM_SPE_FP PROPERTY STRINGS "0;1;2")
diff --git a/config/cp_config_default.cmake b/config/cp_config_default.cmake
new file mode 100644
index 0000000..842bc83
--- /dev/null
+++ b/config/cp_config_default.cmake
@@ -0,0 +1,17 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+################################### FP ########################################
+
+if (NOT DEFINED CONFIG_TFM_FP_ARCH)
+    set(CONFIG_TFM_FP_ARCH "")
+    return()
+endif()
+
+if (CONFIG_TFM_SPE_FP STREQUAL "1" OR CONFIG_TFM_SPE_FP STREQUAL "2")
+    set(CONFIG_TFM_LAZY_STACKING_SPE     ON          CACHE BOOL      "Enable lazy stacking from SPE")
+endif()
diff --git a/config/set_config.cmake b/config/set_config.cmake
index fe69e68..3c81001 100644
--- a/config/set_config.cmake
+++ b/config/set_config.cmake
@@ -56,6 +56,9 @@
     include(${CMAKE_SOURCE_DIR}/bl2/ext/mcuboot/mcuboot_default_config.cmake)
 endif()
 
+# Include coprocessor configs
+include(config/cp_config_default.cmake)
+
 # Load defaults, setting options not already set
 include(config/config_default.cmake)
 
diff --git a/lib/ext/qcbor/CMakeLists.txt b/lib/ext/qcbor/CMakeLists.txt
index b32cdea..a84850a 100644
--- a/lib/ext/qcbor/CMakeLists.txt
+++ b/lib/ext/qcbor/CMakeLists.txt
@@ -7,9 +7,9 @@
 
 cmake_minimum_required(VERSION 3.15)
 
-add_library(tfm_qcbor STATIC EXCLUDE_FROM_ALL)
+add_library(tfm_qcbor_s STATIC EXCLUDE_FROM_ALL)
 
-target_sources(tfm_qcbor
+target_sources(tfm_qcbor_s
     PRIVATE
         src/ieee754.c
         src/qcbor_encode.c
@@ -17,39 +17,18 @@
         src/UsefulBuf.c
 )
 
-target_include_directories(tfm_qcbor
+target_include_directories(tfm_qcbor_s
     PUBLIC
         $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
 )
 
-target_link_libraries(tfm_qcbor
+target_link_libraries(tfm_qcbor_s
     PRIVATE
         tfm_attestation_defs
         tfm_t_cose_defs
 )
 
-############################ qcbor test ########################################
-
-add_library(tfm_qcbor_test STATIC EXCLUDE_FROM_ALL)
-
-target_sources(tfm_qcbor_test
+target_compile_options(tfm_qcbor_s
     PRIVATE
-        test/float_tests.c
-        test/half_to_double_from_rfc7049.c
-        test/qcbor_decode_tests.c
-        test/qcbor_encode_tests.c
-        test/run_tests.c
-        test/UsefulBuf_Tests.c
-)
-
-target_include_directories(tfm_qcbor_test
-    PUBLIC
-        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/test>
-    PRIVATE
-        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
-)
-
-target_link_libraries(tfm_qcbor_test
-    PRIVATE
-        tfm_qcbor
+        ${COMPILER_CP_FLAG}
 )
diff --git a/lib/ext/t_cose/CMakeLists.txt b/lib/ext/t_cose/CMakeLists.txt
index cd780ad..06448b1 100644
--- a/lib/ext/t_cose/CMakeLists.txt
+++ b/lib/ext/t_cose/CMakeLists.txt
@@ -46,18 +46,6 @@
         ${CMAKE_CURRENT_SOURCE_DIR}/crypto_adapters/t_cose_psa_crypto.c
 )
 
-############################ t_cose non secure #################################
-
-add_library(tfm_t_cose_ns STATIC EXCLUDE_FROM_ALL)
-
-target_link_libraries(tfm_t_cose_ns
-    PUBLIC
-        tfm_t_cose_common
-        tfm_t_cose_defs
-        tfm_qcbor
-        tfm_ns_interface
-)
-
 ############################ t_cose secure #####################################
 
 add_library(tfm_t_cose_s STATIC EXCLUDE_FROM_ALL)
@@ -66,30 +54,11 @@
     PUBLIC
         tfm_t_cose_common
         tfm_t_cose_defs
-        tfm_qcbor
+        tfm_qcbor_s
         psa_interface
 )
 
-############################ t_cose test #######################################
-
-add_library(tfm_t_cose_test STATIC EXCLUDE_FROM_ALL)
-
-target_sources(tfm_t_cose_test
-    PRIVATE
-        test/run_tests.c
-        test/t_cose_make_psa_test_key.c
-        test/t_cose_make_test_messages.c
-        test/t_cose_sign_verify_test.c
-        test/t_cose_test.c
-)
-
-target_include_directories(tfm_t_cose_test
+target_compile_options(tfm_t_cose_s
     PUBLIC
-        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>
-        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/test>
-)
-
-target_link_libraries(tfm_t_cose_test
-    PRIVATE
-        tfm_t_cose_ns
+        ${COMPILER_CP_FLAG}
 )
diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt
index 599927d..03f7afb 100755
--- a/platform/CMakeLists.txt
+++ b/platform/CMakeLists.txt
@@ -81,6 +81,8 @@
     PUBLIC
         TFM_SPM_LOG_LEVEL=${TFM_SPM_LOG_LEVEL}
         $<$<BOOL:${OTP_NV_COUNTERS_RAM_EMULATION}>:OTP_NV_COUNTERS_RAM_EMULATION>
+        CONFIG_TFM_SPE_FP=${CONFIG_TFM_SPE_FP}
+        $<$<BOOL:${CONFIG_TFM_LAZY_STACKING_SPE}>:CONFIG_TFM_LAZY_STACKING_SPE>
     PRIVATE
         $<$<BOOL:${SYMMETRIC_INITIAL_ATTESTATION}>:SYMMETRIC_INITIAL_ATTESTATION>
         $<$<OR:$<VERSION_GREATER:${TFM_ISOLATION_LEVEL},1>,$<STREQUAL:"${TEST_PSA_API}","IPC">>:CONFIG_TFM_ENABLE_MEMORY_PROTECT>
@@ -93,6 +95,11 @@
         $<$<BOOL:${PLATFORM_DEFAULT_OTP_WRITEABLE}>:OTP_WRITEABLE>
 )
 
+target_compile_options(platform_s
+    PUBLIC
+        ${COMPILER_CP_FLAG}
+)
+
 #========================= Platform Non-Secure ================================#
 
 target_sources(platform_ns
diff --git a/platform/ext/accelerator/cc312/CMakeLists.txt b/platform/ext/accelerator/cc312/CMakeLists.txt
index d8cd304..20acdb7 100644
--- a/platform/ext/accelerator/cc312/CMakeLists.txt
+++ b/platform/ext/accelerator/cc312/CMakeLists.txt
@@ -104,6 +104,21 @@
             $<$<C_COMPILER_ID:GNU>:-Wno-unused-parameter>
             $<$<C_COMPILER_ID:ARMClang>:-Wno-unused-parameter>
     )
+
+    target_compile_options(bl2_cc312
+        PRIVATE
+            ${BL2_COMPILER_CP_FLAG}
+    )
+
+    target_compile_options(bl2_crypto_hw
+        PRIVATE
+            ${BL2_COMPILER_CP_FLAG}
+    )
+
+    target_compile_options(cc312_cdmpu
+        INTERFACE
+            ${BL2_COMPILER_CP_FLAG}
+    )
 endif()
 
 ############################ Crypto Service ####################################
diff --git a/platform/ext/target/arm/musca_s1/CMakeLists.txt b/platform/ext/target/arm/musca_s1/CMakeLists.txt
index 941762f..4f3155b 100644
--- a/platform/ext/target/arm/musca_s1/CMakeLists.txt
+++ b/platform/ext/target/arm/musca_s1/CMakeLists.txt
@@ -165,4 +165,9 @@
             ${MCUBOOT_PATH}/boot/bootutil/include # for fault_injection_hardening.h only
             ${CMAKE_BINARY_DIR}/bl2/ext/mcuboot # for mcuboot_config.h only
     )
+
+    target_compile_options(platform_bl2
+        PRIVATE
+            ${BL2_COMPILER_CP_FLAG}
+    )
 endif()
diff --git a/platform/ext/target/arm/musca_s1/preload.cmake b/platform/ext/target/arm/musca_s1/preload.cmake
index 0eb0c46..e498bca 100644
--- a/platform/ext/target/arm/musca_s1/preload.cmake
+++ b/platform/ext/target/arm/musca_s1/preload.cmake
@@ -13,7 +13,7 @@
 # Set architecture and CPU
 set(TFM_SYSTEM_PROCESSOR cortex-m33)
 set(TFM_SYSTEM_ARCHITECTURE armv8-m.main)
-
+set(CONFIG_TFM_FP_ARCH "fpv5-sp-d16")
 
 # The MUSCA_S1 has a CryptoCell-312 as an accelerator.
 set(CRYPTO_HW_ACCELERATOR_TYPE cc312)
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index 982bea8..14f6145 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -69,12 +69,19 @@
         RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
 )
 
+target_compile_options(tfm_s
+    PUBLIC
+        ${COMPILER_CP_FLAG}
+)
+
 target_link_options(tfm_s
     PRIVATE
         --entry=Reset_Handler
         $<$<C_COMPILER_ID:GNU>:-Wl,-Map=${CMAKE_BINARY_DIR}/bin/tfm_s.map>
         $<$<C_COMPILER_ID:ARMClang>:--map>
         $<$<C_COMPILER_ID:IAR>:--map\;${CMAKE_BINARY_DIR}/bin/tfm_s.map>
+    PUBLIC
+        ${LINKER_CP_OPTION}
 )
 
 add_convert_to_bin_target(tfm_s)
diff --git a/secure_fw/partitions/initial_attestation/CMakeLists.txt b/secure_fw/partitions/initial_attestation/CMakeLists.txt
index 72cc09e..cd98771 100644
--- a/secure_fw/partitions/initial_attestation/CMakeLists.txt
+++ b/secure_fw/partitions/initial_attestation/CMakeLists.txt
@@ -59,7 +59,7 @@
     PRIVATE
         tfm_secure_api
         platform_s
-        tfm_qcbor
+        tfm_qcbor_s
         tfm_t_cose_s
         secure_fw
         psa_interface
diff --git a/secure_fw/spm/CMakeLists.txt b/secure_fw/spm/CMakeLists.txt
index 2eed0af..eccc807 100755
--- a/secure_fw/spm/CMakeLists.txt
+++ b/secure_fw/spm/CMakeLists.txt
@@ -117,6 +117,12 @@
         $<$<AND:$<BOOL:${BL2}>,$<BOOL:${MCUBOOT_MEASURED_BOOT}>>:BOOT_DATA_AVAILABLE>
         $<$<BOOL:${TFM_EXCEPTION_INFO_DUMP}>:TFM_EXCEPTION_INFO_DUMP>
         $<$<BOOL:${TFM_NS_MANAGE_NSID}>:TFM_NS_MANAGE_NSID>
+        CONFIG_TFM_SPE_FP=${CONFIG_TFM_SPE_FP}
+)
+
+target_compile_options(tfm_spm
+    PUBLIC
+        ${COMPILER_CP_FLAG}
 )
 
 # The veneers give warnings about not being properly declared so they get hidden
diff --git a/secure_fw/spm/cmsis_psa/main.c b/secure_fw/spm/cmsis_psa/main.c
index d586b3c..402b545 100644
--- a/secure_fw/spm/cmsis_psa/main.c
+++ b/secure_fw/spm/cmsis_psa/main.c
@@ -101,6 +101,22 @@
 
     SPMLOG_DBGMSGVAL("TF-M isolation level is: ", TFM_LVL);
 
+#if (CONFIG_TFM_SPE_FP == 0)
+    SPMLOG_INFMSG("\033[1;33mTF-M FPU mode: Software\033[0m\r\n");
+#elif (CONFIG_TFM_SPE_FP == 1)
+    SPMLOG_INFMSG("\033[1;33mTF-M FPU mode: Hybird\033[0m\r\n");
+#elif (CONFIG_TFM_SPE_FP == 2)
+    SPMLOG_INFMSG("\033[1;33mTF-M FPU mode: Hardware\033[0m\r\n");
+#endif
+
+#if (CONFIG_TFM_SPE_FP >= 1)
+#ifdef CONFIG_TFM_LAZY_STACKING_SPE
+    SPMLOG_INFMSG("\033[1;33mLazy stacking enabled\033[0m\r\n");
+#else
+    SPMLOG_INFMSG("\033[1;33mLazy stacking disabled\033[0m\r\n");
+#endif
+#endif
+
     tfm_core_validate_boot_data();
 
     configure_ns_code();
diff --git a/toolchain_GNUARM.cmake b/toolchain_GNUARM.cmake
index 760a098..2ed640b 100644
--- a/toolchain_GNUARM.cmake
+++ b/toolchain_GNUARM.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -49,7 +49,6 @@
         -nostdlib
         -std=c99
         $<$<BOOL:${TFM_DEBUG_SYMBOLS}>:-g>
-        $<$<NOT:$<BOOL:${TFM_SYSTEM_FP}>>:-msoft-float>
     )
 endmacro()
 
@@ -76,6 +75,13 @@
                 string(APPEND CMAKE_SYSTEM_PROCESSOR "+nodsp")
             endif()
         endif()
+        if(GCC_VERSION VERSION_GREATER_EQUAL "8.0.0")
+            if (DEFINED CONFIG_TFM_SPE_FP)
+                if(CONFIG_TFM_SPE_FP STREQUAL "0")
+                    string(APPEND CMAKE_SYSTEM_PROCESSOR "+nofp")
+                endif()
+            endif()
+        endif()
     endif()
 
     # CMAKE_SYSTEM_ARCH variable is not a built-in CMAKE variable. It is used to
@@ -95,6 +101,14 @@
             endif()
         endif()
     endif()
+
+    if(GCC_VERSION VERSION_GREATER_EQUAL "8.0.0")
+        if (DEFINED CONFIG_TFM_SPE_FP)
+            if(CONFIG_TFM_SPE_FP STRGREATER 0)
+                string(APPEND CMAKE_SYSTEM_ARCH "+fp")
+            endif()
+        endif()
+    endif()
 endmacro()
 
 macro(tfm_toolchain_reload_compiler)
@@ -125,6 +139,19 @@
 
     set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_INIT})
     set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS_INIT})
+
+    set(BL2_COMPILER_CP_FLAG -mfloat-abi=soft)
+
+    if (CONFIG_TFM_SPE_FP STREQUAL "2")
+        set(COMPILER_CP_FLAG -mfloat-abi=hard -mfpu=${CONFIG_TFM_FP_ARCH})
+        set(LINKER_CP_OPTION -mfloat-abi=hard -mfpu=${CONFIG_TFM_FP_ARCH})
+    elseif (CONFIG_TFM_SPE_FP STREQUAL "1")
+        set(COMPILER_CP_FLAG -mfloat-abi=softfp -mfpu=${CONFIG_TFM_FP_ARCH})
+        set(LINKER_CP_OPTION -mfloat-abi=softfp -mfpu=${CONFIG_TFM_FP_ARCH})
+    else()
+        set(COMPILER_CP_FLAG -mfloat-abi=soft)
+        set(LINKER_CP_OPTION -mfloat-abi=soft)
+    endif()
 endmacro()
 
 # Configure environment for the compiler setup run by cmake at the first