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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo 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 /* ldr pc, [pc, #<label - instr + 4>] 00026 * LDR (immediate) - ARMv7M ARM section A7.7.42 00027 * 1111;1 00 0; 0 10 1; <Rn - 1111>; <Rt - 1111>; <imm12> (Encoding T3) */ 00028 #define LDR_PC_PC_IMM_OPCODE(instr, label) \ 00029 ((uint32_t) (0xF000F8DFUL | ((((uint32_t) (label) - ((uint32_t) (instr) + 4)) & 0xFFFUL) << 16))) 00030 00031 /** Synchronous RPC Gateway 00032 * 00033 * This macro declares a new function pointer (with no name mangling) named 00034 * `gw_name` to perform a remote procedure call (RPC) to the target function 00035 * given by `fn_name`. RPCs are assembled into a read-only flash structure that 00036 * is read and validated by uVisor before performing the operation. 00037 * 00038 * Create function with following signature: 00039 * UVISOR_EXTERN fn_ret gw_name(uint32_t a, uint32_t b); 00040 * 00041 * @param box_name[in] The name of the source box as declared in 00042 * `UVISOR_BOX_CONFIG` 00043 * @param gw_name[in] The new, callable function pointer for performing RPC 00044 * @param fn_name[in] The function being designated as an RPC target 00045 * @param fn_ret[in] The return type of the function being designated as an 00046 * RPC target 00047 * @param __VA_ARGS__ The type of each parameter passed to the target 00048 * function. There can be up to 4 parameters in a target 00049 * function. Each parameter must be no more than uint32_t 00050 * in size. If the RPC target function accepts no 00051 * arguments, pass `void` here. 00052 */ 00053 #define UVISOR_BOX_RPC_GATEWAY_SYNC(box_name, gw_name, fn_name, fn_ret, ...) \ 00054 UVISOR_STATIC_ASSERT(sizeof(fn_ret) <= sizeof(uint32_t), gw_name ## _return_type_too_big); \ 00055 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK(gw_name, __VA_ARGS__) \ 00056 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER(fn_name, __VA_ARGS__) \ 00057 /* Instanstiate the gateway. This gets resolved at link-time. */ \ 00058 UVISOR_EXTERN TRPCGateway const gw_name ## _rpc_gateway = { \ 00059 .ldr_pc = LDR_PC_PC_IMM_OPCODE(__UVISOR_OFFSETOF(TRPCGateway, ldr_pc), \ 00060 __UVISOR_OFFSETOF(TRPCGateway, function)), \ 00061 .magic = UVISOR_RPC_GATEWAY_MAGIC_SYNC, \ 00062 .box_ptr = (uint32_t) &box_name ## _cfg_ptr, \ 00063 .function = (uint32_t) _sgw_sync_ ## fn_name, \ 00064 }; \ 00065 \ 00066 /* Pointer to the gateway we just created. The pointer is located in a 00067 * discoverable linker section. */ \ 00068 __attribute__((section(".keep.uvisor.rpc_gateway_ptr"))) \ 00069 uint32_t const gw_name ## _rpc_gateway_ptr = (uint32_t) &gw_name ## _rpc_gateway; \ 00070 \ 00071 /* Declare the actual gateway. */ \ 00072 UVISOR_EXTERN_C_BEGIN \ 00073 fn_ret (*gw_name)(__VA_ARGS__) __attribute__((section(".rodata"))) = (fn_ret (*)(__VA_ARGS__)) ((uint32_t) &gw_name ## _rpc_gateway + 1); \ 00074 UVISOR_EXTERN_C_END 00075 00076 /** Asynchronous RPC Gateway 00077 * 00078 * This macro declares a new function pointer (with no name mangling) named 00079 * `gw_name` to perform a remote procedure call (RPC) to the target function 00080 * given by `fn_name`. RPCs are assembled into a read-only flash structure that 00081 * is read and validated by uVisor before performing the operation. 00082 * 00083 * Create function with following signature: 00084 * UVISOR_EXTERN uvisor_rpc_result_t gw_name(uint32_t a, uint32_t b); 00085 * 00086 * @param box_name[in] The name of the source box as declared in 00087 * `UVISOR_BOX_CONFIG` 00088 * @param gw_name[in] The new, callable function pointer for performing RPC 00089 * @param fn_name[in] The function being designated as an RPC target 00090 * @param fn_ret[in] The return type of the function being designated as an 00091 * RPC target 00092 * @param __VA_ARGS__ The type of each parameter passed to the target 00093 * function. There can be up to 4 parameters in a target 00094 * function. Each parameter must be no more than uint32_t 00095 * in size. If the RPC target function accepts no 00096 * arguments, pass `void` here. 00097 */ 00098 #define UVISOR_BOX_RPC_GATEWAY_ASYNC(box_name, gw_name, fn_name, fn_ret, ...) \ 00099 UVISOR_STATIC_ASSERT(sizeof(fn_ret) <= sizeof(uint32_t), gw_name ## _return_type_too_big); \ 00100 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK(gw_name, __VA_ARGS__) \ 00101 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER(fn_name, __VA_ARGS__) \ 00102 /* Instanstiate the gateway. This gets resolved at link-time. */ \ 00103 UVISOR_EXTERN TRPCGateway const gw_name ## _rpc_gateway = { \ 00104 .ldr_pc = LDR_PC_PC_IMM_OPCODE(__UVISOR_OFFSETOF(TRPCGateway, ldr_pc), \ 00105 __UVISOR_OFFSETOF(TRPCGateway, function)), \ 00106 .magic = UVISOR_RPC_GATEWAY_MAGIC_ASYNC, \ 00107 .box_ptr = (uint32_t) &box_name ## _cfg_ptr, \ 00108 .function = (uint32_t) _sgw_async_ ## fn_name, \ 00109 }; \ 00110 \ 00111 /* Pointer to the gateway we just created. The pointer is located in a 00112 * discoverable linker section. */ \ 00113 __attribute__((section(".keep.uvisor.rpc_gateway_ptr"))) \ 00114 uint32_t const gw_name ## _rpc_gateway_ptr = (uint32_t) &gw_name ## _rpc_gateway; \ 00115 \ 00116 /* Declare the actual gateway. */ \ 00117 UVISOR_EXTERN_C_BEGIN \ 00118 uvisor_rpc_result_t (*gw_name)(__VA_ARGS__) __attribute__((section(".rodata"))) = (uvisor_rpc_result_t (*)(__VA_ARGS__)) ((uint32_t) &gw_name ## _rpc_gateway + 1); \ 00119 UVISOR_EXTERN_C_END 00120 00121 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK(gw_name, ...) \ 00122 __UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_4, \ 00123 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_3, \ 00124 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_2, \ 00125 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_1, \ 00126 _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_0)(gw_name, __VA_ARGS__) 00127 00128 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_0(gw_name) 00129 00130 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_1(gw_name, p0_type) \ 00131 UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); 00132 00133 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_2(gw_name, p0_type, p1_type) \ 00134 UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); \ 00135 UVISOR_STATIC_ASSERT(sizeof(p1_type) <= sizeof(uint32_t), gw_name ## _param_1_too_big); 00136 00137 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_3(gw_name, p0_type, p1_type, p2_type) \ 00138 UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); \ 00139 UVISOR_STATIC_ASSERT(sizeof(p1_type) <= sizeof(uint32_t), gw_name ## _param_1_too_big); \ 00140 UVISOR_STATIC_ASSERT(sizeof(p2_type) <= sizeof(uint32_t), gw_name ## _param_2_too_big); 00141 00142 #define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_4(gw_name, p0_type, p1_type, p2_type, p3_type) \ 00143 UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); \ 00144 UVISOR_STATIC_ASSERT(sizeof(p1_type) <= sizeof(uint32_t), gw_name ## _param_1_too_big); \ 00145 UVISOR_STATIC_ASSERT(sizeof(p2_type) <= sizeof(uint32_t), gw_name ## _param_2_too_big); \ 00146 UVISOR_STATIC_ASSERT(sizeof(p3_type) <= sizeof(uint32_t), gw_name ## _param_3_too_big); 00147 00148 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER(fn_name, ...) \ 00149 __UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4, \ 00150 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3, \ 00151 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2, \ 00152 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1, \ 00153 _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0)(fn_name, __VA_ARGS__) 00154 00155 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0(fn_name, ...) \ 00156 static uint32_t _sgw_sync_ ## fn_name(void) \ 00157 { \ 00158 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00159 return rpc_fncall_sync(0, 0, 0, 0, fp); \ 00160 } 00161 00162 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1(fn_name, ...) \ 00163 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0) \ 00164 { \ 00165 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00166 return rpc_fncall_sync(p0, 0, 0, 0, fp); \ 00167 } 00168 00169 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2(fn_name, ...) \ 00170 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1) \ 00171 { \ 00172 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00173 return rpc_fncall_sync(p0, p1, 0, 0, fp); \ 00174 } 00175 00176 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3(fn_name, ...) \ 00177 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2) \ 00178 { \ 00179 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00180 return rpc_fncall_sync(p0, p1, p2, 0, fp); \ 00181 } 00182 00183 #define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4(fn_name, ...) \ 00184 static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) \ 00185 { \ 00186 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00187 return rpc_fncall_sync(p0, p1, p2, p3, fp); \ 00188 } 00189 00190 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER(fn_name, ...) \ 00191 __UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4, \ 00192 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3, \ 00193 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2, \ 00194 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1, \ 00195 _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0)(fn_name, __VA_ARGS__) 00196 00197 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0(fn_name, ...) \ 00198 static uvisor_rpc_result_t _sgw_async_ ## fn_name(void) \ 00199 { \ 00200 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00201 return rpc_fncall_async(0, 0, 0, 0, fp); \ 00202 } 00203 00204 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1(fn_name, ...) \ 00205 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0) \ 00206 { \ 00207 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00208 return rpc_fncall_async(p0, 0, 0, 0, fp); \ 00209 } 00210 00211 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2(fn_name, ...) \ 00212 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1) \ 00213 { \ 00214 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00215 return rpc_fncall_async(p0, p1, 0, 0, fp); \ 00216 } 00217 00218 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3(fn_name, ...) \ 00219 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2) \ 00220 { \ 00221 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00222 return rpc_fncall_async(p0, p1, p2, 0, fp); \ 00223 } 00224 00225 #define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4(fn_name, ...) \ 00226 static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) \ 00227 { \ 00228 TFN_Ptr fp = (TFN_Ptr) fn_name; \ 00229 return rpc_fncall_async(p0, p1, p2, p3, fp); \ 00230 } 00231 00232 /* This function is private to uvisor-lib, but needs to be publicly visible for 00233 * the RPC gateway creation macros to work. */ 00234 UVISOR_EXTERN uint32_t rpc_fncall_sync(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, const TFN_Ptr fn); 00235 00236 /* This function is private to uvisor-lib, but needs to be publicly visible for 00237 * the RPC gateway creation macros to work. */ 00238 UVISOR_EXTERN uvisor_rpc_result_t rpc_fncall_async(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, const TFN_Ptr fn); 00239 00240 #endif /* __UVISOR_API_RPC_GATEWAY_H__ */
Generated on Tue Jul 12 2022 12:28:47 by
