diff options
author | Patrick Georgi <patrick@georgi-clan.de> | 2011-10-14 23:02:57 +0200 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2011-10-27 19:09:29 +0200 |
commit | 07b4215e11537bcbef3848bb520fa201fbcc4eda (patch) | |
tree | 12d1c409c17cbab6ba8a09a33f0f21311f0b33e4 /src/arch/x86/boot | |
parent | e572ef6136114c3cac09b061c6888e44d39d36a5 (diff) |
Move linux 2.6.11 workaround to generic code
Linux 2.6.11 seems to require a certain order in CPUs listed in mptable,
so enforce it. This was only done on arima/hdama, but now is generic.
Unfortunately this is somewhat slow.
Change-Id: I85715ebae8a009cb816bc9ffd6372708f246bf66
Signed-off-by: Patrick Georgi <patrick@georgi-clan.de>
Reviewed-on: http://review.coreboot.org/280
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/arch/x86/boot')
-rw-r--r-- | src/arch/x86/boot/mpspec.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/arch/x86/boot/mpspec.c b/src/arch/x86/boot/mpspec.c index 209e0bbdbd..d519cfaacc 100644 --- a/src/arch/x86/boot/mpspec.c +++ b/src/arch/x86/boot/mpspec.c @@ -134,6 +134,7 @@ void smp_write_processor(struct mp_config_table *mc, void smp_write_processors(struct mp_config_table *mc) { int boot_apic_id; + int order_id; unsigned apic_version; unsigned cpu_features; unsigned cpu_feature_flags; @@ -145,6 +146,8 @@ void smp_write_processors(struct mp_config_table *mc) result = cpuid(1); cpu_features = result.eax; cpu_feature_flags = result.edx; + /* order the output of the cpus to fix a bug in kernel 2.6.11 */ + for(order_id = 0;order_id <256; order_id++) { for(cpu = all_devices; cpu; cpu = cpu->next) { unsigned long cpu_flag; if ((cpu->path.type != DEVICE_PATH_APIC) || @@ -159,10 +162,14 @@ void smp_write_processors(struct mp_config_table *mc) if (boot_apic_id == cpu->path.apic.apic_id) { cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR; } - smp_write_processor(mc, - cpu->path.apic.apic_id, apic_version, - cpu_flag, cpu_features, cpu_feature_flags - ); + if(cpu->path.apic.apic_id == order_id) { + smp_write_processor(mc, + cpu->path.apic.apic_id, apic_version, + cpu_flag, cpu_features, cpu_feature_flags + ); + break; + } + } } } |