在主核启动后,通知其它核进行启动:
for (ulCPUId = 1; ulCPUId < LW_NCPUS; ulCPUId++) { /* 启动其它 CPU */
API_CpuUp(ulCPUId);
}
bspCpuUpSync();
/********************************************************************/
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);
}
VOID bspCpuUp (ULONG ulCPUId)
{
INTREG iregInterLevel;
iregInterLevel = KN_INT_DISABLE(); // 关总中断
_G_ulHoldingPen[ulCPUId] = 0;
KN_SMP_MB();
bspCpuUpSyncPoint1((PVOID)ulCPUId); // 数据cache 同步
sunxiSetSecondaryEntry((PVOID)BSP_CFG_RAM_BASE); // 设置该核启动地址
sunxiEnableCpu(ulCPUId); // 激活该核
bspCpuUpSyncPoint2((PVOID)ulCPUId);
KN_INT_ENABLE(iregInterLevel); // 开总中断
}
VOID bspCpuUpSync (VOID)
{
INT i;
LW_CLASS_CPUSET cpuset;
LW_CPU_ZERO(&cpuset);
LW_CPU_FOREACH (i) {
LW_CPU_SET(i, &cpuset);
}
API_CacheBarrier(bspCpuCacheSync, LW_NULL, sizeof(cpuset), &cpuset); //多核cache 处理
}