/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2007 AMD
 * Written by Yinghai Lu <yinghailu@amd.com> for AMD.
 * Copyright (C) 2009 Harald Gutmann <harald.gutmann@gmx.net>
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 <string.h>
#include <stdint.h>
#include <cpu/amd/amdk8_sysconf.h>

extern unsigned char bus_mcp55[8]; //1

extern unsigned apicid_mcp55;

static void *smp_write_config_table(void *v)
{
        struct mp_config_table *mc;
	unsigned sbdn;
	int i, j, k, bus_isa;

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

	mptable_init(mc, LOCAL_APIC_ADDR);

        smp_write_processors(mc);

	get_bus_conf();
	sbdn = sysconf.sbdn;

	mptable_write_buses(mc, NULL, &bus_isa);

/*I/O APICs:	APIC ID	Version	State		Address*/
        {
                device_t dev;
		struct resource *res;

                dev = dev_find_slot(bus_mcp55[0], PCI_DEVFN(sbdn+ 0x1,0));
                if (dev) {
			res = find_resource(dev, PCI_BASE_ADDRESS_1);
			if (res) {
				smp_write_ioapic(mc, apicid_mcp55, 0x11, res->base);
			}
			/* set up the interrupt registers of mcp55 */
	        	pci_write_config32(dev, 0x7c, 0xc643c643);
		        pci_write_config32(dev, 0x80, 0x8da01009);
		        pci_write_config32(dev, 0x84, 0x200018d2);
                }
	}

	mptable_add_isa_interrupts(mc, bus_isa, apicid_mcp55, 0);

/* PCI interrupts are level triggered, and are
 * associated with a specific bus/device/function tuple.
 */
#define PCI_INT(bus, dev, fn, pin)					\
	smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,\
			 bus_mcp55[bus], (((dev)<<2)|(fn)), apicid_mcp55, (pin))

	PCI_INT(0,sbdn+1,1, 10); /* SMBus */
	PCI_INT(0,sbdn+2,0, 22); /* USB */
	PCI_INT(0,sbdn+2,1, 23); /* USB */
	PCI_INT(0,sbdn+4,0, 21); /* IDE */
	PCI_INT(0,sbdn+5,0, 20); /* SATA */
	PCI_INT(0,sbdn+5,1, 21); /* SATA */
	PCI_INT(0,sbdn+5,2, 22); /* SATA */
	PCI_INT(0,sbdn+6,1, 23); /* HD Audio */
	PCI_INT(0,sbdn+8,0, 20); /* GBit Ethernet */

	/* The PCIe slots, each on its own bus */
        k = 1;
        for(i=0; i<4; i++){
                for(j=7; j>1; j--){
                        if(k>3) k=0;
                        PCI_INT(j,0,i, 16+k);
                        k++;
                }
                k--;
        }

	/* On bus 1: the PCI bus slots...
	   physical PCI slots are j = 7,8
	   FireWire is j = 10
	*/
        k=2;
        for(i=0; i<4; i++){
                for(j=6; j<11; j++){
                        if(k>3) k=0;
                        PCI_INT(1,j,i, 16+k);
                        k++;
                }
        }

/*Local Ints:	Type	Polarity    Trigger	Bus ID	 IRQ	APIC ID	PIN#*/
	mptable_lintsrc(mc, bus_isa);
	/* 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);
}
