Esempio n. 1
0
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 进入任务状态       */
}
Esempio n. 2
0
/*********************************************************************************************************
** 函数名称: _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 进入任务状态       */
}
Esempio n. 3
0
/*********************************************************************************************************
** 函数名称: archDataStorageExceptionHandle
** 功能描述: 数据存储异常处理
** 输 入  : NONE
** 输 出  : NONE
** 全局变量:
** 调用模块:
** 注  意  : 此函数退出时必须为中断关闭状态.
*********************************************************************************************************/
VOID  archDataStorageExceptionHandle (addr_t  ulRetAddr)
{
    PLW_CLASS_TCB   ptcbCur;
    addr_t          ulAbortAddr;
    LW_VMM_ABORT    abtInfo;

    ulAbortAddr          = ppcGetDAR();
    abtInfo.VMABT_uiType = LW_VMM_ABORT_TYPE_TERMINAL;

    LW_TCB_GET_CUR(ptcbCur);

#if LW_CFG_VMM_EN > 0
    UINT32  uiDSISR = ppcMmuGetDSISR();

    /*
     * See << programming_environment_manual >> Figure 7-16
     */

    if (uiDSISR & (0x1 << (31 - 1))) {
        /*
         * Page fault (no PTE found)
         */
        abtInfo.VMABT_uiType   = ppcMmuPteMissHandle(ulAbortAddr);
        abtInfo.VMABT_uiMethod = LW_VMM_ABORT_METHOD_READ;

    } else if (uiDSISR & (0x1 << (31 - 4))) {
        /*
         * Page protection violation
         */
        if (uiDSISR & (0x1 << (31 - 6))) {
            /*
             * If the access is a store
             */
            abtInfo.VMABT_uiType   = LW_VMM_ABORT_TYPE_PERM;
            abtInfo.VMABT_uiMethod = LW_VMM_ABORT_METHOD_WRITE;

        } else {
            /*
             * 不允许读
             */
            abtInfo.VMABT_uiType   = LW_VMM_ABORT_TYPE_PERM;
            abtInfo.VMABT_uiMethod = LW_VMM_ABORT_METHOD_READ;
        }

    } else {
        /*
         * dcbt/dcbtst Instruction
         */
        abtInfo.VMABT_uiType = LW_VMM_ABORT_TYPE_TERMINAL;
    }
#endif

    if (abtInfo.VMABT_uiType) {
        API_VmmAbortIsr(ulRetAddr, ulAbortAddr, &abtInfo, ptcbCur);
    }
}
Esempio n. 4
0
/*********************************************************************************************************
** 函数名称: archTraceHandle
** 功能描述: Trace 处理
** 输 入  : NONE
** 输 出  : NONE
** 全局变量:
** 调用模块:
** 注  意  : 此函数退出时必须为中断关闭状态.
*********************************************************************************************************/
VOID  archTraceHandle (addr_t  ulRetAddr)
{
    PLW_CLASS_TCB   ptcbCur;
    LW_VMM_ABORT    abtInfo;

    LW_TCB_GET_CUR(ptcbCur);

    abtInfo.VMABT_uiType = LW_VMM_ABORT_TYPE_TERMINAL;
    API_VmmAbortIsr(ulRetAddr, ulRetAddr, &abtInfo, ptcbCur);
}
Esempio n. 5
0
/*********************************************************************************************************
** 函数名称: archSystemCallHandle
** 功能描述: 系统调用处理
** 输 入  : NONE
** 输 出  : NONE
** 全局变量:
** 调用模块:
** 注  意  : 此函数退出时必须为中断关闭状态.
*********************************************************************************************************/
VOID  archSystemCallHandle (addr_t  ulRetAddr)
{
    PLW_CLASS_TCB   ptcbCur;
    LW_VMM_ABORT    abtInfo;

    LW_TCB_GET_CUR(ptcbCur);

    abtInfo.VMABT_uiType = LW_VMM_ABORT_TYPE_SYS;
    API_VmmAbortIsr(ulRetAddr, ulRetAddr, &abtInfo, ptcbCur);
}
Esempio n. 6
0
/*********************************************************************************************************
** 函数名称: archInstructionStorageExceptionHandle
** 功能描述: 指令访问异常处理
** 输 入  : NONE
** 输 出  : NONE
** 全局变量:
** 调用模块:
** 注  意  : 此函数退出时必须为中断关闭状态.
*********************************************************************************************************/
VOID  archInstructionStorageExceptionHandle (addr_t  ulRetAddr)
{
    PLW_CLASS_TCB   ptcbCur;
    addr_t          ulAbortAddr;
    LW_VMM_ABORT    abtInfo;

    ulAbortAddr          = ppcGetDAR();
    abtInfo.VMABT_uiType = LW_VMM_ABORT_TYPE_TERMINAL;

    LW_TCB_GET_CUR(ptcbCur);

#if LW_CFG_VMM_EN > 0
    /*
     * See << programming_environment_manual >> Figure 7-16
     */

    UINT32  uiSRR1 = ppcMmuGetSRR1();

    if (uiSRR1 & (0x1 << (31 - 1))) {
        /*
         * Page fault (no PTE found)
         */
        abtInfo.VMABT_uiType   = ppcMmuPteMissHandle(ulAbortAddr);
        abtInfo.VMABT_uiMethod = LW_VMM_ABORT_METHOD_READ;

    } else if (uiSRR1 & (0x1 << (31 - 4))) {
        /*
         * Page protection violation
         * 不允许预取
         */
        abtInfo.VMABT_uiType   = LW_VMM_ABORT_TYPE_PERM;
        abtInfo.VMABT_uiMethod = LW_VMM_ABORT_METHOD_READ;

    } else if (uiSRR1 & (0x1 << (31 - 3))) {
        /*
         * If the segment is designated as no-execute
         */
        abtInfo.VMABT_uiType   = LW_VMM_ABORT_TYPE_PERM;
        abtInfo.VMABT_uiMethod = LW_VMM_ABORT_METHOD_EXEC;

    } else {
        /*
         * dcbt/dcbtst Instruction
         */
        abtInfo.VMABT_uiType = LW_VMM_ABORT_TYPE_TERMINAL;
    }
#endif

    if (abtInfo.VMABT_uiType) {
        API_VmmAbortIsr(ulRetAddr, ulAbortAddr, &abtInfo, ptcbCur);
    }
}
Esempio n. 7
0
/*********************************************************************************************************
** 函数名称: archAlignmentExceptionHandle
** 功能描述: 非对齐异常处理
** 输 入  : NONE
** 输 出  : NONE
** 全局变量:
** 调用模块:
** 注  意  : 此函数退出时必须为中断关闭状态.
*********************************************************************************************************/
VOID  archAlignmentExceptionHandle (addr_t  ulRetAddr)
{
    PLW_CLASS_TCB   ptcbCur;
    addr_t          ulAbortAddr;
    LW_VMM_ABORT    abtInfo;

    ulAbortAddr          = ppcGetDAR();
    abtInfo.VMABT_uiType = LW_VMM_ABORT_TYPE_BUS;

    LW_TCB_GET_CUR(ptcbCur);

    API_VmmAbortIsr(ulRetAddr, ulAbortAddr, &abtInfo, ptcbCur);
}
Esempio n. 8
0
/*********************************************************************************************************
** 函数名称: archFpuUnavailableExceptionHandle
** 功能描述: FPU 不可用异常处理
** 输 入  : NONE
** 输 出  : NONE
** 全局变量:
** 调用模块:
** 注  意  : 此函数退出时必须为中断关闭状态.
*********************************************************************************************************/
VOID  archFpuUnavailableExceptionHandle (addr_t  ulRetAddr)
{
    PLW_CLASS_TCB   ptcbCur;
    LW_VMM_ABORT    abtInfo;

    LW_TCB_GET_CUR(ptcbCur);

#if LW_CFG_CPU_FPU_EN > 0
    if (archFpuUndHandle(ptcbCur) == ERROR_NONE) {                      /*  进行 FPU 指令探测           */
        return;
    }
#endif                                                                  /*  LW_CFG_CPU_FPU_EN > 0       */

    abtInfo.VMABT_uiType = LW_VMM_ABORT_TYPE_FPE;
    API_VmmAbortIsr(ulRetAddr, ulRetAddr, &abtInfo, ptcbCur);
}
Esempio n. 9
0
/*********************************************************************************************************
** 函数名称: archProgramExceptionHandle
** 功能描述: 程序异常处理
** 输 入  : NONE
** 输 出  : NONE
** 全局变量:
** 调用模块:
** 注  意  : 此函数退出时必须为中断关闭状态.
*********************************************************************************************************/
VOID  archProgramExceptionHandle (addr_t  ulRetAddr)
{
    PLW_CLASS_TCB   ptcbCur;
    LW_VMM_ABORT    abtInfo;

#if LW_CFG_GDB_EN > 0
    UINT    uiBpType = archDbgTrapType(ulRetAddr, (PVOID)LW_NULL);      /*  断点指令探测                */
    if (uiBpType) {
        if (API_DtraceBreakTrap(ulRetAddr, uiBpType) == ERROR_NONE) {   /*  进入调试接口断点处理        */
            return;
        }
    }
#endif                                                                  /*  LW_CFG_GDB_EN > 0           */

    LW_TCB_GET_CUR(ptcbCur);

    abtInfo.VMABT_uiType   = LW_VMM_ABORT_TYPE_UNDEF;
    abtInfo.VMABT_uiMethod = LW_VMM_ABORT_METHOD_EXEC;
    API_VmmAbortIsr(ulRetAddr, ulRetAddr, &abtInfo, ptcbCur);
}
Esempio n. 10
0
/*********************************************************************************************************
** 函数名称: archAbtHandle
** 功能描述: 系统发生 data abort 或者 prefetch_abort 异常时会调用此函数
** 输 入  : ulRetAddr     异常返回地址.
**           uiArmExcType  ARM 异常类型
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  archAbtHandle (addr_t  ulRetAddr, UINT32  uiArmExcType)
{
#define ARM_EXC_TYPE_ABT    8
#define ARM_EXC_TYPE_PRE    4
    
    PLW_CLASS_TCB   ptcbCur;
    addr_t          ulAbortAddr;
    ULONG           ulAbortType;
    
    if (uiArmExcType == ARM_EXC_TYPE_ABT) {
        ulAbortAddr = armGetAbtAddr();
        ulAbortType = armGetAbtType();
    
    } else {
        ulAbortAddr = armGetPreAddr(ulRetAddr);
        ulAbortType = armGetPreType();
    }
    
    LW_TCB_GET_CUR(ptcbCur);

    API_VmmAbortIsr(ulRetAddr, ulAbortAddr, ulAbortType, ptcbCur);
}
Esempio n. 11
0
/*********************************************************************************************************
** 函数名称: archUndHandle
** 功能描述: archUndEntry 需要调用此函数处理未定义指令
** 输 入  : ulAddr           对应的地址
**           uiCpsr           产生异常时的 CPSR
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
VOID  archUndHandle (addr_t  ulAddr, UINT32  uiCpsr)
{
    PLW_CLASS_TCB   ptcbCur;
    
#if LW_CFG_GDB_EN > 0
    UINT    uiBpType = archDbgTrapType(ulAddr, (PVOID)uiCpsr);          /*  断点指令探测                */
    if (uiBpType) {                       
        if (API_DtraceBreakTrap(ulAddr, uiBpType) == ERROR_NONE) {      /*  进入调试接口断点处理        */
            return;
        }
    }
#endif                                                                  /*  LW_CFG_GDB_EN > 0           */
    
    LW_TCB_GET_CUR(ptcbCur);
    
#if LW_CFG_CPU_FPU_EN > 0
    if (archFpuUndHandle(ptcbCur) == ERROR_NONE) {                      /*  进行 FPU 指令探测           */
        return;
    }
#endif                                                                  /*  LW_CFG_CPU_FPU_EN > 0       */
    
    API_VmmAbortIsr(ulAddr, ulAddr, LW_VMM_ABORT_TYPE_UNDEF, ptcbCur);
}
Esempio n. 12
0
VOID  _ThreadFpuSwith (BOOL bIntSwitch)
{
    PLW_CLASS_TCB   ptcbCur;
    PLW_CLASS_TCB   ptcbHigh;
    
    LW_TCB_GET_CUR(ptcbCur);
    LW_TCB_GET_HIGH(ptcbHigh);
    
    if (LW_KERN_FPU_EN_GET()) {                                         /*  中断状态支持 FPU            */
        /*
         *  由于内核支持 FPU 所以, 中断函数会保存当前任务的 FPU 上下文
         *  所以如果是中断环境的调度函数, 则不需要保存当前任务 FPU 上下文
         */
        if (bIntSwitch == LW_FALSE) {
            if (ptcbCur->TCB_ulOption & LW_OPTION_THREAD_USED_FP) {
                __ARCH_FPU_SAVE(ptcbCur->TCB_pvStackFP);                /*  需要保存当前 FPU CTX        */
            }
        }
    } else {
        /*
         *  由于中断状态不支持 FPU 所以, 中断函数中不会对 FPU 上下文有任何操作
         *  这里不管是 _Sched() 还是 _SchedInt() 都需要保存当前任务的 FPU 上下文
         */
        if (ptcbCur->TCB_ulOption & LW_OPTION_THREAD_USED_FP) {
            __ARCH_FPU_SAVE(ptcbCur->TCB_pvStackFP);                    /*  需要保存当前 FPU CTX        */
        }
    }
        
        
    if (ptcbHigh->TCB_ulOption & LW_OPTION_THREAD_USED_FP) {
        __ARCH_FPU_RESTORE(ptcbHigh->TCB_pvStackFP);                    /*  需要恢复新任务 FPU CTX      */
        
    } else {
        __ARCH_FPU_DISABLE();                                           /*  新任务不需要 FPU 支持       */
    }
}
Esempio n. 13
0
/*********************************************************************************************************
** 函数名称: _ThreadStatusChange
** 功能描述: 改变线程状态 (进入内核状态被调用)
** 输 入  : ptcb          线程控制块
**           uiStatusReq   状态 (LW_TCB_REQ_SUSPEND / LW_TCB_REQ_WDEATH / LW_TCB_REQ_STOP)
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
** 注  意  : 此函数已经预置的阻塞点, 最后一次退出内核时, 将阻塞等待目标线程状态改变完毕.
*********************************************************************************************************/
ULONG  _ThreadStatusChange (PLW_CLASS_TCB  ptcb, UINT  uiStatusReq)
{
    INTREG         iregInterLevel;
    PLW_CLASS_PCB  ppcb;
    PLW_CLASS_TCB  ptcbCur;
    
    iregInterLevel = KN_INT_DISABLE();                                  /*  关闭中断                    */
    
    LW_TCB_GET_CUR(ptcbCur);
    
#if LW_CFG_SMP_EN > 0
    if (ptcb == ptcbCur) {                                              /*  改变自己的状态              */
        goto    __change1;
    
    } else if (!__LW_THREAD_IS_READY(ptcb)) {                           /*  任务没有就绪                */
        goto    __change2;
    
    } else {                                                            /*  目标任务处于就绪状态        */
        if (LW_CPU_GET_CUR_NESTING()) {
            KN_INT_ENABLE(iregInterLevel);                              /*  打开中断                    */
            return  (ERROR_KERNEL_IN_ISR);                              /*  中断状态下无法完成此工作    */
        }
        
        if (!__LW_THREAD_IS_RUNNING(ptcb)) {                            /*  目标任务不是正在执行        */
            ppcb = _GetPcb(ptcb);
            __DEL_FROM_READY_RING(ptcb, ppcb);                          /*  从就绪表中删除              */
            goto    __change2;
        
        } else {                                                        /*  目标任务正在执行            */
            _SmpUpdateIpi(LW_CPU_GET(ptcb->TCB_ulCPUId));               /*  发送核间中断通知改变状态    */
            _ThreadWaitStatus(ptcbCur, ptcb, uiStatusReq);              /*  设置等待对方完成状态        */
        }
        
        KN_INT_ENABLE(iregInterLevel);                                  /*  打开中断                    */
        return  (ERROR_NONE);                                           /*  退出内核时开始等待          */
    }
    
__change1:
#endif                                                                  /*  LW_CFG_SMP_EN               */
    
    if (__LW_THREAD_IS_READY(ptcb)) {
        ppcb = _GetPcb(ptcb);
        __DEL_FROM_READY_RING(ptcb, ppcb);                              /*  从就绪表中删除              */
    }
    
#if LW_CFG_SMP_EN > 0
__change2:
#endif                                                                  /*  LW_CFG_SMP_EN               */
    
    ptcbCur->TCB_uiStatusChangeReq = 0;                                 /*  状态修改操作执行成功        */
    
    switch (uiStatusReq) {
    
    case LW_TCB_REQ_SUSPEND:
        ptcb->TCB_ulSuspendNesting++;
        ptcb->TCB_usStatus |= LW_THREAD_STATUS_SUSPEND;
        break;
        
    case LW_TCB_REQ_STOP:
        ptcb->TCB_ulStopNesting++;
        ptcb->TCB_usStatus |= LW_THREAD_STATUS_STOP;
        break;
        
    case LW_TCB_REQ_WDEATH:
        ptcb->TCB_usStatus |= LW_THREAD_STATUS_WDEATH;
        break;
    }
        
    KN_INT_ENABLE(iregInterLevel);
    return  (ERROR_NONE);
}