Support a seperate address translation table for DSP2
[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-2015, 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 5
113 /*!
114  *  @def    VAYU_INDEX_DSP1
115  *  @brief  Dsp1 index.
116  */
117 #define VAYU_INDEX_DSP1 4
118 /*!
119  *  @def    VAYU_INDEX_DSP2
120  *  @brief  Dsp2 index.
121  */
122 #define VAYU_INDEX_DSP2 3
123 /*!
124  *  @def    VAYU_INDEX_IPU1
125  *  @brief  IPU1 index.
126  */
127 #define VAYU_INDEX_IPU1 2
128 /*!
129  *  @def    VAYU_INDEX_IPU2
130  *  @brief  IPU2 index.
131  */
132 #define VAYU_INDEX_IPU2 1
133 /*!
134  *  @def    VAYU_INDEX_HOST
135  *  @brief  HOST index.
136  */
137 #define VAYU_INDEX_HOST 0
139 /*!
140  *  @def    VAYU_HOST_IPU1_MBOX
141  *  @brief  Mailbox used for HOST<->IPU1 communication.
142  */
143 #define VAYU_HOST_IPU1_MBOX 5
145 /*!
146  *  @def    VAYU_HOST_IPU2_MBOX
147  *  @brief  Mailbox used for HOST<->IPU2 communication.
148  */
149 #define VAYU_HOST_IPU2_MBOX 6
151 /*!
152  *  @def    IPU1_HOST_SUB_MBOX
153  *  @brief  Sub-Mailbox used for IPU1->HOST communication.
154  */
155 #define IPU1_HOST_SUB_MBOX  4
157 /*!
158  *  @def    HOST_IPU1_SUB_MBOX
159  *  @brief  Sub-Mailbox used for HOST->IPU1 communication.
160  */
161 #define HOST_IPU1_SUB_MBOX  6
163 /*!
164  *  @def    IPU2_HOST_SUB_MBOX
165  *  @brief  Sub-Mailbox used for IPU2->HOST communication.
166  */
167 #define IPU2_HOST_SUB_MBOX  4
169 /*!
170  *  @def    HOST_IPU2_SUB_MBOX
171  *  @brief  Sub-Mailbox used for HOST->IPU2 communication.
172  */
173 #define HOST_IPU2_SUB_MBOX  6
175 /*!
176  *  @def    VAYU_HOST_DSP1_MBOX
177  *  @brief  Mailbox used for HOST<->DSP1 communication.
178  */
179 #define VAYU_HOST_DSP1_MBOX 5
181 /*!
182  *  @def    DSP1_HOST_SUB_MBOX
183  *  @brief  Mailbox used for DSP1->HOST communication.
184  */
185 #define DSP1_HOST_SUB_MBOX  1
187 /*!
188  *  @def    HOST_DSP1_SUB_MBOX
189  *  @brief  Mailbox used for HOST->DSP1 communication.
190  */
191 #define HOST_DSP1_SUB_MBOX  5
193 /*!
194  *  @def    VAYU_HOST_DSP2_MBOX
195  *  @brief  Mailbox used for HOST<->DSP2 communication.
196  */
197 #define VAYU_HOST_DSP2_MBOX 6
199 /*!
200  *  @def    DSP2_HOST_SUB_MBOX
201  *  @brief  Mailbox used for DSP2->HOST communication.
202  */
203 #define DSP2_HOST_SUB_MBOX  1
205 /*!
206  *  @def    HOST_DSP2_SUB_MBOX
207  *  @brief  Mailbox used for HOST->DSP2 communication.
208  */
209 #define HOST_DSP2_SUB_MBOX  5
211 /*!
212  *  @def    VAYU_HOST_USER_ID
213  *  @brief  User ID of HOST.
214  */
215 #define VAYU_HOST_USER_ID 2
217 /*!
218  *  @def    VAYU_IPU1_USER_ID
219  *  @brief  User ID of IPU2.
220  */
221 #define VAYU_IPU1_USER_ID 1
223 /*!
224  *  @def    VAYU_IPU2_USER_ID
225  *  @brief  User ID of IPU2.
226  */
227 #define VAYU_IPU2_USER_ID 1
229 /*!
230  *  @def    VAYU_DSP1_USER_ID
231  *  @brief  User ID of DSP1.
232  */
233 #define VAYU_DSP1_USER_ID 0
235 /*!
236  *  @def    VAYU_DSP2_USER_ID
237  *  @brief  User ID of DSP2.
238  */
239 #define VAYU_DSP2_USER_ID 0
241 /* Macro to make a correct module magic number with refCount */
242 #define VAYUIPCINT_MAKE_MAGICSTAMP(x) \
243                                     ((VAYUIPCINT_MODULEID << 12u) | (x))
245 /*!
246  *  @def    REG
247  *  @brief  Regsiter access method.
248  */
249 #define REG(x)          *((volatile UInt32 *) (x))
250 #define REG32(x)        (*(volatile UInt32 *) (x))
252 /* Register access method. */
253 #define REG16(A)        (*(volatile UInt16 *) (A))
255 /*!
256  *  @def    AINTC_BASE_ADDR
257  *  @brief  configuraion address.
258  */
259 #define AINTC_BASE_ADDR                 0x48200000
261 /*!
262  *  @def    AINTC_BASE_SIZE
263  *  @brief  size to be ioremapped.
264  */
265 #define AINTC_BASE_SIZE                 0x1000
267 /*!
268  *  @def    CTRL_MODULE_BASE
269  *  @brief  configuration address.
270  */
271 #define CTRL_MODULE_BASE                 0x4A002000
273 /*!
274  *  @def    CTRL_MODULE_SIZE
275  *  @brief  size to be ioremapped.
276  */
277 #define CTRL_MODULE_SIZE                 0x1000
279 /*!
280  *  @def    CTRL_MODULE_MMR_OFFSET
281  *  @brief  offset in ctrl module to MMR LOCK reg.
282  */
283 #define CTRL_MODULE_MMR_OFFSET           0x544
285 /*!
286  *  @def    CTRL_MODULE_MPU_OFFSET
287  *  @brief  offset in ctrl module to MPU INTs.
288  */
289 #define CTRL_MODULE_MPU_OFFSET           0xA4C
291 /*!
292  *  @def    CTRL_MODULE_INT_BASE
293  *  @brief  interrupt num at offset.
294  */
295 #define CTRL_MODULE_INT_BASE             0x8
297 /*!
298  *  @def    CTRL_MODULE_INT_m_OFFSET
299  *  @brief  interrupt num at offset.
300  */
301 #define CTRL_MODULE_INT_m_OFFSET(m)      CTRL_MODULE_MPU_OFFSET + \
302                                          ((((m) - CTRL_MODULE_INT_BASE) / 2) * 4) - \
303                                          (((m) > 131) ? 4 : 0)
305 /*!
306  *  @def    IRQ_XBAR_MBOX_6_USR_2
307  *  @brief  irq xbar num for mailbox 6 user 2.
308  */
309 #define IRQ_XBAR_MBOX_6_USR_2            255
311 /*!
312  *  @def    IRQ_XBAR_MBOX_5_USR_2
313  *  @brief  irq xbar num for mailbox 5 user 2.
314  */
315 #define IRQ_XBAR_MBOX_5_USR_2            251
317 /*!
318  *  @def    IRQ_XBAR_DSP1
319  *  @brief  irq xbar num for dsp1.
320  */
321 #define IRQ_XBAR_DSP1                    IRQ_XBAR_MBOX_5_USR_2
323 /*!
324  *  @def    IRQ_XBAR_DSP2
325  *  @brief  irq xbar num for dsp2.
326  */
327 #define IRQ_XBAR_DSP2                    IRQ_XBAR_MBOX_6_USR_2
329 /*!
330  *  @def    IRQ_XBAR_IPU1
331  *  @brief  irq xbar num for ipu1.
332  */
333 #define IRQ_XBAR_IPU1                    IRQ_XBAR_MBOX_5_USR_2
335 /*!
336  *  @def    IRQ_XBAR_IPU2
337  *  @brief  irq xbar num for ipu2.
338  */
339 #define IRQ_XBAR_IPU2                    IRQ_XBAR_MBOX_6_USR_2
341 /* Mailbox management values */
342 /*!
343  *  @def    VAYU_MAILBOX_5_BASE
344  *  @brief  configuraion address.
345  */
346 #define MAILBOX_5_BASE                   0x48840000
348 /*!
349  *  @def    VAYU_MAILBOX_6_BASE
350  *  @brief  configuraion address.
351  */
352 #define MAILBOX_6_BASE                   0x48842000
354 /*!
355  *  @def    MAILBOX_SIZE
356  *  @brief  size to be ioremapped.
357  */
358 #define MAILBOX_SIZE                     0x1000
360 /*!
361  *  @def    MAILBOX_SYSCONFIG_OFFSET
362  *  @brief  Offset from the Mailbox base address.
363  */
364 #define MAILBOX_SYSCONFIG_OFFSET      0x10
366 /*!
367  *  @def    MAILBOX_MAXNUM
368  *  @brief  maximum number of mailbox.
369  */
370 #define MAILBOX_MAXNUM                   0xC
372 /*!
373  *  @def    MAILBOX_MESSAGE_m_OFFSET
374  *  @brief  mailbox message address Offset from the Mailbox base
375  *          address. m = 0 to 7 => offset = 0x40 + 0x4*m
376  */
377 #define MAILBOX_MESSAGE_m_OFFSET(m)        (0x40 + (m<<2))
379 /*!
380  *  @def    MAILBOX_MSGSTATUS_m_OFFSET
381  *  @brief  mailbox message status address Offset from the Mailbox base
382  *          address. m = 0 to 7 => offset = 0x40 + 0x4*m
383  */
384 #define MAILBOX_MSGSTATUS_m_OFFSET(m)        (0xC0 + (m<<2))
386 /*!
387  *  @def    MAILBOX_IRQSTATUS_CLEAR_OFFSET
388  *  @brief  mailbox IRQSTATUS clear address Offset from the Mailbox base
389  *          address.
390  */
391 #define MAILBOX_IRQSTATUS_CLEAR_OFFSET  0x104
393 /*!
394  *  @def    MAILBOX_IRQENABLE_SET_OFFSET
395  *  @brief  mailbox IRQ enable set address Offset from the Mailbox base
396  *          address.
397  */
398 #define MAILBOX_IRQENABLE_SET_OFFSET    0x108
399 /*!
400  *  @def    MAILBOX_IRQENABLE_CLR_OFFSET
401  *  @brief  mailbox IRQ enable clear address Offset from the Mailbox base
402  *          address.
403  */
404 #define MAILBOX_IRQENABLE_CLR_OFFSET    0x10C
407 /* Macro used when saving the mailbox context */
408 #define VAYU_MAILBOX_IRQENABLE(u)    (0x108 + 0x10 * (u))
410 /* Msg elem used to store messages from the remote proc */
411 typedef struct VAYUIpcInt_MsgListElem_tag {
412     List_Elem elem;
413     UInt32 msg;
414     struct VAYUIpcInt_MsgListElem * next;
415     struct VAYUIpcInt_MsgListElem * prev;
416 } VAYUIpcInt_MsgListElem;
418 /* Msg elem used to store isrHandles */
419 typedef struct VAYUIpcInt_isrHandleElem_tag {
420     List_Elem      elem;
421     OsalIsr_Handle isrHandle;
422     UInt32         intId;
423     Atomic         refCount;
424 } VAYUIpcInt_isrHandleElem;
426 /*!
427  *  @brief  Device specific object
428  *          It can be populated as per device need and it is used internally in
429  *          the device specific implementation only.
430  */
431 typedef struct VAYUIpcInt_Object_tag {
432     Atomic                 isrRefCount;
433     /*!< ISR Reference count */
434     Atomic                 asserted;
435     /*!< Indicates receipt of interrupt from particular processor */
436     UInt32                 recvIntId;
437     /*!<recevive interrupt id */
438     ArchIpcInt_CallbackFxn fxn;
439     /*!< Callbck function to be registered for particular instance of driver*/
440     Ptr                    fxnArgs;
441     /*!< Argument to the call back function */
442     List_Elem             * isrHandle;
443     /*!< isrHandle */
444 } VAYUIpcInt_Object;
447 /*!
448  *  @brief  Device specific object
449  *          It can be populated as per device need and it is used internally in
450  *          the device specific implementation only.
451  */
452 typedef struct VAYUIpcInt_ModuleObject_tag {
453     Atomic             isrRefCount;
454     /*!< ISR Reference count */
455     //OsalIsr_Handle     isrHandle;
456     List_Handle        isrHandles;
457     /*!< Handle to the OsalIsr object */
458     UInt16             procIds [VAYU_NUMPROCS];
459     /*!< Processors supported */
460     UInt16             maxProcessors;
461     /*!< Maximum number of processors supported by this platform*/
462     VAYUIpcInt_Object isrObjects [MultiProc_MAXPROCESSORS];
463     /*!< Array of Isr objects */
464     List_Handle isrLists [MultiProc_MAXPROCESSORS];
465     /*!< Array of Isr lists */
466     UInt32         archCoreCmBase;
467     /*!< configuration mgmt base */
468     UInt32         mailbox5Base;
469     /*!< mail box configuration mgmt base */
470     UInt32         mailbox6Base;
471     /*!< mail box configuration mgmt base */
472     UInt32         controlModuleBase;
473     /*!< control module base */
474     UInt32         intId;
475     /*!< interrupt id for this proc */
476 } VAYUIpcInt_ModuleObject;
480 /* =============================================================================
481  * Forward declarations of internal functions.
482  * =============================================================================
483  */
484 /* This function implements the interrupt service routine for the interrupt
485  * received from the remote processor.
486  */
487 static Bool _VAYUIpcInt_isr (Ptr ref);
489 /*!
490  *  @brief  Forward declaration of check and clear function
491  */
492 static Bool _VAYUIpcInt_checkAndClearFunc (Ptr arg);
495 /* =============================================================================
496  *  Globals
497  * =============================================================================
498  */
499 /*!
500  *  @brief  State object for VAYUIpcInt
501  */
502 VAYUIpcInt_ModuleObject VAYUIpcInt_state;
504 /*!
505  *  @brief  Function table for OMAP3530
506  */
507 ArchIpcInt_FxnTable VAYUIpcInt_fxnTable = {
508     VAYUIpcInt_interruptRegister,
509     VAYUIpcInt_interruptUnregister,
510     VAYUIpcInt_interruptEnable,
511     VAYUIpcInt_interruptDisable,
512     VAYUIpcInt_waitClearInterrupt,
513     VAYUIpcInt_sendInterrupt,
514     VAYUIpcInt_clearInterrupt,
515 };
517 int mailbox_5_context_ipu1[MAILBOX_SIZE];
518 int mailbox_5_context_ipu2[MAILBOX_SIZE];
519 int mailbox_6_context[MAILBOX_SIZE];
521 /* =============================================================================
522  *  APIs
523  * =============================================================================
524  */
526 /*!
527  *  @brief      Function to initialize the VAYUIpcInt module.
528  *
529  *  @param      cfg  Configuration for setup
530  *
531  *  @sa         VAYUIpcInt_destroy
532  */
533 Void
534 VAYUIpcInt_setup (VAYUIpcInt_Config * cfg)
536 #if !defined(IPC_BUILD_OPTIMIZE)
537     Int            status = VAYUIPCINT_SUCCESS;
538 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
539     Int i = 0;
540     Memory_MapInfo mapInfo;
541     List_Params listParams;
543     GT_1trace (curTrace, GT_ENTER, "VAYUIpcInt_setup", cfg);
545     GT_assert (curTrace, (cfg != NULL));
547     /* The setup will be called only once, either from SysMgr or from
548      * archipcvayu module. Hence it does not need to be atomic.
549      */
550 #if !defined(IPC_BUILD_OPTIMIZE)
551     if (cfg == NULL) {
552         GT_setFailureReason (curTrace,
553                         GT_4CLASS,
554                         "VAYUIpcInt_setup",
555                         VAYUIPCINT_E_FAIL,
556                         "config for driver specific setup can not be NULL");
557     }
558     else {
559 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
561         /* Map general control base */
562         mapInfo.src      = AINTC_BASE_ADDR;
563         mapInfo.size     = AINTC_BASE_SIZE;
564         mapInfo.isCached = FALSE;
565 #if !defined(IPC_BUILD_OPTIMIZE)
566         status =
567 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
568         Memory_map (&mapInfo);
569 #if !defined(IPC_BUILD_OPTIMIZE)
570         if (status < 0) {
571             GT_setFailureReason (curTrace,
572                                  GT_4CLASS,
573                                  "VAYUIpcInt_setup",
574                                  status,
575                                  "Failure in Memory_map for general ctrl base");
576             VAYUIpcInt_state.archCoreCmBase = 0;
577         }
578         else {
579 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
580             VAYUIpcInt_state.archCoreCmBase = mapInfo.dst;
581             /* Map mailbox5Base */
582             mapInfo.src      = MAILBOX_5_BASE;
583             mapInfo.size     = MAILBOX_SIZE;
584             mapInfo.isCached = FALSE;
585  #if !defined(IPC_BUILD_OPTIMIZE)
586             status =
587 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
588                 Memory_map (&mapInfo);
589 #if !defined(IPC_BUILD_OPTIMIZE)
590             if (status < 0) {
591                 GT_setFailureReason (curTrace,
592                                      GT_4CLASS,
593                                      "VAYUIpcInt_setup",
594                                      status,
595                                      "Failure in Memory_map for mailbox5Base");
596                 VAYUIpcInt_state.mailbox5Base = 0;
597             }
598             else {
599 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
600                 VAYUIpcInt_state.mailbox5Base = mapInfo.dst;
601                 /* Map mailbox5Base */
602                 mapInfo.src      = MAILBOX_6_BASE;
603                 mapInfo.size     = MAILBOX_SIZE;
604                 mapInfo.isCached = FALSE;
605 #if !defined(IPC_BUILD_OPTIMIZE)
606                 status =
607 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
608                     Memory_map (&mapInfo);
609 #if !defined(IPC_BUILD_OPTIMIZE)
610                 if (status < 0) {
611                     GT_setFailureReason (curTrace,
612                                          GT_4CLASS,
613                                          "VAYUIpcInt_setup",
614                                          status,
615                                          "Failure in Memory_map for mailbox6Base");
616                     VAYUIpcInt_state.mailbox6Base = 0;
617                 }
618                 else {
619 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
620                     VAYUIpcInt_state.mailbox6Base = mapInfo.dst;
621                     /* Map mailbox5Base */
622                     mapInfo.src      = CTRL_MODULE_BASE;
623                     mapInfo.size     = CTRL_MODULE_SIZE;
624                     mapInfo.isCached = FALSE;
625 #if !defined(IPC_BUILD_OPTIMIZE)
626                     status =
627 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
628                         Memory_map (&mapInfo);
629 #if !defined(IPC_BUILD_OPTIMIZE)
630                     if (status < 0) {
631                         GT_setFailureReason (curTrace,
632                                              GT_4CLASS,
633                                              "VAYUIpcInt_setup",
634                                              status,
635                                              "Failure in Memory_map for mailbox6Base");
636                         VAYUIpcInt_state.controlModuleBase = 0;
637                     }
638                     else {
639 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
640                         VAYUIpcInt_state.controlModuleBase = mapInfo.dst;
642                         /* Program the MMR lock registers to access the SCM
643                          * IRQ crossbar register address range */
644                         REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_MMR_OFFSET) = 0xF757FDC0;
646                         /* Reset Mailbox 5 */
647                         REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) =
648                             REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
649                         while (REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
650                         /*Set Mailbox to Smart Idle */
651                         REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
652                         /* Reset Mailbox 6 */
653                         REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) =
654                             REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
655                         while (REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
656                         /*Set Mailbox to Smart Idle */
657                         REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
658 #if !defined(IPC_BUILD_OPTIMIZE)
659                     }
660                 }
661             }
662         }
663         if (status >= 0) {
664             /*Registering vayu platform with ArchIpcInt*/
665 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
666             ArchIpcInt_object.fxnTable = &VAYUIpcInt_fxnTable;
667             ArchIpcInt_object.obj      = &VAYUIpcInt_state;
669             for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
670                 Atomic_set (&(VAYUIpcInt_state.isrObjects [i].asserted), 1);
671                 List_Params_init(&listParams);
672                 VAYUIpcInt_state.isrLists [i] = List_create(&listParams);
673                 if (VAYUIpcInt_state.isrLists [i] == NULL) {
674                     status = VAYUIPCINT_E_MEMORY;
675                     GT_setFailureReason (curTrace,
676                                          GT_4CLASS,
677                                          "VAYUIpcInt_setup",
678                                          status,
679                                          "Failure in List_create");
680                     for (i = i - 1; i >= 0; i--) {
681                         List_delete(&VAYUIpcInt_state.isrLists [i]);
682                     }
683                     break;
684                 }
685             }
687             List_Params_init(&listParams);
688             VAYUIpcInt_state.isrHandles = List_create(&listParams);
690             /* Calling MultiProc APIs here in setup save time in ISR and makes
691              * it small and fast with less overhead.  This can be done
692              * regardless of status.
693              */
694             VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] =
695                                                        MultiProc_getId ("DSP1");
696             VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2] =
697                                                        MultiProc_getId ("DSP2");
698             VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1] =
699                                                        MultiProc_getId ("IPU1");
700             VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] =
701                                                     MultiProc_getId ("IPU2");
702             VAYUIpcInt_state.maxProcessors = MultiProc_getNumProcessors();
704             if (status >= 0) {
705                 ArchIpcInt_object.isSetup  = TRUE;
706             }
707 #if !defined(IPC_BUILD_OPTIMIZE)
708         }
709     }
710 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
712     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_setup");
716 /*!
717  *  @brief      Function to finalize the VAYUIpcInt module
718  *
719  *  @sa         VAYUIpcInt_setup
720  */
721 Void
722 VAYUIpcInt_destroy (Void)
724     Memory_UnmapInfo unmapInfo;
725     UInt32 i = 0;
726     List_Elem * elem = NULL, * temp = NULL;
728     GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
730     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
732     ArchIpcInt_object.isSetup  = FALSE;
733     ArchIpcInt_object.obj      = NULL;
734     ArchIpcInt_object.fxnTable = NULL;
736     for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
737         if (VAYUIpcInt_state.isrLists [i]) {
738             List_delete(&VAYUIpcInt_state.isrLists [i]);
739         }
740     }
742     List_traverse_safe(elem, temp, VAYUIpcInt_state.isrHandles) {
743         Memory_free(NULL, elem, sizeof(VAYUIpcInt_isrHandleElem));
744     }
745     List_delete(&VAYUIpcInt_state.isrHandles);
747     if (VAYUIpcInt_state.archCoreCmBase != (UInt32) NULL) {
748         unmapInfo.addr = VAYUIpcInt_state.archCoreCmBase;
749         unmapInfo.size = AINTC_BASE_SIZE;
750         unmapInfo.isCached = FALSE;
751         Memory_unmap (&unmapInfo);
752         VAYUIpcInt_state.archCoreCmBase = (UInt32) NULL;
753     }
755     if (VAYUIpcInt_state.mailbox5Base != (UInt32) NULL) {
756         unmapInfo.addr = VAYUIpcInt_state.mailbox5Base;
757         unmapInfo.size = MAILBOX_SIZE;
758         unmapInfo.isCached = FALSE;
759         Memory_unmap (&unmapInfo);
760         VAYUIpcInt_state.mailbox5Base = (UInt32) NULL;
761     }
763     if (VAYUIpcInt_state.mailbox6Base != (UInt32) NULL) {
764         unmapInfo.addr = VAYUIpcInt_state.mailbox6Base;
765         unmapInfo.size = MAILBOX_SIZE;
766         unmapInfo.isCached = FALSE;
767         Memory_unmap (&unmapInfo);
768         VAYUIpcInt_state.mailbox6Base = (UInt32) NULL;
769     }
771     if (VAYUIpcInt_state.controlModuleBase != (UInt32) NULL) {
772         unmapInfo.addr = VAYUIpcInt_state.controlModuleBase;
773         unmapInfo.size = CTRL_MODULE_SIZE;
774         unmapInfo.isCached = FALSE;
775         Memory_unmap (&unmapInfo);
776         VAYUIpcInt_state.controlModuleBase = (UInt32) NULL;
777     }
779     GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
783 /*!
784  *  @brief      Function to register the interrupt.
785  *
786  *  @param      procId  destination procId.
787  *  @param      intId   interrupt id.
788  *  @param      fxn     callback function to be called on receiving interrupt.
789  *  @param      fxnArgs arguments to the callback function.
790  *
791  *  @sa         VAYUIpcInt_interruptEnable
792  */
794 Int32
795 VAYUIpcInt_interruptRegister  (UInt16                     procId,
796                                UInt32                     intId,
797                                ArchIpcInt_CallbackFxn     fxn,
798                                Ptr                        fxnArgs)
800     Int32 status = VAYUIPCINT_SUCCESS;
801     OsalIsr_Params isrParams;
802     OsalIsr_Handle isrHandle;
803     List_Elem * elem = NULL;
804     UInt32 reg = 0;
805     UInt32 mboxId = 0;
807     GT_4trace (curTrace,
808                GT_ENTER,
809                "VAYUIpcInt_interruptRegister",
810                procId,
811                intId,
812                fxn,
813                fxnArgs);
815     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
816     GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
817     GT_assert(curTrace, (fxn != NULL));
820     /* This sets the refCount variable if not initialized, upper 16 bits is
821      * written with module Id to ensure correctness of refCount variable.
822      */
823     Atomic_cmpmask_and_set (
824                             &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
825                             VAYUIPCINT_MAKE_MAGICSTAMP(0),
826                             VAYUIPCINT_MAKE_MAGICSTAMP(0));
828     /* This is a normal use-case, so should not be inside
829      * IPC_BUILD_OPTIMIZE.
830      */
831     if (Atomic_inc_return (&VAYUIpcInt_state.isrObjects [procId].isrRefCount)
832             != VAYUIPCINT_MAKE_MAGICSTAMP(1u)) {
833         /*! @retval VAYUIPCINT_S_ALREADYREGISTERED ISR already registered!
834          */
835             status = VAYUIPCINT_S_ALREADYREGISTERED;
836         GT_0trace (curTrace,
837                    GT_2CLASS,
838                    "ISR already registered!");
839     }
840     else {
841         VAYUIpcInt_state.isrObjects [procId].fxn       = fxn;
842         VAYUIpcInt_state.isrObjects [procId].fxnArgs   = fxnArgs;
843         VAYUIpcInt_state.isrObjects [procId].recvIntId = intId;
844         /* Enable hardware interrupt. */
845         VAYUIpcInt_interruptEnable (procId, intId);
846     }
848     isrParams.sharedInt        = FALSE;
849     isrParams.checkAndClearFxn = &_VAYUIpcInt_checkAndClearFunc;
850     isrParams.fxnArgs          = NULL;
851     isrParams.intId            = intId;
853     /* Check if handle is already created/installed */
854     List_traverse(elem, VAYUIpcInt_state.isrHandles) {
855         if (((VAYUIpcInt_isrHandleElem *)elem)->intId == intId) {
856             Atomic_inc_return (&((VAYUIpcInt_isrHandleElem *)elem)->refCount);
857             status = VAYUIPCINT_S_ALREADYREGISTERED;
858             GT_0trace (curTrace,
859                        GT_2CLASS,
860                        "ISR already set !");
861             break;
862         }
863     }
864     if (elem == &((List_Object *)VAYUIpcInt_state.isrHandles)->elem) {
865         if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
866             mboxId = IRQ_XBAR_DSP1;
867         }
868         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
869             mboxId = IRQ_XBAR_DSP2;
870         }
871         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]){
872             mboxId = IRQ_XBAR_IPU1;
873         }
874         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]){
875             mboxId = IRQ_XBAR_IPU2;
876         }
878         /* Program the IntXbar */
879         reg = REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32)));
880         if (((intId - 32) - CTRL_MODULE_INT_BASE) % 2) {
881             REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
882                 (reg & 0x0000FFFF) | (mboxId << 16);
883         }
884         else {
885             REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
886                 (reg & 0xFFFF0000) | (mboxId);
887         }
888         isrHandle = OsalIsr_create (&_VAYUIpcInt_isr, NULL, &isrParams);
889 #if !defined(IPC_BUILD_OPTIMIZE)
890         if (isrHandle == NULL) {
891             /*! @retval VAYUIPCINT_E_FAIL OsalIsr_create failed */
892             status = VAYUIPCINT_E_FAIL;
893             GT_setFailureReason (curTrace,
894                                  GT_4CLASS,
895                                  "VAYUIpcInt_interruptRegister",
896                                  status,
897                                  "OsalIsr_create failed");
898         }
899         else {
900 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
901             status = OsalIsr_install (isrHandle);
902 #if !defined(IPC_BUILD_OPTIMIZE)
903             if (status < 0) {
904                 GT_setFailureReason (curTrace,
905                                      GT_4CLASS,
906                                      "VAYUIpcInt_interruptRegister",
907                                      status,
908                                      "OsalIsr_install failed");
909             }
910             else {
911 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
912                 elem = Memory_alloc(NULL, sizeof(VAYUIpcInt_isrHandleElem),
913                                     0, NULL);
914 #if !defined(IPC_BUILD_OPTIMIZE)
915                 if (elem == NULL) {
916                     status = VAYUIPCINT_E_MEMORY;
917                     GT_setFailureReason (curTrace,
918                                          GT_4CLASS,
919                                          "VAYUIpcInt_interruptRegister",
920                                          status,
921                                          "Memory_alloc failed");
922                 }
923                 else {
924 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
925                     ((VAYUIpcInt_isrHandleElem *)elem)->isrHandle = isrHandle;
926                     Atomic_cmpmask_and_set (
927                               &((VAYUIpcInt_isrHandleElem *)elem)->refCount,
928                               VAYUIPCINT_MAKE_MAGICSTAMP(0),
929                               VAYUIPCINT_MAKE_MAGICSTAMP(1));
930                     ((VAYUIpcInt_isrHandleElem *)elem)->intId = intId;
931                     List_put(VAYUIpcInt_state.isrHandles, elem);
932 #if !defined(IPC_BUILD_OPTIMIZE)
933                 }
934             }
935         }
936 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
937     }
939 #if !defined(IPC_BUILD_OPTIMIZE)
940     if (status >= 0) {
941 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
942         VAYUIpcInt_state.isrObjects [procId].isrHandle = elem;
943 #if !defined(IPC_BUILD_OPTIMIZE)
944     }
945 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
947     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptRegister", status);
949     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully registered */
950     return status;
955 /*!
956  *  @brief      Function to unregister interrupt.
957  *
958  *  @param      procId  destination procId
959  *
960  *  @sa         VAYUIpcInt_interruptRegister
961  */
962 Int32
963 VAYUIpcInt_interruptUnregister  (UInt16 procId)
965     Int32 status = VAYUIPCINT_SUCCESS;
966 #if !defined(IPC_BUILD_OPTIMIZE)
967     Int32 tmpStatus = VAYUIPCINT_SUCCESS;
968 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
969     VAYUIpcInt_isrHandleElem * isrHandleElem;
971     GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_interruptUnregister", procId);
973     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
974     GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
976 #if !defined(IPC_BUILD_OPTIMIZE)
977     if (   Atomic_cmpmask_and_lt (
978                             &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
979                             VAYUIPCINT_MAKE_MAGICSTAMP(0),
980                             VAYUIPCINT_MAKE_MAGICSTAMP(1))
981         == TRUE) {
982         /*! @retval VAYUIPCINT_E_INVALIDSTATE ISR was not registered */
983         status = VAYUIPCINT_E_INVALIDSTATE;
984         GT_setFailureReason (curTrace,
985                              GT_4CLASS,
986                              "VAYUIpcInt_interruptUnregister",
987                              status,
988                              "ISR was not registered!");
989     }
990     else {
991 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
992         /* This is a normal use-case, so should not be inside
993          * IPC_BUILD_OPTIMIZE.
994          */
995         if (Atomic_dec_return(&VAYUIpcInt_state.isrObjects[procId].isrRefCount)
996             == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
997             /* Disable hardware interrupt. */
998             VAYUIpcInt_interruptDisable (procId,
999                               VAYUIpcInt_state.isrObjects [procId].recvIntId);
1001             VAYUIpcInt_state.isrObjects [procId].fxn       = NULL;
1002             VAYUIpcInt_state.isrObjects [procId].fxnArgs   = NULL;
1003             VAYUIpcInt_state.isrObjects [procId].recvIntId = -1u;
1004         }
1006         isrHandleElem = (VAYUIpcInt_isrHandleElem *)VAYUIpcInt_state.isrObjects [procId].isrHandle;
1008         if (   Atomic_dec_return (&isrHandleElem->refCount)
1009             == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1010             List_remove(VAYUIpcInt_state.isrHandles, (List_Elem *)isrHandleElem);
1011             status = OsalIsr_uninstall (isrHandleElem->isrHandle);
1012 #if !defined(IPC_BUILD_OPTIMIZE)
1013             if (status < 0) {
1014                 GT_setFailureReason (curTrace,
1015                                      GT_4CLASS,
1016                                      "VAYUIpcInt_interruptUnregister",
1017                                      status,
1018                                      "OsalIsr_uninstall failed");
1019             }
1020             tmpStatus =
1021 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1022                 OsalIsr_delete (&(isrHandleElem->isrHandle));
1023 #if !defined(IPC_BUILD_OPTIMIZE)
1024             if ((status >= 0) && (tmpStatus < 0)) {
1025                 status = tmpStatus;
1026                 GT_setFailureReason (curTrace,
1027                                      GT_4CLASS,
1028                                      "VAYUIpcInt_interruptUnregister",
1029                                      status,
1030                                      "OsalIsr_delete failed");
1031             }
1032 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1033             Memory_free(NULL, isrHandleElem, sizeof(VAYUIpcInt_isrHandleElem));
1034         }
1035 #if !defined(IPC_BUILD_OPTIMIZE)
1036     }
1037 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1039     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptUnregister",
1040                status);
1042     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully unregistered */
1043     return status;
1047 /*!
1048  *  @brief      Function to enable the specified interrupt
1049  *
1050  *  @param      procId  Remote processor ID
1051  *  @param      intId   interrupt id
1052  *
1053  *  @sa         VAYUIpcInt_interruptDisable
1054  */
1055 Void
1056 VAYUIpcInt_interruptEnable (UInt16 procId, UInt32 intId)
1058     GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptEnable",
1059                procId, intId);
1061     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1062     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1064     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1065         /*
1066          * Mailbox 5 is used for HOST<->DSP1 communication
1067          */
1068         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1069                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1070                 ( (DSP1_HOST_SUB_MBOX) << 1));
1071     }
1072     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
1073         /*
1074          * Mailbox 6 is used for HOST<->DSP2 communication
1075          */
1076         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1077                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1078                 ( (DSP2_HOST_SUB_MBOX) << 1));
1079     }
1080     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]) {
1081         /*
1082          * Mailbox 5 is used for HOST<->IPU1 communication
1083          */
1084         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1085                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1086                 ( (IPU1_HOST_SUB_MBOX) << 1));
1087     }
1088     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1089         /*
1090          * Mailbox 6 is used for HOST<->IPU2 communication
1091          */
1092         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1093                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1094                 ( (IPU2_HOST_SUB_MBOX) << 1));
1095     }
1096 #if !defined(IPC_BUILD_OPTIMIZE)
1097     else {
1098         GT_setFailureReason (curTrace,
1099                              GT_4CLASS,
1100                              "VAYUIpcInt_interruptEnable",
1101                              VAYUIPCINT_E_FAIL,
1102                              "Invalid procId specified");
1103     }
1104 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1106     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptEnable");
1110 /*!
1111  *  @brief      Function to disable the specified interrupt
1112  *
1113  *  @param      procId  Remote processor ID
1114  *  @param      intId   interrupt id
1115  *
1116  *  @sa         VAYUIpcInt_interruptEnable
1117  */
1118 Void
1119 VAYUIpcInt_interruptDisable (UInt16 procId, UInt32 intId)
1121     GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptDisable",
1122                procId, intId);
1124     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1125     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1127     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1128         /*
1129          * Mailbox 5 is used for HOST<->DSP1 communication
1130          */
1131         REG(VAYUIpcInt_state.mailbox5Base + \
1132             MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)) =
1133             1 << ((DSP1_HOST_SUB_MBOX) << 1);
1134     }
1135     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
1136         /*
1137          * Mailbox 6 is used for HOST<->DSP2 communication
1138          */
1139         REG(VAYUIpcInt_state.mailbox6Base + \
1140             MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)) =
1141             1 << ((DSP2_HOST_SUB_MBOX) << 1);
1142     }
1143     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]) {
1144         /*
1145          * Mailbox 5 is used for HOST<->IPU1 communication
1146          */
1147         REG(VAYUIpcInt_state.mailbox5Base + \
1148             MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)) =
1149             1 << ((IPU1_HOST_SUB_MBOX) << 1);
1150     }
1151     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1152         /*
1153          * Mailbox 6 is used for HOST<->IPU2 communication
1154          */
1155         REG(VAYUIpcInt_state.mailbox6Base + \
1156             MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)) =
1157             1 << ((IPU2_HOST_SUB_MBOX) << 1);
1158     }
1159 #if !defined(IPC_BUILD_OPTIMIZE)
1160     else {
1161         GT_setFailureReason (curTrace,
1162                              GT_4CLASS,
1163                              "VAYUIpcInt_interruptDisable",
1164                              VAYUIPCINT_E_FAIL,
1165                              "Invalid procId specified");
1166     }
1167 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1169     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptDisable");
1173 /*!
1174  *  @brief      Function to wait for interrupt to be cleared.
1175  *
1176  *  @param      procId  Remote processor ID
1177  *  @param      intId   interrupt id
1178  *
1179  *  @sa         VAYUIpcInt_sendInterrupt
1180  */
1181 Int32
1182 VAYUIpcInt_waitClearInterrupt (UInt16 procId, UInt32 intId)
1184     Int32 status = VAYUIPCINT_SUCCESS;
1186     GT_2trace (curTrace,GT_ENTER,"VAYUIpcInt_waitClearInterrupt",
1187                procId, intId);
1189     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1190     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1192     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1193         /* Wait for DSP to clear the previous interrupt */
1194         while( (  REG32((  VAYUIpcInt_state.mailbox5Base
1195                         + MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX)))
1196                 & 0x3F ));
1197     }
1198     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
1199         /* Wait for DSP to clear the previous interrupt */
1200         while( (  REG32((  VAYUIpcInt_state.mailbox6Base
1201                         + MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP2_SUB_MBOX)))
1202                 & 0x3F ));
1203     }
1204     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]) {
1205         /* Wait for M4 to clear the previous interrupt */
1206         while( (  REG32((VAYUIpcInt_state.mailbox5Base
1207                       + MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU1_SUB_MBOX)))
1208                 & 0x3F ));
1209     }
1210     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1211         /* Wait for M4 to clear the previous interrupt */
1212         while( (  REG32((VAYUIpcInt_state.mailbox6Base
1213                       + MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX)))
1214                 & 0x3F ));
1215     }
1216 #if !defined(IPC_BUILD_OPTIMIZE)
1217     else {
1218         /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1219         status = VAYUIPCINT_E_FAIL;
1220         GT_setFailureReason (curTrace,
1221                              GT_4CLASS,
1222                              "VAYUIpcInt_waitClearInterrupt",
1223                              status,
1224                              "Invalid procId specified");
1225     }
1226 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1228     GT_1trace (curTrace,GT_LEAVE,"VAYUIpcInt_waitClearInterrupt", status);
1230     /*! @retval VAYUIPCINT_SUCCESS Wait for interrupt clearing successfully
1231                 completed. */
1232     return status ;
1236 /*!
1237  *  @brief      Function to send a specified interrupt to the DSP.
1238  *
1239  *  @param      procId  Remote processor ID
1240  *  @param      intId   interrupt id
1241  *  @param      value   Value to be sent with the interrupt
1242  *
1243  *  @sa         VAYUIpcInt_waitClearInterrupt
1244  */
1245 Int32
1246 VAYUIpcInt_sendInterrupt (UInt16 procId, UInt32 intId,  UInt32 value)
1248     Int32 status = VAYUIPCINT_SUCCESS;
1250     GT_3trace (curTrace, GT_ENTER, "VAYUIpcInt_sendInterrupt",
1251                procId, intId, value);
1253     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1254     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1256     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1257         /*
1258          * Mailbox 5 is used for HOST<->DSP1 communication
1259          */
1260         REG32(VAYUIpcInt_state.mailbox5Base + \
1261                   MAILBOX_MESSAGE_m_OFFSET(HOST_DSP1_SUB_MBOX)) = value;
1262     }
1263     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
1264         /*
1265          * Mailbox 6 is used for HOST<->DSP2 communication
1266          */
1267         REG32(VAYUIpcInt_state.mailbox6Base + \
1268                   MAILBOX_MESSAGE_m_OFFSET(HOST_DSP2_SUB_MBOX)) = value;
1269     }
1270     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]) {
1271         /*
1272          * Mailbox 5 is used for HOST<->IPU1 communication
1273          */
1274         REG32(VAYUIpcInt_state.mailbox5Base + \
1275               MAILBOX_MESSAGE_m_OFFSET(HOST_IPU1_SUB_MBOX)) = value;
1276     }
1277     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1278         /*
1279          * Mailbox 6 is used for HOST<->IPU2 communication
1280          */
1281         REG32(VAYUIpcInt_state.mailbox6Base + \
1282               MAILBOX_MESSAGE_m_OFFSET(HOST_IPU2_SUB_MBOX)) = value;
1283     }
1284 #if !defined(IPC_BUILD_OPTIMIZE)
1285     else {
1286         /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1287         status = VAYUIPCINT_E_FAIL;
1288         GT_setFailureReason (curTrace,
1289                              GT_4CLASS,
1290                              "VAYUIpcInt_sendInterrupt",
1291                              status,
1292                              "Invalid procId specified");
1293     }
1294 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1296     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_sendInterrupt",status);
1298     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully sent */
1299     return status;
1303 /*!
1304  *  @brief      Function to clear the specified interrupt received from the
1305  *              remote core.
1306  *
1307  *  @param      procId  Remote processor ID
1308  *  @param      intId   interrupt id
1309  *
1310  *  @sa         VAYUIpcInt_sendInterrupt
1311  */
1312 UInt32
1313 VAYUIpcInt_clearInterrupt (UInt16 procId, UInt16 mboxNum)
1315     UInt32 retVal = 0;
1316     UInt32 mailboxBase = 0;
1318     GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_clearInterrupt", mboxNum);
1320     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1321     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] ||
1322         procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2])
1323         mailboxBase = VAYUIpcInt_state.mailbox6Base;
1324     else
1325         mailboxBase = VAYUIpcInt_state.mailbox5Base;
1327     if (mboxNum < MAILBOX_MAXNUM) {
1328         /* Read the register to get the entry from the mailbox FIFO */
1329         retVal = REG32(mailboxBase + MAILBOX_MESSAGE_m_OFFSET(mboxNum));
1331         /* Clear the IRQ status.
1332          * If there are more in the mailbox FIFO, it will re-assert.
1333          */
1334         REG32(mailboxBase + MAILBOX_IRQSTATUS_CLEAR_OFFSET + \
1335                 (0x10 * VAYU_HOST_USER_ID)) = 0x1 << (mboxNum << 1);
1336     }
1337 #if !defined(IPC_BUILD_OPTIMIZE)
1338     else {
1339         GT_setFailureReason (curTrace,
1340                              GT_4CLASS,
1341                              "VAYUIpcInt_clearInterrupt",
1342                              VAYUIPCINT_E_FAIL,
1343                              "Invalid mailbox number specified");
1344     }
1345 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1347     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_clearInterrupt");
1349     /*! @retval Value Value received with the interrupt. */
1350     return retVal;
1354 /*
1355  * Instead of constantly allocating and freeing the msg structures
1356  * we just cache a few of them, and recycle them instead.
1357  */
1358 #define CACHE_NUM 20
1359 static VAYUIpcInt_MsgListElem *msg_cache;
1360 static int num_msg = 0;
1362 static VAYUIpcInt_MsgListElem *get_msg()
1364     VAYUIpcInt_MsgListElem *msg;
1365     IArg key = NULL;
1367     key = Gate_enterSystem();
1368     msg = msg_cache;
1369     if (msg != NULL) {
1370         msg_cache = (VAYUIpcInt_MsgListElem *)msg_cache->next;
1371         num_msg--;
1372         Gate_leaveSystem(key);
1373     } else {
1374         Gate_leaveSystem(key);
1375         msg = Memory_alloc(NULL, sizeof(VAYUIpcInt_MsgListElem), 0, NULL);
1376     }
1377     return(msg);
1380 static void put_msg(VAYUIpcInt_MsgListElem * msg)
1382     IArg key = NULL;
1383     key = Gate_enterSystem();
1384     if (num_msg >= CACHE_NUM) {
1385         Gate_leaveSystem(key);
1386         Memory_free(NULL, msg, sizeof(*msg));
1387     } else {
1388         msg->next = (struct VAYUIpcInt_MsgListElem *)msg_cache;
1389         msg_cache = msg;
1390         num_msg++;
1391         Gate_leaveSystem(key);
1392     }
1393     return;
1397 /*!
1398  *  @brief      Function to check and clear the remote proc interrupt
1399  *
1400  *  @param      arg     Optional argument to the function.
1401  *
1402  *  @sa         _VAYUIpcInt_isr
1403  */
1404 static
1405 Bool
1406 _VAYUIpcInt_checkAndClearFunc (Ptr arg)
1408     UInt16 procId;
1409     UInt32 msg;
1410     VAYUIpcInt_MsgListElem * elem = NULL;
1412     GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_checkAndClearFunc", arg);
1414     if (REG32(VAYUIpcInt_state.mailbox6Base
1415               + MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX)) != 0 ){
1416         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2];
1417         msg = VAYUIpcInt_clearInterrupt (procId, IPU2_HOST_SUB_MBOX);
1419         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from IPU2", msg);
1421         /* This is a message from IPU2, put the message in IPU2's list */
1422         elem = get_msg();
1423         if (elem) {
1424             elem->msg = msg;
1425             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1426         }
1427     }
1428     if (REG32(VAYUIpcInt_state.mailbox5Base
1429               + MAILBOX_MSGSTATUS_m_OFFSET(IPU1_HOST_SUB_MBOX)) != 0 ){
1430         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1];
1431         msg = VAYUIpcInt_clearInterrupt (procId, IPU1_HOST_SUB_MBOX);
1433         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from IPU1", msg);
1435         /* This is a message from IPU1, put the message in IPU1's list */
1436         elem = get_msg();
1437         if (elem) {
1438             elem->msg = msg;
1439             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1440         }
1441     }
1442     if (REG32(VAYUIpcInt_state.mailbox6Base
1443               + MAILBOX_MSGSTATUS_m_OFFSET(DSP2_HOST_SUB_MBOX)) != 0 ){
1444         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2];
1445         msg = VAYUIpcInt_clearInterrupt (procId, DSP2_HOST_SUB_MBOX);
1447         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from DSP2", msg);
1449         /* This is a message from DSP2, put the message in DSP2's list */
1450         elem = get_msg();
1451         if (elem) {
1452             elem->msg = msg;
1453             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1454         }
1455     }
1456     if (REG32(VAYUIpcInt_state.mailbox5Base
1457               + MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX)) != 0 ){
1458         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1];
1459         msg = VAYUIpcInt_clearInterrupt (procId, DSP1_HOST_SUB_MBOX);
1461         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from DSP1", msg);
1463         /* This is a message from DSP1, put the message in DSP1's list */
1464         elem = get_msg();
1465         if (elem) {
1466             elem->msg = msg;
1467             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1468         }
1469     }
1471     GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_checkAndClearFunc", TRUE);
1473     /* This is not a shared interrupt, so interrupt has always occurred */
1474     /*! @retval TRUE Interrupt has occurred. */
1475     return (TRUE);
1479 /*!
1480  *  @brief      Interrupt Service Routine for VAYUIpcInt module
1481  *
1482  *  @param      arg     Optional argument to the function.
1483  *
1484  *  @sa         _VAYUIpcInt_checkAndClearFunc
1485  */
1486 static
1487 Bool
1488 _VAYUIpcInt_isr (Ptr ref)
1490     UInt16 i = 0;
1491     VAYUIpcInt_MsgListElem * elem = NULL;
1492     GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_isr", ref);
1494     for (i = 0 ; i < VAYUIpcInt_state.maxProcessors ; i++) {
1495         if ((elem = List_get(VAYUIpcInt_state.isrLists [i])) != NULL) {
1496             /*Calling the particular ISR */
1497             GT_assert(curTrace,(VAYUIpcInt_state.isrObjects [i].fxn != NULL));
1498             if (VAYUIpcInt_state.isrObjects [i].fxn != NULL) {
1499                 VAYUIpcInt_state.isrObjects [i].fxn (elem->msg,
1500                                     VAYUIpcInt_state.isrObjects [i].fxnArgs);
1501             }
1502             put_msg(elem);
1503         }
1504     }
1506     GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_isr", TRUE);
1508     /*! @retval TRUE Interrupt has been handled. */
1509     return (TRUE);
1512 #if defined (__cplusplus)
1514 #endif