/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2010 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <console/console.h>
#include <arch/smp/mpspec.h>
#include <device/pci.h>
#include <arch/io.h>
#include <string.h>
#include <stdint.h>
#include <cpu/amd/amdfam10_sysconf.h>

extern u8 bus_rs780[11];
extern u8 bus_sb700[2];

extern u32 apicid_sb700;

extern u32 sbdn_rs780;
extern u32 sbdn_sb700;

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

	mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);

	mptable_init(mc, LOCAL_APIC_ADDR);

	smp_write_processors(mc);

	get_bus_conf();

	mptable_write_buses(mc, NULL, &bus_isa);

	/* I/O APICs:   APIC ID Version State   Address */
	{
		device_t dev;
		u32 dword;
		u8 byte;

		dev =
		    dev_find_slot(bus_sb700[0],
				  PCI_DEVFN(sbdn_sb700 + 0x14, 0));
		if (dev) {
			dword = pci_read_config32(dev, 0x74) & 0xfffffff0;
			smp_write_ioapic(mc, apicid_sb700, 0x11, dword);

			/* Initialize interrupt mapping */
			/* aza */
			byte = pci_read_config8(dev, 0x63);
			byte &= 0xf8;
			byte |= 0;	/* 0: INTA, ...., 7: INTH */
			pci_write_config8(dev, 0x63, byte);

			/* SATA */
			dword = pci_read_config32(dev, 0xac);
			dword &= ~(7 << 26);
			dword |= 6 << 26;	/* 0: INTA, ...., 7: INTH */
			/* dword |= 1<<22; PIC and APIC co exists */
			pci_write_config32(dev, 0xac, dword);

			/*
			 * 00:12.0: PROG SATA : INT F
			 * 00:13.0: INTA USB_0
			 * 00:13.1: INTB USB_1
			 * 00:13.2: INTC USB_2
			 * 00:13.3: INTD USB_3
			 * 00:13.4: INTC USB_4
			 * 00:13.5: INTD USB2
			 * 00:14.1: INTA IDE
			 * 00:14.2: Prog HDA : INT E
			 * 00:14.5: INTB ACI
			 * 00:14.6: INTB MCI
			 */
		}
	}

	/* I/O Ints:    Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN# */
#define IO_LOCAL_INT(type, intr, apicid, pin) \
	smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin));

	mptable_add_isa_interrupts(mc, bus_isa, apicid_sb700, 0);

	/* PCI interrupts are level triggered, and are
	 * associated with a specific bus/device/function tuple.
	 */
#if !CONFIG_GENERATE_ACPI_TABLES
#define PCI_INT(bus, dev, fn, pin) \
        smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(fn)), apicid_sb700, (pin))
#else
#define PCI_INT(bus, dev, fn, pin)
#endif

	/* changes added to match acpi tables */
	PCI_INT(0x0, 0x02, 0x0, 0x12);
	PCI_INT(0x0, 0x03, 0x0, 0x13);
	PCI_INT(0x0, 0x04, 0x0, 0x10);
	PCI_INT(0x0, 0x09, 0x0, 0x11);
	PCI_INT(0x0, 0x0A, 0x0, 0x12);
	PCI_INT(0x0, 0x12, 0x2, 0x12);
	PCI_INT(0x0, 0x12, 0x3, 0x13);
	PCI_INT(0x0, 0x13, 0x2, 0x10);
	PCI_INT(0x0, 0x13, 0x2, 0x11);
	PCI_INT(0x0, 0x14, 0x1, 0x11);
	PCI_INT(0x0, 0x14, 0x3, 0x13);
	PCI_INT(0x1, 0x05, 0x2, 0x10);
	PCI_INT(0x1, 0x05, 0x3, 0x11);
	PCI_INT(0x2, 0x00, 0x0, 0x12);
	PCI_INT(0x2, 0x00, 0x1, 0x13);
	PCI_INT(0x2, 0x00, 0x2, 0x10);
	PCI_INT(0x2, 0x00, 0x3, 0x11);

	/*  RS780 PCI to PCI bridge (PCIE port 4) */
	PCI_INT(0x0, 0x09, 0x0, 0x11);

	/* usb */
	PCI_INT(0x0, 0x12, 0x0, 0x10);	/* USB */
	PCI_INT(0x0, 0x12, 0x1, 0x11);
	PCI_INT(0x0, 0x13, 0x0, 0x12);
	PCI_INT(0x0, 0x13, 0x1, 0x13);
	PCI_INT(0x0, 0x14, 0x0, 0x10);

	/* sata */
	PCI_INT(0x0, 0x11, 0x0, 0x16);

	/* HD Audio: b0:d20:f1:reg63 should be 0. */
	PCI_INT(0x0, 0x14, 0x2, 0x12);

	/* on board NIC & Slot PCIE.  */
	/* PCI_INT(bus_rs780[0x1], 0x5, 0x0, 0x12); */
	/* PCI_INT(bus_rs780[0x1], 0x5, 0x1, 0x13); */
	PCI_INT(0x1, 0x5, 0x0, 0x12);	/* VGA */
	PCI_INT(0x1, 0x5, 0x1, 0x13);	/* Audio */
	/* PCI_INT(bus_rs780[0x2], 0x0, 0x0, 0x12); *//* Dev 2, external GFX */
	/* PCI_INT(bus_rs780[0x3], 0x0, 0x0, 0x13); */
	/* PCI_INT(bus_rs780[0x4], 0x0, 0x0, 0x10); */
	/* configuration B doesnt need dev 5,6,7 */
	/*
	 * PCI_INT(bus_rs780[0x5], 0x0, 0x0, 0x11);
	 * PCI_INT(bus_rs780[0x6], 0x0, 0x0, 0x12);
	 * PCI_INT(bus_rs780[0x7], 0x0, 0x0, 0x13);
	 */
	/* PCI_INT(bus_rs780[0x9], 0x0, 0x0, 0x11); */
	PCI_INT(0x3, 0x0, 0x0, 0x11);	/* NIC */
	/* PCI_INT(bus_rs780[0xA], 0x0, 0x0, 0x12);  NIC */

	/* PCI slots */
	/* PCI_SLOT 0. */
	PCI_INT(bus_sb700[1], 0x5, 0x0, 0x14);
	PCI_INT(bus_sb700[1], 0x5, 0x1, 0x15);
	PCI_INT(bus_sb700[1], 0x5, 0x2, 0x16);
	PCI_INT(bus_sb700[1], 0x5, 0x3, 0x17);

	/* PCI_SLOT 1. */
	PCI_INT(bus_sb700[1], 0x6, 0x0, 0x15);
	PCI_INT(bus_sb700[1], 0x6, 0x1, 0x16);
	PCI_INT(bus_sb700[1], 0x6, 0x2, 0x17);
	PCI_INT(bus_sb700[1], 0x6, 0x3, 0x14);

	/* PCI_SLOT 2. */
	PCI_INT(bus_sb700[1], 0x7, 0x0, 0x16);
	PCI_INT(bus_sb700[1], 0x7, 0x1, 0x17);
	PCI_INT(bus_sb700[1], 0x7, 0x2, 0x14);
	PCI_INT(bus_sb700[1], 0x7, 0x3, 0x15);

	/*Local Ints:   Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN# */
	IO_LOCAL_INT(mp_ExtINT, 0x0, MP_APIC_ALL, 0x0);
	IO_LOCAL_INT(mp_NMI, 0x0, MP_APIC_ALL, 0x1);
	/* There is no extension information... */

	/* Compute the checksums */
	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);
}
