d6f1a17246a3c4bc6b3e75d13db22efd454588e6
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / ipc / hlos / knl / arch / vayu / VAYUIpcInt.c
1 /*
2  *  @file   VAYUIpcInt.c
3  *
4  *  @brief      VAYU interrupt handling code.
5  *              Defines necessary functions for Interrupt Handling.
6  *
7  *
8  *  ============================================================================
9  *
10  *  Copyright (c) 2013, Texas Instruments Incorporated
11  *
12  *  Redistribution and use in source and binary forms, with or without
13  *  modification, are permitted provided that the following conditions
14  *  are met:
15  *
16  *  *  Redistributions of source code must retain the above copyright
17  *     notice, this list of conditions and the following disclaimer.
18  *
19  *  *  Redistributions in binary form must reproduce the above copyright
20  *     notice, this list of conditions and the following disclaimer in the
21  *     documentation and/or other materials provided with the distribution.
22  *
23  *  *  Neither the name of Texas Instruments Incorporated nor the names of
24  *     its contributors may be used to endorse or promote products derived
25  *     from this software without specific prior written permission.
26  *
27  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
31  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
34  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
37  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *  Contact information for paper mail:
39  *  Texas Instruments
40  *  Post Office Box 655303
41  *  Dallas, Texas 75265
42  *  Contact information:
43  *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
44  *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
45  *  ============================================================================
46  *
47  */
51 /* Standard headers */
52 #include <ti/syslink/Std.h>
54 /* OSAL headers */
55 #include <ti/syslink/utils/Trace.h>
56 #include <ti/syslink/utils/List.h>
57 #include <Bitops.h>
59 /* OSAL and utils headers */
60 #include <OsalIsr.h>
61 #include <_MultiProc.h>
62 #include <ti/ipc/MultiProc.h>
63 #include <ti/syslink/utils/Memory.h>
64 #include <ti/syslink/utils/Gate.h>
65 #include <ti/syslink/utils/GateMutex.h>
67 /* Hardware Abstraction Layer */
68 #include <_ArchIpcInt.h>
69 #include <_VAYUIpcInt.h>
70 #include <VAYUIpcInt.h>
71 #include <errno.h>
74 #if defined (__cplusplus)
75 extern "C" {
76 #endif
78 /* From TableInit.xs in packages/ti/sdo/ipc/family/vayu: */
79 /*
80  * src     dst     mbox userid  subidx
81  * IPU1_0  DSP1    5    0       3
82  * HOST    DSP1    5    0       5
83  * IPU1_1  DSP1    5    0       8
84  * DSP1    IPU1_0  5    1       0
85  * HOST    IPU1_0  5    1       6
86  * DSP1    HOST    5    2       1
87  * IPU1_0  HOST    5    2       4
88  * IPU1_1  HOST    5    2       9
89  * DSP1    IPU1_1  5    3       2
90  * HOST    IPU1_1  5    3       7
91  * IPU2_0  DSP2    6    0       3
92  * HOST    DSP2    6    0       5
93  * IPU2_1  DSP2    6    0       8
94  * DSP2    IPU2_0  6    1       0
95  * HOST    IPU2_0  6    1       6
96  * DSP2    HOST    6    2       1
97  * IPU2_0  HOST    6    2       4
98  * IPU2_1  HOST    6    2       9
99  * DSP2    IPU2_1  6    3       2
100  * HOST    IPU2_1  6    3       7
101  */
103 /* =============================================================================
104  *  Macros and types
105  * =============================================================================
106  */
108 /*!
109  *  @def    VAYU_VAYU_NUMPROCS
110  *  @brief  Number of processors supported on this platform
111  */
112 #define VAYU_NUMPROCS 9
113 /*!
114  *  @def    VAYU_VAYU_INDEX_DSP
115  *  @brief  Dsp index.
116  */
117 #define VAYU_INDEX_DSP1 6
118 /*!
119  *  @def    VAYU_INDEX_VIDEOM4
120  *  @brief  M4Video index.
121  */
122 #define VAYU_INDEX_VIDEOM4 1
123 /*!
124  *  @def    VAYU_INDEX_IPU2
125  *  @brief  M4Dss index.
126  */
127 #define VAYU_INDEX_IPU2 1
128 /*!
129  *  @def    VAYU_INDEX_HOST
130  *  @brief  HOST index.
131  */
132 #define VAYU_INDEX_HOST 0
134 /*!
135  *  @def    VAYU_HOST_IPU2_MBOX
136  *  @brief  Mailbox used for HOST<->IPU2 communication.
137  */
138 #define VAYU_HOST_IPU2_MBOX 6
140 /*!
141  *  @def    IPU2_HOST_SUB_MBOX
142  *  @brief  Sub-Mailbox used for HOST->IPU2 communication.
143  */
144 #define IPU2_HOST_SUB_MBOX  4
146 /*!
147  *  @def    HOST_IPU2_SUB_MBOX
148  *  @brief  Sub-Mailbox used for IPU2->HOST communication.
149  */
150 #define HOST_IPU2_SUB_MBOX  6
152 /*!
153  *  @def    VAYU_HOST_DSP1_2_MBOX
154  *  @brief  Mailbox used for HOST<->DSP1 communication.
155  */
156 #define VAYU_HOST_DSP1_MBOX 5
158 /*!
159  *  @def    DSP1_HOST_SUB_MBOX
160  *  @brief  Mailbox used for DSP1->HOST communication.
161  */
162 #define DSP1_HOST_SUB_MBOX  1
164 /*!
165  *  @def    HOST_DSP1_SUB_MBOX
166  *  @brief  Mailbox used for HOST->DSP1 communication.
167  */
168 #define HOST_DSP1_SUB_MBOX  5
170 /*!
171  *  @def    VAYU_HOST_USER_ID
172  *  @brief  User ID of HOST.
173  */
174 #define VAYU_HOST_USER_ID 2
176 /*!
177  *  @def    VAYU_IPU2_USER_ID
178  *  @brief  User ID of IPU2.
179  */
180 #define VAYU_IPU2_USER_ID 1
182 /*!
183  *  @def    VAYU_DSP1_USER_ID
184  *  @brief  User ID of DSP1.
185  */
186 #define VAYU_DSP1_USER_ID 0
188 /* Macro to make a correct module magic number with refCount */
189 #define VAYUIPCINT_MAKE_MAGICSTAMP(x) \
190                                     ((VAYUIPCINT_MODULEID << 12u) | (x))
192 /*!
193  *  @def    REG
194  *  @brief  Regsiter access method.
195  */
196 #define REG(x)          *((volatile UInt32 *) (x))
197 #define REG32(x)        (*(volatile UInt32 *) (x))
199 /* Register access method. */
200 #define REG16(A)        (*(volatile UInt16 *) (A))
202 /*!
203  *  @def    AINTC_BASE_ADDR
204  *  @brief  configuraion address.
205  */
206 #define AINTC_BASE_ADDR                 0x48200000
208 /*!
209  *  @def    AINTC_BASE_SIZE
210  *  @brief  size to be ioremapped.
211  */
212 #define AINTC_BASE_SIZE                 0x1000
214 /*!
215  *  @def    CTRL_MODULE_BASE
216  *  @brief  configuration address.
217  */
218 #define CTRL_MODULE_BASE                 0x4A002000
220 /*!
221  *  @def    CTRL_MODULE_SIZE
222  *  @brief  size to be ioremapped.
223  */
224 #define CTRL_MODULE_SIZE                 0x1000
226 /*!
227  *  @def    CTRL_MODULE_MMR_OFFSET
228  *  @brief  offset in ctrl module to MMR LOCK reg.
229  */
230 #define CTRL_MODULE_MMR_OFFSET           0x544
232 /*!
233  *  @def    CTRL_MODULE_MPU_OFFSET
234  *  @brief  offset in ctrl module to MPU INTs.
235  */
236 #define CTRL_MODULE_MPU_OFFSET           0xA4C
238 /*!
239  *  @def    CTRL_MODULE_INT_BASE
240  *  @brief  interrupt num at offset.
241  */
242 #define CTRL_MODULE_INT_BASE             0x8
244 /*!
245  *  @def    CTRL_MODULE_INT_m_OFFSET
246  *  @brief  interrupt num at offset.
247  */
248 #define CTRL_MODULE_INT_m_OFFSET(m)      CTRL_MODULE_MPU_OFFSET + \
249                                          ((((m) - CTRL_MODULE_INT_BASE) / 2) * 4) - \
250                                          (((m) > 131) ? 4 : 0)
252 /*!
253  *  @def    IRQ_XBAR_MBOX_6_USR_2
254  *  @brief  irq xbar num for mailbox 6 user 2.
255  */
256 #define IRQ_XBAR_MBOX_6_USR_2            255
258 /*!
259  *  @def    IRQ_XBAR_MBOX_5_USR_2
260  *  @brief  irq xbar num for mailbox 5 user 2.
261  */
262 #define IRQ_XBAR_MBOX_5_USR_2            251
264 /*!
265  *  @def    IRQ_XBAR_DSP1
266  *  @brief  irq xbar num for dsp1.
267  */
268 #define IRQ_XBAR_DSP1                    IRQ_XBAR_MBOX_5_USR_2
270 /*!
271  *  @def    IRQ_XBAR_IPU2
272  *  @brief  irq xbar num for ipu2.
273  */
274 #define IRQ_XBAR_IPU2                    IRQ_XBAR_MBOX_6_USR_2
276 /* Mailbox management values */
277 /*!
278  *  @def    VAYU_MAILBOX_5_BASE
279  *  @brief  configuraion address.
280  */
281 #define MAILBOX_5_BASE                   0x48840000
283 /*!
284  *  @def    VAYU_MAILBOX_6_BASE
285  *  @brief  configuraion address.
286  */
287 #define MAILBOX_6_BASE                   0x48842000
289 /*!
290  *  @def    MAILBOX_SIZE
291  *  @brief  size to be ioremapped.
292  */
293 #define MAILBOX_SIZE                     0x1000
295 /*!
296  *  @def    MAILBOX_SYSCONFIG_OFFSET
297  *  @brief  Offset from the Mailbox base address.
298  */
299 #define MAILBOX_SYSCONFIG_OFFSET      0x10
301 /*!
302  *  @def    MAILBOX_MAXNUM
303  *  @brief  maximum number of mailbox.
304  */
305 #define MAILBOX_MAXNUM                   0xC
307 /*!
308  *  @def    MAILBOX_MESSAGE_m_OFFSET
309  *  @brief  mailbox message address Offset from the Mailbox base
310  *          address. m = 0 to 7 => offset = 0x40 + 0x4*m
311  */
312 #define MAILBOX_MESSAGE_m_OFFSET(m)        (0x40 + (m<<2))
314 /*!
315  *  @def    MAILBOX_MSGSTATUS_m_OFFSET
316  *  @brief  mailbox message status address Offset from the Mailbox base
317  *          address. m = 0 to 7 => offset = 0x40 + 0x4*m
318  */
319 #define MAILBOX_MSGSTATUS_m_OFFSET(m)        (0xC0 + (m<<2))
321 /*!
322  *  @def    MAILBOX_IRQSTATUS_CLEAR_OFFSET
323  *  @brief  mailbox IRQSTATUS clear address Offset from the Mailbox base
324  *          address.
325  */
326 #define MAILBOX_IRQSTATUS_CLEAR_OFFSET  0x104
328 /*!
329  *  @def    MAILBOX_IRQENABLE_SET_OFFSET
330  *  @brief  mailbox IRQ enable set address Offset from the Mailbox base
331  *          address.
332  */
333 #define MAILBOX_IRQENABLE_SET_OFFSET    0x108
334 /*!
335  *  @def    MAILBOX_IRQENABLE_CLR_OFFSET
336  *  @brief  mailbox IRQ enable clear address Offset from the Mailbox base
337  *          address.
338  */
339 #define MAILBOX_IRQENABLE_CLR_OFFSET    0x10C
342 /* Macro used when saving the mailbox context */
343 #define VAYU_MAILBOX_IRQENABLE(u)    (0x108 + 0x10 * (u))
345 /* Msg elem used to store messages from the remote proc */
346 typedef struct VAYUIpcInt_MsgListElem_tag {
347     List_Elem elem;
348     UInt32 msg;
349     struct VAYUIpcInt_MsgListElem * next;
350     struct VAYUIpcInt_MsgListElem * prev;
351 } VAYUIpcInt_MsgListElem;
353 /* Msg elem used to store isrHandles */
354 typedef struct VAYUIpcInt_isrHandleElem_tag {
355     List_Elem      elem;
356     OsalIsr_Handle isrHandle;
357     UInt32         intId;
358     Atomic         refCount;
359 } VAYUIpcInt_isrHandleElem;
361 /*!
362  *  @brief  Device specific object
363  *          It can be populated as per device need and it is used internally in
364  *          the device specific implementation only.
365  */
366 typedef struct VAYUIpcInt_Object_tag {
367     Atomic                 isrRefCount;
368     /*!< ISR Reference count */
369     Atomic                 asserted;
370     /*!< Indicates receipt of interrupt from particular processor */
371     UInt32                 recvIntId;
372     /*!<recevive interrupt id */
373     ArchIpcInt_CallbackFxn fxn;
374     /*!< Callbck function to be registered for particular instance of driver*/
375     Ptr                    fxnArgs;
376     /*!< Argument to the call back function */
377     List_Elem             * isrHandle;
378     /*!< isrHandle */
379 } VAYUIpcInt_Object;
382 /*!
383  *  @brief  Device specific object
384  *          It can be populated as per device need and it is used internally in
385  *          the device specific implementation only.
386  */
387 typedef struct VAYUIpcInt_ModuleObject_tag {
388     Atomic             isrRefCount;
389     /*!< ISR Reference count */
390     //OsalIsr_Handle     isrHandle;
391     List_Handle        isrHandles;
392     /*!< Handle to the OsalIsr object */
393     UInt16             procIds [VAYU_NUMPROCS];
394     /*!< Processors supported */
395     UInt16             maxProcessors;
396     /*!< Maximum number of processors supported by this platform*/
397     VAYUIpcInt_Object isrObjects [MultiProc_MAXPROCESSORS];
398     /*!< Array of Isr objects */
399     List_Handle isrLists [MultiProc_MAXPROCESSORS];
400     /*!< Array of Isr lists */
401     UInt32         archCoreCmBase;
402     /*!< configuration mgmt base */
403     UInt32         mailbox5Base;
404     /*!< mail box configuration mgmt base */
405     UInt32         mailbox6Base;
406     /*!< mail box configuration mgmt base */
407     UInt32         controlModuleBase;
408     /*!< control module base */
409     UInt32         intId;
410     /*!< interrupt id for this proc */
411 } VAYUIpcInt_ModuleObject;
415 /* =============================================================================
416  * Forward declarations of internal functions.
417  * =============================================================================
418  */
419 /* This function implements the interrupt service routine for the interrupt
420  * received from the remote processor.
421  */
422 static Bool _VAYUIpcInt_isr (Ptr ref);
424 /*!
425  *  @brief  Forward declaration of check and clear function
426  */
427 static Bool _VAYUIpcInt_checkAndClearFunc (Ptr arg);
430 /* =============================================================================
431  *  Globals
432  * =============================================================================
433  */
434 /*!
435  *  @brief  State object for VAYUIpcInt
436  */
437 VAYUIpcInt_ModuleObject VAYUIpcInt_state;
439 /*!
440  *  @brief  Function table for OMAP3530
441  */
442 ArchIpcInt_FxnTable VAYUIpcInt_fxnTable = {
443     VAYUIpcInt_interruptRegister,
444     VAYUIpcInt_interruptUnregister,
445     VAYUIpcInt_interruptEnable,
446     VAYUIpcInt_interruptDisable,
447     VAYUIpcInt_waitClearInterrupt,
448     VAYUIpcInt_sendInterrupt,
449     VAYUIpcInt_clearInterrupt,
450 };
452 int mailbox_5_context[MAILBOX_SIZE];
453 int mailbox_6_context[MAILBOX_SIZE];
455 /* =============================================================================
456  *  APIs
457  * =============================================================================
458  */
460 /*!
461  *  @brief      Function to initialize the VAYUIpcInt module.
462  *
463  *  @param      cfg  Configuration for setup
464  *
465  *  @sa         VAYUIpcInt_destroy
466  */
467 Void
468 VAYUIpcInt_setup (VAYUIpcInt_Config * cfg)
470 #if !defined(SYSLINK_BUILD_OPTIMIZE)
471     Int            status = VAYUIPCINT_SUCCESS;
472 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
473     Int i = 0;
474     Memory_MapInfo mapInfo;
475     List_Params listParams;
477     GT_1trace (curTrace, GT_ENTER, "VAYUIpcInt_setup", cfg);
479     GT_assert (curTrace, (cfg != NULL));
481     /* The setup will be called only once, either from SysMgr or from
482      * archipcvayu module. Hence it does not need to be atomic.
483      */
484 #if !defined(SYSLINK_BUILD_OPTIMIZE)
485     if (cfg == NULL) {
486         GT_setFailureReason (curTrace,
487                         GT_4CLASS,
488                         "VAYUIpcInt_setup",
489                         VAYUIPCINT_E_FAIL,
490                         "config for driver specific setup can not be NULL");
491     }
492     else {
493 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
495         /* Map general control base */
496         mapInfo.src      = AINTC_BASE_ADDR;
497         mapInfo.size     = AINTC_BASE_SIZE;
498         mapInfo.isCached = FALSE;
499 #if !defined(SYSLINK_BUILD_OPTIMIZE)
500         status =
501 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
502         Memory_map (&mapInfo);
503 #if !defined(SYSLINK_BUILD_OPTIMIZE)
504         if (status < 0) {
505             GT_setFailureReason (curTrace,
506                                  GT_4CLASS,
507                                  "VAYUIpcInt_setup",
508                                  status,
509                                  "Failure in Memory_map for general ctrl base");
510             VAYUIpcInt_state.archCoreCmBase = 0;
511         }
512         else {
513 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
514             VAYUIpcInt_state.archCoreCmBase = mapInfo.dst;
515             /* Map mailbox5Base */
516             mapInfo.src      = MAILBOX_5_BASE;
517             mapInfo.size     = MAILBOX_SIZE;
518             mapInfo.isCached = FALSE;
519  #if !defined(SYSLINK_BUILD_OPTIMIZE)
520             status =
521 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
522                 Memory_map (&mapInfo);
523 #if !defined(SYSLINK_BUILD_OPTIMIZE)
524             if (status < 0) {
525                 GT_setFailureReason (curTrace,
526                                      GT_4CLASS,
527                                      "VAYUIpcInt_setup",
528                                      status,
529                                      "Failure in Memory_map for mailbox5Base");
530                 VAYUIpcInt_state.mailbox5Base = 0;
531             }
532             else {
533 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
534                 VAYUIpcInt_state.mailbox5Base = mapInfo.dst;
535                 /* Map mailbox5Base */
536                 mapInfo.src      = MAILBOX_6_BASE;
537                 mapInfo.size     = MAILBOX_SIZE;
538                 mapInfo.isCached = FALSE;
539 #if !defined(SYSLINK_BUILD_OPTIMIZE)
540                 status =
541 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
542                     Memory_map (&mapInfo);
543 #if !defined(SYSLINK_BUILD_OPTIMIZE)
544                 if (status < 0) {
545                     GT_setFailureReason (curTrace,
546                                          GT_4CLASS,
547                                          "VAYUIpcInt_setup",
548                                          status,
549                                          "Failure in Memory_map for mailbox6Base");
550                     VAYUIpcInt_state.mailbox6Base = 0;
551                 }
552                 else {
553 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
554                     VAYUIpcInt_state.mailbox6Base = mapInfo.dst;
555                     /* Map mailbox5Base */
556                     mapInfo.src      = CTRL_MODULE_BASE;
557                     mapInfo.size     = CTRL_MODULE_SIZE;
558                     mapInfo.isCached = FALSE;
559 #if !defined(SYSLINK_BUILD_OPTIMIZE)
560                     status =
561 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
562                         Memory_map (&mapInfo);
563 #if !defined(SYSLINK_BUILD_OPTIMIZE)
564                     if (status < 0) {
565                         GT_setFailureReason (curTrace,
566                                              GT_4CLASS,
567                                              "VAYUIpcInt_setup",
568                                              status,
569                                              "Failure in Memory_map for mailbox6Base");
570                         VAYUIpcInt_state.controlModuleBase = 0;
571                     }
572                     else {
573 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
574                         VAYUIpcInt_state.controlModuleBase = mapInfo.dst;
576                         /* Program the MMR lock registers to access the SCM
577                          * IRQ crossbar register address range */
578                         REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_MMR_OFFSET) = 0xF757FDC0;
580                         /* Reset Mailbox 5 */
581                         REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) =
582                             REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
583                         while (REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
584                         /*Set Mailbox to Smart Idle */
585                         REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
586                         /* Reset Mailbox 6 */
587                         REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) =
588                             REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
589                         while (REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
590                         /*Set Mailbox to Smart Idle */
591                         REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
592 #if !defined(SYSLINK_BUILD_OPTIMIZE)
593                     }
594                 }
595             }
596         }
597         if (status >= 0) {
598             /*Registering vayu platform with ArchIpcInt*/
599 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
600             ArchIpcInt_object.fxnTable = &VAYUIpcInt_fxnTable;
601             ArchIpcInt_object.obj      = &VAYUIpcInt_state;
603             for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
604                 Atomic_set (&(VAYUIpcInt_state.isrObjects [i].asserted), 1);
605                 List_Params_init(&listParams);
606                 VAYUIpcInt_state.isrLists [i] = List_create(&listParams);
607                 if (VAYUIpcInt_state.isrLists [i] == NULL) {
608                     status = VAYUIPCINT_E_MEMORY;
609                     GT_setFailureReason (curTrace,
610                                          GT_4CLASS,
611                                          "VAYUIpcInt_setup",
612                                          status,
613                                          "Failure in List_create");
614                     for (i = i - 1; i >= 0; i--) {
615                         List_delete(&VAYUIpcInt_state.isrLists [i]);
616                     }
617                     break;
618                 }
619             }
621             List_Params_init(&listParams);
622             VAYUIpcInt_state.isrHandles = List_create(&listParams);
624             /* Calling MultiProc APIs here in setup save time in ISR and makes
625              * it small and fast with less overhead.  This can be done
626              * regardless of status.
627              */
628             VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] =
629                                                        MultiProc_getId ("DSP1");
630             VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] =
631                                                     MultiProc_getId ("IPU2");
632             VAYUIpcInt_state.maxProcessors = MultiProc_getNumProcessors();
634             if (status >= 0) {
635                 ArchIpcInt_object.isSetup  = TRUE;
636             }
637 #if !defined(SYSLINK_BUILD_OPTIMIZE)
638         }
639     }
640 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
642     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_setup");
646 /*!
647  *  @brief      Function to finalize the VAYUIpcInt module
648  *
649  *  @sa         VAYUIpcInt_setup
650  */
651 Void
652 VAYUIpcInt_destroy (Void)
654     Memory_UnmapInfo unmapInfo;
655     UInt32 i = 0;
656     List_Elem * elem = NULL, * temp = NULL;
658     GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
660     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
662     ArchIpcInt_object.isSetup  = FALSE;
663     ArchIpcInt_object.obj      = NULL;
664     ArchIpcInt_object.fxnTable = NULL;
666     for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
667         if (VAYUIpcInt_state.isrLists [i]) {
668             List_delete(&VAYUIpcInt_state.isrLists [i]);
669         }
670     }
672     List_traverse_safe(elem, temp, VAYUIpcInt_state.isrHandles) {
673         Memory_free(NULL, elem, sizeof(VAYUIpcInt_isrHandleElem));
674     }
675     List_delete(&VAYUIpcInt_state.isrHandles);
677     if (VAYUIpcInt_state.archCoreCmBase != (UInt32) NULL) {
678         unmapInfo.addr = VAYUIpcInt_state.archCoreCmBase;
679         unmapInfo.size = AINTC_BASE_SIZE;
680         unmapInfo.isCached = FALSE;
681         Memory_unmap (&unmapInfo);
682         VAYUIpcInt_state.archCoreCmBase = (UInt32) NULL;
683     }
685     if (VAYUIpcInt_state.mailbox5Base != (UInt32) NULL) {
686         unmapInfo.addr = VAYUIpcInt_state.mailbox5Base;
687         unmapInfo.size = MAILBOX_SIZE;
688         unmapInfo.isCached = FALSE;
689         Memory_unmap (&unmapInfo);
690         VAYUIpcInt_state.mailbox5Base = (UInt32) NULL;
691     }
693     if (VAYUIpcInt_state.mailbox6Base != (UInt32) NULL) {
694         unmapInfo.addr = VAYUIpcInt_state.mailbox6Base;
695         unmapInfo.size = MAILBOX_SIZE;
696         unmapInfo.isCached = FALSE;
697         Memory_unmap (&unmapInfo);
698         VAYUIpcInt_state.mailbox6Base = (UInt32) NULL;
699     }
701     if (VAYUIpcInt_state.controlModuleBase != (UInt32) NULL) {
702         unmapInfo.addr = VAYUIpcInt_state.controlModuleBase;
703         unmapInfo.size = CTRL_MODULE_SIZE;
704         unmapInfo.isCached = FALSE;
705         Memory_unmap (&unmapInfo);
706         VAYUIpcInt_state.archCoreCmBase = (UInt32) NULL;
707     }
709     GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
713 /*!
714  *  @brief      Function to register the interrupt.
715  *
716  *  @param      procId  destination procId.
717  *  @param      intId   interrupt id.
718  *  @param      fxn     callback function to be called on receiving interrupt.
719  *  @param      fxnArgs arguments to the callback function.
720  *
721  *  @sa         VAYUIpcInt_interruptEnable
722  */
724 Int32
725 VAYUIpcInt_interruptRegister  (UInt16                     procId,
726                                UInt32                     intId,
727                                ArchIpcInt_CallbackFxn     fxn,
728                                Ptr                        fxnArgs)
730     Int32 status = VAYUIPCINT_SUCCESS;
731     OsalIsr_Params isrParams;
732     OsalIsr_Handle isrHandle;
733     List_Elem * elem = NULL;
734     UInt32 reg = 0;
735     UInt32 mboxId = 0;
737     GT_4trace (curTrace,
738                GT_ENTER,
739                "VAYUIpcInt_interruptRegister",
740                procId,
741                intId,
742                fxn,
743                fxnArgs);
745     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
746     GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
747     GT_assert(curTrace, (fxn != NULL));
750     /* This sets the refCount variable if not initialized, upper 16 bits is
751      * written with module Id to ensure correctness of refCount variable.
752      */
753     Atomic_cmpmask_and_set (
754                             &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
755                             VAYUIPCINT_MAKE_MAGICSTAMP(0),
756                             VAYUIPCINT_MAKE_MAGICSTAMP(0));
758     /* This is a normal use-case, so should not be inside
759      * SYSLINK_BUILD_OPTIMIZE.
760      */
761     if (Atomic_inc_return (&VAYUIpcInt_state.isrObjects [procId].isrRefCount)
762             != VAYUIPCINT_MAKE_MAGICSTAMP(1u)) {
763         /*! @retval VAYUIPCINT_S_ALREADYREGISTERED ISR already registered!
764          */
765             status = VAYUIPCINT_S_ALREADYREGISTERED;
766         GT_0trace (curTrace,
767                    GT_2CLASS,
768                    "ISR already registered!");
769     }
770     else {
771         VAYUIpcInt_state.isrObjects [procId].fxn       = fxn;
772         VAYUIpcInt_state.isrObjects [procId].fxnArgs   = fxnArgs;
773         VAYUIpcInt_state.isrObjects [procId].recvIntId = intId;
774         /* Enable hardware interrupt. */
775         VAYUIpcInt_interruptEnable (procId, intId);
776     }
778     isrParams.sharedInt        = FALSE;
779     isrParams.checkAndClearFxn = &_VAYUIpcInt_checkAndClearFunc;
780     isrParams.fxnArgs          = NULL;
781     isrParams.intId            = intId;
783     /* Check if handle is already created/installed */
784     List_traverse(elem, VAYUIpcInt_state.isrHandles) {
785         if (((VAYUIpcInt_isrHandleElem *)elem)->intId == intId) {
786             Atomic_inc_return (&((VAYUIpcInt_isrHandleElem *)elem)->refCount);
787             status = VAYUIPCINT_S_ALREADYREGISTERED;
788             GT_0trace (curTrace,
789                        GT_2CLASS,
790                        "ISR already set !");
791             break;
792         }
793     }
794     if (elem == &((List_Object *)VAYUIpcInt_state.isrHandles)->elem) {
795         if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
796             mboxId = IRQ_XBAR_DSP1;
797         }
798         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]){
799             mboxId = IRQ_XBAR_IPU2;
800         }
802         /* Program the IntXbar */
803         reg = REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32)));
804         if (((intId - 32) - CTRL_MODULE_INT_BASE) % 2) {
805             REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
806                 (reg & 0x0000FFFF) | (mboxId << 16);
807         }
808         else {
809             REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
810                 (reg & 0xFFFF0000) | (mboxId);
811         }
812         isrHandle = OsalIsr_create (&_VAYUIpcInt_isr, NULL, &isrParams);
813 #if !defined(SYSLINK_BUILD_OPTIMIZE)
814         if (isrHandle == NULL) {
815             /*! @retval VAYUIPCINT_E_FAIL OsalIsr_create failed */
816             status = VAYUIPCINT_E_FAIL;
817             GT_setFailureReason (curTrace,
818                                  GT_4CLASS,
819                                  "VAYUIpcInt_interruptRegister",
820                                  status,
821                                  "OsalIsr_create failed");
822         }
823         else {
824 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
825             status = OsalIsr_install (isrHandle);
826 #if !defined(SYSLINK_BUILD_OPTIMIZE)
827             if (status < 0) {
828                 GT_setFailureReason (curTrace,
829                                      GT_4CLASS,
830                                      "VAYUIpcInt_interruptRegister",
831                                      status,
832                                      "OsalIsr_install failed");
833             }
834             else {
835 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
836                 elem = Memory_alloc(NULL, sizeof(VAYUIpcInt_isrHandleElem),
837                                     0, NULL);
838 #if !defined(SYSLINK_BUILD_OPTIMIZE)
839                 if (elem == NULL) {
840                     status = VAYUIPCINT_E_MEMORY;
841                     GT_setFailureReason (curTrace,
842                                          GT_4CLASS,
843                                          "VAYUIpcInt_interruptRegister",
844                                          status,
845                                          "Memory_alloc failed");
846                 }
847                 else {
848 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
849                     ((VAYUIpcInt_isrHandleElem *)elem)->isrHandle = isrHandle;
850                     Atomic_cmpmask_and_set (
851                               &((VAYUIpcInt_isrHandleElem *)elem)->refCount,
852                               VAYUIPCINT_MAKE_MAGICSTAMP(0),
853                               VAYUIPCINT_MAKE_MAGICSTAMP(1));
854                     ((VAYUIpcInt_isrHandleElem *)elem)->intId = intId;
855                     List_put(VAYUIpcInt_state.isrHandles, elem);
856 #if !defined(SYSLINK_BUILD_OPTIMIZE)
857                 }
858             }
859         }
860 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
861     }
863 #if !defined(SYSLINK_BUILD_OPTIMIZE)
864     if (status >= 0) {
865 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
866         VAYUIpcInt_state.isrObjects [procId].isrHandle = elem;
868         /* Clear the messages in the IPU2->HOST mailbox */
869         while (REG32(VAYUIpcInt_state.mailbox6Base + \
870                      MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX))) {
871             VAYUIpcInt_clearInterrupt(
872                              VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
873                              IPU2_HOST_SUB_MBOX);
874         }
875         /* Clear the messages in the HOST->IPU2 mailbox */
876         while (REG32(VAYUIpcInt_state.mailbox6Base + \
877                      MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX))) {
878             VAYUIpcInt_clearInterrupt(
879                              VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
880                              HOST_IPU2_SUB_MBOX);
881         }
882         /* Clear the messages in the DSP1->HOST mailbox */
883         while (REG32(VAYUIpcInt_state.mailbox5Base + \
884                      MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX))) {
885             VAYUIpcInt_clearInterrupt(
886                              VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
887                              DSP1_HOST_SUB_MBOX);
888         }
889         /* Clear the messages in the HOST->DSP1 mailbox */
890         while (REG32(VAYUIpcInt_state.mailbox5Base + \
891                      MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX))) {
892             VAYUIpcInt_clearInterrupt(
893                              VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
894                              HOST_DSP1_SUB_MBOX);
895         }
896         /* The below seems to be needed for OMAP5 Virtio for
897          * slaying/restarting syslink properly
898          */
899         /* Disables interrupts from HOST->IPU2 */
900         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
901                     MAILBOX_IRQENABLE_CLR_OFFSET + \
902                     (0x10 * VAYU_IPU2_USER_ID)),
903                 ((HOST_IPU2_SUB_MBOX) << 1));
904         /* Disables interrupts from HOST->DSP1 */
905         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
906                     MAILBOX_IRQENABLE_CLR_OFFSET + \
907                     (0x10 * VAYU_DSP1_USER_ID)),
908                 ((HOST_DSP1_SUB_MBOX) << 1));
910         /* Set mailbox to smart-idle */
911         REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
912         REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
913 #if !defined(SYSLINK_BUILD_OPTIMIZE)
914     }
915 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
917     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptRegister", status);
919     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully registered */
920     return status;
923 /*!
924  *  @brief      Function to Save context.
925  *
926  *  @param      procId  The procId associated with the mailbox context being
927  *                      saved.
928  *
929  *  @sa         VAYUIpcInt_mbxRestoreCtxt
930  */
932 Int32
933 VAYUIpcInt_mboxSaveCtxt (UInt16 procId)
935     Int32 status = VAYUIPCINT_SUCCESS;
936     UInt32 i = 0;
938     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] &&
939         VAYUIpcInt_state.mailbox5Base == NULL) {
940         status = VAYUIPCINT_E_MEMORY;
941         GT_setFailureReason (curTrace,
942                              GT_4CLASS,
943                              "VAYUIpcInt_mboxSaveCtxt",
944                              status,
945                              "Unable to map the Mailbox memory in SaveCtxt");
946     }
947     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] &&
948         VAYUIpcInt_state.mailbox6Base == NULL) {
949         status = VAYUIPCINT_E_MEMORY;
950         GT_setFailureReason (curTrace,
951                              GT_4CLASS,
952                              "VAYUIpcInt_mboxSaveCtxt",
953                              status,
954                              "Unable to map the Mailbox memory in SaveCtxt");
955     }
956     else {
957         if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
958             for (i = 0; i < 4; i++) {
959                 mailbox_5_context[i] = REG32(VAYUIpcInt_state.mailbox5Base + \
960                                              VAYU_MAILBOX_IRQENABLE(i));
961             }
962         }
963         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
964             for (i = 0; i < 4; i++) {
965                 mailbox_6_context[i] = REG32(VAYUIpcInt_state.mailbox6Base + \
966                                              VAYU_MAILBOX_IRQENABLE(i));
967             }
968         }
969         VAYUIpcInt_interruptDisable(procId, VAYUIpcInt_state.intId);
970     }
971     return status;
974 /*!
975  *  @brief      Function to Restore context.
976  *
977  *  @param      procId  The procId associated with the mailbox context being
978  *                      restored.
979  *
980  *  @sa         VAYUIpcInt_mbxSaveCtxt
981  */
983 Int32
984 VAYUIpcInt_mboxRestoreCtxt (UInt16 procId)
986     Int32 status = VAYUIPCINT_SUCCESS;
987     UInt32 i = 0;
989     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] &&
990         VAYUIpcInt_state.mailbox5Base == NULL) {
991         status = VAYUIPCINT_E_MEMORY;
992         GT_setFailureReason (curTrace,
993                              GT_4CLASS,
994                              "VAYUIpcInt_mboxRestoreCtxt",
995                              status,
996                              "Unable to map the Mailbox memory in RestoreCtxt");
997     }
998     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] &&
999         VAYUIpcInt_state.mailbox6Base == NULL) {
1000         status = VAYUIPCINT_E_MEMORY;
1001         GT_setFailureReason (curTrace,
1002                              GT_4CLASS,
1003                              "VAYUIpcInt_mboxRestoreCtxt",
1004                              status,
1005                              "Unable to map the Mailbox memory in RestoreCtxt");
1006     }
1007     else {
1008         if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1009             /* Set to Smart Idle mode*/
1010             REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
1012             for (i = 0; i < 4; i++) {
1013                 REG32(VAYUIpcInt_state.mailbox5Base + \
1014                               VAYU_MAILBOX_IRQENABLE(i)) = mailbox_5_context[i];
1015             }
1016         }
1017         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1018             /* Set to Smart Idle mode*/
1019             REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
1021             for (i = 0; i < 4; i++) {
1022                 REG32(VAYUIpcInt_state.mailbox6Base + \
1023                               VAYU_MAILBOX_IRQENABLE(i)) = mailbox_6_context[i];
1024             }
1025         }
1027         VAYUIpcInt_interruptEnable(procId, VAYUIpcInt_state.intId);
1028     }
1030     return status;
1034 /*!
1035  *  @brief      Function to unregister interrupt.
1036  *
1037  *  @param      procId  destination procId
1038  *
1039  *  @sa         VAYUIpcInt_interruptRegister
1040  */
1041 Int32
1042 VAYUIpcInt_interruptUnregister  (UInt16 procId)
1044     Int32 status = VAYUIPCINT_SUCCESS;
1045 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1046     Int32 tmpStatus = VAYUIPCINT_SUCCESS;
1047 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1048     VAYUIpcInt_isrHandleElem * isrHandleElem;
1050     GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_interruptUnregister", procId);
1052     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1053     GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
1055 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1056     if (   Atomic_cmpmask_and_lt (
1057                             &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
1058                             VAYUIPCINT_MAKE_MAGICSTAMP(0),
1059                             VAYUIPCINT_MAKE_MAGICSTAMP(1))
1060         == TRUE) {
1061         /*! @retval VAYUIPCINT_E_INVALIDSTATE ISR was not registered */
1062         status = VAYUIPCINT_E_INVALIDSTATE;
1063         GT_setFailureReason (curTrace,
1064                              GT_4CLASS,
1065                              "VAYUIpcInt_interruptUnregister",
1066                              status,
1067                              "ISR was not registered!");
1068     }
1069     else {
1070 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1071         /* This is a normal use-case, so should not be inside
1072          * SYSLINK_BUILD_OPTIMIZE.
1073          */
1074         if (Atomic_dec_return(&VAYUIpcInt_state.isrObjects[procId].isrRefCount)
1075             == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1076             /* Disable hardware interrupt. */
1077             VAYUIpcInt_interruptDisable (procId,
1078                               VAYUIpcInt_state.isrObjects [procId].recvIntId);
1080             VAYUIpcInt_state.isrObjects [procId].fxn       = NULL;
1081             VAYUIpcInt_state.isrObjects [procId].fxnArgs   = NULL;
1082             VAYUIpcInt_state.isrObjects [procId].recvIntId = -1u;
1083         }
1085         isrHandleElem = (VAYUIpcInt_isrHandleElem *)VAYUIpcInt_state.isrObjects [procId].isrHandle;
1087         if (   Atomic_dec_return (&isrHandleElem->refCount)
1088             == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1089             List_remove(VAYUIpcInt_state.isrHandles, (List_Elem *)isrHandleElem);
1090             status = OsalIsr_uninstall (isrHandleElem->isrHandle);
1091 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1092             if (status < 0) {
1093                 GT_setFailureReason (curTrace,
1094                                      GT_4CLASS,
1095                                      "VAYUIpcInt_interruptUnregister",
1096                                      status,
1097                                      "OsalIsr_uninstall failed");
1098             }
1099 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1100             /* Clear the messages in the IPU2->HOST mailbox */
1101             while (REG32(VAYUIpcInt_state.mailbox6Base + \
1102                          MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX))) {
1103                 VAYUIpcInt_clearInterrupt(
1104                                      VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
1105                                      IPU2_HOST_SUB_MBOX);
1106             }
1107             /* Clear the messages in the HOST->IPU2 mailbox */
1108             while (REG32(VAYUIpcInt_state.mailbox6Base + \
1109                          MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX))) {
1110                 VAYUIpcInt_clearInterrupt(
1111                                      VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
1112                                      HOST_IPU2_SUB_MBOX);
1113             }
1114             /* Clear the messages in the DSP1->HOST mailbox */
1115             while (REG32(VAYUIpcInt_state.mailbox5Base + \
1116                          MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX))) {
1117                 VAYUIpcInt_clearInterrupt(
1118                                      VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
1119                                      DSP1_HOST_SUB_MBOX);
1120             }
1121             /* Clear the messages in the HOST->DSP1 mailbox */
1122             while (REG32(VAYUIpcInt_state.mailbox5Base + \
1123                          MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX))) {
1124                 VAYUIpcInt_clearInterrupt(
1125                                      VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
1126                                      HOST_DSP1_SUB_MBOX);
1127             }
1128             /* The below seems to be needed for OMAP5 Virtio for
1129              * slaying/restarting syslink properly
1130              */
1131             /* Disables interrupts from HOST->IPU2 */
1132             SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1133                         MAILBOX_IRQENABLE_CLR_OFFSET + \
1134                         (0x10 * VAYU_IPU2_USER_ID)),
1135                     ((HOST_IPU2_SUB_MBOX) << 1));
1136             /* Disables interrupts from HOST->DSP1 */
1137             SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1138                         MAILBOX_IRQENABLE_CLR_OFFSET + \
1139                         (0x10 * VAYU_DSP1_USER_ID)),
1140                     ((HOST_DSP1_SUB_MBOX) << 1));
1141 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1142             tmpStatus =
1143 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1144                 OsalIsr_delete (&(isrHandleElem->isrHandle));
1145 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1146             if ((status >= 0) && (tmpStatus < 0)) {
1147                 status = tmpStatus;
1148                 GT_setFailureReason (curTrace,
1149                                      GT_4CLASS,
1150                                      "VAYUIpcInt_interruptUnregister",
1151                                      status,
1152                                      "OsalIsr_delete failed");
1153             }
1154 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1155             Memory_free(NULL, isrHandleElem, sizeof(VAYUIpcInt_isrHandleElem));
1156         }
1157 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1158     }
1159 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1161     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptUnregister",
1162                status);
1164     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully unregistered */
1165     return status;
1169 /*!
1170  *  @brief      Function to enable the specified interrupt
1171  *
1172  *  @param      procId  Remote processor ID
1173  *  @param      intId   interrupt id
1174  *
1175  *  @sa         VAYUIpcInt_interruptDisable
1176  */
1177 Void
1178 VAYUIpcInt_interruptEnable (UInt16 procId, UInt32 intId)
1180     GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptEnable",
1181                procId, intId);
1183     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1184     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1186     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1187         /*
1188          * Mailbox 5 is used for HOST<->DSP1 communication
1189          */
1190         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1191                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1192                 ( (DSP1_HOST_SUB_MBOX) << 1));
1193     }
1194     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1195         /*
1196          * Mailbox 6 is used for HOST<->IPU2 communication
1197          */
1198         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1199                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1200                 ( (IPU2_HOST_SUB_MBOX) << 1));
1201     }
1202 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1203     else {
1204         GT_setFailureReason (curTrace,
1205                              GT_4CLASS,
1206                              "VAYUIpcInt_interruptEnable",
1207                              VAYUIPCINT_E_FAIL,
1208                              "Invalid procId specified");
1209     }
1210 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1212     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptEnable");
1216 /*!
1217  *  @brief      Function to disable the specified interrupt
1218  *
1219  *  @param      procId  Remote processor ID
1220  *  @param      intId   interrupt id
1221  *
1222  *  @sa         VAYUIpcInt_interruptEnable
1223  */
1224 Void
1225 VAYUIpcInt_interruptDisable (UInt16 procId, UInt32 intId)
1227     GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptDisable",
1228                procId, intId);
1230     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1231     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1233     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1234         /*
1235          * Mailbox 5 is used for HOST<->DSP1 communication
1236          */
1237         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1238                     MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)),
1239                 ( (DSP1_HOST_SUB_MBOX) << 1));
1240     }
1241     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1242         /*
1243          * Mailbox 6 is used for HOST<->IPU2 communication
1244          */
1245         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1246                     MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)),
1247                 ( (IPU2_HOST_SUB_MBOX) << 1));
1248     }
1249 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1250     else {
1251         GT_setFailureReason (curTrace,
1252                              GT_4CLASS,
1253                              "VAYUIpcInt_interruptDisable",
1254                              VAYUIPCINT_E_FAIL,
1255                              "Invalid procId specified");
1256     }
1257 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1259     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptDisable");
1263 /*!
1264  *  @brief      Function to wait for interrupt to be cleared.
1265  *
1266  *  @param      procId  Remote processor ID
1267  *  @param      intId   interrupt id
1268  *
1269  *  @sa         VAYUIpcInt_sendInterrupt
1270  */
1271 Int32
1272 VAYUIpcInt_waitClearInterrupt (UInt16 procId, UInt32 intId)
1274     Int32 status = VAYUIPCINT_SUCCESS;
1276     GT_2trace (curTrace,GT_ENTER,"VAYUIpcInt_waitClearInterrupt",
1277                procId, intId);
1279     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1280     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1282     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1283         /* Wait for DSP to clear the previous interrupt */
1284         while( (  REG32((  VAYUIpcInt_state.mailbox5Base
1285                         + MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX)))
1286                 & 0x3F ));
1287     }
1288     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1289         /* Wait for VIDEOM4 to clear the previous interrupt */
1290         while( (  REG32((VAYUIpcInt_state.mailbox6Base
1291                       + MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX)))
1292                 & 0x3F ));
1293     }
1294 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1295     else {
1296         /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1297         status = VAYUIPCINT_E_FAIL;
1298         GT_setFailureReason (curTrace,
1299                              GT_4CLASS,
1300                              "VAYUIpcInt_waitClearInterrupt",
1301                              status,
1302                              "Invalid procId specified");
1303     }
1304 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1306     GT_1trace (curTrace,GT_LEAVE,"VAYUIpcInt_waitClearInterrupt", status);
1308     /*! @retval VAYUIPCINT_SUCCESS Wait for interrupt clearing successfully
1309                 completed. */
1310     return status ;
1314 /*!
1315  *  @brief      Function to send a specified interrupt to the DSP.
1316  *
1317  *  @param      procId  Remote processor ID
1318  *  @param      intId   interrupt id
1319  *  @param      value   Value to be sent with the interrupt
1320  *
1321  *  @sa         VAYUIpcInt_waitClearInterrupt
1322  */
1323 Int32
1324 VAYUIpcInt_sendInterrupt (UInt16 procId, UInt32 intId,  UInt32 value)
1326     Int32 status = VAYUIPCINT_SUCCESS;
1328     GT_3trace (curTrace, GT_ENTER, "VAYUIpcInt_sendInterrupt",
1329                procId, intId, value);
1331     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1332     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1334     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1335         /*
1336          * Mailbox 5 is used for HOST<->DSP1 communication
1337          */
1338         REG32(VAYUIpcInt_state.mailbox5Base + \
1339                   MAILBOX_MESSAGE_m_OFFSET(HOST_DSP1_SUB_MBOX)) = value;
1340     } else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1341         /*
1342          * Mailbox 6 is used for HOST<->DSP1 communication
1343          */
1344         REG32(VAYUIpcInt_state.mailbox6Base + \
1345               MAILBOX_MESSAGE_m_OFFSET(HOST_IPU2_SUB_MBOX)) = value;
1346     }
1347 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1348     else {
1349         /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1350         status = VAYUIPCINT_E_FAIL;
1351         GT_setFailureReason (curTrace,
1352                              GT_4CLASS,
1353                              "VAYUIpcInt_sendInterrupt",
1354                              status,
1355                              "Invalid procId specified");
1356     }
1357 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1359     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_sendInterrupt",status);
1361     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully sent */
1362     return status;
1366 /*!
1367  *  @brief      Function to clear the specified interrupt received from the
1368  *              remote core.
1369  *
1370  *  @param      procId  Remote processor ID
1371  *  @param      intId   interrupt id
1372  *
1373  *  @sa         VAYUIpcInt_sendInterrupt
1374  */
1375 UInt32
1376 VAYUIpcInt_clearInterrupt (UInt16 procId, UInt16 mboxNum)
1378     UInt32 retVal = 0;
1379     UInt32 mailboxBase = 0;
1381     GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_clearInterrupt", mboxNum);
1383     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1385     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2])
1386         mailboxBase = VAYUIpcInt_state.mailbox6Base;
1387     else
1388         mailboxBase = VAYUIpcInt_state.mailbox5Base;
1390     if (mboxNum < MAILBOX_MAXNUM) {
1391         /* Read the register to get the entry from the mailbox FIFO */
1392         retVal = REG32(mailboxBase + MAILBOX_MESSAGE_m_OFFSET(mboxNum));
1394         /* Clear the IRQ status.
1395          * If there are more in the mailbox FIFO, it will re-assert.
1396          */
1397         SET_BIT(REG(mailboxBase + MAILBOX_IRQSTATUS_CLEAR_OFFSET + \
1398                     (0x10 * VAYU_HOST_USER_ID)),
1399                     (mboxNum<<1));
1400     }
1401 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1402     else {
1403         GT_setFailureReason (curTrace,
1404                              GT_4CLASS,
1405                              "VAYUIpcInt_clearInterrupt",
1406                              VAYUIPCINT_E_FAIL,
1407                              "Invalid mailbox number specified");
1408     }
1409 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1411     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_clearInterrupt");
1413     /*! @retval Value Value received with the interrupt. */
1414     return retVal;
1418 /*
1419  * Instead of constantly allocating and freeing the msg structures
1420  * we just cache a few of them, and recycle them instead.
1421  */
1422 #define CACHE_NUM 20
1423 static VAYUIpcInt_MsgListElem *msg_cache;
1424 static int num_msg = 0;
1426 static VAYUIpcInt_MsgListElem *get_msg()
1428     VAYUIpcInt_MsgListElem *msg;
1429     IArg key = NULL;
1431     key = Gate_enterSystem();
1432     msg = msg_cache;
1433     if (msg != NULL) {
1434         msg_cache = (VAYUIpcInt_MsgListElem *)msg_cache->next;
1435         num_msg--;
1436         Gate_leaveSystem(key);
1437     } else {
1438         Gate_leaveSystem(key);
1439         msg = Memory_alloc(NULL, sizeof(VAYUIpcInt_MsgListElem), 0, NULL);
1440     }
1441     return(msg);
1444 static void put_msg(VAYUIpcInt_MsgListElem * msg)
1446     IArg key = NULL;
1447     key = Gate_enterSystem();
1448     if (num_msg >= CACHE_NUM) {
1449         Gate_leaveSystem(key);
1450         Memory_free(NULL, msg, sizeof(*msg));
1451     } else {
1452         msg->next = (struct VAYUIpcInt_MsgListElem *)msg_cache;
1453         msg_cache = msg;
1454         num_msg++;
1455         Gate_leaveSystem(key);
1456     }
1457     return;
1461 /*!
1462  *  @brief      Function to check and clear the remote proc interrupt
1463  *
1464  *  @param      arg     Optional argument to the function.
1465  *
1466  *  @sa         _VAYUIpcInt_isr
1467  */
1468 static
1469 Bool
1470 _VAYUIpcInt_checkAndClearFunc (Ptr arg)
1472     UInt16 procId;
1473     UInt32 msg;
1474     VAYUIpcInt_MsgListElem * elem = NULL;
1476     GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_checkAndClearFunc", arg);
1478     if( REG32(  VAYUIpcInt_state.mailbox6Base
1479               + MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX)) != 0 ){
1480         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2];
1481         msg = VAYUIpcInt_clearInterrupt (procId, IPU2_HOST_SUB_MBOX);
1483         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from IPU2", msg);
1485         /* This is a message from IPU2, put the message in IPU2's list */
1486         elem = get_msg();
1487         if (elem) {
1488             elem->msg = msg;
1489             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1490         }
1491     }
1492     if( REG32(  VAYUIpcInt_state.mailbox5Base
1493               + MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX)) != 0 ){
1494         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1];
1495         msg = VAYUIpcInt_clearInterrupt (procId, DSP1_HOST_SUB_MBOX);
1497         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from DSP1", msg);
1499         /* This is a message from DSP, put the message in DSP's list */
1500         elem = get_msg();
1501         if (elem) {
1502             elem->msg = msg;
1503             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1504         }
1505     }
1507     GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_checkAndClearFunc", TRUE);
1509     /* This is not a shared interrupt, so interrupt has always occurred */
1510     /*! @retval TRUE Interrupt has occurred. */
1511     return (TRUE);
1515 /*!
1516  *  @brief      Interrupt Service Routine for VAYUIpcInt module
1517  *
1518  *  @param      arg     Optional argument to the function.
1519  *
1520  *  @sa         _VAYUIpcInt_checkAndClearFunc
1521  */
1522 static
1523 Bool
1524 _VAYUIpcInt_isr (Ptr ref)
1526     UInt16 i = 0;
1527     VAYUIpcInt_MsgListElem * elem = NULL;
1528     GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_isr", ref);
1530     for (i = 0 ; i < VAYUIpcInt_state.maxProcessors ; i++) {
1531         if ((elem = List_get(VAYUIpcInt_state.isrLists [i])) != NULL) {
1532             /*Calling the particular ISR */
1533             GT_assert(curTrace,(VAYUIpcInt_state.isrObjects [i].fxn != NULL));
1534             if (VAYUIpcInt_state.isrObjects [i].fxn != NULL) {
1535                 VAYUIpcInt_state.isrObjects [i].fxn (elem->msg,
1536                                     VAYUIpcInt_state.isrObjects [i].fxnArgs);
1537             }
1538             put_msg(elem);
1539         }
1540     }
1542     GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_isr", TRUE);
1544     /*! @retval TRUE Interrupt has been handled. */
1545     return (TRUE);
1548 #if defined (__cplusplus)
1550 #endif