/* * ======== Swi_restore ======== */ Void Swi_restore(UInt swiKey) { if (swiKey == FALSE) { if (Core_getId() != 0) { Swi_restoreSMP(); return; } Core_hwiDisable(); if (Swi_module->curSet) { Hwi_enable(); Swi_schedule(); /* sets locked to FALSE */ } else { Swi_module->locked = FALSE; if (BIOS_taskEnabled) { TASK_RESTORE(TASK_DISABLE()); /* required for Swi's posted from Tasks */ } else { Hwi_enable(); } } } }
/* * ======== Swi_restoreSMP ======== * Only called when coreId != 0 */ Void Swi_restoreSMP() { UInt tskKey; /* make Core 0 process the Swis */ if (Swi_module->curSet) { Core_interruptCore(0); } if (BIOS_taskEnabled) { tskKey = TASK_DISABLE(); /* required for Swi's posted from Tasks */ /* release our hold on the Swi scheduler */ Swi_module->locked = FALSE; /* run task scheduler if its unlocked */ TASK_RESTORE(tskKey); } else { /* release our hold on the Swi scheduler */ Swi_module->locked = FALSE; /* release the Inter-core Gate */ Hwi_enable(); } }
/* * ======== Hwi_dispatchC ======== * Configurable dispatcher. */ Void Hwi_dispatchC(Int intNum) { Int tskKey; if (Hwi_dispatcherTaskSupport) { tskKey = TASK_DISABLE(); } Hwi_switchAndDispatch(intNum); if (Hwi_dispatcherTaskSupport) { TASK_RESTORE(tskKey); /* returns with ints disabled */ } }
Void Swi_schedule() { Queue_Handle curQ, maxQ; UInt hwiKey; UInt tskKey; /* Remember current Swi priority */ curQ = Swi_module->curQ; hwiKey = Hwi_disable(); /* required for Swi's posted from Tasks */ /* determine current highest priority Q */ maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); if (maxQ > curQ) { if (BIOS_taskEnabled) { tskKey = TASK_DISABLE(); /* required for Swi's posted from Tasks */ /* Switch stacks and call Swi_runLoop() */ ti_sysbios_family_xxx_Hwi_switchAndRunFunc(&Swi_runLoop); } else { /* Call Swi_runLoop() */ Swi_runLoop(); } /* MUST(!) unlock the scheduler before enabling interrupts */ Swi_module->locked = FALSE; Hwi_restore(hwiKey); if (BIOS_taskEnabled) { TASK_RESTORE(tskKey); } } else { Swi_module->locked = FALSE; Hwi_restore(hwiKey); } }
/* * ======== Swi_restore ======== */ Void Swi_restore(UInt swiKey) { UInt hwiKey; if (swiKey == FALSE) { hwiKey = Hwi_disable(); if (Swi_module->curSet) { Hwi_restore(hwiKey); Swi_schedule(); /* sets locked to FALSE */ } else { Swi_module->locked = FALSE; Hwi_restore(hwiKey); } if (BIOS_taskEnabled) { /* run task scheduler if its unlocked */ TASK_RESTORE(TASK_DISABLE()); } } }
/* * ======== 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 */ } }
/* * ======== 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 */ } }
Void Swi_schedule() { Queue_Handle curQ, maxQ; Swi_Object *swi; UInt hwiKey; UInt tskKey; Char *oldTaskSP; volatile Bool taskEnabled; /* Remember current Swi priority */ curQ = Swi_module->curQ; hwiKey = Hwi_disable(); /* required for Swi's posted from Tasks */ /* determine current highest priority Q */ maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); if (maxQ > curQ) { if (BIOS_taskEnabled) { tskKey = TASK_DISABLE(); /* required for Swi's posted from Tasks */ /* Switch to HWI stack if not already on it */ oldTaskSP = ti_sysbios_family_xxx_Hwi_switchToIsrStack(); /* must refresh local variables after stack switch */ /* refresh curQ */ curQ = Swi_module->curQ; /* refresh maxQ */ maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); /* set local variable inited after stack switch */ taskEnabled = TRUE; } else { taskEnabled = FALSE; } /* * Run all Swis of higher priority than * the current Swi priority. * Will pre-empt any currently running swi. */ do { swi = (Swi_Object *)Queue_dequeue(maxQ); /* remove from curSet if last one in this ready list */ if (Queue_empty(maxQ)) { Swi_module->curSet &= ~swi->mask; } Swi_run(swi); if (Swi_module->curSet == 0) { break; } maxQ = (Queue_Handle)((UInt8 *)(Swi_module->readyQ) + (UInt)(Intrinsics_maxbit(Swi_module->curSet)*(2*sizeof(Ptr)))); } while (maxQ > curQ); /* check local variable inited after stack switch */ if (taskEnabled) { /* Switch back to Task stack if at bottom of HWI stack */ ti_sysbios_family_xxx_Hwi_switchToTaskStack(oldTaskSP); } /* MUST(!) unlock the scheduler before enabling interrupts */ Swi_module->locked = FALSE; Hwi_restore(hwiKey); if (BIOS_taskEnabled) { TASK_RESTORE(tskKey); } } else { Swi_module->locked = FALSE; Hwi_restore(hwiKey); } }