1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2017-2019 NXP
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted provided that the following conditions are met:
9  *
10  * o Redistributions of source code must retain the above copyright notice, this list
11  *   of conditions and the following disclaimer.
12  *
13  * o Redistributions in binary form must reproduce the above copyright notice, this
14  *   list of conditions and the following disclaimer in the documentation and/or
15  *   other materials provided with the distribution.
16  *
17  * o Neither the name of the copyright holder nor the names of its
18  *   contributors may be used to endorse or promote products derived from this
19  *   software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*!
34  * Header file for the RPC implementation.
35  */
36 
37 #ifndef SC_RPC_H
38 #define SC_RPC_H
39 
40 /* Includes */
41 
42 #include "main/types.h"
43 #include "main/ipc.h"
44 
45 /* Defines */
46 
47 #define SCFW_API_VERSION_MAJOR  1U
48 #define SCFW_API_VERSION_MINOR  16U
49 
50 #define SC_RPC_VERSION          1U
51 
52 #define SC_RPC_MAX_MSG          8U
53 
54 #define RPC_VER(MESG)           ((MESG)->version)
55 #define RPC_SIZE(MESG)          ((MESG)->size)
56 #define RPC_SVC(MESG)           ((MESG)->svc)
57 #define RPC_FUNC(MESG)          ((MESG)->func)
58 #define RPC_R8(MESG)            ((MESG)->func)
59 #define RPC_I64(MESG, IDX)      ((I64(RPC_U32((MESG), (IDX))) << 32ULL) \
60                                     | I64(RPC_U32((MESG), (IDX) + 4U)))
61 #define RPC_I32(MESG, IDX)      ((MESG)->DATA.i32[(IDX) / 4U])
62 #define RPC_I16(MESG, IDX)      ((MESG)->DATA.i16[(IDX) / 2U])
63 #define RPC_I8(MESG, IDX)       ((MESG)->DATA.i8[(IDX)])
64 #define RPC_U64(MESG, IDX)      ((U64(RPC_U32((MESG), (IDX))) << 32ULL) \
65                                     | U64(RPC_U32((MESG), (IDX) + 4U)))
66 #define RPC_U32(MESG, IDX)      ((MESG)->DATA.u32[(IDX) / 4U])
67 #define RPC_U16(MESG, IDX)      ((MESG)->DATA.u16[(IDX) / 2U])
68 #define RPC_U8(MESG, IDX)       ((MESG)->DATA.u8[(IDX)])
69 
70 #define SC_RPC_SVC_UNKNOWN      0U
71 #define SC_RPC_SVC_RETURN       1U
72 #define SC_RPC_SVC_PM           2U
73 #define SC_RPC_SVC_RM           3U
74 #define SC_RPC_SVC_TIMER        5U
75 #define SC_RPC_SVC_PAD          6U
76 #define SC_RPC_SVC_MISC         7U
77 #define SC_RPC_SVC_IRQ          8U
78 #define SC_RPC_SVC_SECO         9U
79 #define SC_RPC_SVC_ABORT        10U
80 
81 #define SC_RPC_ASYNC_STATE_RD_START      0U
82 #define SC_RPC_ASYNC_STATE_RD_ACTIVE     1U
83 #define SC_RPC_ASYNC_STATE_RD_DONE       2U
84 #define SC_RPC_ASYNC_STATE_WR_START      3U
85 #define SC_RPC_ASYNC_STATE_WR_ACTIVE     4U
86 #define SC_RPC_ASYNC_STATE_WR_DONE       5U
87 
88 /* SC -> Client general-purpose MU IRQs */
89 #define SC_RPC_MU_GIR_SVC       0x1U
90 #define SC_RPC_MU_GIR_WAKE      0x2U
91 #define SC_RPC_MU_GIR_BOOT      0x4U
92 #define SC_RPC_MU_GIR_DBG       0x8U
93 
94 /* Client -> SC general-purpose MU IRQs */
95 #define SC_RPC_MU_GIR_RST       0x1U
96 
97 #define I8(X)       ((int8_t) (X))
98 #define I16(X)      ((int16_t) (X))
99 #define I32(X)      ((int32_t) (X))
100 #define I64(X)      ((int64_t) (X))
101 #define U8(X)       ((uint8_t) (X))
102 #define U16(X)      ((uint16_t) (X))
103 #define U32(X)      ((uint32_t) (X))
104 #define U64(X)      ((uint64_t) (X))
105 
106 #define PTR_I8(X)   ((int8_t*) (X))
107 #define PTR_I16(X)  ((int16_t*) (X))
108 #define PTR_I32(X)  ((int32_t*) (X))
109 #define PTR_I64(X)  ((int64_t*) (X))
110 #define PTR_U8(X)   ((uint8_t*) (X))
111 #define PTR_U16(X)  ((uint16_t*) (X))
112 #define PTR_U32(X)  ((uint32_t*) (X))
113 #define PTR_U64(X)  ((uint64_t*) (X))
114 
115 #define U2B(X)      (((X) != 0U) ? SC_TRUE : SC_FALSE)
116 #define U2B32(X)    (((X) != 0UL) ? SC_TRUE : SC_FALSE)
117 #define B2U8(X)     (((X) != SC_FALSE) ? U8(0x01U) : U8(0x00U))
118 #define B2U16(X)    (((X) != SC_FALSE) ? U16(0x01U) : U16(0x00U))
119 #define B2U32(X)    (((X) != SC_FALSE) ? U32(0x01U) : U32(0x00U))
120 
121 /* Types */
122 
123 typedef uint8_t sc_rpc_svc_t;
124 
125 typedef struct
126 {
127     union
128     {
129         uint32_t header;
130         struct
131         {
132             uint8_t version;
133             uint8_t size;
134             uint8_t svc;
135             uint8_t func;
136         };
137     };
138     union
139     {
140         int32_t i32[(SC_RPC_MAX_MSG - 1U)];
141         int16_t i16[(SC_RPC_MAX_MSG - 1U) * 2U];
142         int8_t i8[(SC_RPC_MAX_MSG - 1U) * 4U];
143         uint32_t u32[(SC_RPC_MAX_MSG - 1U)];
144         uint16_t u16[(SC_RPC_MAX_MSG - 1U) * 2U];
145         uint8_t u8[(SC_RPC_MAX_MSG - 1U) * 4U];
146     } DATA;
147 } sc_rpc_msg_t;
148 
149 typedef uint8_t sc_rpc_async_state_t;
150 
151 typedef struct
152 {
153     sc_rpc_async_state_t state;
154     uint8_t wordIdx;
155     sc_rpc_msg_t msg;
156     uint32_t timeStamp;
157 } sc_rpc_async_msg_t;
158 
159 /* Functions */
160 
161 /*!
162  * This is an internal function to send an RPC message over an IPC
163  * channel. It is called by client-side SCFW API function shims.
164  *
165  * @param[in]     ipc         IPC handle
166  * @param[in,out] msg         handle to a message
167  * @param[in]     no_resp     response flag
168  *
169  * If \a no_resp is SC_FALSE then this function waits for a response
170  * and returns the result in \a msg.
171  */
172 void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, sc_bool_t no_resp);
173 
174 #endif /* SC_RPC_H */
175 
176