mptable: Refactor mptable generation some more
[coreboot.git] / src / arch / x86 / boot / mpspec.c
index 70bc5401fdda72ef7d4e4c04e399d03391455d1f..209e0bbdbd8c3b8d690bfb39f1e42bba6e326adf 100644 (file)
@@ -8,20 +8,17 @@
 #include <cpu/x86/lapic.h>
 
 /* Initialize the specified "mc" struct with initial values. */
-void mptable_init(struct mp_config_table *mc, const char *productid,
-                 u32 lapic_addr)
+void mptable_init(struct mp_config_table *mc, u32 lapic_addr)
 {
-       /* Error out if 'product_id' length doesn't match exactly. */
-       if (strlen(productid) != 12)
-               die("ERROR: 'productid' must be 12 bytes long!");
+       int i;
 
        memset(mc, 0, sizeof(*mc));
+
        memcpy(mc->mpc_signature, MPC_SIGNATURE, 4);
+
        mc->mpc_length = sizeof(*mc);   /* Initially just the header size. */
        mc->mpc_spec = 0x04;            /* MultiProcessor specification 1.4 */
        mc->mpc_checksum = 0;           /* Not yet computed. */
-       memcpy(mc->mpc_oem, "COREBOOT", 8);
-       memcpy(mc->mpc_productid, productid, 12);
        mc->mpc_oemptr = 0;
        mc->mpc_oemsize = 0;
        mc->mpc_entry_count = 0;        /* No entries yet... */
@@ -29,9 +26,21 @@ void mptable_init(struct mp_config_table *mc, const char *productid,
        mc->mpe_length = 0;
        mc->mpe_checksum = 0;
        mc->reserved = 0;
+
+       strncpy(mc->mpc_oem, CONFIG_MAINBOARD_VENDOR, 8);
+       strncpy(mc->mpc_productid, CONFIG_MAINBOARD_PART_NUMBER, 12);
+
+       /*
+        * The oem/productid fields are exactly 8/12 bytes long. If the resp.
+        * entry is shorter, the remaining bytes are filled with spaces.
+        */
+       for (i = MIN(strlen(CONFIG_MAINBOARD_VENDOR), 8); i < 8; i++)
+               mc->mpc_oem[i] = ' ';
+       for (i = MIN(strlen(CONFIG_MAINBOARD_PART_NUMBER), 12); i < 12; i++)
+               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;
@@ -44,14 +53,7 @@ unsigned char smp_compute_checksum(void *v, int len)
        return checksum;
 }
 
-void *smp_write_floating_table(unsigned long addr)
-{
-       /* 16 byte align the table address */
-       addr = (addr + 0xf) & (~0xf);
-       return smp_write_floating_table_physaddr(addr, addr + SMP_FLOATING_TABLE_LEN);
-}
-
-void *smp_write_floating_table_physaddr(unsigned long addr, unsigned long mpf_physptr)
+static void *smp_write_floating_table_physaddr(unsigned long addr, unsigned long mpf_physptr, unsigned int virtualwire)
 {
         struct intel_mp_floating *mf;
         void *v;
@@ -67,7 +69,7 @@ void *smp_write_floating_table_physaddr(unsigned long addr, unsigned long mpf_ph
         mf->mpf_specification = 4;
         mf->mpf_checksum = 0;
         mf->mpf_feature1 = 0;
-        mf->mpf_feature2 = 0;
+        mf->mpf_feature2 = virtualwire?MP_FEATURE_VIRTUALWIRE:0;
         mf->mpf_feature3 = 0;
         mf->mpf_feature4 = 0;
         mf->mpf_feature5 = 0;
@@ -75,6 +77,13 @@ void *smp_write_floating_table_physaddr(unsigned long addr, unsigned long mpf_ph
         return v;
 }
 
+void *smp_write_floating_table(unsigned long addr, unsigned int virtualwire)
+{
+       /* 16 byte align the table address */
+       addr = (addr + 0xf) & (~0xf);
+       return smp_write_floating_table_physaddr(addr, addr + SMP_FLOATING_TABLE_LEN, virtualwire);
+}
+
 void *smp_next_mpc_entry(struct mp_config_table *mc)
 {
        void *v;
@@ -326,6 +335,12 @@ void smp_write_compatibility_address_space(struct mp_config_table *mc,
        smp_add_mpe_entry(mc, (mpe_t)mpe);
 }
 
+void mptable_lintsrc(struct mp_config_table *mc, unsigned long bus_isa)
+{
+       smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0);
+       smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1);
+}
+
 void mptable_add_isa_interrupts(struct mp_config_table *mc, unsigned long bus_isa, unsigned long apicid, int external_int2)
 {
 /*I/O Ints:                   Type         Trigger            Polarity         Bus ID   IRQ  APIC ID   PIN# */
@@ -381,3 +396,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);
+}