Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b9b89e7 authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar
Browse files

x86: add apic probe for genapic 64bit, v2



introducing an APIC handling probing abstraction:

 static struct genapic *apic_probe[] __initdata = {
	&apic_x2apic_uv_x,
	&apic_x2apic_phys,
	&apic_x2apic_cluster,
	&apic_physflat,
	NULL,
 };

This way we can remove UV, x2apic specific code from genapic_64.c and
move them to their specific genapic files.

[ v2: fix compiling when CONFIG_ACPI is not set ]

Signed-off-by: default avatarYinghai Lu <yhlu.kernel@gmail.com>
Cc: Jack Steiner <steiner@sgi.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 76c3bb15
Loading
Loading
Loading
Loading
+26 −59
Original line number Original line Diff line number Diff line
@@ -16,63 +16,38 @@
#include <linux/ctype.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/hardirq.h>
#include <linux/hardirq.h>
#include <linux/dmar.h>


#include <asm/smp.h>
#include <asm/smp.h>
#include <asm/ipi.h>
#include <asm/ipi.h>
#include <asm/genapic.h>
#include <asm/genapic.h>


#ifdef CONFIG_ACPI
extern struct genapic apic_flat;
#include <acpi/acpi_bus.h>
extern struct genapic apic_physflat;
#endif
extern struct genapic apic_x2xpic_uv_x;

extern struct genapic apic_x2apic_phys;
DEFINE_PER_CPU(int, x2apic_extra_bits);
extern struct genapic apic_x2apic_cluster;


struct genapic __read_mostly *genapic = &apic_flat;
struct genapic __read_mostly *genapic = &apic_flat;


static int x2apic_phys = 0;
static struct genapic *apic_probe[] __initdata = {

	&apic_x2apic_uv_x,
static int set_x2apic_phys_mode(char *arg)
	&apic_x2apic_phys,
{
	&apic_x2apic_cluster,
	x2apic_phys = 1;
	&apic_physflat,
	return 0;
	NULL,
}
};
early_param("x2apic_phys", set_x2apic_phys_mode);

static enum uv_system_type uv_system_type;


/*
/*
 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
 */
 */
void __init setup_apic_routing(void)
void __init setup_apic_routing(void)
{
{
	if (uv_system_type == UV_NON_UNIQUE_APIC)
	if (genapic == &apic_flat) {
		genapic = &apic_x2apic_uv_x;
		if (max_physical_apicid >= 8)
	else if (cpu_has_x2apic && intr_remapping_enabled) {
		if (x2apic_phys)
			genapic = &apic_x2apic_phys;
		else
			genapic = &apic_x2apic_cluster;
	} else
#ifdef CONFIG_ACPI
	/*
	 * Quirk: some x86_64 machines can only use physical APIC mode
	 * regardless of how many processors are present (x86_64 ES7000
	 * is an example).
	 */
	if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
			(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
		genapic = &apic_physflat;
	else
#endif

	if (max_physical_apicid < 8)
		genapic = &apic_flat;
	else
			genapic = &apic_physflat;
			genapic = &apic_physflat;

		printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
		printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
	}
	}
}


/* Same for both flat and physical. */
/* Same for both flat and physical. */


@@ -83,23 +58,15 @@ void apic_send_IPI_self(int vector)


int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
{
	if (!strcmp(oem_id, "SGI")) {
	int i;
		if (!strcmp(oem_table_id, "UVL"))
			uv_system_type = UV_LEGACY_APIC;
		else if (!strcmp(oem_table_id, "UVX"))
			uv_system_type = UV_X2APIC;
		else if (!strcmp(oem_table_id, "UVH"))
			uv_system_type = UV_NON_UNIQUE_APIC;
	}
	return 0;
}


enum uv_system_type get_uv_system_type(void)
	for (i = 0; apic_probe[i]; ++i) {
{
		if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
	return uv_system_type;
			genapic = apic_probe[i];
			printk(KERN_INFO "Setting APIC routing to %s.\n",
				genapic->name);
			return 1;
		}
		}

	}
int is_uv_system(void)
	return 0;
{
	return uv_system_type != UV_NONE;
}
}
+26 −0
Original line number Original line Diff line number Diff line
@@ -21,6 +21,15 @@
#include <asm/genapic.h>
#include <asm/genapic.h>
#include <mach_apicdef.h>
#include <mach_apicdef.h>


#ifdef CONFIG_ACPI
#include <acpi/acpi_bus.h>
#endif

static int __init flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
	return 1;
}

static cpumask_t flat_target_cpus(void)
static cpumask_t flat_target_cpus(void)
{
{
	return cpu_online_map;
	return cpu_online_map;
@@ -138,6 +147,7 @@ static unsigned int phys_pkg_id(int index_msb)


struct genapic apic_flat =  {
struct genapic apic_flat =  {
	.name = "flat",
	.name = "flat",
	.acpi_madt_oem_check = flat_acpi_madt_oem_check,
	.int_delivery_mode = dest_LowestPrio,
	.int_delivery_mode = dest_LowestPrio,
	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
	.target_cpus = flat_target_cpus,
	.target_cpus = flat_target_cpus,
@@ -160,6 +170,21 @@ struct genapic apic_flat = {
 * We cannot use logical delivery in this case because the mask
 * We cannot use logical delivery in this case because the mask
 * overflows, so use physical mode.
 * overflows, so use physical mode.
 */
 */
static int __init physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
#ifdef CONFIG_ACPI
	/*
	 * Quirk: some x86_64 machines can only use physical APIC mode
	 * regardless of how many processors are present (x86_64 ES7000
	 * is an example).
	 */
	if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
		return 1;
#endif

	return 0;
}


static cpumask_t physflat_target_cpus(void)
static cpumask_t physflat_target_cpus(void)
{
{
@@ -206,6 +231,7 @@ static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)


struct genapic apic_physflat =  {
struct genapic apic_physflat =  {
	.name = "physical flat",
	.name = "physical flat",
	.acpi_madt_oem_check = physflat_acpi_madt_oem_check,
	.int_delivery_mode = dest_Fixed,
	.int_delivery_mode = dest_Fixed,
	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
	.target_cpus = physflat_target_cpus,
	.target_cpus = physflat_target_cpus,
+11 −0
Original line number Original line Diff line number Diff line
@@ -4,12 +4,22 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/ctype.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/dmar.h>

#include <asm/smp.h>
#include <asm/smp.h>
#include <asm/ipi.h>
#include <asm/ipi.h>
#include <asm/genapic.h>
#include <asm/genapic.h>


DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);


static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
	if (cpu_has_x2apic && intr_remapping_enabled)
		return 1;

	return 0;
}

/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */


static cpumask_t x2apic_target_cpus(void)
static cpumask_t x2apic_target_cpus(void)
@@ -135,6 +145,7 @@ static void init_x2apic_ldr(void)


struct genapic apic_x2apic_cluster = {
struct genapic apic_x2apic_cluster = {
	.name = "cluster x2apic",
	.name = "cluster x2apic",
	.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
	.int_delivery_mode = dest_LowestPrio,
	.int_delivery_mode = dest_LowestPrio,
	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
	.target_cpus = x2apic_target_cpus,
	.target_cpus = x2apic_target_cpus,
+21 −0
Original line number Original line Diff line number Diff line
@@ -4,10 +4,30 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/ctype.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/dmar.h>

#include <asm/smp.h>
#include <asm/smp.h>
#include <asm/ipi.h>
#include <asm/ipi.h>
#include <asm/genapic.h>
#include <asm/genapic.h>


DEFINE_PER_CPU(int, x2apic_extra_bits);

static int x2apic_phys;

static int set_x2apic_phys_mode(char *arg)
{
	x2apic_phys = 1;
	return 0;
}
early_param("x2apic_phys", set_x2apic_phys_mode);

static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
	if (cpu_has_x2apic && intr_remapping_enabled && x2apic_phys)
		return 1;

	return 0;
}


/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */


@@ -122,6 +142,7 @@ void init_x2apic_ldr(void)


struct genapic apic_x2apic_phys = {
struct genapic apic_x2apic_phys = {
	.name = "physical x2apic",
	.name = "physical x2apic",
	.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
	.int_delivery_mode = dest_Fixed,
	.int_delivery_mode = dest_Fixed,
	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
	.target_cpus = x2apic_target_cpus,
	.target_cpus = x2apic_target_cpus,
+31 −1
Original line number Original line Diff line number Diff line
@@ -27,6 +27,33 @@
#include <asm/uv/uv_hub.h>
#include <asm/uv/uv_hub.h>
#include <asm/uv/bios.h>
#include <asm/uv/bios.h>


static enum uv_system_type uv_system_type;

static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
	if (!strcmp(oem_id, "SGI")) {
		if (!strcmp(oem_table_id, "UVL"))
			uv_system_type = UV_LEGACY_APIC;
		else if (!strcmp(oem_table_id, "UVX"))
			uv_system_type = UV_X2APIC;
		else if (!strcmp(oem_table_id, "UVH")) {
			uv_system_type = UV_NON_UNIQUE_APIC;
			return 1;
		}
	}
	return 0;
}

enum uv_system_type get_uv_system_type(void)
{
	return uv_system_type;
}

int is_uv_system(void)
{
	return uv_system_type != UV_NONE;
}

DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);


@@ -153,7 +180,7 @@ static unsigned int get_apic_id(unsigned long x)
	return id;
	return id;
}
}


static long set_apic_id(unsigned int id)
static unsigned long set_apic_id(unsigned int id)
{
{
	unsigned long x;
	unsigned long x;


@@ -182,6 +209,7 @@ static void uv_send_IPI_self(int vector)


struct genapic apic_x2apic_uv_x = {
struct genapic apic_x2apic_uv_x = {
	.name = "UV large system",
	.name = "UV large system",
	.acpi_madt_oem_check = uv_acpi_madt_oem_check,
	.int_delivery_mode = dest_Fixed,
	.int_delivery_mode = dest_Fixed,
	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
	.target_cpus = uv_target_cpus,
	.target_cpus = uv_target_cpus,
@@ -433,3 +461,5 @@ void __cpuinit uv_cpu_init(void)
	if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
	if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
		set_x2apic_extra_bits(uv_hub_info->pnode);
		set_x2apic_extra_bits(uv_hub_info->pnode);
}
}

Loading