summaryrefslogtreecommitdiff
path: root/src/cpu/intel/hyperthreading
diff options
context:
space:
mode:
authorSven Schnelle <svens@stackframe.org>2012-07-29 19:18:03 +0200
committerRonald G. Minnich <rminnich@gmail.com>2012-07-31 06:46:02 +0200
commit51676b14e8cfd5bbabf487f659f11704f17f6d0f (patch)
treef75a6c5ba610385e2edb69a83223b98732ef0d09 /src/cpu/intel/hyperthreading
parenta2701c60052df5544930a8dce8f01768834fdf28 (diff)
downloadcoreboot-51676b14e8cfd5bbabf487f659f11704f17f6d0f.tar.xz
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.c65
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);
+ }
+}
+