/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2014 Sage Electronic Engineering, LLC.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <console/console.h>
#include <device/path.h>
#include <device/pci_ids.h>
#include <arch/smp/mpspec.h>
#include <string.h>
#include <arch/cpu.h>
#include <cpu/x86/lapic.h>
#include <drivers/generic/ioapic/chip.h>

/* Initialize the specified "mc" struct with initial values. */
void mptable_init(struct mp_config_table *mc, u32 lapic_addr)
{
	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. */
	mc->mpc_oemptr = 0;
	mc->mpc_oemsize = 0;
	mc->mpc_entry_count = 0;	/* No entries yet... */
	mc->mpc_lapic = lapic_addr;
	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] = ' ';
}

static unsigned char smp_compute_checksum(void *v, int len)
{
	unsigned char *bytes;
	unsigned char checksum;
	int i;
	bytes = v;
	checksum = 0;
	for (i = 0; i < len; i++)
		checksum -= bytes[i];
	return checksum;
}

static void *smp_write_floating_table_physaddr(uintptr_t addr,
	uintptr_t mpf_physptr, unsigned int virtualwire)
{
	struct intel_mp_floating *mf;
	void *v;

	v = (void *)addr;
	mf = v;
	mf->mpf_signature[0] = '_';
	mf->mpf_signature[1] = 'M';
	mf->mpf_signature[2] = 'P';
	mf->mpf_signature[3] = '_';
	mf->mpf_physptr = mpf_physptr;
	mf->mpf_length = 1;
	mf->mpf_specification = 4;
	mf->mpf_checksum = 0;
	mf->mpf_feature1 = 0;
	mf->mpf_feature2 = virtualwire?MP_FEATURE_PIC:MP_FEATURE_VIRTUALWIRE;
	mf->mpf_feature3 = 0;
	mf->mpf_feature4 = 0;
	mf->mpf_feature5 = 0;
	mf->mpf_checksum = smp_compute_checksum(mf, mf->mpf_length*16);
	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;
	v = (void *)(((char *)mc) + mc->mpc_length);

	return v;
}
static void smp_add_mpc_entry(struct mp_config_table *mc, u16 length)
{
	mc->mpc_length += length;
	mc->mpc_entry_count++;
}

void *smp_next_mpe_entry(struct mp_config_table *mc)
{
	void *v;
	v = (void *)(((char *)mc) + mc->mpc_length + mc->mpe_length);

	return v;
}
static void smp_add_mpe_entry(struct mp_config_table *mc, mpe_t mpe)
{
	mc->mpe_length += mpe->mpe_length;
}

/*
 * Type 0: Processor Entries:
 * Entry Type, LAPIC ID, LAPIC Version, CPU Flags EN/BP,
 * CPU Signature (Stepping, Model, Family), Feature Flags
 */
void smp_write_processor(struct mp_config_table *mc,
	u8 apicid, u8 apicver, u8 cpuflag,
	u32 cpufeature, u32 featureflag)
{
	struct mpc_config_processor *mpc;
	mpc = smp_next_mpc_entry(mc);
	memset(mpc, '\0', sizeof(*mpc));
	mpc->mpc_type = MP_PROCESSOR;
	mpc->mpc_apicid = apicid;
	mpc->mpc_apicver = apicver;
	mpc->mpc_cpuflag = cpuflag;
	mpc->mpc_cpufeature = cpufeature;
	mpc->mpc_featureflag = featureflag;
	smp_add_mpc_entry(mc, sizeof(*mpc));
}

/*
 * 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.
 */
void smp_write_processors(struct mp_config_table *mc)
{
	int boot_apic_id;
	int order_id;
	unsigned int apic_version;
	unsigned int cpu_features;
	unsigned int cpu_feature_flags;
	struct device *cpu;

	boot_apic_id = lapicid();
	apic_version = lapic_read(LAPIC_LVR) & 0xff;
	cpu_features = cpu_get_cpuid();
	cpu_feature_flags = cpu_get_feature_flags_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) ||
				(cpu->bus->dev->path.type !=
					DEVICE_PATH_CPU_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;
			}
		}
	}
}

/*
 * Type 1: Bus Entries:
 * Entry Type, Bus ID, Bus Type
 */
static void smp_write_bus(struct mp_config_table *mc,
	u8 id, const char *bustype)
{
	struct mpc_config_bus *mpc;
	mpc = smp_next_mpc_entry(mc);
	memset(mpc, '\0', sizeof(*mpc));
	mpc->mpc_type = MP_BUS;
	mpc->mpc_busid = id;
	memcpy(mpc->mpc_bustype, bustype, sizeof(mpc->mpc_bustype));
	smp_add_mpc_entry(mc, sizeof(*mpc));
}

/*
 * Type 2: I/O APIC Entries:
 * Entry Type, APIC ID, Version,
 * APIC Flags:EN, Address
 */
void smp_write_ioapic(struct mp_config_table *mc,
	u8 id, u8 ver, void *apicaddr)
{
	struct mpc_config_ioapic *mpc;
	mpc = smp_next_mpc_entry(mc);
	memset(mpc, '\0', sizeof(*mpc));
	mpc->mpc_type = MP_IOAPIC;
	mpc->mpc_apicid = id;
	mpc->mpc_apicver = ver;
	mpc->mpc_flags = MPC_APIC_USABLE;
	mpc->mpc_apicaddr = apicaddr;
	smp_add_mpc_entry(mc, sizeof(*mpc));
}

/*
 * Type 3: I/O Interrupt Table Entries:
 * Entry Type, Int Type, Int Polarity, Int Level,
 * Source Bus ID, Source Bus IRQ, Dest APIC ID, Dest PIN#
 */
void smp_write_intsrc(struct mp_config_table *mc,
	u8 irqtype, u16 irqflag,
	u8 srcbus, u8 srcbusirq,
	u8 dstapic, u8 dstirq)
{
	struct mpc_config_intsrc *mpc;
	mpc = smp_next_mpc_entry(mc);
	memset(mpc, '\0', sizeof(*mpc));
	mpc->mpc_type = MP_INTSRC;
	mpc->mpc_irqtype = irqtype;
	mpc->mpc_irqflag = irqflag;
	mpc->mpc_srcbus = srcbus;
	mpc->mpc_srcbusirq = srcbusirq;
	mpc->mpc_dstapic = dstapic;
	mpc->mpc_dstirq = dstirq;
	smp_add_mpc_entry(mc, sizeof(*mpc));
#ifdef DEBUG_MPTABLE
	printk(BIOS_DEBUG,
		"add intsrc srcbus 0x%x srcbusirq 0x%x, dstapic 0x%x, dstirq 0x%x\n",
				srcbus, srcbusirq, dstapic, dstirq);
	hexdump(__func__, mpc, sizeof(*mpc));
#endif
}

/*
 * Type 3: I/O Interrupt Table Entries for PCI Devices:
 * This has the same fields as 'Type 3: I/O Interrupt Table Entries'
 * but the Source Bus IRQ field has a slightly different
 * definition:
 * Bits 1-0: PIRQ pin: INT_A# = 0, INT_B# = 1, INT_C# = 2, INT_D# = 3
 * Bits 2-6: Originating PCI Device Number (Not its parent bridge device number)
 * Bit 7: Reserved
 */
void smp_write_pci_intsrc(struct mp_config_table *mc,
	u8 irqtype, u8 srcbus, u8 dev, u8 pirq,
	u8 dstapic, u8 dstirq)
{
	u8 srcbusirq = (dev << 2) | pirq;
	printk(BIOS_SPEW,
		"\tPCI srcbusirq = 0x%x from dev = 0x%x and pirq = %x\n",
		srcbusirq, dev, pirq);
	smp_write_intsrc(mc, irqtype, MP_IRQ_TRIGGER_LEVEL
		| MP_IRQ_POLARITY_LOW, srcbus, srcbusirq, dstapic, dstirq);
}

void smp_write_intsrc_pci_bridge(struct mp_config_table *mc,
	u8 irqtype, u16 irqflag, struct device *dev,
	unsigned char dstapic, unsigned char *dstirq)
{
	struct device *child;

	int i;
	int srcbus;
	int slot;

	struct bus *link;
	unsigned char dstirq_x[4];

	for (link = dev->link_list; link; link = link->next) {

		child = link->children;
		srcbus = link->secondary;

		while (child) {
			if (child->path.type != DEVICE_PATH_PCI)
				goto next;

			slot = (child->path.pci.devfn >> 3);
			/* round pins */
			for (i = 0; i < 4; i++)
				dstirq_x[i] = dstirq[(i + slot) % 4];

			if ((child->class >> 16) != PCI_BASE_CLASS_BRIDGE) {
				/* pci device */
				printk(BIOS_DEBUG, "route irq: %s\n",
					dev_path(child));
				for (i = 0; i < 4; i++)
					smp_write_intsrc(mc, irqtype, irqflag,
						srcbus, (slot<<2)|i, dstapic,
						dstirq_x[i]);
				goto next;
			}

			switch (child->class>>8) {
			case PCI_CLASS_BRIDGE_PCI:
			case PCI_CLASS_BRIDGE_PCMCIA:
			case PCI_CLASS_BRIDGE_CARDBUS:
				printk(BIOS_DEBUG, "route irq bridge: %s\n",
					dev_path(child));
				smp_write_intsrc_pci_bridge(mc, irqtype,
					irqflag, child, dstapic, dstirq_x);
			}

next:
			child = child->sibling;
		}

	}
}

/*
 * Type 4: Local Interrupt Assignment Entries:
 * Entry Type, Int Type, Int Polarity, Int Level,
 * Source Bus ID, Source Bus IRQ, Dest LAPIC ID,
 * Dest LAPIC LINTIN#
 */
void smp_write_lintsrc(struct mp_config_table *mc,
	u8 irqtype, u16 irqflag,
	u8 srcbusid, u8 srcbusirq,
	u8 destapic, u8 destapiclint)
{
	struct mpc_config_lintsrc *mpc;
	mpc = smp_next_mpc_entry(mc);
	memset(mpc, '\0', sizeof(*mpc));
	mpc->mpc_type = MP_LINTSRC;
	mpc->mpc_irqtype = irqtype;
	mpc->mpc_irqflag = irqflag;
	mpc->mpc_srcbusid = srcbusid;
	mpc->mpc_srcbusirq = srcbusirq;
	mpc->mpc_destapic = destapic;
	mpc->mpc_destapiclint = destapiclint;
	smp_add_mpc_entry(mc, sizeof(*mpc));
}

/*
 * Type 128: System Address Space Mapping Entries
 * Entry Type, Entry Length, Bus ID, Address Type,
 * Address Base Lo/Hi, Address Length Lo/Hi
 */
void smp_write_address_space(struct mp_config_table *mc,
	u8 busid, u8 address_type,
	u32 address_base_low, u32 address_base_high,
	u32 address_length_low, u32 address_length_high)
{
	struct mp_exten_system_address_space *mpe;
	mpe = smp_next_mpe_entry(mc);
	memset(mpe, '\0', sizeof(*mpe));
	mpe->mpe_type = MPE_SYSTEM_ADDRESS_SPACE;
	mpe->mpe_length = sizeof(*mpe);
	mpe->mpe_busid = busid;
	mpe->mpe_address_type = address_type;
	mpe->mpe_address_base_low  = address_base_low;
	mpe->mpe_address_base_high = address_base_high;
	mpe->mpe_address_length_low  = address_length_low;
	mpe->mpe_address_length_high = address_length_high;
	smp_add_mpe_entry(mc, (mpe_t)mpe);
}

/*
 * Type 129: Bus Hierarchy Descriptor Entry
 * Entry Type, Entry Length, Bus ID, Bus Info,
 * Parent Bus ID
 */
void smp_write_bus_hierarchy(struct mp_config_table *mc,
	u8 busid, u8 bus_info, u8 parent_busid)
{
	struct mp_exten_bus_hierarchy *mpe;
	mpe = smp_next_mpe_entry(mc);
	memset(mpe, '\0', sizeof(*mpe));
	mpe->mpe_type = MPE_BUS_HIERARCHY;
	mpe->mpe_length = sizeof(*mpe);
	mpe->mpe_busid = busid;
	mpe->mpe_bus_info = bus_info;
	mpe->mpe_parent_busid = parent_busid;
	smp_add_mpe_entry(mc, (mpe_t)mpe);
}

/*
 * Type 130: Compatibility Bus Address Space Modifier Entry
 * Entry Type, Entry Length, Bus ID, Address Modifier
 * Predefined Range List
 */
void smp_write_compatibility_address_space(struct mp_config_table *mc,
	u8 busid, u8 address_modifier,
	u32 range_list)
{
	struct mp_exten_compatibility_address_space *mpe;
	mpe = smp_next_mpe_entry(mc);
	memset(mpe, '\0', sizeof(*mpe));
	mpe->mpe_type = MPE_COMPATIBILITY_ADDRESS_SPACE;
	mpe->mpe_length = sizeof(*mpe);
	mpe->mpe_busid = busid;
	mpe->mpe_address_modifier = address_modifier;
	mpe->mpe_range_list = range_list;
	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# */
	smp_write_intsrc(mc, external_int2?mp_INT:mp_ExtINT,
				     MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0x0, apicid, 0x0);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0x1, apicid, 0x1);
	smp_write_intsrc(mc, external_int2?mp_ExtINT:mp_INT,
				     MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0x0, apicid, 0x2);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0x3, apicid, 0x3);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0x4, apicid, 0x4);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0x6, apicid, 0x6);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0x7, apicid, 0x7);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0x8, apicid, 0x8);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0x9, apicid, 0x9);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0xa, apicid, 0xa);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0xb, apicid, 0xb);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0xc, apicid, 0xc);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0xd, apicid, 0xd);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0xe, apicid, 0xe);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
				     bus_isa, 0xf, apicid, 0xf);
}

void mptable_write_buses(struct mp_config_table *mc, int *max_pci_bus,
	int *isa_bus)
{
	int dummy, i, highest;
	char buses[256];
	struct device *dev;

	if (!max_pci_bus)
		max_pci_bus = &dummy;
	if (!isa_bus)
		isa_bus = &dummy;

	*max_pci_bus = 0;
	highest = 0;
	memset(buses, 0, sizeof(buses));

	for (dev = all_devices; dev; dev = dev->next) {
		struct bus *bus;
		for (bus = dev->link_list; bus; bus = bus->next) {
			if (bus->secondary > 255) {
				printk(BIOS_ERR,
					"A bus claims to have a bus ID > 255?!? Aborting");
				return;
			}
			buses[bus->secondary] = 1;
			if (highest < bus->secondary)
				highest = bus->secondary;
		}
	}
	for (i = 0; i <= highest; i++) {
		if (buses[i]) {
			smp_write_bus(mc, i, "PCI   ");
			*max_pci_bus = i;
		}
	}
	*isa_bus = *max_pci_bus + 1;
	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);
}

static const struct device *find_next_ioapic(unsigned int last_ioapic_id)
{
	const struct device *dev;
	const struct device *result = NULL;
	unsigned int ioapic_id = MAX_APICS;

	for (dev = all_devices; dev; dev = dev->next) {
		if (dev->path.type == DEVICE_PATH_IOAPIC &&
		    dev->path.ioapic.ioapic_id > last_ioapic_id &&
		    dev->path.ioapic.ioapic_id <= ioapic_id) {
			result = dev;
		}
	}
	return result;
}

unsigned long __weak write_smp_table(unsigned long addr)
{
	struct drivers_generic_ioapic_config *ioapic_config;
	struct mp_config_table *mc;
	int isa_bus, pin, parentpin;
	const struct device *dev;
	const struct device *parent;
	const struct device *oldparent;
	void *tmp, *v;
	int isaioapic = -1, have_fixed_entries;
	const struct pci_irq_info *pci_irq_info;
	unsigned int ioapic_id = 0;

	v = smp_write_floating_table(addr, 0);
	mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);

	mptable_init(mc, LOCAL_APIC_ADDR);

	smp_write_processors(mc);

	mptable_write_buses(mc, NULL, &isa_bus);

	while ((dev = find_next_ioapic(ioapic_id))) {
		ioapic_config = dev->chip_info;
		if (!ioapic_config) {
			printk(BIOS_ERR, "%s has no config, ignoring\n",
				dev_path(dev));
			ioapic_id++;
			continue;
		}

		ioapic_id = dev->path.ioapic.ioapic_id;
		smp_write_ioapic(mc, ioapic_id,
				     ioapic_config->version,
				     ioapic_config->base);

		if (ioapic_config->have_isa_interrupts) {
			if (isaioapic >= 0)
				printk(BIOS_ERR,
					"More than one IOAPIC with ISA interrupts?\n");
			else
				isaioapic = dev->path.ioapic.ioapic_id;
		}
	}

	if (isaioapic >= 0) {
		/* Legacy Interrupts */
		printk(BIOS_DEBUG, "Writing ISA IRQs\n");
		mptable_add_isa_interrupts(mc, isa_bus, isaioapic, 0);
	}

	for (dev = all_devices; dev; dev = dev->next) {

		if (dev->path.type != DEVICE_PATH_PCI || !dev->enabled)
			continue;

		have_fixed_entries = 0;
		for (pin = 0; pin < 4; pin++) {
			if (dev->pci_irq_info[pin].ioapic_dst_id) {
				printk(BIOS_DEBUG,
					"fixed IRQ entry for: %s: INT%c# -> IOAPIC %d PIN %d\n",
						dev_path(dev),
				       pin + 'A',
				       dev->pci_irq_info[pin].ioapic_dst_id,
				       dev->pci_irq_info[pin].ioapic_irq_pin);
				smp_write_intsrc(mc, mp_INT,
					 dev->pci_irq_info[pin].ioapic_flags,
					 dev->bus->secondary,
					 ((dev->path.pci.devfn & 0xf8) >> 1)
						| pin,
					 dev->pci_irq_info[pin].ioapic_dst_id,
					 dev->pci_irq_info[pin].ioapic_irq_pin);
				have_fixed_entries = 1;
			}
		}

		if (!have_fixed_entries) {
			pin = (dev->path.pci.devfn & 7) % 4;
			oldparent = parent = dev;
			while ((parent = parent->bus->dev)) {
				parentpin = (oldparent->path.pci.devfn >> 3)
					+ (oldparent->path.pci.devfn & 7);
				parentpin += dev->path.pci.devfn & 7;
				parentpin += dev->path.pci.devfn >> 3;
				parentpin %= 4;

				pci_irq_info = &parent->pci_irq_info[parentpin];
				if (pci_irq_info->ioapic_dst_id) {
					printk(BIOS_DEBUG,
					       "automatic IRQ entry for %s: INT%c# -> IOAPIC %d PIN %d\n",
					       dev_path(dev), pin + 'A',
					       pci_irq_info->ioapic_dst_id,
					       pci_irq_info->ioapic_irq_pin);
					smp_write_intsrc(mc, mp_INT,
						 pci_irq_info->ioapic_flags,
						 dev->bus->secondary,
						 ((dev->path.pci.devfn & 0xf8)
							>> 1) | pin,
						 pci_irq_info->ioapic_dst_id,
						 pci_irq_info->ioapic_irq_pin);

					break;
				}

				if (parent->path.type == DEVICE_PATH_DOMAIN) {
					printk(BIOS_WARNING,
						"no IRQ found for %s\n",
						dev_path(dev));
					break;
				}
				oldparent = parent;
			}
		}
	}

	mptable_lintsrc(mc, isa_bus);
	tmp = mptable_finalize(mc);
	printk(BIOS_INFO, "MPTABLE len: %d\n", (unsigned int)((uintptr_t)tmp -
				(uintptr_t)v));
	return (unsigned long)tmp;
}
