summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Georgi <patrick@georgi-clan.de>2011-10-14 23:02:57 +0200
committerStefan Reinauer <stefan.reinauer@coreboot.org>2011-10-27 19:09:29 +0200
commit07b4215e11537bcbef3848bb520fa201fbcc4eda (patch)
tree12d1c409c17cbab6ba8a09a33f0f21311f0b33e4
parente572ef6136114c3cac09b061c6888e44d39d36a5 (diff)
downloadcoreboot-07b4215e11537bcbef3848bb520fa201fbcc4eda.tar.xz
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>
-rw-r--r--src/arch/x86/boot/mpspec.c15
-rw-r--r--src/mainboard/arima/hdama/mptable.c50
2 files changed, 12 insertions, 53 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;
+ }
+ }
}
}
diff --git a/src/mainboard/arima/hdama/mptable.c b/src/mainboard/arima/hdama/mptable.c
index 19bbf258a8..466ba882e6 100644
--- a/src/mainboard/arima/hdama/mptable.c
+++ b/src/mainboard/arima/hdama/mptable.c
@@ -11,54 +11,6 @@
#define HT_INIT_CONTROL 0x6c
#define HTIC_BIOSR_Detect (1<<5)
-/* If we assume a symmetric processor configuration we can
- * get all of the information we need to write the processor
- * entry from the bootstrap processor.
- * Plus I don't think linux really even cares.
- * Having the proper apicid's in the table so the non-bootstrap
- * processors can be woken up should be enough. Linux-2.6.11 work-around.
- */
-static void smp_write_processors_inorder(struct mp_config_table *mc)
-{
- int boot_apic_id;
- int order_id;
- unsigned apic_version;
- unsigned cpu_features;
- unsigned cpu_feature_flags;
- struct cpuid_result result;
- device_t cpu;
-
- boot_apic_id = lapicid();
- apic_version = lapic_read(LAPIC_LVR) & 0xff;
- result = cpuid(1);
- cpu_features = result.eax;
- cpu_feature_flags = result.edx;
- /* order the output of the cpus to fix a bug in kernel 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) ||
- (cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER))
- {
- continue;
- }
- if (!cpu->enabled) {
- continue;
- }
- cpu_flag = MPC_CPU_ENABLED;
- if (boot_apic_id == cpu->path.apic.apic_id) {
- cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
- }
- 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;
- }
- }
- }
-}
-
static unsigned node_link_to_bus(unsigned node, unsigned link)
{
device_t dev;
@@ -125,7 +77,7 @@ static void *smp_write_config_table(void *v)
mptable_init(mc, LAPIC_ADDR);
- smp_write_processors_inorder(mc);
+ smp_write_processors(mc);
apicid_base = max_apicid() + 1;
apicid_8111 = apicid_base;