| 367 | } |
| 368 | |
| 369 | static int |
| 370 | set_autonomous_hwp(struct hwp_softc *sc) |
| 371 | { |
| 372 | struct pcpu *pc; |
| 373 | device_t dev; |
| 374 | uint64_t caps; |
| 375 | int ret; |
| 376 | |
| 377 | dev = sc->dev; |
| 378 | |
| 379 | pc = cpu_get_pcpu(dev); |
| 380 | if (pc == NULL) |
| 381 | return (ENXIO); |
| 382 | |
| 383 | thread_lock(curthread); |
| 384 | sched_bind(curthread, pc->pc_cpuid); |
| 385 | thread_unlock(curthread); |
| 386 | |
| 387 | /* XXX: Many MSRs aren't readable until feature is enabled */ |
| 388 | ret = wrmsr_safe(MSR_IA32_PM_ENABLE, 1); |
| 389 | if (ret) { |
| 390 | /* |
| 391 | * This is actually a package-level MSR, and only the first |
| 392 | * write is not ignored. So it is harmless to enable it across |
| 393 | * all devices, and this allows us not to care especially in |
| 394 | * which order cores (and packages) are probed. This error |
| 395 | * condition should not happen given we gate on the HWP CPUID |
| 396 | * feature flag, if the Intel SDM is correct. |
| 397 | */ |
| 398 | device_printf(dev, "Failed to enable HWP for cpu%d (%d)\n", |
| 399 | pc->pc_cpuid, ret); |
| 400 | goto out; |
| 401 | } |
| 402 | |
| 403 | ret = rdmsr_safe(MSR_IA32_HWP_REQUEST, &sc->req); |
| 404 | if (ret) { |
| 405 | device_printf(dev, |
| 406 | "Failed to read HWP request MSR for cpu%d (%d)\n", |
| 407 | pc->pc_cpuid, ret); |
| 408 | goto out; |
| 409 | } |
| 410 | |
| 411 | ret = rdmsr_safe(MSR_IA32_HWP_CAPABILITIES, &caps); |
| 412 | if (ret) { |
| 413 | device_printf(dev, |
| 414 | "Failed to read HWP capabilities MSR for cpu%d (%d)\n", |
| 415 | pc->pc_cpuid, ret); |
| 416 | goto out; |
| 417 | } |
| 418 | |
| 419 | /* |
| 420 | * High and low are static; "guaranteed" is dynamic; and efficient is |
| 421 | * also dynamic. |
| 422 | */ |
| 423 | sc->high = IA32_HWP_CAPABILITIES_HIGHEST_PERFORMANCE(caps); |
| 424 | sc->guaranteed = IA32_HWP_CAPABILITIES_GUARANTEED_PERFORMANCE(caps); |
| 425 | sc->efficient = IA32_HWP_CAPABILITIES_EFFICIENT_PERFORMANCE(caps); |
| 426 | sc->low = IA32_HWP_CAPABILITIES_LOWEST_PERFORMANCE(caps); |
no test coverage detected