static VOID _KernelSecondaryCoreStartup (PLW_CLASS_CPU pcpuCur) { PLW_CLASS_TCB ptcbOrg; KN_SMP_MB(); while (KN_PRIMARY_IS_GO() == LW_FALSE) { /* 等待主核运行 */ LW_SPINLOCK_DELAY(); /* 短延迟并释放总线 */ } LW_SPIN_KERN_LOCK_IGNIRQ(); LW_TCB_GET_CUR(ptcbOrg); _CpuActive(pcpuCur); /* CPU 激活 */ LW_SPIN_KERN_UNLOCK_SCHED(ptcbOrg); pcpuCur->CPU_iKernelCounter = 0; /* 允许调度 */ KN_SMP_MB(); _DebugHandle(__LOGMESSAGE_LEVEL, "secondary cpu multi-task start...\r\n"); #if LW_CFG_CPU_FPU_EN > 0 _ThreadFpuSwith(LW_FALSE); /* 初始化将要运行任务 FPU 环境 */ #endif errno = ERROR_NONE; /* 清除错误 */ archTaskCtxStart(pcpuCur); /* 当前 CPU 进入任务状态 */ }
/********************************************************************************************************* ** 函数名称: API_VmmMmuEnable ** 功能描述: 启动 MMU, MMU 启动前后虚拟地址不能有任何变化. ** 输 入 : NONE ** 输 出 : NONE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API VOID API_VmmMmuEnable (VOID) { KN_SMP_MB(); __VMM_MMU_ENABLE(); /* 启动 MMU */ KN_SMP_MB(); }
/********************************************************************************************************* ** 函数名称: API_VmmMmuDisable ** 功能描述: 停止 MMU, MMU 停止前后虚拟地址不能有任何变化. ** 输 入 : NONE ** 输 出 : NONE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API VOID API_VmmMmuDisable (VOID) { KN_SMP_MB(); __VMM_MMU_DISABLE(); /* 停止 MMU */ KN_SMP_MB(); }
/********************************************************************************************************* ** 函数名称: _KernelPrimaryCoreStartup ** 功能描述: 系统的主核 (负责初始化的核) 进入多任务状态, 进入多任务状态后, 所有核均对等不分主从 ** 输 入 : pcpuCur 当前 CPU ** 输 出 : ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID _KernelPrimaryCoreStartup (PLW_CLASS_CPU pcpuCur) { PLW_CLASS_TCB ptcbOrg; LW_SPIN_KERN_LOCK_IGNIRQ(); LW_TCB_GET_CUR(ptcbOrg); _CpuActive(pcpuCur); /* CPU 激活 */ LW_SPIN_KERN_UNLOCK_SCHED(ptcbOrg); #if LW_CFG_SMP_EN > 0 KN_SMP_MB(); /* 内存屏障, 确保之前操作已处理*/ KN_PRIMARY_GO(); /* 通知从核可以进入多任务模式 */ LW_SPINLOCK_NOTIFY(); #endif /* LW_CFG_SMP_EN */ pcpuCur->CPU_iKernelCounter = 0; /* 允许调度 */ KN_SMP_MB(); _DebugHandle(__LOGMESSAGE_LEVEL, "primary cpu multi-task start...\r\n"); #if LW_CFG_CPU_FPU_EN > 0 _ThreadFpuSwith(LW_FALSE); /* 初始化将要运行任务 FPU 环境 */ #endif errno = ERROR_NONE; /* 清除错误 */ archTaskCtxStart(pcpuCur); /* 当前 CPU 进入任务状态 */ }
/********************************************************************************************************* ** 函数名称: __smpProcCallfunc ** 功能描述: 处理核间中断调用函数 ** 输 入 : pcpuCur 当前 CPU ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __smpProcCallfunc (PLW_CLASS_CPU pcpuCur) { #define LW_KERNEL_OWN_CPU() (PLW_CLASS_CPU)(_K_klKernel.KERN_pvCpuOwner) UINT i, uiCnt; PLW_IPI_MSG pipim; PLW_LIST_RING pringTemp; PLW_LIST_RING pringDelete; VOIDFUNCPTR pfuncAsync; PVOID pvAsync; LW_SPIN_LOCK_IGNIRQ(&pcpuCur->CPU_slIpi); /* 锁定 CPU */ pringTemp = pcpuCur->CPU_pringMsg; uiCnt = pcpuCur->CPU_uiMsgCnt; for (i = 0; i < uiCnt; i++) { _BugHandle((!pcpuCur->CPU_pringMsg), LW_TRUE, "ipi call func error!\r\n"); pipim = _LIST_ENTRY(pringTemp, LW_IPI_MSG, IPIM_ringManage); if ((LW_KERNEL_OWN_CPU() == pcpuCur) && (pipim->IPIM_iOption & IPIM_OPT_NOKERN)) { /* 此函数不能再内核锁定状态执行*/ pringTemp = _list_ring_get_next(pringTemp); continue; } pringDelete = pringTemp; pringTemp = _list_ring_get_next(pringTemp); _List_Ring_Del(pringDelete, &pcpuCur->CPU_pringMsg); /* 删除一个节点 */ pcpuCur->CPU_uiMsgCnt--; if (pipim->IPIM_pfuncCall) { pipim->IPIM_iRet = pipim->IPIM_pfuncCall(pipim->IPIM_pvArg);/* 执行同步调用 */ } pfuncAsync = pipim->IPIM_pfuncAsyncCall; pvAsync = pipim->IPIM_pvAsyncArg; KN_SMP_MB(); pipim->IPIM_iWait = 0; /* 调用结束 */ KN_SMP_WMB(); LW_SPINLOCK_NOTIFY(); if (pfuncAsync) { pfuncAsync(pvAsync); /* 执行异步调用 */ } } KN_SMP_MB(); if (pcpuCur->CPU_pringMsg == LW_NULL) { LW_CPU_CLR_IPI_PEND2(pcpuCur, LW_IPI_CALL_MSK); /* 清除 */ } LW_SPIN_UNLOCK_IGNIRQ(&pcpuCur->CPU_slIpi); /* 解锁 CPU */ LW_SPINLOCK_NOTIFY(); }
/** * setting if we are a gateway */ void aodv_gw_set (int enable) { #ifdef SYLIXOS KN_SMP_MB(); #endif aodv_gw = enable; #ifdef SYLIXOS KN_SMP_MB(); #endif }
int aodv_gw_get (void) { #ifdef SYLIXOS KN_SMP_MB(); #endif return (aodv_gw); #ifdef SYLIXOS KN_SMP_MB(); #endif }
/********************************************************************************************************* ** 函数名称: sio16c550Isr ** 功能描述: 16C550 中断服务函数 ** 输 入 : psiochan SIO CHAN ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID sio16c550Isr (SIO16C550_CHAN *psiochan) { volatile UINT8 iir; UINT8 msr; UINT8 ucRd; UINT8 ucTx; INT i; psiochan->int_ctx = 1; KN_SMP_MB(); iir = (UINT8)(GET_REG(psiochan, IIR) & 0x0f); while (GET_REG(psiochan, LSR) & RxCHAR_AVAIL) { /* receive data */ ucRd = GET_REG(psiochan, RBR); psiochan->pcbPutRcvChar(psiochan->putRcvArg, ucRd); } if ((psiochan->ier & TxFIFO_BIT) && (GET_REG(psiochan, LSR) & LSR_THRE)) { /* transmit data */ for (i = 0; i < psiochan->fifo_len; i++) { if (psiochan->pcbGetTxChar(psiochan->getTxArg, &ucTx) < 0) { psiochan->ier &= (~TxFIFO_BIT); break; } else { SET_REG(psiochan, THR, ucTx); /* char to Transmit Holding Reg */ } } } if (iir == IIR_MSTAT) { /* modem status changed */ msr = GET_REG(psiochan, MSR); if (msr & MSR_DCTS) { if (msr & MSR_CTS) { psiochan->ier |= TxFIFO_BIT; /* CTS was turned on */ } else { psiochan->ier &= (~TxFIFO_BIT); /* CTS was turned off */ } } } KN_SMP_MB(); psiochan->int_ctx = 0; KN_SMP_MB(); SET_REG(psiochan, IER, psiochan->ier); /* update ier */ }
/********************************************************************************************************* ** 函数名称: _SmpSpinUnlockIrq ** 功能描述: 自旋锁解锁操作, 连同解锁中断 ** 输 入 : psl 自旋锁 ** iregInterLevel 中断锁定信息 ** 输 出 : 调度器返回值 ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT _SmpSpinUnlockIrq (spinlock_t *psl, INTREG iregInterLevel) { PLW_CLASS_CPU pcpuCur; PLW_CLASS_TCB ptcbCur; BOOL bTrySched = LW_FALSE; INT iRet; KN_SMP_MB(); iRet = __ARCH_SPIN_UNLOCK(psl); _BugFormat((iRet != LW_SPIN_OK), LW_TRUE, "unlock error 0x%p!\r\n", psl); pcpuCur = LW_CPU_GET_CUR(); if (!pcpuCur->CPU_ulInterNesting) { ptcbCur = pcpuCur->CPU_ptcbTCBCur; __THREAD_LOCK_DEC(ptcbCur); /* 解除任务锁定 */ if (__ISNEED_SCHED(pcpuCur, 0)) { bTrySched = LW_TRUE; /* 需要尝试调度 */ } } LW_CPU_SPIN_NESTING_DEC(pcpuCur); KN_INT_ENABLE(iregInterLevel); if (bTrySched) { return (_ThreadSched(ptcbCur)); } else { return (ERROR_NONE); } }
/********************************************************************************************************* ** 函数名称: _SmpSpinUnlockTask ** 功能描述: 自旋锁原始解锁操作. (不锁定中断, 同时允许加锁后调用可能产生阻塞的操作) ** 输 入 : psl 自旋锁 ** 输 出 : 调度器返回值 ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT _SmpSpinUnlockTask (spinlock_t *psl) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; PLW_CLASS_TCB ptcbCur; BOOL bTrySched = LW_FALSE; iregInterLevel = KN_INT_DISABLE(); KN_SMP_MB(); __ARCH_SPIN_UNLOCK_RAW(psl); pcpuCur = LW_CPU_GET_CUR(); _BugHandle(pcpuCur->CPU_ulInterNesting, LW_TRUE, "called from ISR.\r\n"); ptcbCur = pcpuCur->CPU_ptcbTCBCur; __THREAD_LOCK_DEC(ptcbCur); /* 解除任务锁定 */ if (__ISNEED_SCHED(pcpuCur, 0)) { bTrySched = LW_TRUE; /* 需要尝试调度 */ } KN_INT_ENABLE(iregInterLevel); if (bTrySched) { return (_ThreadSched(ptcbCur)); } else { return (ERROR_NONE); } }
/********************************************************************************************************* ** 函数名称: _SmpSpinTryLock ** 功能描述: 自旋锁尝试加锁操作 ** 输 入 : psl 自旋锁 ** 输 出 : LW_TRUE 加锁正常 LW_FALSE 加锁失败 ** 全局变量: ** 调用模块: *********************************************************************************************************/ BOOL _SmpSpinTryLock (spinlock_t *psl) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; INT iRet; iregInterLevel = KN_INT_DISABLE(); pcpuCur = LW_CPU_GET_CUR(); if (!pcpuCur->CPU_ulInterNesting) { __THREAD_LOCK_INC(pcpuCur->CPU_ptcbTCBCur); /* 锁定任务在当前 CPU */ } LW_CPU_SPIN_NESTING_INC(pcpuCur); iRet = __ARCH_SPIN_TRYLOCK(psl); KN_SMP_MB(); if (iRet != LW_SPIN_OK) { if (!pcpuCur->CPU_ulInterNesting) { __THREAD_LOCK_DEC(pcpuCur->CPU_ptcbTCBCur); /* 解锁失败, 解除任务锁定 */ } LW_CPU_SPIN_NESTING_DEC(pcpuCur); } KN_INT_ENABLE(iregInterLevel); return ((iRet == LW_SPIN_OK) ? (LW_TRUE) : (LW_FALSE)); }
/********************************************************************************************************* ** 函数名称: sio16c550TxStartup ** 功能描述: 串口接口启动发送 ** 输 入 : psiochan SIO CHAN ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT sio16c550TxStartup (SIO16C550_CHAN *psiochan) { INTREG intreg; UINT8 mask; CHAR cTx; if (psiochan->switch_en && (psiochan->hw_option & CLOCAL)) { SEND_START(psiochan); /* switch direct to send mode */ do { if (psiochan->pcbGetTxChar(psiochan->getTxArg, &cTx) != ERROR_NONE) { break; } while (!IS_Tx_HOLD_REG_EMPTY(psiochan)); /* wait tx holding reg empty */ SET_REG(psiochan, THR, cTx); } while (1); while (!IS_Tx_HOLD_REG_EMPTY(psiochan)); /* wait tx holding reg empty */ SEND_END(psiochan); /* switch direct to rx mode */ return (ERROR_NONE); } if (psiochan->channel_mode == SIO_MODE_INT) { intreg = KN_INT_DISABLE(); if (psiochan->hw_option & CLOCAL) { /* No modem control */ psiochan->ier |= TxFIFO_BIT; } else { mask = (UINT8)(GET_REG(psiochan, MSR) & MSR_CTS); if (mask & MSR_CTS) { /* if the CTS is enable Tx Int */ psiochan->ier |= TxFIFO_BIT; /* enable Tx interrupt */ } else { psiochan->ier &= (~TxFIFO_BIT); /* disable Tx interrupt */ } } KN_SMP_MB(); if (psiochan->int_ctx == 0) { SET_REG(psiochan, IER, psiochan->ier); } KN_INT_ENABLE(intreg); return (ERROR_NONE); } else { _ErrorHandle(ENOSYS); return (ENOSYS); } }
/********************************************************************************************************* ** 函数名称: archDbgAbInsert ** 功能描述: 插入一个异常点. ** 输 入 : ulAddr 断点地址 ** pulIns 返回的之前的指令 ** 输 出 : NONE ** 全局变量: ** 调用模块: ** 注 意 : 插入异常断点时, 不考虑 CPU 运行模式, 直接插入 32 位断点即可. *********************************************************************************************************/ VOID archDbgAbInsert (addr_t ulAddr, ULONG *pulIns) { *pulIns = *(ULONG *)ulAddr; *(ULONG *)ulAddr = ARM_ABORTPOINT_INS; KN_SMP_MB(); #if LW_CFG_CACHE_EN > 0 API_CacheTextUpdate((PVOID)ulAddr, sizeof(ULONG)); #endif /* LW_CFG_CACHE_EN > 0 */ }
/********************************************************************************************************* ** 函数名称: archDbgBpRemove ** 功能描述: 删除一个断点. ** 输 入 : ulAddr 断点地址 ** stSize 断点大小 ** pulIns 返回的之前的指令 ** bLocal 是否仅更新当前 CPU I-CACHE ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID archDbgBpRemove (addr_t ulAddr, size_t stSize, ULONG ulIns, BOOL bLocal) { lib_memcpy((PCHAR)ulAddr, (PCHAR)&ulIns, stSize); KN_SMP_MB(); #if LW_CFG_CACHE_EN > 0 if (bLocal) { API_CacheLocalTextUpdate((PVOID)ulAddr, stSize); } else { API_CacheTextUpdate((PVOID)ulAddr, stSize); } #endif /* LW_CFG_CACHE_EN > 0 */ }
/********************************************************************************************************* ** 函数名称: _SmpSpinLockIgnIrq ** 功能描述: 自旋锁加锁操作, 忽略中断锁定 (必须在中断关闭的状态下被调用) ** 输 入 : psl 自旋锁 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _SmpSpinLockIgnIrq (spinlock_t *psl) { PLW_CLASS_CPU pcpuCur; pcpuCur = LW_CPU_GET_CUR(); if (!pcpuCur->CPU_ulInterNesting) { __THREAD_LOCK_INC(pcpuCur->CPU_ptcbTCBCur); /* 锁定任务在当前 CPU */ } LW_CPU_SPIN_NESTING_INC(pcpuCur); __ARCH_SPIN_LOCK(psl); /* 驱动保证锁定必须成功 */ KN_SMP_MB(); }
VOID API_KernelSecondaryStart (PKERNEL_START_ROUTINE pfuncStartHook) { KN_SMP_MB(); while (KN_SECONDARY_WAIT()) { LW_SPINLOCK_DELAY(); /* 短延迟并释放总线 */ } _KernelSecondaryLowLevelInit(); /* 从核底层初始化 */ _DebugHandle(__LOGMESSAGE_LEVEL, "kernel secondary cpu usrStartup...\r\n"); if (pfuncStartHook) { /* 用户是否要求需要初始化 */ pfuncStartHook(); /* 用户系统初始化 */ } _KernelSecondaryCoreStartup(LW_CPU_GET_CUR()); /* 主核初始化完毕直接启动多任务*/ }
/********************************************************************************************************* ** 函数名称: _SmpSpinUnlockIgnIrq ** 功能描述: 自旋锁解锁操作, 忽略中断锁定 (必须在中断关闭的状态下被调用) ** 输 入 : psl 自旋锁 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _SmpSpinUnlockIgnIrq (spinlock_t *psl) { PLW_CLASS_CPU pcpuCur; INT iRet; KN_SMP_MB(); iRet = __ARCH_SPIN_UNLOCK(psl); _BugFormat((iRet != LW_SPIN_OK), LW_TRUE, "unlock error 0x%p!\r\n", psl); pcpuCur = LW_CPU_GET_CUR(); if (!pcpuCur->CPU_ulInterNesting) { __THREAD_LOCK_DEC(pcpuCur->CPU_ptcbTCBCur); /* 解除任务锁定 */ } LW_CPU_SPIN_NESTING_DEC(pcpuCur); }
/********************************************************************************************************* ** 函数名称: archDbgBpInsert ** 功能描述: 插入一个断点. ** 输 入 : ulAddr 断点地址 ** stSize 断点大小 ** pulIns 返回的之前的指令 ** bLocal 是否仅更新当前 CPU I-CACHE ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID archDbgBpInsert (addr_t ulAddr, size_t stSize, ULONG *pulIns, BOOL bLocal) { ULONG ulIns = ARM_BREAKPOINT_INS; lib_memcpy((PCHAR)pulIns, (PCHAR)ulAddr, stSize); /* memcpy 避免 arm 对齐问题 */ lib_memcpy((PCHAR)ulAddr, (PCHAR)&ulIns, stSize); KN_SMP_MB(); #if LW_CFG_CACHE_EN > 0 if (bLocal) { API_CacheLocalTextUpdate((PVOID)ulAddr, stSize); } else { API_CacheTextUpdate((PVOID)ulAddr, stSize); } #endif /* LW_CFG_CACHE_EN > 0 */ }
ULONG __vmmLibSecondaryInit (CPCHAR pcMachineName) { REGISTER PLW_MMU_CONTEXT pmmuctx = __vmmGetCurCtx(); REGISTER INT iError; REGISTER ULONG ulError; iError = __VMM_MMU_GLOBAL_INIT(pcMachineName); /* 初始化体系相关关键数据 */ if (iError < ERROR_NONE) { ulError = errno; return (ulError); } __VMM_MMU_MAKE_CURCTX(pmmuctx); /* 设置页表位置 */ KN_SMP_MB(); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: _SmpSpinLockTask ** 功能描述: 自旋锁原始加锁操作. (不锁定中断, 同时允许加锁后调用可能产生阻塞的操作) ** 输 入 : psl 自旋锁 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _SmpSpinLockTask (spinlock_t *psl) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; iregInterLevel = KN_INT_DISABLE(); pcpuCur = LW_CPU_GET_CUR(); _BugHandle(pcpuCur->CPU_ulInterNesting, LW_TRUE, "called from ISR.\r\n"); __THREAD_LOCK_INC(pcpuCur->CPU_ptcbTCBCur); /* 锁定任务在当前 CPU */ __ARCH_SPIN_LOCK_RAW(psl); /* 驱动保证锁定必须成功 */ KN_SMP_MB(); KN_INT_ENABLE(iregInterLevel); }
/********************************************************************************************************* ** 函数名称: _SmpSpinLock ** 功能描述: 自旋锁加锁操作 ** 输 入 : psl 自旋锁 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _SmpSpinLock (spinlock_t *psl) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; iregInterLevel = KN_INT_DISABLE(); pcpuCur = LW_CPU_GET_CUR(); if (!pcpuCur->CPU_ulInterNesting) { __THREAD_LOCK_INC(pcpuCur->CPU_ptcbTCBCur); /* 锁定任务在当前 CPU */ } LW_CPU_SPIN_NESTING_INC(pcpuCur); __ARCH_SPIN_LOCK(psl); /* 驱动保证锁定必须成功 */ KN_SMP_MB(); KN_INT_ENABLE(iregInterLevel); }
/********************************************************************************************************* ** 函数名称: API_CpuIsUp ** 功能描述: 指定 CPU 是否启动. ** 输 入 : ulCPUId CPU ID ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API BOOL API_CpuIsUp (ULONG ulCPUId) { PLW_CLASS_CPU pcpu; if (ulCPUId >= LW_NCPUS) { _ErrorHandle(EINVAL); return (LW_FALSE); } KN_SMP_MB(); pcpu = LW_CPU_GET(ulCPUId); if (LW_CPU_IS_ACTIVE(pcpu)) { return (LW_TRUE); } else { return (LW_FALSE); } }
/********************************************************************************************************* ** 函数名称: _SmpCallIpiAllOther ** 功能描述: 发送一个自定义核间中断给其他所有 CPU 关中断情况下被调用, 如果需要等待, 则必须保证其他 CPU 已经运行. ** 输 入 : pipim 核间中断参数 ** 输 出 : NONE (无法确定返回值) ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID _SmpCallIpiAllOther (PLW_IPI_MSG pipim) { ULONG i; ULONG ulCPUId; INT iWaitSave = pipim->IPIM_iWait; ulCPUId = LW_CPU_GET_CUR_ID(); KN_SMP_WMB(); for (i = 0; i < LW_NCPUS; i++) { if (ulCPUId != i) { _SmpCallIpi(i, pipim); KN_SMP_MB(); pipim->IPIM_iWait = iWaitSave; KN_SMP_WMB(); } } }
/********************************************************************************************************* ** 函数名称: _SmpSpinTryLockTask ** 功能描述: 自旋锁尝试原始加锁操作. (不锁定中断, 同时允许加锁后调用可能产生阻塞的操作) ** 输 入 : psl 自旋锁 ** 输 出 : LW_TRUE 加锁正常 LW_FALSE 加锁失败 ** 全局变量: ** 调用模块: *********************************************************************************************************/ BOOL _SmpSpinTryLockTask (spinlock_t *psl) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; INT iRet; iregInterLevel = KN_INT_DISABLE(); pcpuCur = LW_CPU_GET_CUR(); _BugHandle(pcpuCur->CPU_ulInterNesting, LW_TRUE, "called from ISR.\r\n"); __THREAD_LOCK_INC(pcpuCur->CPU_ptcbTCBCur); /* 锁定任务在当前 CPU */ iRet = __ARCH_SPIN_TRYLOCK_RAW(psl); KN_SMP_MB(); if (iRet != LW_SPIN_OK) { __THREAD_LOCK_DEC(pcpuCur->CPU_ptcbTCBCur); /* 解锁失败, 解除任务锁定 */ } KN_INT_ENABLE(iregInterLevel); return ((iRet == LW_SPIN_OK) ? (LW_TRUE) : (LW_FALSE)); }
/********************************************************************************************************* ** 函数名称: 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); }
static VOID _KernelBootSecondary (VOID) { KN_SMP_MB(); /* 内存屏障, 确保之前操作已处理*/ KN_SECONDARY_GO(); /* 通知从核可以进行基本初始化 */ LW_SPINLOCK_NOTIFY(); }
/********************************************************************************************************* ** 函数名称: __vmmLibPrimaryInit ** 功能描述: 初始化 MMU 功能, CPU 构架相关。(多核模式下, 为主核 MMU 初始化) ** 输 入 : pmmugdesc 初始化使用的全局映射表 ** pcMachineName 正在运行的机器名称 ** 输 出 : BSP 函数返回值 ** 全局变量: ** 调用模块: *********************************************************************************************************/ ULONG __vmmLibPrimaryInit (PLW_MMU_GLOBAL_DESC pmmugdesc, CPCHAR pcMachineName) { static BOOL bIsInit = LW_FALSE; BOOL bIsNeedGlobalMap = LW_FALSE; REGISTER PLW_MMU_CONTEXT pmmuctx = __vmmGetCurCtx(); REGISTER INT iError; REGISTER ULONG ulError; INT iErrLevel = 0; if (bIsInit == LW_FALSE) { __ARCH_MMU_INIT(pcMachineName); /* 初始化 MMU 函数 */ bIsInit = LW_TRUE; bIsNeedGlobalMap = LW_TRUE; } iError = __VMM_MMU_MEM_INIT(pmmuctx); /* 创建页表内存缓冲区 */ if (iError < ERROR_NONE) { _DebugHandle(__ERRORMESSAGE_LEVEL, "mmu memory init error.\r\n"); return (ERROR_KERNEL_MEMORY); } _DebugHandle(__LOGMESSAGE_LEVEL, "mmu initialize. start memory pagination...\r\n"); /* * __vmm_pgd_alloc() 地址为 0 , 表示页表基址 + 0 偏移量, 所以返回的页表项就是页表基址. */ pmmuctx->MMUCTX_pgdEntry = LW_NULL; pmmuctx->MMUCTX_pgdEntry = __vmm_pgd_alloc(pmmuctx, 0ul); /* 创建 PGD 区域 */ if (pmmuctx->MMUCTX_pgdEntry == LW_NULL) { _DebugHandle(__ERRORMESSAGE_LEVEL, "mmu can not allocate pgd entry.\r\n"); iErrLevel = 1; ulError = ERROR_KERNEL_MEMORY; goto __error_handle; } if (bIsNeedGlobalMap) { iError = __VMM_MMU_GLOBAL_INIT(pcMachineName); /* 初始化体系相关关键数据 */ if (iError < ERROR_NONE) { iErrLevel = 2; ulError = errno; goto __error_handle; } iError = __vmmLibGlobalMap(pmmuctx, pmmugdesc); /* 全局内存关系映射 */ if (iError < ERROR_NONE) { iErrLevel = 2; ulError = errno; goto __error_handle; } } __VMM_MMU_MAKE_CURCTX(pmmuctx); /* 设置页表基地址 */ KN_SMP_MB(); return (ERROR_NONE); __error_handle: if (iErrLevel > 1) { __vmm_pgd_free(pmmuctx->MMUCTX_pgdEntry); } _ErrorHandle(ulError); return (ulError); }