1#------------------------------------------------------------------------------- 2# Copyright (c) 2020-2022, Arm Limited. All rights reserved. 3# 4# SPDX-License-Identifier: BSD-3-Clause 5# 6#------------------------------------------------------------------------------- 7 8cmake_minimum_required(VERSION 3.15) 9find_package(Python3) 10 11############################### Manifest lists declaration ##################### 12list(APPEND MANIFEST_LISTS ${TFM_MANIFEST_LIST}) 13 14if (TFM_NS_REG_TEST OR TFM_S_REG_TEST) 15 list(APPEND MANIFEST_LISTS ${TFM_TEST_PATH}/secure_fw/tfm_test_manifest_list.yaml) 16endif() 17 18if ("${TEST_PSA_API}" STREQUAL "IPC") 19 # The manifest tool does not recognize CMake varibles. Do configure_file() first. 20 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tfm_psa_ff_test_manifest_list.yaml 21 ${CMAKE_CURRENT_BINARY_DIR}/tfm_psa_ff_test_manifest_list.yaml) 22 list(APPEND MANIFEST_LISTS ${CMAKE_CURRENT_BINARY_DIR}/tfm_psa_ff_test_manifest_list.yaml) 23endif() 24 25if (TFM_EXTRA_MANIFEST_LIST_FILES) 26 list(APPEND MANIFEST_LISTS ${TFM_EXTRA_MANIFEST_LIST_FILES}) 27endif() 28 29if (TFM_EXTRAS_REPO_EXTRA_MANIFEST_LIST) 30 set(TMP_MANIFEST_LISTS ${TFM_EXTRAS_REPO_EXTRA_MANIFEST_LIST}) 31 list(TRANSFORM TMP_MANIFEST_LISTS PREPEND ${TFM_EXTRAS_REPO_PATH}/) 32 list(APPEND MANIFEST_LISTS ${TMP_MANIFEST_LISTS}) 33endif() 34 35# Remove any duplicate entries to prevent same path appended twice in case of mulitiple runs 36list(REMOVE_DUPLICATES MANIFEST_LISTS) 37 38############################### File list declaration ########################## 39set(GENERATED_FILE_LISTS ${CMAKE_CURRENT_SOURCE_DIR}/tfm_generated_file_list.yaml) 40set(GENERATED_FILE_LISTS ${GENERATED_FILE_LISTS} ${TFM_EXTRA_GENERATED_FILE_LIST_PATH}) 41 42############################### Functions declaration ########################## 43# Parses the given YAML "files" to find out all the items of the given "field" 44# and put them to the "output_variable" as a list. 45function(parse_field_from_yaml files field output_variable) 46 set(local_variable "") 47 foreach(yaml_file ${files}) 48 # Load the lines that refer to the key we selected 49 file(STRINGS ${yaml_file} temp_variable REGEX " *\"${field}\":") 50 # Take only the value of the key 51 list(TRANSFORM temp_variable REPLACE " *\"${field}\": *" ";") 52 # Remove all commas 53 list(TRANSFORM temp_variable REPLACE "," "") 54 # Remove all quote marks 55 list(TRANSFORM temp_variable REPLACE "\"" "") 56 list(APPEND local_variable ${temp_variable}) 57 endforeach() 58 set(${output_variable} ${local_variable} PARENT_SCOPE) 59endfunction() 60 61############################### Dependency generation ########################## 62# Get all the manifest files from manifest lists 63foreach(MANIFEST_LIST ${MANIFEST_LISTS}) 64 if (NOT EXISTS ${MANIFEST_LIST}) 65 message(FATAL_ERROR "Manifest list ${MANIFEST_LIST} doesn't exist") 66 endif() 67 68 # Get the path of the manifest list 69 get_filename_component(MANIFEST_LIST_PATH ${MANIFEST_LIST} DIRECTORY) 70 71 # Get all the "manifest" 72 parse_field_from_yaml(${MANIFEST_LIST} manifest MANIFESTS) 73 74 foreach(MANIFEST ${MANIFESTS}) 75 # Convert to absolute paths 76 if (NOT IS_ABSOLUTE ${MANIFEST}) 77 get_filename_component(MANIFEST "${MANIFEST_LIST_PATH}/${MANIFEST}" ABSOLUTE) 78 endif() 79 list(APPEND MANIFEST_FILES ${MANIFEST}) 80 endforeach() 81endforeach() 82 83parse_field_from_yaml("${GENERATED_FILE_LISTS}" template TEMPLATE_FILES) 84# Replace relative paths with absolute paths 85# Paths used in GENERATED_FILE_LISTS are all relative to TF-M root (${CMAKE_SOURCE_DIR}) 86list(TRANSFORM TEMPLATE_FILES REPLACE "^([^/\\][^:].*)" "${CMAKE_SOURCE_DIR}/\\1") 87 88parse_field_from_yaml("${GENERATED_FILE_LISTS}" output OUTPUT_FILES) 89# Replace relative paths with absolute paths 90# Paths used in GENERATED_FILE_LISTS are all relative to TF-M root (${CMAKE_SOURCE_DIR}) 91list(TRANSFORM OUTPUT_FILES REPLACE "^([^/\\][^:].*)" "${CMAKE_BINARY_DIR}/generated/\\1") 92 93############################### Generate Manifest config header ################ 94 95# The function appends the given `config` to the `out_var` variable. 96# Supported `type` are [BOOL, STRING]. 97# The format of contents appended is 98# #cmakedefine01 config for BOOL types 99# #cmakedefine config @config@ for STRING types 100function(append_manifest_config out_var config type) 101 # Operate on a local var and write back to the out_var later 102 set(local_var ${${out_var}}) 103 104 # Avoid duplications of configs 105 string(FIND "${local_var}" ${config} config_exists) 106 if(${config_exists} EQUAL -1) # Not found 107 if (${type} STREQUAL "BOOL") 108 string(APPEND local_var "#cmakedefine01 ${config}\r\n") 109 elseif(${type} STREQUAL "STRING") 110 string(APPEND local_var "#cmakedefine ${config} @${config}@\r\n") 111 else() 112 message(FATAL_ERROR "Unsupported config type: ${type}") 113 endif() 114 endif() 115 116 set(${out_var} ${local_var} PARENT_SCOPE) 117endfunction() 118 119# The following build configurations are required to pass to manifest tool via the config header 120# - The isolation level 121# - The SPM backend 122# - "conditional" attributes for every Secure Partition in manifest lists 123# - "stack_size" in manifests 124# - "heap_size" in manifests 125append_manifest_config(MANIFEST_CONFIG_H_CONTENT TFM_ISOLATION_LEVEL STRING) 126append_manifest_config(MANIFEST_CONFIG_H_CONTENT CONFIG_TFM_SPM_BACKEND STRING) 127 128parse_field_from_yaml("${MANIFEST_LISTS}" conditional CONDITIONS) 129foreach(CON ${CONDITIONS}) 130 append_manifest_config(MANIFEST_CONFIG_H_CONTENT ${CON} BOOL) 131endforeach() 132 133parse_field_from_yaml("${MANIFEST_FILES}" stack_size STACK_SIZES) 134foreach(STK_SIZE ${STACK_SIZES}) 135 if (NOT STK_SIZE GREATER 0) 136 # The "stack_size" might not be a valid number. Treat it as a configuration 137 append_manifest_config(MANIFEST_CONFIG_H_CONTENT ${STK_SIZE} STRING) 138 endif() 139endforeach() 140 141parse_field_from_yaml("${MANIFEST_FILES}" heap_size HEAP_SIZES) 142foreach(HEAP_SIZE ${HEAP_SIZES}) 143 if (NOT HEAP_SIZE GREATER 0) 144 # The "heap_size" might not be a valid number. Treat it as a configuration 145 append_manifest_config(MANIFEST_CONFIG_H_CONTENT ${HEAP_SIZE} STRING) 146 endif() 147endforeach() 148 149# Generate the config header 150file(WRITE 151 ${CMAKE_CURRENT_BINARY_DIR}/manifest_config.h.in 152 ${MANIFEST_CONFIG_H_CONTENT}) 153 154configure_file(${CMAKE_CURRENT_BINARY_DIR}/manifest_config.h.in 155 ${CMAKE_CURRENT_BINARY_DIR}/manifest_config.h) 156 157############################### Command declaration ############################ 158 159# Workaround for heap support 160if ("${TEST_PSA_API}" STREQUAL "IPC") 161 execute_process( 162 WORKING_DIRECTORY ${PSA_ARCH_TESTS_PATH}/api-tests 163 COMMAND ${Python3_EXECUTABLE} tools/scripts/manifest_update.py 164 ) 165endif() 166 167if (CONFIG_TFM_PARSE_MANIFEST_QUIET) 168 set(PARSE_MANIFEST_QUIET_FLAG "-q") 169else() 170 set(PARSE_MANIFEST_QUIET_FLAG "") 171endif() 172 173set(MANIFEST_COMMAND 174 ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tfm_parse_manifest_list.py 175 -m ${MANIFEST_LISTS} 176 -f ${GENERATED_FILE_LISTS} 177 -c ${CMAKE_CURRENT_BINARY_DIR}/manifest_config.h 178 -o ${CMAKE_BINARY_DIR}/generated 179 ${PARSE_MANIFEST_QUIET_FLAG}) 180 181# The files need to be generated before cmake will allow them to be used as 182# sources. Due to issue with custom_command scoping the easiest way to do this 183# is to run the script at cmake-time. 184execute_process( 185 COMMAND ${MANIFEST_COMMAND} 186 RESULT_VARIABLE RET 187) 188 189if(RET EQUAL 0) 190 include(${CMAKE_BINARY_DIR}/generated/tools/config_impl.cmake) 191else() 192 message(FATAL_ERROR "Manifest tool failed to generate files!") 193endif() 194