Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rpc_exports.h Source File

rpc_exports.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_EXPORTS_H__
00018 #define __UVISOR_API_RPC_EXPORTS_H__
00019 
00020 #include "api/inc/pool_queue_exports.h"
00021 #include "api/inc/uvisor_semaphore_exports.h"
00022 #include "api/inc/rpc_gateway_exports.h"
00023 #include "api/inc/vmpu_exports.h"
00024 
00025 typedef uint32_t (*TFN_Ptr)(uint32_t, uint32_t, uint32_t, uint32_t);
00026 
00027 #define UVISOR_RESULT_SLOT_BITS 10
00028 #define UVISOR_RESULT_SLOT_MASK ((1 << UVISOR_RESULT_SLOT_BITS) - 1)
00029 
00030 #define UVISOR_RESULT_COUNTER_MASK (0xFFFFFFFFUL << UVISOR_RESULT_SLOT_BITS)
00031 
00032 /* Increment by 2 because we never want to overflow into the invalid value. */
00033 #define UVISOR_RESULT_COUNTER_INCREMENT (2 << UVISOR_RESULT_SLOT_BITS)
00034 
00035 #define UVISOR_RESULT_INVALID_COUNTER (UVISOR_RESULT_COUNTER_MASK)
00036 
00037 /* This is the token to wait on for the result of an asynchronous RPC. */
00038 typedef uint32_t uvisor_rpc_result_t;
00039 
00040 static inline uvisor_pool_slot_t uvisor_result_slot(uvisor_rpc_result_t result)
00041 {
00042     return result & UVISOR_RESULT_SLOT_MASK;
00043 }
00044 
00045 static inline uint32_t uvisor_result_counter(uvisor_rpc_result_t result)
00046 {
00047     return result & UVISOR_RESULT_COUNTER_MASK;
00048 }
00049 
00050 static inline uvisor_rpc_result_t uvisor_result_build(uint32_t counter, uvisor_pool_slot_t slot)
00051 {
00052     return (counter & UVISOR_RESULT_COUNTER_MASK) | (slot & UVISOR_RESULT_SLOT_MASK);
00053 }
00054 
00055 typedef enum {
00056     /* Who sets this value for caller (outgoing queue), Who sets this value for (incoming queue) callee. */
00057     UVISOR_RPC_MESSAGE_STATE_INVALID, /* nobody, nobody */
00058     UVISOR_RPC_MESSAGE_STATE_IDLE, /* caller receive function before freeing, uvisor when delivers back */
00059     UVISOR_RPC_MESSAGE_STATE_READY_TO_SEND, /* send function, nobody */
00060     UVISOR_RPC_MESSAGE_STATE_SENT, /* uvisor, uvisor */
00061     UVISOR_RPC_MESSAGE_STATE_DONE, /* waitfor_fngroup function, uvisor when delivers back */
00062 } uvisor_rpc_message_state_t;
00063 
00064 typedef struct uvisor_rpc_message {
00065     /* NOTE: These are set by the caller, and read by the callee. */
00066     uint32_t p0;
00067     uint32_t p1;
00068     uint32_t p2;
00069     uint32_t p3;
00070 
00071     const TRPCGateway * gateway;
00072 
00073     /* The box ID of the other box. For callers, this is the destination box
00074      * ID. For callees, this is the source box ID. */
00075     int other_box_id;
00076 
00077     /* The semaphore to post to when a result is ready */
00078     UvisorSemaphore semaphore;
00079 
00080     /* This cookie keeps track of which result to wait for. It changes
00081      * atomically to an invalid cookie when being waited on, to prevent
00082      * multiple waits for the same result. */
00083     uvisor_rpc_result_t wait_cookie;
00084 
00085     /* This is an extra copy of the above cookie, used by uVisor to verify that
00086      * a certain result matches a certain caller. This identifies to uVisor
00087      * which RPC it should complete. uVisor must verify this information of
00088      * course, to see if this box is currently being called into and is allowed
00089      * to complete the RPC. */
00090     uvisor_rpc_result_t match_cookie;
00091 
00092     uvisor_rpc_message_state_t state;
00093 
00094     uint32_t result;
00095 } uvisor_rpc_message_t;
00096 
00097 typedef struct uvisor_rpc_fn_group {
00098     /* A pointer to the function group */
00099     TFN_Ptr const * fn_ptr_array;
00100     size_t fn_count;
00101 
00102     /* The semaphore to wait on for this function group */
00103     UvisorSemaphore semaphore;
00104 } uvisor_rpc_fn_group_t;
00105 
00106 #define UVISOR_RPC_OUTGOING_MESSAGE_SLOTS (8)
00107 
00108 #define UVISOR_RPC_INCOMING_MESSAGE_SLOTS (8)
00109 
00110 #define UVISOR_RPC_FN_GROUP_SLOTS (8)
00111 
00112 #define UVISOR_RPC_OUTGOING_MESSAGE_TYPE(slots) \
00113     struct { \
00114         uvisor_pool_queue_t queue; \
00115         uvisor_pool_t pool; \
00116         uvisor_pool_queue_entry_t entries[slots]; \
00117         uvisor_rpc_message_t messages[slots]; \
00118     }
00119 
00120 #define UVISOR_RPC_INCOMING_MESSAGE_TYPE(slots) \
00121     struct { \
00122         uvisor_pool_queue_t todo_queue; \
00123         uvisor_pool_queue_t done_queue; \
00124         uvisor_pool_t pool; \
00125         uvisor_pool_queue_entry_t entries[slots]; \
00126         uvisor_rpc_message_t messages[slots]; \
00127     }
00128 
00129 #define UVISOR_RPC_FN_GROUP_TYPE(slots) \
00130     struct { \
00131         uvisor_pool_queue_t queue; \
00132         uvisor_pool_t pool; \
00133         uvisor_pool_queue_entry_t entries[slots]; \
00134         uvisor_rpc_fn_group_t fn_groups[slots]; \
00135     }
00136 
00137 typedef UVISOR_RPC_OUTGOING_MESSAGE_TYPE(UVISOR_RPC_OUTGOING_MESSAGE_SLOTS) uvisor_rpc_outgoing_message_queue_t;
00138 typedef UVISOR_RPC_INCOMING_MESSAGE_TYPE(UVISOR_RPC_INCOMING_MESSAGE_SLOTS) uvisor_rpc_incoming_message_queue_t;
00139 typedef UVISOR_RPC_FN_GROUP_TYPE(UVISOR_RPC_FN_GROUP_SLOTS) uvisor_rpc_fn_group_queue_t;
00140 
00141 typedef struct uvisor_rpc_t {
00142     /* Outgoing message queue */
00143     uvisor_rpc_outgoing_message_queue_t outgoing_message_queue;
00144 
00145     /* Incoming message queue */
00146     uvisor_rpc_incoming_message_queue_t incoming_message_queue;
00147 
00148     /* Function group queue */
00149     uvisor_rpc_fn_group_queue_t fn_group_queue;
00150 
00151     /* Counter to avoid waiting on the same RPC result twice by accident. */
00152     uint32_t result_counter;
00153 } uvisor_rpc_t;
00154 
00155 static inline uvisor_rpc_t * uvisor_rpc(UvisorBoxIndex * const index)
00156 {
00157     return (uvisor_rpc_t *) index->bss.address_of.rpc;
00158 }
00159 
00160 #endif