615fd73e25068df66f732930399e5cef86a1fb83
[ipc/ipcdev.git] / packages / ti / sdo / ipc / family / vayu / InterruptIpu.c
1 /*
2  * Copyright (c) 2013-2014, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*
33  *  ======== InterruptIpu.c ========
34  *  Vayu IPU based interupt manager
35  */
37 #include <xdc/std.h>
38 #include <xdc/runtime/Assert.h>
39 #include <xdc/runtime/System.h>
40 #include <xdc/runtime/Startup.h>
42 #include <ti/sysbios/BIOS.h>
43 #include <ti/sysbios/family/shared/vayu/IntXbar.h>
44 #include <ti/sysbios/family/arm/m3/Hwi.h>
45 #include <ti/sysbios/family/arm/ducati/Core.h>
46 #include <ti/sdo/ipc/notifyDrivers/IInterrupt.h>
47 #include <ti/sdo/utils/_MultiProc.h>
49 #include "package/internal/InterruptIpu.xdc.h"
51 /* Register access method. */
52 #define REG16(A)   (*(volatile UInt16 *) (A))
53 #define REG32(A)   (*(volatile UInt32 *) (A))
55 /*
56  *  Ducati control register that maintains inter-core interrupt bits.
57  *
58  *  Using separate CORE0 and CORE1 values to do 16-bit reads/writes
59  *  because we do not want to overwrite the other cores value.
60  */
61 #define INTERRUPT_CORE0         (InterruptIpu_ducatiCtrlBaseAddr)
62 #define INTERRUPT_CORE1         (InterruptIpu_ducatiCtrlBaseAddr + 2)
64 #define PROCID(IDX)               (InterruptIpu_procIdTable[(IDX)])
65 #define MBX_TABLE_IDX(SRC, DST)   ((PROCID(SRC) * InterruptIpu_NUM_CORES) + \
66                                     PROCID(DST))
67 #define SUBMBX_IDX(IDX)           (InterruptIpu_mailboxTable[(IDX)] & 0xFF)
68 #define MBX_USER_IDX(IDX)         ((InterruptIpu_mailboxTable[(IDX)] >> 8) \
69                                     & 0xFF)
70 #define MBX_BASEADDR_IDX(IDX)    ((InterruptIpu_mailboxTable[(IDX)] >> 16) \
71                                     & 0xFFFF)
73 #define MAILBOX_REG_VAL(M)        (0x1 << (2 * M))
75 #define MAILBOX_MESSAGE(IDX)      (InterruptIpu_mailboxBaseAddr[  \
76                                     MBX_BASEADDR_IDX(IDX)] + 0x40 +   \
77                                     (0x4 * SUBMBX_IDX(IDX)))
78 #define MAILBOX_STATUS(IDX)       (InterruptIpu_mailboxBaseAddr[  \
79                                     MBX_BASEADDR_IDX(IDX)] + 0xC0 +   \
80                                     (0x4 * SUBMBX_IDX(IDX)))
82 #define MAILBOX_IRQSTATUS_CLR(IDX)   (InterruptIpu_mailboxBaseAddr[  \
83                                         MBX_BASEADDR_IDX(IDX)] + (0x10 * \
84                                         MBX_USER_IDX(IDX)) + 0x104)
85 #define MAILBOX_IRQENABLE_SET(IDX)   (InterruptIpu_mailboxBaseAddr[  \
86                                         MBX_BASEADDR_IDX(IDX)] + (0x10 * \
87                                         MBX_USER_IDX(IDX)) + 0x108)
88 #define MAILBOX_IRQENABLE_CLR(IDX)   (InterruptIpu_mailboxBaseAddr[  \
89                                         MBX_BASEADDR_IDX(IDX)] + (0x10 * \
90                                         MBX_USER_IDX(IDX)) + 0x10C)
91 #define MAILBOX_EOI_REG(IDX)         (InterruptIpu_mailboxBaseAddr[  \
92                                         MBX_BASEADDR_IDX(IDX)] + 0x140)
94 #define WUGENIPU        19
96 /*
97  *************************************************************************
98  *                      Module functions
99  *************************************************************************
100  */
102 /*
103  *  ======== InterruptIpu_Module_startup ========
104  */
105 Int InterruptIpu_Module_startup(Int phase)
107     if (IntXbar_Module_startupDone()) {
108         /* connect mailbox interrupts at startup */
109         if (Core_ipuId == 1) {
110             if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
111                 /* IPU1-0 */
112                 IntXbar_connect(42, 285);  // eve1 mailbox 0 user 2
113                 IntXbar_connect(43, 294);  // eve2 mailbox 0 user 2
114                 IntXbar_connect(44, 250);  // system mailbox 5 user 1
115                 InterruptIpu_module->interruptTable[4] = 66;    // DSP1
116                 InterruptIpu_module->interruptTable[8] = 66;    // HOST
117                 InterruptIpu_module->interruptTable[9] = 19;    // IPU1-1
119                 /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */
120                 if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) ||
121                     (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) {
122                     IntXbar_connect(45, 303);  // eve3 mailbox 0 user 2
123                     IntXbar_connect(46, 312);  // eve4 mailbox 0 user 2
124                 }
126                 /* plug mbx7 only if DSP2 or IPU2 exists */
127                 if ((MultiProc_getId("DSP2") != MultiProc_INVALIDID) ||
128                     (MultiProc_getId("IPU2") != MultiProc_INVALIDID) ||
129                     (MultiProc_getId("IPU2-0") != MultiProc_INVALIDID)) {
130                     IntXbar_connect(47, 259);  // system mailbox 7 user 2
131                     InterruptIpu_module->interruptTable[5] = 69;    // DSP2
132                     InterruptIpu_module->interruptTable[7] = 69;    // IPU2-0
133                 }
135                 /* plug mbx8 only if IPU2-1 exists */
136                 if (MultiProc_getId("IPU2-1") != MultiProc_INVALIDID) {
137                     IntXbar_connect(48, 263);  // system mailbox 8 user 2
138                     InterruptIpu_module->interruptTable[10] = 70;    // IPU2-1
139                 }
140             }
141             else { /* IPU1-1 */
142                 IntXbar_connect(49, 289);  // eve1 mailbox 1 user 3
143                 IntXbar_connect(50, 298);  // eve2 mailbox 1 user 3
144                 IntXbar_connect(51, 252);  // system mailbox 5 user 3
145                 InterruptIpu_module->interruptTable[4] = 73;    // DSP1
146                 InterruptIpu_module->interruptTable[8] = 73;    // HOST
147                 InterruptIpu_module->interruptTable[6] = 19;    // IPU1-0
149                 /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */
150                 if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) ||
151                     (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) {
152                     IntXbar_connect(52, 307);  // eve3 mailbox 1 user 3
153                     IntXbar_connect(53, 316);  // eve4 mailbox 1 user 3
154                 }
156                 /* plug mbx8 only if DSP2 or IPU2 exists */
157                 if ((MultiProc_getId("DSP2") != MultiProc_INVALIDID) ||
158                     (MultiProc_getId("IPU2") != MultiProc_INVALIDID) ||
159                     (MultiProc_getId("IPU2-0") != MultiProc_INVALIDID)) {
160                     IntXbar_connect(54, 263);  // system mailbox 8 user 2
161                     InterruptIpu_module->interruptTable[5] = 76;    // DSP2
162                     InterruptIpu_module->interruptTable[7] = 76;    // IPU2-0
163                 }
164             }
165         }
166         else {
167             if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
168                 /* IPU2-0 */
169                 IntXbar_connect(42, 288);  // eve1 mailbox 1 user 2
170                 IntXbar_connect(43, 297);  // eve2 mailbox 1 user 2
171                 IntXbar_connect(44, 254);  // system mailbox 6 user 1
172                 InterruptIpu_module->interruptTable[5] = 66;    // DSP2
173                 InterruptIpu_module->interruptTable[8] = 66;    // HOST
174                 InterruptIpu_module->interruptTable[10] = 19;    // IPU2-1
176                 /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */
177                 if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) ||
178                     (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) {
179                     IntXbar_connect(45, 306);  // eve3 mailbox 1 user 2
180                     IntXbar_connect(46, 315);  // eve4 mailbox 1 user 2
181                 }
183                 /* plug mbx7 only if DSP1 or IPU1 exists */
184                 if ((MultiProc_getId("DSP1") != MultiProc_INVALIDID) ||
185                     (MultiProc_getId("IPU1") != MultiProc_INVALIDID) ||
186                     (MultiProc_getId("IPU1-0") != MultiProc_INVALIDID)) {
187                     IntXbar_connect(47, 260);  // system mailbox 7 user 3
188                     InterruptIpu_module->interruptTable[4] = 69;    // DSP1
189                     InterruptIpu_module->interruptTable[6] = 69;    // IPU1-0
190                 }
192                 /* plug mbx8 only if IPU1-1 exists */
193                 if (MultiProc_getId("IPU1-1") != MultiProc_INVALIDID) {
194                     IntXbar_connect(48, 264);  // system mailbox 8 user 3
195                     InterruptIpu_module->interruptTable[9] = 70;    // IPU1-1
196                 }
197             }
198             else { /* IPU2-1 */
199                 IntXbar_connect(49, 289);  // eve1 mailbox 1 user 3
200                 IntXbar_connect(50, 298);  // eve2 mailbox 1 user 3
201                 IntXbar_connect(51, 256);  // system mailbox 6 user 3
202                 InterruptIpu_module->interruptTable[5] = 73;    // DSP2
203                 InterruptIpu_module->interruptTable[8] = 73;    // HOST
204                 InterruptIpu_module->interruptTable[7] = 19;    // IPU2-0
206                 /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */
207                 if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) ||
208                     (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) {
209                     IntXbar_connect(52, 307);  // eve3 mailbox 1 user 3
210                     IntXbar_connect(53, 316);  // eve4 mailbox 1 user 3
211                 }
213                 /* plug mbx8 only if DSP2 or IPU2 exists */
214                 if ((MultiProc_getId("DSP1") != MultiProc_INVALIDID) ||
215                     (MultiProc_getId("IPU1") != MultiProc_INVALIDID) ||
216                     (MultiProc_getId("IPU1-0") != MultiProc_INVALIDID)) {
217                     IntXbar_connect(54, 264);  // system mailbox 8 user 3
218                     InterruptIpu_module->interruptTable[4] = 76;    // DSP1
219                     InterruptIpu_module->interruptTable[6] = 76;    // IPU1-0
220                 }
221             }
222         }
224         return (Startup_DONE);
225     }
227     return (Startup_NOTDONE);
230 /*
231  *  ======== InterruptIpu_intEnable ========
232  *  Enable remote processor interrupt
233  */
234 Void InterruptIpu_intEnable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
236     UInt16 index;
237     Bool useMailbox = TRUE;
238     UInt8 subMbxIdx;
240     index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
242     if (Core_ipuId == 1) {
243         if ((remoteProcId == InterruptIpu_ipu1_0ProcId) ||
244             (remoteProcId == InterruptIpu_ipu1_1ProcId)) {
245             Hwi_enableInterrupt(WUGENIPU);
246             useMailbox = FALSE;
247         }
248     }
249     else {
250         if ((remoteProcId == InterruptIpu_ipu2_0ProcId) ||
251             (remoteProcId == InterruptIpu_ipu2_1ProcId)) {
252             Hwi_enableInterrupt(WUGENIPU);
253             useMailbox = FALSE;
254         }
255     }
257     /*  If the remote processor communicates via mailboxes, we should enable
258      *  the Mailbox IRQ instead of enabling the Hwi because multiple mailboxes
259      *  share the same Hwi
260      */
261     if (useMailbox) {
262         subMbxIdx = SUBMBX_IDX(index);
263         REG32(MAILBOX_IRQENABLE_SET(index)) = MAILBOX_REG_VAL(subMbxIdx);
264     }
267 /*
268  *  ======== InterruptIpu_intDisable ========
269  *  Disables remote processor interrupt
270  */
271 Void InterruptIpu_intDisable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
273     UInt16 index;
274     Bool useMailbox = TRUE;
275     UInt8 subMbxIdx;
277     if (Core_ipuId == 1) {
278         if ((remoteProcId == InterruptIpu_ipu1_0ProcId) ||
279             (remoteProcId == InterruptIpu_ipu1_1ProcId)) {
280             Hwi_disableInterrupt(WUGENIPU);
281             useMailbox = FALSE;
282         }
283     }
284     else {
285         if ((remoteProcId == InterruptIpu_ipu2_0ProcId) ||
286             (remoteProcId == InterruptIpu_ipu2_1ProcId)) {
287             Hwi_disableInterrupt(WUGENIPU);
288             useMailbox = FALSE;
289         }
290     }
292     index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
294     /*  If the remote processor communicates via mailboxes, we should disable
295      *  the Mailbox IRQ instead of disabling the Hwi because multiple mailboxes
296      *  share the same Hwi
297      */
298     if (useMailbox) {
299         subMbxIdx = SUBMBX_IDX(index);
300         REG32(MAILBOX_IRQENABLE_CLR(index)) = MAILBOX_REG_VAL(subMbxIdx);
301     }
304 /*
305  *  ======== InterruptIpu_intRegister ========
306  */
307 Void InterruptIpu_intRegister(UInt16 remoteProcId,
308                               IInterrupt_IntInfo *intInfo,
309                               Fxn func, UArg arg)
311     Hwi_Params  hwiAttrs;
312     UInt        key;
313     UInt        mbxIdx;
314     Int         index;
315     InterruptIpu_FxnTable *table;
317     Assert_isTrue(remoteProcId < ti_sdo_utils_MultiProc_numProcessors,
318             ti_sdo_utils_MultiProc_A_invalidMultiProcId);
320     mbxIdx = MBX_BASEADDR_IDX(MBX_TABLE_IDX(remoteProcId, MultiProc_self()));
322     index = PROCID(remoteProcId);
324     intInfo->localIntId = InterruptIpu_module->interruptTable[index];
326     /* Disable global interrupts */
327     key = Hwi_disable();
329     table = &(InterruptIpu_module->fxnTable[index]);
330     table->func = func;
331     table->arg  = arg;
333     InterruptIpu_intClear(remoteProcId, intInfo);
335     Hwi_Params_init(&hwiAttrs);
336     hwiAttrs.maskSetting = Hwi_MaskingOption_LOWER;
338     if (Core_ipuId == 1) {
339         if ((remoteProcId == InterruptIpu_ipu1_0ProcId) ||
340             (remoteProcId == InterruptIpu_ipu1_1ProcId)) {
341             Hwi_create(intInfo->localIntId,
342                    (Hwi_FuncPtr)InterruptIpu_intShmDucatiStub,
343                    &hwiAttrs,
344                    NULL);
345         }
346         else {
347             /* Make sure the interrupt only gets plugged once */
348             InterruptIpu_module->numPlugged[mbxIdx]++;
349             if (InterruptIpu_module->numPlugged[mbxIdx] == 1) {
350                 Hwi_create(intInfo->localIntId,
351                            (Hwi_FuncPtr)InterruptIpu_intShmMbxStub,
352                             &hwiAttrs,
353                             NULL);
355                 /* Interrupt_intEnable won't enable the Hwi */
356                 Hwi_enableInterrupt(intInfo->localIntId);
357             }
358         }
359     }
360     else {
361         if ((remoteProcId == InterruptIpu_ipu2_0ProcId) ||
362             (remoteProcId == InterruptIpu_ipu2_1ProcId)) {
363             Hwi_create(intInfo->localIntId,
364                    (Hwi_FuncPtr)InterruptIpu_intShmDucatiStub,
365                    &hwiAttrs,
366                    NULL);
367         }
368         else {
369             /* Make sure the interrupt only gets plugged once */
370             InterruptIpu_module->numPlugged[mbxIdx]++;
371             if (InterruptIpu_module->numPlugged[mbxIdx] == 1) {
372                 Hwi_create(intInfo->localIntId,
373                            (Hwi_FuncPtr)InterruptIpu_intShmMbxStub,
374                             &hwiAttrs,
375                             NULL);
377                 /* Interrupt_intEnable won't enable the Hwi */
378                 Hwi_enableInterrupt(intInfo->localIntId);
379             }
380         }
381     }
383     InterruptIpu_intEnable(remoteProcId, intInfo);
385     /* Restore global interrupts */
386     Hwi_restore(key);
389 /*
390  *  ======== InterruptIpu_intUnregister ========
391  */
392 Void InterruptIpu_intUnregister(UInt16 remoteProcId,
393                                 IInterrupt_IntInfo *intInfo)
395     UInt                       mbxIdx;
396     Int                        index;
397     InterruptIpu_FxnTable *table;
398     Hwi_Handle                 hwiHandle;
400     mbxIdx = MBX_BASEADDR_IDX(MBX_TABLE_IDX(remoteProcId, MultiProc_self()));
402     index = PROCID(remoteProcId);
404     /* Disable the mailbox interrupt source */
405     InterruptIpu_intDisable(remoteProcId, intInfo);
407     if (Core_ipuId == 1) {
408         if ((remoteProcId == InterruptIpu_ipu1_0ProcId) ||
409             (remoteProcId == InterruptIpu_ipu1_1ProcId)) {
410             hwiHandle = Hwi_getHandle(WUGENIPU);
411             Hwi_delete(&hwiHandle);
412         }
413         else {
414             /* Disable the interrupt itself */
415             InterruptIpu_module->numPlugged[mbxIdx]--;
416             if (InterruptIpu_module->numPlugged[mbxIdx] == 0) {
417                 hwiHandle = Hwi_getHandle(intInfo->localIntId);
418                 Hwi_delete(&hwiHandle);
419             }
420         }
421     }
422     else {
423         if ((remoteProcId == InterruptIpu_ipu2_0ProcId) ||
424             (remoteProcId == InterruptIpu_ipu2_1ProcId)) {
425             hwiHandle = Hwi_getHandle(WUGENIPU);
426             Hwi_delete(&hwiHandle);
427         }
428         else {
429             /* Disable the interrupt itself */
430             InterruptIpu_module->numPlugged[mbxIdx]--;
431             if (InterruptIpu_module->numPlugged[mbxIdx] == 0) {
432                 hwiHandle = Hwi_getHandle(intInfo->localIntId);
433                 Hwi_delete(&hwiHandle);
434             }
435         }
436     }
438     /* Clear the FxnTable entry for the remote processor */
439     table = &(InterruptIpu_module->fxnTable[index]);
440     table->func = NULL;
441     table->arg  = 0;
445 /*
446  *  ======== InterruptIpu_intSend ========
447  *  Send interrupt to the remote processor
448  */
449 Void InterruptIpu_intSend(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo,
450                              UArg arg)
452     UInt key;
453     UInt16 index;
455     if (Core_ipuId == 1) {
456         if ((remoteProcId == InterruptIpu_ipu1_0ProcId) ||
457             (remoteProcId == InterruptIpu_ipu1_1ProcId)) {
458             if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
459                 /* CORE1 to CORE0 */
460                 REG16(INTERRUPT_CORE0) |= 0x1;
461             }
462             else {
463                 /* CORE0 to CORE1 */
464                 REG16(INTERRUPT_CORE1) |= 0x1;
465             }
466         }
467         else {
468             index = MBX_TABLE_IDX(MultiProc_self(), remoteProcId);
469             key = Hwi_disable();
470             while (REG32(MAILBOX_STATUS(index)) != 0) {
471                 Hwi_restore(key);
472                 key = Hwi_disable();
473             }
474             REG32(MAILBOX_MESSAGE(index)) = arg;
475             Hwi_restore(key);
476         }
477     }
478     else {
479         if ((remoteProcId == InterruptIpu_ipu2_0ProcId) ||
480             (remoteProcId == InterruptIpu_ipu2_1ProcId)) {
481             if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
482                 /* CORE1 to CORE0 */
483                 REG16(INTERRUPT_CORE0) |= 0x1;
484             }
485             else {
486                 /* CORE0 to CORE1 */
487                 REG16(INTERRUPT_CORE1) |= 0x1;
488             }
489         }
490         else {
491             index = MBX_TABLE_IDX(MultiProc_self(), remoteProcId);
492             key = Hwi_disable();
493             while (REG32(MAILBOX_STATUS(index)) != 0) {
494                 Hwi_restore(key);
495                 key = Hwi_disable();
496             }
497             REG32(MAILBOX_MESSAGE(index)) = arg;
498             Hwi_restore(key);
499         }
500     }
504 /*
505  *  ======== InterruptIpu_intPost ========
506  *  Simulate an interrupt from a remote processor
507  */
508 Void InterruptIpu_intPost(UInt16 srcProcId, IInterrupt_IntInfo *intInfo,
509                              UArg arg)
511     UInt key;
512     UInt16 index;
514     if (Core_ipuId == 1) {
515         if ((srcProcId == InterruptIpu_ipu1_0ProcId) ||
516             (srcProcId == InterruptIpu_ipu1_1ProcId)) {
517             if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
518                 /* CORE0 to CORE1 */
519                 REG16(INTERRUPT_CORE1) |= 0x1;
520             }
521             else {
522                 /* CORE1 to CORE0 */
523                 REG16(INTERRUPT_CORE0) |= 0x1;
524             }
525         }
526         else {
527             index = MBX_TABLE_IDX(srcProcId, MultiProc_self());
528             key = Hwi_disable();
529             if (REG32(MAILBOX_STATUS(index)) == 0) {
530                 REG32(MAILBOX_MESSAGE(index)) = arg;
531             }
532             Hwi_restore(key);
533         }
534     }
535     else {
536         if ((srcProcId == InterruptIpu_ipu2_0ProcId) ||
537             (srcProcId == InterruptIpu_ipu2_1ProcId)) {
538             if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
539                 /* CORE0 to CORE1 */
540                 REG16(INTERRUPT_CORE1) |= 0x1;
541             }
542             else {
543                 /* CORE1 to CORE0 */
544                 REG16(INTERRUPT_CORE0) |= 0x1;
545             }
546         }
547         else {
548             index = MBX_TABLE_IDX(srcProcId, MultiProc_self());
549             key = Hwi_disable();
550             if (REG32(MAILBOX_STATUS(index)) == 0) {
551                 REG32(MAILBOX_MESSAGE(index)) = arg;
552             }
553             Hwi_restore(key);
554         }
555     }
558 /*
559  *  ======== InterruptIpu_intClear ========
560  *  Clear interrupt
561  */
562 UInt InterruptIpu_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
564     UInt arg;
565     UInt16 index;
567     if (Core_ipuId == 1) {
568         if ((remoteProcId == InterruptIpu_ipu1_0ProcId) ||
569             (remoteProcId == InterruptIpu_ipu1_1ProcId)) {
570             arg = REG32(InterruptIpu_ducatiCtrlBaseAddr);
572             /* Look at BIOS's ducati Core id */
573             if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
574                 if ((REG16(INTERRUPT_CORE0) & 0x1) == 0x1) {
575                     /* CORE1 to CORE0 */
576                     REG16(INTERRUPT_CORE0) &= ~(0x1);
577                 }
578             }
579             else {
580                 if ((REG16(INTERRUPT_CORE1) & 0x1) == 0x1) {
581                     /* CORE0 to CORE1 */
582                     REG16(INTERRUPT_CORE1) &= ~(0x1);
583                 }
584             }
585         }
586         else {
587             index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
588             arg = REG32(MAILBOX_MESSAGE(index));
589             REG32(MAILBOX_IRQSTATUS_CLR(index)) =
590                 MAILBOX_REG_VAL(SUBMBX_IDX(index));
591         }
592     }
593     else {
594         if ((remoteProcId == InterruptIpu_ipu2_0ProcId) ||
595             (remoteProcId == InterruptIpu_ipu2_1ProcId)) {
596             arg = REG32(InterruptIpu_ducatiCtrlBaseAddr);
598             /* Look at BIOS's ducati Core id */
599             if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
600                 if ((REG16(INTERRUPT_CORE0) & 0x1) == 0x1) {
601                     /* CORE1 to CORE0 */
602                     REG16(INTERRUPT_CORE0) &= ~(0x1);
603                 }
604             }
605             else {
606                 if ((REG16(INTERRUPT_CORE1) & 0x1) == 0x1) {
607                     /* CORE0 to CORE1 */
608                     REG16(INTERRUPT_CORE1) &= ~(0x1);
609                 }
610             }
611         }
612         else {
613             index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
614             arg = REG32(MAILBOX_MESSAGE(index));
615             REG32(MAILBOX_IRQSTATUS_CLR(index)) =
616                 MAILBOX_REG_VAL(SUBMBX_IDX(index));
617         }
618     }
620     return (arg);
623 /*
624  *************************************************************************
625  *                      Internals functions
626  *************************************************************************
627  */
629  /*
630  *  ======== InterruptIpu_intShmDucatiStub ========
631  */
632 Void InterruptIpu_intShmDucatiStub(UArg arg)
634     UInt16 index;
635     InterruptIpu_FxnTable *table;
637     if (Core_ipuId == 1) {
638         if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
639             index = 9;
640         }
641         else {
642             index = 6;
643         }
644     }
645     else {
646         if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
647             index = 10;
648         }
649         else {
650             index = 7;
651         }
652     }
654     table = &(InterruptIpu_module->fxnTable[index]);
655     (table->func)(table->arg);
659 /*
660  *  ======== InterruptIpu_intShmMbxStub ========
661  */
662 Void InterruptIpu_intShmMbxStub(UArg arg)
664     UInt16 index;
665     UInt16 selfIdx;
666     UInt16 loopIdx;
667     InterruptIpu_FxnTable *table;
669     selfIdx = MultiProc_self();
671     for (loopIdx = 0; loopIdx < MultiProc_getNumProcsInCluster(); loopIdx++) {
673         if (loopIdx == selfIdx) {
674             continue;
675         }
677         index = MBX_TABLE_IDX(loopIdx, selfIdx);
679         /* skip mailbox if it's not being used */
680         if (InterruptIpu_mailboxTable[index] == (UInt32)(-1)) {
681             continue;
682         }
684         if (((REG32(MAILBOX_STATUS(index)) != 0) &&
685              (REG32(MAILBOX_IRQENABLE_SET(index)) &
686               MAILBOX_REG_VAL(SUBMBX_IDX(index))))) {
687             table = &(InterruptIpu_module->fxnTable[PROCID(loopIdx)]);
688             (table->func)(table->arg);
689         }
690     }