diff --git a/sys/x86/cpufreq/hwpstate_amd.c b/sys/x86/cpufreq/hwpstate_amd.c --- a/sys/x86/cpufreq/hwpstate_amd.c +++ b/sys/x86/cpufreq/hwpstate_amd.c @@ -123,6 +123,7 @@ static int hwpstate_features(driver_t *driver, u_int *features); static int hwpstate_get_info_from_acpi_perf(device_t dev, device_t perf_dev); static int hwpstate_get_info_from_msr(device_t dev); +static void hwpstate_override_msr(device_t dev); static int hwpstate_goto_pstate(device_t dev, int pstate_id); static int hwpstate_verbose; @@ -144,6 +145,11 @@ &hwpstate_prefer_msr, 0, "If enabled (1), use MSR instead of acpi_perf for P-state information."); +static char hwpstate_override_pstatecfgmsr[8 * sizeof("0x8000000049120890")]; +SYSCTL_STRING(_debug, OID_AUTO, hwpstate_override_pstatecfgmsr, CTLFLAG_RWTUN, + hwpstate_override_pstatecfgmsr, sizeof(hwpstate_override_pstatecfgmsr), + "Allows overriding PStateDef, up to 8 hexadecimals."); + static device_method_t hwpstate_methods[] = { /* Device interface */ DEVMETHOD(device_identify, hwpstate_identify), @@ -413,6 +419,9 @@ } } + if (strlen(&hwpstate_override_pstatecfgmsr[0]) > 0) + hwpstate_override_msr(dev); + /* * If we cannot get info from acpi_perf, * Let's get info from MSRs. @@ -433,6 +442,33 @@ return (cpufreq_register(dev)); } +static void +hwpstate_override_msr(device_t dev) +{ + char temp[sizeof(hwpstate_override_pstatecfgmsr)]; + char *token, *next; + uint64_t msr; + int i; + + memcpy(&temp[0], &hwpstate_override_pstatecfgmsr[0], sizeof(temp)); + next = &temp[0]; + token = strsep(&next, " "); + /* Ignore PStateCurLim here, sysadmin knows best. */ + for (i = 0; (i < 8) && (token != NULL); ++i) { + if (sscanf(token, "0x%lx", &msr) == 1) { + HWPSTATE_DEBUG(dev, "Overriding P%d-state with 0x%lx.\n", + i, msr); + wrmsr(MSR_AMD_10H_11H_CONFIG + i, msr); + } else { + HWPSTATE_DEBUG(dev, + "P%d-state MSR override value not parsable: \"%s\"\n", + i, token); + break; + } + token = strsep(&next, " "); + } +} + static int hwpstate_get_info_from_msr(device_t dev) { @@ -449,6 +485,7 @@ hwpstate_set = sc->hwpstate_settings; for (i = 0; i < sc->cfnum; i++) { msr = rdmsr(MSR_AMD_10H_11H_CONFIG + i); + HWPSTATE_DEBUG(dev, "PStateDef[%d]: 0x%lx\n", i, msr); if ((msr & ((uint64_t)1 << 63)) == 0) { HWPSTATE_DEBUG(dev, "msr is not valid.\n"); return (ENXIO);