/* generated by MPTable, version 2.0.15*/
/* as modified by RGM for coreboot */
#include <console/console.h>
#include <arch/smp/mpspec.h>
#include <arch/ioapic.h>
#include <device/pci.h>
#include <string.h>
#include <stdint.h>

#define INTA 0x00
#define INTB 0x01
#define INTC 0x02
#define INTD 0x03

static void *smp_write_config_table(void *v)
{
	struct mp_config_table *mc;
	int isa_bus;

	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);
	/* I/O APICs: APIC ID  Version  State  Address */
	smp_write_ioapic(mc, 0x2, 0x20, 0xfec00000);

	mptable_add_isa_interrupts(mc, isa_bus, 0x2, 0);

	/* I/O Ints: Type  Polarity  Trigger  Bus ID  IRQ  APIC ID  PIN# */
	smp_write_intsrc(mc, mp_ExtINT,
			 MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 0x3, 0x0,
			 0x2, 0x0);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0x1, 0x2, 0x1);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0x0, 0x2, 0x2);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0x3, 0x2, 0x3);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0x4, 0x2, 0x4);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0x5, 0x2, 0x5);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0x6, 0x2, 0x6);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0x7, 0x2, 0x7);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0x8, 0x2, 0x8);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0x9, 0x2, 0x9);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0xa, 0x2, 0xa);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0xb, 0x2, 0xb);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0xc, 0x2, 0xc);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0xd, 0x2, 0xd);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0xe, 0x2, 0xe);
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
			 0x3, 0xf, 0x2, 0xf);
	/* Local Ints: Type  Polarity  Trigger  Bus ID  IRQ  APIC ID  PIN# */
	smp_write_lintsrc(mc, mp_ExtINT,
			  MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 0x3, 0x0,
			  MP_APIC_ALL, 0x0);
	smp_write_lintsrc(mc, mp_NMI,
			  MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 0x3, 0x0,
			  MP_APIC_ALL, 0x1);

	return mptable_finalize(mc);
}

unsigned long write_smp_table(unsigned long addr)
{
	void *v;
	v = smp_write_floating_table(addr, 0);
	return (unsigned long)smp_write_config_table(v);
}
