Beispiel #1
0
/*!
 *  ======== InterruptBenelli_intShmMbxStub ========
 */
Void InterruptBenelli_intShmMbxStub(UArg arg)
{
    UInt16 index;
    UInt16 selfIdx;
    UInt16 loopIdx;
    InterruptBenelli_FxnTable *table;

    selfIdx = MultiProc_self();

    for (loopIdx = 0; loopIdx < MultiProc_getNumProcsInCluster(); loopIdx++) {

        if (loopIdx == selfIdx) {
            continue;
        }

        index = MBX_TABLE_IDX(loopIdx, selfIdx);

        if (((REG32(MAILBOX_STATUS(index)) != 0) && 
             (REG32(MAILBOX_IRQENABLE_SET(index)) & 
              MAILBOX_REG_VAL(SUBMBX_IDX(index))))) {
            table = &(InterruptBenelli_module->fxnTable[PROCID(loopIdx)]);
            (table->func)(table->arg);
        }
    }
}
Beispiel #2
0
/*!
 *  ======== InterruptDsp_intShmStub ======== 
 */
Void InterruptDsp_intShmStub(UArg arg)
{
    UInt16 index;
    UInt16 selfIdx;
    UInt16 loopIdx;
    InterruptDsp_FxnTable *table;    

    selfIdx = MultiProc_self();

    /* 
     * Loop through each Sub-mailbox to determine which one generated 
     * interrupt. 
     */
    for (loopIdx = 0; loopIdx < MultiProc_getNumProcsInCluster(); loopIdx++) {

        if (loopIdx == selfIdx) {
            continue;
        }

        index = MBX_TABLE_IDX(loopIdx, selfIdx);

        if ((REG32(MAILBOX_STATUS(index)) != 0) && 
            (REG32(MAILBOX_IRQENABLE_SET_DSP(index)) & 
             MAILBOX_REG_VAL(SUBMBX_IDX(index)))) {
            table = &(InterruptDsp_module->fxnTable[PROCID(loopIdx)]);    
            (table->func)(table->arg);     
        }
    }
}
Beispiel #3
0
/*!
 *  ======== InterruptBenelli_intUnregister ========
 */
Void InterruptBenelli_intUnregister(UInt16 remoteProcId,
                                   IInterrupt_IntInfo *intInfo)
{
    UInt                       mbxIdx;
    Int                        index;
    InterruptBenelli_FxnTable *table;
    Hwi_Handle                 hwiHandle;

    mbxIdx = MBX_BASEADDR_IDX(MBX_TABLE_IDX(remoteProcId, MultiProc_self()));

    index = PROCID(remoteProcId);

    /* Disable the mailbox interrupt source */
    InterruptBenelli_intDisable(remoteProcId, intInfo);

    /* Disable the interrupt itself */
    InterruptBenelli_module->numPlugged[mbxIdx]--;
    if (InterruptBenelli_module->numPlugged[mbxIdx] == 0) {
        hwiHandle = Hwi_getHandle(intInfo->localIntId);
        Hwi_delete(&hwiHandle);
    }

    /* Clear the FxnTable entry for the remote processor */
    table = &(InterruptBenelli_module->fxnTable[index]);
    table->func = NULL;
    table->arg  = 0;
}
Beispiel #4
0
/*!
 *  ======== InterruptDsp_intSend ========
 *  Send interrupt to the remote processor
 */
Void InterruptDsp_intSend(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo,
                          UArg arg)
{
    UInt key;
    UInt16 index;

    index = MBX_TABLE_IDX(MultiProc_self(), remoteProcId);
    
    /* 
     *  Before writing to a mailbox, check whehter it already contains a message
     *  If so, then don't write to the mailbox since we want one and only one
     *  message per interrupt.  Disable interrupts between reading 
     *  the MSGSTATUS_X register and writing to the mailbox to protect from 
     *  another thread doing an intSend at the same time
     *
     *  Note regarding possible race condition between local 'intSend' and 
     *  remote 'intClear':
     *  It is possible that we we read the MAILBOX_MSGSTATUS_X register during
     *  the remote side's intClear.  Therefore, we might choose _not_ to send
     *  write to the mailbox even though the mailbox is about to be cleared a
     *  few cycles later. In this case, the interrupt will be lost.
     *  This is OK, however. intClear should always be called by the Notify
     *  driver _before_ shared memory is read, so the event will be picked up
     *  anyway by the previous interrupt that caused intClear to be called.
     */
    key = Hwi_disable();
    if (REG32(MAILBOX_STATUS(index)) == 0) {
        REG32(MAILBOX_MESSAGE(index)) = arg;
    }
    Hwi_restore(key);
}
Beispiel #5
0
/*!
 *  ======== InterruptArp32_intEnable ========
 *  Enable remote processor interrupt
 */
Void InterruptArp32_intEnable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
{
    UInt16 index;

    index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
    
    REG32(MAILBOX_IRQENABLE_SET(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index));
}
Beispiel #6
0
/*!
 *  ======== InterruptBenelli_intClear ========
 *  Clear interrupt
 */
UInt InterruptBenelli_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
{
    UInt arg;
    UInt16 index;

    index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
    arg = REG32(MAILBOX_MESSAGE(index));
    REG32(MAILBOX_IRQSTATUS_CLR(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index));

    return (arg);
}
Beispiel #7
0
/*!
 *  ======== InterruptDsp_intDisable ========
 *  Disables remote processor interrupt
 */     
Void InterruptDsp_intDisable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
{
    UInt16 index;

    Assert_isTrue(((remoteProcId < MultiProc_getNumProcsInCluster()) &&
            (remoteProcId != MultiProc_self())), ti_sdo_ipc_Ipc_A_internal);

    index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());

    REG32(MAILBOX_IRQENABLE_CLR_DSP(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index));
}
Beispiel #8
0
/*!
 *  ======== InterruptBenelli_intEnable ========
 *  Enable remote processor interrupt
 */
Void InterruptBenelli_intEnable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
{
    UInt16 index;

    index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
    /*  
     *  If the remote processor communicates via mailboxes, we should enable 
     *  the Mailbox IRQ instead of enabling the Hwi because multiple mailboxes
     *  share the same Hwi
     */
    REG32(MAILBOX_IRQENABLE_SET(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index));
}
Beispiel #9
0
/*!
 *  ======== InterruptBenelli_intRegister ========
 */
Void InterruptBenelli_intRegister(UInt16 remoteProcId,
                                 IInterrupt_IntInfo *intInfo,
                                 Fxn func, UArg arg)
{
    Hwi_Params  hwiAttrs;
    UInt        key;
    UInt        mbxIdx;
    Int         index;
    InterruptBenelli_FxnTable *table;

    Assert_isTrue(remoteProcId < ti_sdo_utils_MultiProc_numProcessors, 
            ti_sdo_ipc_Ipc_A_internal);

    /* Assert that our MultiProc id is set correctly */
    Assert_isTrue((InterruptBenelli_benelliProcId == MultiProc_self()),
                  ti_sdo_ipc_Ipc_A_internal);

    mbxIdx = MBX_BASEADDR_IDX(MBX_TABLE_IDX(remoteProcId, MultiProc_self()));

    index = PROCID(remoteProcId);

    intInfo->localIntId = InterruptBenelli_benelliInterruptTable[index];

    /* Disable global interrupts */
    key = Hwi_disable();

    table = &(InterruptBenelli_module->fxnTable[index]);
    table->func = func;
    table->arg  = arg;

    InterruptBenelli_intClear(remoteProcId, intInfo);

    Hwi_Params_init(&hwiAttrs);
    hwiAttrs.maskSetting = Hwi_MaskingOption_LOWER;

    /* Make sure the interrupt only gets plugged once */
    InterruptBenelli_module->numPlugged[mbxIdx]++;
    if (InterruptBenelli_module->numPlugged[mbxIdx] == 1) {
        Hwi_create(intInfo->localIntId,
                   (Hwi_FuncPtr)InterruptBenelli_intShmMbxStub,
                    &hwiAttrs,
                    NULL);
            
        /* Interrupt_intEnable won't enable the Hwi */
        Hwi_enableInterrupt(intInfo->localIntId);
    }
    
    InterruptBenelli_intEnable(remoteProcId, intInfo);
    
    /* Restore global interrupts */
    Hwi_restore(key);
}
Beispiel #10
0
/*!
 *  ======== InterruptBenelli_intPost ========
 *  Simulate an interrupt from a remote processor
 */
Void InterruptBenelli_intPost(UInt16 srcProcId, IInterrupt_IntInfo *intInfo,
                             UArg arg)
{
    UInt key;
    UInt16 index;

    index = MBX_TABLE_IDX(srcProcId, MultiProc_self());
    key = Hwi_disable();
    if (REG32(MAILBOX_STATUS(index)) == 0) {
        REG32(MAILBOX_MESSAGE(index)) = arg;
    }
    Hwi_restore(key);
}
Beispiel #11
0
/*!
 *  ======== InterruptDsp_intClear ========
 *  Clear interrupt 
 */
UInt InterruptDsp_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
{
    UInt arg;
    UInt16 index;
    
    index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
    
    arg = REG32(MAILBOX_MESSAGE(index));
    REG32(MAILBOX_IRQSTATUS_CLR_DSP(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index));
    
    /* Write to EOI (End Of Interrupt) register */
    REG32(MAILBOX_EOI_REG(index)) = 0x1;

    return (arg);
}
Beispiel #12
0
/*!
 *  ======== InterruptArp32_intPost ========
 *  Simulate an interrupt from a remote processor
 */
Void InterruptArp32_intPost(UInt16 srcProcId, IInterrupt_IntInfo *intInfo,
                             UArg arg)
{
    UInt key;
    UInt16 index;

    index = MBX_TABLE_IDX(srcProcId, MultiProc_self());

    /* disable interrupts */
    key = Hwi_disable();

    if (REG32(MAILBOX_STATUS(index)) == 0) {
        /* write the mailbox message to arp32 */
        REG32(MAILBOX_MESSAGE(index)) = arg;
    }
    
    /* restore interrupts */
    Hwi_restore(key);
}