⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpmain.c

📁 摩托罗拉Motolola公司网络处理器C3的示范代码.实现了ATM的AAL2层交换功能.想了解网络处理器的可以
💻 C
📖 第 1 页 / 共 2 页
字号:
    TimeoutDesc*    timeoutDesc;    XpInQueueDesc*  xpInQueueDesc;    CellDescriptor* controlDesc;    Aal2CpsDesc*    aal2ControlDesc;    TimerStartData* data;    int32u          scoreBoard;    int16u          timerFired;    int16u          timerIndex;    Boolean         somethingToBeRead = FALSE;    Boolean         atLeastOneTimerFired = FALSE;    register int32u timer = NUMBER_OF_TIMERS;    register int8u* pTimeout8 = &timeout[NUMBER_OF_TIMERS-1];    int32           head = -1;    int32           tail = -1;    int32u          error = 0;    int32u          all = 0;    Boolean         allFlag = 1;    KsEventId       event;	ksEventRegisterInterrupt(ksEventIdQmuError,                              (KsFunc)&xpQmuIrqHandler,			                 (void *)0);    /*     * Initialise the Queue related Descriptors     */    timeoutDesc   = (TimeoutDesc *) qsMessageGetData (&timeoutMsg);    xpInQueueDesc = (XpInQueueDesc *) qsMessageGetData (&incomingMsg);    controlDesc   = (CellDescriptor *) qsMessageGetData (&controlMsg);    aal2ControlDesc = (Aal2CpsDesc *) qsMessageGetData (&aal2ControlMsg);    scoreBoard = XP_SONET_SOAK_TIME -        (CU_TIMER_GRANULARITY * SYS_TIMER_TICKS_PER_MILLISEC);        while (TRUE)    {#if !defined(SIM)        ksPrintService ();#endif        /*         * SONET timer tick event         * ----------------------------------------------------------         */        if (BitIsSet(dcpCregs.eventRegister[0], EV0_TIMER_EVENT))        {            scoreBoard = XP_SONET_SOAK_TIME;            error = 0;            all = 0;            allFlag = 1;            /*             * Check and see if any defects have reached their             * soak threshold             */            sonetMonitorSoakIncrement();            /*             * If 500ms timer has expired             */            if ((event = ksEventNext()) == ksEventIdTimer) {               /*                * Reset soak timeout                */                ksTimerSet(XP_SONET_SOAK_TIME);            }        }        /*         * CU timer tick event         * ----------------------------------------------------------         */        if (dcpCregs.eventTimer <= scoreBoard) {            /* CU timer tick. Schedule next tick and             * update the CU timer related counters.             */            scoreBoard -= (CU_TIMER_GRANULARITY * SYS_TIMER_TICKS_PER_MILLISEC);            if (timer) {                error++;            }            timer = NUMBER_OF_TIMERS;            pTimeout8 = &timeout[NUMBER_OF_TIMERS-1];            allFlag = 1;        }        /*         * Dequeue the timer start command descriptors from AAL2 Tx         * CPs         */        if (somethingToBeRead)        {            while(!qsMessageReceiveComplete(XP_BASE_QUEUE, &incomingMsg));            switch (xpInQueueDesc->command)            {                case TIMER_START_COMMAND:                {                    data = (TimerStartData *)                         &(xpInQueueDesc->data.timerStartCommand);                    timerIndex = data->vcIndex;                    timeout[timerIndex] = (data->cpId << 4) | CU_TIMER_TICKS;                    next[timerIndex] = SetBitFieldIn(next[timerIndex],                                           data->seqNo, SEQ_NUM);                    break;                }                default:                    break;            }            somethingToBeRead = FALSE;        }        else if (qsQueueGetLength(XP_BASE_QUEUE))        {            qsMessageReceiveStart(XP_BASE_QUEUE, &incomingMsg);            somethingToBeRead = TRUE;        }        /* Attempt an enqueue only if previous enqueue is completed.         * Poll for the Q Write Mailbox for availability.         */        if (atLeastOneTimerFired &&            BitIsSet(dcpCregs.eventRegister[1], EV1_QWR_MBX_AVAIL))        {            /* If there is at least one element in the list of fired             * timers, enqueue a Timeout message to the CPRC.             */            timerFired = head;                                head = ((head ^ tail) ?                    (BitField(next[head],NEXT_POINTER)) :                    (tail = -1));            if (head < 0)                atLeastOneTimerFired = FALSE;            if (!(timeout[timerFired] & 0x0F))    /* Timeout still valid */            {                timeoutDesc->seqNo   = BitField(next[timerFired], SEQ_NUM);                timeoutDesc->vcIndex = timerFired ;                payloadEnqueue = FALSE;                qsMessageSend (nqQId[timeout[timerFired] >> 4], &timeoutMsg);            }        }        /*         * Timer update         */        if (timer)        {            if (allFlag)            {                all++;                allFlag = 0;            }            do            {                int8u timeVal = *pTimeout8 & 0x0F;                if (timeVal)                            {                    if (!(--timeVal))                    {                        /* A timer has fired. append it to the list                         * of fired timers.                         */                        if (tail < 0)                        {                            /* This is the first element being added                             * to the empty list.                             */                            head = tail = timer-1;                            atLeastOneTimerFired = TRUE;                        }                        else                        {                            int16u* pNext16;                            pNext16 = &next[tail];                            /* Add this element at the tail of the                             * queue of timers that are timed out                             */                            *pNext16 = SetBitFieldIn(*pNext16,                                             timer - 1, NEXT_POINTER);                            tail = timer-1;                        }                    }                    (*pTimeout8)--;                }                pTimeout8--;            } while (--timer & 0x0007);        }        /*         * Sonet monitoring         */        if (qsQueueGetLength(XP_SONET_MONITOR_QUEUE))        {            /*             * Jump to SONET monitoring function to monitor any SONET             * faults and defects.             */            sonetMonitorXpQueue();        }        /*         * Control messages         */        if (qsQueueGetLength(XP_ATM_CONTROL_QUEUE))         {            qsMessageReceive(XP_ATM_CONTROL_QUEUE, &controlMsg);#ifdef XP_TEST            ++cellNum;            ksPrintf ("Aal2 Xp : Control Cell : VcIndex %d : PTI : %d",                       controlDesc->VcIndex,controlDesc->payloadType) ;#endif            /*             *  For now, send the cells out of ATM TX CP 1              *  to allow verification             */            lastBufferEnqueued = controlDesc->Bh;            payloadEnqueue = TRUE;            qsMessageSend(ATM_PORT2_BASE_QUEUE, &controlMsg);         }        /*         * Aal2 Control messages (CIDS from 1 to 7)         */        if (qsQueueGetLength(XP_RES_CID_QUEUE))        {            qsMessageReceive(XP_RES_CID_QUEUE, &aal2ControlMsg);#ifdef XP_TEST            ++cpsNum;            ksPrintf ("Xp aal2 %d, cid : %d",cpsNum, aal2ControlDesc->cid);#endif            /*             *  For now, send the cells out through AAL2 Tx CP 10              *  to allow verification             */             lastBufferEnqueued = aal2ControlDesc->cpsPckPayload;            payloadEnqueue = TRUE;            qsMessageSend(AAL2_TX1_BASE_QUEUE, &aal2ControlMsg);         }         }}/* *  Function:      xpQmuIrqHandler() * *  Description:   This function is interrupt handler for QMU errors.  *                 It is typically *                 called under normal congestion conditions  *                 when an enqueue fails *                 to succeed due to the target queue being full.  *                 When this occurs *                 this irq handler must free the buffer  *                 associated with the last *                 enqueue. * *  Arguments:     An eventInfo block passed in by kernel services. * *  Returns: */int32u xpQmuIrqHandler(void *irqInfo){    KsEventInfo *eventInfo = (KsEventInfo *)irqInfo;    if(eventInfo->eventId == ksEventIdQmuError) {        dcpTrace1(("Queue irq, queue %d", eventInfo->address));        /* Only free the buffer associated with the last enqueue          * if the failed enqueue         * was a unicast operation with payload information. */            if(payloadEnqueue == TRUE ) {                /* Save any context before doing an operation. */                ksEventContextSave();                /* Free the buffer associated with the last enqueue. */                bsBufferFree(lastBufferEnqueued);                /* Wait until operation is done and then restore any context. */                while(!bsBufferWriteComplete());                ksEventContextRestore();                payloadEnqueue = FALSE;            }    }    return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -