aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
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
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')
-rw-r--r--arch/x86/include/asm/uv/uv_hub.h21
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c25
2 files changed, 41 insertions, 5 deletions
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index bf6b88ef8eeb..e969f691cbfd 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * SGI UV architectural definitions 6 * SGI UV architectural definitions
7 * 7 *
8 * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. 8 * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
9 */ 9 */
10 10
11#ifndef _ASM_X86_UV_UV_HUB_H 11#ifndef _ASM_X86_UV_UV_HUB_H
@@ -77,7 +77,8 @@
77 * 77 *
78 * 1111110000000000 78 * 1111110000000000
79 * 5432109876543210 79 * 5432109876543210
80 * pppppppppplc0cch 80 * pppppppppplc0cch Nehalem-EX
81 * ppppppppplcc0cch Westmere-EX
81 * sssssssssss 82 * sssssssssss
82 * 83 *
83 * p = pnode bits 84 * p = pnode bits
@@ -148,12 +149,25 @@ struct uv_hub_info_s {
148 unsigned char m_val; 149 unsigned char m_val;
149 unsigned char n_val; 150 unsigned char n_val;
150 struct uv_scir_s scir; 151 struct uv_scir_s scir;
152 unsigned char apic_pnode_shift;
151}; 153};
152 154
153DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); 155DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
154#define uv_hub_info (&__get_cpu_var(__uv_hub_info)) 156#define uv_hub_info (&__get_cpu_var(__uv_hub_info))
155#define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) 157#define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu))
156 158
159union uvh_apicid {
160 unsigned long v;
161 struct uvh_apicid_s {
162 unsigned long local_apic_mask : 24;
163 unsigned long local_apic_shift : 5;
164 unsigned long unused1 : 3;
165 unsigned long pnode_mask : 24;
166 unsigned long pnode_shift : 5;
167 unsigned long unused2 : 3;
168 } s;
169};
170
157/* 171/*
158 * Local & Global MMR space macros. 172 * Local & Global MMR space macros.
159 * Note: macros are intended to be used ONLY by inline functions 173 * Note: macros are intended to be used ONLY by inline functions
@@ -182,6 +196,7 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
182#define UV_GLOBAL_MMR64_PNODE_BITS(p) \ 196#define UV_GLOBAL_MMR64_PNODE_BITS(p) \
183 (((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT) 197 (((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT)
184 198
199#define UVH_APICID 0x002D0E00L
185#define UV_APIC_PNODE_SHIFT 6 200#define UV_APIC_PNODE_SHIFT 6
186 201
187/* Local Bus from cpu's perspective */ 202/* Local Bus from cpu's perspective */
@@ -280,7 +295,7 @@ static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
280 */ 295 */
281static inline int uv_apicid_to_pnode(int apicid) 296static inline int uv_apicid_to_pnode(int apicid)
282{ 297{
283 return (apicid >> UV_APIC_PNODE_SHIFT); 298 return (apicid >> uv_hub_info->apic_pnode_shift);
284} 299}
285 300
286/* 301/*
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;