📄 ixperfprofaccxscalepmu.c
字号:
/*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 + -