summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authoravieira <avieira@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-02 15:22:43 +0000
committeravieira <avieira@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-02 15:22:43 +0000
commit0120ae3031097eb092abd20bddac45f58762b1a9 (patch)
tree6811602f7f8aa090716356b734baf53b5076392b /libgcc
parentb99ff0e778469b11eaab6563f68478c4486903ad (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--libgcc/config/arm/cmse.c108
-rw-r--r--libgcc/config/arm/t-arm12
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