Fill out ChromeOS specific coreboot table extensions
[coreboot.git] / src / arch / x86 / boot / mpspec.c
index 604f1918e2c2d7b9e91381e1c9d8ae104156aa61..e7d767b7ac61a156fbfb4d26bebc943e72955a81 100644 (file)
@@ -40,7 +40,7 @@ void mptable_init(struct mp_config_table *mc, u32 lapic_addr)
                mc->mpc_productid[i] = ' ';
 }
 
-unsigned char smp_compute_checksum(void *v, int len)
+static unsigned char smp_compute_checksum(void *v, int len)
 {
        unsigned char *bytes;
        unsigned char checksum;
@@ -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;
+               }
+            }
        }
 }
 
@@ -260,7 +267,7 @@ void smp_write_intsrc_pci_bridge(struct mp_config_table *mc,
                                smp_write_intsrc_pci_bridge(mc, irqtype, irqflag, child, dstapic, dstirq_x);
                        }
 
-               next:
+next:
                        child = child->sibling;
                }
 
@@ -396,3 +403,10 @@ void mptable_write_buses(struct mp_config_table *mc, int *max_pci_bus, int *isa_
        smp_write_bus(mc, *isa_bus, "ISA   ");
 }
 
+void *mptable_finalize(struct mp_config_table *mc)
+{
+       mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+       mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+       printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc));
+       return smp_next_mpe_entry(mc);
+}