Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 May 2012 18:24:39 +0000 (UTC)
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r235024 - in head: share/man/man4 sys/dev/acpica
Message-ID:  <201205041824.q44IOdjw016990@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jkim
Date: Fri May  4 18:24:38 2012
New Revision: 235024
URL: http://svn.freebsd.org/changeset/base/235024

Log:
  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

Modified:
  head/share/man/man4/acpi.4
  head/sys/dev/acpica/acpi.c

Modified: head/share/man/man4/acpi.4
==============================================================================
--- head/share/man/man4/acpi.4	Fri May  4 18:23:03 2012	(r235023)
+++ head/share/man/man4/acpi.4	Fri May  4 18:24:38 2012	(r235024)
@@ -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: head/sys/dev/acpica/acpi.c
==============================================================================
--- head/sys/dev/acpica/acpi.c	Fri May  4 18:23:03 2012	(r235023)
+++ head/sys/dev/acpica/acpi.c	Fri May  4 18:24:38 2012	(r235024)
@@ -289,6 +289,13 @@ SYSCTL_INT(_debug_acpi, OID_AUTO, reset_
     &acpi_reset_clock, 1, "Reset system clock while resuming.");
 #endif
 
+/* Allow users to ignore processor orders in MADT. */
+static int acpi_cpu_unordered;
+TUNABLE_INT("debug.acpi.cpu_unordered", &acpi_cpu_unordered);
+SYSCTL_INT(_debug_acpi, OID_AUTO, cpu_unordered, CTLFLAG_RDTUN,
+    &acpi_cpu_unordered, 0,
+    "Do not use the MADT to match ACPI processor objects to CPUs.");
+
 /* Allow users to override quirks. */
 TUNABLE_INT("debug.acpi.quirks", &acpi_quirks);
 
@@ -1856,11 +1863,15 @@ static ACPI_STATUS
 acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
 {
     struct acpi_prw_data prw;
+    ACPI_BUFFER buf;
+    ACPI_OBJECT obj;
     ACPI_OBJECT_TYPE type;
     ACPI_HANDLE h;
+    struct pcpu *pc;
     device_t bus, child;
     char *handle_str;
-    int order;
+    u_int cpuid;
+    int order, unit;
 
     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 
@@ -1898,6 +1909,31 @@ acpi_probe_child(ACPI_HANDLE handle, UIN
 	case ACPI_TYPE_PROCESSOR:
 	case ACPI_TYPE_THERMAL:
 	case ACPI_TYPE_POWER:
+	    unit = -1;
+	    if (type == ACPI_TYPE_PROCESSOR && acpi_cpu_unordered == 0) {
+		ACPI_STATUS s;
+		buf.Pointer = &obj;
+		buf.Length = sizeof(obj);
+		s = AcpiEvaluateObject(handle, NULL, NULL, &buf);
+		if (ACPI_SUCCESS(s)) {
+		    CPU_FOREACH(cpuid) {
+			pc = pcpu_find(cpuid);
+			if (pc->pc_acpi_id == obj.Processor.ProcId) {
+			    unit = cpuid;
+			    if (bootverbose)
+				printf("ACPI: %s (ACPI ID %u) -> cpu%d\n",
+				    handle_str, obj.Processor.ProcId, unit);
+			    break;
+			}
+		    }
+		    if (unit == -1) {
+			if (bootverbose)
+			    printf("ACPI: %s (ACPI ID %u) ignored\n",
+				handle_str, obj.Processor.ProcId);
+			break;
+		    }
+		}
+	    }
 	    /* 
 	     * Create a placeholder device for this node.  Sort the
 	     * placeholder so that the probe/attach passes will run
@@ -1908,7 +1944,7 @@ acpi_probe_child(ACPI_HANDLE handle, UIN
 	    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n", handle_str));
 	    order = level * 10 + ACPI_DEV_BASE_ORDER;
 	    acpi_probe_order(handle, &order);
-	    child = BUS_ADD_CHILD(bus, order, NULL, -1);
+	    child = BUS_ADD_CHILD(bus, order, NULL, unit);
 	    if (child == NULL)
 		break;
 



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