1 /*
2 * Copyright (C) 2018-2020 Texas Instruments Incorporated
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
34 /**
35 * \file sciclient_priv.h
36 *
37 * \brief This file contains the handle structure used internally by sciclient.
38 */
39 #ifndef SCICLIENT_PRIV_H_
40 #define SCICLIENT_PRIV_H_
42 /* ========================================================================== */
43 /* Include Files */
44 /* ========================================================================== */
46 #include <stdint.h>
47 #include <ti/csl/hw_types.h>
48 #include <ti/csl/csl_sec_proxy.h>
49 #include <ti/osal/osal.h>
50 #include <ti/osal/SemaphoreP.h>
51 #include <ti/osal/RegisterIntr.h>
53 #include <ti/drv/sciclient/sciclient.h>
54 #include <ti/drv/sciclient/src/sciclient/sciclient_romMessages.h>
55 #include <ti/drv/sciclient/soc/sciclient_soc_priv.h>
57 #if defined (SOC_AM65XX)
58 #include <ti/drv/sciclient/soc/V0/sciclient_defaultBoardcfg.h>
59 #endif
61 #if defined (SOC_J721E)
62 #include <ti/drv/sciclient/soc/V1/sciclient_defaultBoardcfg.h>
63 #endif
65 #if defined (SOC_J7200)
66 #include <ti/drv/sciclient/soc/V2/sciclient_defaultBoardcfg.h>
67 #endif
69 #if defined (SOC_AM64X)
70 #include <ti/drv/sciclient/soc/V3/sciclient_defaultBoardcfg.h>
71 #endif
73 #ifdef __cplusplus
74 extern "C" {
75 #endif
77 /* ========================================================================== */
78 /* Macros & Typedefs */
79 /* ========================================================================== */
81 /**
82 * \brief Maximum number of messages waiting to be read.
83 * Cannot be greater than 256.
84 */
85 #define SCICLIENT_MAX_QUEUE_SIZE (7U)
87 /* Current context is SECURE */
88 #define SCICLIENT_SECURE_CONTEXT (0U)
90 /* Current context is NON-SECURE */
91 #define SCICLIENT_NON_SECURE_CONTEXT (1U)
93 /* ========================================================================== */
94 /* Structure Declarations */
95 /* ========================================================================== */
97 /**
98 * \brief Map structure used by #Sciclient_init function.
99 */
100 typedef struct
101 {
102 uint32_t context;
103 /**< context(sec/non-sec) **/
105 uint32_t hostId;
106 /**< CPU ID of the A53/A72/R5F/DSP */
107 #if !defined (SOC_AM64X)
108 uint32_t reqHighPrioThreadId;
109 /**< Thread ID of the high priority thread(write) allowed for the CPU */
110 #endif
111 uint32_t reqLowPrioThreadId;
112 /**< Thread ID of the low priority thread(write) allowed for the CPU */
114 #if !defined (SOC_AM64X)
115 uint32_t notificationRespThreadId;
116 /**< Thread ID of the thread(write) for sending a notification to the
117 * firmware
118 */
119 #endif
120 uint32_t respThreadId;
121 /**< Thread ID of the response thread(read) available for the CPU */
123 #if !defined (SOC_AM64X)
124 uint32_t notificationThreadId;
125 /**< Thread ID of the notification thread(read) available for the CPU */
126 #endif
127 uint32_t respIntrNum;
128 /**< Response Interrupt Number. */
129 } Sciclient_MapStruct_t;
131 /**
132 * \brief Handle for #Sciclient_service function
133 */
134 typedef struct
135 {
136 SemaphoreP_Handle semHandles[SCICLIENT_MAX_QUEUE_SIZE];
137 /**< Semaphore is posted when there is a interrupt for the response.
138 * Index is the currSeqId
139 */
140 SemaphoreP_Status semStatus[SCICLIENT_MAX_QUEUE_SIZE];
141 /**< Status returned for the SemaphoreP_pend corresponding to a
142 * particular seqId.
143 */
144 uint32_t currSeqId;
145 /**< Sequence ID of the current request **/
146 HwiP_Handle notificationIntr;
147 /**< Interrupt for notification **/
148 HwiP_Handle respIntr[2];
149 /**< Interrupt for response message. Have 2 for secure and non-secure context **/
150 uint32_t opModeFlag;
151 /**< Operation mode for the Sciclient Service API. Refer to
152 * \ref Sciclient_ServiceOperationMode for valid values.
153 */
154 uint8_t initCount;
155 /**< Count to keep track of the number of inits/de-inits done. Actual
156 * initialization done
157 * only when initCount=0, and de-init done only when initCount=1
158 */
159 uint32_t isSecureMode;
160 /**< Variable to check whether Core context is secure/non-secure. This has
161 * to be given by the user via configParams. Default value is 0.
162 */
164 } Sciclient_ServiceHandle_t;
167 /**
168 * \anchor Sciclient_proxyMap
169 * \name Sciclient map structure
170 * @{
171 * Map structure for R5F,A53,GPU and ICSSG \n
172 * in different contexts.
173 */
174 extern const Sciclient_MapStruct_t gSciclientMap[SCICLIENT_CONTEXT_MAX_NUM];
175 /* @} */
177 /** Board Configuration array */
178 extern const uint32_t gSciclient_boardCfgLow[(SCICLIENT_BOARDCFG_SIZE_IN_BYTES+3U)/4U];
179 /** Board Configuration - RM array */
180 extern const uint32_t gSciclient_boardCfgLow_rm[(SCICLIENT_BOARDCFG_RM_SIZE_IN_BYTES+3U)/4U];
181 /** Board Configuration - Security array */
182 extern const uint32_t gSciclient_boardCfgLow_sec[(SCICLIENT_BOARDCFG_SECURITY_SIZE_IN_BYTES+3U)/4U];
183 /** Board Configuration - PM array */
184 extern const uint32_t gSciclient_boardCfgLow_pm[(SCICLIENT_BOARDCFG_PM_SIZE_IN_BYTES+3U)/4U];
186 /* ========================================================================== */
187 /* Function Declarations */
188 /* ========================================================================== */
190 /**<
191 * \brief API to send the board configuration messsage to the firmware .
192 * Valid(not NULL) pointer to Sciclient_BoardCfgPrms_t will use the
193 * provided values for tisci_msg_board_config_req, otherwise
194 * default values are used .
195 *
196 * \param pInPrms [IN] Pointer to #Sciclient_BoardCfgPrms_t .
197 *
198 * \return status Status of the message.
199 */
200 int32_t Sciclient_boardCfg(const Sciclient_BoardCfgPrms_t * pInPrms);
202 /**
203 * \brief API to identify which mode the CPU is operating in. This utility
204 * function would read CPU related registers to know which mode
205 * (secure or non secure) the CPU is in and then would determine the
206 * context to be used. If more than one context is required for a
207 * a given code, users of SCICLENT would need to modify this function
208 * and recompile.
209 *
210 * \param messageType The Message ID to be checked.
211 *
212 * \return retVal SCICLENT Context of the CPU
213 */
214 uint32_t Sciclient_getCurrentContext(uint16_t messageType);
216 /**
217 * \brief Gives the address for status register for a particular thread.
218 *
219 * \param thread Index of the thread.
220 *
221 * \return address address of the thread status
222 */
223 uint32_t Sciclient_threadStatusReg(uint32_t thread);
225 /**
226 * \brief Read a 32 bit word from the thread.
227 *
228 * \param thread Index of the thread to be read from.
229 * \param idx Index of the word to be read from the thread.
230 *
231 * \return word Value read back.
232 */
233 uint32_t Sciclient_readThread32(uint32_t thread, uint8_t idx);
235 /**
236 * \brief Read the current thread count.
237 *
238 * \param thread Index of the thread to be read from.
239 *
240 * \return word Count read back.
241 */
242 uint32_t Sciclient_readThreadCount(uint32_t thread);
244 /**
245 * \brief Validate thread has no errors and has space to accept the next
246 * message.
247 *
248 * \param thread Index of the thread.
249 *
250 * \return status Status of the message.
251 */
252 int32_t Sciclient_verifyThread(uint32_t thread);
254 /**
255 * \brief Check if there are credits to write to the thread.
256 *
257 * \param thread Index of the thread.
258 * \param timeout Wait for timeout if operation is complete.
259 *
260 * \return status Status of the message.
261 */
262 int32_t Sciclient_waitThread(uint32_t thread, uint32_t timeout);
264 /**
265 * \brief API to send the message to the thread.
266 *
267 * \param thread Index of the thread.
268 * \param pSecHeader Pointer to the security header extension.
269 * \param secHeaderSizeWords Secure Header size in Words.
270 * \param pHeader Pointer to the header structure.
271 * \param pPayload Pointer to the payload structure.
272 * \param payloadSize Size of the payload.
273 * \param maxMsgSizeBytes Maximum Message size in words.
274 *
275 * \return status Status of the message.
276 */
277 void Sciclient_sendMessage(uint32_t thread,
278 const uint8_t *pSecHeader,
279 const uint8_t secHeaderSizeWords,
280 const uint8_t *pHeader,
281 const uint8_t *pPayload,
282 uint32_t payloadSize,
283 const uint32_t maxMsgSizeBytes);
285 /**
286 * \brief This utility function would find the proxy map context id for
287 * 'gSciclientMap' corresponding to a particular interrupt number.
288 *
289 * \param intrNum Interrupt number.
290 *
291 * \return retVal Context Id for the interrupt number.
292 */
293 int32_t Sciclient_contextIdFromIntrNum(uint32_t intrNum);
295 /**
296 * \brief API to flush/remove all outstanding messages on a thread .
297 *
298 * \param thread Index of the thread.
299 * \param maxMsgSizeBytes Maximum message size in Bytes.
300 *
301 * \return None
302 */
303 void Sciclient_flush(uint32_t thread, uint32_t maxMsgSizeBytes);
306 /**
307 * \brief This API allows communicating with the System firmware which can be
308 * called to perform various functions in the system.
309 * Core sciclient function for transmitting payload and recieving
310 * the response.
311 * The caller is expected to allocate memory for the input request
312 * parameter (Refer #Sciclient_ReqPrm_t). This involves setting the
313 * message type being communicated to the firmware, the response flags,
314 * populate the payload of the message based on the inputs in the
315 * files sciclient_fmwPmMessages.h,sciclient_fmwRmMessages.h,
316 * sciclient_fmwSecMessages.h and sciclient_fmwCommonMessages.h.
317 * Since the payload in considered a stream of bytes in this API,
318 * the caller should also populate the size of this stream in
319 * reqPayloadSize. The timeout is used to determine for what amount
320 * of iterations the API would wait for their operation to complete.
321 *
322 * To make sure the response is captured correctly the caller should
323 * also allocate the space for #Sciclient_RespPrm_t parameters. The
324 * caller should populate the pointer to the pRespPayload and the size
325 * respPayloadSize. The API would populate the response flags to
326 * indicate any firmware specific errors and also populate the memory
327 * pointed by pRespPayload till the size given in respPayloadSize.
328 *
329 *
330 * Requirement: DOX_REQ_TAG(PDK-2142), DOX_REQ_TAG(PDK-2141),
331 * DOX_REQ_TAG(PDK-2140), DOX_REQ_TAG(PDK-2139)
332 *
333 * \param pReqPrm [IN] Pointer to #Sciclient_ReqPrm_t
334 * \param pRespPrm [OUT] Pointer to #Sciclient_RespPrm_t
335 *
336 * \return CSL_PASS on success, else failure
337 *
338 */
339 int32_t Sciclient_serviceSecureProxy(const Sciclient_ReqPrm_t *pReqPrm,
340 Sciclient_RespPrm_t *pRespPrm);
342 /**
343 * \brief Sciclient_serviceGetThreadIds Gets the threads used for message.
344 *
345 * \param pReqPrm [IN] Pointer to #Sciclient_ReqPrm_t
346 * \param contextId [OUT] Context ID to be used.
347 * \param txThread [OUT] Transmit Thread
348 * \param rxThread [OUT] Recieve Thread
349 *
350 * \return CSL_PASS on success, else failure
351 *
352 */
353 int32_t Sciclient_serviceGetThreadIds (const Sciclient_ReqPrm_t *pReqPrm,
354 uint32_t *contextId,
355 uint32_t *txThread,
356 uint32_t *rxThread);
358 /**
359 * \brief Sciclient_servicePrepareHeader Prepares the Message Header.
360 *
361 * \param pReqPrm [IN] Pointer to #Sciclient_ReqPrm_t
362 * \param contextId [IN] Context ID to be used.
363 * \param localSeqId [OUT] Transmit Thread
364 * \param header [OUT] Pointer to the header
365 *
366 * \return CSL_PASS on success, else failure
367 *
368 */
369 int32_t Sciclient_servicePrepareHeader(const Sciclient_ReqPrm_t *pReqPrm,
370 uint8_t *localSeqId,
371 uint32_t contextId,
372 struct tisci_header **header);
374 int32_t Sciclient_ProcessRmMessage(void *tx_msg);
375 int32_t Sciclient_ProcessPmMessage(const uint32_t reqFlags, void *tx_msg);
377 #ifdef __cplusplus
378 }
379 #endif
381 #endif /* #ifndef SCICLIENT_PRIV_H_*/