From 51676b14e8cfd5bbabf487f659f11704f17f6d0f Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Sun, 29 Jul 2012 19:18:03 +0200 Subject: 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 Reviewed-on: http://review.coreboot.org/1381 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich --- src/cpu/intel/hyperthreading/intel_sibling.c | 65 ++++++++++++++++++++++++++++ src/cpu/intel/model_1067x/model_1067x_init.c | 4 ++ src/cpu/intel/model_106cx/Kconfig | 4 +- src/cpu/intel/model_106cx/model_106cx_init.c | 4 ++ src/cpu/intel/model_206ax/Kconfig | 1 + src/cpu/intel/model_206ax/acpi.c | 9 ++-- src/cpu/intel/model_206ax/model_206ax_init.c | 55 +++++++++++++++++++++++ src/cpu/intel/model_6ex/Kconfig | 1 + src/cpu/intel/model_6ex/model_6ex_init.c | 3 ++ src/cpu/intel/model_6fx/Kconfig | 1 + src/cpu/intel/model_6fx/model_6fx_init.c | 3 ++ src/cpu/intel/model_f2x/model_f2x_init.c | 3 ++ src/cpu/intel/model_f3x/model_f3x_init.c | 3 ++ src/cpu/intel/model_f4x/model_f4x_init.c | 3 ++ src/cpu/intel/socket_LGA771/Kconfig | 1 + 15 files changed, 152 insertions(+), 8 deletions(-) (limited to 'src/cpu/intel') 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 #include +#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 #include #include +#include #include #include @@ -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 #include #include +#include #include #include #include @@ -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 #include #include -#include #include #include #include @@ -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 -- cgit v1.2.3