/********************************************************************************************************* ** 函数名称: _SmpTryProcIpi ** 功能描述: 尝试处理核间中断 (这里仅仅尝试执行 FLUSH_TLB 与 call 函数) ** 输 入 : pcpuCur 当前 CPU ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _SmpTryProcIpi (PLW_CLASS_CPU pcpuCur) { #if LW_CFG_VMM_EN > 0 if (LW_CPU_GET_IPI_PEND2(pcpuCur) & LW_IPI_FLUSH_TLB_MSK) { /* 更新 MMU 快表 */ _SmpProcFlushTlb(pcpuCur); } #endif /* LW_CFG_VMM_EN > 0 */ if (LW_CPU_GET_IPI_PEND2(pcpuCur) & LW_IPI_CALL_MSK) { /* 自定义调用 ? */ _SmpProcCallfuncIgnIrq(pcpuCur); } }
LW_API ULONG API_CpuDown (ULONG ulCPUId) { INTREG iregInterLevel; PLW_CLASS_CPU pcpu; if ((ulCPUId == 0) || (ulCPUId >= LW_NCPUS)) { _ErrorHandle(EINVAL); return (EINVAL); } __KERNEL_ENTER(); pcpu = LW_CPU_GET(ulCPUId); if (!LW_CPU_IS_ACTIVE(pcpu) || (LW_CPU_GET_IPI_PEND2(pcpu) & LW_IPI_DOWN_MSK)) { __KERNEL_EXIT(); return (ERROR_NONE); } LW_SPIN_LOCK_QUICK(&pcpu->CPU_slIpi, &iregInterLevel); LW_CPU_ADD_IPI_PEND2(pcpu, LW_IPI_DOWN_MSK); LW_SPIN_UNLOCK_QUICK(&pcpu->CPU_slIpi, iregInterLevel); _ThreadOffAffinity(pcpu); /* 关闭与此 CPU 有关的亲和度 */ __KERNEL_EXIT(); _SmpSendIpi(ulCPUId, LW_IPI_DOWN, 0, LW_FALSE); /* 使用核间中断通知 CPU 停止 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: _SmpProcIpi ** 功能描述: 处理核间中断 (这里不处理调度器消息) ** 输 入 : pcpuCur 当前 CPU ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _SmpProcIpi (PLW_CLASS_CPU pcpuCur) { pcpuCur->CPU_iIPICnt++; /* 核间中断数量 ++ */ #if LW_CFG_VMM_EN > 0 if (LW_CPU_GET_IPI_PEND2(pcpuCur) & LW_IPI_FLUSH_TLB_MSK) { /* 更新 MMU 快表 */ _SmpProcFlushTlb(pcpuCur); } #endif /* LW_CFG_VMM_EN > 0 */ #if LW_CFG_CACHE_EN > 0 if (LW_CPU_GET_IPI_PEND2(pcpuCur) & LW_IPI_FLUSH_CACHE_MSK) { /* 回写 CACHE */ _SmpProcFlushCache(pcpuCur); } #endif /* LW_CFG_CACHE_EN > 0 */ if (LW_CPU_GET_IPI_PEND2(pcpuCur) & LW_IPI_BOOT_MSK) { /* 其他核正在启动 */ _SmpProcBoot(pcpuCur); } if (LW_CPU_GET_IPI_PEND2(pcpuCur) & LW_IPI_CALL_MSK) { /* 自定义调用 ? */ _SmpProcCallfunc(pcpuCur); } }
/********************************************************************************************************* ** 函数名称: _SchedGetCand ** 功能描述: 获的需要运行的线程表 (被调用时已经锁定了调度器 spinlock) ** 输 入 : ptcbRunner 需要运行的 TCB 列表 (大小等于 CPU 数量) ** ulCPUIdCur 当前 CPU ID ** ulCurMaxLock 当前 CPU 允许的最多任务锁定层数. ** 输 出 : ** 全局变量: ** 调用模块: *********************************************************************************************************/ PLW_CLASS_TCB _SchedGetCand (PLW_CLASS_CPU pcpuCur, ULONG ulCurMaxLock) { if (!__COULD_SCHED(pcpuCur, ulCurMaxLock)) { /* 当前执行线程不能调度 */ return (pcpuCur->CPU_ptcbTCBCur); } else { /* 可以执行线程切换 */ #if LW_CFG_SMP_EN > 0 if (LW_CPU_GET_IPI_PEND2(pcpuCur) & LW_IPI_CALL_MSK) { /* 由延迟的 IPI CALL 需要执行 */ _SmpUpdateIpi(pcpuCur); } #endif /* LW_CFG_SMP_EN > 0 */ if (LW_CAND_ROT(pcpuCur)) { /* 产生优先级卷绕 */ _CandTableUpdate(pcpuCur); } return (LW_CAND_TCB(pcpuCur)); } }
/********************************************************************************************************* ** 函数名称: API_CpuUp ** 功能描述: 开启一个 CPU. (非 0 号 CPU) ** 输 入 : ulCPUId CPU ID ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_CpuUp (ULONG ulCPUId) { INTREG iregInterLevel; PLW_CLASS_CPU pcpu; if ((ulCPUId == 0) || (ulCPUId >= LW_NCPUS)) { _ErrorHandle(EINVAL); return (EINVAL); } KN_SMP_MB(); pcpu = LW_CPU_GET(ulCPUId); if (LW_CPU_IS_ACTIVE(pcpu) || (LW_CPU_GET_IPI_PEND2(pcpu) & LW_IPI_DOWN_MSK)) { return (ERROR_NONE); } iregInterLevel = KN_INT_DISABLE(); bspCpuUp(ulCPUId); KN_INT_ENABLE(iregInterLevel); return (ERROR_NONE); }