/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2007 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 <cpu/cpu.h>
#include <cpu/x86/lapic.h>
#include <device/device.h>
#include <device/pci.h>
#include <pc80/mc146818rtc.h>
#include <smp/spinlock.h>
#include <cpu/x86/mtrr.h>
#include <cpu/amd/model_10xxx_msr.h>
#include <cpu/amd/model_10xxx_rev.h>
#include <cpu/amd/amdfam10_sysconf.h>

extern device_t get_node_pci(u32 nodeid, u32 fn);

#if 0
static int first_time = 1;
#endif

#include "quadcore_id.c"

static u32 get_max_siblings(u32 nodes)
{
	device_t dev;
	u32 nodeid;
	u32 siblings=0;

	//get max siblings from all the nodes
	for(nodeid=0; nodeid<nodes; nodeid++){
		int j;
		dev = get_node_pci(nodeid, 3);
		j = (pci_read_config32(dev, 0xe8) >> 12) & 3;
		if(siblings < j) {
			siblings = j;
		}
	}

	return siblings;
}


static void enable_apic_ext_id(u32 nodes)
{
	device_t dev;
	u32 nodeid;

	//enable APIC_EXIT_ID all the nodes
	for(nodeid=0; nodeid<nodes; nodeid++){
		u32 val;
		dev = get_node_pci(nodeid, 0);
		val = pci_read_config32(dev, 0x68);
		val |= (1<<17)|(1<<18);
		pci_write_config32(dev, 0x68, val);
	}
}


u32 get_apicid_base(u32 ioapic_num)
{
	u32 apicid_base;
	u32 siblings;
	u32 nb_cfg_54;

	u32 disable_siblings = !CONFIG_LOGICAL_CPUS;

	get_option(&disable_siblings, "multi_core");

	siblings = get_max_siblings(sysconf.nodes);

	if(sysconf.bsp_apicid > 0) { // io apic could start from 0
		return 0;
	} else if (sysconf.enabled_apic_ext_id)	{ // enabled ext id but bsp = 0
		return 1;
	}

	nb_cfg_54 = read_nb_cfg_54();


	//contruct apicid_base

	if((!disable_siblings) && (siblings>0) ) {
		/* for 8 way dual core, we will used up apicid 16:16, actualy
		   16 is not allowed by current kernel and the kernel will try
		   to get one that is small than 16 to make io apic work. I don't
		   know when the kernel can support 256 apic id.
		   (APIC_EXT_ID is enabled) */

		//4:10 for two way  8:12 for four way 16:16 for eight way
		//Use CONFIG_MAX_PHYSICAL_CPUS instead of nodes for better consistency?
		apicid_base = nb_cfg_54 ? (siblings+1) * sysconf.nodes :  8 * siblings + sysconf.nodes;

	} else {
		apicid_base = sysconf.nodes;
	}

	if((apicid_base+ioapic_num-1)>0xf) {
		// We need to enable APIC EXT ID
		printk(BIOS_SPEW, "if the IO APIC device doesn't support 256 apic id, \n you need to set CONFIG_ENABLE_APIC_EXT_ID in MB Option.lb so you can spare 16 id for ioapic\n");
		enable_apic_ext_id(sysconf.nodes);
	}

	return apicid_base;
}
