blob: e988664ddaafdc28322bf459f4734d2e81be88a1 [file] [log] [blame]
Eric Biedermanfcd5ace2004-10-14 19:29:29 +00001#include <console/console.h>
2#include <cpu/cpu.h>
3#include <cpu/x86/lapic.h>
4#include <cpu/intel/hyperthreading.h>
5#include <device/device.h>
6#include <pc80/mc146818rtc.h>
7#include <smp/spinlock.h>
Kyösti Mälkki8b28d502012-03-09 17:02:37 +02008#include <assert.h>
9
10#if CONFIG_SERIAL_CPU_INIT==0
11#error Intel hyper-threading requires serialized cpu init
12#endif
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000013
14static int first_time = 1;
Luc Verhaegena9c5ea02009-06-03 14:19:33 +000015static int disable_siblings = !CONFIG_LOGICAL_CPUS;
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000016
17void intel_sibling_init(device_t cpu)
18{
19 unsigned i, siblings;
20 struct cpuid_result result;
21
22 /* On the bootstrap processor see if I want sibling cpus enabled */
23 if (first_time) {
24 first_time = 0;
Luc Verhaegena9c5ea02009-06-03 14:19:33 +000025 get_option(&disable_siblings, "hyper_threading");
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000026 }
27 result = cpuid(1);
Patrick Georgi6af0cb62009-04-22 08:07:31 +000028 /* Is hyperthreading supported */
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000029 if (!(result.edx & (1 << 28))) {
30 return;
31 }
32 /* See how many sibling cpus we have */
33 siblings = (result.ebx >> 16) & 0xff;
34 if (siblings < 1) {
35 siblings = 1;
36 }
37
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000038 printk(BIOS_DEBUG, "CPU: %u %d siblings\n",
Stefan Reinauer2b34db82009-02-28 20:10:20 +000039 cpu->path.apic.apic_id,
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000040 siblings);
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000041
42 /* See if I am a sibling cpu */
Stefan Reinauer2b34db82009-02-28 20:10:20 +000043 if (cpu->path.apic.apic_id & (siblings -1)) {
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000044 if (disable_siblings) {
45 cpu->enabled = 0;
46 }
47 return;
48 }
Stefan Reinauer14e22772010-04-27 06:56:47 +000049
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000050 /* I am the primary cpu start up my siblings */
51 for(i = 1; i < siblings; i++) {
52 struct device_path cpu_path;
53 device_t new;
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000054 /* Build the cpu device path */
55 cpu_path.type = DEVICE_PATH_APIC;
Stefan Reinauer2b34db82009-02-28 20:10:20 +000056 cpu_path.apic.apic_id = cpu->path.apic.apic_id + i;
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000057
58
Kyösti Mälkki8b28d502012-03-09 17:02:37 +020059 /* Allocate new cpu device structure iff sibling CPU
60 * was not in static device tree.
61 */
62 new = alloc_find_dev(cpu->bus, &cpu_path);
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000063
64 if (!new) {
65 continue;
66 }
67
Stefan Reinauer14e22772010-04-27 06:56:47 +000068 printk(BIOS_DEBUG, "CPU: %u has sibling %u\n",
Stefan Reinauer2b34db82009-02-28 20:10:20 +000069 cpu->path.apic.apic_id,
70 new->path.apic.apic_id);
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000071 }
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000072}
73