Index: dev/acpica/acpi.c =================================================================== --- dev/acpica/acpi.c (revision 235608) +++ dev/acpica/acpi.c (working copy) @@ -289,13 +289,6 @@ &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 @@ 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 @@ 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_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; Index: dev/acpica/acpi_cpu.c =================================================================== --- dev/acpica/acpi_cpu.c (revision 235608) +++ dev/acpica/acpi_cpu.c (working copy) @@ -124,6 +124,13 @@ #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_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_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 @@ } /* - * 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); }