acpi/cstate: Allow forcing busmastering status and arbitration for C3
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 19 Jun 2015 06:35:28 +0000 (14:35 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 19 Jun 2015 06:37:03 +0000 (14:37 +0800)
sys/dev/acpica/acpi_cpu_cstate.c
sys/dev/acpica/acpi_cpu_cstate.h
sys/platform/pc64/acpica/acpi_cstate_machdep.c

index a1a70e2..f47e82f 100644 (file)
@@ -172,6 +172,12 @@ static int acpi_cst_cx_setup(struct acpi_cst_cx *cx);
 static void    acpi_cst_c1_halt_enter(const struct acpi_cst_cx *);
 static void    acpi_cst_cx_io_enter(const struct acpi_cst_cx *);
 
+int            acpi_cst_force_bmarb;
+TUNABLE_INT("hw.acpi.cpu.cst.force_bmarb", &acpi_cst_force_bmarb);
+
+int            acpi_cst_force_bmsts;
+TUNABLE_INT("hw.acpi.cpu.cst.force_bmsts", &acpi_cst_force_bmsts);
+
 static device_method_t acpi_cst_methods[] = {
     /* Device interface */
     DEVMETHOD(device_probe,    acpi_cst_probe),
index a4a75c0..64fbf01 100644 (file)
@@ -64,4 +64,7 @@ extern int    acpi_cst_quirks;        /* ACPI_CST_QUIRK_ */
 
 int    acpi_cst_md_cx_setup(struct acpi_cst_cx *);
 
+extern int     acpi_cst_force_bmarb;
+extern int     acpi_cst_force_bmsts;
+
 #endif /* !__ACPI_CPU_CSTATE_H__ */
index 3c009b6..a8c2282 100644 (file)
@@ -104,9 +104,10 @@ acpi_cst_md_cx_setup(struct acpi_cst_cx *cx)
        }
 
        if (cx->type >= ACPI_STATE_C3) {
-               if (CPUID_TO_FAMILY(cpu_id) > 0xf ||
-                   (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
-                    CPUID_TO_MODEL(cpu_id) >= 0xf)) {
+               if ((CPUID_TO_FAMILY(cpu_id) > 0xf ||
+                    (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+                     CPUID_TO_MODEL(cpu_id) >= 0xf)) &&
+                   !acpi_cst_force_bmarb) {
                        /*
                         * Pentium dual-core, Core 2 and beyond do not
                         * need any additional activities to enter C3(+).
@@ -164,7 +165,8 @@ acpi_cst_cx_mwait_setup(struct acpi_cst_cx *cx)
        cx->md_arg0 = eax_hint;
        cx->enter = acpi_cst_cx_mwait_enter;
 
-       if ((cx->gas.AccessWidth & ACPI_GAS_INTEL_ARG1_BM_STS) == 0) {
+       if ((cx->gas.AccessWidth & ACPI_GAS_INTEL_ARG1_BM_STS) == 0 &&
+           !acpi_cst_force_bmsts) {
                cpu_mwait_cx_no_bmsts();
                if (cx->type >= ACPI_STATE_C3)
                        cx->flags &= ~ACPI_CST_CX_FLAG_BM_STS;
@@ -177,8 +179,10 @@ acpi_cst_cx_mwait_setup(struct acpi_cst_cx *cx)
                 * operations are needed before entering deep CPU specific
                 * C-states.
                 */
-               cpu_mwait_cx_no_bmsts();
-               cpu_mwait_cx_no_bmarb();
+               if (!acpi_cst_force_bmsts)
+                       cpu_mwait_cx_no_bmsts();
+               if (!acpi_cst_force_bmarb)
+                       cpu_mwait_cx_no_bmarb();
        }
 
        return 0;