aboutsummaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/Kconfig4
-rw-r--r--src/arch/x86/include/arch/cpu.h24
-rw-r--r--src/arch/x86/lib/cpu.c20
3 files changed, 38 insertions, 10 deletions
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig
index 4dfbe70280..6d56ec6bfc 100644
--- a/src/arch/x86/Kconfig
+++ b/src/arch/x86/Kconfig
@@ -3,6 +3,10 @@ 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 0fe5ea58b7..0dc92fba9e 100644
--- a/src/arch/x86/include/arch/cpu.h
+++ b/src/arch/x86/include/arch/cpu.h
@@ -158,6 +158,30 @@ 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 7cd955ebb3..98ede068ef 100644
--- a/src/arch/x86/lib/cpu.c
+++ b/src/arch/x86/lib/cpu.c
@@ -9,7 +9,6 @@
#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)
@@ -235,7 +234,7 @@ static void set_cpu_ops(struct device *cpu)
cpu->ops = driver ? driver->ops : NULL;
}
-void cpu_initialize(struct bus *cpu_bus, int index)
+void cpu_initialize(void)
{
/* Because we busy wait at the printk spinlock.
* It is important to keep the number of printed messages
@@ -243,17 +242,17 @@ void cpu_initialize(struct bus *cpu_bus, int index)
* disabled.
*/
struct device *cpu;
+ struct cpu_info *info;
struct cpuinfo_x86 c;
- struct device_path cpu_path;
- unsigned char id = lapicid();
- cpu_path.type = DEVICE_PATH_APIC;
- cpu_path.apic.apic_id = id;
+ info = cpu_info();
- cpu = alloc_find_dev(cpu_bus, &cpu_path);
- cpu->path.apic.index = index;
+ printk(BIOS_INFO, "Initializing CPU #%ld\n", info->index);
- printk(BIOS_DEBUG, "Initializing CPU #%d\n", id);
+ cpu = info->cpu;
+ if (!cpu) {
+ die("CPU: missing cpu device structure");
+ }
/* Find what type of cpu we are dealing with */
identify_cpu(cpu);
@@ -277,6 +276,7 @@ void cpu_initialize(struct bus *cpu_bus, int index)
printk(BIOS_DEBUG, "Using generic cpu ops (good)\n");
}
+
/* Initialize the cpu */
if (cpu->ops && cpu->ops->init) {
cpu->enabled = 1;
@@ -284,7 +284,7 @@ void cpu_initialize(struct bus *cpu_bus, int index)
cpu->ops->init(cpu);
}
- printk(BIOS_INFO, "CPU #%d initialized\n", id);
+ printk(BIOS_INFO, "CPU #%ld initialized\n", info->index);
return;
}