Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
rpc_gateway.h
00001 /* 00002 * Copyright (c) 2016, 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_RPC_GATEWAY_H__ 00018 #define __UVISOR_API_RPC_GATEWAY_H__ 00019 00020 #include "api/inc/rpc_gateway_exports.h" 00021 #include "api/inc/rpc.h" 00022 #include "api/inc/uvisor_exports.h" 00023 #include <stdint.h> 00024 00025 /** Synchronous RPC Gateway 00026 * 00027 * This macro declares a new function pointer (with no name mangling) named 00028 * `gw_name` to perform a remote procedure call (RPC) to the target function 00029 * given by `fn_name`. RPCs are assembled into a read-only flash structure that 00030 * is read and validated by uVisor before performing the operation. 00031 * 00032 * Create function with following signature: 00033 * UVISOR_EXTERN fn_ret gw_name(uint32_t a, uint32_t b); 00034 * 00035 * @param box_name[in] The name of the source box as declared in 00036 * `UVISOR_BOX_CONFIG` 00037 * @param gw_name[in] The new, callable function pointer for initiating an RPC from the caller's box 00038 * @param fn_name[in] The function that will run in the callee's box as an RPC target 00039 * @param fn_ret[in] The return type of the function being designated as an 00040 * RPC target 00041 * @param __VA_ARGS__ The type of each parameter passed to the target 00042 * function. There can be up to 4 parameters in a target 00043 * function. Each parameter must be no more than uint32_t 00044 * in size. If the RPC target function accepts no 00045 * arguments, pass `void` here. 00046 */ 00047 #define UVISOR_BOX_RPC_GATEWAY_SYNC(box_name, gw_name, fn_name, fn_ret, ...) \ 00048 UVISOR_STATIC_ASSERT(sizeof(fn_ret) <= sizeof(uint32_t), gw_name ## _return_type_too_big); \ 00049 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK(gw_name, __VA_ARGS__) \ 00050 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_DECL(fn_name, gw_name ## _rpc_gateway, __VA_ARGS__) \ 00051 /* Instanstiate the gateway. This gets resolved at link-time. */ \ 00052 UVISOR_EXTERN TRPCGateway const gw_name ## _rpc_gateway = { \ 00053 .ldr_pc = LDR_PC_PC_IMM_OPCODE(__UVISOR_OFFSETOF(TRPCGateway, ldr_pc), \ 00054 __UVISOR_OFFSETOF(TRPCGateway, caller)), \ 00055 .magic = UVISOR_RPC_GATEWAY_MAGIC_SYNC, \ 00056 .box_ptr = (uint32_t) &box_name ## _cfg_ptr, \ 00057 .target = (uint32_t) fn_name, \ 00058 .caller = (uint32_t) _sgw_sync_ ## fn_name, \ 00059 }; \ 00060 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER(fn_name, gw_name ## _rpc_gateway, __VA_ARGS__) \ 00061 \ 00062 /* Pointer to the gateway we just created. The pointer is located in a 00063 * discoverable linker section. */ \ 00064 __attribute__((section(".keep.uvisor.rpc_gateway_ptr"))) \ 00065 uint32_t const gw_name ## _rpc_gateway_ptr = (uint32_t) &gw_name ## _rpc_gateway; \ 00066 \ 00067 /* Declare the actual gateway. */ \ 00068 UVISOR_EXTERN_C_BEGIN \ 00069 fn_ret (*gw_name)(__VA_ARGS__) __attribute__((section(".rodata"))) = (fn_ret (*)(__VA_ARGS__)) ((uint32_t) &gw_name ## _rpc_gateway + 1); \ 00070 UVISOR_EXTERN_C_END 00071 00072 /** Asynchronous RPC Gateway 00073 * 00074 * This macro declares a new function pointer (with no name mangling) named 00075 * `gw_name` to perform a remote procedure call (RPC) to the target function 00076 * given by `fn_name`. RPCs are assembled into a read-only flash structure that 00077 * is read and validated by uVisor before performing the operation. 00078 * 00079 * Create function with following signature: 00080 * UVISOR_EXTERN uvisor_rpc_result_t gw_name(uint32_t a, uint32_t b); 00081 * 00082 * @param box_name[in] The name of the source box as declared in 00083 * `UVISOR_BOX_CONFIG` 00084 * @param gw_name[in] The new, callable function pointer for initiating an RPC from the caller's box 00085 * @param fn_name[in] The function that will run in the callee's box as an RPC target 00086 * @param fn_ret[in] The return type of the function being designated as an 00087 * RPC target 00088 * @param __VA_ARGS__ The type of each parameter passed to the target 00089 * function. There can be up to 4 parameters in a target 00090 * function. Each parameter must be no more than uint32_t 00091 * in size. If the RPC target function accepts no 00092 * arguments, pass `void` here. 00093 */ 00094 #define UVISOR_BOX_RPC_GATEWAY_ASYNC(box_name, gw_name, fn_name, fn_ret, ...) \ 00095 UVISOR_STATIC_ASSERT(sizeof(fn_ret) <= sizeof(uint32_t), gw_name ## _return_type_too_big); \ 00096 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK(gw_name, __VA_ARGS__) \ 00097 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_DECL(fn_name, gw_name ## _rpc_gateway, __VA_ARGS__) \ 00098 /* Instanstiate the gateway. This gets resolved at link-time. */ \ 00099 UVISOR_EXTERN TRPCGateway const gw_name ## _rpc_gateway = { \ 00100 .ldr_pc = LDR_PC_PC_IMM_OPCODE(__UVISOR_OFFSETOF(TRPCGateway, ldr_pc), \ 00101 __UVISOR_OFFSETOF(TRPCGateway, caller)), \ 00102 .magic = UVISOR_RPC_GATEWAY_MAGIC_ASYNC, \ 00103 .box_ptr = (uint32_t) &box_name ## _cfg_ptr, \ 00104 .target = (uint32_t) fn_name, \ 00105 .caller = (uint32_t) _sgw_async_ ## fn_name, \ 00106 }; \ 00107 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER(fn_name, gw_name ## _rpc_gateway, __VA_ARGS__) \ 00108 \ 00109 /* Pointer to the gateway we just created. The pointer is located in a 00110 * discoverable linker section. */ \ 00111 __attribute__((section(".keep.uvisor.rpc_gateway_ptr"))) \ 00112 uint32_t const gw_name ## _rpc_gateway_ptr = (uint32_t) &gw_name ## _rpc_gateway; \ 00113 \ 00114 /* Declare the actual gateway. */ \ 00115 UVISOR_EXTERN_C_BEGIN \ 00116 uvisor_rpc_result_t (*gw_name)(__VA_ARGS__) __attribute__((section(".rodata"))) = (uvisor_rpc_result_t (*)(__VA_ARGS__)) ((uint32_t) &gw_name ## _rpc_gateway + 1); \ 00117 UVISOR_EXTERN_C_END 00118 00119 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK(gw_name, ...) \ 00120 __UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_4, \ 00121 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_3, \ 00122 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_2, \ 00123 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_1, \ 00124 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_0)(gw_name, __VA_ARGS__) 00125 00126 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_0(gw_name) 00127 00128 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_1(gw_name, p0_type) \ 00129 UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); 00130 00131 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_2(gw_name, p0_type, p1_type) \ 00132 UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); \ 00133 UVISOR_STATIC_ASSERT(sizeof(p1_type) <= sizeof(uint32_t), gw_name ## _param_1_too_big); 00134 00135 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_3(gw_name, p0_type, p1_type, p2_type) \ 00136 UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); \ 00137 UVISOR_STATIC_ASSERT(sizeof(p1_type) <= sizeof(uint32_t), gw_name ## _param_1_too_big); \ 00138 UVISOR_STATIC_ASSERT(sizeof(p2_type) <= sizeof(uint32_t), gw_name ## _param_2_too_big); 00139 00140 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_4(gw_name, p0_type, p1_type, p2_type, p3_type) \ 00141 UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); \ 00142 UVISOR_STATIC_ASSERT(sizeof(p1_type) <= sizeof(uint32_t), gw_name ## _param_1_too_big); \ 00143 UVISOR_STATIC_ASSERT(sizeof(p2_type) <= sizeof(uint32_t), gw_name ## _param_2_too_big); \ 00144 UVISOR_STATIC_ASSERT(sizeof(p3_type) <= sizeof(uint32_t), gw_name ## _param_3_too_big); 00145 00146 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_DECL(fn_name, gateway, ...) \ 00147 __UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4_DECL, \ 00148 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3_DECL, \ 00149 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2_DECL, \ 00150 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1_DECL, \ 00151 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0_DECL)(fn_name, gateway, __VA_ARGS__) 00152 00153 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER(fn_name, gateway, ...) \ 00154 __UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4, \ 00155 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3, \ 00156 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2, \ 00157 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1, \ 00158 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0)(fn_name, gateway, __VA_ARGS__) 00159 00160 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0_DECL(fn_name, gateway, ...) \ 00161 static uint32_t _sgw_sync_ ## fn_name(void); 00162 00163 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0(fn_name, gateway, ...) \ 00164 static uint32_t _sgw_sync_ ## fn_name(void) \ 00165 { \ 00166 return rpc_fncall_sync(0, 0, 0, 0, &gateway); \ 00167 } 00168 00169 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1_DECL(fn_name, gateway, ...) \ 00170 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0); 00171 00172 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1(fn_name, gateway, ...) \ 00173 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0) \ 00174 { \ 00175 return rpc_fncall_sync(p0, 0, 0, 0, &gateway); \ 00176 } 00177 00178 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2_DECL(fn_name, gateway, ...) \ 00179 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1); 00180 00181 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2(fn_name, gateway, ...) \ 00182 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1) \ 00183 { \ 00184 return rpc_fncall_sync(p0, p1, 0, 0, &gateway); \ 00185 } 00186 00187 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3_DECL(fn_name, gateway, ...) \ 00188 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2); 00189 00190 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3(fn_name, gateway, ...) \ 00191 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2) \ 00192 { \ 00193 return rpc_fncall_sync(p0, p1, p2, 0, &gateway); \ 00194 } 00195 00196 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4_DECL(fn_name, gateway, ...) \ 00197 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3); 00198 00199 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4(fn_name, gateway, ...) \ 00200 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) \ 00201 { \ 00202 return rpc_fncall_sync(p0, p1, p2, p3, &gateway); \ 00203 } 00204 00205 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_DECL(fn_name, gateway, ...) \ 00206 __UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4_DECL, \ 00207 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3_DECL, \ 00208 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2_DECL, \ 00209 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1_DECL, \ 00210 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0_DECL)(fn_name, gateway, __VA_ARGS__) 00211 00212 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER(fn_name, gateway, ...) \ 00213 __UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4, \ 00214 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3, \ 00215 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2, \ 00216 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1, \ 00217 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0)(fn_name, gateway, __VA_ARGS__) 00218 00219 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0_DECL(fn_name, gateway, ...) \ 00220 static uvisor_rpc_result_t _sgw_async_ ## fn_name(void); 00221 00222 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0(fn_name, gateway, ...) \ 00223 static uvisor_rpc_result_t _sgw_async_ ## fn_name(void) \ 00224 { \ 00225 return rpc_fncall_async(0, 0, 0, 0, &gateway); \ 00226 } 00227 00228 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1_DECL(fn_name, gateway, ...) \ 00229 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0); 00230 00231 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1(fn_name, gateway, ...) \ 00232 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0) \ 00233 { \ 00234 return rpc_fncall_async(p0, 0, 0, 0, &gateway); \ 00235 } 00236 00237 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2_DECL(fn_name, gateway, ...) \ 00238 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1); 00239 00240 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2(fn_name, gateway, ...) \ 00241 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1) \ 00242 { \ 00243 return rpc_fncall_async(p0, p1, 0, 0, &gateway); \ 00244 } 00245 00246 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3_DECL(fn_name, gateway, ...) \ 00247 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2); 00248 00249 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3(fn_name, gateway, ...) \ 00250 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2) \ 00251 { \ 00252 return rpc_fncall_async(p0, p1, p2, 0, &gateway); \ 00253 } 00254 00255 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4_DECL(fn_name, gateway, ...) \ 00256 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3); 00257 00258 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4(fn_name, gateway, ...) \ 00259 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) \ 00260 { \ 00261 return rpc_fncall_async(p0, p1, p2, p3, &gateway); \ 00262 } 00263 00264 /* This function is private to uvisor-lib, but needs to be publicly visible for 00265 * the RPC gateway creation macros to work. */ 00266 UVISOR_EXTERN uint32_t rpc_fncall_sync(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, const TRPCGateway * gateway); 00267 00268 /* This function is private to uvisor-lib, but needs to be publicly visible for 00269 * the RPC gateway creation macros to work. */ 00270 UVISOR_EXTERN uvisor_rpc_result_t rpc_fncall_async(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, const TRPCGateway * gateway); 00271 00272 #endif /* __UVISOR_API_RPC_GATEWAY_H__ */
Generated on Sun Jul 17 2022 08:25:29 by 1.7.2