diff options
author | Russ Anderson <rja@sgi.com> | 2010-10-26 17:27:28 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2010-10-26 18:15:28 -0400 |
commit | c8f730b1ab825f06733e1c074264f0078721f365 (patch) | |
tree | 90f5b48ececb4020beeb3b6612e994f3e8f1f594 /arch/x86/kernel | |
parent | b365a85c68161ea5db5476eb8845a91ceb1777ea (diff) |
x86, uv: Enable Westmere support on SGI UV
Enable Westmere support on SGI UV. The UV initialization code is dependent on
the APICID bits. Westmere-EX uses different APIC bit mapping than Nehalem-EX.
This code reads the apic shift value from a UV MMR to do the proper bit
decoding to determint the pnode.
Signed-off-by: Russ Anderson <rja@sgi.com>
LKML-Reference: <20101026212728.GB15071@sgi.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index f744f54cb248..0a2918eaab34 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * SGI UV APIC functions (note: not an Intel compatible APIC) | 6 | * SGI UV APIC functions (note: not an Intel compatible APIC) |
7 | * | 7 | * |
8 | * Copyright (C) 2007-2009 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | #include <linux/cpumask.h> | 10 | #include <linux/cpumask.h> |
11 | #include <linux/hardirq.h> | 11 | #include <linux/hardirq.h> |
@@ -41,6 +41,7 @@ DEFINE_PER_CPU(int, x2apic_extra_bits); | |||
41 | 41 | ||
42 | static enum uv_system_type uv_system_type; | 42 | static enum uv_system_type uv_system_type; |
43 | static u64 gru_start_paddr, gru_end_paddr; | 43 | static u64 gru_start_paddr, gru_end_paddr; |
44 | static union uvh_apicid uvh_apicid; | ||
44 | int uv_min_hub_revision_id; | 45 | int uv_min_hub_revision_id; |
45 | EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); | 46 | EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); |
46 | static DEFINE_SPINLOCK(uv_nmi_lock); | 47 | static DEFINE_SPINLOCK(uv_nmi_lock); |
@@ -70,6 +71,22 @@ static int early_get_nodeid(void) | |||
70 | return node_id.s.node_id; | 71 | return node_id.s.node_id; |
71 | } | 72 | } |
72 | 73 | ||
74 | static int __init early_get_apic_pnode_shift(void) | ||
75 | { | ||
76 | unsigned long *mmr; | ||
77 | |||
78 | mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_APICID, sizeof(*mmr)); | ||
79 | uvh_apicid.v = *mmr; | ||
80 | early_iounmap(mmr, sizeof(*mmr)); | ||
81 | if (!uvh_apicid.v) | ||
82 | /* | ||
83 | * Old bios, use default value | ||
84 | */ | ||
85 | uvh_apicid.s.pnode_shift = UV_APIC_PNODE_SHIFT; | ||
86 | |||
87 | return uvh_apicid.s.pnode_shift; | ||
88 | } | ||
89 | |||
73 | static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 90 | static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
74 | { | 91 | { |
75 | int nodeid; | 92 | int nodeid; |
@@ -84,7 +101,7 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
84 | uv_system_type = UV_X2APIC; | 101 | uv_system_type = UV_X2APIC; |
85 | else if (!strcmp(oem_table_id, "UVH")) { | 102 | else if (!strcmp(oem_table_id, "UVH")) { |
86 | __get_cpu_var(x2apic_extra_bits) = | 103 | __get_cpu_var(x2apic_extra_bits) = |
87 | nodeid << (UV_APIC_PNODE_SHIFT - 1); | 104 | nodeid << (early_get_apic_pnode_shift() - 1); |
88 | uv_system_type = UV_NON_UNIQUE_APIC; | 105 | uv_system_type = UV_NON_UNIQUE_APIC; |
89 | return 1; | 106 | return 1; |
90 | } | 107 | } |
@@ -716,6 +733,10 @@ void __init uv_system_init(void) | |||
716 | int apicid = per_cpu(x86_cpu_to_apicid, cpu); | 733 | int apicid = per_cpu(x86_cpu_to_apicid, cpu); |
717 | 734 | ||
718 | nid = cpu_to_node(cpu); | 735 | nid = cpu_to_node(cpu); |
736 | /* | ||
737 | * apic_pnode_shift must be set before calling uv_apicid_to_pnode(); | ||
738 | */ | ||
739 | uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; | ||
719 | pnode = uv_apicid_to_pnode(apicid); | 740 | pnode = uv_apicid_to_pnode(apicid); |
720 | blade = boot_pnode_to_blade(pnode); | 741 | blade = boot_pnode_to_blade(pnode); |
721 | lcpu = uv_blade_info[blade].nr_possible_cpus; | 742 | lcpu = uv_blade_info[blade].nr_possible_cpus; |