1 /*
2  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*!
8  * Header file for the RPC implementation.
9  */
10 
11 #ifndef SCI_RPC_H
12 #define SCI_RPC_H
13 
14 /* Includes */
15 
16 #include <stdbool.h>
17 
18 #include <sci/sci_types.h>
19 #include <sci/sci_ipc.h>
20 
21 /* Defines */
22 
23 #define SC_RPC_VERSION          1U
24 
25 #define SC_RPC_MAX_MSG          8U
26 
27 #define RPC_VER(MSG)            ((MSG)->version)
28 #define RPC_SIZE(MSG)           ((MSG)->size)
29 #define RPC_SVC(MSG)            ((MSG)->svc)
30 #define RPC_FUNC(MSG)           ((MSG)->func)
31 #define RPC_R8(MSG)             ((MSG)->func)
32 #define RPC_I32(MSG, IDX)       ((MSG)->DATA.i32[(IDX) / 4U])
33 #define RPC_I16(MSG, IDX)       ((MSG)->DATA.i16[(IDX) / 2U])
34 #define RPC_I8(MSG, IDX)        ((MSG)->DATA.i8[(IDX)])
35 #define RPC_U32(MSG, IDX)       ((MSG)->DATA.u32[(IDX) / 4U])
36 #define RPC_U16(MSG, IDX)       ((MSG)->DATA.u16[(IDX) / 2U])
37 #define RPC_U8(MSG, IDX)        ((MSG)->DATA.u8[(IDX)])
38 
39 #define SC_RPC_SVC_UNKNOWN      0U
40 #define SC_RPC_SVC_RETURN       1U
41 #define SC_RPC_SVC_PM           2U
42 #define SC_RPC_SVC_RM           3U
43 #define SC_RPC_SVC_TIMER        5U
44 #define SC_RPC_SVC_PAD          6U
45 #define SC_RPC_SVC_MISC         7U
46 #define SC_RPC_SVC_IRQ          8U
47 #define SC_RPC_SVC_ABORT        9U
48 
49 #define SC_RPC_ASYNC_STATE_RD_START      0U
50 #define SC_RPC_ASYNC_STATE_RD_ACTIVE     1U
51 #define SC_RPC_ASYNC_STATE_RD_DONE       2U
52 #define SC_RPC_ASYNC_STATE_WR_START      3U
53 #define SC_RPC_ASYNC_STATE_WR_ACTIVE     4U
54 #define SC_RPC_ASYNC_STATE_WR_DONE       5U
55 
56 #define SC_RPC_MU_GIR_SVC       0x1U
57 #define SC_RPC_MU_GIR_DBG       0x8U
58 
59 /* Types */
60 
61 typedef uint8_t sc_rpc_svc_t;
62 
63 typedef struct sc_rpc_msg_s {
64 	uint8_t version;
65 	uint8_t size;
66 	uint8_t svc;
67 	uint8_t func;
68 	union {
69 		int32_t i32[(SC_RPC_MAX_MSG - 1U)];
70 		int16_t i16[(SC_RPC_MAX_MSG - 1U) * 2U];
71 		int8_t i8[(SC_RPC_MAX_MSG - 1U) * 4U];
72 		uint32_t u32[(SC_RPC_MAX_MSG - 1U)];
73 		uint16_t u16[(SC_RPC_MAX_MSG - 1U) * 2U];
74 		uint8_t u8[(SC_RPC_MAX_MSG - 1U) * 4U];
75 	} DATA;
76 } sc_rpc_msg_t;
77 
78 typedef uint8_t sc_rpc_async_state_t;
79 
80 typedef struct sc_rpc_async_msg_s {
81 	sc_rpc_async_state_t state;
82 	uint8_t wordIdx;
83 	sc_rpc_msg_t msg;
84 	uint32_t timeStamp;
85 } sc_rpc_async_msg_t;
86 
87 /* Functions */
88 
89 /*!
90  * This is an internal function to send an RPC message over an IPC
91  * channel. It is called by client-side SCFW API function shims.
92  *
93  * @param[in]     ipc         IPC handle
94  * @param[in,out] msg         handle to a message
95  * @param[in]     no_resp     response flag
96  *
97  * If \a no_resp is SC_FALSE then this function waits for a response
98  * and returns the result in \a msg.
99  */
100 void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, bool no_resp);
101 
102 /*!
103  * This is an internal function to dispatch an RPC call that has
104  * arrived via IPC over an MU. It is called by server-side SCFW.
105  *
106  * @param[in]     mu          MU message arrived on
107  * @param[in,out] msg         handle to a message
108  *
109  * The function result is returned in \a msg.
110  */
111 void sc_rpc_dispatch(sc_rsrc_t mu, sc_rpc_msg_t *msg);
112 
113 /*!
114  * This function translates an RPC message and forwards on to the
115  * normal RPC API.  It is used only by hypervisors.
116  *
117  * @param[in]     ipc         IPC handle
118  * @param[in,out] msg         handle to a message
119  *
120  * This function decodes a message, calls macros to translate the
121  * resources, pads, addresses, partitions, memory regions, etc. and
122  * then forwards on to the hypervisors SCFW API.Return results are
123  * translated back abd placed back into the message to be returned
124  * to the original API.
125  */
126 void sc_rpc_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
127 
128 #endif /* SCI_RPC_H */
129