aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/x2apic_uv_x.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/apic/x2apic_uv_x.c')
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index f744f54cb248..194539aea175 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,12 +71,27 @@ 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 void __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
73static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) 88static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
74{ 89{
75 int nodeid; 90 int nodeid;
76 91
77 if (!strcmp(oem_id, "SGI")) { 92 if (!strcmp(oem_id, "SGI")) {
78 nodeid = early_get_nodeid(); 93 nodeid = early_get_nodeid();
94 early_get_apic_pnode_shift();
79 x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range; 95 x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
80 x86_platform.nmi_init = uv_nmi_init; 96 x86_platform.nmi_init = uv_nmi_init;
81 if (!strcmp(oem_table_id, "UVL")) 97 if (!strcmp(oem_table_id, "UVL"))
@@ -84,7 +100,7 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
84 uv_system_type = UV_X2APIC; 100 uv_system_type = UV_X2APIC;
85 else if (!strcmp(oem_table_id, "UVH")) { 101 else if (!strcmp(oem_table_id, "UVH")) {
86 __get_cpu_var(x2apic_extra_bits) = 102 __get_cpu_var(x2apic_extra_bits) =
87 nodeid << (UV_APIC_PNODE_SHIFT - 1); 103 nodeid << (uvh_apicid.s.pnode_shift - 1);
88 uv_system_type = UV_NON_UNIQUE_APIC; 104 uv_system_type = UV_NON_UNIQUE_APIC;
89 return 1; 105 return 1;
90 } 106 }
@@ -363,14 +379,14 @@ struct redir_addr {
363#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT 379#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT
364 380
365static __initdata struct redir_addr redir_addrs[] = { 381static __initdata struct redir_addr redir_addrs[] = {
366 {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG}, 382 {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR},
367 {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG}, 383 {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR},
368 {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG}, 384 {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR},
369}; 385};
370 386
371static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) 387static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
372{ 388{
373 union uvh_si_alias0_overlay_config_u alias; 389 union uvh_rh_gam_alias210_overlay_config_2_mmr_u alias;
374 union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; 390 union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect;
375 int i; 391 int i;
376 392
@@ -644,7 +660,7 @@ void uv_nmi_init(void)
644 660
645void __init uv_system_init(void) 661void __init uv_system_init(void)
646{ 662{
647 union uvh_si_addr_map_config_u m_n_config; 663 union uvh_rh_gam_config_mmr_u m_n_config;
648 union uvh_node_id_u node_id; 664 union uvh_node_id_u node_id;
649 unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; 665 unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size;
650 int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; 666 int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val;
@@ -654,7 +670,7 @@ void __init uv_system_init(void)
654 670
655 map_low_mmrs(); 671 map_low_mmrs();
656 672
657 m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); 673 m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR );
658 m_val = m_n_config.s.m_skt; 674 m_val = m_n_config.s.m_skt;
659 n_val = m_n_config.s.n_skt; 675 n_val = m_n_config.s.n_skt;
660 mmr_base = 676 mmr_base =
@@ -716,6 +732,10 @@ void __init uv_system_init(void)
716 int apicid = per_cpu(x86_cpu_to_apicid, cpu); 732 int apicid = per_cpu(x86_cpu_to_apicid, cpu);
717 733
718 nid = cpu_to_node(cpu); 734 nid = cpu_to_node(cpu);
735 /*
736 * apic_pnode_shift must be set before calling uv_apicid_to_pnode();
737 */
738 uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift;
719 pnode = uv_apicid_to_pnode(apicid); 739 pnode = uv_apicid_to_pnode(apicid);
720 blade = boot_pnode_to_blade(pnode); 740 blade = boot_pnode_to_blade(pnode);
721 lcpu = uv_blade_info[blade].nr_possible_cpus; 741 lcpu = uv_blade_info[blade].nr_possible_cpus;