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

📄 ixperfprofaccxscalepmu.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 5 页
字号:
    /*move value to coprocessor 14 from interrupt enable register*/    mcr\tp14, 0, value, c4, c1, 0;}__asm volatile UINT32_ixPerfProfAccXscalePmuPmncRead(void){! "r0"    /*move to performance monitor control register from coprocessor 14 and store     *in value     */    mrc\tp14, 0, r0, c0, c1, 0;    and	r0, r0, #15;    /*mask return value to ensure only first 4 bits in                              *the register are set                              */    ;/* return value is returned through register R0 */}__asm volatile void_ixPerfProfAccXscalePmuPmncWrite(UINT32 value){% reg value    /*move value to coprocessor 14 from performance monitor control register*/    mcr\tp14, 0, value, c0, c1, 0;}__asm volatile void_ixPerfProfAccXscalePmuEvtSelectWrite(UINT32 value){% reg value    /*move to event select register from coprocessor 14 and store     *in value     */    mcr\tp14, 0, value, c8, c1, 0;}__asm volatile UINT32_ixPerfProfAccXscalePmuEvtSelectRead(void){! "r0"    /*move to event select register from coprocessor 14 and store     *in value     */    mov	r0, #0;    mrc\tp14, 0, r0, c8, c1, 0;    ;/* return value is returned through register R0 */}__asm volatile UINT32_ixPerfProfAccXscalePmuPmnCnt1Read_(void){! "r0"    mrc\tp14, 0, r0, c0, c2, 0;    ;/* return value is returned through register R0 */}__asm volatile UINT32_ixPerfProfAccXscalePmuPmnCnt2Read_(void){! "r0"    mrc\tp14, 0, r0, c1, c2, 0;    ;/* return value is returned through register R0 */}__asm volatile UINT32_ixPerfProfAccXscalePmuPmnCnt3Read_(void){! "r0"    mrc\tp14, 0, r0, c2, c2, 0;    ;/* return value is returned through register R0 */}__asm volatile UINT32_ixPerfProfAccXscalePmuPmnCnt4Read_(void){! "r0"    mrc\tp14, 0, r0, c3, c2, 0;    ;/* return value is returned through register R0 */}INLINE UINT32_ixPerfProfAccXscalePmuPmnRead(UINT32 num, BOOL *check){    register UINT32 _value_ = 0;    if (IX_PERFPROF_ACC_XSCALE_PMU_MAX_EVENTS < num) /*num passed in exceeds                                                      *maximum counters allowed                                                      */    {        *check = FALSE;    }    switch (num)/*move value to coprocessor 14 from event counter registers*/    {        case 0: /*read value of event counter 1 only*/            return _ixPerfProfAccXscalePmuPmnCnt1Read_();            break;        case 1: /*read value of event counter 2 only*/            return _ixPerfProfAccXscalePmuPmnCnt2Read_();            break;        case 2: /*read value of event counter 3 only*/            return _ixPerfProfAccXscalePmuPmnCnt3Read_();            break;        case 3: /*read value of event counter 4 only*/            return _ixPerfProfAccXscalePmuPmnCnt4Read_();            break;        default:            break;    }    return _value_;}__asm volatile void_ixPerfProfAccXscalePmuPmnCnt1Write(UINT32 value){%reg value    mcr\tp14, 0, value, c0, c2, 0;}__asm volatile void_ixPerfProfAccXscalePmuPmnCnt2Write(UINT32 value){%reg value    mcr\tp14, 0, value, c1, c2, 0;}__asm volatile void_ixPerfProfAccXscalePmuPmnCnt3Write(UINT32 value){%reg value    mcr\tp14, 0, value, c2, c2, 0;}__asm volatile void_ixPerfProfAccXscalePmuPmnCnt4Write(UINT32 value){%reg value    mcr\tp14, 0, value, c3, c2, 0;}INLINE void_ixPerfProfAccXscalePmuPmnWrite(UINT32 num, UINT32 value, BOOL *check){    /*set value of *check to FALSE if num passed in is greater than maximum     *counters allowed     */    if(IX_PERFPROF_ACC_XSCALE_PMU_MAX_EVENTS<num)    {        *check = FALSE;    } /*end of if IX_PERFPROF_ACC_XSCALE_PMU_MAX_EVENTS*/    switch (num)/*move to event counter registers from coprocessor 14 and store                 *in value                 */    {        case 0:   /*write value to event counter 1 only*/            _ixPerfProfAccXscalePmuPmnCnt1Write(value);            break;        case 1:   /*write value to event counter 2 only*/            _ixPerfProfAccXscalePmuPmnCnt2Write(value);            break;        case 2:   /*write value to event counter 3 only*/            _ixPerfProfAccXscalePmuPmnCnt3Write(value);            break;        case 3:   /*write value to event counter 4 only*/            _ixPerfProfAccXscalePmuPmnCnt4Write(value);            break;        default:            break;    } /*end of switch (num )*/} /*end of _ixPerfProfAccXscalePmuPmnWrite()*/#endif /* ifndef _DIAB_TOOL */INLINE void_ixPerfProfAccXscalePmuProfilePcStore (    UINT32 eventCounterId,    UINT32 idx,    UINT32 pc){    switch (eventCounterId)    {        case IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR1_ID :            evtCtr1Array[idx] = pc ;            break;        case IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR2_ID :            evtCtr2Array[idx] = pc ;            break;        case IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR3_ID :            evtCtr3Array[idx] = pc ;            break;        case IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR4_ID :            evtCtr4Array[idx] = pc ;            break;        default:            break;    } /*end of switch*/}VXWORKS_INLINE void_ixPerfProfAccXscalePmuEventHandler (    UINT32 eventOflowSelect,    UINT32 eventCounterId,    UINT32 pcAddr){    BOOL checkNum = TRUE;       /*determines if num passed into                                 *_ixPerfProfAccXscalePmuPmnWrite() is valid                                 */    if (eventCounting)  /*event counting only is on*/    {        IxPerfProfAccXscalePmuIntrStatus[eventCounterId] = TRUE; /*set to show                                                                  *ctr overflowed                                                                  */        ctrSamples[eventCounterId]++;    /*keep track                                          *of overflows                                          */        /*clear the clk cnt bit in the overflow flag reg*/        _ixPerfProfAccXscalePmuOverFlowWrite(            eventCounterId);    }    else if (eventSampStarted)/*is not event counting; only event-based sampling*/    {        if (IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES >                ctrSamples[eventCounterId])             /*profile buffer not                                                         *full yet                                                         */        {            /* store PC and increment index */            _ixPerfProfAccXscalePmuProfilePcStore (eventCounterId,                                                   ctrSamples[eventCounterId],                                                   pcAddr );            ctrSamples[eventCounterId]++;            /*clear the event counter bit in the overflow flag reg*/            _ixPerfProfAccXscalePmuOverFlowWrite(eventCounterId);            /*rewrite base value to evt counter 2 reg*/            _ixPerfProfAccXscalePmuPmnWrite(eventCounterId,                                            ctrBase[eventCounterId],                                            &checkNum);        }        else    /*profile buffer is full*/        {            /*check if buffer full had been handled; if it is, we ignore this             *interrupt. Otherwise, disable source of interrupt.             */            if (!IxPerfProfAccXscalePmuIntrStatus[eventCounterId])            {                /* Disable interrupt, by disabling the appropriate bit in the                 * current value of the interrupt enable register                 */                _ixPerfProfAccXscalePmuIntenWrite(                    _ixPerfProfAccXscalePmuIntenRead() &                    ~(eventCounterId));                /* Remember that we have reached MAX storage */                IxPerfProfAccXscalePmuIntrStatus[eventCounterId] = TRUE;                _ixPerfProfAccXscalePmuEvtSelectWrite(                    (_ixPerfProfAccXscalePmuEvtSelectRead()) |                    (IX_PERFPROF_ACC_XSCALE_PMU_EVT_SELECT_NONE <<                     (eventCounterId <<                     IX_PERFPROF_ACC_XSCALE_PMU_SHIFT_TO_MULT_8)));             }/*end of if !IxPerfProfAccXscalePmuIntrStatus */        }/*end of if-else*/    }/*end of if-else eventCounting*/} /* end of _ixPerfProfAccXscalePmuEventHandler() */voidixPerfProfAccXscalePmuIntrHandler (void){    UINT32 overflow;    /*variable to determine if overflow bit is set */    UINT32 pcAddr;     /*variable to store address of pc*/#ifdef __vxworks    /**     * PMU event is presented as IRQ to XScale in VxWorks. VxWorks saves minimal     * registers including R14 before switching to the interrupt routine.     * Therefore, the interrupted PC is available at the base of the IRQ     * interrupt stack.     */    pcAddr = (*vxIrqIntStackBase)[-1];#elif defined(__linux)    /**     * For Linux, we need Osal to pass the interrupted PC     * because Osal does not pass the frame pointers to our     * ISR. ixOsalLinuxInterruptedPc is a global variables defined     * in IxOsal.c     */    pcAddr = ixOsalLinuxInterruptedPc;#endif /*end of if vxWorks*/    overflow =_ixPerfProfAccXscalePmuOverFlowRead();    /*read the overflow flag                                                         *status register to                                                         *determine which counter                                                         *has overflowed                                                         */    /* overflow occured in clock counter; for clock counting, only occurs when     * counter is full     */    if (overflow & IX_PERFPROF_ACC_XSCALE_PMU_OFLOW_FLAG_CCNT)    {        if (eventCounting)  /*events counting only on*/        {            IxPerfProfAccXscalePmuIntrStatus[                IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID] = TRUE; /*set to show clk                                                                *ctr overflowed                                                                */            ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID]++; /*keep track of                                                                  *number of                                                                  *overflows for                                                                  *clk ctr                                                                  */            /*clear the clk cnt bit in the overflow flag reg*/            _ixPerfProfAccXscalePmuOverFlowWrite(                IX_PERFPROF_ACC_XSCALE_PMU_OFLOW_FLAG_CCNT);        }        else if (timeSampStarted)       /*is not event counting; only time-based                                         *sampling                                         */        {            if (IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES >                ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID]) /*profile                                                                    *buffer not                                                                    *full yet                                                                    */            {                /*store add of PC to results profile*/                clkCtrArray[ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID]] =                    pcAddr;                ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID]++;                /*clear the clk cnt bit in the overflow flag reg*/                _ixPerfProfAccXscalePmuOverFlowWrite(                    IX_PERFPROF_ACC_XSCALE_PMU_OFLOW_FLAG_CCNT);                /*rewrite base value to clk cnt reg*/                _ixPerfProfAccXscalePmuCcntWrite(                    ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID]);            }            else    /*profile buffer is full*/            {                /*check if this buffer is full; if is full, the interrupt is                 *being triggered by another counter overflow                 */                if (!IxPerfProfAccXscalePmuIntrStatus[                    IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID])                {                    /* Disable clock counter interrupt, by disabling the appropriate                     * bit in the current value of the interrupt enable register                     */                    _ixPerfProfAccXscalePmuIntenWrite(                        _ixPerfProfAccXscalePmuIntenRead() &                        ~(IX_PERFPROF_ACC_XSCALE_PMU_OFLOW_FLAG_CCNT));                    /*set to show that buffer is full*/                    IxPerfProfAccXscalePmuIntrStatus[                        IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID] = TRUE;

⌨️ 快捷键说明

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