diff options
author | Sven Schnelle <svens@stackframe.org> | 2012-07-29 19:18:03 +0200 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2012-07-31 06:46:02 +0200 |
commit | 51676b14e8cfd5bbabf487f659f11704f17f6d0f (patch) | |
tree | f75a6c5ba610385e2edb69a83223b98732ef0d09 /src/cpu/intel/hyperthreading | |
parent | a2701c60052df5544930a8dce8f01768834fdf28 (diff) |
Revert "Use broadcast SIPI to startup siblings"
This reverts commit 042c1461fb777e583e5de48edf9326e47ee5595f.
It turned out that sending IPIs via broadcast doesn't work on
Sandybridge. We tried to come up with a solution, but didn't
found any so far. So revert the code for now until we have
a working solution.
Change-Id: I7dd1cba5a4c1e4b0af366b20e8263b1f6f4b9714
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-on: http://review.coreboot.org/1381
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/cpu/intel/hyperthreading')
-rw-r--r-- | src/cpu/intel/hyperthreading/intel_sibling.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/cpu/intel/hyperthreading/intel_sibling.c b/src/cpu/intel/hyperthreading/intel_sibling.c index 8377cd0130..b9a9ae7bb1 100644 --- a/src/cpu/intel/hyperthreading/intel_sibling.c +++ b/src/cpu/intel/hyperthreading/intel_sibling.c @@ -7,6 +7,13 @@ #include <smp/spinlock.h> #include <assert.h> +#if !CONFIG_SERIAL_CPU_INIT +#error Intel hyper-threading requires serialized cpu init +#endif + +static int first_time = 1; +static int disable_siblings = !CONFIG_LOGICAL_CPUS; + /* Return true if running thread does not have the smallest lapic ID * within a CPU core. */ @@ -27,3 +34,61 @@ int intel_ht_sibling(void) threads = (apic_ids / core_ids); return !!(lapicid() & (threads-1)); } + +void intel_sibling_init(device_t cpu) +{ + unsigned i, siblings; + struct cpuid_result result; + + /* On the bootstrap processor see if I want sibling cpus enabled */ + if (first_time) { + first_time = 0; + get_option(&disable_siblings, "hyper_threading"); + } + result = cpuid(1); + /* Is hyperthreading supported */ + if (!(result.edx & (1 << 28))) { + return; + } + /* See how many sibling cpus we have */ + siblings = (result.ebx >> 16) & 0xff; + if (siblings < 1) { + siblings = 1; + } + + printk(BIOS_DEBUG, "CPU: %u %d siblings\n", + cpu->path.apic.apic_id, + siblings); + + /* See if I am a sibling cpu */ + if (cpu->path.apic.apic_id & (siblings -1)) { + if (disable_siblings) { + cpu->enabled = 0; + } + return; + } + + /* I am the primary cpu start up my siblings */ + for(i = 1; i < siblings; i++) { + struct device_path cpu_path; + device_t new; + /* Build the cpu device path */ + cpu_path.type = DEVICE_PATH_APIC; + cpu_path.apic.apic_id = cpu->path.apic.apic_id + i; + + + /* Allocate new cpu device structure iff sibling CPU + * was not in static device tree. + */ + new = alloc_find_dev(cpu->bus, &cpu_path); + + if (!new) { + continue; + } + + printk(BIOS_DEBUG, "CPU: %u has sibling %u\n", + cpu->path.apic.apic_id, + new->path.apic.apic_id); + } +} + |