1 /*
2 * Copyright (c) Texas Instruments Incorporated 2020
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 */
33 /**
34 * \file mailbox_soc.c
35 *
36 * \brief The file implements the Platform specific Mailbox Driver Interface
37 */
39 /* ========================================================================== */
40 /* Include Files */
41 /* ========================================================================== */
43 #include <stdint.h>
44 #include <ti/csl/soc.h>
45 #include <ti/csl/csl_types.h>
46 #include <ti/drv/mailbox/mailbox.h>
47 #include <ti/drv/mailbox/src/mailbox_internal.h>
49 /* ========================================================================== */
50 /* Macros & Typedefs */
51 /* ========================================================================== */
53 /* None */
55 /* ========================================================================== */
56 /* Structure Declarations */
57 /* ========================================================================== */
59 /*!
60 * @brief
61 * Mailbox Entry Information
62 *
63 * This structure is used to store the cluser/user/fifo information used for communication between a core pair
64 *
65 * \ingroup MAILBOX_DRIVER_INTERNAL_DATA_STRUCTURE
66 */
67 typedef struct Mailbox_Entry_s
68 {
69 /**
70 * @brief Cluster id.
71 */
72 uint32_t cluster;
74 /**
75 * @brief User id.
76 */
77 uint32_t user;
79 /**
80 * @brief Fifo id.
81 */
82 uint32_t fifo;
84 } Mailbox_Entry;
86 /**
87 * @brief
88 * Mailbox Driver HW configuration
89 *
90 * @details
91 * The structure is used to store the hardware specific configuration which is
92 * passed to each driver instance
93 *
94 */
95 typedef struct Mailbox_HwCfg_t
96 {
97 /**
98 * @brief Entry for the mailbox info for receiving messages
99 */
100 Mailbox_Entry rx;
101 /**
102 * @brief Entry for the mailbox info for sending messages
103 */
104 Mailbox_Entry tx;
105 /**
106 * @brief Flag to indicate if there is exclusive access to the mailbox
107 * for receiving messages from a single remote core. For example, if
108 * the interrupt line for mailbox cluster 0 is only used for
109 * receiving messages from a single remote core. Some optimiation
110 * can be done when handling the incoming message in this case.
111 */
112 bool exclusive;
113 /**
114 * @brief The associated eventId for the interrupt.
115 */
116 uint32_t eventId;
117 } Mailbox_HwCfg;
120 /* ========================================================================== */
121 /* Function Declarations */
122 /* ========================================================================== */
124 /* None */
126 /* ========================================================================== */
127 /* Global Variables */
128 /* ========================================================================== */
130 #define MAILBOX_MAXFIFO_CNT (16U)
131 #define MAILBOX_CLUSTER_CNT (8U)
132 #define MAILBOX_USER_CNT (4U)
134 /**
135 * @brief
136 * Global Variable for tracking information required by the mailbox driver.
137 */
138 extern Mailbox_MCB gMailboxMCB;
140 /**
141 * \brief Maps mBoxData allocated to a given Remote Processor
142 */
143 uintptr_t gInstToMBoxDataMap[MAILBOX_MAX_INST];
145 typedef struct Mailbox_Fifo_s
146 {
147 int32_t cfgNdx;
148 Mailbox_Callback func;
149 uint32_t arg;
150 uint32_t queueId;
151 void *handle;
152 } Mailbox_Fifo;
154 /* mboxData */
155 typedef struct Mailbox_Data_s
156 {
157 uint32_t baseAddr;
158 uint32_t fifoCnt;
159 Mailbox_Fifo fifoTable[MAILBOX_MAXFIFO_CNT];
160 uint32_t noMsgCnt;
161 uint32_t intCnt;
162 uint32_t userId;
164 } Mailbox_Data;
166 /* ========================================================================== */
167 /* Globals */
168 /* ========================================================================== */
169 uint32_t g_mBoxCnt = 0U;
170 Mailbox_Data g_mBoxData[MAILBOX_MAX_INST];
171 Mailbox_Callback g_VimCallback[MAILBOX_MAX_INST];
172 Mbox_Handle g_VimCallbackArg[MAILBOX_MAX_INST];
173 Mailbox_Callback g_FastCallback[MAILBOX_MAX_INST];
174 Mbox_Handle g_FastCallbackArg[MAILBOX_MAX_INST];
175 Mailbox_Driver g_mBoxDrivers[MAILBOX_MAX_INST];
177 /* Mailbox Cluster Base Address */
178 static uint32_t g_Mailbox_BaseAddr[MAILBOX_CLUSTER_CNT] =
179 {
180 CSL_MAILBOX0_REGS0_BASE,
181 CSL_MAILBOX0_REGS1_BASE,
182 CSL_MAILBOX0_REGS2_BASE,
183 CSL_MAILBOX0_REGS3_BASE,
184 CSL_MAILBOX0_REGS4_BASE,
185 CSL_MAILBOX0_REGS5_BASE,
186 CSL_MAILBOX0_REGS6_BASE,
187 CSL_MAILBOX0_REGS7_BASE,
188 };
190 Mailbox_HwCfg g_Mailbox_HwCfg[MAILBOX_MAX_INST][MAILBOX_MAX_INST] =
191 {
192 /* Host Processor - A53-vm0 */
193 {
194 { { 0xFFU, 0xFFU, 0U}, { 0xFFU, 0xFFU, 0U}, true, 0 }, /* Self - A53-vm0 */
195 { { 2U, 2U, 0U}, { 2U, 2U, 1U}, false, 0 }, /* mcu-r5f0 */
196 { { 2U, 2U, 2U}, { 2U, 2U, 3U}, false, 0 }, /* mcu-r5f1 */
197 { { 4U, 2U, 0U}, { 4U, 2U, 1U}, false, 0 }, /* pulsar1_cr5f_0 */
198 { { 4U, 2U, 2U}, { 4U, 2U, 3U}, false, 0 }, /* pulsar1_cr5f_1 */
199 { { 6U, 2U, 0U}, { 6U, 2U, 1U}, true, 0 }, /* m4f_0 */
200 },
201 /* Host Processor - mcu1_0 */
202 {
203 { { 2U, 0U, 1U }, { 2U, 0U, 0U}, true, 0 }, /* A53-vm0 */
204 { { 0xFFU, 0xFFU, 0U }, { 0xFFU, 0xFFU, 0U}, true, 0 }, /* Self - mcu-r5f0 */
205 { { 0U, 0U, 0U }, { 0U, 0xFFU, 1U}, true, 0 }, /* mcu-r5f1 */
206 { { 1U, 0U, 0U }, { 0U, 0xFFU, 2U}, true, 0 }, /* pulsar1_cr5f_0 */
207 { { 3U, 0U, 0U }, { 0U, 0xFFU, 3U}, true, 0 }, /* pulsar1_cr5f_1 */
208 { { 6U, 0U, 2U }, { 6U, 0xFFU, 3U}, true, 0 }, /* m4f_0 */
209 },
210 /* Host Processor - mcu1_1 */
211 {
212 { { 2U, 1U, 3U }, { 2U, 1U, 2U}, true, 0 }, /* A53-vm0 */
213 { { 0U, 1U, 1U }, { 0U, 0xFFU, 0U}, true, 0 }, /* mcu-r5f0 */
214 { { 0xFFU, 0xFFU, 0U }, { 0xFFU, 0xFFU, 0U}, true, 0 }, /* Self - mcu-r5f1 */
215 { { 1U, 1U, 1U }, { 1U, 0xFFU, 2U}, true, 0 }, /* pulsar1_cr5f_0 */
216 { { 3U, 1U, 1U }, { 1U, 0xFFU, 3U}, true, 0 }, /* pulsar1_cr5F_1 */
217 { { 6U, 1U, 4U }, { 6U, 0xFFU, 5U}, true, 0 }, /* m4f_0 */
218 },
219 /* Host Processor - pulsar1_cr5f_0 */
220 {
221 { { 4U, 0U, 1U }, { 4U, 0U, 0U}, true, 0 }, /* A53-vm0 */
222 { { 0U, 2U, 2U }, { 1U, 0xFFU, 0U}, true, 0 }, /* mcu-r5f0 */
223 { { 1U, 2U, 2U }, { 1U, 0xFFU, 1U}, true, 0 }, /* mcu-r5f1 */
224 { { 0xFFU, 0xFFU, 0U }, { 0xFFU, 0xFFU, 0U}, true, 0 }, /* Self - pulsar1_cr5f_0 */
225 { { 5U, 0U, 2U }, { 5U, 0xFFU, 3U}, true, 0 }, /* pulsar1_cr5f_1 */
226 { { 7U, 0U, 2U }, { 7U, 0xFFU, 4U}, true, 0 }, /* m4f_0 */
227 },
228 /* Host Processor - pulsar1_cr5f_1 */
229 {
230 { { 4U, 1U, 3U }, { 4U, 1U, 2U}, true, 0 }, /* A53-vm0 */
231 { { 0U, 3U, 3U }, { 3U, 0xFFU, 0U}, true, 0 }, /* mcu-r5f0 */
232 { { 1U, 3U, 3U }, { 3U, 0xFFU, 1U}, true, 0 }, /* mcu-r5f1 */
233 { { 5U, 1U, 3U }, { 5U, 0xFFU, 2U}, true, 0 }, /* pulsar1_cr5f_0 */
234 { { 0xFFU, 0xFFU, 0U }, { 0xFFU, 0xFFU, 0U}, true, 0 }, /* Self - pulsar1_cr5f_1 */
235 { { 7U, 1U, 3U }, { 7U, 0xFFU, 5U}, true, 0 }, /* m4f_0 */
236 },
237 /* Host Processor - m4f_0 */
238 {
239 { { 6U, 3U, 1U }, { 6U, 3U, 0U}, false, 0 }, /* A53-vm0 */
240 { { 6U, 3U, 3U }, { 6U, 0xFFU, 2U}, false, 0 }, /* mcu-r5f0 */
241 { { 6U, 3U, 5U }, { 6U, 0xFFU, 4U}, false, 0 }, /* mcu-r5f1 */
242 { { 7U, 3U, 4U }, { 7U, 0xFFU, 2U}, false, 0 }, /* pulsar1_cr5f_0 */
243 { { 7U, 3U, 5U }, { 7U, 0xFFU, 3U}, false, 0 }, /* pulsar1_cr5f_1 */
244 { { 0xFFU, 0xFFU, 0U }, { 0xFFU, 0xFFU, 0U}, false, 0 }, /* Self - m4f_0 */
245 }
246 };
248 /* ========================================================================== */
249 /* Function Definitions */
250 /* ========================================================================== */
252 Mailbox_Instance Mailbox_getLocalEndPoint(void)
253 {
254 Mailbox_Instance localEndpoint = MAILBOX_INST_INVALID;
256 #if defined (BUILD_MPU1_0)
257 localEndpoint = MAILBOX_INST_MPU1_0;
258 #elif defined (BUILD_MCU1_0)
259 localEndpoint = MAILBOX_INST_MCU1_0;
260 #elif defined (BUILD_MCU1_1)
261 localEndpoint = MAILBOX_INST_MCU1_1;
262 #elif defined (BUILD_MCU2_0)
263 localEndpoint = MAILBOX_INST_MCU2_0;
264 #elif defined (BUILD_MCU2_1)
265 localEndpoint = MAILBOX_INST_MCU2_1;
266 #elif defined (BUILD_M4F_0)
267 localEndpoint = MAILBOX_INST_M4F_0;
268 #endif
270 return localEndpoint;
271 }
273 int32_t Mailbox_validateLocalEndPoint(Mailbox_Instance localEndpoint)
274 {
275 int32_t retVal = MAILBOX_SOK;
276 /* Validate local End point based on the Core. */
277 #if defined (BUILD_MPU1_0)
278 if (localEndpoint != MAILBOX_INST_MPU1_0)
279 {
280 retVal = MAILBOX_EINVAL;
281 }
282 #elif defined (BUILD_MCU1_0)
283 if (localEndpoint != MAILBOX_INST_MCU1_0)
284 {
285 retVal = MAILBOX_EINVAL;
286 }
287 #elif defined (BUILD_MCU1_1)
288 if (localEndpoint != MAILBOX_INST_MCU1_1)
289 {
290 retVal = MAILBOX_EINVAL;
291 }
292 #elif defined (BUILD_MCU2_0)
293 if (localEndpoint != MAILBOX_INST_MCU2_0)
294 {
295 retVal = MAILBOX_EINVAL;
296 }
297 #elif defined (BUILD_MCU2_1)
298 if (localEndpoint != MAILBOX_INST_MCU2_1)
299 {
300 retVal = MAILBOX_EINVAL;
301 }
302 #elif defined (BUILD_M4F_0)
303 if (localEndpoint != MAILBOX_INST_M4F_0)
304 {
305 retVal = MAILBOX_EINVAL;
306 }
307 #else
308 /* Currently not supported for other cores. */
309 retVal = MAILBOX_EINVAL;
310 #endif
311 return retVal;
312 }
314 int32_t Mailbox_validateRemoteEndPoint(Mailbox_Instance localEndpoint, Mailbox_Instance remoteEndpoint)
315 {
316 int32_t retVal = MAILBOX_SOK;
317 if ((remoteEndpoint == localEndpoint) || (remoteEndpoint > MAILBOX_INST_LAST))
318 {
319 retVal = MAILBOX_EINVAL;
320 }
321 return retVal;
322 }
324 int32_t Mailbox_validateDataTransferMode(Mailbox_DataTransferMode dataTransferMode)
325 {
326 /* We ignore data transfer mode for this Mailbox IP. Only way to get data is with register read */
327 return MAILBOX_SOK;
328 }
330 int32_t Mailbox_validateReadWriteMode(Mailbox_Mode readMode, Mailbox_Mode writeMode)
331 {
332 int32_t retVal = MAILBOX_SOK;
333 if ((writeMode == MAILBOX_MODE_CALLBACK) || (writeMode == MAILBOX_MODE_BLOCKING) ||
334 (readMode == MAILBOX_MODE_BLOCKING))
335 {
336 retVal = MAILBOX_EINVAL;
337 }
338 return retVal;
339 }
341 int32_t Mailbox_isMultiChannelSupported(Mailbox_Instance localEndpoint, Mailbox_Instance remoteEndpoint)
342 {
343 /* We do not support Multi-channel for this Mailbox IP */
344 return MAILBOX_EINVAL;
345 }
347 Mbox_Handle Mailbox_allocDriver(Mailbox_Instance remoteEndpoint)
348 {
349 Mailbox_Driver *driver = NULL;
351 driver = &g_mBoxDrivers[remoteEndpoint];
353 return (Mbox_Handle)driver;
354 }
356 int32_t Mailbox_freeDriver(Mbox_Handle handle)
357 {
358 return MAILBOX_SOK;
359 }
361 /**
362 * @b Description
363 * @n
364 * The function configures the hardware base addresses and interrupt numbers
365 * It populates the driver with hard coded information derived from the platform
366 * files.
367 *
368 * @param[in] driver handle
369 *
370 *
371 * @retval
372 * Not applicable
373 *
374 * \ingroup MAILBOX_DRIVER_INTERNAL_FUNCTION
375 *
376 */
377 void* Mailbox_getHwCfg(Mailbox_Instance remoteEndpoint)
378 {
379 Mailbox_HwCfg *hwCfg = NULL;
380 Mailbox_Instance localEndpoint = Mailbox_getLocalEndPoint();
382 if ((remoteEndpoint < MAILBOX_MAX_INST) && (localEndpoint < MAILBOX_MAX_INST))
383 {
384 hwCfg = &g_Mailbox_HwCfg[localEndpoint][remoteEndpoint];
385 }
387 return (void *)hwCfg;
388 }
390 int32_t Mailbox_initHw(Mbox_Handle handle)
391 {
392 int32_t retVal = MAILBOX_SOK;
394 if (handle == NULL)
395 {
396 retVal = MAILBOX_EINVAL;
397 }
399 if (retVal == MAILBOX_SOK)
400 {
401 // TODO
402 }
403 return retVal;
404 }
406 uint32_t Mailbox_GetMessageCount(Mbox_Handle handle)
407 {
408 int32_t count = 0;
410 if (handle != NULL)
411 {
412 count = MailboxGetMessageCount(((Mailbox_Driver *)handle)->baseAddrRx,
413 ((Mailbox_HwCfg *)(((Mailbox_Driver *)handle)->hwCfg))->rx.fifo);
414 }
415 return count;
416 }
418 /*
419 * ======== Mailbox_write ========
420 */
421 int32_t Mailbox_write(Mbox_Handle handle, const uint8_t *buffer, uint32_t size)
422 {
423 int32_t retVal = MAILBOX_SOK;
425 if ((handle != NULL) &&
426 (((Mailbox_Driver *)handle)->hwCfg != NULL) &&
427 (buffer != NULL) &&
428 (((Mailbox_Driver *)handle)->cfg.writeMode == MAILBOX_MODE_FAST))
429 {
430 MailboxWriteMessage(((Mailbox_Driver *)handle)->baseAddrTx,
431 ((Mailbox_HwCfg *)(((Mailbox_Driver *)handle)->hwCfg))->tx.fifo,
432 *((uint32_t *)buffer));
433 }
434 else
435 {
436 Mailbox_Driver* driver = (Mailbox_Driver*)handle;
437 Mailbox_HwCfg *hwCfg = NULL;
438 int32_t key = 0U;
439 uint32_t cnt;
441 if (handle == NULL)
442 {
443 retVal = MAILBOX_EINVAL;
444 }
445 else if (driver->hwCfg == NULL)
446 {
447 retVal = MAILBOX_EINVAL;
448 }
449 else if (buffer == NULL)
450 {
451 retVal = MAILBOX_EINVAL;
452 }
453 else
454 {
455 hwCfg = (Mailbox_HwCfg *)driver->hwCfg;
456 cnt = driver->cfg.writeTimeout;
458 key = gMailboxMCB.initParam.osalPrms.disableAllIntr();
460 do
461 {
462 retVal = MailboxSendMessage(driver->baseAddrTx, hwCfg->tx.fifo, *((uint32_t *)buffer));
463 cnt--;
464 } while( (cnt != 0U) && (retVal == MESSAGE_INVALID));
466 if (MESSAGE_INVALID == retVal)
467 {
468 retVal = MAILBOX_EINVAL;
469 }
471 gMailboxMCB.initParam.osalPrms.restoreAllIntr(key);
472 }
473 }
475 return retVal;
476 }
478 int32_t Mailbox_read(Mbox_Handle handle, uint8_t *buffer, uint32_t size)
479 {
480 int32_t retVal = MAILBOX_SOK;
482 if ((handle != NULL) &&
483 (((Mailbox_Driver *)handle)->hwCfg != NULL) &&
484 (buffer != NULL) &&
485 (((Mailbox_Driver *)handle)->cfg.readMode == MAILBOX_MODE_FAST))
486 {
487 MailboxReadMessage(((Mailbox_Driver *)handle)->baseAddrRx,
488 ((Mailbox_HwCfg *)(((Mailbox_Driver *)handle)->hwCfg))->rx.fifo,
489 (uint32_t *)buffer);
490 }
491 else
492 {
493 Mailbox_Driver* driver = (Mailbox_Driver*)handle;
494 Mailbox_HwCfg* hwCfg = NULL;
496 if (handle == NULL)
497 {
498 retVal = MAILBOX_EINVAL;
499 }
500 else if (driver->hwCfg == NULL)
501 {
502 retVal = MAILBOX_EINVAL;
503 }
504 else if (buffer == NULL)
505 {
506 retVal = MAILBOX_EINVAL;
507 }
508 else
509 {
510 hwCfg = (Mailbox_HwCfg *)driver->hwCfg;
512 /* Get the message from Mailbox fifo */
513 retVal = MailboxGetMessage(driver->baseAddrRx, hwCfg->rx.fifo, (uint32_t *)buffer);
514 if (retVal == MESSAGE_INVALID)
515 {
516 retVal = MAILBOX_EINVAL;
517 }
518 }
519 }
521 return retVal;
522 }
524 uint32_t Mailbox_getBaseAddr(uint32_t clusterId)
525 {
526 uint32_t baseAddrPhy = 0x00000000U;
527 uint32_t baseAddrVirt = 0x00000000U;
529 if( clusterId < MAILBOX_CLUSTER_CNT)
530 {
531 baseAddrPhy = g_Mailbox_BaseAddr[clusterId];
532 if (gMailboxMCB.initParam.phyToVirtFxn)
533 {
534 baseAddrVirt = (uint32_t)gMailboxMCB.initParam.phyToVirtFxn(baseAddrPhy);
535 }
536 else
537 {
538 baseAddrVirt = baseAddrPhy;
539 }
540 }
542 return baseAddrVirt;
543 }
545 int32_t Mailbox_getMailboxIntrRouterCfg(uint32_t selfId, uint32_t clusterId, uint32_t userId,
546 Mailbox_MbConfig* cfg, uint32_t cnt)
547 {
548 int32_t retVal = MAILBOX_SOK;
550 switch(selfId)
551 {
552 case MAILBOX_INST_MPU1_0:
553 if (clusterId == 2 && userId == 2)
554 {
555 cfg->eventId = CSLR_GICSS0_SPI_MAILBOX0_MAILBOX_CLUSTER_2_MAILBOX_CLUSTER_PEND_2;
556 }
557 else if (clusterId == 3 && userId == 2)
558 {
559 cfg->eventId = CSLR_GICSS0_SPI_MAILBOX0_MAILBOX_CLUSTER_3_MAILBOX_CLUSTER_PEND_2;
560 }
561 else if (clusterId == 4 && userId == 2)
562 {
563 cfg->eventId = CSLR_GICSS0_SPI_MAILBOX0_MAILBOX_CLUSTER_4_MAILBOX_CLUSTER_PEND_2;
564 }
565 else if (clusterId == 5 && userId == 2)
566 {
567 cfg->eventId = CSLR_GICSS0_SPI_MAILBOX0_MAILBOX_CLUSTER_5_MAILBOX_CLUSTER_PEND_2;
568 }
569 else if (clusterId == 6 && userId == 2)
570 {
571 cfg->eventId = CSLR_GICSS0_SPI_MAILBOX0_MAILBOX_CLUSTER_6_MAILBOX_CLUSTER_PEND_2;
572 }
573 else
574 {
575 retVal = MAILBOX_EINVAL;
576 }
577 break;
578 case MAILBOX_INST_MCU1_0:
579 if (clusterId == 0 && userId == 0)
580 {
581 cfg->eventId = CSLR_R5FSS0_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_0_MAILBOX_CLUSTER_PEND_0;
582 }
583 else if (clusterId == 1 && userId == 0)
584 {
585 cfg->eventId = CSLR_R5FSS0_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_1_MAILBOX_CLUSTER_PEND_0;
586 }
587 else if (clusterId == 2 && userId == 0)
588 {
589 cfg->eventId = CSLR_R5FSS0_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_2_MAILBOX_CLUSTER_PEND_0;
590 }
591 else if (clusterId == 3 && userId == 0)
592 {
593 cfg->eventId = CSLR_R5FSS0_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_3_MAILBOX_CLUSTER_PEND_0;
594 }
595 else if (clusterId == 6 && userId == 0)
596 {
597 cfg->eventId = CSLR_R5FSS0_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_6_MAILBOX_CLUSTER_PEND_0;
598 }
599 else
600 {
601 retVal = MAILBOX_EINVAL;
602 }
603 break;
604 case MAILBOX_INST_MCU1_1:
605 if (clusterId == 0 && userId == 1)
606 {
607 cfg->eventId = CSLR_R5FSS0_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_0_MAILBOX_CLUSTER_PEND_1;
608 }
609 else if (clusterId == 1 && userId == 1)
610 {
611 cfg->eventId = CSLR_R5FSS0_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_1_MAILBOX_CLUSTER_PEND_1;
612 }
613 else if (clusterId == 2 && userId == 1)
614 {
615 cfg->eventId = CSLR_R5FSS0_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_2_MAILBOX_CLUSTER_PEND_1;
616 }
617 else if (clusterId == 3 && userId == 1)
618 {
619 cfg->eventId = CSLR_R5FSS0_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_3_MAILBOX_CLUSTER_PEND_1;
620 }
621 else if (clusterId == 6 && userId == 1)
622 {
623 cfg->eventId = CSLR_R5FSS0_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_6_MAILBOX_CLUSTER_PEND_1;
624 }
625 else
626 {
627 retVal = MAILBOX_EINVAL;
628 }
629 break;
630 case MAILBOX_INST_MCU2_0:
631 if (clusterId == 0 && userId == 2)
632 {
633 cfg->eventId = CSLR_R5FSS1_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_0_MAILBOX_CLUSTER_PEND_2;
634 }
635 else if (clusterId == 1 && userId == 2)
636 {
637 cfg->eventId = CSLR_R5FSS1_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_1_MAILBOX_CLUSTER_PEND_2;
638 }
639 else if (clusterId == 4 && userId == 0)
640 {
641 cfg->eventId = CSLR_R5FSS1_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_4_MAILBOX_CLUSTER_PEND_0;
642 }
643 else if (clusterId == 5 && userId == 0)
644 {
645 cfg->eventId = CSLR_R5FSS1_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_5_MAILBOX_CLUSTER_PEND_0;
646 }
647 else if (clusterId == 7 && userId == 0)
648 {
649 cfg->eventId = CSLR_R5FSS1_CORE0_INTR_MAILBOX0_MAILBOX_CLUSTER_7_MAILBOX_CLUSTER_PEND_0;
650 }
651 else
652 {
653 retVal = MAILBOX_EINVAL;
654 }
655 break;
656 case MAILBOX_INST_MCU2_1:
657 if (clusterId == 0 && userId == 3)
658 {
659 cfg->eventId = CSLR_R5FSS1_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_0_MAILBOX_CLUSTER_PEND_3;
660 }
661 else if (clusterId == 1 && userId == 3)
662 {
663 cfg->eventId = CSLR_R5FSS1_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_1_MAILBOX_CLUSTER_PEND_3;
664 }
665 else if (clusterId == 4 && userId == 1)
666 {
667 cfg->eventId = CSLR_R5FSS1_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_4_MAILBOX_CLUSTER_PEND_1;
668 }
669 else if (clusterId == 5 && userId == 1)
670 {
671 cfg->eventId = CSLR_R5FSS1_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_5_MAILBOX_CLUSTER_PEND_1;
672 }
673 else if (clusterId == 7 && userId == 1)
674 {
675 cfg->eventId = CSLR_R5FSS1_CORE1_INTR_MAILBOX0_MAILBOX_CLUSTER_7_MAILBOX_CLUSTER_PEND_1;
676 }
677 else
678 {
679 retVal = MAILBOX_EINVAL;
680 }
681 break;
682 case MAILBOX_INST_M4F_0:
683 if (clusterId == 6 && userId == 3)
684 {
685 cfg->eventId = CSLR_MCU_M4FSS0_CORE0_NVIC_MAILBOX0_MAILBOX_CLUSTER_6_MAILBOX_CLUSTER_PEND_3;
686 }
687 else if (clusterId == 7 && userId == 3)
688 {
689 cfg->eventId = CSLR_MCU_M4FSS0_CORE0_NVIC_MAILBOX0_MAILBOX_CLUSTER_7_MAILBOX_CLUSTER_PEND_3;
690 }
691 else
692 {
693 retVal = MAILBOX_EINVAL;
694 }
695 break;
696 default:
697 retVal = MAILBOX_EINVAL;
698 break;
699 }
701 cfg->priority = 1U;
703 return retVal;
704 }
706 #if defined(BUILD_MCU) && defined(VIM_DIRECT_REGISTRATION)
707 static inline void Mailbox_directClrNewMsgStatus(Mbox_Handle handle)
708 {
709 MailboxClrNewMsgStatus(((Mailbox_Driver *)handle)->baseAddrRx,
710 ((Mailbox_HwCfg *)((Mailbox_Driver *)handle)->hwCfg)->rx.user,
711 ((Mailbox_HwCfg *)((Mailbox_Driver *)handle)->hwCfg)->rx.fifo);
713 CSL_vimClrIntrPending((CSL_vimRegs *)(uintptr_t)TEST_VIM_BASE_ADDR,
714 ((Mailbox_HwCfg *)((Mailbox_Driver *)handle)->hwCfg)->eventId);
715 /* Acknowledge interrupt servicing */
716 CSL_vimAckIntr((CSL_vimRegs *)(uintptr_t)TEST_VIM_BASE_ADDR, \
717 (CSL_VimIntrMap)0u );
718 }
720 __attribute__((interrupt("IRQ"))) void mailboxIsr_0(void);
721 __attribute__((interrupt("IRQ"))) void mailboxIsr_1(void);
722 __attribute__((interrupt("IRQ"))) void mailboxIsr_2(void);
723 __attribute__((interrupt("IRQ"))) void mailboxIsr_3(void);
724 __attribute__((interrupt("IRQ"))) void mailboxIsr_4(void);
725 __attribute__((interrupt("IRQ"))) void mailboxIsr_5(void);
729 #ifdef __cplusplus
730 #pragma CODE_STATE (32)
731 #else
732 #pragma CODE_STATE (mailboxIsr_0,32)
733 #endif /* #ifdef __cplusplus */
734 void mailboxIsr_0(void)
735 {
736 (g_VimCallback[MAILBOX_INST_MPU1_0])(g_VimCallbackArg[MAILBOX_INST_MPU1_0], MAILBOX_INST_MPU1_0);
737 Mailbox_directClrNewMsgStatus(g_VimCallbackArg[MAILBOX_INST_MPU1_0]);
738 }
740 #ifdef __cplusplus
741 #pragma CODE_STATE (32)
742 #else
743 #pragma CODE_STATE (mailboxIsr_1,32)
744 #endif /* #ifdef __cplusplus */
745 void mailboxIsr_1(void)
746 {
747 (g_VimCallback[MAILBOX_INST_MCU1_0])(g_VimCallbackArg[MAILBOX_INST_MCU1_0], MAILBOX_INST_MCU1_0);
748 Mailbox_directClrNewMsgStatus(g_VimCallbackArg[MAILBOX_INST_MCU1_0]);
749 }
751 #ifdef __cplusplus
752 #pragma CODE_STATE (32)
753 #else
754 #pragma CODE_STATE (mailboxIsr_2,32)
755 #endif /* #ifdef __cplusplus */
756 void mailboxIsr_2(void)
757 {
758 (g_VimCallback[MAILBOX_INST_MCU1_1])(g_VimCallbackArg[MAILBOX_INST_MCU1_1], MAILBOX_INST_MCU1_1);
759 Mailbox_directClrNewMsgStatus(g_VimCallbackArg[MAILBOX_INST_MCU1_1]);
760 }
762 #ifdef __cplusplus
763 #pragma CODE_STATE (32)
764 #else
765 #pragma CODE_STATE (mailboxIsr_3,32)
766 #endif /* #ifdef __cplusplus */
767 void mailboxIsr_3(void)
768 {
769 (g_VimCallback[MAILBOX_INST_MCU2_0])(g_VimCallbackArg[MAILBOX_INST_MCU2_0], MAILBOX_INST_MCU2_0);
770 Mailbox_directClrNewMsgStatus(g_VimCallbackArg[MAILBOX_INST_MCU2_0]);
771 }
773 #ifdef __cplusplus
774 #pragma CODE_STATE (32)
775 #else
776 #pragma CODE_STATE (mailboxIsr_4,32)
777 #endif /* #ifdef __cplusplus */
778 void mailboxIsr_4(void)
779 {
780 (g_VimCallback[MAILBOX_INST_MCU2_1])(g_VimCallbackArg[MAILBOX_INST_MCU2_1], MAILBOX_INST_MCU2_1);
781 Mailbox_directClrNewMsgStatus(g_VimCallbackArg[MAILBOX_INST_MCU2_1]);
782 }
784 #ifdef __cplusplus
785 #pragma CODE_STATE (32)
786 #else
787 #pragma CODE_STATE (mailboxIsr_5,32)
788 #endif /* #ifdef __cplusplus */
789 void mailboxIsr_5(void)
790 {
791 (g_VimCallback[MAILBOX_INST_M4F_0])(g_VimCallbackArg[MAILBOX_INST_M4F_0], MAILBOX_INST_M4F_0);
792 Mailbox_directClrNewMsgStatus(g_VimCallbackArg[MAILBOX_INST_M4F_0]);
793 }
795 uintptr_t mailboxIsrArray[6] =
796 {
797 (uintptr_t)&mailboxIsr_0,
798 (uintptr_t)&mailboxIsr_1,
799 (uintptr_t)&mailboxIsr_2,
800 (uintptr_t)&mailboxIsr_3,
801 (uintptr_t)&mailboxIsr_4,
802 (uintptr_t)&mailboxIsr_5
803 };
804 #endif
806 void Mailbox_InternalCallbackFast(uintptr_t arg)
807 {
808 uint32_t idx = (uint32_t)arg;
809 Mbox_Handle handle = g_FastCallbackArg[idx];
811 (g_FastCallback[idx])(g_FastCallbackArg[idx], idx);
813 MailboxClrNewMsgStatus(((Mailbox_Driver *)handle)->baseAddrRx,
814 ((Mailbox_HwCfg *)((Mailbox_Driver *)handle)->hwCfg)->rx.user,
815 ((Mailbox_HwCfg *)((Mailbox_Driver *)handle)->hwCfg)->rx.fifo);
816 }
818 void Mailbox_InternalCallback(uintptr_t arg)
819 {
820 uint32_t n;
821 Mailbox_Data *mbox;
822 Mailbox_Fifo *fifo;
824 mbox = (Mailbox_Data *)arg;
825 if(mbox != NULL)
826 {
827 mbox->intCnt++;
828 /* Optimization to save time checking the fifo if only one is being used */
829 if (mbox->fifoCnt == 1U)
830 {
831 fifo = &mbox->fifoTable[0];
832 if (mbox->fifoTable[0].func)
833 {
834 /* Call the function with handle and arg */
835 (mbox->fifoTable[0].func)(fifo->handle, fifo->arg);
836 }
837 /* Clear new message status of Mailbox */
838 MailboxClrNewMsgStatus(mbox->baseAddr, mbox->userId, fifo->queueId);
839 }
840 else
841 {
842 for(n = 0; n < mbox->fifoCnt; n++)
843 {
844 fifo = &mbox->fifoTable[n];
846 if(0U != MailboxGetRawNewMsgStatus(mbox->baseAddr, mbox->userId, fifo->queueId))
847 {
848 if (mbox->fifoTable[n].func)
849 {
850 /* Call the function with handle and arg */
851 (mbox->fifoTable[n].func)(fifo->handle, fifo->arg);
852 }
853 /* Clear new message status of Mailbox */
854 MailboxClrNewMsgStatus(mbox->baseAddr, mbox->userId, fifo->queueId);
855 }
856 }
857 }
858 mbox->noMsgCnt++;
859 }
860 }
862 int32_t Mailbox_registerInterrupts(Mbox_Handle handle)
863 {
864 Mailbox_Driver *driver;
865 int32_t retVal = MAILBOX_SOK;
866 Mailbox_HwCfg *hwCfg = NULL;
867 uint32_t n;
868 Mailbox_Data *mbox = NULL;
869 Mailbox_MbConfig cfg;
870 Mailbox_Instance localEndpoint;
871 void *hwiHandle = NULL;
872 uint32_t i = 0;
873 Mailbox_Instance remoteEndpoint;
874 uint32_t q = 0;
876 driver = (Mailbox_Driver *)handle;
877 localEndpoint = driver->localEndpoint;
878 remoteEndpoint = driver->remoteEndpoint;
880 hwCfg = (Mailbox_HwCfg *)driver->hwCfg;
882 /* Get the mailbox base addr for RX cluster */
883 driver->baseAddrRx = Mailbox_getBaseAddr(hwCfg->rx.cluster);
884 driver->baseAddrTx = Mailbox_getBaseAddr(hwCfg->tx.cluster);
886 if ((driver->cfg.readMode != MAILBOX_MODE_POLLING) && (driver->cfg.readCallback != NULL))
887 {
888 if (gMailboxMCB.initParam.osalPrms.registerIntr == NULL)
889 {
890 retVal = MAILBOX_EINVAL;
891 }
893 if (retVal == MAILBOX_SOK)
894 {
895 /*
896 * check if this cluster and user ID is already registered, and if so,
897 * skip interrupt registration and just store callback/arg data for this
898 * fifo to be handled in the callback
899 */
900 for (n = 0; n < g_mBoxCnt; n++)
901 {
902 if ((driver->baseAddrRx == g_mBoxData[n].baseAddr) &&
903 (hwCfg->rx.user == g_mBoxData[n].userId))
904 break;
905 }
907 /* Get the MailBox Data */
908 mbox = &g_mBoxData[n];
910 if (n == g_mBoxCnt)
911 {
912 /* Could not find one, this is new entry */
913 mbox->baseAddr = driver->baseAddrRx;
914 mbox->fifoCnt = 0;
915 mbox->userId = hwCfg->rx.user;
917 /*
918 * Before we register for the interrupt, make sure that all the fifo
919 * new msg interrupts are disabled. This helps in case there is
920 * some stale state from previous run.
921 */
922 for (q = 0; q < MAILBOX_MAXFIFO_CNT; q++)
923 {
924 MailboxDisableNewMsgInt(driver->baseAddrRx, hwCfg->rx.user, q);
925 MailboxClrNewMsgStatus(driver->baseAddrRx, hwCfg->rx.user, q);
926 }
928 /* clear new msg status */
929 MailboxClrNewMsgStatus(driver->baseAddrRx, hwCfg->rx.user, hwCfg->rx.fifo);
931 /* Get the interrupt configuration */
932 retVal = Mailbox_getMailboxIntrRouterCfg(localEndpoint, hwCfg->rx.cluster, hwCfg->rx.user, &cfg, g_mBoxCnt);
933 if (retVal == MAILBOX_SOK)
934 {
935 hwCfg->eventId = cfg.eventId;
937 /* Register interrupts */
938 if ((hwCfg->exclusive == TRUE) && ((driver->cfg.readMode == MAILBOX_MODE_FAST)))
939 {
940 #if defined(BUILD_MCU) && defined(VIM_DIRECT_REGISTRATION)
941 if (driver->cfg.enableVIMDirectInterrupt == true)
942 {
943 g_VimCallback[remoteEndpoint] = driver->cfg.readCallback;
944 g_VimCallbackArg[remoteEndpoint] = driver;
946 hwiHandle = gMailboxMCB.initParam.osalPrms.registerDirectIntr((Mbox_OsalDirectIsrFxn)mailboxIsrArray[remoteEndpoint],
947 cfg.eventId,
948 cfg.priority);
949 }
950 #endif
951 if (hwiHandle == NULL)
952 {
953 /* Direct interrupt registration failed or isn't enabled, try regular registration */
954 g_FastCallback[remoteEndpoint] = driver->cfg.readCallback;
955 g_FastCallbackArg[remoteEndpoint] = driver;
956 hwiHandle = gMailboxMCB.initParam.osalPrms.registerIntr(Mailbox_InternalCallbackFast,
957 cfg.eventId,
958 cfg.priority,
959 (void *)remoteEndpoint,
960 (char *)"MAILBOX_NEW_MSG");
961 gMailboxMCB.hwiHandles.mailboxFull = hwiHandle;
962 if(hwiHandle == NULL)
963 {
964 //SystemP_printf("Mailbox_plugInterrupt : Failed to register ISR...\n");
965 }
966 }
967 }
968 else
969 {
970 hwiHandle = gMailboxMCB.initParam.osalPrms.registerIntr(Mailbox_InternalCallback,
971 cfg.eventId,
972 cfg.priority,
973 (void *)mbox,
974 (char *)"MAILBOX_NEW_MSG");
975 gMailboxMCB.hwiHandles.mailboxFull = hwiHandle;
976 if(hwiHandle == NULL)
977 {
978 //SystemP_printf("Mailbox_plugInterrupt : Failed to register ISR...\n");
979 }
980 }
981 g_mBoxCnt++;
982 }
983 }
984 }
986 if (retVal == MAILBOX_SOK)
987 {
988 /* Check if there is empty space in our fifoTable (for example if handle is closed and re-opened) */
989 for (i = 0; i < mbox->fifoCnt; i++)
990 {
991 if (mbox->fifoTable[i].func == NULL)
992 {
993 break;
994 }
995 }
997 /* Add the fifo data for the remoteProcId. */
998 mbox->fifoTable[i].cfgNdx = n;
999 mbox->fifoTable[i].func = driver->cfg.readCallback;
1000 mbox->fifoTable[i].arg = driver->remoteEndpoint;
1001 mbox->fifoTable[i].queueId = hwCfg->rx.fifo;
1002 mbox->fifoTable[i].handle = driver;
1003 gInstToMBoxDataMap[driver->remoteEndpoint] = (uintptr_t)mbox;
1005 if (i == mbox->fifoCnt)
1006 {
1007 mbox->fifoCnt++;
1008 }
1010 if (driver->cfg.enableInterrupts == true)
1011 {
1012 /* enable the mailbox interrupt */
1013 MailboxEnableNewMsgInt(driver->baseAddrRx, hwCfg->rx.user, hwCfg->rx.fifo);
1014 }
1015 }
1016 }
1018 return retVal;
1019 }
1021 int32_t Mailbox_unregisterInterrupts(Mbox_Handle handle)
1022 {
1023 Mailbox_Driver* driver;
1024 int32_t retVal = MAILBOX_SOK;
1025 Mailbox_HwCfg *hwCfg = NULL;
1026 Mailbox_Data *mbox = NULL;
1027 uint8_t i = 0;
1029 driver = (Mailbox_Driver *)handle;
1030 hwCfg = (Mailbox_HwCfg *)driver->hwCfg;
1032 if ((driver->cfg.readMode != MAILBOX_MODE_POLLING) && (driver->cfg.readCallback != NULL))
1033 {
1034 mbox = (Mailbox_Data *)gInstToMBoxDataMap[driver->remoteEndpoint];
1036 /* Disable the mailbox interrupt */
1037 MailboxDisableNewMsgInt(driver->baseAddrRx, hwCfg->rx.user, hwCfg->rx.fifo);
1039 /* Remove the callback info from the fifo table */
1040 gInstToMBoxDataMap[driver->remoteEndpoint] = (uintptr_t)NULL;
1042 for (i = 0; i < mbox->fifoCnt; i++)
1043 {
1044 if (mbox->fifoTable[i].queueId == hwCfg->rx.fifo)
1045 {
1046 /* clear the fifo info */
1047 mbox->fifoTable[i].cfgNdx = 0;
1048 mbox->fifoTable[i].func = NULL;
1049 mbox->fifoTable[i].arg = 0;
1050 mbox->fifoTable[i].queueId = 0;
1051 mbox->fifoTable[i].handle = NULL;
1052 }
1053 }
1054 }
1056 return retVal;
1057 }
1059 int32_t Mailbox_enableInterrupts(Mbox_Handle handle)
1060 {
1061 Mailbox_Driver* driver;
1062 int32_t retVal = MAILBOX_SOK;
1063 Mailbox_HwCfg *hwCfg = NULL;
1065 if (handle != NULL)
1066 {
1067 driver = (Mailbox_Driver *)handle;
1068 hwCfg = (Mailbox_HwCfg *)driver->hwCfg;
1070 if (hwCfg != NULL)
1071 {
1072 MailboxEnableNewMsgInt(driver->baseAddrRx, hwCfg->rx.user, hwCfg->rx.fifo);
1073 }
1074 else
1075 {
1076 retVal = MAILBOX_EINVAL;
1077 }
1078 }
1079 else
1080 {
1081 retVal = MAILBOX_EINVAL;
1082 }
1084 return retVal;
1085 }
1087 int32_t Mailbox_disableInterrupts(Mbox_Handle handle)
1088 {
1089 Mailbox_Driver* driver;
1090 int32_t retVal = MAILBOX_SOK;
1091 Mailbox_HwCfg *hwCfg = NULL;
1093 if (handle != NULL)
1094 {
1095 driver = (Mailbox_Driver *)handle;
1096 hwCfg = (Mailbox_HwCfg *)driver->hwCfg;
1098 if (hwCfg != NULL)
1099 {
1100 MailboxDisableNewMsgInt(driver->baseAddrRx, hwCfg->rx.user, hwCfg->rx.fifo);
1101 }
1102 else
1103 {
1104 retVal = MAILBOX_EINVAL;
1105 }
1106 }
1107 else
1108 {
1109 retVal = MAILBOX_EINVAL;
1110 }
1112 return retVal;
1113 }
1115 uint64_t Mailbox_defaultVirtToPhyFxn(const void *virtAddr)
1116 {
1117 return ((uint64_t) virtAddr);
1118 }
1120 void *Mailbox_defaultPhyToVirtFxn(uint64_t phyAddr)
1121 {
1122 #if defined (__aarch64__)
1123 uint64_t temp = phyAddr;
1124 #else
1125 /* R5 is 32-bit machine, need to truncate to avoid void * typecast error */
1126 uint32_t temp = (uint32_t) phyAddr;
1127 #endif
1129 #if defined (BUILD_M4F_0)
1130 temp = phyAddr + 0x40000000;
1131 #endif
1133 return ((void *) temp);
1134 }