Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
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 Fri Jul 22 2022 04:53:59 by
1.7.2
