Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 #include <stddef.h> 00022 00023 /* maximum number of boxes allowed: 1 is the minimum (unprivileged box) */ 00024 #define UVISOR_MAX_BOXES 5U 00025 00026 #define UVISOR_WAIT_FOREVER (0xFFFFFFFFUL) 00027 00028 /* extern keyword */ 00029 #ifdef __cplusplus 00030 #define UVISOR_EXTERN extern "C" 00031 #else 00032 #define UVISOR_EXTERN extern 00033 #endif/*__CPP__*/ 00034 00035 /** Extern C block macros 00036 * 00037 * Use these macros to disable name mangling in C++. Use these macros instead 00038 * of UVISOR_EXTERN when you also need to initialize the object. C++ compilers 00039 * warn when initializing an object declared as `extern`. Use of these macros 00040 * enables the defining of global non-name-mangled symbols in C++ without 00041 * affecting C code (which doesn't ever name mangle). */ 00042 #ifdef __cplusplus 00043 #define UVISOR_EXTERN_C_BEGIN extern "C" { 00044 #define UVISOR_EXTERN_C_END } 00045 #else 00046 #define UVISOR_EXTERN_C_BEGIN 00047 #define UVISOR_EXTERN_C_END 00048 #endif 00049 00050 /* asm keyword */ 00051 #ifndef asm 00052 #define asm __asm__ 00053 #endif 00054 00055 /* Shared compiler attributes */ 00056 #if defined(__ICCARM__) 00057 #define UVISOR_ALIGN(x) __align(x) 00058 #define UVISOR_FORCEINLINE inline 00059 #define UVISOR_PACKED __packed 00060 #define UVISOR_WEAK __weak 00061 #define UVISOR_NORETURN __noreturn 00062 #define UVISOR_RAMFUNC __ramfunc 00063 #define UVISOR_DEPRECATED 00064 #else 00065 #define UVISOR_ALIGN(x) __attribute__((aligned(x))) 00066 #define UVISOR_FORCEINLINE inline __attribute__((always_inline)) 00067 #define UVISOR_PACKED __attribute__((packed)) 00068 #define UVISOR_WEAK __attribute__((weak)) 00069 #define UVISOR_NORETURN __attribute__((noreturn)) 00070 #define UVISOR_RAMFUNC __attribute__ ((section (".ramfunc"), noinline)) 00071 #define UVISOR_DEPRECATED __attribute__((deprecated)) 00072 #endif 00073 00074 /* array count macro */ 00075 #define UVISOR_ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0])) 00076 00077 /** Static Assertion Macro 00078 * 00079 * This macro works from both inside and outside function scope. 00080 * The implementations differ due to compilation differences, C++ static_assert 00081 * is known from C++11 (__cplusplus > 199711L) while mbed-os compiles with c++98, 00082 * and C _Static_assert is known from GCC version 4.6.0. */ 00083 #define GCC_VERSION (__GNUC__ * 10000 \ 00084 + __GNUC_MINOR__ * 100 \ 00085 + __GNUC_PATCHLEVEL__) 00086 #if (__cplusplus > 199711L) 00087 #define UVISOR_STATIC_ASSERT(cond, msg) static_assert(cond, #msg) 00088 #elif (!__cplusplus && GCC_VERSION > 40600) 00089 #define UVISOR_STATIC_ASSERT(cond, msg) _Static_assert(cond, #msg) 00090 #else 00091 #define UVISOR_STATIC_ASSERT(cond, msg) typedef char STATIC_ASSERT_##msg[(cond)?1:-1] 00092 #endif 00093 00094 /* convert macro argument to string */ 00095 /* note: this needs one level of indirection, accomplished with the helper macro 00096 * __UVISOR_TO_STRING */ 00097 #define __UVISOR_TO_STRING(x) #x 00098 #define UVISOR_TO_STRING(x) __UVISOR_TO_STRING(x) 00099 00100 /* select an overloaded macro, so that 0 to 4 arguments can be used */ 00101 #define __UVISOR_MACRO_SELECT(_0, _1, _2, _3, _4, NAME, ...) NAME 00102 00103 /* count macro arguments */ 00104 #define UVISOR_MACRO_NARGS(...) \ 00105 __UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, 4, 3, 2, 1, 0) 00106 00107 /* declare explicit callee-saved registers to hold input arguments (0 to 4) */ 00108 /* note: sizeof(type) must be less than or equal to 4 */ 00109 #define UVISOR_MACRO_REGS_ARGS(type, ...) \ 00110 __UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, __UVISOR_MACRO_REGS_ARGS4, \ 00111 __UVISOR_MACRO_REGS_ARGS3, \ 00112 __UVISOR_MACRO_REGS_ARGS2, \ 00113 __UVISOR_MACRO_REGS_ARGS1, \ 00114 __UVISOR_MACRO_REGS_ARGS0)(type, ##__VA_ARGS__) 00115 #define __UVISOR_MACRO_REGS_ARGS0(type) 00116 #define __UVISOR_MACRO_REGS_ARGS1(type, a0) \ 00117 register type r0 asm("r0") = (type) a0; 00118 #define __UVISOR_MACRO_REGS_ARGS2(type, a0, a1) \ 00119 register type r0 asm("r0") = (type) a0; \ 00120 register type r1 asm("r1") = (type) a1; 00121 #define __UVISOR_MACRO_REGS_ARGS3(type, a0, a1, a2) \ 00122 register type r0 asm("r0") = (type) a0; \ 00123 register type r1 asm("r1") = (type) a1; \ 00124 register type r2 asm("r2") = (type) a2; 00125 #define __UVISOR_MACRO_REGS_ARGS4(type, a0, a1, a2, a3) \ 00126 register type r0 asm("r0") = (type) a0; \ 00127 register type r1 asm("r1") = (type) a1; \ 00128 register type r2 asm("r2") = (type) a2; \ 00129 register type r3 asm("r3") = (type) a3; 00130 00131 /* declare explicit callee-saved registers to hold output values */ 00132 /* note: currently only one output value is allowed, up to 32bits */ 00133 #define UVISOR_MACRO_REGS_RETVAL(type, name) \ 00134 register type name asm("r0"); 00135 00136 UVISOR_FORCEINLINE void uvisor_noreturn(void) 00137 { 00138 volatile int var = 1; 00139 while(var); 00140 } 00141 00142 /* declare callee-saved input/output operands for gcc-style inline asm */ 00143 /* note: this macro requires that a C variable having the same name of the 00144 * corresponding callee-saved register is declared; these operands follow 00145 * the official ABI for ARMv7M (e.g. 2 input arguments of 32bits each max, 00146 * imply that registers r0 and r1 are used) */ 00147 /* note: gcc only */ 00148 /* note: for 0 inputs a dummy immediate is passed to avoid errors on a misplaced 00149 * comma in the inline assembly */ 00150 #ifdef __GNUC__ 00151 00152 #define UVISOR_MACRO_GCC_ASM_INPUT(...) \ 00153 __UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, __UVISOR_MACRO_GCC_ASM_INPUT4, \ 00154 __UVISOR_MACRO_GCC_ASM_INPUT3, \ 00155 __UVISOR_MACRO_GCC_ASM_INPUT2, \ 00156 __UVISOR_MACRO_GCC_ASM_INPUT1, \ 00157 __UVISOR_MACRO_GCC_ASM_INPUT0)(__VA_ARGS__) 00158 #define __UVISOR_MACRO_GCC_ASM_INPUT0() [__dummy] "I" (0) 00159 #define __UVISOR_MACRO_GCC_ASM_INPUT1(a0) [r0] "r" (r0) 00160 #define __UVISOR_MACRO_GCC_ASM_INPUT2(a0, a1) [r0] "r" (r0), [r1] "r" (r1) 00161 #define __UVISOR_MACRO_GCC_ASM_INPUT3(a0, a1, a2) [r0] "r" (r0), [r1] "r" (r1), [r2] "r" (r2) 00162 #define __UVISOR_MACRO_GCC_ASM_INPUT4(a0, a1, a2, a3) [r0] "r" (r0), [r1] "r" (r1), [r2] "r" (r2), [r3] "r" (r3) 00163 00164 #define UVISOR_MACRO_GCC_ASM_OUTPUT(name) [res] "=r" (name) 00165 00166 #endif /* __GNUC__ */ 00167 00168 /* this macro multiplexes read/write opcodes depending on the number of 00169 * arguments */ 00170 #define UVISOR_ASM_MEMORY_ACCESS(opcode, type, ...) \ 00171 __UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, /* no macro for 4 args */ , \ 00172 /* no macro for 3 args */ , \ 00173 __UVISOR_ASM_MEMORY_ACCESS_W, \ 00174 __UVISOR_ASM_MEMORY_ACCESS_R, \ 00175 /* no macro for 0 args */ )(opcode, type, ##__VA_ARGS__) 00176 /* the macros that actually generate the assembly code for the memory access are 00177 * toolchain-specific */ 00178 #if defined(__CC_ARM) 00179 00180 /* TODO/FIXME */ 00181 00182 #elif defined(__GNUC__) 00183 00184 #define __UVISOR_ASM_MEMORY_ACCESS_R(opcode, type, ...) \ 00185 ({ \ 00186 UVISOR_MACRO_REGS_ARGS(uint32_t, ##__VA_ARGS__); \ 00187 UVISOR_MACRO_REGS_RETVAL(type, res); \ 00188 asm volatile( \ 00189 UVISOR_TO_STRING(opcode)" %[res], [%[r0]]\n" \ 00190 UVISOR_NOP_GROUP \ 00191 : UVISOR_MACRO_GCC_ASM_OUTPUT(res) \ 00192 : UVISOR_MACRO_GCC_ASM_INPUT(__VA_ARGS__) \ 00193 ); \ 00194 res; \ 00195 }) 00196 00197 #define __UVISOR_ASM_MEMORY_ACCESS_W(opcode, type, ...) \ 00198 UVISOR_MACRO_REGS_ARGS(uint32_t, ##__VA_ARGS__); \ 00199 asm volatile( \ 00200 UVISOR_TO_STRING(opcode)" %[r1], [%[r0]]\n" \ 00201 UVISOR_NOP_GROUP \ 00202 : \ 00203 : UVISOR_MACRO_GCC_ASM_INPUT(__VA_ARGS__) \ 00204 ); 00205 00206 #endif /* defined(__CC_ARM) || defined(__GNUC__) */ 00207 00208 typedef struct { 00209 void (*function)(const void *); 00210 size_t priority; 00211 size_t stack_size; 00212 } uvisor_box_main_t; 00213 00214 #endif /* __UVISOR_API_UVISOR_EXPORTS_H__ */
Generated on Sun Jul 17 2022 08:25:33 by 1.7.2