joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

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