Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Jun 2012 21:25:24 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r237823 - in stable/8: share/man/man4 sys/amd64/acpica sys/dev/acpica sys/i386/acpica
Message-ID:  <201206292125.q5TLPOid071099@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Jun 29 21:25:24 2012
New Revision: 237823
URL: http://svn.freebsd.org/changeset/base/237823

Log:
  MFC 235024,235029,235556,235834,235845:
  Use MADT to match ACPI Processor objects to CPUs.  MADT and DSDT/SSDTs may
  list CPUs in different orders, especially for disabled logical cores.  Now
  we match ACPI IDs from the MADT with Processor objects, strictly order CPUs
  accordingly, and ignore disabled cores.  This prevents us from executing
  methods for other CPUs, e. g., _PSS for disabled logical core, which may not
  exist.  Unfortunately, it is known that there are a few systems with buggy
  BIOSes that do not have unique ACPI IDs for MADT and Processor objects.  To
  work around these problems, 'debug.acpi.cpu_unordered' tunable is added.
  Set this to a non-zero value to restore the old behavior.

Modified:
  stable/8/share/man/man4/acpi.4
  stable/8/sys/amd64/acpica/acpi_machdep.c
  stable/8/sys/dev/acpica/acpi_cpu.c
  stable/8/sys/dev/acpica/acpi_ec.c
  stable/8/sys/dev/acpica/acpi_smbat.c
  stable/8/sys/dev/acpica/acpivar.h
  stable/8/sys/i386/acpica/acpi_machdep.c
Directory Properties:
  stable/8/share/man/man4/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)

Modified: stable/8/share/man/man4/acpi.4
==============================================================================
--- stable/8/share/man/man4/acpi.4	Fri Jun 29 21:24:56 2012	(r237822)
+++ stable/8/share/man/man4/acpi.4	Fri Jun 29 21:25:24 2012	(r237823)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 22, 2012
+.Dd May 4, 2012
 .Dt ACPI 4
 .Os
 .Sh NAME
@@ -198,6 +198,11 @@ entry for access after boot.
 Enables loading of a custom ACPI DSDT.
 .It Va acpi_dsdt_name
 Name of the DSDT table to load, if loading is enabled.
+.It Va debug.acpi.cpu_unordered
+Do not use the MADT to match ACPI Processor objects to CPUs.
+This is needed on a few systems with a buggy BIOS that does not use
+consistent processor IDs.
+Default is 0 (disabled).
 .It Va debug.acpi.disabled
 Selectively disables portions of ACPI for debugging purposes.
 .It Va debug.acpi.interpreter_slack

Modified: stable/8/sys/amd64/acpica/acpi_machdep.c
==============================================================================
--- stable/8/sys/amd64/acpica/acpi_machdep.c	Fri Jun 29 21:24:56 2012	(r237822)
+++ stable/8/sys/amd64/acpica/acpi_machdep.c	Fri Jun 29 21:25:24 2012	(r237823)
@@ -44,8 +44,6 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/nexusvar.h>
 
-SYSCTL_DECL(_debug_acpi);
-
 int acpi_resume_beep;
 TUNABLE_INT("debug.acpi.resume_beep", &acpi_resume_beep);
 SYSCTL_INT(_debug_acpi, OID_AUTO, resume_beep, CTLFLAG_RW, &acpi_resume_beep,

Modified: stable/8/sys/dev/acpica/acpi_cpu.c
==============================================================================
--- stable/8/sys/dev/acpica/acpi_cpu.c	Fri Jun 29 21:24:56 2012	(r237822)
+++ stable/8/sys/dev/acpica/acpi_cpu.c	Fri Jun 29 21:25:24 2012	(r237823)
@@ -121,6 +121,13 @@ struct acpi_cpu_device {
 #define PIIX4_STOP_BREAK_MASK	(PIIX4_BRLD_EN_IRQ0 | PIIX4_BRLD_EN_IRQ | PIIX4_BRLD_EN_IRQ8)
 #define PIIX4_PCNTRL_BST_EN	(1<<10)
 
+/* Allow users to ignore processor orders in MADT. */
+static int cpu_unordered;
+TUNABLE_INT("debug.acpi.cpu_unordered", &cpu_unordered);
+SYSCTL_INT(_debug_acpi, OID_AUTO, cpu_unordered, CTLFLAG_RDTUN,
+    &cpu_unordered, 0,
+    "Do not use the MADT to match ACPI Processor objects to CPUs.");
+
 /* Platform hardware resource information. */
 static uint32_t		 cpu_smi_cmd;	/* Value to write to SMI_CMD. */
 static uint8_t		 cpu_cst_cnt;	/* Indicate we are _CST aware. */
@@ -145,7 +152,7 @@ static int	acpi_cpu_probe(device_t dev);
 static int	acpi_cpu_attach(device_t dev);
 static int	acpi_cpu_suspend(device_t dev);
 static int	acpi_cpu_resume(device_t dev);
-static int	acpi_pcpu_get_id(uint32_t idx, uint32_t *acpi_id,
+static int	acpi_pcpu_get_id(device_t dev, uint32_t *acpi_id,
 		    uint32_t *cpu_id);
 static struct resource_list *acpi_cpu_get_rlist(device_t dev, device_t child);
 static device_t	acpi_cpu_add_child(device_t dev, u_int order, const char *name,
@@ -242,7 +249,7 @@ acpi_cpu_probe(device_t dev)
      */
     acpi_id = obj->Processor.ProcId;
     AcpiOsFree(obj);
-    if (acpi_pcpu_get_id(device_get_unit(dev), &acpi_id, &cpu_id) != 0)
+    if (acpi_pcpu_get_id(dev, &acpi_id, &cpu_id) != 0)
 	return (ENXIO);
 
     /*
@@ -433,36 +440,66 @@ acpi_cpu_resume(device_t dev)
 }
 
 /*
- * Find the nth present CPU and return its pc_cpuid as well as set the
- * pc_acpi_id from the most reliable source.
+ * Find the processor associated with a given ACPI ID.  By default,
+ * use the MADT to map ACPI IDs to APIC IDs and use that to locate a
+ * processor.  Some systems have inconsistent ASL and MADT however.
+ * For these systems the cpu_unordered tunable can be set in which
+ * case we assume that Processor objects are listed in the same order
+ * in both the MADT and ASL.
  */
 static int
-acpi_pcpu_get_id(uint32_t idx, uint32_t *acpi_id, uint32_t *cpu_id)
+acpi_pcpu_get_id(device_t dev, uint32_t *acpi_id, uint32_t *cpu_id)
 {
-    struct pcpu	*pcpu_data;
-    uint32_t	 i;
+    struct pcpu	*pc;
+    uint32_t	 i, idx;
 
     KASSERT(acpi_id != NULL, ("Null acpi_id"));
     KASSERT(cpu_id != NULL, ("Null cpu_id"));
+    idx = device_get_unit(dev);
+
+    /*
+     * If pc_acpi_id for CPU 0 is not initialized (e.g. a non-APIC
+     * UP box) use the ACPI ID from the first processor we find.
+     */
+    if (idx == 0 && mp_ncpus == 1) {
+	pc = pcpu_find(0);
+	if (pc->pc_acpi_id == 0xffffffff)
+	    pc->pc_acpi_id = *acpi_id;
+	*cpu_id = 0;
+	return (0);
+    }
+
     CPU_FOREACH(i) {
-	pcpu_data = pcpu_find(i);
-	KASSERT(pcpu_data != NULL, ("no pcpu data for %d", i));
-	if (idx-- == 0) {
-	    /*
-	     * If pc_acpi_id was not initialized (e.g., a non-APIC UP box)
-	     * override it with the value from the ASL.  Otherwise, if the
-	     * two don't match, prefer the MADT-derived value.  Finally,
-	     * return the pc_cpuid to reference this processor.
-	     */
-	    if (pcpu_data->pc_acpi_id == 0xffffffff)
-		pcpu_data->pc_acpi_id = *acpi_id;
-	    else if (pcpu_data->pc_acpi_id != *acpi_id)
-		*acpi_id = pcpu_data->pc_acpi_id;
-	    *cpu_id = pcpu_data->pc_cpuid;
-	    return (0);
+	pc = pcpu_find(i);
+	KASSERT(pc != NULL, ("no pcpu data for %d", i));
+	if (cpu_unordered) {
+	    if (idx-- == 0) {
+		/*
+		 * If pc_acpi_id doesn't match the ACPI ID from the
+		 * ASL, prefer the MADT-derived value.
+		 */
+		if (pc->pc_acpi_id != *acpi_id)
+		    *acpi_id = pc->pc_acpi_id;
+		*cpu_id = pc->pc_cpuid;
+		return (0);
+	    }
+	} else {
+	    if (pc->pc_acpi_id == *acpi_id) {
+		if (bootverbose)
+		    device_printf(dev,
+			"Processor %s (ACPI ID %u) -> APIC ID %d\n",
+			acpi_name(acpi_get_handle(dev)), *acpi_id,
+			pc->pc_cpuid);
+		*cpu_id = pc->pc_cpuid;
+		return (0);
+	    }
 	}
     }
 
+    if (bootverbose)
+	printf("ACPI: Processor %s (ACPI ID %u) ignored\n",
+	    acpi_name(acpi_get_handle(dev)), *acpi_id);
+
     return (ESRCH);
 }
 

Modified: stable/8/sys/dev/acpica/acpi_ec.c
==============================================================================
--- stable/8/sys/dev/acpica/acpi_ec.c	Fri Jun 29 21:24:56 2012	(r237822)
+++ stable/8/sys/dev/acpica/acpi_ec.c	Fri Jun 29 21:25:24 2012	(r237823)
@@ -178,7 +178,6 @@ struct acpi_ec_softc {
 
 ACPI_SERIAL_DECL(ec, "ACPI embedded controller");
 
-SYSCTL_DECL(_debug_acpi);
 SYSCTL_NODE(_debug_acpi, OID_AUTO, ec, CTLFLAG_RD, NULL, "EC debugging");
 
 static int	ec_burst_mode;

Modified: stable/8/sys/dev/acpica/acpi_smbat.c
==============================================================================
--- stable/8/sys/dev/acpica/acpi_smbat.c	Fri Jun 29 21:24:56 2012	(r237822)
+++ stable/8/sys/dev/acpica/acpi_smbat.c	Fri Jun 29 21:25:24 2012	(r237823)
@@ -62,7 +62,6 @@ static int	acpi_smbat_get_bst(device_t d
 
 ACPI_SERIAL_DECL(smbat, "ACPI Smart Battery");
 
-SYSCTL_DECL(_debug_acpi);
 SYSCTL_NODE(_debug_acpi, OID_AUTO, batt, CTLFLAG_RD, NULL, "Battery debugging");
 
 /* On some laptops with smart batteries, enabling battery monitoring

Modified: stable/8/sys/dev/acpica/acpivar.h
==============================================================================
--- stable/8/sys/dev/acpica/acpivar.h	Fri Jun 29 21:24:56 2012	(r237822)
+++ stable/8/sys/dev/acpica/acpivar.h	Fri Jun 29 21:25:24 2012	(r237823)
@@ -475,5 +475,7 @@ ACPI_HANDLE	acpi_GetReference(ACPI_HANDL
 /* Use the device logging level for ktr(4). */
 #define	KTR_ACPI		KTR_DEV
 
+SYSCTL_DECL(_debug_acpi);
+
 #endif /* _KERNEL */
 #endif /* !_ACPIVAR_H_ */

Modified: stable/8/sys/i386/acpica/acpi_machdep.c
==============================================================================
--- stable/8/sys/i386/acpica/acpi_machdep.c	Fri Jun 29 21:24:56 2012	(r237822)
+++ stable/8/sys/i386/acpica/acpi_machdep.c	Fri Jun 29 21:25:24 2012	(r237823)
@@ -59,8 +59,6 @@ __FBSDID("$FreeBSD$");
 
 #include <i386/bios/apm.h>
 
-SYSCTL_DECL(_debug_acpi);
-
 uint32_t acpi_resume_beep;
 TUNABLE_INT("debug.acpi.resume_beep", &acpi_resume_beep);
 SYSCTL_UINT(_debug_acpi, OID_AUTO, resume_beep, CTLFLAG_RW, &acpi_resume_beep,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206292125.q5TLPOid071099>