blob: 001fea81b2639a61f0fd4c8e50852f5ded2502c3 [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>
8
9static int first_time = 1;
10static int disable_siblings = !CONFIG_LOGICAL_CPUS;
11
12void intel_sibling_init(device_t cpu)
13{
14 unsigned i, siblings;
15 struct cpuid_result result;
16
17 /* On the bootstrap processor see if I want sibling cpus enabled */
18 if (first_time) {
19 first_time = 0;
20 get_option(&disable_siblings, "hyper_threading");
21 }
22 result = cpuid(1);
23 /* Is hypethreading supported */
24 if (!(result.edx & (1 << 28))) {
25 return;
26 }
27 /* See how many sibling cpus we have */
28 siblings = (result.ebx >> 16) & 0xff;
29 if (siblings < 1) {
30 siblings = 1;
31 }
32
33#if 1
34 printk_debug("CPU: %u %d siblings\n",
35 cpu->path.u.apic.apic_id,
36 siblings);
37#endif
38
39 /* See if I am a sibling cpu */
40 if (cpu->path.u.apic.apic_id & (siblings -1)) {
41 if (disable_siblings) {
42 cpu->enabled = 0;
43 }
44 return;
45 }
46
47 /* I am the primary cpu start up my siblings */
48 for(i = 1; i < siblings; i++) {
49 struct device_path cpu_path;
50 device_t new;
51 unsigned long count;
52 /* Build the cpu device path */
53 cpu_path.type = DEVICE_PATH_APIC;
54 cpu_path.u.apic.apic_id = cpu->path.u.apic.apic_id + i;
55
56
57 /* Allocate the new cpu device structure */
58 new = alloc_dev(cpu->bus, &cpu_path);
59
60 if (!new) {
61 continue;
62 }
63
64#if 1
65 printk_debug("CPU: %u has sibling %u\n",
66 cpu->path.u.apic.apic_id,
67 new->path.u.apic.apic_id);
68#endif
69 /* Start the new cpu */
70 start_cpu(new);
71 }
72
73}
74