1 /*
2  * Copyright (c) 2023, Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_SIP_SVC_PROTO_H_
8 #define ZEPHYR_INCLUDE_SIP_SVC_PROTO_H_
9 
10 /**
11  * @file
12  * @brief Arm SiP services communication protocol
13  *        between service provider and client.
14  *
15  * Client to fill in the input data in struct sip_svc_request format
16  * when requesting SMC/HVC service via 'send' function.
17  *
18  * Service to fill in the SMC/HVC return value in struct sip_svc_response
19  * format and pass to client via Callback.
20  */
21 
22 /**
23  *  @brief Invalid id value
24  */
25 #define SIP_SVC_ID_INVALID 0xFFFFFFFF
26 
27 /** @brief Header format
28  */
29 
30 #define SIP_SVC_PROTO_VER 0x0
31 
32 #define SIP_SVC_PROTO_HEADER_CODE_OFFSET 0
33 #define SIP_SVC_PROTO_HEADER_CODE_MASK	 0xFFFF
34 
35 #define SIP_SVC_PROTO_HEADER_TRANS_ID_OFFSET 16
36 #define SIP_SVC_PROTO_HEADER_TRANS_ID_MASK   0xFF
37 
38 #define SIP_SVC_PROTO_HEADER_VER_OFFSET 30
39 #define SIP_SVC_PROTO_HEADER_VER_MASK	0x3
40 
41 #define SIP_SVC_PROTO_HEADER(code, trans_id)                                                       \
42 	((((code)&SIP_SVC_PROTO_HEADER_CODE_MASK) << SIP_SVC_PROTO_HEADER_CODE_OFFSET) |           \
43 	 (((trans_id)&SIP_SVC_PROTO_HEADER_TRANS_ID_MASK)                                          \
44 	  << SIP_SVC_PROTO_HEADER_TRANS_ID_OFFSET) |                                               \
45 	 ((SIP_SVC_PROTO_VER & SIP_SVC_PROTO_HEADER_VER_MASK) << SIP_SVC_PROTO_HEADER_VER_OFFSET))
46 
47 #define SIP_SVC_PROTO_HEADER_GET_CODE(header)                                                      \
48 	(((header) >> SIP_SVC_PROTO_HEADER_CODE_OFFSET) & SIP_SVC_PROTO_HEADER_CODE_MASK)
49 
50 #define SIP_SVC_PROTO_HEADER_GET_TRANS_ID(header)                                                  \
51 	(((header) >> SIP_SVC_PROTO_HEADER_TRANS_ID_OFFSET) & SIP_SVC_PROTO_HEADER_TRANS_ID_MASK)
52 
53 #define SIP_SVC_PROTO_HEADER_SET_TRANS_ID(header, trans_id)                                        \
54 	(header) &= ~(SIP_SVC_PROTO_HEADER_TRANS_ID_MASK << SIP_SVC_PROTO_HEADER_TRANS_ID_OFFSET); \
55 	(header) |= (((trans_id)&SIP_SVC_PROTO_HEADER_TRANS_ID_MASK)                               \
56 		     << SIP_SVC_PROTO_HEADER_TRANS_ID_OFFSET);
57 
58 /** @brief Arm SiP services command code in request header
59  *
60  * SIP_SVC_PROTO_CMD_SYNC
61  *     - Typical flow, synchronous request. Service expects EL3/EL2 firmware to
62  *       return the result immediately during SMC/HVC call.
63  *
64  * SIP_SVC_PROTO_CMD_ASYNC
65  *     - Asynchronous request. Service is required to poll the response via a
66  *       separate SMC/HVC call. Use this method if the request requires longer
67  *       processing in EL3/EL2.
68  */
69 
70 #define SIP_SVC_PROTO_CMD_SYNC	0x0
71 #define SIP_SVC_PROTO_CMD_ASYNC 0x1
72 #define SIP_SVC_PROTO_CMD_MAX	SIP_SVC_PROTO_CMD_ASYNC
73 
74 /** @brief Error code in response header
75  *
76  * SIP_SVC_PROTO_STATUS_OK
77  *     - Successfully execute the request.
78  *
79  * SIP_SVC_PROTO_STATUS_UNKNOWN
80  *     - Unrecognized SMC/HVC Function ID.
81  *
82  * SIP_SVC_PROTO_STATUS_BUSY
83  *     - The request is still in progress. Please try again.
84  *
85  * SIP_SVC_PROTO_STATUS_REJECT
86  *     - The request have been rejected due to improper input data.
87  *
88  * SIP_SVC_PROTO_STATUS_NO_RESPONSE
89  *     - No response from target hardware yet.
90  *
91  * SIP_SVC_PROTO_STATUS_ERROR
92  *     - Error occurred when executing the request.
93  *
94  * SIP_SVC_PROTO_STATUS_NOT_SUPPORT
95  *     - Unsupported Arm SiP services command code
96  */
97 
98 #define SIP_SVC_PROTO_STATUS_OK		 0x0
99 #define SIP_SVC_PROTO_STATUS_UNKNOWN	 0xFFFF
100 #define SIP_SVC_PROTO_STATUS_BUSY	 0x1
101 #define SIP_SVC_PROTO_STATUS_REJECT	 0x2
102 #define SIP_SVC_PROTO_STATUS_NO_RESPONSE 0x3
103 #define SIP_SVC_PROTO_STATUS_ERROR	 0x4
104 
105 /** @brief SiP Service communication protocol
106  *         request format.
107  *
108  * request header
109  *     - bits [15: 0] Arm SiP services command code
110  *     - bits [23:16] Transaction ID (Filled in by sip_svc service)
111  *     - bits [29:24] Unused. Reserved.
112  *     - bits [31:30] Arm SiP services communication protocol version
113  *
114  * a0 - a7
115  *     - User input data to be filled into a0-a7 registers when trigger
116  *       SMC/HVC
117  *
118  * resp_data_addr
119  *     - This parameter only used by asynchronous command.
120  *     - Dynamic memory address for service to put the asynchronous response
121  *       data. The service will free this memory space if the client has
122  *       cancelled the transaction.
123  *
124  * resp_data_size
125  *     - This parameter only used by asynchronous command.
126  *     - Maximum memory size in bytes of resp_data_addr
127  *
128  * priv_data
129  *     - Memory address to client context. Service will pass this address back
130  *       to client in response format via callback.
131  */
132 
133 struct sip_svc_request {
134 	uint32_t header;
135 	unsigned long a0;
136 	unsigned long a1;
137 	unsigned long a2;
138 	unsigned long a3;
139 	unsigned long a4;
140 	unsigned long a5;
141 	unsigned long a6;
142 	unsigned long a7;
143 	uint64_t resp_data_addr;
144 	uint32_t resp_data_size;
145 	void *priv_data;
146 };
147 
148 /** @brief SiP Services service communication protocol
149  *         response format.
150  *
151  * response header
152  *     - bits [15: 0] Error code
153  *     - bits [23:16] Transaction ID
154  *     - bits [29:24] Unused. Reserved.
155  *     - bits [31:30] Arm SiP services communication protocol version
156  *
157  * a0 - a3
158  *     - SMC/HVC return value
159  *
160  * resp_data_addr
161  *     - This parameter only used by asynchronous command.
162  *     - Dynamic memory address that put the asynchronous response data.
163  *       This address is provided by client during request. Client is responsible
164  *       to free the memory space when receive the callback of a asynchronous
165  *       command transaction.The memory needs to be dynamically allocated,
166  *       the framework will free the allocated memory if the channel is in ABORT
167  *       state.
168  *
169  * resp_data_size
170  *     - This parameter only used by asynchronous command.
171  *     - Valid data size in bytes of resp_data_addr
172  *
173  * priv_data
174  *     - Memory address to client context which given during request.
175  */
176 
177 struct sip_svc_response {
178 	uint32_t header;
179 	unsigned long a0;
180 	unsigned long a1;
181 	unsigned long a2;
182 	unsigned long a3;
183 	uint64_t resp_data_addr;
184 	uint32_t resp_data_size;
185 	void *priv_data;
186 };
187 
188 #endif /* ZEPHYR_INCLUDE_SIP_SVC_PROTO_H_ */
189