Changeset View
Changeset View
Standalone View
Standalone View
head/sys/x86/cpufreq/hwpstate.c
Show First 20 Lines • Show All 154 Lines • ▼ Show 20 Lines | |||||
DRIVER_MODULE(hwpstate, cpu, hwpstate_driver, hwpstate_devclass, 0, 0); | DRIVER_MODULE(hwpstate, cpu, hwpstate_driver, hwpstate_devclass, 0, 0); | ||||
/* | /* | ||||
* Go to Px-state on all cpus considering the limit. | * Go to Px-state on all cpus considering the limit. | ||||
*/ | */ | ||||
static int | static int | ||||
hwpstate_goto_pstate(device_t dev, int pstate) | hwpstate_goto_pstate(device_t dev, int pstate) | ||||
{ | { | ||||
sbintime_t sbt; | |||||
int i; | int i; | ||||
uint64_t msr; | uint64_t msr; | ||||
int j; | int j; | ||||
int limit; | int limit; | ||||
int id = pstate; | int id = pstate; | ||||
int error; | int error; | ||||
/* get the current pstate limit */ | /* get the current pstate limit */ | ||||
msr = rdmsr(MSR_AMD_10H_11H_LIMIT); | msr = rdmsr(MSR_AMD_10H_11H_LIMIT); | ||||
limit = AMD_10H_11H_GET_PSTATE_LIMIT(msr); | limit = AMD_10H_11H_GET_PSTATE_LIMIT(msr); | ||||
if(limit > id) | if (limit > id) | ||||
id = limit; | id = limit; | ||||
/* | /* | ||||
* We are going to the same Px-state on all cpus. | * We are going to the same Px-state on all cpus. | ||||
* Probably should take _PSD into account. | * Probably should take _PSD into account. | ||||
*/ | */ | ||||
error = 0; | error = 0; | ||||
CPU_FOREACH(i) { | CPU_FOREACH(i) { | ||||
/* Bind to each cpu. */ | /* Bind to each cpu. */ | ||||
thread_lock(curthread); | thread_lock(curthread); | ||||
sched_bind(curthread, i); | sched_bind(curthread, i); | ||||
thread_unlock(curthread); | thread_unlock(curthread); | ||||
HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", | HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", | ||||
id, PCPU_GET(cpuid)); | id, PCPU_GET(cpuid)); | ||||
/* Go To Px-state */ | /* Go To Px-state */ | ||||
wrmsr(MSR_AMD_10H_11H_CONTROL, id); | wrmsr(MSR_AMD_10H_11H_CONTROL, id); | ||||
} | } | ||||
CPU_FOREACH(i) { | CPU_FOREACH(i) { | ||||
/* Bind to each cpu. */ | /* Bind to each cpu. */ | ||||
thread_lock(curthread); | thread_lock(curthread); | ||||
sched_bind(curthread, i); | sched_bind(curthread, i); | ||||
thread_unlock(curthread); | thread_unlock(curthread); | ||||
/* wait loop (100*100 usec is enough ?) */ | /* wait loop (100*100 usec is enough ?) */ | ||||
for(j = 0; j < 100; j++){ | for (j = 0; j < 100; j++){ | ||||
/* get the result. not assure msr=id */ | /* get the result. not assure msr=id */ | ||||
msr = rdmsr(MSR_AMD_10H_11H_STATUS); | msr = rdmsr(MSR_AMD_10H_11H_STATUS); | ||||
if(msr == id){ | if (msr == id) | ||||
break; | break; | ||||
} | sbt = SBT_1MS / 10; | ||||
DELAY(100); | tsleep_sbt(dev, PZERO, "pstate_goto", sbt, | ||||
sbt >> tc_precexp, 0); | |||||
} | } | ||||
HWPSTATE_DEBUG(dev, "result: P%d-state on cpu%d\n", | HWPSTATE_DEBUG(dev, "result: P%d-state on cpu%d\n", | ||||
(int)msr, PCPU_GET(cpuid)); | (int)msr, PCPU_GET(cpuid)); | ||||
if (msr != id) { | if (msr != id) { | ||||
HWPSTATE_DEBUG(dev, "error: loop is not enough.\n"); | HWPSTATE_DEBUG(dev, "error: loop is not enough.\n"); | ||||
error = ENXIO; | error = ENXIO; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 314 Lines • Show Last 20 Lines |