svn commit: r235834 - head/sys/dev/acpica

John Baldwin jhb at FreeBSD.org
Wed May 23 13:45:53 UTC 2012


Author: jhb
Date: Wed May 23 13:45:52 2012
New Revision: 235834
URL: http://svn.freebsd.org/changeset/base/235834

Log:
  Rework the previous change to honor MADT processor IDs when probing
  processor objects.  Instead of forcing the new-bus CPU objects to use
  a unit number equal to pc_cpuid, adjust acpi_pcpu_get_id() to honor the
  MADT IDs by default.  As with the previous change, setting
  debug.acpi.cpu_unordered to 1 in the loader will revert to the old
  behavior.
  
  Tested by:	jimharris
  MFC after:	1 month

Modified:
  head/sys/dev/acpica/acpi.c
  head/sys/dev/acpica/acpi_cpu.c

Modified: head/sys/dev/acpica/acpi.c
==============================================================================
--- head/sys/dev/acpica/acpi.c	Wed May 23 13:41:12 2012	(r235833)
+++ head/sys/dev/acpica/acpi.c	Wed May 23 13:45:52 2012	(r235834)
@@ -289,13 +289,6 @@ 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);
 
@@ -1863,15 +1856,11 @@ 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;
-    u_int cpuid;
-    int order, unit;
+    int order;
 
     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 
@@ -1909,31 +1898,6 @@ 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
@@ -1944,7 +1908,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, unit);
+	    child = BUS_ADD_CHILD(bus, order, NULL, -1);
 	    if (child == NULL)
 		break;
 

Modified: head/sys/dev/acpica/acpi_cpu.c
==============================================================================
--- head/sys/dev/acpica/acpi_cpu.c	Wed May 23 13:41:12 2012	(r235833)
+++ head/sys/dev/acpica/acpi_cpu.c	Wed May 23 13:45:52 2012	(r235834)
@@ -124,6 +124,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. */
@@ -148,7 +155,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,
@@ -245,7 +252,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);
 
     /*
@@ -436,36 +443,64 @@ 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, "(ACPI ID %u) -> APIC ID %d\n",
+			*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);
 }
 


More information about the svn-src-all mailing list