summaryrefslogtreecommitdiff
path: root/src/cpu/intel
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
parenta2701c60052df5544930a8dce8f01768834fdf28 (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')
-rw-r--r--src/cpu/intel/hyperthreading/intel_sibling.c65
-rw-r--r--src/cpu/intel/model_1067x/model_1067x_init.c4
-rw-r--r--src/cpu/intel/model_106cx/Kconfig4
-rw-r--r--src/cpu/intel/model_106cx/model_106cx_init.c4
-rw-r--r--src/cpu/intel/model_206ax/Kconfig1
-rw-r--r--src/cpu/intel/model_206ax/acpi.c9
-rw-r--r--src/cpu/intel/model_206ax/model_206ax_init.c55
-rw-r--r--src/cpu/intel/model_6ex/Kconfig1
-rw-r--r--src/cpu/intel/model_6ex/model_6ex_init.c3
-rw-r--r--src/cpu/intel/model_6fx/Kconfig1
-rw-r--r--src/cpu/intel/model_6fx/model_6fx_init.c3
-rw-r--r--src/cpu/intel/model_f2x/model_f2x_init.c3
-rw-r--r--src/cpu/intel/model_f3x/model_f3x_init.c3
-rw-r--r--src/cpu/intel/model_f4x/model_f4x_init.c3
-rw-r--r--src/cpu/intel/socket_LGA771/Kconfig1
15 files changed, 152 insertions, 8 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);
+ }
+}
+
diff --git a/src/cpu/intel/model_1067x/model_1067x_init.c b/src/cpu/intel/model_1067x/model_1067x_init.c
index ddd1381a55..c6d716d958 100644
--- a/src/cpu/intel/model_1067x/model_1067x_init.c
+++ b/src/cpu/intel/model_1067x/model_1067x_init.c
@@ -29,6 +29,7 @@
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/speedstep.h>
+#include <cpu/intel/hyperthreading.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/name.h>
@@ -220,6 +221,9 @@ static void model_1067x_init(device_t cpu)
/* PIC thermal sensor control */
configure_pic_thermal_sensors();
+
+ /* Start up my cpu siblings */
+ intel_sibling_init(cpu);
}
static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_106cx/Kconfig b/src/cpu/intel/model_106cx/Kconfig
index 2ef7392ab9..103ed50d3e 100644
--- a/src/cpu/intel/model_106cx/Kconfig
+++ b/src/cpu/intel/model_106cx/Kconfig
@@ -3,12 +3,10 @@ config CPU_INTEL_MODEL_106CX
select SMP
select SSE2
select UDELAY_LAPIC
-
-if CPU_INTEL_MODEL_106CX
+ select AP_IN_SIPI_WAIT
config CPU_ADDR_BITS
int
default 32
-endif
diff --git a/src/cpu/intel/model_106cx/model_106cx_init.c b/src/cpu/intel/model_106cx/model_106cx_init.c
index 8d2ef3d84f..4bf2924fed 100644
--- a/src/cpu/intel/model_106cx/model_106cx_init.c
+++ b/src/cpu/intel/model_106cx/model_106cx_init.c
@@ -27,6 +27,7 @@
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/speedstep.h>
+#include <cpu/intel/hyperthreading.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/name.h>
#include <usbdebug.h>
@@ -177,6 +178,9 @@ static void model_106cx_init(device_t cpu)
configure_misc();
/* TODO: PIC thermal sensor control */
+
+ /* Start up my cpu siblings */
+ intel_sibling_init(cpu);
}
static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_206ax/Kconfig b/src/cpu/intel/model_206ax/Kconfig
index a8419d53ec..9cc6edd94e 100644
--- a/src/cpu/intel/model_206ax/Kconfig
+++ b/src/cpu/intel/model_206ax/Kconfig
@@ -13,6 +13,7 @@ config CPU_SPECIFIC_OPTIONS
select UDELAY_LAPIC
select SMM_TSEG
select MICROCODE_IN_CBFS
+ #select AP_IN_SIPI_WAIT
config BOOTBLOCK_CPU_INIT
string
diff --git a/src/cpu/intel/model_206ax/acpi.c b/src/cpu/intel/model_206ax/acpi.c
index f66df51a2a..c8c30a4986 100644
--- a/src/cpu/intel/model_206ax/acpi.c
+++ b/src/cpu/intel/model_206ax/acpi.c
@@ -26,7 +26,6 @@
#include <arch/acpigen.h>
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
-#include <cpu/x86/lapic.h>
#include <cpu/intel/acpi.h>
#include <cpu/intel/speedstep.h>
#include <cpu/intel/turbo.h>
@@ -89,8 +88,8 @@ static int generate_cstate_entries(acpi_cstate_t *cstates,
static int generate_C_state_entries(void)
{
+ struct cpu_info *info;
struct cpu_driver *cpu;
- struct device *cpu_dev;
int len, lenif;
device_t lapic;
struct cpu_intel_model_206ax_config *conf = NULL;
@@ -104,10 +103,10 @@ static int generate_C_state_entries(void)
return 0;
/* Find CPU map of supported C-states */
- cpu_dev = dev_find_lapic(lapicid());
- if (!cpu_dev)
+ info = cpu_info();
+ if (!info)
return 0;
- cpu = find_cpu_driver(cpu_dev);
+ cpu = find_cpu_driver(info->cpu);
if (!cpu || !cpu->cstates)
return 0;
diff --git a/src/cpu/intel/model_206ax/model_206ax_init.c b/src/cpu/intel/model_206ax/model_206ax_init.c
index 2ad8012edf..9676ad175b 100644
--- a/src/cpu/intel/model_206ax/model_206ax_init.c
+++ b/src/cpu/intel/model_206ax/model_206ax_init.c
@@ -430,6 +430,58 @@ static void configure_mca(void)
static unsigned ehci_debug_addr;
#endif
+/*
+ * Initialize any extra cores/threads in this package.
+ */
+static void intel_cores_init(device_t cpu)
+{
+ struct cpuid_result result;
+ unsigned cores, threads, i;
+
+ result = cpuid_ext(0xb, 0); /* Threads per core */
+ threads = result.ebx & 0xff;
+
+ result = cpuid_ext(0xb, 1); /* Cores per package */
+ cores = result.ebx & 0xff;
+
+ /* Only initialize extra cores from BSP */
+ if (cpu->path.apic.apic_id)
+ return;
+
+ printk(BIOS_DEBUG, "CPU: %u has %u cores %u threads\n",
+ cpu->path.apic.apic_id, cores, threads);
+
+ for (i = 1; i < cores; ++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;
+
+ /* Update APIC ID if no hyperthreading */
+ if (threads == 1)
+ cpu_path.apic.apic_id <<= 1;
+
+ /* Allocate the new cpu device structure */
+ new = alloc_dev(cpu->bus, &cpu_path);
+ if (!new)
+ continue;
+
+ printk(BIOS_DEBUG, "CPU: %u has core %u\n",
+ cpu->path.apic.apic_id,
+ new->path.apic.apic_id);
+
+ /* Start the new cpu */
+ if (!start_cpu(new)) {
+ /* Record the error in cpu? */
+ printk(BIOS_ERR, "CPU %u would not start!\n",
+ new->path.apic.apic_id);
+ }
+ }
+}
+
static void model_206ax_init(device_t cpu)
{
char processor_name[49];
@@ -491,6 +543,9 @@ static void model_206ax_init(device_t cpu)
/* Enable Turbo */
enable_turbo();
+
+ /* Start up extra cores */
+ intel_cores_init(cpu);
}
static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_6ex/Kconfig b/src/cpu/intel/model_6ex/Kconfig
index c3faa39b06..31d24bd68f 100644
--- a/src/cpu/intel/model_6ex/Kconfig
+++ b/src/cpu/intel/model_6ex/Kconfig
@@ -3,3 +3,4 @@ config CPU_INTEL_MODEL_6EX
select SMP
select SSE2
select UDELAY_LAPIC
+ select AP_IN_SIPI_WAIT
diff --git a/src/cpu/intel/model_6ex/model_6ex_init.c b/src/cpu/intel/model_6ex/model_6ex_init.c
index a0afd2e4c7..1c8c72b3f0 100644
--- a/src/cpu/intel/model_6ex/model_6ex_init.c
+++ b/src/cpu/intel/model_6ex/model_6ex_init.c
@@ -205,6 +205,9 @@ static void model_6ex_init(device_t cpu)
/* PIC thermal sensor control */
configure_pic_thermal_sensors();
+
+ /* Start up my cpu siblings */
+ intel_sibling_init(cpu);
}
static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_6fx/Kconfig b/src/cpu/intel/model_6fx/Kconfig
index 065cdd9756..851685cb06 100644
--- a/src/cpu/intel/model_6fx/Kconfig
+++ b/src/cpu/intel/model_6fx/Kconfig
@@ -3,3 +3,4 @@ config CPU_INTEL_MODEL_6FX
select SMP
select SSE2
select UDELAY_LAPIC
+ select AP_IN_SIPI_WAIT
diff --git a/src/cpu/intel/model_6fx/model_6fx_init.c b/src/cpu/intel/model_6fx/model_6fx_init.c
index c5d7a6b21e..106719ea7b 100644
--- a/src/cpu/intel/model_6fx/model_6fx_init.c
+++ b/src/cpu/intel/model_6fx/model_6fx_init.c
@@ -243,6 +243,9 @@ static void model_6fx_init(device_t cpu)
/* PIC thermal sensor control */
configure_pic_thermal_sensors();
+
+ /* Start up my cpu siblings */
+ intel_sibling_init(cpu);
}
static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_f2x/model_f2x_init.c b/src/cpu/intel/model_f2x/model_f2x_init.c
index fa9e05f0b6..8fd8abc7bf 100644
--- a/src/cpu/intel/model_f2x/model_f2x_init.c
+++ b/src/cpu/intel/model_f2x/model_f2x_init.c
@@ -60,6 +60,9 @@ static void model_f2x_init(device_t cpu)
/* Enable the local cpu apics */
setup_lapic();
+
+ /* Start up my cpu siblings */
+ intel_sibling_init(cpu);
};
static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_f3x/model_f3x_init.c b/src/cpu/intel/model_f3x/model_f3x_init.c
index dd2a45f3c7..2504ba9423 100644
--- a/src/cpu/intel/model_f3x/model_f3x_init.c
+++ b/src/cpu/intel/model_f3x/model_f3x_init.c
@@ -43,6 +43,9 @@ static void model_f3x_init(device_t cpu)
/* Enable the local cpu apics */
setup_lapic();
+
+ /* Start up my cpu siblings */
+ intel_sibling_init(cpu);
};
static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/model_f4x/model_f4x_init.c b/src/cpu/intel/model_f4x/model_f4x_init.c
index af7d9d2176..f3f0b2af0f 100644
--- a/src/cpu/intel/model_f4x/model_f4x_init.c
+++ b/src/cpu/intel/model_f4x/model_f4x_init.c
@@ -51,6 +51,9 @@ static void model_f4x_init(device_t cpu)
/* Enable the local cpu apics */
setup_lapic();
+
+ /* Start up my cpu siblings */
+ intel_sibling_init(cpu);
};
static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/intel/socket_LGA771/Kconfig b/src/cpu/intel/socket_LGA771/Kconfig
index f549210d25..62bd17b1fe 100644
--- a/src/cpu/intel/socket_LGA771/Kconfig
+++ b/src/cpu/intel/socket_LGA771/Kconfig
@@ -3,3 +3,4 @@ config CPU_INTEL_SOCKET_LGA771
select CPU_INTEL_MODEL_6FX
select SSE2
select MMX
+ select AP_IN_SIPI_WAIT