From 815a00d09754006bf9d0b78ecec3fd4fb2585622 Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Thu, 2 May 2019 13:26:49 +0300 Subject: [PATCH] Permit non-TrustZone ARMv8 build Change the heuristic for selection of CMSE in the tools python, so that a non-TrustZone ARMv8 build can happen. Ideally we would have more direct flagging in the targets, but this refines the heuristic so the necessary behaviour can be easily achieved. * DOMAIN_NS=1 is based purely on the `-NS` suffix on the core name. * Enabling CMSE in the compiler and outputting a secure import library is now enabled when the core doesn't have an `-NS` suffix by either the target label `TFM` being present or the flag `trustzone` being set. This covers the existing ARMv8-M behaviour - TF-M builds have the TFM label, as per its documentation; M2351 secure builds have no explicit flagging, so we ensure that the M2351_NS target has the trustzone flag set, and the out-of-tree secure target inherits that. --- .../TARGET_PSA/TARGET_TFM/tf-m-integration.md | 6 ++-- targets/targets.json | 2 ++ tools/build_api.py | 5 +--- tools/targets/__init__.py | 26 ++++++++++++++++ tools/toolchains/arm.py | 29 +++++++++--------- tools/toolchains/gcc.py | 28 +++++++++-------- tools/toolchains/iar.py | 30 ++++++++++--------- 7 files changed, 77 insertions(+), 49 deletions(-) diff --git a/components/TARGET_PSA/TARGET_TFM/tf-m-integration.md b/components/TARGET_PSA/TARGET_TFM/tf-m-integration.md index 089a46075b..f3b4f54556 100644 --- a/components/TARGET_PSA/TARGET_TFM/tf-m-integration.md +++ b/components/TARGET_PSA/TARGET_TFM/tf-m-integration.md @@ -26,12 +26,12 @@ TF-M is built as bare-metal in a secure target, in order to build a secure targe ## Build hooks Mbed-OS testing tools are designed to work with a single image (`.bin` or `.hex`). -When building mbed-os for ARMv8-M targets two images are created. One for normal world(NW) and one for TrustZone(TZ). +When building mbed-os for TF-M targets two images are created. One for normal world(NW) and one for TrustZone(TZ). Mbed-OS build system provides `post_binary_hook` that allows executing arbitrary Python script for merging NW and TZ images. Typically `post_binary_hook` is added to NW target and assumes TZ target images as a prerequisite. -## Porting ARMv8-M targets +## Porting TF-M targets -Typically firmware for ARMv8-M targets consist of 2 or more images: normal world and TrustZone image. More images can be present in case boot loaders are used. +Typically firmware for TF-M targets consist of 2 or more images: normal world and TrustZone image. More images can be present in case boot loaders are used. Two images must be built and linked separately. TrustZone image must be built first. There may be code and/or header files sharing between the two targets. diff --git a/targets/targets.json b/targets/targets.json index f46d8158ce..6c49ae8a5d 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1,6 +1,7 @@ { "Target": { "core": null, + "trustzone": false, "default_toolchain": "ARM", "supported_toolchains": null, "extra_labels": [], @@ -8038,6 +8039,7 @@ "MBED_TZ_DEFAULT_ACCESS=1", "LPTICKER_DELAY_TICKS=3" ], + "trustzone": true, "is_disk_virtual": true, "supported_toolchains": ["ARMC6"], "config": { diff --git a/tools/build_api.py b/tools/build_api.py index bc41376fef..b1d0e7353a 100755 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -604,10 +604,7 @@ def build_project(src_paths, build_path, target, toolchain_name, if into_dir: copy_when_different(res[0], into_dir) if not extra_artifacts: - if ( - CORE_ARCH[toolchain.target.core] == 8 and - not toolchain.target.core.endswith("NS") - ): + if toolchain.target.is_TrustZone_secure_target: cmse_lib = join(dirname(res[0]), "cmse_lib.o") copy_when_different(cmse_lib, into_dir) else: diff --git a/tools/targets/__init__.py b/tools/targets/__init__.py index c69e60fdf5..421630fd3a 100644 --- a/tools/targets/__init__.py +++ b/tools/targets/__init__.py @@ -379,6 +379,32 @@ class Target(namedtuple( labels = (names + CORE_LABELS[self.core] + self.extra_labels) return labels + @property + def core_without_NS(self): + if self.core.endswith('-NS'): + return self.core[:-3] + else: + return self.core + + # Mechanism for specifying TrustZone is subject to change - see + # discussion on https://github.com/ARMmbed/mbed-os/issues/9460 + # In the interim, we follow heuristics that support existing + # documentation for ARMv8-M TF-M integration (check the "TFM" label), + # plus an extra "trustzone" flag set by M2351, and looking at the "-NS" + # suffix. This now permits non-TrustZone ARMv8 builds if + # having trustzone = false (default), no TFM flag, and no -NS suffix. + @property + def is_TrustZone_secure_target(self): + return (getattr(self, 'trustzone', False) or 'TFM' in self.labels) and not self.core.endswith('-NS') + + @property + def is_TrustZone_non_secure_target(self): + return self.core.endswith('-NS') + + @property + def is_TrustZone_target(self): + return self.is_TrustZone_secure_target or self.is_TrustZone_non_secure_target + @property def is_PSA_secure_target(self): return 'SPE_Target' in self.labels diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index efafbae59c..6e65b33f7e 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -25,7 +25,6 @@ from tempfile import mkstemp from shutil import rmtree from distutils.version import LooseVersion -from tools.targets import CORE_ARCH from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS from tools.utils import mkdir, NotSupportedException, run_cmd from tools.resources import FileRef @@ -521,25 +520,25 @@ class ARMC6(ARM_STD): if "--library_type=microlib" not in self.flags['asm']: self.flags['asm'].append("--library_type=microlib") - core = target.core - if CORE_ARCH[target.core] == 8: - if ((not target.core.endswith("-NS")) and - kwargs.get('build_dir', False)): - # Create Secure library + if target.is_TrustZone_secure_target: + if kwargs.get('build_dir', False): + # Output secure import library build_dir = kwargs['build_dir'] secure_file = join(build_dir, "cmse_lib.o") self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file] - # Add linking time preprocessor macro DOMAIN_NS - if target.core.endswith("-NS"): - define_string = self.make_ld_define("DOMAIN_NS", "0x1") - self.flags["ld"].append(define_string) - core = target.core[:-3] - else: - # Add secure build flag - self.flags['cxx'].append("-mcmse") - self.flags['c'].append("-mcmse") + # Enable compiler security extensions + self.flags['cxx'].append("-mcmse") + self.flags['c'].append("-mcmse") + if target.is_TrustZone_non_secure_target: + # Add linking time preprocessor macro DOMAIN_NS + # (DOMAIN_NS is passed to compiler and assembler via CORTEX_SYMBOLS + # in mbedToolchain.get_symbols) + define_string = self.make_ld_define("DOMAIN_NS", "0x1") + self.flags["ld"].append(define_string) + + core = target.core_without_NS cpu = { "Cortex-M0+": "cortex-m0plus", "Cortex-M4F": "cortex-m4", diff --git a/tools/toolchains/gcc.py b/tools/toolchains/gcc.py index 1ec3b4cb83..29651e6737 100644 --- a/tools/toolchains/gcc.py +++ b/tools/toolchains/gcc.py @@ -20,7 +20,6 @@ from os import getenv from distutils.spawn import find_executable from distutils.version import LooseVersion -from tools.targets import CORE_ARCH from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS from tools.utils import run_cmd @@ -59,20 +58,23 @@ class GCC(mbedToolchain): self.flags["common"].append("-DMBED_RTOS_SINGLE_THREAD") self.flags["ld"].append("--specs=nano.specs") - core = target.core self.cpu = [] - if CORE_ARCH[target.core] == 8: - # Add linking time preprocessor macro DOMAIN_NS - if target.core.endswith("-NS"): - self.flags["ld"].append("-DDOMAIN_NS=1") - core = target.core[:-3] - else: - self.cpu.append("-mcmse") - self.flags["ld"].extend([ - "-Wl,--cmse-implib", - "-Wl,--out-implib=%s" % join(build_dir, "cmse_lib.o") - ]) + if target.is_TrustZone_secure_target: + # Enable compiler security extensions + self.cpu.append("-mcmse") + # Output secure import library + self.flags["ld"].extend([ + "-Wl,--cmse-implib", + "-Wl,--out-implib=%s" % join(build_dir, "cmse_lib.o") + ]) + if target.is_TrustZone_non_secure_target: + # Add linking time preprocessor macro DOMAIN_NS + # (DOMAIN_NS is passed to compiler and assembler via CORTEX_SYMBOLS + # in mbedToolchain.get_symbols) + self.flags["ld"].append("-DDOMAIN_NS=1") + + core = target.core_without_NS cpu = { "Cortex-M0+": "cortex-m0plus", "Cortex-M4F": "cortex-m4", diff --git a/tools/toolchains/iar.py b/tools/toolchains/iar.py index bec91e37d5..b2a5d4d8fc 100644 --- a/tools/toolchains/iar.py +++ b/tools/toolchains/iar.py @@ -19,7 +19,6 @@ from os import remove from os.path import join, splitext, exists from distutils.version import LooseVersion -from tools.targets import CORE_ARCH from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS from tools.utils import run_cmd @@ -54,20 +53,23 @@ class IAR(mbedToolchain): build_dir=build_dir, build_profile=build_profile ) - core = target.core - if CORE_ARCH[target.core] == 8: - # Add linking time preprocessor macro DOMAIN_NS - if target.core.endswith("-NS"): - define_string = self.make_ld_define("DOMAIN_NS", "0x1") - self.flags["ld"].append(define_string) - core = target.core[:-3] - else: - # Create Secure library - self.flags["asm"] += ["--cmse"] - self.flags["common"] += ["--cmse"] - secure_file = join(build_dir, "cmse_lib.o") - self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file] + if target.is_TrustZone_secure_target: + # Enable compiler security extensions + self.flags["asm"] += ["--cmse"] + self.flags["common"] += ["--cmse"] + # Output secure import library + secure_file = join(build_dir, "cmse_lib.o") + self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file] + + if target.is_TrustZone_non_secure_target: + # Add linking time preprocessor macro DOMAIN_NS + # (DOMAIN_NS is passed to compiler and assembler via CORTEX_SYMBOLS + # in mbedToolchain.get_symbols) + define_string = self.make_ld_define("DOMAIN_NS", "0x1") + self.flags["ld"].append(define_string) + + core = target.core_without_NS cpu = { "Cortex-M7F": "Cortex-M7.fp.sp", "Cortex-M7FD": "Cortex-M7.fp.dp",