QNX: Don't Disable Host->rproc Interrupts During Register
[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;
867 #if !defined(SYSLINK_BUILD_OPTIMIZE)
868     }
869 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
871     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptRegister", status);
873     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully registered */
874     return status;
877 /*!
878  *  @brief      Function to Save context.
879  *
880  *  @param      procId  The procId associated with the mailbox context being
881  *                      saved.
882  *
883  *  @sa         VAYUIpcInt_mbxRestoreCtxt
884  */
886 Int32
887 VAYUIpcInt_mboxSaveCtxt (UInt16 procId)
889     Int32 status = VAYUIPCINT_SUCCESS;
890     UInt32 i = 0;
892     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] &&
893         VAYUIpcInt_state.mailbox5Base == NULL) {
894         status = VAYUIPCINT_E_MEMORY;
895         GT_setFailureReason (curTrace,
896                              GT_4CLASS,
897                              "VAYUIpcInt_mboxSaveCtxt",
898                              status,
899                              "Unable to map the Mailbox memory in SaveCtxt");
900     }
901     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] &&
902         VAYUIpcInt_state.mailbox6Base == NULL) {
903         status = VAYUIPCINT_E_MEMORY;
904         GT_setFailureReason (curTrace,
905                              GT_4CLASS,
906                              "VAYUIpcInt_mboxSaveCtxt",
907                              status,
908                              "Unable to map the Mailbox memory in SaveCtxt");
909     }
910     else {
911         if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
912             for (i = 0; i < 4; i++) {
913                 mailbox_5_context[i] = REG32(VAYUIpcInt_state.mailbox5Base + \
914                                              VAYU_MAILBOX_IRQENABLE(i));
915             }
916         }
917         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
918             for (i = 0; i < 4; i++) {
919                 mailbox_6_context[i] = REG32(VAYUIpcInt_state.mailbox6Base + \
920                                              VAYU_MAILBOX_IRQENABLE(i));
921             }
922         }
923         VAYUIpcInt_interruptDisable(procId, VAYUIpcInt_state.intId);
924     }
925     return status;
928 /*!
929  *  @brief      Function to Restore context.
930  *
931  *  @param      procId  The procId associated with the mailbox context being
932  *                      restored.
933  *
934  *  @sa         VAYUIpcInt_mbxSaveCtxt
935  */
937 Int32
938 VAYUIpcInt_mboxRestoreCtxt (UInt16 procId)
940     Int32 status = VAYUIPCINT_SUCCESS;
941     UInt32 i = 0;
943     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] &&
944         VAYUIpcInt_state.mailbox5Base == NULL) {
945         status = VAYUIPCINT_E_MEMORY;
946         GT_setFailureReason (curTrace,
947                              GT_4CLASS,
948                              "VAYUIpcInt_mboxRestoreCtxt",
949                              status,
950                              "Unable to map the Mailbox memory in RestoreCtxt");
951     }
952     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] &&
953         VAYUIpcInt_state.mailbox6Base == NULL) {
954         status = VAYUIPCINT_E_MEMORY;
955         GT_setFailureReason (curTrace,
956                              GT_4CLASS,
957                              "VAYUIpcInt_mboxRestoreCtxt",
958                              status,
959                              "Unable to map the Mailbox memory in RestoreCtxt");
960     }
961     else {
962         if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
963             /* Set to Smart Idle mode*/
964             REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
966             for (i = 0; i < 4; i++) {
967                 REG32(VAYUIpcInt_state.mailbox5Base + \
968                               VAYU_MAILBOX_IRQENABLE(i)) = mailbox_5_context[i];
969             }
970         }
971         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
972             /* Set to Smart Idle mode*/
973             REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
975             for (i = 0; i < 4; i++) {
976                 REG32(VAYUIpcInt_state.mailbox6Base + \
977                               VAYU_MAILBOX_IRQENABLE(i)) = mailbox_6_context[i];
978             }
979         }
981         VAYUIpcInt_interruptEnable(procId, VAYUIpcInt_state.intId);
982     }
984     return status;
988 /*!
989  *  @brief      Function to unregister interrupt.
990  *
991  *  @param      procId  destination procId
992  *
993  *  @sa         VAYUIpcInt_interruptRegister
994  */
995 Int32
996 VAYUIpcInt_interruptUnregister  (UInt16 procId)
998     Int32 status = VAYUIPCINT_SUCCESS;
999 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1000     Int32 tmpStatus = VAYUIPCINT_SUCCESS;
1001 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1002     VAYUIpcInt_isrHandleElem * isrHandleElem;
1004     GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_interruptUnregister", procId);
1006     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1007     GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
1009 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1010     if (   Atomic_cmpmask_and_lt (
1011                             &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
1012                             VAYUIPCINT_MAKE_MAGICSTAMP(0),
1013                             VAYUIPCINT_MAKE_MAGICSTAMP(1))
1014         == TRUE) {
1015         /*! @retval VAYUIPCINT_E_INVALIDSTATE ISR was not registered */
1016         status = VAYUIPCINT_E_INVALIDSTATE;
1017         GT_setFailureReason (curTrace,
1018                              GT_4CLASS,
1019                              "VAYUIpcInt_interruptUnregister",
1020                              status,
1021                              "ISR was not registered!");
1022     }
1023     else {
1024 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1025         /* This is a normal use-case, so should not be inside
1026          * SYSLINK_BUILD_OPTIMIZE.
1027          */
1028         if (Atomic_dec_return(&VAYUIpcInt_state.isrObjects[procId].isrRefCount)
1029             == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1030             /* Disable hardware interrupt. */
1031             VAYUIpcInt_interruptDisable (procId,
1032                               VAYUIpcInt_state.isrObjects [procId].recvIntId);
1034             VAYUIpcInt_state.isrObjects [procId].fxn       = NULL;
1035             VAYUIpcInt_state.isrObjects [procId].fxnArgs   = NULL;
1036             VAYUIpcInt_state.isrObjects [procId].recvIntId = -1u;
1037         }
1039         isrHandleElem = (VAYUIpcInt_isrHandleElem *)VAYUIpcInt_state.isrObjects [procId].isrHandle;
1041         if (   Atomic_dec_return (&isrHandleElem->refCount)
1042             == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1043             List_remove(VAYUIpcInt_state.isrHandles, (List_Elem *)isrHandleElem);
1044             status = OsalIsr_uninstall (isrHandleElem->isrHandle);
1045 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1046             if (status < 0) {
1047                 GT_setFailureReason (curTrace,
1048                                      GT_4CLASS,
1049                                      "VAYUIpcInt_interruptUnregister",
1050                                      status,
1051                                      "OsalIsr_uninstall failed");
1052             }
1053             tmpStatus =
1054 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1055                 OsalIsr_delete (&(isrHandleElem->isrHandle));
1056 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1057             if ((status >= 0) && (tmpStatus < 0)) {
1058                 status = tmpStatus;
1059                 GT_setFailureReason (curTrace,
1060                                      GT_4CLASS,
1061                                      "VAYUIpcInt_interruptUnregister",
1062                                      status,
1063                                      "OsalIsr_delete failed");
1064             }
1065 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1066             Memory_free(NULL, isrHandleElem, sizeof(VAYUIpcInt_isrHandleElem));
1067         }
1068 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1069     }
1070 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1072     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptUnregister",
1073                status);
1075     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully unregistered */
1076     return status;
1080 /*!
1081  *  @brief      Function to enable the specified interrupt
1082  *
1083  *  @param      procId  Remote processor ID
1084  *  @param      intId   interrupt id
1085  *
1086  *  @sa         VAYUIpcInt_interruptDisable
1087  */
1088 Void
1089 VAYUIpcInt_interruptEnable (UInt16 procId, UInt32 intId)
1091     GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptEnable",
1092                procId, intId);
1094     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1095     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1097     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1098         /*
1099          * Mailbox 5 is used for HOST<->DSP1 communication
1100          */
1101         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1102                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1103                 ( (DSP1_HOST_SUB_MBOX) << 1));
1104     }
1105     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1106         /*
1107          * Mailbox 6 is used for HOST<->IPU2 communication
1108          */
1109         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1110                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1111                 ( (IPU2_HOST_SUB_MBOX) << 1));
1112     }
1113 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1114     else {
1115         GT_setFailureReason (curTrace,
1116                              GT_4CLASS,
1117                              "VAYUIpcInt_interruptEnable",
1118                              VAYUIPCINT_E_FAIL,
1119                              "Invalid procId specified");
1120     }
1121 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1123     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptEnable");
1127 /*!
1128  *  @brief      Function to disable the specified interrupt
1129  *
1130  *  @param      procId  Remote processor ID
1131  *  @param      intId   interrupt id
1132  *
1133  *  @sa         VAYUIpcInt_interruptEnable
1134  */
1135 Void
1136 VAYUIpcInt_interruptDisable (UInt16 procId, UInt32 intId)
1138     GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptDisable",
1139                procId, intId);
1141     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1142     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1144     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1145         /*
1146          * Mailbox 5 is used for HOST<->DSP1 communication
1147          */
1148         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1149                     MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)),
1150                 ( (DSP1_HOST_SUB_MBOX) << 1));
1151     }
1152     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1153         /*
1154          * Mailbox 6 is used for HOST<->IPU2 communication
1155          */
1156         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1157                     MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)),
1158                 ( (IPU2_HOST_SUB_MBOX) << 1));
1159     }
1160 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1161     else {
1162         GT_setFailureReason (curTrace,
1163                              GT_4CLASS,
1164                              "VAYUIpcInt_interruptDisable",
1165                              VAYUIPCINT_E_FAIL,
1166                              "Invalid procId specified");
1167     }
1168 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1170     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptDisable");
1174 /*!
1175  *  @brief      Function to wait for interrupt to be cleared.
1176  *
1177  *  @param      procId  Remote processor ID
1178  *  @param      intId   interrupt id
1179  *
1180  *  @sa         VAYUIpcInt_sendInterrupt
1181  */
1182 Int32
1183 VAYUIpcInt_waitClearInterrupt (UInt16 procId, UInt32 intId)
1185     Int32 status = VAYUIPCINT_SUCCESS;
1187     GT_2trace (curTrace,GT_ENTER,"VAYUIpcInt_waitClearInterrupt",
1188                procId, intId);
1190     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1191     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1193     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1194         /* Wait for DSP to clear the previous interrupt */
1195         while( (  REG32((  VAYUIpcInt_state.mailbox5Base
1196                         + MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX)))
1197                 & 0x3F ));
1198     }
1199     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1200         /* Wait for VIDEOM4 to clear the previous interrupt */
1201         while( (  REG32((VAYUIpcInt_state.mailbox6Base
1202                       + MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX)))
1203                 & 0x3F ));
1204     }
1205 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1206     else {
1207         /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1208         status = VAYUIPCINT_E_FAIL;
1209         GT_setFailureReason (curTrace,
1210                              GT_4CLASS,
1211                              "VAYUIpcInt_waitClearInterrupt",
1212                              status,
1213                              "Invalid procId specified");
1214     }
1215 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1217     GT_1trace (curTrace,GT_LEAVE,"VAYUIpcInt_waitClearInterrupt", status);
1219     /*! @retval VAYUIPCINT_SUCCESS Wait for interrupt clearing successfully
1220                 completed. */
1221     return status ;
1225 /*!
1226  *  @brief      Function to send a specified interrupt to the DSP.
1227  *
1228  *  @param      procId  Remote processor ID
1229  *  @param      intId   interrupt id
1230  *  @param      value   Value to be sent with the interrupt
1231  *
1232  *  @sa         VAYUIpcInt_waitClearInterrupt
1233  */
1234 Int32
1235 VAYUIpcInt_sendInterrupt (UInt16 procId, UInt32 intId,  UInt32 value)
1237     Int32 status = VAYUIPCINT_SUCCESS;
1239     GT_3trace (curTrace, GT_ENTER, "VAYUIpcInt_sendInterrupt",
1240                procId, intId, value);
1242     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1243     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1245     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1246         /*
1247          * Mailbox 5 is used for HOST<->DSP1 communication
1248          */
1249         REG32(VAYUIpcInt_state.mailbox5Base + \
1250                   MAILBOX_MESSAGE_m_OFFSET(HOST_DSP1_SUB_MBOX)) = value;
1251     } else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1252         /*
1253          * Mailbox 6 is used for HOST<->DSP1 communication
1254          */
1255         REG32(VAYUIpcInt_state.mailbox6Base + \
1256               MAILBOX_MESSAGE_m_OFFSET(HOST_IPU2_SUB_MBOX)) = value;
1257     }
1258 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1259     else {
1260         /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1261         status = VAYUIPCINT_E_FAIL;
1262         GT_setFailureReason (curTrace,
1263                              GT_4CLASS,
1264                              "VAYUIpcInt_sendInterrupt",
1265                              status,
1266                              "Invalid procId specified");
1267     }
1268 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1270     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_sendInterrupt",status);
1272     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully sent */
1273     return status;
1277 /*!
1278  *  @brief      Function to clear the specified interrupt received from the
1279  *              remote core.
1280  *
1281  *  @param      procId  Remote processor ID
1282  *  @param      intId   interrupt id
1283  *
1284  *  @sa         VAYUIpcInt_sendInterrupt
1285  */
1286 UInt32
1287 VAYUIpcInt_clearInterrupt (UInt16 procId, UInt16 mboxNum)
1289     UInt32 retVal = 0;
1290     UInt32 mailboxBase = 0;
1292     GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_clearInterrupt", mboxNum);
1294     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1296     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2])
1297         mailboxBase = VAYUIpcInt_state.mailbox6Base;
1298     else
1299         mailboxBase = VAYUIpcInt_state.mailbox5Base;
1301     if (mboxNum < MAILBOX_MAXNUM) {
1302         /* Read the register to get the entry from the mailbox FIFO */
1303         retVal = REG32(mailboxBase + MAILBOX_MESSAGE_m_OFFSET(mboxNum));
1305         /* Clear the IRQ status.
1306          * If there are more in the mailbox FIFO, it will re-assert.
1307          */
1308         SET_BIT(REG(mailboxBase + MAILBOX_IRQSTATUS_CLEAR_OFFSET + \
1309                     (0x10 * VAYU_HOST_USER_ID)),
1310                     (mboxNum<<1));
1311     }
1312 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1313     else {
1314         GT_setFailureReason (curTrace,
1315                              GT_4CLASS,
1316                              "VAYUIpcInt_clearInterrupt",
1317                              VAYUIPCINT_E_FAIL,
1318                              "Invalid mailbox number specified");
1319     }
1320 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1322     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_clearInterrupt");
1324     /*! @retval Value Value received with the interrupt. */
1325     return retVal;
1329 /*
1330  * Instead of constantly allocating and freeing the msg structures
1331  * we just cache a few of them, and recycle them instead.
1332  */
1333 #define CACHE_NUM 20
1334 static VAYUIpcInt_MsgListElem *msg_cache;
1335 static int num_msg = 0;
1337 static VAYUIpcInt_MsgListElem *get_msg()
1339     VAYUIpcInt_MsgListElem *msg;
1340     IArg key = NULL;
1342     key = Gate_enterSystem();
1343     msg = msg_cache;
1344     if (msg != NULL) {
1345         msg_cache = (VAYUIpcInt_MsgListElem *)msg_cache->next;
1346         num_msg--;
1347         Gate_leaveSystem(key);
1348     } else {
1349         Gate_leaveSystem(key);
1350         msg = Memory_alloc(NULL, sizeof(VAYUIpcInt_MsgListElem), 0, NULL);
1351     }
1352     return(msg);
1355 static void put_msg(VAYUIpcInt_MsgListElem * msg)
1357     IArg key = NULL;
1358     key = Gate_enterSystem();
1359     if (num_msg >= CACHE_NUM) {
1360         Gate_leaveSystem(key);
1361         Memory_free(NULL, msg, sizeof(*msg));
1362     } else {
1363         msg->next = (struct VAYUIpcInt_MsgListElem *)msg_cache;
1364         msg_cache = msg;
1365         num_msg++;
1366         Gate_leaveSystem(key);
1367     }
1368     return;
1372 /*!
1373  *  @brief      Function to check and clear the remote proc interrupt
1374  *
1375  *  @param      arg     Optional argument to the function.
1376  *
1377  *  @sa         _VAYUIpcInt_isr
1378  */
1379 static
1380 Bool
1381 _VAYUIpcInt_checkAndClearFunc (Ptr arg)
1383     UInt16 procId;
1384     UInt32 msg;
1385     VAYUIpcInt_MsgListElem * elem = NULL;
1387     GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_checkAndClearFunc", arg);
1389     if( REG32(  VAYUIpcInt_state.mailbox6Base
1390               + MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX)) != 0 ){
1391         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2];
1392         msg = VAYUIpcInt_clearInterrupt (procId, IPU2_HOST_SUB_MBOX);
1394         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from IPU2", msg);
1396         /* This is a message from IPU2, put the message in IPU2's list */
1397         elem = get_msg();
1398         if (elem) {
1399             elem->msg = msg;
1400             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1401         }
1402     }
1403     if( REG32(  VAYUIpcInt_state.mailbox5Base
1404               + MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX)) != 0 ){
1405         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1];
1406         msg = VAYUIpcInt_clearInterrupt (procId, DSP1_HOST_SUB_MBOX);
1408         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from DSP1", msg);
1410         /* This is a message from DSP, put the message in DSP's list */
1411         elem = get_msg();
1412         if (elem) {
1413             elem->msg = msg;
1414             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1415         }
1416     }
1418     GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_checkAndClearFunc", TRUE);
1420     /* This is not a shared interrupt, so interrupt has always occurred */
1421     /*! @retval TRUE Interrupt has occurred. */
1422     return (TRUE);
1426 /*!
1427  *  @brief      Interrupt Service Routine for VAYUIpcInt module
1428  *
1429  *  @param      arg     Optional argument to the function.
1430  *
1431  *  @sa         _VAYUIpcInt_checkAndClearFunc
1432  */
1433 static
1434 Bool
1435 _VAYUIpcInt_isr (Ptr ref)
1437     UInt16 i = 0;
1438     VAYUIpcInt_MsgListElem * elem = NULL;
1439     GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_isr", ref);
1441     for (i = 0 ; i < VAYUIpcInt_state.maxProcessors ; i++) {
1442         if ((elem = List_get(VAYUIpcInt_state.isrLists [i])) != NULL) {
1443             /*Calling the particular ISR */
1444             GT_assert(curTrace,(VAYUIpcInt_state.isrObjects [i].fxn != NULL));
1445             if (VAYUIpcInt_state.isrObjects [i].fxn != NULL) {
1446                 VAYUIpcInt_state.isrObjects [i].fxn (elem->msg,
1447                                     VAYUIpcInt_state.isrObjects [i].fxnArgs);
1448             }
1449             put_msg(elem);
1450         }
1451     }
1453     GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_isr", TRUE);
1455     /*! @retval TRUE Interrupt has been handled. */
1456     return (TRUE);
1459 #if defined (__cplusplus)
1461 #endif