diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/Kconfig | 4 | ||||
-rw-r--r-- | src/arch/x86/include/arch/cpu.h | 24 | ||||
-rw-r--r-- | src/arch/x86/lib/cpu.c | 35 |
3 files changed, 22 insertions, 41 deletions
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig index 6d56ec6bfc..4dfbe70280 100644 --- a/src/arch/x86/Kconfig +++ b/src/arch/x86/Kconfig @@ -3,10 +3,6 @@ menu "Architecture (x86)" # This is an SMP option. It relates to starting up APs. # It is usually set in mainboard/*/Kconfig. # TODO: Improve description. -config AP_IN_SIPI_WAIT - bool - default n - depends on ARCH_X86 # Aligns 16bit entry code in bootblock so that hyper-threading CPUs # can boot AP CPUs to enable their shared caches. diff --git a/src/arch/x86/include/arch/cpu.h b/src/arch/x86/include/arch/cpu.h index 0dc92fba9e..0fe5ea58b7 100644 --- a/src/arch/x86/include/arch/cpu.h +++ b/src/arch/x86/include/arch/cpu.h @@ -158,30 +158,6 @@ struct cpu_driver { struct device; struct cpu_driver *find_cpu_driver(struct device *cpu); -struct cpu_info { - device_t cpu; - unsigned long index; -}; - -static inline struct cpu_info *cpu_info(void) -{ - struct cpu_info *ci; - __asm__("andl %%esp,%0; " - "orl %2, %0 " - :"=r" (ci) - : "0" (~(CONFIG_STACK_SIZE - 1)), - "r" (CONFIG_STACK_SIZE - sizeof(struct cpu_info)) - ); - return ci; -} - -static inline unsigned long cpu_index(void) -{ - struct cpu_info *ci; - ci = cpu_info(); - return ci->index; -} - struct cpuinfo_x86 { uint8_t x86; /* CPU family */ uint8_t x86_vendor; /* CPU vendor */ diff --git a/src/arch/x86/lib/cpu.c b/src/arch/x86/lib/cpu.c index 98ede068ef..2d64be95ba 100644 --- a/src/arch/x86/lib/cpu.c +++ b/src/arch/x86/lib/cpu.c @@ -9,6 +9,7 @@ #include <device/path.h> #include <device/device.h> #include <smp/spinlock.h> +#include <cpu/x86/lapic.h> /* Standard macro to see if a specific flag is changeable */ static inline int flag_is_changeable_p(uint32_t flag) @@ -234,7 +235,11 @@ static void set_cpu_ops(struct device *cpu) cpu->ops = driver ? driver->ops : NULL; } -void cpu_initialize(void) +#if CONFIG_SMP +static spinlock_t start_cpu_lock = SPIN_LOCK_UNLOCKED; +#endif + +void cpu_initialize(struct bus *cpu_bus, int index) { /* Because we busy wait at the printk spinlock. * It is important to keep the number of printed messages @@ -242,17 +247,22 @@ void cpu_initialize(void) * disabled. */ struct device *cpu; - struct cpu_info *info; struct cpuinfo_x86 c; - - info = cpu_info(); - - printk(BIOS_INFO, "Initializing CPU #%ld\n", info->index); - - cpu = info->cpu; - if (!cpu) { - die("CPU: missing cpu device structure"); - } + struct device_path cpu_path; + unsigned char id = lapicid(); + + cpu_path.type = DEVICE_PATH_APIC; + cpu_path.apic.apic_id = id; + cpu_path.apic.index = index; + +#if CONFIG_SMP + spin_lock(&start_cpu_lock); +#endif + cpu = alloc_find_dev(cpu_bus, &cpu_path); +#if CONFIG_SMP + spin_unlock(&start_cpu_lock); +#endif + printk(BIOS_DEBUG, "Initializing CPU #%d\n", id); /* Find what type of cpu we are dealing with */ identify_cpu(cpu); @@ -276,7 +286,6 @@ void cpu_initialize(void) printk(BIOS_DEBUG, "Using generic cpu ops (good)\n"); } - /* Initialize the cpu */ if (cpu->ops && cpu->ops->init) { cpu->enabled = 1; @@ -284,7 +293,7 @@ void cpu_initialize(void) cpu->ops->init(cpu); } - printk(BIOS_INFO, "CPU #%ld initialized\n", info->index); + printk(BIOS_INFO, "CPU #%d initialized\n", id); return; } |