Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Move the evaluation of the _PDC control method out from ...



details:   https://anonhg.NetBSD.org/src/rev/cc11540f0aae
branches:  trunk
changeset: 765988:cc11540f0aae
user:      jruoho <jruoho%NetBSD.org@localhost>
date:      Sun Jun 12 10:11:52 2011 +0000

description:
Move the evaluation of the _PDC control method out from the acpicpu(4)
driver to the main acpi(4) stack. Follow Linux and evaluate it early.
Should fix PR port-amd64/42895, possibly also PR kern/42583, and many
other comparable bugs.

A common sense explanation is that Intel supplies additional CPU tables to
OEMs. BIOS writers do not bother to modify their DSDTs, but instead load
these extra tables dynamically as secondary SSDT tables. The actual Load()
happens when the _PDC method is invoked, and thus namespace errors occur
when the CPU-specific ACPI methods are not yet present but referenced in the
AML by various drivers, including, but not limited to, acpitz(4).

diffstat:

 sys/arch/ia64/acpi/acpi_machdep.c    |   15 ++-
 sys/arch/ia64/include/acpi_machdep.h |    3 +-
 sys/arch/x86/acpi/acpi_cpu_md.c      |   55 +-------------
 sys/arch/x86/acpi/acpi_pdc.c         |  142 +++++++++++++++++++++++++++++++++++
 sys/arch/x86/conf/files.x86          |    3 +-
 sys/arch/x86/include/acpi_machdep.h  |    4 +-
 sys/dev/acpi/acpi.c                  |   14 ++-
 sys/dev/acpi/acpi_cpu.c              |   53 +-----------
 sys/dev/acpi/acpi_cpu.h              |    3 +-
 9 files changed, 179 insertions(+), 113 deletions(-)

diffs (truncated from 465 to 300 lines):

diff -r d647c7aca686 -r cc11540f0aae sys/arch/ia64/acpi/acpi_machdep.c
--- a/sys/arch/ia64/acpi/acpi_machdep.c Sun Jun 12 07:25:43 2011 +0000
+++ b/sys/arch/ia64/acpi/acpi_machdep.c Sun Jun 12 10:11:52 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: acpi_machdep.c,v 1.3 2011/01/13 03:40:50 jruoho Exp $  */
+/*     $NetBSD: acpi_machdep.c,v 1.4 2011/06/12 10:11:52 jruoho Exp $  */
 /*
  * Copyright (c) 2009 KIYOHARA Takashi
  * All rights reserved.
@@ -28,7 +28,7 @@
  * Machine-dependent routines for ACPICA.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.3 2011/01/13 03:40:50 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.4 2011/06/12 10:11:52 jruoho Exp $");
 
 #include <sys/param.h>
 
@@ -186,20 +186,23 @@
 }
 
 uint32_t
+acpi_md_pdc(void)
+{
+       return 0;
+}
+
+uint32_t
 acpi_md_ncpus(void)
 {
-
        return 0;               /* XXX. */
 }
 
 void
 acpi_md_callback(void)
 {
-
-       /* nothing */
+       /* Nothing. */
 }
 
-
 int
 acpi_md_sleep(int state)
 {
diff -r d647c7aca686 -r cc11540f0aae sys/arch/ia64/include/acpi_machdep.h
--- a/sys/arch/ia64/include/acpi_machdep.h      Sun Jun 12 07:25:43 2011 +0000
+++ b/sys/arch/ia64/include/acpi_machdep.h      Sun Jun 12 10:11:52 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: acpi_machdep.h,v 1.3 2011/01/13 03:40:50 jruoho Exp $  */
+/*     $NetBSD: acpi_machdep.h,v 1.4 2011/06/12 10:11:52 jruoho Exp $  */
 
 ACPI_STATUS acpi_md_OsInitialize(void);
 ACPI_STATUS acpi_md_OsTerminate(void);
@@ -27,5 +27,6 @@
 void           acpi_md_OsDisableInterrupt(void);
 
 int            acpi_md_sleep(int);
+uint32_t       acpi_md_pdc(void);
 uint32_t       acpi_md_ncpus(void);
 void           acpi_md_callback(void);
diff -r d647c7aca686 -r cc11540f0aae sys/arch/x86/acpi/acpi_cpu_md.c
--- a/sys/arch/x86/acpi/acpi_cpu_md.c   Sun Jun 12 07:25:43 2011 +0000
+++ b/sys/arch/x86/acpi/acpi_cpu_md.c   Sun Jun 12 10:11:52 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_md.c,v 1.60 2011/06/06 07:42:32 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_md.c,v 1.61 2011/06/12 10:11:52 jruoho Exp $ */
 
 /*-
  * Copyright (c) 2010, 2011 Jukka Ruohonen <jruohonen%iki.fi@localhost>
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.60 2011/06/06 07:42:32 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.61 2011/06/12 10:11:52 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -141,57 +141,6 @@
 }
 
 uint32_t
-acpicpu_md_cap(void)
-{
-       struct cpu_info *ci = curcpu();
-       uint32_t regs[4];
-       uint32_t val = 0;
-
-       if (cpu_vendor != CPUVENDOR_IDT &&
-           cpu_vendor != CPUVENDOR_INTEL)
-               return val;
-
-       /*
-        * Basic SMP C-states (required for e.g. _CST).
-        */
-       val |= ACPICPU_PDC_C_C1PT | ACPICPU_PDC_C_C2C3;
-
-       /*
-        * Claim to support dependency coordination.
-        */
-       val |= ACPICPU_PDC_P_SW | ACPICPU_PDC_C_SW | ACPICPU_PDC_T_SW;
-
-        /*
-        * If MONITOR/MWAIT is available, announce
-        * support for native instructions in all C-states.
-        */
-        if ((ci->ci_feat_val[1] & CPUID2_MONITOR) != 0)
-               val |= ACPICPU_PDC_C_C1_FFH | ACPICPU_PDC_C_C2C3_FFH;
-
-       /*
-        * Set native P- and T-states, if available.
-        */
-        if ((ci->ci_feat_val[1] & CPUID2_EST) != 0)
-               val |= ACPICPU_PDC_P_FFH;
-
-       if ((ci->ci_feat_val[0] & CPUID_ACPI) != 0)
-               val |= ACPICPU_PDC_T_FFH;
-
-       /*
-        * Declare support for APERF and MPERF.
-        */
-       if (cpuid_level >= 0x06) {
-
-               x86_cpuid(0x00000006, regs);
-
-               if ((regs[2] & CPUID_DSPM_HWF) != 0)
-                       val |= ACPICPU_PDC_P_HWF;
-       }
-
-       return val;
-}
-
-uint32_t
 acpicpu_md_flags(void)
 {
        struct cpu_info *ci = curcpu();
diff -r d647c7aca686 -r cc11540f0aae sys/arch/x86/acpi/acpi_pdc.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/x86/acpi/acpi_pdc.c      Sun Jun 12 10:11:52 2011 +0000
@@ -0,0 +1,142 @@
+/* $NetBSD: acpi_pdc.c,v 1.1 2011/06/12 10:11:52 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010, 2011 Jukka Ruohonen <jruohonen%iki.fi@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: acpi_pdc.c,v 1.1 2011/06/12 10:11:52 jruoho Exp $");
+
+#include <sys/param.h>
+
+#include <x86/cpu.h>
+#include <x86/cputypes.h>
+#include <x86/cpuvar.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_cpu.h>
+
+#include <machine/acpi_machdep.h>
+
+#define _COMPONENT     ACPI_BUS_COMPONENT
+ACPI_MODULE_NAME       ("acpi_pdc")
+
+static uint32_t                flags = 0;
+
+static ACPI_STATUS     acpi_md_pdc_walk(ACPI_HANDLE, uint32_t,void *,void **);
+static ACPI_STATUS     acpi_md_pdc_set(ACPI_HANDLE, uint32_t);
+
+uint32_t
+acpi_md_pdc(void)
+{
+       char *hid = __UNCONST("ACPI0007");
+       struct cpu_info *ci = curcpu();
+       uint32_t regs[4];
+
+       if (flags != 0)
+               return flags;
+
+       if (cpu_vendor != CPUVENDOR_IDT &&
+           cpu_vendor != CPUVENDOR_INTEL)
+               return 0;
+
+       /*
+        * Basic SMP C-states (required for e.g. _CST).
+        */
+       flags |= ACPICPU_PDC_C_C1PT | ACPICPU_PDC_C_C2C3;
+
+       /*
+        * Claim to support dependency coordination.
+        */
+       flags |= ACPICPU_PDC_P_SW | ACPICPU_PDC_C_SW | ACPICPU_PDC_T_SW;
+
+        /*
+        * If MONITOR/MWAIT is available, announce
+        * support for native instructions in all C-states.
+        */
+        if ((ci->ci_feat_val[1] & CPUID2_MONITOR) != 0)
+               flags |= ACPICPU_PDC_C_C1_FFH | ACPICPU_PDC_C_C2C3_FFH;
+
+       /*
+        * Set native P- and T-states, if available.
+        */
+        if ((ci->ci_feat_val[1] & CPUID2_EST) != 0)
+               flags |= ACPICPU_PDC_P_FFH;
+
+       if ((ci->ci_feat_val[0] & CPUID_ACPI) != 0)
+               flags |= ACPICPU_PDC_T_FFH;
+
+       /*
+        * Declare support for APERF and MPERF.
+        */
+       if (cpuid_level >= 0x06) {
+
+               x86_cpuid(0x00000006, regs);
+
+               if ((regs[2] & CPUID_DSPM_HWF) != 0)
+                       flags |= ACPICPU_PDC_P_HWF;
+       }
+
+       /*
+        * As the _PDC must be evaluated before the internal namespace
+        * is built, we have no option but to walk with the interpreter.
+        */
+       (void)AcpiGetDevices(hid, acpi_md_pdc_walk, NULL, NULL);
+
+       (void)AcpiWalkNamespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
+           UINT32_MAX, acpi_md_pdc_walk, NULL, NULL, NULL);
+
+       return flags;
+}
+
+static ACPI_STATUS
+acpi_md_pdc_walk(ACPI_HANDLE hdl, uint32_t level, void *context, void **status)
+{
+       return acpi_md_pdc_set(hdl, flags);
+}
+
+static ACPI_STATUS
+acpi_md_pdc_set(ACPI_HANDLE hdl, uint32_t val)
+{
+       ACPI_OBJECT_LIST arg;
+       ACPI_OBJECT obj;
+       uint32_t cap[3];
+
+       arg.Count = 1;
+       arg.Pointer = &obj;
+
+       cap[0] = ACPICPU_PDC_REVID;
+       cap[1] = 1;
+       cap[2] = val;
+
+       obj.Type = ACPI_TYPE_BUFFER;
+       obj.Buffer.Length = sizeof(cap);
+       obj.Buffer.Pointer = (void *)cap;
+
+       (void)AcpiEvaluateObject(hdl, "_PDC", &arg, NULL);
+
+       return AE_OK;
+}
diff -r d647c7aca686 -r cc11540f0aae sys/arch/x86/conf/files.x86
--- a/sys/arch/x86/conf/files.x86       Sun Jun 12 07:25:43 2011 +0000
+++ b/sys/arch/x86/conf/files.x86       Sun Jun 12 10:11:52 2011 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.x86,v 1.69 2011/06/12 03:35:49 rmind Exp $
+#      $NetBSD: files.x86,v 1.70 2011/06/12 10:11:52 jruoho Exp $
 
 # options for MP configuration through the MP spec
 defflag opt_mpbios.h MPBIOS MPVERBOSE MPDEBUG MPBIOS_SCANPCI
@@ -107,6 +107,7 @@
 
 file   arch/x86/x86/acpi_machdep.c     acpi
 
+file   arch/x86/acpi/acpi_pdc.c        acpi
 file   arch/x86/acpi/acpi_wakeup.c     acpi
 



Home | Main Index | Thread Index | Old Index