Ejemplo n.º 1
0
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);                                  /*  退出内核同时打开中断        */
}
Ejemplo n.º 2
0
/*********************************************************************************************************
** 函数名称: __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);
}
Ejemplo n.º 3
0
/*********************************************************************************************************
** 函数名称: 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);
}
Ejemplo n.º 4
0
/*********************************************************************************************************
** 函数名称: 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);
}
Ejemplo n.º 5
0
/*********************************************************************************************************
** 函数名称: _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));
}
Ejemplo n.º 6
0
/*********************************************************************************************************
** 函数名称: __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);
}
Ejemplo n.º 7
0
/*********************************************************************************************************
** 函数名称: _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);
}
Ejemplo n.º 8
0
/*********************************************************************************************************
** 函数名称: _SmpSpinUnlock
** 功能描述: 自旋锁解锁操作
** 输 入  : psl           自旋锁
** 输 出  : 调度器返回值
** 全局变量:
** 调用模块:
*********************************************************************************************************/
INT  _SmpSpinUnlock (spinlock_t *psl)
{
    INTREG          iregInterLevel;
    PLW_CLASS_CPU   pcpuCur;
    PLW_CLASS_TCB   ptcbCur;
    BOOL            bTrySched = LW_FALSE;
    INT             iRet;

    iregInterLevel = KN_INT_DISABLE();

    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);
    }
}
Ejemplo n.º 9
0
/*********************************************************************************************************
** 函数名称: _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);
}
Ejemplo n.º 10
0
/*********************************************************************************************************
** 函数名称: 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);
}
Ejemplo n.º 11
0
/*********************************************************************************************************
** 函数名称: _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);
    }
}
Ejemplo n.º 12
0
/*********************************************************************************************************
** 函数名称: API_ThreadCancel
** 功能描述: 取消一个指定的线程
** 输 入  : ulId                          线程句柄
** 输 出  : ERROR_NONE or ESRCH
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
ULONG  API_ThreadCancel (LW_OBJECT_HANDLE  *pulId)
{
             INTREG                iregInterLevel;
    REGISTER LW_OBJECT_HANDLE      ulId;
    REGISTER UINT16                usIndex;
    REGISTER PLW_CLASS_TCB         ptcbDel;

    ulId = *pulId;
    
    usIndex = _ObjectGetIndex(ulId);
    
#if LW_CFG_ARG_CHK_EN > 0
    if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) {                        /*  检查 ID 类型有效性          */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
        return  (ERROR_KERNEL_HANDLE_NULL);
    }
    
    if (_Thread_Index_Invalid(usIndex)) {                               /*  检查线程有效性              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }
#endif

    __KERNEL_ENTER();                                                   /*  进入内核                    */
    if (_Thread_Invalid(usIndex)) {
        __KERNEL_EXIT();                                                /*  退出内核                    */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "thread handle invalidate.\r\n");
        _ErrorHandle(ERROR_THREAD_NULL);
        return  (ERROR_THREAD_NULL);
    }
    
    iregInterLevel = KN_INT_DISABLE();
    
    ptcbDel = _K_ptcbTCBIdTable[usIndex];
    if (ptcbDel->TCB_iCancelState == LW_THREAD_CANCEL_ENABLE) {         /*  允许 CANCEL                 */
        if (ptcbDel->TCB_iCancelType == LW_THREAD_CANCEL_DEFERRED) {    /*  延迟 CANCEL                 */
            ptcbDel->TCB_bCancelRequest = LW_TRUE;                      /*  目标线程进入下一个 TEST 点  */
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核并打开中断          */
        
        } else {                                                        /*  异步取消                    */
            __KERNEL_EXIT_IRQ(iregInterLevel);                          /*  退出内核并打开中断          */
#if LW_CFG_SIGNAL_EN > 0
            kill(ulId, SIGCANCEL);                                      /*  立即发送取消信号            */
#else
            return  (API_ThreadDelete(ulId, LW_NULL));
#endif                                                                  /*  LW_CFG_SIGNAL_EN > 0        */
        }
    
    } else {
        __KERNEL_EXIT_IRQ(iregInterLevel);                              /*  退出内核并打开中断          */
        _ErrorHandle(ERROR_THREAD_DISCANCEL);                           /*  不允许 CACNCEL              */
        return  (ERROR_THREAD_DISCANCEL);
    }
    
    return  (ERROR_NONE);
}
Ejemplo n.º 13
0
/*********************************************************************************************************
** 函数名称: _SmpProcCallfunc
** 功能描述: 处理核间中断调用函数
** 输 入  : pcpuCur       当前 CPU
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static VOID  _SmpProcCallfunc (PLW_CLASS_CPU  pcpuCur)
{
    INTREG  iregInterLevel;
    
    iregInterLevel = KN_INT_DISABLE();
    __smpProcCallfunc(pcpuCur);
    KN_INT_ENABLE(iregInterLevel);
}
Ejemplo n.º 14
0
/*********************************************************************************************************
** 函数名称: 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);
}
Ejemplo n.º 15
0
/*********************************************************************************************************
** 函数名称: 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);
    }
}
Ejemplo n.º 16
0
/*********************************************************************************************************
** 函数名称: _UpKernelLockQuick
** 功能描述: 内核自旋锁加锁操作, 连同锁定中断
** 输 入  : piregInterLevel   中断锁定信息
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _UpKernelLockQuick (INTREG  *piregInterLevel)
{
    PLW_CLASS_CPU   pcpuCur = LW_CPU_GET_CUR();
    
    if (!pcpuCur->CPU_ulInterNesting) {
        __THREAD_LOCK_INC(pcpuCur->CPU_ptcbTCBCur);                     /*  锁定任务在当前 CPU          */
    }
    
    *piregInterLevel = KN_INT_DISABLE();
}
Ejemplo n.º 17
0
/*********************************************************************************************************
** 函数名称: _UpSpinLockIrq
** 功能描述: 自旋锁加锁操作, 连同锁定中断
** 输 入  : psl               自旋锁
**           piregInterLevel   中断锁定信息
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  _UpSpinLockIrq (spinlock_t *psl, INTREG  *piregInterLevel)
{
    PLW_CLASS_CPU   pcpuCur = LW_CPU_GET_CUR();
    
    if (!pcpuCur->CPU_ulInterNesting) {
        __THREAD_LOCK_INC(pcpuCur->CPU_ptcbTCBCur);                     /*  锁定任务在当前 CPU          */
    }
    
    *piregInterLevel = KN_INT_DISABLE();
}
Ejemplo n.º 18
0
/*********************************************************************************************************
** 函数名称: 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);
}
Ejemplo n.º 19
0
/*********************************************************************************************************
** 函数名称: 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);
}
Ejemplo n.º 20
0
/*********************************************************************************************************
** 函数名称: 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);
}
Ejemplo n.º 21
0
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();
}
Ejemplo n.º 22
0
/*********************************************************************************************************
** 函数名称: __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);
    }
}
Ejemplo n.º 23
0
/*********************************************************************************************************
** 函数名称: _SmpSpinLockIrq
** 功能描述: 自旋锁加锁操作, 连同锁定中断
** 输 入  : psl               自旋锁
**           piregInterLevel   中断锁定信息
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
VOID  _SmpSpinLockIrq (spinlock_t *psl, INTREG  *piregInterLevel)
{
    PLW_CLASS_CPU   pcpuCur;

    *piregInterLevel = 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();
}
Ejemplo n.º 24
0
/*********************************************************************************************************
** 函数名称: 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);                          /*  退出内核并打开中断          */
}
Ejemplo n.º 25
0
/*********************************************************************************************************
** 函数名称: _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);
}
Ejemplo n.º 26
0
/*********************************************************************************************************
** 函数名称: _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);                                  /*  退出内核同时打开中断        */
}
Ejemplo n.º 27
0
/*********************************************************************************************************
** 函数名称: 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);
}
Ejemplo n.º 28
0
/*********************************************************************************************************
** 函数名称: 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);
}
Ejemplo n.º 29
0
/*********************************************************************************************************
** 函数名称: archIntHandle
** 功能描述: bspIntHandle 需要调用此函数处理中断 (关闭中断情况被调用)
** 输 入  : ulVector         中断向量
**           bPreemptive      中断是否可抢占
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
** 注  意  : 此函数退出时必须为中断关闭状态.
*********************************************************************************************************/
VOID  archIntHandle (ULONG  ulVector, BOOL  bPreemptive)
{
    REGISTER irqreturn_t irqret;

    if (_Inter_Vector_Invalid(ulVector)) {
        return;                                                         /*  向量号不正确                */
    }

    if (LW_IVEC_GET_FLAG(ulVector) & LW_IRQ_FLAG_PREEMPTIVE) {
        bPreemptive = LW_TRUE;
    }

    if (bPreemptive) {
        VECTOR_OP_LOCK();
        __ARCH_INT_VECTOR_DISABLE(ulVector);                            /*  屏蔽 vector 中断            */
        VECTOR_OP_UNLOCK();
        KN_INT_ENABLE_FORCE();                                          /*  允许中断                    */
    }

    irqret = API_InterVectorIsr(ulVector);                              /*  调用中断服务程序            */
    
    KN_INT_DISABLE();                                                   /*  禁能中断                    */
    
    if (bPreemptive) {
        if (irqret != LW_IRQ_HANDLED_DISV) {
            VECTOR_OP_LOCK();
            __ARCH_INT_VECTOR_ENABLE(ulVector);                         /*  允许 vector 中断            */
            VECTOR_OP_UNLOCK();
        }
    
    } else if (irqret == LW_IRQ_HANDLED_DISV) {
        VECTOR_OP_LOCK();
        __ARCH_INT_VECTOR_DISABLE(ulVector);                            /*  屏蔽 vector 中断            */
        VECTOR_OP_UNLOCK();
    }
}
Ejemplo n.º 30
0
/*********************************************************************************************************
** 函数名称: _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));
}