VOID _WatchDogTick (VOID) { INTREG iregInterLevel; REGISTER PLW_CLASS_TCB ptcb; PLW_CLASS_WAKEUP_NODE pwun; ULONG ulCounter = 1; iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核同时关闭中断 */ __WAKEUP_PASS_FIRST(&_K_wuWatchDog, pwun, ulCounter); ptcb = _LIST_ENTRY(pwun, LW_CLASS_TCB, TCB_wunWatchDog); __DEL_FROM_WATCHDOG_LINE(ptcb); /* 从扫描链表中删除 */ KN_INT_ENABLE(iregInterLevel); bspWdTimerHook(ptcb->TCB_ulId); __LW_WATCHDOG_TIMER_HOOK(ptcb->TCB_ulId); /* 执行回调函数 */ iregInterLevel = KN_INT_DISABLE(); __WAKEUP_PASS_SECOND(); KN_INT_ENABLE(iregInterLevel); /* 这里允许响应中断 */ iregInterLevel = KN_INT_DISABLE(); __WAKEUP_PASS_END(); __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核同时打开中断 */ }
/********************************************************************************************************* ** 函数名称: __vmmLibPageMap ** 功能描述: 将物理页面重新映射 ** 输 入 : ulPhysicalAddr 物理页面地址 ** ulVirtualAddr 需要映射的虚拟地址 ** ulPageNum 需要映射的页面个数 ** ulFlag 页面标志 ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ ULONG __vmmLibPageMap (addr_t ulPhysicalAddr, addr_t ulVirtualAddr, ULONG ulPageNum, ULONG ulFlag) { INTREG iregInterLevel; ULONG i; PLW_MMU_CONTEXT pmmuctx = __vmmGetCurCtx(); LW_PGD_TRANSENTRY *p_pgdentry; LW_PMD_TRANSENTRY *p_pmdentry; LW_PTE_TRANSENTRY *p_pteentry; for (i = 0; i < ulPageNum; i++) { p_pgdentry = __vmm_pgd_alloc(pmmuctx, ulVirtualAddr); if (p_pgdentry == LW_NULL) { return (ERROR_VMM_LOW_LEVEL); } p_pmdentry = __vmm_pmd_alloc(pmmuctx, p_pgdentry, ulVirtualAddr); if (p_pmdentry == LW_NULL) { return (ERROR_VMM_LOW_LEVEL); } p_pteentry = __vmm_pte_alloc(pmmuctx, p_pmdentry, ulVirtualAddr); if (p_pteentry == LW_NULL) { return (ERROR_VMM_LOW_LEVEL); } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ __VMM_MMU_MAKE_TRANS(pmmuctx, p_pteentry, ulPhysicalAddr, ulFlag); /* 创建映射关系 */ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ ulPhysicalAddr += LW_CFG_VMM_PAGE_SIZE; ulVirtualAddr += LW_CFG_VMM_PAGE_SIZE; } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ #if LW_CFG_SMP_EN > 0 if (LW_SYS_STATUS_IS_RUNNING() && (__VMM_MMU_OPTION() & LW_VMM_MMU_FLUSH_TLB_MP)) { _SmpSendIpiAllOther(LW_IPI_FLUSH_TLB, 1); /* 同步刷新所有 CPU TLB */ } #endif /* LW_CFG_SMP_EN */ __VMM_MMU_INV_TLB(pmmuctx); /* 无效快表 */ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_GetLastError ** 功能描述: 获得系统最近一个错误 ** 输 入 : ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_GetLastError (VOID) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; PLW_CLASS_TCB ptcbCur; ULONG ulLastError; iregInterLevel = KN_INT_DISABLE(); /* 关闭中断, 防止调度到其他 CPU*/ pcpuCur = LW_CPU_GET_CUR(); if (pcpuCur->CPU_ulInterNesting) { ulLastError = pcpuCur->CPU_ulInterError[pcpuCur->CPU_ulInterNesting]; } else { ptcbCur = pcpuCur->CPU_ptcbTCBCur; if (ptcbCur) { ulLastError = ptcbCur->TCB_ulLastError; } else { ulLastError = _K_ulNotRunError; } } KN_INT_ENABLE(iregInterLevel); return (ulLastError); }
/********************************************************************************************************* ** 函数名称: API_CacheTextUpdate ** 功能描述: 清空(回写内存) D CACHE 无效(访问不命中) I CACHE ** 输 入 : pvAdrs 虚拟地址 ** stBytes 长度 ** 输 出 : BSP 函数返回值 ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT API_CacheTextUpdate (PVOID pvAdrs, size_t stBytes) { INTREG iregInterLevel; INT iError; #if LW_CFG_SMP_EN > 0 LW_CACHE_TU_ARG tuarg; #endif /* LW_CFG_SMP_EN */ __CACHE_OP_ENTER(iregInterLevel); /* 开始操作 cache */ iError = ((_G_cacheopLib.CACHEOP_pfuncTextUpdate == LW_NULL) ? ERROR_NONE : (_G_cacheopLib.CACHEOP_pfuncTextUpdate)(pvAdrs, stBytes)); __CACHE_OP_EXIT(iregInterLevel); /* 结束操作 cache */ #if LW_CFG_SMP_EN > 0 if (_G_cacheopLib.CACHEOP_ulOption & CACHE_TEXT_UPDATE_MP) { tuarg.TUA_pvAddr = pvAdrs; tuarg.TUA_stSize = stBytes; iregInterLevel = KN_INT_DISABLE(); _SmpCallFuncAllOther(__cacheTextUpdate, &tuarg, LW_NULL, LW_NULL, IPIM_OPT_NORMAL); /* 通知其他的 CPU */ KN_INT_ENABLE(iregInterLevel); } #endif /* LW_CFG_SMP_EN */ return (iError); }
/********************************************************************************************************* ** 函数名称: __errno ** 功能描述: posix 获得当前 errno ** 输 入 : NONE ** 输 出 : errno ** 全局变量: ** 调用模块: ** 注 意 : 由于 longwing 由于历史原因采用 ulong 保存错误编号, 而 posix 使用 errno_t 类型, 而绝大多数系统 将 errno_t 定义为 int 型, 假设使用 GCC 3.x 以上版本带有 -fstrict-aliasing 参数.这里的代码可能 会产生一个警告: strict aliasing, 目前将此警告忽略处理. *********************************************************************************************************/ errno_t *__errno (VOID) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; PLW_CLASS_TCB ptcbCur; errno_t *perrno; iregInterLevel = KN_INT_DISABLE(); /* 关闭中断, 防止调度到其他 CPU*/ pcpuCur = LW_CPU_GET_CUR(); if (pcpuCur->CPU_ulInterNesting) { perrno = (errno_t *)(&pcpuCur->CPU_ulInterError[pcpuCur->CPU_ulInterNesting]); } else { ptcbCur = pcpuCur->CPU_ptcbTCBCur; if (ptcbCur) { perrno = (errno_t *)(&ptcbCur->TCB_ulLastError); } else { perrno = (errno_t *)(&_K_ulNotRunError); } } KN_INT_ENABLE(iregInterLevel); return (perrno); }
/********************************************************************************************************* ** 函数名称: _UpSpinUnlock ** 功能描述: 自旋锁解锁操作 ** 输 入 : psl 自旋锁 ** 输 出 : 调度器返回值 ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT _UpSpinUnlock (spinlock_t *psl) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur = LW_CPU_GET_CUR(); BOOL bTrySched = LW_FALSE; iregInterLevel = KN_INT_DISABLE(); if (!pcpuCur->CPU_ulInterNesting) { __THREAD_LOCK_DEC(pcpuCur->CPU_ptcbTCBCur); /* 解除任务锁定 */ if (__COULD_SCHED(pcpuCur, 0)) { bTrySched = LW_TRUE; /* 需要尝试调度 */ } } KN_INT_ENABLE(iregInterLevel); if (bTrySched) { return (_ThreadSched(pcpuCur->CPU_ptcbTCBCur)); } else { return (ERROR_NONE); } 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)); }
/********************************************************************************************************* ** 函数名称: _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); } }
/********************************************************************************************************* ** 函数名称: sio16c550Open ** 功能描述: 串口接口打开 (Set the modem control lines) ** 输 入 : psiochan SIO CHAN ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT sio16c550Open (SIO16C550_CHAN *psiochan) { INTREG intreg; UINT8 mask; mask = (UINT8)(GET_REG(psiochan, MCR) & (MCR_RTS | MCR_DTR)); if (mask != (MCR_RTS | MCR_DTR)) { /* * RTS and DTR not set yet */ intreg = KN_INT_DISABLE(); /* * set RTS and DTR TRUE */ psiochan->mcr |= (MCR_DTR | MCR_RTS); SET_REG(psiochan, MCR, psiochan->mcr); /* * clear Tx and receive and enable FIFO */ SET_REG(psiochan, FCR, ((psiochan->rx_trigger_level << 6) | RxCLEAR | TxCLEAR | FIFO_ENABLE)); KN_INT_ENABLE(intreg); } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: _ErrorHandle ** 功能描述: 记录当前错误号 ** 输 入 : ulErrorCode 当前错误号 ** 输 出 : NONE ** 全局变量: ** 调用模块: ** 注 意 : *********************************************************************************************************/ VOID _ErrorHandle (ULONG ulErrorCode) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; PLW_CLASS_TCB ptcbCur; #if LW_CFG_ERRORNO_AUTO_CLEAR == 0 if (ulErrorCode == 0) { return; } #endif iregInterLevel = KN_INT_DISABLE(); /* 关闭中断, 防止调度到其他 CPU*/ pcpuCur = LW_CPU_GET_CUR(); if (pcpuCur->CPU_ulInterNesting) { pcpuCur->CPU_ulInterError[pcpuCur->CPU_ulInterNesting] = ulErrorCode; } else { ptcbCur = pcpuCur->CPU_ptcbTCBCur; if (ptcbCur) { ptcbCur->TCB_ulLastError = ulErrorCode; } else { _K_ulNotRunError = ulErrorCode; } } KN_INT_ENABLE(iregInterLevel); }
/********************************************************************************************************* ** 函数名称: _SmpProcCallfunc ** 功能描述: 处理核间中断调用函数 ** 输 入 : pcpuCur 当前 CPU ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID _SmpProcCallfunc (PLW_CLASS_CPU pcpuCur) { INTREG iregInterLevel; iregInterLevel = KN_INT_DISABLE(); __smpProcCallfunc(pcpuCur); KN_INT_ENABLE(iregInterLevel); }
/********************************************************************************************************* ** 函数名称: sigwaitinfo ** 功能描述: 等待 sigset 内信号的到来,以串行的方式从信号队列中取出信号进行处理, 信号将不再被执行. ** 输 入 : psigset 指定的信号集 ** psiginfo 获取的信号信息 ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigwaitinfo (const sigset_t *psigset, struct siginfo *psiginfo) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; INT iSigNo; PLW_CLASS_SIGCONTEXT psigctx; struct siginfo siginfo; LW_CLASS_SIGWAIT sigwt; if (!psigset) { _ErrorHandle(EINVAL); return (PX_ERROR); } __THREAD_CANCEL_POINT(); /* 测试取消点 */ LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_D2(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_SIGWAIT, ptcbCur->TCB_ulId, *psigset, LW_NULL); __KERNEL_ENTER(); /* 进入内核 */ psigctx = _signalGetCtx(ptcbCur); iSigNo = _sigPendGet(psigctx, psigset, &siginfo); /* 检查当前是否有等待的信号 */ if (__issig(iSigNo)) { __KERNEL_EXIT(); /* 退出内核 */ if (psiginfo) { *psiginfo = siginfo; } return (siginfo.si_signo); } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL; /* 等待信号 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ sigwt.SIGWT_sigset = *psigset; psigctx->SIGCTX_sigwait = &sigwt; /* 保存等待信息 */ if (__KERNEL_EXIT()) { /* 是否其他信号激活 */ psigctx->SIGCTX_sigwait = LW_NULL; _ErrorHandle(EINTR); /* SA_RESTART 也退出 */ return (PX_ERROR); } psigctx->SIGCTX_sigwait = LW_NULL; if (psiginfo) { *psiginfo = sigwt.SIGWT_siginfo; } return (sigwt.SIGWT_siginfo.si_signo); }
/********************************************************************************************************* ** 函数名称: 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); } }
/********************************************************************************************************* ** 函数名称: _UpKernelUnlockQuick ** 功能描述: 内核自旋锁解锁操作, 连同解锁中断, 不进行尝试调度 ** 输 入 : iregInterLevel 中断锁定信息 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _UpKernelUnlockQuick (INTREG iregInterLevel) { PLW_CLASS_CPU pcpuCur = LW_CPU_GET_CUR(); if (!pcpuCur->CPU_ulInterNesting) { __THREAD_LOCK_DEC(pcpuCur->CPU_ptcbTCBCur); /* 解锁任务在当前 CPU */ } KN_INT_ENABLE(iregInterLevel); }
/********************************************************************************************************* ** 函数名称: sigsuspend ** 功能描述: 使用指定的掩码等待一个有效信号的到来, 然后返回先前的信号掩码. ** 输 入 : psigsetMask 指定的信号掩码 ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigsuspend (const sigset_t *psigsetMask) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; BOOL bIsRun; PLW_CLASS_SIGCONTEXT psigctx; sigset_t sigsetOld; if (!psigsetMask) { _ErrorHandle(EINVAL); return (PX_ERROR); } __THREAD_CANCEL_POINT(); /* 测试取消点 */ LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_D2(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_SIGSUSPEND, ptcbCur->TCB_ulId, *psigsetMask, LW_NULL); __KERNEL_ENTER(); /* 进入内核 */ psigctx = _signalGetCtx(ptcbCur); sigsetOld = psigctx->SIGCTX_sigsetSigBlockMask; /* 记录先前的掩码 */ psigctx->SIGCTX_sigsetSigBlockMask = *psigsetMask & (~__SIGNO_UNMASK); bIsRun = _sigPendRun(ptcbCur); if (bIsRun) { __KERNEL_EXIT(); /* 退出内核 */ sigprocmask(SIG_SETMASK, &sigsetOld, LW_NULL); /* 设置为原先的 mask */ _ErrorHandle(EINTR); return (PX_ERROR); } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL; /* 等待信号 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ __KERNEL_EXIT(); /* 退出内核 */ sigprocmask(SIG_SETMASK, &sigsetOld, NULL); _ErrorHandle(EINTR); return (PX_ERROR); }
/********************************************************************************************************* ** 函数名称: sio16550SetMode ** 功能描述: 串口接口设置模式 ** 输 入 : psiochan SIO CHAN ** newmode 新的模式 SIO_MODE_INT / SIO_MODE_POLL ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT sio16c550SetMode (SIO16C550_CHAN *psiochan, INT newmode) { INTREG intreg; UINT8 mask; if ((newmode != SIO_MODE_POLL) && (newmode != SIO_MODE_INT)) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (psiochan->channel_mode == newmode) { return (ERROR_NONE); } intreg = KN_INT_DISABLE(); if (newmode == SIO_MODE_INT) { /* * Enable appropriate interrupts */ if (psiochan->hw_option & CLOCAL) { SET_REG(psiochan, IER, (psiochan->ier | RxFIFO_BIT | TxFIFO_BIT)); } else { mask = (UINT8)(GET_REG(psiochan, MSR) & MSR_CTS); /* * if the CTS is asserted enable Tx interrupt */ if (mask & MSR_CTS) { psiochan->ier |= TxFIFO_BIT; /* enable Tx interrupt */ } else { psiochan->ier &= (~TxFIFO_BIT); /* disable Tx interrupt */ } SET_REG(psiochan, IER, psiochan->ier); } } else { /* * disable all ns16550 interrupts */ SET_REG(psiochan, IER, 0); } psiochan->channel_mode = newmode; KN_INT_ENABLE(intreg); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: sio16c550Hup ** 功能描述: 串口接口挂起 ** 输 入 : psiochan SIO CHAN ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT sio16c550Hup (SIO16C550_CHAN *psiochan) { INTREG intreg; intreg = KN_INT_DISABLE(); psiochan->mcr &= (~(MCR_RTS | MCR_DTR)); SET_REG(psiochan, MCR, psiochan->mcr); SET_REG(psiochan, FCR, (RxCLEAR | TxCLEAR)); KN_INT_ENABLE(intreg); return (ERROR_NONE); }
static VOID _SmpProcFlushTlb (PLW_CLASS_CPU pcpuCur) { INTREG iregInterLevel; PLW_MMU_CONTEXT pmmuctx = __vmmGetCurCtx(); iregInterLevel = KN_INT_DISABLE(); __VMM_MMU_INV_TLB(pmmuctx); /* 无效快表 */ KN_INT_ENABLE(iregInterLevel); LW_SPIN_LOCK_QUICK(&pcpuCur->CPU_slIpi, &iregInterLevel); /* 锁定 CPU */ LW_CPU_CLR_IPI_PEND2(pcpuCur, LW_IPI_FLUSH_TLB_MSK); /* 清除 */ LW_SPIN_UNLOCK_QUICK(&pcpuCur->CPU_slIpi, iregInterLevel); /* 解锁 CPU */ LW_SPINLOCK_NOTIFY(); }
/********************************************************************************************************* ** 函数名称: __vmmLibSetFlag ** 功能描述: 设置指定逻辑地址的访问权限 ** 输 入 : ulVirtualAddr 需要映射的虚拟地址 ** ulFlag 页面标志 ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ ULONG __vmmLibSetFlag (addr_t ulVirtualAddr, ULONG ulFlag) { INTREG iregInterLevel; PLW_MMU_CONTEXT pmmuctx = __vmmGetCurCtx(); INT iError; iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ iError = __VMM_MMU_FLAG_SET(pmmuctx, ulVirtualAddr, ulFlag); KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ if (iError < ERROR_NONE) { return (ERROR_VMM_LOW_LEVEL); } else { return (ERROR_NONE); } }
/********************************************************************************************************* ** 函数名称: API_KernelTicksContext ** 功能描述: 处理系统时钟中断. (此函数必须在中断中被调用) ** 输 入 : ** 输 出 : ** 全局变量: ** 调用模块: ** 注 意 : vprocTickHook() 可能会激活新的任务, 会在中断退出时会尝试调度. 所以这里允许在 QUICK 操作中打开中断. API 函数 *********************************************************************************************************/ LW_API VOID API_KernelTicksContext (VOID) { INTREG iregInterLevel; REGISTER INT i; PLW_CLASS_CPU pcpu; PLW_CLASS_TCB ptcb; LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel); /* 锁定内核并关闭中断 */ #if LW_CFG_RTC_EN > 0 __kernelTODUpdate(); /* 更新 TOD 时间 */ #endif /* LW_CFG_RTC_EN > 0 */ __kernelTickUpdate(); /* 更新 TICK 时间 */ KN_INT_ENABLE(iregInterLevel); /* 允许其他中断进入 */ #if LW_CFG_SMP_EN > 0 for (i = 0; i < LW_NCPUS; i++) { /* 遍历所有的核 */ #else i = 0; #endif /* LW_CFG_SMP_EN */ pcpu = LW_CPU_GET(i); if (LW_CPU_IS_ACTIVE(pcpu)) { /* CPU 必须被激活 */ ptcb = pcpu->CPU_ptcbTCBCur; ptcb->TCB_ulCPUTicks++; if (pcpu->CPU_iKernelCounter) { ptcb->TCB_ulCPUKernelTicks++; } __LW_TICK_CPUUSAGE_UPDATE(ptcb, pcpu); /* 更新所有 CPU 利用率 */ #if LW_CFG_MODULELOADER_EN > 0 vprocTickHook(ptcb, pcpu); /* 测算进程执行时间 */ #endif } #if LW_CFG_SMP_EN > 0 } #endif /* LW_CFG_SMP_EN */ iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ _SchedTick(); /* 处理所有 CPU 线程的时间片 */ LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel); /* 退出内核并打开中断 */ }
/********************************************************************************************************* ** 函数名称: _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); }
/********************************************************************************************************* ** 函数名称: _SmpSpinUnlockIrqQuick ** 功能描述: 自旋锁解锁操作, 连同解锁中断, 不进行尝试调度 ** 输 入 : psl 自旋锁 ** iregInterLevel 中断锁定信息 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _SmpSpinUnlockIrqQuick (spinlock_t *psl, INTREG iregInterLevel) { 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); 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); }
/********************************************************************************************************* ** 函数名称: _ThreadTick ** 功能描述: 扫描等待唤醒链表, tick 处理函数 ** 输 入 : NONE ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _ThreadTick (VOID) { INTREG iregInterLevel; REGISTER PLW_CLASS_TCB ptcb; REGISTER PLW_CLASS_PCB ppcb; PLW_CLASS_WAKEUP_NODE pwun; ULONG ulCounter = 1; iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核同时关闭中断 */ __WAKEUP_PASS_FIRST(&_K_wuDelay, pwun, ulCounter); ptcb = _LIST_ENTRY(pwun, LW_CLASS_TCB, TCB_wunDelay); __DEL_FROM_WAKEUP_LINE(ptcb); /* 从等待链中删除 */ if (ptcb->TCB_usStatus & LW_THREAD_STATUS_PEND_ANY) { /* 检查是否在等待事件 */ ptcb->TCB_usStatus &= (~LW_THREAD_STATUS_PEND_ANY); /* 等待超时清除事件等待位 */ ptcb->TCB_ucWaitTimeout = LW_WAIT_TIME_OUT; /* 等待超时 */ } else { ptcb->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR; /* 没有等待事件 */ } if (__LW_THREAD_IS_READY(ptcb)) { /* 检查是否就绪 */ ptcb->TCB_ucSchedActivate = LW_SCHED_ACT_OTHER; ppcb = _GetPcb(ptcb); /* 获得优先级控制块 */ __ADD_TO_READY_RING(ptcb, ppcb); /* 加入就绪环 */ } __WAKEUP_PASS_SECOND(); KN_INT_ENABLE(iregInterLevel); /* 这里允许响应中断 */ iregInterLevel = KN_INT_DISABLE(); __WAKEUP_PASS_END(); __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核同时打开中断 */ }
/********************************************************************************************************* ** 函数名称: sio16c550SetBaud ** 功能描述: 设置波特率 ** 输 入 : psiochan SIO CHAN ** baud 波特率 ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT sio16c550SetBaud (SIO16C550_CHAN *psiochan, ULONG baud) { INTREG intreg; INT divisor = (INT)((psiochan->xtal + (8 * baud)) / (16 * baud)); if ((divisor < 1) || (divisor > 0xffff)) { _ErrorHandle(EIO); return (PX_ERROR); } /* * disable interrupts during chip access */ intreg = KN_INT_DISABLE(); /* * Enable access to the divisor latches by setting DLAB in LCR. */ SET_REG(psiochan, LCR, (LCR_DLAB | psiochan->lcr)); /* * Set divisor latches. */ SET_REG(psiochan, DLL, divisor); SET_REG(psiochan, DLM, (divisor >> 8)); /* * Restore line control register */ SET_REG(psiochan, LCR, psiochan->lcr); psiochan->baud = baud; KN_INT_ENABLE(intreg); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: _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); }
/********************************************************************************************************* ** 函数名称: API_CoroutineExit ** 功能描述: 在当前线程正在执行的协程删除 ** 输 入 : NONE ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_CoroutineExit (VOID) { INTREG iregInterLevel; PLW_CLASS_CPU pcpuCur; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_COROUTINE pcrcbExit; REGISTER PLW_CLASS_COROUTINE pcrcbNext; REGISTER PLW_LIST_RING pringNext; if (!LW_SYS_STATUS_IS_RUNNING()) { /* 系统必须已经启动 */ _ErrorHandle(ERROR_KERNEL_NOT_RUNNING); return (ERROR_KERNEL_NOT_RUNNING); } if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n"); _ErrorHandle(ERROR_KERNEL_IN_ISR); return (ERROR_KERNEL_IN_ISR); } LW_TCB_GET_CUR_SAFE(ptcbCur); pcrcbExit = _LIST_ENTRY(ptcbCur->TCB_pringCoroutineHeader, LW_CLASS_COROUTINE, COROUTINE_ringRoutine); /* 获得当前协程 */ if (&pcrcbExit->COROUTINE_ringRoutine == _list_ring_get_next(&pcrcbExit->COROUTINE_ringRoutine)) { /* 仅有这一个协程 */ #if LW_CFG_THREAD_DEL_EN > 0 API_ThreadExit(LW_NULL); #endif /* LW_CFG_THREAD_DEL_EN > 0 */ return (ERROR_NONE); } pringNext = _list_ring_get_next(&pcrcbExit->COROUTINE_ringRoutine); pcrcbNext = _LIST_ENTRY(pringNext, LW_CLASS_COROUTINE, COROUTINE_ringRoutine); /* 获得下一个协程 */ LW_SPIN_LOCK_QUICK(&ptcbCur->TCB_slLock, &iregInterLevel); _List_Ring_Del(&pcrcbExit->COROUTINE_ringRoutine, &ptcbCur->TCB_pringCoroutineHeader); /* 从协程表中删除 */ LW_SPIN_UNLOCK_QUICK(&ptcbCur->TCB_slLock, iregInterLevel); ptcbCur->TCB_pringCoroutineHeader = pringNext; /* 转动到下一个协程 */ MONITOR_EVT_LONG2(MONITOR_EVENT_ID_COROUTINE, MONITOR_EVENT_COROUTINE_DELETE, ptcbCur->TCB_ulId, pcrcbExit, LW_NULL); if (pcrcbExit->COROUTINE_bIsNeedFree) { _StackFree(ptcbCur, pcrcbExit->COROUTINE_pstkStackLowAddr, LW_TRUE); /* 释放内存 */ } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ INIT_DUMMY_STACK(); pcpuCur = LW_CPU_GET_CUR(); pcpuCur->CPU_pcrcbCur = &_K_pcrcbDummy; pcpuCur->CPU_pcrcbNext = pcrcbNext; archCrtCtxSwitch(LW_CPU_GET_CUR()); /* 协程切换 */ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ return (ERROR_NONE); /* 理论上是无法运行到这里的 */ }
PVOID _ITimerThread (PVOID pvArg) { INTREG iregInterLevel; REGISTER PLW_CLASS_TIMER ptmr; PTIMER_CALLBACK_ROUTINE pfuncRoutine; PVOID pvRoutineArg; #if (LW_CFG_RMS_EN > 0) && (LW_CFG_MAX_RMSS > 0) LW_OBJECT_HANDLE ulRms = API_RmsCreate("rms_timer", LW_OPTION_OBJECT_GLOBAL, LW_NULL); #endif (VOID)pvArg; for (;;) { PLW_CLASS_WAKEUP_NODE pwun; ULONG ulCounter = LW_ITIMER_RATE; #if (LW_CFG_RMS_EN > 0) && (LW_CFG_MAX_RMSS > 0) API_RmsPeriod(ulRms, LW_ITIMER_RATE); /* 使用 RMS 进行周期运行 */ #else API_TimeSleep(LW_ITIMER_RATE); /* 等待一个扫描周期 */ #endif iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核同时关闭中断 */ __WAKEUP_PASS_FIRST(&_K_wuITmr, pwun, ulCounter); ptmr = _LIST_ENTRY(pwun, LW_CLASS_TIMER, TIMER_wunTimer); _WakeupDel(&_K_wuITmr, pwun); if (ptmr->TIMER_ulOption & LW_OPTION_AUTO_RESTART) { ptmr->TIMER_ulCounter = ptmr->TIMER_ulCounterSave; _WakeupAdd(&_K_wuITmr, pwun); } else { ptmr->TIMER_ucStatus = LW_TIMER_STATUS_STOP; /* 填写停止标志位 */ } pfuncRoutine = ptmr->TIMER_cbRoutine; pvRoutineArg = ptmr->TIMER_pvArg; __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核同时打开中断 */ LW_SOFUNC_PREPARE(pfuncRoutine); pfuncRoutine(pvRoutineArg); iregInterLevel = __KERNEL_ENTER_IRQ(); /* 进入内核同时关闭中断 */ __WAKEUP_PASS_SECOND(); KN_INT_ENABLE(iregInterLevel); /* 这里允许响应中断 */ iregInterLevel = KN_INT_DISABLE(); __WAKEUP_PASS_END(); __KERNEL_EXIT_IRQ(iregInterLevel); /* 退出内核同时打开中断 */ } return (LW_NULL); }