aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorRuss Anderson <rja@sgi.com>2010-10-26 17:27:28 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2010-10-26 18:15:28 -0400
commitc8f730b1ab825f06733e1c074264f0078721f365 (patch)
tree90f5b48ececb4020beeb3b6612e994f3e8f1f594 /arch/x86/kernel
parentb365a85c68161ea5db5476eb8845a91ceb1777ea (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.c25
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
42static enum uv_system_type uv_system_type; 42static enum uv_system_type uv_system_type;
43static u64 gru_start_paddr, gru_end_paddr; 43static u64 gru_start_paddr, gru_end_paddr;
44static union uvh_apicid uvh_apicid;
44int uv_min_hub_revision_id; 45int uv_min_hub_revision_id;
45EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); 46EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
46static DEFINE_SPINLOCK(uv_nmi_lock); 47static 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
74static 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
73static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) 90static 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;