ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uvisor_exports.h Source File

uvisor_exports.h

00001 /*
00002  * Copyright (c) 2013-2015, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 #ifndef __UVISOR_API_UVISOR_EXPORTS_H__
00018 #define __UVISOR_API_UVISOR_EXPORTS_H__
00019 
00020 #include <stdint.h>
00021 
00022 /* maximum number of boxes allowed: 1 is the minimum (unprivileged box) */
00023 #define UVISOR_MAX_BOXES 5U
00024 
00025 #define UVISOR_WAIT_FOREVER (0xFFFFFFFFUL)
00026 
00027 /* extern keyword */
00028 #ifdef  __cplusplus
00029 #define UVISOR_EXTERN extern "C"
00030 #else
00031 #define UVISOR_EXTERN extern
00032 #endif/*__CPP__*/
00033 
00034 /** Extern C block macros
00035  *
00036  * Use these macros to disable name mangling in C++. Use these macros instead
00037  * of UVISOR_EXTERN when you also need to initialize the object. C++ compilers
00038  * warn when initializing an object declared as `extern`. Use of these macros
00039  * enables the defining of global non-name-mangled symbols in C++ without
00040  * affecting C code (which doesn't ever name mangle).  */
00041 #ifdef  __cplusplus
00042 #define UVISOR_EXTERN_C_BEGIN extern "C" {
00043 #define UVISOR_EXTERN_C_END }
00044 #else
00045 #define UVISOR_EXTERN_C_BEGIN
00046 #define UVISOR_EXTERN_C_END
00047 #endif
00048 
00049 /* asm keyword */
00050 #ifndef asm
00051 #define asm __asm__
00052 #endif
00053 
00054 /* Shared compiler attributes */
00055 #if defined(__ICCARM__)
00056 #define UVISOR_ALIGN(x)    __align(x)
00057 #define UVISOR_FORCEINLINE inline
00058 #define UVISOR_PACKED      __packed
00059 #define UVISOR_WEAK        __weak
00060 #define UVISOR_NORETURN    __noreturn
00061 #define UVISOR_RAMFUNC     __ramfunc
00062 #define UVISOR_DEPRECATED
00063 #else
00064 #define UVISOR_ALIGN(x)    __attribute__((aligned(x)))
00065 #define UVISOR_FORCEINLINE inline __attribute__((always_inline))
00066 #define UVISOR_PACKED      __attribute__((packed))
00067 #define UVISOR_WEAK        __attribute__((weak))
00068 #define UVISOR_NORETURN    __attribute__((noreturn))
00069 #define UVISOR_RAMFUNC     __attribute__ ((section (".ramfunc"), noinline))
00070 #define UVISOR_DEPRECATED  __attribute__((deprecated))
00071 #endif
00072 
00073 /* array count macro */
00074 #define UVISOR_ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0]))
00075 
00076 /** Static Assertion Macro
00077  *
00078  * This macro works from both inside and outside function scope.
00079  *
00080  * FIXME This is currently not implemented. This issue is tracked at
00081  * https://github.com/ARMmbed/uvisor/issues/288
00082  */
00083 #define UVISOR_STATIC_ASSERT(cond, msg)
00084 
00085 /* convert macro argument to string */
00086 /* note: this needs one level of indirection, accomplished with the helper macro
00087  *       __UVISOR_TO_STRING */
00088 #define __UVISOR_TO_STRING(x) #x
00089 #define UVISOR_TO_STRING(x)   __UVISOR_TO_STRING(x)
00090 
00091 /* select an overloaded macro, so that 0 to 4 arguments can be used */
00092 #define __UVISOR_MACRO_SELECT(_0, _1, _2, _3, _4, NAME, ...) NAME
00093 
00094 /* count macro arguments */
00095 #define UVISOR_MACRO_NARGS(...) \
00096      __UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, 4, 3, 2, 1, 0)
00097 
00098 /* declare explicit callee-saved registers to hold input arguments (0 to 4) */
00099 /* note: sizeof(type) must be less than or equal to 4 */
00100 #define UVISOR_MACRO_REGS_ARGS(type, ...) \
00101      __UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, __UVISOR_MACRO_REGS_ARGS4, \
00102                                               __UVISOR_MACRO_REGS_ARGS3, \
00103                                               __UVISOR_MACRO_REGS_ARGS2, \
00104                                               __UVISOR_MACRO_REGS_ARGS1, \
00105                                               __UVISOR_MACRO_REGS_ARGS0)(type, ##__VA_ARGS__)
00106 #define __UVISOR_MACRO_REGS_ARGS0(type)
00107 #define __UVISOR_MACRO_REGS_ARGS1(type, a0) \
00108         register type r0 asm("r0") = (type) a0;
00109 #define __UVISOR_MACRO_REGS_ARGS2(type, a0, a1) \
00110         register type r0 asm("r0") = (type) a0; \
00111         register type r1 asm("r1") = (type) a1;
00112 #define __UVISOR_MACRO_REGS_ARGS3(type, a0, a1, a2) \
00113         register type r0 asm("r0") = (type) a0; \
00114         register type r1 asm("r1") = (type) a1; \
00115         register type r2 asm("r2") = (type) a2;
00116 #define __UVISOR_MACRO_REGS_ARGS4(type, a0, a1, a2, a3) \
00117         register type r0 asm("r0") = (type) a0; \
00118         register type r1 asm("r1") = (type) a1; \
00119         register type r2 asm("r2") = (type) a2; \
00120         register type r3 asm("r3") = (type) a3;
00121 
00122 /* declare explicit callee-saved registers to hold output values */
00123 /* note: currently only one output value is allowed, up to 32bits */
00124 #define UVISOR_MACRO_REGS_RETVAL(type, name) \
00125     register type name asm("r0");
00126 
00127 /* declare callee-saved input/output operands for gcc-style inline asm */
00128 /* note: this macro requires that a C variable having the same name of the
00129  *       corresponding callee-saved register is declared; these operands follow
00130  *       the official ABI for ARMv7M (e.g. 2 input arguments of 32bits each max,
00131  *       imply that registers r0 and r1 are used) */
00132 /* note: gcc only */
00133 /* note: for 0 inputs a dummy immediate is passed to avoid errors on a misplaced
00134  *       comma in the inline assembly */
00135 #ifdef __GNUC__
00136 
00137 #define UVISOR_MACRO_GCC_ASM_INPUT(...) \
00138      __UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, __UVISOR_MACRO_GCC_ASM_INPUT4, \
00139                                               __UVISOR_MACRO_GCC_ASM_INPUT3, \
00140                                               __UVISOR_MACRO_GCC_ASM_INPUT2, \
00141                                               __UVISOR_MACRO_GCC_ASM_INPUT1, \
00142                                               __UVISOR_MACRO_GCC_ASM_INPUT0)(__VA_ARGS__)
00143 #define __UVISOR_MACRO_GCC_ASM_INPUT0()               [__dummy] "I" (0)
00144 #define __UVISOR_MACRO_GCC_ASM_INPUT1(a0)             [r0] "r" (r0)
00145 #define __UVISOR_MACRO_GCC_ASM_INPUT2(a0, a1)         [r0] "r" (r0), [r1] "r" (r1)
00146 #define __UVISOR_MACRO_GCC_ASM_INPUT3(a0, a1, a2)     [r0] "r" (r0), [r1] "r" (r1), [r2] "r" (r2)
00147 #define __UVISOR_MACRO_GCC_ASM_INPUT4(a0, a1, a2, a3) [r0] "r" (r0), [r1] "r" (r1), [r2] "r" (r2), [r3] "r" (r3)
00148 
00149 #define UVISOR_MACRO_GCC_ASM_OUTPUT(name) [res] "=r" (name)
00150 
00151 #endif /* __GNUC__ */
00152 
00153 /* this macro multiplexes read/write opcodes depending on the number of
00154  * arguments */
00155 #define UVISOR_ASM_MEMORY_ACCESS(opcode, type, ...) \
00156     __UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, /* no macro for 4 args */   , \
00157                                              /* no macro for 3 args */   , \
00158                                              __UVISOR_ASM_MEMORY_ACCESS_W, \
00159                                              __UVISOR_ASM_MEMORY_ACCESS_R, \
00160                                              /* no macro for 0 args */   )(opcode, type, ##__VA_ARGS__)
00161 /* the macros that actually generate the assembly code for the memory access are
00162  * toolchain-specific */
00163 #if defined(__CC_ARM)
00164 
00165 /* TODO/FIXME */
00166 
00167 #elif defined(__GNUC__)
00168 
00169 #define __UVISOR_ASM_MEMORY_ACCESS_R(opcode, type, ...) \
00170     ({ \
00171         UVISOR_MACRO_REGS_ARGS(uint32_t, ##__VA_ARGS__); \
00172         UVISOR_MACRO_REGS_RETVAL(type, res); \
00173         asm volatile( \
00174             UVISOR_TO_STRING(opcode)" %[res], [%[r0]]\n" \
00175             UVISOR_NOP_GROUP \
00176             : UVISOR_MACRO_GCC_ASM_OUTPUT(res) \
00177             : UVISOR_MACRO_GCC_ASM_INPUT(__VA_ARGS__) \
00178         ); \
00179         res; \
00180     })
00181 
00182 #define __UVISOR_ASM_MEMORY_ACCESS_W(opcode, type, ...) \
00183     UVISOR_MACRO_REGS_ARGS(uint32_t, ##__VA_ARGS__); \
00184     asm volatile( \
00185         UVISOR_TO_STRING(opcode)" %[r1], [%[r0]]\n" \
00186         UVISOR_NOP_GROUP \
00187         : \
00188         : UVISOR_MACRO_GCC_ASM_INPUT(__VA_ARGS__) \
00189     );
00190 
00191 #endif /* defined(__CC_ARM) || defined(__GNUC__) */
00192 
00193 #endif /* __UVISOR_API_UVISOR_EXPORTS_H__ */