1 /*******************************************************************************
2 * Copyright (C) 2018 Cadence Design Systems, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to use this Software with Cadence processor cores only and
7 * not with any other processors and platforms, subject to
8 * the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 ******************************************************************************/
22 
23 #ifndef __XF_H
24 #error "xf-ipc.h mustn't be included directly"
25 #endif
26 
27 /*******************************************************************************
28  * Types definitions
29  ******************************************************************************/
30 
31 /* ...proxy IPC data */
32 typedef struct xf_proxy_ipc_data
33 {
34     /* ...shared memory buffer pointer */
35     void                   *shmem;
36 
37     /* ...file descriptor */
38     int                     fd;
39 
40     /* ...pipe for asynchronous response delivery */
41     int                     pipe[2];
42 
43 }   xf_proxy_ipc_data_t;
44 
45 /*******************************************************************************
46  * Helpers for asynchronous response delivery
47  ******************************************************************************/
48 
49 #define xf_proxy_ipc_response_put(ipc, msg) \
50     (write((ipc)->pipe[1], (msg), sizeof(*(msg))) == sizeof(*(msg)) ? 0 : -errno)
51 
52 #define xf_proxy_ipc_response_get(ipc, msg) \
53     (read((ipc)->pipe[0], (msg), sizeof(*(msg))) == sizeof(*(msg)) ? 0 : -errno)
54 
55 /*******************************************************************************
56  * Shared memory translation
57  ******************************************************************************/
58 
59 /* ...translate proxy shared address into local virtual address */
xf_ipc_a2b(xf_proxy_ipc_data_t * ipc,u32 address)60 static inline void * xf_ipc_a2b(xf_proxy_ipc_data_t *ipc, u32 address)
61 {
62     if (address < XF_CFG_REMOTE_IPC_POOL_SIZE)
63         return (unsigned char *) ipc->shmem + address;
64     else if (address == XF_PROXY_NULL)
65         return NULL;
66     else
67         return (void *) -1;
68 }
69 
70 /* ...translate local virtual address into shared proxy address */
xf_ipc_b2a(xf_proxy_ipc_data_t * ipc,void * b)71 static inline u32 xf_ipc_b2a(xf_proxy_ipc_data_t *ipc, void *b)
72 {
73     u32     a;
74 
75     if (b == NULL)
76         return XF_PROXY_NULL;
77     if ((a = (u32)((u8 *)b - (u8 *)ipc->shmem)) < XF_CFG_REMOTE_IPC_POOL_SIZE)
78         return a;
79     else
80         return XF_PROXY_BADADDR;
81 }
82 
83 /*******************************************************************************
84  * Component inter-process communication
85  ******************************************************************************/
86 
87 typedef struct xf_ipc_data
88 {
89     /* ...asynchronous response delivery pipe */
90     int                 pipe[2];
91 
92 }   xf_ipc_data_t;
93 
94 /*******************************************************************************
95  * Helpers for asynchronous response delivery
96  ******************************************************************************/
97 
98 #define xf_ipc_response_put(ipc, msg)       \
99     (write((ipc)->pipe[1], (msg), sizeof(*(msg))) == sizeof(*(msg)) ? 0 : -errno)
100 
101 #define xf_ipc_response_get(ipc, msg)       \
102     (read((ipc)->pipe[0], (msg), sizeof(*(msg))) == sizeof(*(msg)) ? 0 : -errno)
103 
104 #define xf_ipc_data_init(ipc)               \
105     (pipe((ipc)->pipe) == 0 ? 0 : -errno)
106 
107 #define xf_ipc_data_destroy(ipc)            \
108     (close((ipc)->pipe[0]), close((ipc)->pipe[1]))
109 
110 /*******************************************************************************
111 * API functions
112  ******************************************************************************/
113 
114 /* ...send asynchronous command */
115 extern int  xf_ipc_send(xf_proxy_ipc_data_t *ipc, xf_proxy_msg_t *msg, void *b);
116 
117 /* ...wait for response from remote proxy */
118 extern int  xf_ipc_wait(xf_proxy_ipc_data_t *ipc, u32 timeout);
119 
120 /* ...receive response from IPC layer */
121 extern int  xf_ipc_recv(xf_proxy_ipc_data_t *ipc, xf_proxy_msg_t *msg, void **b);
122 
123 /* ...open proxy interface on proper DSP partition */
124 extern int  xf_ipc_open(xf_proxy_ipc_data_t *proxy, u32 core, void *p_shmem);
125 
126 /* ...close proxy handle */
127 extern void xf_ipc_close(xf_proxy_ipc_data_t *proxy, u32 core);
128