/* * ======== Hwi_dispatchIRQC ======== * Configurable IRQ interrupt dispatcher. */ Void Hwi_dispatchIRQC(Hwi_Irp irp) { /* * Enough room is reserved above the isr stack to handle * as many as 16 32-bit stack resident local variables. * If the dispatcher requires more than this, you must * handle this in Hwi_Module_startup(). */ Hwi_Object *hwi; BIOS_ThreadType prevThreadType; UInt intNum; Char *oldTaskSP; Int tskKey; Int swiKey; Int i; /* save irp somewhere that survives the stack switch */ Hwi_module->irp = irp; if (Hwi_dispatcherTaskSupport) { tskKey = TASK_DISABLE(); /* * If this is a non-nested interrupt, * tskkey is saved on the task stack. * It must not be referenced again until * switching back to the task stack!!!! * All other local variables will be * on the isr stack. */ } /* * Switch to Hwi stack if not already on it. * This step, and the corresponding switch back to the task * stack are performed outside the "if (Hwi_dispatcherTaskSupport)" * conditionals because sometimes the generated code placed a copy * of Hwi_dispatcherTaskSupport on the task stack for use below. */ oldTaskSP = Hwi_switchToIsrStack(); /* * all references to local variables beyond this point * will be on the isr stack */ if (Hwi_dispatcherSwiSupport) { swiKey = SWI_DISABLE(); } /* set thread type to Hwi */ prevThreadType = BIOS_setThreadType(BIOS_ThreadType_Hwi); /* Porcess ALL pending and enabled interrupts */ do { intNum = Hwi_l1Intc.SIR_IRQ; /* get current L1 int num */ if (intNum == 0) { /* is from L2? */ intNum = Hwi_l2Intc.SIR_IRQ; /* get current L2 int num */ intNum += 32; /* force to linear index */ } hwi = Hwi_module->dispatchTable[intNum]; hwi->irp = Hwi_module->irp; #ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS /* call the begin hooks */ for (i = 0; i < Hwi_hooks.length; i++) { if (Hwi_hooks.elem[i].beginFxn != NULL) { Hwi_hooks.elem[i].beginFxn((IHwi_Handle)hwi); } } #endif Log_write5(Hwi_LM_begin, (IArg)hwi, (IArg)hwi->fxn, (IArg)prevThreadType, (IArg)intNum, hwi->irp); (hwi->fxn)(hwi->arg); Hwi_disable(); Log_write1(Hwi_LD_end, (IArg)hwi); #ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS /* call the end hooks */ for (i = 0; i < Hwi_hooks.length; i++) { if (Hwi_hooks.elem[i].endFxn != NULL) { Hwi_hooks.elem[i].endFxn((IHwi_Handle)hwi); } } #endif if (intNum > 31) { /* is from L2? */ Hwi_l2Intc.CONTROL = L2_NEW_IRQ_AGR;/* force NEW_IRQ_AGR */ } Hwi_l1Intc.CONTROL = L1_NEW_IRQ_AGR; /* force NEW_IRQ_AGR */ } /* loop thru all active and enabled IRQ ints */ while (Hwi_l1Intc.ITR & ~Hwi_l1Intc.MIR & Hwi_module->irq0Mask); /* Run Swi scheduler */ if (Hwi_dispatcherSwiSupport) { SWI_RESTORE(swiKey); } /* restore thread type */ BIOS_setThreadType(prevThreadType); /* * Switch back to Task stack if at bottom of Hwi stack * While it seems that this step should be placed in the * "if (Hwi_dispatcherTaskSupport)" conditional below, * some code generators placed a copy of the Hwi_dispatcherTaskSupport * constant on the task stack (see above comment), which would * make the test below bogus as it would be being performed on * on the ISR stack... */ Hwi_switchToTaskStack(oldTaskSP); /* Run Task scheduler */ if (Hwi_dispatcherTaskSupport) { /* tskKey fetched from task stack if this is a non-nested interrupt */ TASK_RESTORE(tskKey); /* returns with ints disabled */ } }
/* * ======== Event_pend ======== */ UInt Event_pend(Event_Object *event, UInt andMask, UInt orMask, UInt32 timeout) { UInt hwiKey, tskKey; Event_PendElem elem; UInt matchingEvents; Queue_Handle pendQ; Clock_Struct clockStruct; Assert_isTrue(((andMask | orMask) != 0), Event_A_nullEventMasks); Log_write5(Event_LM_pend, (UArg)event, (UArg)event->postedEvents, (UArg)andMask, (UArg)orMask, (IArg)((Int)timeout)); /* * elem is filled in entirely before interrupts are disabled. * This significantly reduces latency at the potential cost of wasted time * if it turns out that there is already an event match. */ /* add Clock event if timeout is not FOREVER nor NO_WAIT */ if (BIOS_clockEnabled && (timeout != BIOS_WAIT_FOREVER) && (timeout != BIOS_NO_WAIT)) { Clock_addI(Clock_handle(&clockStruct), (Clock_FuncPtr)Event_pendTimeout, timeout, (UArg)&elem); elem.tpElem.clock = Clock_handle(&clockStruct); elem.pendState = Event_PendState_CLOCK_WAIT; } else { elem.tpElem.clock = NULL; elem.pendState = Event_PendState_WAIT_FOREVER; } /* fill in this task's Event_PendElem */ elem.andMask = andMask; elem.orMask = orMask; pendQ = Event_Instance_State_pendQ(event); /* get task handle */ elem.tpElem.task = Task_self(); /* Atomically check for a match and block if none */ hwiKey = Hwi_disable(); /* check if events are already available */ matchingEvents = Event_checkEvents(event, andMask, orMask); if (matchingEvents != 0) { /* remove Clock object from Clock Q */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_removeI(elem.tpElem.clock); elem.tpElem.clock = NULL; } Hwi_restore(hwiKey); return (matchingEvents);/* yes, then return with matching bits */ } if (timeout == BIOS_NO_WAIT) { Hwi_restore(hwiKey); return (0); /* No match, no wait */ } Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task), Event_A_badContext); /* * Verify that THIS core hasn't already disabled the scheduler * so that the Task_restore() call below will indeed block */ Assert_isTrue((Task_enabled()), Event_A_pendTaskDisabled); /* lock scheduler */ tskKey = Task_disable(); /* only one Task allowed!!! */ Assert_isTrue(Queue_empty(pendQ), Event_A_eventInUse); /* leave a pointer for Task_delete() */ elem.tpElem.task->pendElem = (Task_PendElem *)&(elem); /* add it to Event_PendElem queue */ Queue_enqueue(pendQ, (Queue_Elem *)&elem); Task_blockI(elem.tpElem.task); if (BIOS_clockEnabled && (elem.pendState == Event_PendState_CLOCK_WAIT)) { Clock_startI(elem.tpElem.clock); } Hwi_restore(hwiKey); /* unlock task scheduler and block */ Task_restore(tskKey); /* the calling task will switch out here */ /* Here on unblock due to Event_post or Event_pendTimeout */ hwiKey = Hwi_disable(); /* remove Clock object from Clock Q */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_removeI(elem.tpElem.clock); elem.tpElem.clock = NULL; } elem.tpElem.task->pendElem = NULL; Hwi_restore(hwiKey); /* event match? */ if (elem.pendState != Event_PendState_TIMEOUT) { return (elem.matchingEvents); } else { return (0); /* timeout */ } }
/* * ======== Hwi_dispatchIRQC ======== * Configurable IRQ interrupt dispatcher. */ Void Hwi_dispatchIRQC(Hwi_Irp irp) { /* * Enough room is reserved above the isr stack to handle * as many as 16 32-bit stack resident local variables. * This space is reserved for the Swi scheduler. * * If the swi scheduler requires more than this, you must * handle this in Hwi_Module_startup(). */ Hwi_Object *hwi; BIOS_ThreadType prevThreadType; UInt intNum; Int swiKey; Int i; /* save irp for ROV call stack view */ Hwi_module->irp = irp; if (Hwi_dispatcherSwiSupport) { swiKey = SWI_DISABLE(); } /* set thread type to Hwi */ prevThreadType = BIOS_setThreadType(BIOS_ThreadType_Hwi); /* Porcess ALL pending and enabled interrupts */ do { intNum = Hwi_l1Intc.SIR_IRQ; /* get current L1 int num */ if (intNum == 0) { /* is from L2? */ intNum = Hwi_l2Intc.SIR_IRQ; /* get current L2 int num */ intNum += 32; /* force to linear index */ } hwi = Hwi_module->dispatchTable[intNum]; hwi->irp = Hwi_module->irp; #ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS /* call the begin hooks */ for (i = 0; i < Hwi_hooks.length; i++) { if (Hwi_hooks.elem[i].beginFxn != NULL) { Hwi_hooks.elem[i].beginFxn((IHwi_Handle)hwi); } } #endif Log_write5(Hwi_LM_begin, (IArg)hwi, (IArg)hwi->fxn, (IArg)prevThreadType, (IArg)intNum, hwi->irp); (hwi->fxn)(hwi->arg); Hwi_disable(); Log_write1(Hwi_LD_end, (IArg)hwi); #ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS /* call the end hooks */ for (i = 0; i < Hwi_hooks.length; i++) { if (Hwi_hooks.elem[i].endFxn != NULL) { Hwi_hooks.elem[i].endFxn((IHwi_Handle)hwi); } } #endif if (intNum > 31) { /* is from L2? */ Hwi_l2Intc.CONTROL = L2_NEW_IRQ_AGR;/* force NEW_IRQ_AGR */ } Hwi_l1Intc.CONTROL = L1_NEW_IRQ_AGR; /* force NEW_IRQ_AGR */ } /* loop thru all active and enabled IRQ ints */ while (Hwi_l1Intc.ITR & ~Hwi_l1Intc.MIR & Hwi_module->irq0Mask); /* Run Swi scheduler */ if (Hwi_dispatcherSwiSupport) { SWI_RESTORE(swiKey); } /* restore thread type */ BIOS_setThreadType(prevThreadType); }
/* * ======== Hwi_dispatchIRQC ======== * Configurable IRQ interrupt dispatcher. */ Void Hwi_dispatchIRQC() { /* * Enough room is reserved above the isr stack to handle * as many as 16 32-bit stack resident local variables. * If the dispatcher requires more than this, you must * handle this in Hwi_Module_startup(). */ Hwi_Object *hwi; BIOS_ThreadType prevThreadType; Int intNum; Char *oldTaskSP; Int tskKey; Int swiKey; Int i; if (Hwi_dispatcherTaskSupport) { tskKey = TASK_DISABLE(); /* * If this is a non-nested interrupt, * tskkey is saved on the task stack. * It must not be referenced again until * switching back to the task stack!!!! * All other local variables will be * on the isr stack. */ } /* * Switch to Hwi stack if not already on it. * This step, and the corresponding switch back to the task * stack are performed outside the "if (Hwi_dispatcherTaskSupport)" * conditionals because sometimes the generated code placed a copy * of Hwi_dispatcherTaskSupport on the task stack for use below. */ oldTaskSP = Hwi_switchToIsrStack(); /* * all references to local variables beyond this point * will be on the isr stack */ if (Hwi_dispatcherSwiSupport) { swiKey = SWI_DISABLE(); } /* set thread type to Hwi */ prevThreadType = BIOS_setThreadType(BIOS_ThreadType_Hwi); /* read interrupt index */ intNum = Hwi_cpIntc.HIPIR[1]; /* disable host interrupt 1 (IRQ) */ Hwi_cpIntc.HIDISR = 1; hwi = Hwi_module->dispatchTable[intNum]; hwi->irp = Hwi_module->irp; #ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS /* call the begin hooks */ for (i = 0; i < Hwi_hooks.length; i++) { if (Hwi_hooks.elem[i].beginFxn != NULL) { Hwi_hooks.elem[i].beginFxn((IHwi_Handle)hwi); } } #endif Log_write5(Hwi_LM_begin, (IArg)hwi, (IArg)hwi->fxn, (IArg)prevThreadType, (IArg)intNum, hwi->irp); /* call the user's isr */ if (Hwi_dispatcherAutoNestingSupport) { (hwi->handler)(hwi, intNum); } else { /* clear the interrupt status for this int */ Hwi_cpIntc.SICR = intNum; (hwi->fxn)(hwi->arg); /* re-enable IRQ */ Hwi_cpIntc.HIEISR = 1; } Log_write1(Hwi_LD_end, (IArg)hwi); #ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS /* call the end hooks */ for (i = 0; i < Hwi_hooks.length; i++) { if (Hwi_hooks.elem[i].endFxn != NULL) { Hwi_hooks.elem[i].endFxn((IHwi_Handle)hwi); } } #endif /* Run Swi scheduler */ if (Hwi_dispatcherSwiSupport) { SWI_RESTORE(swiKey); } /* restore thread type */ BIOS_setThreadType(prevThreadType); /* * Switch back to Task stack if at bottom of Hwi stack * While it seems that this step should be placed in the * "if (Hwi_dispatcherTaskSupport)" conditional below, * some code generators placed a copy of the Hwi_dispatcherTaskSupport * constant on the task stack (see above comment), which would * make the test below bogus as it would be being performed on * on the ISR stack... */ Hwi_switchToTaskStack(oldTaskSP); /* Run Task scheduler */ if (Hwi_dispatcherTaskSupport) { /* tskKey fetched from task stack if this is a non-nested interrupt */ TASK_RESTORE(tskKey); /* returns with ints disabled */ } }
/* * ======== Hwi_dispatchCore ======== * Configurable dispatcher. */ Void Hwi_dispatchCore(Int intNum) { /* * Enough room is reserved above the isr stack to handle * as many as 16 32-bit stack resident local variables. * If the dispatcher requires more than this, you must * handle this in Hwi_Module_startup(). */ Hwi_Object *hwi; BIOS_ThreadType prevThreadType; UInt16 oldIER, disableMask, restoreMask; Int swiKey; Int i; Hwi_FuncPtr fxn; UArg arg; /* save away intNum in module state because it might be saved on stack */ Hwi_module->intNum = intNum; /* * pre-read local copies of the variables used * within to eliminate memory fetch nops */ hwi = Hwi_module->dispatchTable[intNum]; fxn = hwi->fxn; arg = hwi->arg; if (Hwi_dispatcherIrpTrackingSupport) { hwi->irp = IRP; } if (Hwi_dispatcherAutoNestingSupport) { disableMask = hwi->disableMask; restoreMask = hwi->restoreMask; } if (Hwi_dispatcherSwiSupport) { swiKey = SWI_DISABLE(); } /* set thread type to Hwi */ prevThreadType = BIOS_setThreadType(BIOS_ThreadType_Hwi); #ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS /* call the begin hooks */ for (i = 0; i < Hwi_hooks.length; i++) { if (Hwi_hooks.elem[i].beginFxn != NULL) { Hwi_hooks.elem[i].beginFxn((IHwi_Handle)hwi); } } #endif Log_write5(Hwi_LM_begin, (IArg)hwi, (IArg)hwi->fxn, (IArg)prevThreadType, (IArg)intNum, hwi->irp); /* call the user's isr */ if (Hwi_dispatcherAutoNestingSupport) { oldIER = IER; IER &= ~disableMask; _enable_interrupts(); (fxn)(arg); _disable_interrupts(); IER |= (restoreMask & oldIER); } else { (fxn)(arg); } Log_write1(Hwi_LD_end, (IArg)hwi); #ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS /* call the end hooks */ for (i = 0; i < Hwi_hooks.length; i++) { if (Hwi_hooks.elem[i].endFxn != NULL) { Hwi_hooks.elem[i].endFxn((IHwi_Handle)hwi); } } #endif /* Run Swi scheduler */ if (Hwi_dispatcherSwiSupport) { SWI_RESTORE(swiKey); } /* restore thread type */ BIOS_setThreadType(prevThreadType); }