📄 gv3lib.c
字号:
pentiumMsrSet (IA32_THERM_CONTROL, (LL_INT *)&value); return (OK); }/********************************************************************************* gv3DutyCycleCheck - check if the CPU on-demand throttling is enabled** This routine checks if the CPU on-demand throttling is enabled.** RETURNS: TRUE if the on-demand throttling is enabled, FALSE otherwise.*/BOOL gv3DutyCycleCheck (void) { INT32 value[2]; /* toggle the On-Demand Thermal Control Circuit Enable bit */ pentiumMsrGet (IA32_THERM_CONTROL, (LL_INT *)&value); if (value[0] & THERM_TCC_EN) return (TRUE); else return (FALSE); }/********************************************************************************* gv3AcCheck - check the AC powered or Battery powered** This routine checks the AC powered or Battery powered.** RETURNS: TRUE if it is AC powered (default), FALSE otherwise.*/BOOL gv3AcCheck (void) { BOOL ac = TRUE; /* default */ /* get the power-source AC(default) or Battery */ if (gv3AcCheckRtn != (FUNCPTR) NULL) ac = (* gv3AcCheckRtn) (); return (ac); }/********************************************************************************* gv3WdogRtn - watch dog routine for the performance state transition** This routine is the watch dog routine for the performance state transition.* It is executed in the interrupt level. The transition policy implemented * in this routine is suggested by Intel and is fast-up slow-down approach.* - if CPU utilization is above X <gv3UpUtil> % of state S for * N <gv3UpTime> millisecond, transition CPU to state S+1.* - if CPU utilization is below Y <gv3DownUtil> % of state S for * M <gv3DownTime> millisecond, transition CPU to state S-1.* - sampling interval depends on the previous transition. If the* previous transition was to a higher state, N millisecond is used.** RETURNS: N/A*/LOCAL VOID gv3WdogRtn ( UINT32 prevDelay /* previous sampling interval in system tick */ ) { UINT32 util = vxIdleUtilGet (); /* get CPU utilization */ UINT32 delay = prevDelay; /* get previous sampling interval */ INT32 thermStatus[2]; /* value of IA32_THERM_STATUS */ INT32 value[2]; /* value of other MSRs */ FREQ_VID_STATE * pState; /* FREQ_VID_STATE pointer */ UINT16 busRatio; /* bus ratio */ INT8 dutyCycle; /* duty cycle */ INT32 ix; /* check if the On-Demand/Automatic TCC has been activated */ pentiumMsrGet (IA32_THERM_STATUS, (LL_INT *)&thermStatus); if ((thermStatus[0] & THERM_HOT_LOG) && ((thermStatus[0] & THERM_HOT_NOW) == 0)) { /* reset the Thermal Status Log sticky bit */ thermStatus[0] &= ~THERM_HOT_LOG; pentiumMsrSet (IA32_THERM_STATUS, (LL_INT *)&thermStatus); /* get the state lowered by the On-Demand/Automatic TCC */ if (gv3LibState & GV3_OK_TM2) { pentiumMsrGet (MSR_PERF_STS, (LL_INT *)&value); busRatio = (value[0] & BUS_RATIO_STS) >> 8; for (ix = 0; ix < gv3Header->nState; ix++) { pState = gv3Header->pState + ix; if (busRatio == pState->ratio) { gv3State = pState; /* update */ break; } } } else if (gv3LibState & GV3_OK_TM1) { pentiumMsrGet (IA32_THERM_CONTROL, (LL_INT *)&value); dutyCycle = value[0] & THERM_DUTY_CYCLE; for (ix = 0; ix < NELEMENTS (gv3DutyCycle); ix++) { if (dutyCycle == gv3DutyCycle[ix]) { gv3DutyCycleIx = ix; /* update */ break; } } } } /* perform the transition if it is necessary */ if (util > gv3UpUtil) { /* * if CPU utilization is above X <gv3UpUtil> % of state S for * N <gv3UpTime> millisecond, and the CPU is not HOT, * transition CPU to state S+1. */ if (gv3PrevUtil > gv3UpUtil) gv3TotalTick += prevDelay; /* accumulate */ else gv3TotalTick = prevDelay; /* reset */ if ((gv3TotalTick > gv3UpTick) && ((thermStatus[0] & THERM_HOT_NOW) == 0)) { /* transition CPU to the next state above */ if (gv3LibState & GV3_OK_TM2) gv3StateSet (gv3State->no - 1); else if (gv3LibState & GV3_OK_TM1) gv3DutyCycleSet (gv3DutyCycleIx + 1); else ; gv3TotalTick = 0; /* reset */ delay = gv3UpTick; /* update the sampling interval */ } } else if (util < gv3DownUtil) { /* * if CPU utilization is below Y <gv3DownUtil> % of state S for * M <gv3DownTime> millisecond, transition CPU to state S-1. */ if (gv3PrevUtil < gv3DownUtil) gv3TotalTick += prevDelay; /* accumulate */ else gv3TotalTick = prevDelay; /* reset */ if (gv3TotalTick > gv3DownTick) { /* transition CPU to the next state below */ if (gv3LibState & GV3_OK_TM2) gv3StateSet (gv3State->no + 1); else if (gv3LibState & GV3_OK_TM1) gv3DutyCycleSet (gv3DutyCycleIx - 1); else ; gv3TotalTick = 0; /* reset */ delay = gv3DownTick; /* update the sampling interval */ } } else { /* * utilization did not stay above gv3UpUtil or below gv3DownUtil. * reset the totalTick, and use the previous sampling interval. */ gv3TotalTick = 0; /* reset */ } /* remember the previous utilization */ gv3PrevUtil = util; /* restart the watch dog routine */ wdStart (gv3WdogId, delay, (FUNCPTR)gv3WdogRtn, delay); }/********************************************************************************* gv3AutoEnable - enable the automatic performance state transition** This routine enables the automatic performance state transition.* This routine creates/starts/stops the watch dog routine that runs at * the sampling interval.** RETURNS: OK if succeeded, ERROR otherwise.*/STATUS gv3AutoEnable ( BOOL enable /* TRUE to enable, or FALSE to disable */ ) { STATUS status; if (gv3LibState & GV3_ERR_NO_TM) return (ERROR); if (enable) { if (gv3WdogId == NULL) { if ((gv3WdogId = wdCreate ()) == NULL) return (ERROR); /* convert milliseconds to system ticks */ gv3UpTick = (gv3UpTime * sysClkRateGet ()) / 1000; gv3DownTick = (gv3DownTime * sysClkRateGet ()) / 1000; } /* let's use the up (gv3UpTick) sampling interval */ status = wdStart (gv3WdogId, gv3UpTick, (FUNCPTR)gv3WdogRtn, gv3UpTick); } else { if (gv3WdogId == NULL) return (ERROR); status = wdCancel (gv3WdogId); /* reset the previous value */ gv3PrevUtil = 0; /* previous utilization(%) */ gv3TotalTick = 0; /* total time spent in the util */ } return (status); }/********************************************************************************* gv3AutoSet - set the automatic performance state transition parameters** This routine sets the automatic performance state transition parameters.** RETURNS: OK always*/STATUS gv3AutoSet ( UINT32 upUtil, /* utilization(%) to go next state up */ UINT32 downUtil, /* utilization(%) to go next state down */ UINT32 upTime, /* time(millisec) to go next state up */ UINT32 downTime /* time(millisec) to go next state down */ ) { gv3UpUtil = upUtil; gv3DownUtil = downUtil; gv3UpTime = upTime; gv3DownTime = downTime; /* convert milliseconds to system ticks */ gv3UpTick = (upTime * sysClkRateGet ()) / 1000; gv3DownTick = (downTime * sysClkRateGet ()) / 1000; return (OK); }/********************************************************************************* gv3AutoGet - get the automatic performance state transition parameters** This routine gets the automatic performance state transition parameters.** RETURNS: OK always*/STATUS gv3AutoGet ( UINT32 * pUpUtil, /* utilization(%) to go next state up */ UINT32 * pDownUtil, /* utilization(%) to go next state down */ UINT32 * pUpTime, /* time(millisec) to go next state up */ UINT32 * pDownTime /* time(millisec) to go next state down */ ) { *pUpUtil = gv3UpUtil; *pDownUtil = gv3DownUtil; *pUpTime = gv3UpTime; *pDownTime = gv3DownTime; return (OK); }#ifdef GV3_DEBUG/********************************************************************************* gv3Loop - consume the processor power for the specified system ticks** This routine consumes the processor power for the specified system ticks.* This routine boost up the CPU utilization to cause the performance state * transition to the next level above for debugging.** RETURNS: N/A*/void gv3Loop (UINT32 a) { UINT32 tick = tickGet (); while (1) { if (((UINT32)tickGet() - tick) > a) break; } }#endif /* GV3_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -