diff options
author | avieira <avieira@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-12-02 15:22:43 +0000 |
---|---|---|
committer | avieira <avieira@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-12-02 15:22:43 +0000 |
commit | 0120ae3031097eb092abd20bddac45f58762b1a9 (patch) | |
tree | 6811602f7f8aa090716356b734baf53b5076392b /libgcc | |
parent | b99ff0e778469b11eaab6563f68478c4486903ad (diff) | |
download | gcc-0120ae3031097eb092abd20bddac45f58762b1a9.tar.gz |
Add support for ARMv8-M's Secure Extensions flag and intrinsics
gcc/ChangeLog:
2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com>
Thomas Preud'homme <thomas.preudhomme@arm.com>
* config.gcc (extra_headers): Added arm_cmse.h.
* config/arm/arm-arches.def (ARM_ARCH):
(armv8-m): Add FL2_CMSE.
(armv8-m.main): Likewise.
(armv8-m.main+dsp): Likewise.
* config/arm/arm-c.c
(arm_cpu_builtins): Added __ARM_FEATURE_CMSE macro.
* config/arm/arm-flags.h: Define FL2_CMSE.
* config/arm.c (arm_arch_cmse): New.
(arm_option_override): New error for unsupported cmse target.
* config/arm/arm.h (arm_arch_cmse): New.
* config/arm/arm.opt (mcmse): New.
* config/arm/arm_cmse.h: New file.
* doc/invoke.texi (ARM Options): Add -mcmse.
* doc/sourcebuild.texi (arm_cmse_ok): Add new effective target.
* doc/extend.texi: Add ARMv8-M Security Extensions entry.
gcc/testsuite/ChangeLog:
2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com>
Thomas Preud'homme <thomas.preudhomme@arm.com>
* gcc.target/arm/cmse/cmse.exp: New.
* gcc.target/arm/cmse/cmse-1.c: New.
* gcc.target/arm/cmse/cmse-12.c: New.
* lib/target-supports.exp
(check_effective_target_arm_cmse_ok): New.
libgcc/ChangeLog:
2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com>
Thomas Preud'homme <thomas.preudhomme@arm.com>
* config/arm/t-arm (HAVE_CMSE): New.
* config/arm/cmse.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@243187 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 6 | ||||
-rw-r--r-- | libgcc/config/arm/cmse.c | 108 | ||||
-rw-r--r-- | libgcc/config/arm/t-arm | 12 |
3 files changed, 126 insertions, 0 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 438021aa1ab..f323f4384af 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2016-12-02 Andre Vieira <andre.simoesdiasvieira@arm.com> + Thomas Preud'homme <thomas.preudhomme@arm.com> + + * config/arm/t-arm (HAVE_CMSE): New. + * config/arm/cmse.c: New. + 2016-11-28 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> PR gcc/74748 diff --git a/libgcc/config/arm/cmse.c b/libgcc/config/arm/cmse.c new file mode 100644 index 00000000000..fe3a22967c8 --- /dev/null +++ b/libgcc/config/arm/cmse.c @@ -0,0 +1,108 @@ +/* ARMv8-M Security Extensions routines. + Copyright (C) 2015-2016 Free Software Foundation, Inc. + Contributed by ARM Ltd. + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + + +#if __ARM_FEATURE_CMSE & 1 + +#include <arm_cmse.h> + +/* ARM intrinsic function to perform a permission check on a given + address range. See ACLE changes for ARMv8-M. */ + +void * +cmse_check_address_range (void *p, size_t size, int flags) +{ + cmse_address_info_t permb, perme; + char *pb = (char *) p, *pe; + + /* Check if the range wraps around. */ + if (UINTPTR_MAX - (uintptr_t) p < size) + return NULL; + + /* Check if an unknown flag is present. */ + int known = CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE | CMSE_MPU_READ; + int known_secure_level = CMSE_MPU_UNPRIV; +#if __ARM_FEATURE_CMSE & 2 + known |= CMSE_AU_NONSECURE | CMSE_MPU_NONSECURE; + known_secure_level |= CMSE_MPU_NONSECURE; +#endif + if (flags & (~known)) + return NULL; + + /* Execute the right variant of the TT instructions. */ + pe = pb + size - 1; + const int singleCheck = (((uintptr_t) pb ^ (uintptr_t) pe) < 32); + switch (flags & known_secure_level) + { + case 0: + permb = cmse_TT (pb); + perme = singleCheck ? permb : cmse_TT (pe); + break; + case CMSE_MPU_UNPRIV: + permb = cmse_TTT (pb); + perme = singleCheck ? permb : cmse_TTT (pe); + break; +#if __ARM_FEATURE_CMSE & 2 + case CMSE_MPU_NONSECURE: + permb = cmse_TTA (pb); + perme = singleCheck ? permb : cmse_TTA (pe); + break; + case CMSE_MPU_UNPRIV | CMSE_MPU_NONSECURE: + permb = cmse_TTAT (pb); + perme = singleCheck ? permb : cmse_TTAT (pe); + break; +#endif + default: + /* Invalid flag, eg. CMSE_MPU_NONSECURE specified but + __ARM_FEATURE_CMSE & 2 == 0. */ + return NULL; + } + + /* Check that the range does not cross MPU, SAU, or IDAU boundaries. */ + if (permb.value != perme.value) + return NULL; + + /* Check the permissions on the range. */ + switch (flags & (~known_secure_level)) + { +#if __ARM_FEATURE_CMSE & 2 + case CMSE_MPU_READ | CMSE_MPU_READWRITE | CMSE_AU_NONSECURE: + case CMSE_MPU_READWRITE | CMSE_AU_NONSECURE: + return permb.flags.nonsecure_readwrite_ok ? p : NULL; + case CMSE_MPU_READ | CMSE_AU_NONSECURE: + return permb.flags.nonsecure_read_ok ? p : NULL; + case CMSE_AU_NONSECURE: + return permb.flags.secure ? NULL : p; +#endif + case CMSE_MPU_READ | CMSE_MPU_READWRITE: + case CMSE_MPU_READWRITE: + return permb.flags.readwrite_ok ? p : NULL; + case CMSE_MPU_READ: + return permb.flags.read_ok ? p : NULL; + default: + return NULL; + } +} + + +#endif /* __ARM_FEATURE_CMSE & 1. */ diff --git a/libgcc/config/arm/t-arm b/libgcc/config/arm/t-arm index 4e17e99b4a5..5618143bfd0 100644 --- a/libgcc/config/arm/t-arm +++ b/libgcc/config/arm/t-arm @@ -1,3 +1,15 @@ LIB1ASMSRC = arm/lib1funcs.S LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \ _thumb1_case_uhi _thumb1_case_si + +HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - </dev/null)) +ifneq ($(shell $(gcc_compile_bare) -E -mcmse - </dev/null 2>/dev/null),) +CMSE_OPTS:=-mcmse +endif + +ifdef HAVE_CMSE +libgcc-objects += cmse.o cmse_nonsecure_call.o + +cmse.o: $(srcdir)/config/arm/cmse.c + $(gcc_compile) -c $(CMSE_OPTS) $< +endif |