1 /* ARMv8-M Secure Extensions intrinsics include file. 2 3 Copyright (C) 2015-2019 Free Software Foundation, Inc. 4 Contributed by ARM Ltd. 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it 9 under the terms of the GNU General Public License as published 10 by the Free Software Foundation; either version 3, or (at your 11 option) any later version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16 License for more details. 17 18 Under Section 7 of GPL version 3, you are granted additional 19 permissions described in the GCC Runtime Library Exception, version 20 3.1, as published by the Free Software Foundation. 21 22 You should have received a copy of the GNU General Public License and 23 a copy of the GCC Runtime Library Exception along with this program; 24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25 <http://www.gnu.org/licenses/>. */ 26 27 28 #ifndef _GCC_ARM_CMSE_H 29 #define _GCC_ARM_CMSE_H 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #if __ARM_FEATURE_CMSE & 1 36 37 #include <stddef.h> 38 39 #ifdef __ARM_BIG_ENDIAN 40 41 typedef union { 42 struct cmse_address_info { 43 #if __ARM_FEATURE_CMSE & 2 44 unsigned idau_region:8; 45 unsigned idau_region_valid:1; 46 unsigned secure:1; 47 unsigned nonsecure_readwrite_ok:1; 48 unsigned nonsecure_read_ok:1; 49 #else 50 unsigned :12; 51 #endif 52 unsigned readwrite_ok:1; 53 unsigned read_ok:1; 54 #if __ARM_FEATURE_CMSE & 2 55 unsigned sau_region_valid:1; 56 #else 57 unsigned :1; 58 #endif 59 unsigned mpu_region_valid:1; 60 #if __ARM_FEATURE_CMSE & 2 61 unsigned sau_region:8; 62 #else 63 unsigned :8; 64 #endif 65 unsigned mpu_region:8; 66 } flags; 67 unsigned value; 68 } cmse_address_info_t; 69 70 #else 71 72 typedef union { 73 struct cmse_address_info { 74 unsigned mpu_region:8; 75 #if __ARM_FEATURE_CMSE & 2 76 unsigned sau_region:8; 77 #else 78 unsigned :8; 79 #endif 80 unsigned mpu_region_valid:1; 81 #if __ARM_FEATURE_CMSE & 2 82 unsigned sau_region_valid:1; 83 #else 84 unsigned :1; 85 #endif 86 unsigned read_ok:1; 87 unsigned readwrite_ok:1; 88 #if __ARM_FEATURE_CMSE & 2 89 unsigned nonsecure_read_ok:1; 90 unsigned nonsecure_readwrite_ok:1; 91 unsigned secure:1; 92 unsigned idau_region_valid:1; 93 unsigned idau_region:8; 94 #else 95 unsigned :12; 96 #endif 97 } flags; 98 unsigned value; 99 } cmse_address_info_t; 100 101 #endif /* __ARM_BIG_ENDIAN */ 102 103 #define cmse_TT_fptr(p) (__cmse_TT_fptr ((__cmse_fptr)(p))) 104 105 typedef void (*__cmse_fptr)(void); 106 107 #define __CMSE_TT_ASM(flags) \ 108 { \ 109 cmse_address_info_t __result; \ 110 __asm__ ("tt" # flags " %0,%1" \ 111 : "=r"(__result) \ 112 : "r"(__p) \ 113 : "memory"); \ 114 return __result; \ 115 } 116 117 __extension__ static __inline __attribute__ ((__always_inline__)) 118 cmse_address_info_t 119 __cmse_TT_fptr (__cmse_fptr __p) 120 __CMSE_TT_ASM () 121 122 __extension__ static __inline __attribute__ ((__always_inline__)) 123 cmse_address_info_t 124 cmse_TT (void *__p) 125 __CMSE_TT_ASM () 126 127 #define cmse_TTT_fptr(p) (__cmse_TTT_fptr ((__cmse_fptr)(p))) 128 129 __extension__ static __inline __attribute__ ((__always_inline__)) 130 cmse_address_info_t 131 __cmse_TTT_fptr (__cmse_fptr __p) 132 __CMSE_TT_ASM (t) 133 134 __extension__ static __inline __attribute__ ((__always_inline__)) 135 cmse_address_info_t 136 cmse_TTT (void *__p) 137 __CMSE_TT_ASM (t) 138 139 #if __ARM_FEATURE_CMSE & 2 140 141 #define cmse_TTA_fptr(p) (__cmse_TTA_fptr ((__cmse_fptr)(p))) 142 143 __extension__ static __inline __attribute__ ((__always_inline__)) 144 cmse_address_info_t 145 __cmse_TTA_fptr (__cmse_fptr __p) 146 __CMSE_TT_ASM (a) 147 148 __extension__ static __inline __attribute__ ((__always_inline__)) 149 cmse_address_info_t 150 cmse_TTA (void *__p) 151 __CMSE_TT_ASM (a) 152 153 #define cmse_TTAT_fptr(p) (__cmse_TTAT_fptr ((__cmse_fptr)(p))) 154 155 __extension__ static __inline cmse_address_info_t 156 __attribute__ ((__always_inline__)) 157 __cmse_TTAT_fptr (__cmse_fptr __p) 158 __CMSE_TT_ASM (at) 159 160 __extension__ static __inline cmse_address_info_t 161 __attribute__ ((__always_inline__)) 162 cmse_TTAT (void *__p) 163 __CMSE_TT_ASM (at) 164 165 /* FIXME: diagnose use outside cmse_nonsecure_entry functions. */ 166 __extension__ static __inline int __attribute__ ((__always_inline__)) 167 cmse_nonsecure_caller (void) 168 { 169 return __builtin_arm_cmse_nonsecure_caller (); 170 } 171 172 #define CMSE_AU_NONSECURE 2 173 #define CMSE_MPU_NONSECURE 16 174 #define CMSE_NONSECURE 18 175 176 #define cmse_nsfptr_create(p) ((__typeof__ ((p))) ((__INTPTR_TYPE__) (p) & ~1)) 177 178 #define cmse_is_nsfptr(p) (!((__INTPTR_TYPE__) (p) & 1)) 179 180 #endif /* __ARM_FEATURE_CMSE & 2 */ 181 182 #define CMSE_MPU_UNPRIV 4 183 #define CMSE_MPU_READWRITE 1 184 #define CMSE_MPU_READ 8 185 186 __extension__ void * 187 cmse_check_address_range (void *, size_t, int); 188 189 #define cmse_check_pointed_object(p, f) \ 190 ((__typeof__ ((p))) cmse_check_address_range ((p), sizeof (*(p)), (f))) 191 192 #endif /* __ARM_FEATURE_CMSE & 1 */ 193 194 #ifdef __cplusplus 195 } 196 #endif 197 198 #endif /* _GCC_ARM_CMSE_H */ 199