/* Copyright 2003 Andi Kleen, SuSE Labs. 
 * Subject to the GNU Public License, v.2 
 * 
 * Generic x86 APIC driver probe layer.
 */  
#include <linux/config.h>
#include <linux/threads.h>
#include <linux/cpumask.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <asm/fixmap.h>
#include <asm/mpspec.h>
#include <asm/apicdef.h>
#include <asm/genapic.h>

extern struct genapic apic_summit;
extern struct genapic apic_bigsmp;
extern struct genapic apic_es7000;
extern struct genapic apic_default;

struct genapic *genapic = &apic_default;

struct genapic *apic_probe[] __initdata = { 
	&apic_summit,
	&apic_bigsmp, 
	&apic_es7000,
	&apic_default,	/* must be last */
	NULL,
};

void __init generic_apic_probe(char *command_line) 
{ 
	char *s;
	int i;
	int changed = 0;

	s = strstr(command_line, "apic=");
	if (s && (s == command_line || isspace(s[-1]))) { 
		char *p = strchr(s, ' '), old; 
		if (!p)
			p = strchr(s, '\0'); 
		old = *p; 
		*p = 0; 
		for (i = 0; !changed && apic_probe[i]; i++) {
			if (!strcmp(apic_probe[i]->name, s+5)) { 
				changed = 1;
				genapic = apic_probe[i];
			}
		}
		if (!changed)
			printk(KERN_ERR "Unknown genapic `%s' specified.\n", s);
		*p = old;
	} 
	for (i = 0; !changed && apic_probe[i]; i++) { 
		if (apic_probe[i]->probe()) {
			changed = 1;
			genapic = apic_probe[i]; 
		} 
	}
	/* Not visible without early console */ 
	if (!changed) 
		panic("Didn't find an APIC driver"); 

	printk(KERN_INFO "Using APIC driver %s\n", genapic->name);
} 

/* These functions can switch the APIC even after the initial ->probe() */

int __init mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid)
{ 
	int i;
	for (i = 0; apic_probe[i]; ++i) { 
		if (apic_probe[i]->mps_oem_check(mpc,oem,productid)) { 
			genapic = apic_probe[i];
			printk(KERN_INFO "Switched to APIC driver `%s'.\n", 
			       genapic->name);
			return 1;
		} 
	} 
	return 0;
} 

int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
	int i;
	for (i = 0; apic_probe[i]; ++i) { 
		if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) { 
			genapic = apic_probe[i];
			printk(KERN_INFO "Switched to APIC driver `%s'.\n", 
			       genapic->name);
			return 1;
		} 
	} 
	return 0;	
}

int hard_smp_processor_id(void)
{
	return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID));
}
