]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - qnx/src/ipc3x_dev/ti/syslink/ipc/hlos/knl/arch/vayu/VAYUIpcInt.c
QNX IPC: Vayu - Update Xbar Config for 16_eng
[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)
251 /*!
252  *  @def    IRQ_XBAR_MBOX_6_USR_2
253  *  @brief  irq xbar num for mailbox 6 user 2.
254  */
255 #define IRQ_XBAR_MBOX_6_USR_2            255
257 /*!
258  *  @def    IRQ_XBAR_MBOX_5_USR_2
259  *  @brief  irq xbar num for mailbox 5 user 2.
260  */
261 #define IRQ_XBAR_MBOX_5_USR_2            251
263 /*!
264  *  @def    IRQ_XBAR_DSP1
265  *  @brief  irq xbar num for dsp1.
266  */
267 #define IRQ_XBAR_DSP1                    IRQ_XBAR_MBOX_5_USR_2
269 /*!
270  *  @def    IRQ_XBAR_IPU2
271  *  @brief  irq xbar num for ipu2.
272  */
273 #define IRQ_XBAR_IPU2                    IRQ_XBAR_MBOX_6_USR_2
275 /* Mailbox management values */
276 /*!
277  *  @def    VAYU_MAILBOX_5_BASE
278  *  @brief  configuraion address.
279  */
280 #define MAILBOX_5_BASE                   0x48840000
282 /*!
283  *  @def    VAYU_MAILBOX_6_BASE
284  *  @brief  configuraion address.
285  */
286 #define MAILBOX_6_BASE                   0x48842000
288 /*!
289  *  @def    MAILBOX_SIZE
290  *  @brief  size to be ioremapped.
291  */
292 #define MAILBOX_SIZE                     0x1000
294 /*!
295  *  @def    MAILBOX_SYSCONFIG_OFFSET
296  *  @brief  Offset from the Mailbox base address.
297  */
298 #define MAILBOX_SYSCONFIG_OFFSET      0x10
300 /*!
301  *  @def    MAILBOX_MAXNUM
302  *  @brief  maximum number of mailbox.
303  */
304 #define MAILBOX_MAXNUM                   0xC
306 /*!
307  *  @def    MAILBOX_MESSAGE_m_OFFSET
308  *  @brief  mailbox message address Offset from the Mailbox base
309  *          address. m = 0 to 7 => offset = 0x40 + 0x4*m
310  */
311 #define MAILBOX_MESSAGE_m_OFFSET(m)        (0x40 + (m<<2))
313 /*!
314  *  @def    MAILBOX_MSGSTATUS_m_OFFSET
315  *  @brief  mailbox message status address Offset from the Mailbox base
316  *          address. m = 0 to 7 => offset = 0x40 + 0x4*m
317  */
318 #define MAILBOX_MSGSTATUS_m_OFFSET(m)        (0xC0 + (m<<2))
320 /*!
321  *  @def    MAILBOX_IRQSTATUS_CLEAR_OFFSET
322  *  @brief  mailbox IRQSTATUS clear address Offset from the Mailbox base
323  *          address.
324  */
325 #define MAILBOX_IRQSTATUS_CLEAR_OFFSET  0x104
327 /*!
328  *  @def    MAILBOX_IRQENABLE_SET_OFFSET
329  *  @brief  mailbox IRQ enable set address Offset from the Mailbox base
330  *          address.
331  */
332 #define MAILBOX_IRQENABLE_SET_OFFSET    0x108
333 /*!
334  *  @def    MAILBOX_IRQENABLE_CLR_OFFSET
335  *  @brief  mailbox IRQ enable clear address Offset from the Mailbox base
336  *          address.
337  */
338 #define MAILBOX_IRQENABLE_CLR_OFFSET    0x10C
341 /* Macro used when saving the mailbox context */
342 #define VAYU_MAILBOX_IRQENABLE(u)    (0x108 + 0x10 * (u))
344 /* Msg elem used to store messages from the remote proc */
345 typedef struct VAYUIpcInt_MsgListElem_tag {
346     List_Elem elem;
347     UInt32 msg;
348     struct VAYUIpcInt_MsgListElem * next;
349     struct VAYUIpcInt_MsgListElem * prev;
350 } VAYUIpcInt_MsgListElem;
352 /* Msg elem used to store isrHandles */
353 typedef struct VAYUIpcInt_isrHandleElem_tag {
354     List_Elem      elem;
355     OsalIsr_Handle isrHandle;
356     UInt32         intId;
357     Atomic         refCount;
358 } VAYUIpcInt_isrHandleElem;
360 /*!
361  *  @brief  Device specific object
362  *          It can be populated as per device need and it is used internally in
363  *          the device specific implementation only.
364  */
365 typedef struct VAYUIpcInt_Object_tag {
366     Atomic                 isrRefCount;
367     /*!< ISR Reference count */
368     Atomic                 asserted;
369     /*!< Indicates receipt of interrupt from particular processor */
370     UInt32                 recvIntId;
371     /*!<recevive interrupt id */
372     ArchIpcInt_CallbackFxn fxn;
373     /*!< Callbck function to be registered for particular instance of driver*/
374     Ptr                    fxnArgs;
375     /*!< Argument to the call back function */
376     List_Elem             * isrHandle;
377     /*!< isrHandle */
378 } VAYUIpcInt_Object;
381 /*!
382  *  @brief  Device specific object
383  *          It can be populated as per device need and it is used internally in
384  *          the device specific implementation only.
385  */
386 typedef struct VAYUIpcInt_ModuleObject_tag {
387     Atomic             isrRefCount;
388     /*!< ISR Reference count */
389     //OsalIsr_Handle     isrHandle;
390     List_Handle        isrHandles;
391     /*!< Handle to the OsalIsr object */
392     UInt16             procIds [VAYU_NUMPROCS];
393     /*!< Processors supported */
394     UInt16             maxProcessors;
395     /*!< Maximum number of processors supported by this platform*/
396     VAYUIpcInt_Object isrObjects [MultiProc_MAXPROCESSORS];
397     /*!< Array of Isr objects */
398     List_Handle isrLists [MultiProc_MAXPROCESSORS];
399     /*!< Array of Isr lists */
400     UInt32         archCoreCmBase;
401     /*!< configuration mgmt base */
402     UInt32         mailbox5Base;
403     /*!< mail box configuration mgmt base */
404     UInt32         mailbox6Base;
405     /*!< mail box configuration mgmt base */
406     UInt32         controlModuleBase;
407     /*!< control module base */
408     UInt32         intId;
409     /*!< interrupt id for this proc */
410 } VAYUIpcInt_ModuleObject;
414 /* =============================================================================
415  * Forward declarations of internal functions.
416  * =============================================================================
417  */
418 /* This function implements the interrupt service routine for the interrupt
419  * received from the remote processor.
420  */
421 static Bool _VAYUIpcInt_isr (Ptr ref);
423 /*!
424  *  @brief  Forward declaration of check and clear function
425  */
426 static Bool _VAYUIpcInt_checkAndClearFunc (Ptr arg);
429 /* =============================================================================
430  *  Globals
431  * =============================================================================
432  */
433 /*!
434  *  @brief  State object for VAYUIpcInt
435  */
436 VAYUIpcInt_ModuleObject VAYUIpcInt_state;
438 /*!
439  *  @brief  Function table for OMAP3530
440  */
441 ArchIpcInt_FxnTable VAYUIpcInt_fxnTable = {
442     VAYUIpcInt_interruptRegister,
443     VAYUIpcInt_interruptUnregister,
444     VAYUIpcInt_interruptEnable,
445     VAYUIpcInt_interruptDisable,
446     VAYUIpcInt_waitClearInterrupt,
447     VAYUIpcInt_sendInterrupt,
448     VAYUIpcInt_clearInterrupt,
449 };
451 int mailbox_5_context[MAILBOX_SIZE];
452 int mailbox_6_context[MAILBOX_SIZE];
454 /* =============================================================================
455  *  APIs
456  * =============================================================================
457  */
459 /*!
460  *  @brief      Function to initialize the VAYUIpcInt module.
461  *
462  *  @param      cfg  Configuration for setup
463  *
464  *  @sa         VAYUIpcInt_destroy
465  */
466 Void
467 VAYUIpcInt_setup (VAYUIpcInt_Config * cfg)
469 #if !defined(SYSLINK_BUILD_OPTIMIZE)
470     Int            status = VAYUIPCINT_SUCCESS;
471 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
472     Int i = 0;
473     Memory_MapInfo mapInfo;
474     List_Params listParams;
476     GT_1trace (curTrace, GT_ENTER, "VAYUIpcInt_setup", cfg);
478     GT_assert (curTrace, (cfg != NULL));
480     /* The setup will be called only once, either from SysMgr or from
481      * archipcvayu module. Hence it does not need to be atomic.
482      */
483 #if !defined(SYSLINK_BUILD_OPTIMIZE)
484     if (cfg == NULL) {
485         GT_setFailureReason (curTrace,
486                         GT_4CLASS,
487                         "VAYUIpcInt_setup",
488                         VAYUIPCINT_E_FAIL,
489                         "config for driver specific setup can not be NULL");
490     }
491     else {
492 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
494         /* Map general control base */
495         mapInfo.src      = AINTC_BASE_ADDR;
496         mapInfo.size     = AINTC_BASE_SIZE;
497         mapInfo.isCached = FALSE;
498 #if !defined(SYSLINK_BUILD_OPTIMIZE)
499         status =
500 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
501         Memory_map (&mapInfo);
502 #if !defined(SYSLINK_BUILD_OPTIMIZE)
503         if (status < 0) {
504             GT_setFailureReason (curTrace,
505                                  GT_4CLASS,
506                                  "VAYUIpcInt_setup",
507                                  status,
508                                  "Failure in Memory_map for general ctrl base");
509             VAYUIpcInt_state.archCoreCmBase = 0;
510         }
511         else {
512 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
513             VAYUIpcInt_state.archCoreCmBase = mapInfo.dst;
514             /* Map mailbox5Base */
515             mapInfo.src      = MAILBOX_5_BASE;
516             mapInfo.size     = MAILBOX_SIZE;
517             mapInfo.isCached = FALSE;
518  #if !defined(SYSLINK_BUILD_OPTIMIZE)
519             status =
520 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
521                 Memory_map (&mapInfo);
522 #if !defined(SYSLINK_BUILD_OPTIMIZE)
523             if (status < 0) {
524                 GT_setFailureReason (curTrace,
525                                      GT_4CLASS,
526                                      "VAYUIpcInt_setup",
527                                      status,
528                                      "Failure in Memory_map for mailbox5Base");
529                 VAYUIpcInt_state.mailbox5Base = 0;
530             }
531             else {
532 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
533                 VAYUIpcInt_state.mailbox5Base = mapInfo.dst;
534                 /* Map mailbox5Base */
535                 mapInfo.src      = MAILBOX_6_BASE;
536                 mapInfo.size     = MAILBOX_SIZE;
537                 mapInfo.isCached = FALSE;
538 #if !defined(SYSLINK_BUILD_OPTIMIZE)
539                 status =
540 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
541                     Memory_map (&mapInfo);
542 #if !defined(SYSLINK_BUILD_OPTIMIZE)
543                 if (status < 0) {
544                     GT_setFailureReason (curTrace,
545                                          GT_4CLASS,
546                                          "VAYUIpcInt_setup",
547                                          status,
548                                          "Failure in Memory_map for mailbox6Base");
549                     VAYUIpcInt_state.mailbox6Base = 0;
550                 }
551                 else {
552 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
553                     VAYUIpcInt_state.mailbox6Base = mapInfo.dst;
554                     /* Map mailbox5Base */
555                     mapInfo.src      = CTRL_MODULE_BASE;
556                     mapInfo.size     = CTRL_MODULE_SIZE;
557                     mapInfo.isCached = FALSE;
558 #if !defined(SYSLINK_BUILD_OPTIMIZE)
559                     status =
560 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
561                         Memory_map (&mapInfo);
562 #if !defined(SYSLINK_BUILD_OPTIMIZE)
563                     if (status < 0) {
564                         GT_setFailureReason (curTrace,
565                                              GT_4CLASS,
566                                              "VAYUIpcInt_setup",
567                                              status,
568                                              "Failure in Memory_map for mailbox6Base");
569                         VAYUIpcInt_state.controlModuleBase = 0;
570                     }
571                     else {
572 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
573                         VAYUIpcInt_state.controlModuleBase = mapInfo.dst;
575                         /* Program the MMR lock registers to access the SCM
576                          * IRQ crossbar register address range */
577                         REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_MMR_OFFSET) = 0xF757FDC0;
579                         /* Reset Mailbox 5 */
580                         REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) =
581                             REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
582                         while (REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
583                         /*Set Mailbox to Smart Idle */
584                         REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
585                         /* Reset Mailbox 6 */
586                         REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) =
587                             REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
588                         while (REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
589                         /*Set Mailbox to Smart Idle */
590                         REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
591 #if !defined(SYSLINK_BUILD_OPTIMIZE)
592                     }
593                 }
594             }
595         }
596         if (status >= 0) {
597             /*Registering vayu platform with ArchIpcInt*/
598 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
599             ArchIpcInt_object.fxnTable = &VAYUIpcInt_fxnTable;
600             ArchIpcInt_object.obj      = &VAYUIpcInt_state;
602             for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
603                 Atomic_set (&(VAYUIpcInt_state.isrObjects [i].asserted), 1);
604                 List_Params_init(&listParams);
605                 VAYUIpcInt_state.isrLists [i] = List_create(&listParams);
606                 if (VAYUIpcInt_state.isrLists [i] == NULL) {
607                     status = VAYUIPCINT_E_MEMORY;
608                     GT_setFailureReason (curTrace,
609                                          GT_4CLASS,
610                                          "VAYUIpcInt_setup",
611                                          status,
612                                          "Failure in List_create");
613                     for (i = i - 1; i >= 0; i--) {
614                         List_delete(&VAYUIpcInt_state.isrLists [i]);
615                     }
616                     break;
617                 }
618             }
620             List_Params_init(&listParams);
621             VAYUIpcInt_state.isrHandles = List_create(&listParams);
623             /* Calling MultiProc APIs here in setup save time in ISR and makes
624              * it small and fast with less overhead.  This can be done
625              * regardless of status.
626              */
627             VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] =
628                                                        MultiProc_getId ("DSP1");
629             VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] =
630                                                     MultiProc_getId ("IPU2");
631             VAYUIpcInt_state.maxProcessors = MultiProc_getNumProcessors();
633             if (status >= 0) {
634                 ArchIpcInt_object.isSetup  = TRUE;
635             }
636 #if !defined(SYSLINK_BUILD_OPTIMIZE)
637         }
638     }
639 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
641     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_setup");
645 /*!
646  *  @brief      Function to finalize the VAYUIpcInt module
647  *
648  *  @sa         VAYUIpcInt_setup
649  */
650 Void
651 VAYUIpcInt_destroy (Void)
653     Memory_UnmapInfo unmapInfo;
654     UInt32 i = 0;
655     List_Elem * elem = NULL, * temp = NULL;
657     GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
659     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
661     ArchIpcInt_object.isSetup  = FALSE;
662     ArchIpcInt_object.obj      = NULL;
663     ArchIpcInt_object.fxnTable = NULL;
665     for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
666         if (VAYUIpcInt_state.isrLists [i]) {
667             List_delete(&VAYUIpcInt_state.isrLists [i]);
668         }
669     }
671     List_traverse_safe(elem, temp, VAYUIpcInt_state.isrHandles) {
672         Memory_free(NULL, elem, sizeof(VAYUIpcInt_isrHandleElem));
673     }
674     List_delete(&VAYUIpcInt_state.isrHandles);
676     if (VAYUIpcInt_state.archCoreCmBase != (UInt32) NULL) {
677         unmapInfo.addr = VAYUIpcInt_state.archCoreCmBase;
678         unmapInfo.size = AINTC_BASE_SIZE;
679         unmapInfo.isCached = FALSE;
680         Memory_unmap (&unmapInfo);
681         VAYUIpcInt_state.archCoreCmBase = (UInt32) NULL;
682     }
684     if (VAYUIpcInt_state.mailbox5Base != (UInt32) NULL) {
685         unmapInfo.addr = VAYUIpcInt_state.mailbox5Base;
686         unmapInfo.size = MAILBOX_SIZE;
687         unmapInfo.isCached = FALSE;
688         Memory_unmap (&unmapInfo);
689         VAYUIpcInt_state.mailbox5Base = (UInt32) NULL;
690     }
692     if (VAYUIpcInt_state.mailbox6Base != (UInt32) NULL) {
693         unmapInfo.addr = VAYUIpcInt_state.mailbox6Base;
694         unmapInfo.size = MAILBOX_SIZE;
695         unmapInfo.isCached = FALSE;
696         Memory_unmap (&unmapInfo);
697         VAYUIpcInt_state.mailbox6Base = (UInt32) NULL;
698     }
700     if (VAYUIpcInt_state.controlModuleBase != (UInt32) NULL) {
701         unmapInfo.addr = VAYUIpcInt_state.controlModuleBase;
702         unmapInfo.size = CTRL_MODULE_SIZE;
703         unmapInfo.isCached = FALSE;
704         Memory_unmap (&unmapInfo);
705         VAYUIpcInt_state.archCoreCmBase = (UInt32) NULL;
706     }
708     GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
712 /*!
713  *  @brief      Function to register the interrupt.
714  *
715  *  @param      procId  destination procId.
716  *  @param      intId   interrupt id.
717  *  @param      fxn     callback function to be called on receiving interrupt.
718  *  @param      fxnArgs arguments to the callback function.
719  *
720  *  @sa         VAYUIpcInt_interruptEnable
721  */
723 Int32
724 VAYUIpcInt_interruptRegister  (UInt16                     procId,
725                                UInt32                     intId,
726                                ArchIpcInt_CallbackFxn     fxn,
727                                Ptr                        fxnArgs)
729     Int32 status = VAYUIPCINT_SUCCESS;
730     OsalIsr_Params isrParams;
731     OsalIsr_Handle isrHandle;
732     List_Elem * elem = NULL;
733     UInt32 reg = 0;
734     UInt32 mboxId = 0;
736     GT_4trace (curTrace,
737                GT_ENTER,
738                "VAYUIpcInt_interruptRegister",
739                procId,
740                intId,
741                fxn,
742                fxnArgs);
744     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
745     GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
746     GT_assert(curTrace, (fxn != NULL));
749     /* This sets the refCount variable if not initialized, upper 16 bits is
750      * written with module Id to ensure correctness of refCount variable.
751      */
752     Atomic_cmpmask_and_set (
753                             &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
754                             VAYUIPCINT_MAKE_MAGICSTAMP(0),
755                             VAYUIPCINT_MAKE_MAGICSTAMP(0));
757     /* This is a normal use-case, so should not be inside
758      * SYSLINK_BUILD_OPTIMIZE.
759      */
760     if (Atomic_inc_return (&VAYUIpcInt_state.isrObjects [procId].isrRefCount)
761             != VAYUIPCINT_MAKE_MAGICSTAMP(1u)) {
762         /*! @retval VAYUIPCINT_S_ALREADYREGISTERED ISR already registered!
763          */
764             status = VAYUIPCINT_S_ALREADYREGISTERED;
765         GT_0trace (curTrace,
766                    GT_2CLASS,
767                    "ISR already registered!");
768     }
769     else {
770         VAYUIpcInt_state.isrObjects [procId].fxn       = fxn;
771         VAYUIpcInt_state.isrObjects [procId].fxnArgs   = fxnArgs;
772         VAYUIpcInt_state.isrObjects [procId].recvIntId = intId;
773         /* Enable hardware interrupt. */
774         VAYUIpcInt_interruptEnable (procId, intId);
775     }
777     isrParams.sharedInt        = FALSE;
778     isrParams.checkAndClearFxn = &_VAYUIpcInt_checkAndClearFunc;
779     isrParams.fxnArgs          = NULL;
780     isrParams.intId            = intId;
782     /* Check if handle is already created/installed */
783     List_traverse(elem, VAYUIpcInt_state.isrHandles) {
784         if (((VAYUIpcInt_isrHandleElem *)elem)->intId == intId) {
785             Atomic_inc_return (&((VAYUIpcInt_isrHandleElem *)elem)->refCount);
786             status = VAYUIPCINT_S_ALREADYREGISTERED;
787             GT_0trace (curTrace,
788                        GT_2CLASS,
789                        "ISR already set !");
790             break;
791         }
792     }
793     if (elem == &((List_Object *)VAYUIpcInt_state.isrHandles)->elem) {
794         if (procId == MultiProc_getId("DSP1")) {
795             mboxId = IRQ_XBAR_DSP1;
796         }
797         else if (procId == MultiProc_getId("IPU2")){
798             mboxId = IRQ_XBAR_IPU2;
799         }
800         /* Program the IntXbar */
801         reg = REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32)));
802         if (((intId - 32) - CTRL_MODULE_INT_BASE) % 2) {
803             REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
804                 (reg & 0x0000FFFF) | (mboxId << 16);
805         }
806         else {
807             REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
808                 (reg & 0xFFFF0000) | (mboxId);
809         }
810         isrHandle = OsalIsr_create (&_VAYUIpcInt_isr, NULL, &isrParams);
811 #if !defined(SYSLINK_BUILD_OPTIMIZE)
812         if (isrHandle == NULL) {
813             /*! @retval VAYUIPCINT_E_FAIL OsalIsr_create failed */
814             status = VAYUIPCINT_E_FAIL;
815             GT_setFailureReason (curTrace,
816                                  GT_4CLASS,
817                                  "VAYUIpcInt_interruptRegister",
818                                  status,
819                                  "OsalIsr_create failed");
820         }
821         else {
822 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
823             status = OsalIsr_install (isrHandle);
824 #if !defined(SYSLINK_BUILD_OPTIMIZE)
825             if (status < 0) {
826                 GT_setFailureReason (curTrace,
827                                      GT_4CLASS,
828                                      "VAYUIpcInt_interruptRegister",
829                                      status,
830                                      "OsalIsr_install failed");
831             }
832             else {
833 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
834                 elem = Memory_alloc(NULL, sizeof(VAYUIpcInt_isrHandleElem),
835                                     0, NULL);
836 #if !defined(SYSLINK_BUILD_OPTIMIZE)
837                 if (elem == NULL) {
838                     status = VAYUIPCINT_E_MEMORY;
839                     GT_setFailureReason (curTrace,
840                                          GT_4CLASS,
841                                          "VAYUIpcInt_interruptRegister",
842                                          status,
843                                          "Memory_alloc failed");
844                 }
845                 else {
846 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
847                     ((VAYUIpcInt_isrHandleElem *)elem)->isrHandle = isrHandle;
848                     Atomic_cmpmask_and_set (
849                               &((VAYUIpcInt_isrHandleElem *)elem)->refCount,
850                               VAYUIPCINT_MAKE_MAGICSTAMP(0),
851                               VAYUIPCINT_MAKE_MAGICSTAMP(1));
852                     ((VAYUIpcInt_isrHandleElem *)elem)->intId = intId;
853                     List_put(VAYUIpcInt_state.isrHandles, elem);
854 #if !defined(SYSLINK_BUILD_OPTIMIZE)
855                 }
856             }
857         }
858 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
859     }
861 #if !defined(SYSLINK_BUILD_OPTIMIZE)
862     if (status >= 0) {
863 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
864         VAYUIpcInt_state.isrObjects [procId].isrHandle = elem;
866         /* Clear the messages in the IPU2->HOST mailbox */
867         while (REG32(VAYUIpcInt_state.mailbox6Base + \
868                      MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX))) {
869             VAYUIpcInt_clearInterrupt(
870                              VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
871                              IPU2_HOST_SUB_MBOX);
872         }
873         /* Clear the messages in the HOST->IPU2 mailbox */
874         while (REG32(VAYUIpcInt_state.mailbox6Base + \
875                      MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX))) {
876             VAYUIpcInt_clearInterrupt(
877                              VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
878                              HOST_IPU2_SUB_MBOX);
879         }
880         /* Clear the messages in the DSP1->HOST mailbox */
881         while (REG32(VAYUIpcInt_state.mailbox5Base + \
882                      MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX))) {
883             VAYUIpcInt_clearInterrupt(
884                              VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
885                              DSP1_HOST_SUB_MBOX);
886         }
887         /* Clear the messages in the HOST->DSP1 mailbox */
888         while (REG32(VAYUIpcInt_state.mailbox5Base + \
889                      MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX))) {
890             VAYUIpcInt_clearInterrupt(
891                              VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
892                              HOST_DSP1_SUB_MBOX);
893         }
894         /* The below seems to be needed for OMAP5 Virtio for
895          * slaying/restarting syslink properly
896          */
897         /* Disables interrupts from HOST->IPU2 */
898         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
899                     MAILBOX_IRQENABLE_CLR_OFFSET + \
900                     (0x10 * VAYU_IPU2_USER_ID)),
901                 ((HOST_IPU2_SUB_MBOX) << 1));
902         /* Disables interrupts from HOST->DSP1 */
903         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
904                     MAILBOX_IRQENABLE_CLR_OFFSET + \
905                     (0x10 * VAYU_DSP1_USER_ID)),
906                 ((HOST_DSP1_SUB_MBOX) << 1));
908         /* Set mailbox to smart-idle */
909         REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
910         REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
911 #if !defined(SYSLINK_BUILD_OPTIMIZE)
912     }
913 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
915     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptRegister", status);
917     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully registered */
918     return status;
921 /*!
922  *  @brief      Function to Save context.
923  *
924  *  @param      procId  The procId associated with the mailbox context being
925  *                      saved.
926  *
927  *  @sa         VAYUIpcInt_mbxRestoreCtxt
928  */
930 Int32
931 VAYUIpcInt_mboxSaveCtxt (UInt16 procId)
933     Int32 status = VAYUIPCINT_SUCCESS;
934     UInt32 i = 0;
936     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] &&
937         VAYUIpcInt_state.mailbox5Base == NULL) {
938         status = VAYUIPCINT_E_MEMORY;
939         GT_setFailureReason (curTrace,
940                              GT_4CLASS,
941                              "VAYUIpcInt_mboxSaveCtxt",
942                              status,
943                              "Unable to map the Mailbox memory in SaveCtxt");
944     }
945     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] &&
946         VAYUIpcInt_state.mailbox6Base == NULL) {
947         status = VAYUIPCINT_E_MEMORY;
948         GT_setFailureReason (curTrace,
949                              GT_4CLASS,
950                              "VAYUIpcInt_mboxSaveCtxt",
951                              status,
952                              "Unable to map the Mailbox memory in SaveCtxt");
953     }
954     else {
955         if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
956             for (i = 0; i < 4; i++) {
957                 mailbox_5_context[i] = REG32(VAYUIpcInt_state.mailbox5Base + \
958                                              VAYU_MAILBOX_IRQENABLE(i));
959             }
960         }
961         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
962             for (i = 0; i < 4; i++) {
963                 mailbox_6_context[i] = REG32(VAYUIpcInt_state.mailbox6Base + \
964                                              VAYU_MAILBOX_IRQENABLE(i));
965             }
966         }
967         VAYUIpcInt_interruptDisable(procId, VAYUIpcInt_state.intId);
968     }
969     return status;
972 /*!
973  *  @brief      Function to Restore context.
974  *
975  *  @param      procId  The procId associated with the mailbox context being
976  *                      restored.
977  *
978  *  @sa         VAYUIpcInt_mbxSaveCtxt
979  */
981 Int32
982 VAYUIpcInt_mboxRestoreCtxt (UInt16 procId)
984     Int32 status = VAYUIPCINT_SUCCESS;
985     UInt32 i = 0;
987     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] &&
988         VAYUIpcInt_state.mailbox5Base == NULL) {
989         status = VAYUIPCINT_E_MEMORY;
990         GT_setFailureReason (curTrace,
991                              GT_4CLASS,
992                              "VAYUIpcInt_mboxRestoreCtxt",
993                              status,
994                              "Unable to map the Mailbox memory in RestoreCtxt");
995     }
996     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] &&
997         VAYUIpcInt_state.mailbox6Base == NULL) {
998         status = VAYUIPCINT_E_MEMORY;
999         GT_setFailureReason (curTrace,
1000                              GT_4CLASS,
1001                              "VAYUIpcInt_mboxRestoreCtxt",
1002                              status,
1003                              "Unable to map the Mailbox memory in RestoreCtxt");
1004     }
1005     else {
1006         if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1007             /* Set to Smart Idle mode*/
1008             REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
1010             for (i = 0; i < 4; i++) {
1011                 REG32(VAYUIpcInt_state.mailbox5Base + \
1012                               VAYU_MAILBOX_IRQENABLE(i)) = mailbox_5_context[i];
1013             }
1014         }
1015         else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1016             /* Set to Smart Idle mode*/
1017             REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
1019             for (i = 0; i < 4; i++) {
1020                 REG32(VAYUIpcInt_state.mailbox6Base + \
1021                               VAYU_MAILBOX_IRQENABLE(i)) = mailbox_6_context[i];
1022             }
1023         }
1025         VAYUIpcInt_interruptEnable(procId, VAYUIpcInt_state.intId);
1026     }
1028     return status;
1032 /*!
1033  *  @brief      Function to unregister interrupt.
1034  *
1035  *  @param      procId  destination procId
1036  *
1037  *  @sa         VAYUIpcInt_interruptRegister
1038  */
1039 Int32
1040 VAYUIpcInt_interruptUnregister  (UInt16 procId)
1042     Int32 status = VAYUIPCINT_SUCCESS;
1043 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1044     Int32 tmpStatus = VAYUIPCINT_SUCCESS;
1045 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1046     VAYUIpcInt_isrHandleElem * isrHandleElem;
1048     GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_interruptUnregister", procId);
1050     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1051     GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
1053 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1054     if (   Atomic_cmpmask_and_lt (
1055                             &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
1056                             VAYUIPCINT_MAKE_MAGICSTAMP(0),
1057                             VAYUIPCINT_MAKE_MAGICSTAMP(1))
1058         == TRUE) {
1059         /*! @retval VAYUIPCINT_E_INVALIDSTATE ISR was not registered */
1060         status = VAYUIPCINT_E_INVALIDSTATE;
1061         GT_setFailureReason (curTrace,
1062                              GT_4CLASS,
1063                              "VAYUIpcInt_interruptUnregister",
1064                              status,
1065                              "ISR was not registered!");
1066     }
1067     else {
1068 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1069         /* This is a normal use-case, so should not be inside
1070          * SYSLINK_BUILD_OPTIMIZE.
1071          */
1072         if (Atomic_dec_return(&VAYUIpcInt_state.isrObjects[procId].isrRefCount)
1073             == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1074             /* Disable hardware interrupt. */
1075             VAYUIpcInt_interruptDisable (procId,
1076                               VAYUIpcInt_state.isrObjects [procId].recvIntId);
1078             VAYUIpcInt_state.isrObjects [procId].fxn       = NULL;
1079             VAYUIpcInt_state.isrObjects [procId].fxnArgs   = NULL;
1080             VAYUIpcInt_state.isrObjects [procId].recvIntId = -1u;
1081         }
1083         isrHandleElem = (VAYUIpcInt_isrHandleElem *)VAYUIpcInt_state.isrObjects [procId].isrHandle;
1085         if (   Atomic_dec_return (&isrHandleElem->refCount)
1086             == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1087             List_remove(VAYUIpcInt_state.isrHandles, (List_Elem *)isrHandleElem);
1088             status = OsalIsr_uninstall (isrHandleElem->isrHandle);
1089 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1090             if (status < 0) {
1091                 GT_setFailureReason (curTrace,
1092                                      GT_4CLASS,
1093                                      "VAYUIpcInt_interruptUnregister",
1094                                      status,
1095                                      "OsalIsr_uninstall failed");
1096             }
1097 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1098             /* Clear the messages in the IPU2->HOST mailbox */
1099             while (REG32(VAYUIpcInt_state.mailbox6Base + \
1100                          MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX))) {
1101                 VAYUIpcInt_clearInterrupt(
1102                                      VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
1103                                      IPU2_HOST_SUB_MBOX);
1104             }
1105             /* Clear the messages in the HOST->IPU2 mailbox */
1106             while (REG32(VAYUIpcInt_state.mailbox6Base + \
1107                          MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX))) {
1108                 VAYUIpcInt_clearInterrupt(
1109                                      VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
1110                                      HOST_IPU2_SUB_MBOX);
1111             }
1112             /* Clear the messages in the DSP1->HOST mailbox */
1113             while (REG32(VAYUIpcInt_state.mailbox5Base + \
1114                          MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX))) {
1115                 VAYUIpcInt_clearInterrupt(
1116                                      VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
1117                                      DSP1_HOST_SUB_MBOX);
1118             }
1119             /* Clear the messages in the HOST->DSP1 mailbox */
1120             while (REG32(VAYUIpcInt_state.mailbox5Base + \
1121                          MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX))) {
1122                 VAYUIpcInt_clearInterrupt(
1123                                      VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
1124                                      HOST_DSP1_SUB_MBOX);
1125             }
1126             /* The below seems to be needed for OMAP5 Virtio for
1127              * slaying/restarting syslink properly
1128              */
1129             /* Disables interrupts from HOST->IPU2 */
1130             SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1131                         MAILBOX_IRQENABLE_CLR_OFFSET + \
1132                         (0x10 * VAYU_IPU2_USER_ID)),
1133                     ((HOST_IPU2_SUB_MBOX) << 1));
1134             /* Disables interrupts from HOST->DSP1 */
1135             SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1136                         MAILBOX_IRQENABLE_CLR_OFFSET + \
1137                         (0x10 * VAYU_DSP1_USER_ID)),
1138                     ((HOST_DSP1_SUB_MBOX) << 1));
1139 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1140             tmpStatus =
1141 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1142                 OsalIsr_delete (&(isrHandleElem->isrHandle));
1143 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1144             if ((status >= 0) && (tmpStatus < 0)) {
1145                 status = tmpStatus;
1146                 GT_setFailureReason (curTrace,
1147                                      GT_4CLASS,
1148                                      "VAYUIpcInt_interruptUnregister",
1149                                      status,
1150                                      "OsalIsr_delete failed");
1151             }
1152 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1153             Memory_free(NULL, isrHandleElem, sizeof(VAYUIpcInt_isrHandleElem));
1154         }
1155 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1156     }
1157 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1159     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptUnregister",
1160                status);
1162     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully unregistered */
1163     return status;
1167 /*!
1168  *  @brief      Function to enable the specified interrupt
1169  *
1170  *  @param      procId  Remote processor ID
1171  *  @param      intId   interrupt id
1172  *
1173  *  @sa         VAYUIpcInt_interruptDisable
1174  */
1175 Void
1176 VAYUIpcInt_interruptEnable (UInt16 procId, UInt32 intId)
1178     GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptEnable",
1179                procId, intId);
1181     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1182     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1184     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1185         /*
1186          * Mailbox 5 is used for HOST<->DSP1 communication
1187          */
1188         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1189                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1190                 ( (DSP1_HOST_SUB_MBOX) << 1));
1191     }
1192     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1193         /*
1194          * Mailbox 6 is used for HOST<->IPU2 communication
1195          */
1196         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1197                     VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1198                 ( (IPU2_HOST_SUB_MBOX) << 1));
1199     }
1200 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1201     else {
1202         GT_setFailureReason (curTrace,
1203                              GT_4CLASS,
1204                              "VAYUIpcInt_interruptEnable",
1205                              VAYUIPCINT_E_FAIL,
1206                              "Invalid procId specified");
1207     }
1208 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1210     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptEnable");
1214 /*!
1215  *  @brief      Function to disable the specified interrupt
1216  *
1217  *  @param      procId  Remote processor ID
1218  *  @param      intId   interrupt id
1219  *
1220  *  @sa         VAYUIpcInt_interruptEnable
1221  */
1222 Void
1223 VAYUIpcInt_interruptDisable (UInt16 procId, UInt32 intId)
1225     GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptDisable",
1226                procId, intId);
1228     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1229     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1231     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1232         /*
1233          * Mailbox 5 is used for HOST<->DSP1 communication
1234          */
1235         SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1236                     MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)),
1237                 ( (DSP1_HOST_SUB_MBOX) << 1));
1238     }
1239     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1240         /*
1241          * Mailbox 6 is used for HOST<->IPU2 communication
1242          */
1243         SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1244                     MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)),
1245                 ( (IPU2_HOST_SUB_MBOX) << 1));
1246     }
1247 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1248     else {
1249         GT_setFailureReason (curTrace,
1250                              GT_4CLASS,
1251                              "VAYUIpcInt_interruptDisable",
1252                              VAYUIPCINT_E_FAIL,
1253                              "Invalid procId specified");
1254     }
1255 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1257     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptDisable");
1261 /*!
1262  *  @brief      Function to wait for interrupt to be cleared.
1263  *
1264  *  @param      procId  Remote processor ID
1265  *  @param      intId   interrupt id
1266  *
1267  *  @sa         VAYUIpcInt_sendInterrupt
1268  */
1269 Int32
1270 VAYUIpcInt_waitClearInterrupt (UInt16 procId, UInt32 intId)
1272     Int32 status = VAYUIPCINT_SUCCESS;
1274     GT_2trace (curTrace,GT_ENTER,"VAYUIpcInt_waitClearInterrupt",
1275                procId, intId);
1277     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1278     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1280     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1281         /* Wait for DSP to clear the previous interrupt */
1282         while( (  REG32((  VAYUIpcInt_state.mailbox5Base
1283                         + MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX)))
1284                 & 0x3F ));
1285     }
1286     else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1287         /* Wait for VIDEOM4 to clear the previous interrupt */
1288         while( (  REG32((VAYUIpcInt_state.mailbox6Base
1289                       + MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX)))
1290                 & 0x3F ));
1291     }
1292 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1293     else {
1294         /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1295         status = VAYUIPCINT_E_FAIL;
1296         GT_setFailureReason (curTrace,
1297                              GT_4CLASS,
1298                              "VAYUIpcInt_waitClearInterrupt",
1299                              status,
1300                              "Invalid procId specified");
1301     }
1302 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1304     GT_1trace (curTrace,GT_LEAVE,"VAYUIpcInt_waitClearInterrupt", status);
1306     /*! @retval VAYUIPCINT_SUCCESS Wait for interrupt clearing successfully
1307                 completed. */
1308     return status ;
1312 /*!
1313  *  @brief      Function to send a specified interrupt to the DSP.
1314  *
1315  *  @param      procId  Remote processor ID
1316  *  @param      intId   interrupt id
1317  *  @param      value   Value to be sent with the interrupt
1318  *
1319  *  @sa         VAYUIpcInt_waitClearInterrupt
1320  */
1321 Int32
1322 VAYUIpcInt_sendInterrupt (UInt16 procId, UInt32 intId,  UInt32 value)
1324     Int32 status = VAYUIPCINT_SUCCESS;
1326     GT_3trace (curTrace, GT_ENTER, "VAYUIpcInt_sendInterrupt",
1327                procId, intId, value);
1329     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1330     GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1332     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1333         /*
1334          * Mailbox 5 is used for HOST<->DSP1 communication
1335          */
1336         if (REG32(VAYUIpcInt_state.mailbox5Base + \
1337                   MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX)) == 0)
1338             REG32(VAYUIpcInt_state.mailbox5Base + \
1339                   MAILBOX_MESSAGE_m_OFFSET(HOST_DSP1_SUB_MBOX)) = value;
1340         else
1341             GT_0trace (curTrace, GT_4CLASS, "Dropping HOST->DSP1 Mbox Msg");
1342     } else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1343         /*
1344          * Mailbox 6 is used for HOST<->DSP1 communication
1345          */
1346         REG32(VAYUIpcInt_state.mailbox6Base + \
1347               MAILBOX_MESSAGE_m_OFFSET(HOST_IPU2_SUB_MBOX)) = value;
1348     }
1349 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1350     else {
1351         /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1352         status = VAYUIPCINT_E_FAIL;
1353         GT_setFailureReason (curTrace,
1354                              GT_4CLASS,
1355                              "VAYUIpcInt_sendInterrupt",
1356                              status,
1357                              "Invalid procId specified");
1358     }
1359 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1361     GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_sendInterrupt",status);
1363     /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully sent */
1364     return status;
1368 /*!
1369  *  @brief      Function to clear the specified interrupt received from the
1370  *              remote core.
1371  *
1372  *  @param      procId  Remote processor ID
1373  *  @param      intId   interrupt id
1374  *
1375  *  @sa         VAYUIpcInt_sendInterrupt
1376  */
1377 UInt32
1378 VAYUIpcInt_clearInterrupt (UInt16 procId, UInt16 mboxNum)
1380     UInt32 retVal = 0;
1381     UInt32 mailboxBase = 0;
1383     GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_clearInterrupt", mboxNum);
1385     GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1387     if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2])
1388         mailboxBase = VAYUIpcInt_state.mailbox6Base;
1389     else
1390         mailboxBase = VAYUIpcInt_state.mailbox5Base;
1392     if (mboxNum < MAILBOX_MAXNUM) {
1393         /* Read the register to get the entry from the mailbox FIFO */
1394         retVal = REG32(mailboxBase + MAILBOX_MESSAGE_m_OFFSET(mboxNum));
1396         /* Clear the IRQ status.
1397          * If there are more in the mailbox FIFO, it will re-assert.
1398          */
1399         SET_BIT(REG(mailboxBase + MAILBOX_IRQSTATUS_CLEAR_OFFSET + \
1400                     (0x10 * VAYU_HOST_USER_ID)),
1401                     (mboxNum<<1));
1402     }
1403 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1404     else {
1405         GT_setFailureReason (curTrace,
1406                              GT_4CLASS,
1407                              "VAYUIpcInt_clearInterrupt",
1408                              VAYUIPCINT_E_FAIL,
1409                              "Invalid mailbox number specified");
1410     }
1411 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1413     GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_clearInterrupt");
1415     /*! @retval Value Value received with the interrupt. */
1416     return retVal;
1420 /*
1421  * Instead of constantly allocating and freeing the msg structures
1422  * we just cache a few of them, and recycle them instead.
1423  */
1424 #define CACHE_NUM 20
1425 static VAYUIpcInt_MsgListElem *msg_cache;
1426 static int num_msg = 0;
1428 static VAYUIpcInt_MsgListElem *get_msg()
1430     VAYUIpcInt_MsgListElem *msg;
1431     IArg key = NULL;
1433     key = Gate_enterSystem();
1434     msg = msg_cache;
1435     if (msg != NULL) {
1436         msg_cache = (VAYUIpcInt_MsgListElem *)msg_cache->next;
1437         num_msg--;
1438         Gate_leaveSystem(key);
1439     } else {
1440         Gate_leaveSystem(key);
1441         msg = Memory_alloc(NULL, sizeof(VAYUIpcInt_MsgListElem), 0, NULL);
1442     }
1443     return(msg);
1446 static void put_msg(VAYUIpcInt_MsgListElem * msg)
1448     IArg key = NULL;
1449     key = Gate_enterSystem();
1450     if (num_msg >= CACHE_NUM) {
1451         Gate_leaveSystem(key);
1452         Memory_free(NULL, msg, sizeof(*msg));
1453     } else {
1454         msg->next = (struct VAYUIpcInt_MsgListElem *)msg_cache;
1455         msg_cache = msg;
1456         num_msg++;
1457         Gate_leaveSystem(key);
1458     }
1459     return;
1463 /*!
1464  *  @brief      Function to check and clear the remote proc interrupt
1465  *
1466  *  @param      arg     Optional argument to the function.
1467  *
1468  *  @sa         _VAYUIpcInt_isr
1469  */
1470 static
1471 Bool
1472 _VAYUIpcInt_checkAndClearFunc (Ptr arg)
1474     UInt16 procId;
1475     UInt32 msg;
1476     VAYUIpcInt_MsgListElem * elem = NULL;
1478     GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_checkAndClearFunc", arg);
1480     if( REG32(  VAYUIpcInt_state.mailbox6Base
1481               + MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX)) != 0 ){
1482         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2];
1483         msg = VAYUIpcInt_clearInterrupt (procId, IPU2_HOST_SUB_MBOX);
1485         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from IPU2", msg);
1487         /* This is a message from IPU2, put the message in IPU2's list */
1488         elem = get_msg();
1489         if (elem) {
1490             elem->msg = msg;
1491             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1492         }
1493     }
1494     if( REG32(  VAYUIpcInt_state.mailbox5Base
1495               + MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX)) != 0 ){
1496         procId = VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1];
1497         msg = VAYUIpcInt_clearInterrupt (procId, DSP1_HOST_SUB_MBOX);
1499         GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from DSP1", msg);
1501         /* This is a message from DSP, put the message in DSP's list */
1502         elem = get_msg();
1503         if (elem) {
1504             elem->msg = msg;
1505             List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1506         }
1507     }
1509     GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_checkAndClearFunc", TRUE);
1511     /* This is not a shared interrupt, so interrupt has always occurred */
1512     /*! @retval TRUE Interrupt has occurred. */
1513     return (TRUE);
1517 /*!
1518  *  @brief      Interrupt Service Routine for VAYUIpcInt module
1519  *
1520  *  @param      arg     Optional argument to the function.
1521  *
1522  *  @sa         _VAYUIpcInt_checkAndClearFunc
1523  */
1524 static
1525 Bool
1526 _VAYUIpcInt_isr (Ptr ref)
1528     UInt16 i = 0;
1529     VAYUIpcInt_MsgListElem * elem = NULL;
1530     GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_isr", ref);
1532     for (i = 0 ; i < VAYUIpcInt_state.maxProcessors ; i++) {
1533         if ((elem = List_get(VAYUIpcInt_state.isrLists [i])) != NULL) {
1534             /*Calling the particular ISR */
1535             GT_assert(curTrace,(VAYUIpcInt_state.isrObjects [i].fxn != NULL));
1536             if (VAYUIpcInt_state.isrObjects [i].fxn != NULL) {
1537                 VAYUIpcInt_state.isrObjects [i].fxn (elem->msg,
1538                                     VAYUIpcInt_state.isrObjects [i].fxnArgs);
1539             }
1540             put_msg(elem);
1541         }
1542     }
1544     GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_isr", TRUE);
1546     /*! @retval TRUE Interrupt has been handled. */
1547     return (TRUE);
1550 #if defined (__cplusplus)
1552 #endif