Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ipc_exports.h Source File

ipc_exports.h

00001 /*
00002  * Copyright (c) 2017, 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_IPC_EXPORTS_H__
00018 #define __UVISOR_API_IPC_EXPORTS_H__
00019 
00020 #include "api/inc/pool_queue_exports.h"
00021 #include "api/inc/uvisor_spinlock_exports.h"
00022 #include "api/inc/vmpu_exports.h"
00023 #include <stddef.h>
00024 
00025 /* Use the invalid box ID to mean "receive from any" box. */
00026 #define UVISOR_BOX_ID_ANY UVISOR_BOX_ID_INVALID
00027 
00028 #define UVISOR_IPC_SEND_SLOTS 16
00029 #define UVISOR_IPC_RECV_SLOTS 16
00030 
00031 /* The value UVISOR_IPC_INVALID_TOKEN is defined to should be useful as a null
00032  * token, and preferably not having any other legitimate use. Due to the
00033  * internal bitfield representation of tokens, it makes a lot of sense to use 0
00034  * as the null token. ipc_allocate_token() returns 0 if no tokens are
00035  * available. Freeing 0 bits means nothing ('&= ~0' is a no-op). No other value
00036  * makes as much sense to use as 0. If tokens become represented internally as
00037  * something other than a bitfield, it would make sense to reconsider the value
00038  * used here. */
00039 #define UVISOR_IPC_INVALID_TOKEN 0
00040 
00041 typedef enum uvisor_ipc_io_state {
00042     UVISOR_IPC_IO_STATE_INVALID,
00043     UVISOR_IPC_IO_STATE_IDLE,
00044     UVISOR_IPC_IO_STATE_READY_TO_SEND, /* Enqueued and waiting for delivery */
00045     UVISOR_IPC_IO_STATE_READY_TO_RECV, /* Enqueued and waiting for delivery */
00046     UVISOR_IPC_IO_STATE_VALID, /* uVisor has copied the message */
00047 } uvisor_ipc_io_state_t;
00048 
00049 /* IPC Descriptor Structure
00050  * When sending:
00051  * @param[in]  box_id  the ID of the destination box
00052  * @param[in]  port    the port to send the message to
00053  * @param[in]  len     the length of the message
00054  * @param[out] token   a token that can be used to wait at a later time for
00055  *                     the send to complete
00056  *
00057  * When receiving before a message has been received:
00058  * @param[in]   box_id  an ID of a box that is allowed to send to this box, or
00059  *                      UVISOR_BOX_ID_ANY to allow messages from any box
00060  * @param[in]   port    the port to listen for messages on
00061  * @param[in]   len     the maximum length of message to receive
00062  * @param[out]  token   a token that can be used to wait at a later time for
00063  *                      the recv to complete
00064  *
00065  * When receiving after a message has been received:
00066  * @param[out]  box_id  the box ID of the sender
00067  * @param[out]  port    the port the message arrived on
00068  * @param[out]  len     the length of the message
00069  * @param[out]  token   not modified
00070  */
00071 typedef struct uvisor_ipc_desc {
00072     int box_id;
00073     size_t port;
00074     size_t len;
00075     uint32_t token;
00076 } uvisor_ipc_desc_t;
00077 
00078 /* IPC IO Request Structure */
00079 typedef struct uvisor_ipc_io {
00080     uvisor_ipc_desc_t * desc;
00081     void * msg;
00082     uvisor_ipc_io_state_t state;
00083 } uvisor_ipc_io_t;
00084 
00085 #define UVISOR_IPC_SEND_TYPE(slots) \
00086     struct { \
00087         uvisor_pool_queue_t queue; \
00088         uvisor_pool_t pool; \
00089         uvisor_pool_queue_entry_t entries[slots]; \
00090         uvisor_ipc_io_t io[slots]; \
00091     }
00092 
00093 #define UVISOR_IPC_RECV_TYPE(slots) \
00094     struct { \
00095         uvisor_pool_queue_t queue; \
00096         uvisor_pool_t pool; \
00097         uvisor_pool_queue_entry_t entries[slots]; \
00098         uvisor_ipc_io_t io[slots]; \
00099     }
00100 
00101 typedef UVISOR_IPC_SEND_TYPE(UVISOR_IPC_SEND_SLOTS) uvisor_ipc_send_queue_t;
00102 typedef UVISOR_IPC_RECV_TYPE(UVISOR_IPC_RECV_SLOTS) uvisor_ipc_recv_queue_t;
00103 
00104 typedef struct uvisor_ipc {
00105     uvisor_ipc_send_queue_t send_queue;
00106     uvisor_ipc_recv_queue_t recv_queue;
00107     UvisorSpinlock tokens_lock; /* Protect access to tokens. */
00108     uint32_t allocated_tokens; /* Endpoints read and write. */
00109     uint32_t completed_tokens; /* uVisor and endpoints read and write. */
00110 } uvisor_ipc_t;
00111 
00112 static inline uvisor_ipc_t * uvisor_ipc(UvisorBoxIndex * const index)
00113 {
00114     return (uvisor_ipc_t *) index->bss.address_of.ipc;
00115 }
00116 
00117 #endif