From 97d31723e73ab6e80b3d0d586fc9a9998c2e1b6e Mon Sep 17 00:00:00 2001 From: Nate Lawson Date: Sun, 27 Feb 2005 02:43:02 +0000 Subject: [PATCH] Make a pass through all drivers checking specs for desired behavior on SMP systems. It appears all drivers except ichss should attach to each CPU and that settings should be performed on each CPU. Add comments about this. Also, add a guard for p4tcc's identify method being called more than once. --- sys/dev/acpica/acpi_perf.c | 5 +++++ sys/dev/cpufreq/ichss.c | 6 +++++- sys/i386/cpufreq/est.c | 4 ++++ sys/i386/cpufreq/p4tcc.c | 11 +++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/sys/dev/acpica/acpi_perf.c b/sys/dev/acpica/acpi_perf.c index 23070006c0f..ab17a561cae 100644 --- a/sys/dev/acpica/acpi_perf.c +++ b/sys/dev/acpica/acpi_perf.c @@ -152,6 +152,11 @@ acpi_perf_identify(driver_t *driver, device_t parent) return; if (ACPI_FAILURE(AcpiEvaluateObject(handle, "_PSS", NULL, NULL))) return; + + /* + * Add a child to every CPU that has the right methods. In future + * versions of the ACPI spec, CPUs can have different settings. + */ if (BUS_ADD_CHILD(parent, 0, "acpi_perf", -1) == NULL) device_printf(parent, "add acpi_perf child failed\n"); } diff --git a/sys/dev/cpufreq/ichss.c b/sys/dev/cpufreq/ichss.c index b8d35421583..d38ed523482 100644 --- a/sys/dev/cpufreq/ichss.c +++ b/sys/dev/cpufreq/ichss.c @@ -166,7 +166,11 @@ ichss_pci_probe(device_t dev) if (devclass_get_device(ichss_devclass, 0)) return (ENXIO); - /* Add a child under the CPU parent. */ + /* + * Add a child under the CPU parent. It appears that ICH SpeedStep + * only requires a single CPU to set the value (since the chipset + * is shared by all CPUs.) Thus, we only add a child to cpu 0. + */ parent = devclass_get_device(devclass_find("cpu"), 0); KASSERT(parent != NULL, ("cpu parent is NULL")); child = BUS_ADD_CHILD(parent, 0, "ichss", 0); diff --git a/sys/i386/cpufreq/est.c b/sys/i386/cpufreq/est.c index 53b1cd73d2f..6239332b1d4 100644 --- a/sys/i386/cpufreq/est.c +++ b/sys/i386/cpufreq/est.c @@ -582,6 +582,10 @@ est_identify(driver_t *driver, device_t parent) if ((p[2] & 0x80) == 0) return; + /* + * We add a child for each CPU since settings must be performed + * on each CPU in the SMP case. + */ if (BUS_ADD_CHILD(parent, 0, "est", -1) == NULL) device_printf(parent, "add est child failed\n"); } diff --git a/sys/i386/cpufreq/p4tcc.c b/sys/i386/cpufreq/p4tcc.c index cff04fe6177..b8cf66e75d8 100644 --- a/sys/i386/cpufreq/p4tcc.c +++ b/sys/i386/cpufreq/p4tcc.c @@ -102,6 +102,17 @@ p4tcc_identify(driver_t *driver, device_t parent) if ((cpu_feature & (CPUID_ACPI | CPUID_TM)) != (CPUID_ACPI | CPUID_TM)) return; + + /* Make sure we're not being doubly invoked. */ + if (device_find_child(parent, "p4tcc", -1) != NULL) + return; + + /* + * We attach a p4tcc child for every CPU since settings need to + * be performed on every CPU in the SMP case. See section 13.15.3 + * of the IA32 Intel Architecture Software Developer's Manual, + * Volume 3, for more info. + */ if (BUS_ADD_CHILD(parent, 0, "p4tcc", -1) == NULL) device_printf(parent, "add p4tcc child failed\n"); }