Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146364224
D55606.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D55606.id.diff
View Options
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
@@ -588,6 +588,18 @@
return (val);
}
+static int
+hwpstate_pstate_read_limit(device_t dev)
+{
+ int cpu;
+ uint64_t msr;
+
+ cpu = cpu_get_pcpu(dev)->pc_cpuid;
+ x86_msr_op(MSR_AMD_10H_11H_LIMIT,
+ MSR_OP_READ | MSR_OP_RENDEZVOUS_ONE | MSR_OP_CPUID(cpu), 0, &msr);
+ return (msr);
+}
+
/*
* Go to Px-state on all cpus, considering the limit register (if so
* configured).
@@ -597,11 +609,13 @@
{
sbintime_t sbt;
uint64_t msr;
- int cpu, i, j, limit;
+ int cpu, j, limit;
+
+ cpu = cpu_get_pcpu(dev)->pc_cpuid;
if (hwpstate_pstate_limit) {
/* get the current pstate limit */
- msr = rdmsr(MSR_AMD_10H_11H_LIMIT);
+ msr = hwpstate_pstate_read_limit(dev);
limit = AMD_10H_11H_GET_PSTATE_LIMIT(msr);
if (limit > id) {
HWPSTATE_DEBUG(dev, "Restricting requested P%d to P%d "
@@ -610,53 +624,34 @@
}
}
- cpu = curcpu;
HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", id, cpu);
/* Go To Px-state */
- wrmsr(MSR_AMD_10H_11H_CONTROL, id);
-
- /*
- * We are going to the same Px-state on all cpus.
- * Probably should take _PSD into account.
- */
- CPU_FOREACH(i) {
- if (i == cpu)
- continue;
-
- /* Bind to each cpu. */
- thread_lock(curthread);
- sched_bind(curthread, i);
- thread_unlock(curthread);
- HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", id, i);
- /* Go To Px-state */
- wrmsr(MSR_AMD_10H_11H_CONTROL, id);
- }
+ x86_msr_op(MSR_AMD_10H_11H_CONTROL,
+ MSR_OP_WRITE | MSR_OP_RENDEZVOUS_ONE | MSR_OP_CPUID(cpu), id, NULL);
/*
* Verify whether each core is in the requested P-state.
*/
if (hwpstate_verify) {
- CPU_FOREACH(i) {
- thread_lock(curthread);
- sched_bind(curthread, i);
- thread_unlock(curthread);
- /* wait loop (100*100 usec is enough ?) */
- for (j = 0; j < 100; j++) {
- /* get the result. not assure msr=id */
- msr = rdmsr(MSR_AMD_10H_11H_STATUS);
- if (msr == id)
- break;
- sbt = SBT_1MS / 10;
- tsleep_sbt(dev, PZERO, "pstate_goto", sbt,
- sbt >> tc_precexp, 0);
- }
- HWPSTATE_DEBUG(dev, "result: P%d-state on cpu%d\n",
- (int)msr, i);
- if (msr != id) {
- HWPSTATE_DEBUG(dev,
- "error: loop is not enough.\n");
- return (ENXIO);
- }
+ /* wait loop (100*100 usec is enough ?) */
+ for (j = 0; j < 100; j++) {
+ /* get the result. not assure msr=id */
+ x86_msr_op(MSR_AMD_10H_11H_CONTROL,
+ MSR_OP_READ | MSR_OP_RENDEZVOUS_ONE |
+ MSR_OP_CPUID(cpu),
+ 0, &msr);
+
+ if (msr == id)
+ break;
+ sbt = SBT_1MS / 10;
+ tsleep_sbt(dev, PZERO, "pstate_goto", sbt,
+ sbt >> tc_precexp, 0);
+ }
+ HWPSTATE_DEBUG(dev, "result: P%d-state on cpu%d\n", (int)msr,
+ cpu);
+ if (msr != id) {
+ HWPSTATE_DEBUG(dev, "error: loop is not enough.\n");
+ return (ENXIO);
}
}
@@ -723,7 +718,6 @@
pc = cpu_get_pcpu(dev);
if (pc == NULL)
return (ENXIO);
-
memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf));
cf->dev = dev;
if ((ret = cpu_est_clockrate(pc->pc_cpuid, &rate)))
@@ -738,13 +732,15 @@
struct hwpstate_softc *sc;
struct hwpstate_setting set;
uint64_t msr;
+ int cpu;
sc = device_get_softc(dev);
- msr = rdmsr(MSR_AMD_10H_11H_STATUS);
+ cpu = cpu_get_pcpu(dev)->pc_cpuid;
+ x86_msr_op(MSR_AMD_10H_11H_STATUS,
+ MSR_OP_READ | MSR_OP_RENDEZVOUS_ONE | MSR_OP_CPUID(cpu), 0, &msr);
if (msr >= sc->cfnum)
return (EINVAL);
set = sc->hwpstate_settings[msr];
-
cf->freq = set.freq;
cf->volts = set.volts;
cf->power = set.power;
@@ -1095,7 +1091,7 @@
* Now we get _PSS info from acpi_perf without error.
* Let's check it.
*/
- msr = rdmsr(MSR_AMD_10H_11H_LIMIT);
+ msr = hwpstate_pstate_read_limit(dev);
if (sc->cfnum != 1 + AMD_10H_11H_GET_PSTATE_MAX_VAL(msr)) {
HWPSTATE_DEBUG(dev, "MSR (%jd) and ACPI _PSS (%d)"
" count mismatch\n", (intmax_t)msr, sc->cfnum);
@@ -1133,15 +1129,8 @@
sc->flags |= HWPFL_USE_CPPC;
device_set_desc(dev,
"AMD Collaborative Processor Performance Control (CPPC)");
- } else {
- /*
- * No CPPC support. Only keep hwpstate0, it goes well with
- * acpi_throttle.
- */
- if (device_get_unit(dev) != 0)
- return (ENXIO);
+ } else
device_set_desc(dev, "Cool`n'Quiet 2.0");
- }
sc->dev = dev;
if ((sc->flags & HWPFL_USE_CPPC) != 0) {
@@ -1230,22 +1219,59 @@
return (cpufreq_register(dev));
}
+struct hwpstate_pstate_read_settings_cb {
+ struct hwpstate_softc *sc;
+ uint64_t *vals;
+ int err;
+};
+
+static void
+hwpstate_pstate_read_settings_cb(void *args)
+{
+ struct hwpstate_pstate_read_settings_cb *req = args;
+ int i;
+
+ req->err = 0;
+ for (i = 0; i < req->sc->cfnum; i++) {
+ req->err = rdmsr_safe(MSR_AMD_10H_11H_CONFIG + i,
+ &req->vals[i]);
+ if (req->err)
+ return;
+ }
+}
+
+static int
+hwpstate_pstate_read_settings(struct hwpstate_softc *sc, uint64_t vals[])
+{
+ struct hwpstate_pstate_read_settings_cb req;
+ device_t dev;
+
+ req.sc = sc;
+ req.vals = vals;
+ dev = sc->dev;
+ smp_rendezvous_cpu(cpu_get_pcpu(dev)->pc_cpuid,
+ smp_no_rendezvous_barrier, hwpstate_pstate_read_settings_cb,
+ smp_no_rendezvous_barrier, &req);
+ return (req.err);
+}
+
static int
hwpstate_get_info_from_msr(device_t dev)
{
struct hwpstate_softc *sc;
struct hwpstate_setting *hwpstate_set;
- uint64_t msr;
+ uint64_t msrs[AMD_10H_11H_MAX_STATES], msr;
int family, i, fid, did;
family = CPUID_TO_FAMILY(cpu_id);
sc = device_get_softc(dev);
/* Get pstate count */
- msr = rdmsr(MSR_AMD_10H_11H_LIMIT);
+ msr = hwpstate_pstate_read_limit(dev);
sc->cfnum = 1 + AMD_10H_11H_GET_PSTATE_MAX_VAL(msr);
hwpstate_set = sc->hwpstate_settings;
+ hwpstate_pstate_read_settings(sc, msrs);
for (i = 0; i < sc->cfnum; i++) {
- msr = rdmsr(MSR_AMD_10H_11H_CONFIG + i);
+ msr = msrs[i];
if ((msr & ((uint64_t)1 << 63)) == 0) {
HWPSTATE_DEBUG(dev, "msr is not valid.\n");
return (ENXIO);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 3, 2:36 AM (18 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29166764
Default Alt Text
D55606.id.diff (5 KB)
Attached To
Mode
D55606: hwpstate_amd: Expose node as much as possible
Attached
Detach File
Event Timeline
Log In to Comment