+ /* Local interrupt assignment */
+ intsrc->type = MPT_TYPE_LOCAL_INT;
+ intsrc->irqtype = 3; /* ExtINT */
+ intsrc->irqflag = 0; /* PO, EL default */
+ intsrc->srcbus = isabusid; /* ISA */
+ intsrc->srcbusirq = 0;
+ intsrc->dstapic = 0; /* BSP == APIC #0 */
+ intsrc->dstirq = 0; /* LINTIN0 */
+ intsrc++;
+
+ intsrc->type = MPT_TYPE_LOCAL_INT;
+ intsrc->irqtype = 1; /* NMI */
+ intsrc->irqflag = 0; /* PO, EL default */
+ intsrc->srcbus = isabusid; /* ISA */
+ intsrc->srcbusirq = 0;
+ intsrc->dstapic = 0xff; /* to all local APICs */
+ intsrc->dstirq = 1; /* LINTIN1 */
+ intsrc++;
+ entrycount += intsrc - intsrcs;
+
+ // Finalize config structure.
+ int length = (void*)intsrc - (void*)config;
+ config->entrycount = entrycount;
+ config->length = length;
+ config->checksum -= checksum(config, length);
+
+ // Allocate final memory locations. (In theory the config
+ // structure can go in high memory, but Linux kernels before
+ // v2.6.30 crash with that.)
+ struct mptable_config_s *finalconfig = malloc_fseg(length);
+ struct mptable_floating_s *floating = malloc_fseg(sizeof(*floating));
+ if (!finalconfig || !floating) {
+ warn_noalloc();
+ free(config);
+ free(finalconfig);
+ free(floating);
+ return;
+ }
+ memcpy(finalconfig, config, length);
+ free(config);
+
+ /* floating pointer structure */
+ memset(floating, 0, sizeof(*floating));
+ floating->signature = MPTABLE_SIGNATURE;
+ floating->physaddr = (u32)finalconfig;
+ floating->length = 1;
+ floating->spec_rev = 4;
+ floating->checksum -= checksum(floating, sizeof(*floating));