/*
 * 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.
 */


#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/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();


	//Construct apicid_base

	if((!disable_siblings) && (siblings>0) ) {
		/* for 8 way dual core, we will used up apicid 16:16, actually
		   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;
}
