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>