📄 ixperfprofaccxscalepmu.c
字号:
(IxPerfProfAccXscalePmuIntrStatus[i] == TRUE))|| (!eventCounting)) { switch (i) { case 0: eventCount[i].upper32BitsEventCount = ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR1_ID]; break; case 1: eventCount[i].upper32BitsEventCount = ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR2_ID]; break; case 2: eventCount[i].upper32BitsEventCount = ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR3_ID]; break; case 3: eventCount[i].upper32BitsEventCount = ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR4_ID]; break; default: break; } /*end of switch*/ }/*end of if eventCounting*/ /*always store end event count in lower 32 bits counter*/ eventCount[i].lower32BitsEventCount = currentCnt[i] - ctrBase[i]; }/*end of for numberEvents*/ return status;}/*end of ixPerfProfAccXscalePmuEvtCntGet()*/voidixPerfProfAccXscalePmuProfileConstruct ( UINT32 pcAddr, IxPerfProfAccXscalePmuSamplePcProfile *profile){ UINT32 i; for(i=0; IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES > i; i++) { if (profile[i].programCounter == pcAddr) /*this PC already captured*/ { profile[i].freq++; /*add to the frequency*/ break; /*break out of loop because this entry has been captured*/ } else if (profile[i].programCounter== 0) /*this PC is captured for *the first time */ { profile[i].programCounter = pcAddr; profile[i].freq = 1; sumLen++; /*number of different pc adds captured*/ break; /*break out of loop because entry has been captured*/ }/*end of if-else profile[i]*/ }/*end of for IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES>i*/}/*end of ixPerfProfAccXscalePmuProfileConstruct()*/voidixPerfProfAccXscalePmuProfileSort (IxPerfProfAccXscalePmuSamplePcProfile *profileArray, UINT32 total){ UINT32 i; /* Counter to go through values in the array */ UINT32 j; /* Counter to compare with other value in array */ UINT32 profileMax; /* Higest value in array */ UINT32 indexTempMax;/* Index of array component that contains maximum value */ UINT32 pc; /* Program counter value */ for (i = 0 ; i < total; i++) { indexTempMax=i; /* Look for any value higher than the current value and store it in its location */ profileMax = profileArray[i].freq; for (j =i ; j < total; j++) { if (profileMax < profileArray[j].freq) { indexTempMax=j; profileMax = profileArray[j].freq; } /* end if */ } /* end for */ /* swap freq */ profileArray[indexTempMax].freq=profileArray[i].freq; profileArray[i].freq = profileMax; /* swap pc */ pc = profileArray[indexTempMax].programCounter; profileArray[indexTempMax].programCounter = profileArray[i].programCounter; profileArray[i].programCounter= pc; } /* end for */} /* end ixPerfProfAccXscalePmuProfileSort */PUBLIC IxPerfProfAccStatusixPerfProfAccXscalePmuEventCountStart( BOOL clkCntDiv, UINT32 numEvents, IxPerfProfAccXscalePmuEvent pmuEvent1, IxPerfProfAccXscalePmuEvent pmuEvent2, IxPerfProfAccXscalePmuEvent pmuEvent3, IxPerfProfAccXscalePmuEvent pmuEvent4 ){ UINT32 i; IxPerfProfAccStatus status = IX_PERFPROF_ACC_STATUS_SUCCESS; IxFeatureCtrlDeviceId deviceType = IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X; numberEvents = numEvents; deviceType = ixFeatureCtrlDeviceRead (); if(IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X == deviceType) { IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixPerfProfAcc - This PPU component is not supported\n", 0, 0, 0, 0, 0, 0); return IX_PERFPROF_ACC_STATUS_COMPONENT_NOT_SUPPORTED; } /* initialize global variables*/ ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR1_ID] = 0; ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR2_ID] = 0; ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR3_ID] = 0; ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR4_ID] = 0; ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID] = 0; ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR1_ID] = 0; ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR2_ID] = 0; ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR3_ID] = 0; ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR4_ID] = 0; ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID] = 0; eventCounting = TRUE; /*indicates that event counting is on*/ /*check if any other util is currently running*/ status = ixPerfProfAccLock(); if (IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS == status) { IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "Another utility is running\n", 0,0, 0, 0, 0, 0); return status; } /*check validity of input parameters*/ if (IX_PERFPROF_ACC_XSCALE_PMU_MAX_EVENTS < numEvents ) { IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "numEvents cannot be greater than 4\n", 0,0, 0, 0, 0, 0); ixPerfProfAccUnlock(); /*call unlock; process has been terminated*/ return IX_PERFPROF_ACC_STATUS_XSCALE_PMU_NUM_INVALID; } /*end of if IX_PERFPROF_ACC_XSCALE_PMU_MAX_EVENTS*/ if((IX_PERFPROF_ACC_XSCALE_PMU_EVENT_MAX < pmuEvent1) || (IX_PERFPROF_ACC_XSCALE_PMU_EVENT_MAX < pmuEvent2) || (IX_PERFPROF_ACC_XSCALE_PMU_EVENT_MAX < pmuEvent3) || (IX_PERFPROF_ACC_XSCALE_PMU_EVENT_MAX < pmuEvent4)) { IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "value of event type entered is out of bounds\n", 0,0, 0, 0, 0, 0); ixPerfProfAccUnlock(); /*call unlock; process has been terminated*/ return IX_PERFPROF_ACC_STATUS_XSCALE_PMU_EVENT_INVALID; }/*end of if IX_PERFPROF_ACC_XSCALE_PMU_EVENT_MAX*/ if (numEvents) /*events counting*/ { /* initialize interrupt status array */ for (i=0;i<IX_PERFPROF_ACC_XSCALE_PMU_MAX_COUNTERS;i++) { IxPerfProfAccXscalePmuIntrStatus[i] = FALSE; }/* end of for loop */ } else /*clock counting only*/ { IxPerfProfAccXscalePmuIntrStatus[ IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID] = FALSE; }/*end of if-else numEvents*/ /* bind interrupt to handler*/ ixPerfProfAccXscalePmuIntrConnect(); /*assign the appropriate events to each event counter*/ if (numEvents) { ixPerfProfAccXscalePmuEventSelect ( pmuEvent1, pmuEvent2, pmuEvent3, pmuEvent4); } else /*if no event counting, write default value to all event counters to *save power */ { _ixPerfProfAccXscalePmuEvtSelectWrite( IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR); }/*end of if-else numEvents*/ /* Clear all bits in overflow flag register*/ _ixPerfProfAccXscalePmuOverFlowWrite( IX_PERFPROF_ACC_XSCALE_PMU_OFLOW_FLAG_ALL); /*write the pmu interrupt enable register*/ ixPerfProfAccXscalePmuIntrEnable(TRUE); /*clk ctr is on*/ /*Configure Performance Monitor Control Register - enable all counters, *reset event counters, reset clock counter, enable clock divider if *appropriate */ ixPerfProfAccXscalePmuCtrEnableReset (clkCntDiv, TRUE, TRUE, TRUE); /*enable BSP interrupts*/ ixPerfProfAccXscalePmuBspIntrEnable(); /* initialize evt counters only if event counting on*/ if (numEvents) { status = ixPerfProfAccXscalePmuEvtCtrInit(); if (status == IX_PERFPROF_ACC_STATUS_FAIL) { /*error due to num events out of bounds*/ IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "Warning: error initializing event counter\n", 0,0, 0, 0, 0, 0); ixPerfProfAccUnlock(); /*call unlock; process has been terminated*/ } /*end of if status*/ }/*end of if numEvents*/ /*set clock counter to zero*/ _ixPerfProfAccXscalePmuCcntWrite( ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID]); eventCountStarted = TRUE; /*set to show that this process has been started*/ return status;}/*end of ixPerfProfAccXscalePmuEventCountStart()*/PUBLIC IxPerfProfAccStatusixPerfProfAccXscalePmuEventCountStop ( IxPerfProfAccXscalePmuResults *eventCountStopResults){ UINT32 i; IxPerfProfAccXscalePmuEvtCnt evtCnt[IX_PERFPROF_ACC_XSCALE_PMU_MAX_EVENTS]; /*check whether ixPerfProfAccXscalePmuEventCountStart() has been called*/ if (!eventCountStarted) { return IX_PERFPROF_ACC_STATUS_XSCALE_PMU_START_NOT_CALLED; } /*error check the parameter*/ if (NULL == eventCountStopResults) { /* report the error */ IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixPerfProfAccXscalePmuEventCountStop - eventCountStopResults is invalid\n", 0, 0, 0, 0, 0, 0); /* return error */ return IX_PERFPROF_ACC_STATUS_FAIL; } /*initialize counter results array*/ for(i=0; i<IX_PERFPROF_ACC_XSCALE_PMU_MAX_EVENTS; i++) { evtCnt[i].lower32BitsEventCount = 0; evtCnt[i].upper32BitsEventCount = 0; } /*end of for loop*/ /*disable all interrupts to stop counting*/ ixPerfProfAccXscalePmuIntrDisable(); /*get the final clock and event counts*/ ixPerfProfAccXscalePmuResultsGet(eventCountStopResults); eventCounting = FALSE; /*event counting has ended*/ eventCountStarted = FALSE; /*reset flag as event counting has ended*/ /*call unlock because process has ended*/ ixPerfProfAccUnlock(); return IX_PERFPROF_ACC_STATUS_SUCCESS; }/*end of ixPerfProfAccXscalePmuEventCountStop()*/PUBLIC IxPerfProfAccStatusixPerfProfAccXscalePmuTimeSampStart( UINT32 samplingRate, BOOL clkCntDiv){ IxPerfProfAccStatus status = IX_PERFPROF_ACC_STATUS_SUCCESS; IxFeatureCtrlDeviceId deviceType = IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X; deviceType = ixFeatureCtrlDeviceRead (); if(IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X == deviceType) { IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixPerfProfAcc - This PPU component is not supported\n", 0, 0, 0, 0, 0, 0); return IX_PERFPROF_ACC_STATUS_COMPONENT_NOT_SUPPORTED; } /*check if any other util is currently running*/ status = ixPerfProfAccLock(); if (IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS == status) { IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "Another utility is running\n", 0,0, 0, 0, 0, 0); return status; } /*check validity of parameters*/ if ((0 == samplingRate) || (IX_PERFPROF_ACC_XSCALE_PMU_MAX_COUNTER_VALUE < samplingRate)) { IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "samplingRate can't be zero or greater than counter size\n", 0,0, 0, 0, 0, 0); ixPerfProfAccUnlock(); /*call unlock; process has been terminated*/ return IX_PERFPROF_ACC_STATUS_FAIL; } /*end of if samplingRate*/ if ((FALSE != clkCntDiv) && (TRUE!= clkCntDiv)) { IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "enter TRUE or FALSE for clkCntDiv\n", 0,0, 0, 0, 0, 0); ixPerfProfAccUnlock(); /*call unlock; process has been terminated*/ return IX_PERFPROF_ACC_STATUS_FAIL; } /*end of if clkCntDiv*/ /*initialize globals*/ ctrSamples[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID] = 0; ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID] = IX_PERFPROF_ACC_XSCALE_PMU_MAX_COUNTER_VALUE - samplingRate; ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR1_ID] = 0; ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR2_ID] = 0; ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR3_ID] = 0; ctrBase[IX_PERFPROF_ACC_XSCALE_PMU_EVT_CTR4_ID] = 0; eventCounting = FALSE; numberEvents=0; /*initialize interrupt status for clock counter only*/ IxPerfProfAccXscalePmuIntrStatus[IX_PERFPROF_ACC_XSCALE_PMU_CLK_CTR_ID] = FALSE; /*bind interrupt to handler*/ ixPerfProfAccXscalePmuIntrConnect(); /* Clear clk ctr bits in overflow flag register*/ _ixPerfProfAccXscalePmuOverFlowWrite( IX_PERFPROF_ACC_XSCALE_PMU_OFLOW_FLAG_CCNT); /*write to pmu interrupt enable register-clk counting only, and clk ctr on*/ ixPerfProfAccXscalePmuIntrEnable(TRUE); /*Configure Performance Monitor Control Register - enable all counters, * reset clock counter, enable clock divider if appropriate */ ixPerfProfAccXscalePmuCtrEnableReset (clkCntDiv, TRUE, TRUE, FALSE); /*enable BSP interrupt*/ ixPerfProfAccXscalePmuBspIntrEnable(); /*initialize clk ctr to base value*/ _ixPerfProfAccXscalePmuCcntWrite(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -