mirror of https://gitee.com/openkylin/linux.git
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: Yinghai Lu <yhlu.kernel@gmail.com> Cc: Jack Steiner <steiner@sgi.com> Cc: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
76c3bb15d6
commit
1b9b89e7f1
|
@ -16,62 +16,37 @@
|
|||
#include <linux/ctype.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/dmar.h>
|
||||
|
||||
#include <asm/smp.h>
|
||||
#include <asm/ipi.h>
|
||||
#include <asm/genapic.h>
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
#include <acpi/acpi_bus.h>
|
||||
#endif
|
||||
|
||||
DEFINE_PER_CPU(int, x2apic_extra_bits);
|
||||
extern struct genapic apic_flat;
|
||||
extern struct genapic apic_physflat;
|
||||
extern struct genapic apic_x2xpic_uv_x;
|
||||
extern struct genapic apic_x2apic_phys;
|
||||
extern struct genapic apic_x2apic_cluster;
|
||||
|
||||
struct genapic __read_mostly *genapic = &apic_flat;
|
||||
|
||||
static int x2apic_phys = 0;
|
||||
|
||||
static int set_x2apic_phys_mode(char *arg)
|
||||
{
|
||||
x2apic_phys = 1;
|
||||
return 0;
|
||||
}
|
||||
early_param("x2apic_phys", set_x2apic_phys_mode);
|
||||
|
||||
static enum uv_system_type uv_system_type;
|
||||
static struct genapic *apic_probe[] __initdata = {
|
||||
&apic_x2apic_uv_x,
|
||||
&apic_x2apic_phys,
|
||||
&apic_x2apic_cluster,
|
||||
&apic_physflat,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
|
||||
*/
|
||||
void __init setup_apic_routing(void)
|
||||
{
|
||||
if (uv_system_type == UV_NON_UNIQUE_APIC)
|
||||
genapic = &apic_x2apic_uv_x;
|
||||
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;
|
||||
|
||||
printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
|
||||
if (genapic == &apic_flat) {
|
||||
if (max_physical_apicid >= 8)
|
||||
genapic = &apic_physflat;
|
||||
printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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;
|
||||
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 "Setting APIC routing to %s.\n",
|
||||
genapic->name);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,15 @@
|
|||
#include <asm/genapic.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)
|
||||
{
|
||||
return cpu_online_map;
|
||||
|
@ -138,6 +147,7 @@ static unsigned int phys_pkg_id(int index_msb)
|
|||
|
||||
struct genapic apic_flat = {
|
||||
.name = "flat",
|
||||
.acpi_madt_oem_check = flat_acpi_madt_oem_check,
|
||||
.int_delivery_mode = dest_LowestPrio,
|
||||
.int_dest_mode = (APIC_DEST_LOGICAL != 0),
|
||||
.target_cpus = flat_target_cpus,
|
||||
|
@ -160,6 +170,21 @@ struct genapic apic_flat = {
|
|||
* We cannot use logical delivery in this case because the mask
|
||||
* 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)
|
||||
{
|
||||
|
@ -206,6 +231,7 @@ static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)
|
|||
|
||||
struct genapic apic_physflat = {
|
||||
.name = "physical flat",
|
||||
.acpi_madt_oem_check = physflat_acpi_madt_oem_check,
|
||||
.int_delivery_mode = dest_Fixed,
|
||||
.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
|
||||
.target_cpus = physflat_target_cpus,
|
||||
|
|
|
@ -4,12 +4,22 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/dmar.h>
|
||||
|
||||
#include <asm/smp.h>
|
||||
#include <asm/ipi.h>
|
||||
#include <asm/genapic.h>
|
||||
|
||||
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. */
|
||||
|
||||
static cpumask_t x2apic_target_cpus(void)
|
||||
|
@ -135,6 +145,7 @@ static void init_x2apic_ldr(void)
|
|||
|
||||
struct genapic apic_x2apic_cluster = {
|
||||
.name = "cluster x2apic",
|
||||
.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
|
||||
.int_delivery_mode = dest_LowestPrio,
|
||||
.int_dest_mode = (APIC_DEST_LOGICAL != 0),
|
||||
.target_cpus = x2apic_target_cpus,
|
||||
|
|
|
@ -4,10 +4,30 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/dmar.h>
|
||||
|
||||
#include <asm/smp.h>
|
||||
#include <asm/ipi.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. */
|
||||
|
||||
|
@ -122,6 +142,7 @@ void init_x2apic_ldr(void)
|
|||
|
||||
struct genapic apic_x2apic_phys = {
|
||||
.name = "physical x2apic",
|
||||
.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
|
||||
.int_delivery_mode = dest_Fixed,
|
||||
.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
|
||||
.target_cpus = x2apic_target_cpus,
|
||||
|
|
|
@ -27,6 +27,33 @@
|
|||
#include <asm/uv/uv_hub.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);
|
||||
EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
|
||||
|
||||
|
@ -153,7 +180,7 @@ static unsigned int get_apic_id(unsigned long x)
|
|||
return id;
|
||||
}
|
||||
|
||||
static long set_apic_id(unsigned int id)
|
||||
static unsigned long set_apic_id(unsigned int id)
|
||||
{
|
||||
unsigned long x;
|
||||
|
||||
|
@ -182,6 +209,7 @@ static void uv_send_IPI_self(int vector)
|
|||
|
||||
struct genapic apic_x2apic_uv_x = {
|
||||
.name = "UV large system",
|
||||
.acpi_madt_oem_check = uv_acpi_madt_oem_check,
|
||||
.int_delivery_mode = dest_Fixed,
|
||||
.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
|
||||
.target_cpus = uv_target_cpus,
|
||||
|
@ -433,3 +461,5 @@ void __cpuinit uv_cpu_init(void)
|
|||
if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
|
||||
set_x2apic_extra_bits(uv_hub_info->pnode);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
struct genapic {
|
||||
char *name;
|
||||
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
|
||||
u32 int_delivery_mode;
|
||||
u32 int_dest_mode;
|
||||
int (*apic_id_registered)(void);
|
||||
|
|
Loading…
Reference in New Issue