📄 gv3lib.c
字号:
gv3Header = &gv3FvidHeader[0]; gv3State = gv3Header->pState;#endif /* GV3_DEBUG */ /* check if the Thermal Monitor is supported */ pentiumMsrGet (IA32_PLATFORM_ID, (LL_INT *)&value); if (value[0] & PFM_TM_DISABLED) { gv3LibState = GV3_ERR_NO_TM; return (ERROR); } if (sysCpuId.featuresEdx & CPUID_ACPI) { gv3LibState |= GV3_OK_TM1; } /* check if the Geyserville 1+ or 3 is supported */ if ((value[1] & PFM_MOBILE_GV) == 0) { pentiumMsrGet (IA32_MISC_ENABLE, (LL_INT *)&value); value[0] &= ~(MSC_GV1_EN | MSC_GV3_EN); value[0] |= MSC_GV_SEL_LOCK; pentiumMsrSet (IA32_MISC_ENABLE, (LL_INT *)&value); gv3LibState |= GV3_OK_NO_GV; } /* check if the Geyserville III is supported */ if ((sysCpuId.featuresEcx & CPUID_GV3) && ((value[1] & PFM_GV3_DISABLED) == 0)) { gv3LibState |= GV3_OK_GV3; /* CPU has the GV3. get the matching FREQ_VID state table */ cpuId = sysCpuId.signature & (CPUID_FAMILY | CPUID_MODEL | CPUID_STEPID); pentiumMsrGet (MSR_PERF_STS, (LL_INT *)&value); maxVid = value[1] & GV_VID_MAX; maxRatio = (value[1] & BUS_RATIO_MAX) >> 8; bootVid = (value[1] & GV_VID_BOOT) >> 16; bootRatio = (value[1] & BUS_RATIO_BOOT) >> 24; minRatio = (value[0] & BUS_RATIO_MIN) >> 24; for (ix = 0; ix < NELEMENTS (gv3FvidHeader); ix++) { gv3Header = &gv3FvidHeader[ix]; if ((cpuId == gv3Header->cpuId) && (maxVid == gv3Header->maxVid) && (maxRatio == gv3Header->maxRatio)) { gv3State = gv3Header->pState; } } /* if there are no matching state, make it up */ if (gv3State == NULL) { gv3State = gv3Header->pState; (gv3State + 0)->vid = maxVid; (gv3State + 0)->ratio = maxRatio; (gv3State + 1)->vid = bootVid; (gv3State + 1)->ratio = minRatio; gv3LibState |= GV3_OK_NO_MATCH; } /* enable the GV3 */ pentiumMsrGet (IA32_MISC_ENABLE, (LL_INT *)&value); value[0] |= (MSC_GV3_EN | MSC_GV_SEL_LOCK); pentiumMsrSet (IA32_MISC_ENABLE, (LL_INT *)&value); /* check if the Thermal Monitor 2 is supported */ pentiumMsrGet (IA32_PLATFORM_ID, (LL_INT *)&value); if ((sysCpuId.featuresEcx & CPUID_TM2) && ((value[0] & PFM_GV3_TM_DISABLED) == 0)) { gv3LibState |= GV3_OK_TM2; /* get the matching state and set up the GV_THERM */ for (ix = 0; ix < gv3Header->nState; ix++) { pState = gv3Header->pState + ix; if (gv3ThrottleRatio == pState->ratio) { pentiumMsrGet (MSR_GV_THERM, (LL_INT *)&value); value[0] &= ~(GV_THROT_SEL | BUS_RATIO_THROT | GV_VID_THROT); value[0] |= GV_THROT_SEL | ((pState->ratio << 8) & BUS_RATIO_THROT) | (pState->vid & GV_VID_THROT); pentiumMsrSet (MSR_GV_THERM, (LL_INT *)&value); gv3State = pState; break; } } } } /* enable Automatic Thermal Control Circuit (Automatic TCC) */ pentiumMsrGet (IA32_MISC_ENABLE, (LL_INT *)&value); value[0] |= MSC_THERMAL_MON_ENABLE; pentiumMsrSet (IA32_MISC_ENABLE, (LL_INT *)&value); /* set up On-Demand Thermal Control Circuit (On-Demand TCC) */ pentiumMsrGet (IA32_THERM_CONTROL, (LL_INT *)&value); value[0] &= ~(THERM_TCC_EN | THERM_DUTY_CYCLE); value[0] |= gv3ThrottleDuty; pentiumMsrSet (IA32_THERM_CONTROL, (LL_INT *)&value); /* get the power-source AC(default) or Battery */ if (acCheckRtn != (FUNCPTR) NULL) ac = (* acCheckRtn) (); /* select the state for the specified mode */ if (ac) { gv3LibState |= GV3_OK_AC; switch (mode) { case GV3_MAX_PERF: case GV3_AUTO: stateNo = 0; gv3DutyCycleIx = NELEMENTS (gv3DutyCycle) - 1; break; case GV3_OPT_BATT: case GV3_MAX_BATT: stateNo = gv3Header->nState - 1; gv3DutyCycleIx = 1; break; default: gv3Mode = GV3_DEFAULT; stateNo = 0; gv3DutyCycleIx = NELEMENTS (gv3DutyCycle) - 1; break; } } else { gv3LibState |= GV3_OK_BATT; switch (mode) { case GV3_MAX_PERF: stateNo = 0; gv3DutyCycleIx = NELEMENTS (gv3DutyCycle) - 1; break; case GV3_AUTO: case GV3_OPT_BATT: case GV3_MAX_BATT: stateNo = gv3Header->nState - 1; gv3DutyCycleIx = 1; break; default: gv3Mode = GV3_DEFAULT; stateNo = gv3Header->nState - 1; gv3DutyCycleIx = 1; break; } } /* set the selected state */ if (gv3LibState & GV3_OK_TM2) gv3StateSet (stateNo); else if (gv3LibState & GV3_OK_TM1) gv3DutyCycleSet (gv3DutyCycleIx); /* set the parameters and enable the automatic state transition */ if ((gv3Mode == GV3_AUTO) || (gv3Mode == GV3_DEFAULT)) { gv3AutoSet (upUtil, downUtil, upTime, downTime); gv3AutoEnable (TRUE); } return (OK); }/********************************************************************************* gv3StateSet - perform the Geyserville III state transition** This routine performs the Geyserville III state transition.** RETURNS: OK or ERROR if the specified state is out of range.*/STATUS gv3StateSet ( UINT32 stateNo /* GV3 FREQ_VID state index */ ) { INT32 value[2]; INT32 oldLevel; /* sanity check */ if (stateNo >= gv3Header->nState) return (ERROR);#ifdef GV3_DEBUG stateLog[stateIx++] = stateNo;#endif /* GV3_DEBUG */ /* update the current state pointer, and perform the GV3 transition */ oldLevel = intLock (); /* LOCK INTERRUPTS */ gv3State = gv3Header->pState + stateNo; pentiumMsrGet (MSR_PERF_CTL, (LL_INT *)&value); value[0] &= ~(BUS_RATIO_SEL | GV_VID_SEL); value[0] |= (((gv3State->ratio << 8) & BUS_RATIO_SEL) | ((gv3State->vid) & GV_VID_SEL)); pentiumMsrSet (MSR_PERF_CTL, (LL_INT *)&value); intUnlock (oldLevel); /* UNLOCK INTERRUPTS */ return (OK); }/********************************************************************************* gv3HotCheck - check the thermal sensor high-temperature signal** This routine checks the thermal sensor high-temperature signal.* It checks the bit 0 of IA32_THERM_STATUS MSR that reflect the current * state of the thermal sensor. The bit is 1 if the output signal * PROCHOT# is currently active, and 0 if it is not active. ** RETURNS: TRUE if the bit 0 is set, FALSE otherwise.*/BOOL gv3HotCheck (void) { INT32 value[2]; /* check the thermal sensor high-temparature output signal */ pentiumMsrGet (IA32_THERM_STATUS, (LL_INT *)&value); if (value[0] & THERM_HOT_NOW) return (TRUE); else return (FALSE); }/********************************************************************************* gv3DutyCycleSet - set the on-demand throttle clock duty cycle** This routine sets on-demand throttle clock duty cycle.** RETURNS: OK if the duty cycle has changed, ERROR otherwise.*/STATUS gv3DutyCycleSet ( UINT32 dutyCycleIx /* clock duty cycle table index */ ) { INT32 value[2]; INT32 oldLevel; /* sanity check */ if ((dutyCycleIx >= NELEMENTS (gv3DutyCycle)) || (dutyCycleIx == 0)) return (ERROR);#ifdef GV3_DEBUG stateLog[stateIx++] = dutyCycleIx;#endif /* GV3_DEBUG */ /* update the duty cycle table index, and change the duty cycle */ oldLevel = intLock (); /* LOCK INTERRUPTS */ gv3DutyCycleIx = dutyCycleIx; pentiumMsrGet (IA32_THERM_CONTROL, (LL_INT *)&value); value[0] &= ~(THERM_TCC_EN | THERM_DUTY_CYCLE); value[0] |= (THERM_TCC_EN | gv3DutyCycle[dutyCycleIx]); pentiumMsrSet (IA32_THERM_CONTROL, (LL_INT *)&value); intUnlock (oldLevel); /* UNLOCK INTERRUPTS */ return (OK); }/********************************************************************************* gv3DutyCycleEnable - enable or disable the CPU on-demand throttling** This routine enables or disables the CPU on-demand throttling.** RETURNS: OK or ERROR if the on-demand throttling is not supported*/STATUS gv3DutyCycleEnable ( BOOL enable /* TRUE to enable, FALSE to disable */ ) { INT32 value[2]; if (gv3LibState & GV3_ERR_NO_TM) return (ERROR); /* toggle the On-Demand Thermal Control Circuit Enable bit */ pentiumMsrGet (IA32_THERM_CONTROL, (LL_INT *)&value); if (enable) value[0] |= THERM_TCC_EN; else value[0] &= ~THERM_TCC_EN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -