1ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner/*
2ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner * This file is subject to the terms and conditions of the GNU General Public
3ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner * License.  See the file "COPYING" in the main directory of this archive
4ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner * for more details.
5ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner *
6ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner * SGI UV APIC functions (note: not an Intel compatible APIC)
7ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner *
8c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
9ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner */
10ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner#include <linux/cpumask.h>
110b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <linux/hardirq.h>
120b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <linux/proc_fs.h>
130b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <linux/threads.h>
140b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <linux/kernel.h>
150b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <linux/module.h>
16ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner#include <linux/string.h>
17ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner#include <linux/ctype.h>
18ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner#include <linux/sched.h>
197f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis#include <linux/timer.h>
205a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
210b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <linux/cpu.h>
220b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <linux/init.h>
2327229ca63269c1be0a710f074fa9de4024f283f1Jack Steiner#include <linux/io.h>
24841582ea9e29a8f757c30c5377ce649586ba793aMike Travis#include <linux/pci.h>
2578c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson#include <linux/kdebug.h>
26ca444564a947034557a85357b3911d067cac4b8fJean Delvare#include <linux/delay.h>
27818987e9a19c52240ba9b1c20f28f047eef76072Cliff Wickman#include <linux/crash_dump.h>
280b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar
29ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner#include <asm/uv/uv_mmrs.h>
30ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner#include <asm/uv/uv_hub.h>
310b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <asm/current.h>
320b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <asm/pgtable.h>
337019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson#include <asm/uv/bios.h>
340b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <asm/uv/uv.h>
350b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <asm/apic.h>
360b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <asm/ipi.h>
370b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#include <asm/smp.h>
38fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner#include <asm/x86_init.h>
39818987e9a19c52240ba9b1c20f28f047eef76072Cliff Wickman#include <asm/emergency-restart.h>
401d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner#include <asm/nmi.h>
411d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner
421d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner/* BMC sets a bit this MMR non-zero before sending an NMI */
431d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner#define UVH_NMI_MMR				UVH_SCRATCH5
441d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner#define UVH_NMI_MMR_CLEAR			(UVH_NMI_MMR + 8)
451d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner#define UV_NMI_PENDING_MASK			(1UL << 63)
461d44e8288a0557c28c447d7e511f50d06ff93a34Jack SteinerDEFINE_PER_CPU(unsigned long, cpu_last_nmi_count);
47ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
48510b37258dfd61693ca6c039865c78bd996e3718Yinghai LuDEFINE_PER_CPU(int, x2apic_extra_bits);
49510b37258dfd61693ca6c039865c78bd996e3718Yinghai Lu
50841582ea9e29a8f757c30c5377ce649586ba793aMike Travis#define PR_DEVEL(fmt, args...)	pr_devel("%s: " fmt, __func__, args)
51841582ea9e29a8f757c30c5377ce649586ba793aMike Travis
521b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lustatic enum uv_system_type uv_system_type;
53fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steinerstatic u64 gru_start_paddr, gru_end_paddr;
54c8f730b1ab825f06733e1c074264f0078721f365Russ Andersonstatic union uvh_apicid uvh_apicid;
557a1110e861b2666ac09f5708d6fbe71d18ce64bbJack Steinerint uv_min_hub_revision_id;
567a1110e861b2666ac09f5708d6fbe71d18ce64bbJack SteinerEXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
578191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanichunsigned int uv_apicid_hibits;
588191c9f69202d4dbc66063cb92059b8a58640d34Dimitri SivanichEXPORT_SYMBOL_GPL(uv_apicid_hibits);
5978c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Andersonstatic DEFINE_SPINLOCK(uv_nmi_lock);
60fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner
611a8880a14270814dae0d226a2ad065d30587e60aSuresh Siddhastatic struct apic apic_x2apic_uv_x;
621a8880a14270814dae0d226a2ad065d30587e60aSuresh Siddha
63e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steinerstatic unsigned long __init uv_early_read_mmr(unsigned long addr)
64e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner{
65e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner	unsigned long val, *mmr;
66e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner
67e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner	mmr = early_ioremap(UV_LOCAL_MMR_BASE | addr, sizeof(*mmr));
68e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner	val = *mmr;
69e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner	early_iounmap(mmr, sizeof(*mmr));
70e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner	return val;
71e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner}
72e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner
73eb41c8be89dbe079f49202774e04a79ccac48a09H. Peter Anvinstatic inline bool is_GRU_range(u64 start, u64 end)
74fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner{
75ccef086454d4c97e7b722e9303390207d681cb4cH. Peter Anvin	return start >= gru_start_paddr && end <= gru_end_paddr;
76fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner}
77fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner
78eb41c8be89dbe079f49202774e04a79ccac48a09H. Peter Anvinstatic bool uv_is_untracked_pat_range(u64 start, u64 end)
79fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner{
80fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner	return is_ISA_range(start, end) || is_GRU_range(start, end);
81fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner}
821b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu
83d8850ba425d9823d3184bd52f065899dac4689f9Jack Steinerstatic int __init early_get_pnodeid(void)
8427229ca63269c1be0a710f074fa9de4024f283f1Jack Steiner{
8527229ca63269c1be0a710f074fa9de4024f283f1Jack Steiner	union uvh_node_id_u node_id;
86d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	union uvh_rh_gam_config_mmr_u  m_n_config;
87d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	int pnode;
887a1110e861b2666ac09f5708d6fbe71d18ce64bbJack Steiner
897a1110e861b2666ac09f5708d6fbe71d18ce64bbJack Steiner	/* Currently, all blades have same revision number */
90e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner	node_id.v = uv_early_read_mmr(UVH_NODE_ID);
91d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	m_n_config.v = uv_early_read_mmr(UVH_RH_GAM_CONFIG_MMR);
927a1110e861b2666ac09f5708d6fbe71d18ce64bbJack Steiner	uv_min_hub_revision_id = node_id.s.revision;
937a1110e861b2666ac09f5708d6fbe71d18ce64bbJack Steiner
942a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	if (node_id.s.part_number == UV2_HUB_PART_NUMBER)
952a919596c16b4333af851ff473ebf96e289ab90cJack Steiner		uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1;
96b495e039b4ce2ce4a96b3006004faf082f4d50e2Jack Steiner	if (node_id.s.part_number == UV2_HUB_PART_NUMBER_X)
97b495e039b4ce2ce4a96b3006004faf082f4d50e2Jack Steiner		uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1;
982a919596c16b4333af851ff473ebf96e289ab90cJack Steiner
992a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	uv_hub_info->hub_revision = uv_min_hub_revision_id;
100d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	pnode = (node_id.s.node_id >> 1) & ((1 << m_n_config.s.n_skt) - 1);
101d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	return pnode;
10227229ca63269c1be0a710f074fa9de4024f283f1Jack Steiner}
10327229ca63269c1be0a710f074fa9de4024f283f1Jack Steiner
1040520bd8438f18f2b1b2af5fd1c4ecc070a1bf837Russ Andersonstatic void __init early_get_apic_pnode_shift(void)
105c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson{
106e681041388e61ecd7f99dba66b3c1db11a564d92Jack Steiner	uvh_apicid.v = uv_early_read_mmr(UVH_APICID);
107c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson	if (!uvh_apicid.v)
108c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson		/*
109c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson		 * Old bios, use default value
110c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson		 */
111c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson		uvh_apicid.s.pnode_shift = UV_APIC_PNODE_SHIFT;
112c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson}
113c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson
1148191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich/*
1158191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich * Add an extra bit as dictated by bios to the destination apicid of
1168191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich * interrupts potentially passing through the UV HUB.  This prevents
1178191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich * a deadlock between interrupts and IO port operations.
1188191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich */
1198191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanichstatic void __init uv_set_apicid_hibit(void)
1208191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich{
1212a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	union uv1h_lb_target_physical_apic_id_mask_u apicid_mask;
1228191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich
1232a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	if (is_uv1_hub()) {
1242a919596c16b4333af851ff473ebf96e289ab90cJack Steiner		apicid_mask.v =
1252a919596c16b4333af851ff473ebf96e289ab90cJack Steiner			uv_early_read_mmr(UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK);
1262a919596c16b4333af851ff473ebf96e289ab90cJack Steiner		uv_apicid_hibits =
1272a919596c16b4333af851ff473ebf96e289ab90cJack Steiner			apicid_mask.s1.bit_enables & UV_APICID_HIBIT_MASK;
1282a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	}
1298191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich}
1308191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich
13152459ab91363343af8ae252766e9da762344a2e7Leonardo Potenzastatic int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
1321b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu{
1332a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	int pnodeid, is_uv1, is_uv2;
1341d2c867c941d635e53e8ad7bf37d060bb5b25ec5Russ Anderson
1352a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	is_uv1 = !strcmp(oem_id, "SGI");
1362a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	is_uv2 = !strcmp(oem_id, "SGI2");
1372a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	if (is_uv1 || is_uv2) {
1382a919596c16b4333af851ff473ebf96e289ab90cJack Steiner		uv_hub_info->hub_revision =
1392a919596c16b4333af851ff473ebf96e289ab90cJack Steiner			is_uv1 ? UV1_HUB_REVISION_BASE : UV2_HUB_REVISION_BASE;
140d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner		pnodeid = early_get_pnodeid();
1410520bd8438f18f2b1b2af5fd1c4ecc070a1bf837Russ Anderson		early_get_apic_pnode_shift();
142fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner		x86_platform.is_untracked_pat_range =  uv_is_untracked_pat_range;
14378c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson		x86_platform.nmi_init = uv_nmi_init;
1441b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu		if (!strcmp(oem_table_id, "UVL"))
1451b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu			uv_system_type = UV_LEGACY_APIC;
1461b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu		else if (!strcmp(oem_table_id, "UVX"))
1471b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu			uv_system_type = UV_X2APIC;
1481b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu		else if (!strcmp(oem_table_id, "UVH")) {
1490a3aee0da4402aa19b66e458038533c896fb80c6Tejun Heo			__this_cpu_write(x2apic_extra_bits,
15072eb6a791459c87a0340318840bb3bd9252b627bLinus Torvalds				pnodeid << uvh_apicid.s.pnode_shift);
1511b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu			uv_system_type = UV_NON_UNIQUE_APIC;
1528191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich			uv_set_apicid_hibit();
1531b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu			return 1;
1541b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu		}
1551b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu	}
1561b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu	return 0;
1571b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu}
1581b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu
1591b9b89e7f163336ad84200b66a17284dbf26acedYinghai Luenum uv_system_type get_uv_system_type(void)
1601b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu{
1611b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu	return uv_system_type;
1621b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu}
1631b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu
1641b9b89e7f163336ad84200b66a17284dbf26acedYinghai Luint is_uv_system(void)
1651b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu{
1661b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu	return uv_system_type != UV_NONE;
1671b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu}
1688067794bec1cc5de1431102cf0a6a1c7ce75cd85Ingo MolnarEXPORT_SYMBOL_GPL(is_uv_system);
1691b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu
170ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack SteinerDEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
171ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack SteinerEXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
172ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
173ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steinerstruct uv_blade_info *uv_blade_info;
174ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack SteinerEXPORT_SYMBOL_GPL(uv_blade_info);
175ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
176ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steinershort *uv_node_to_blade;
177ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack SteinerEXPORT_SYMBOL_GPL(uv_node_to_blade);
178ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
179ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steinershort *uv_cpu_to_blade;
180ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack SteinerEXPORT_SYMBOL_GPL(uv_cpu_to_blade);
181ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
182ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steinershort uv_possible_blades;
183ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack SteinerEXPORT_SYMBOL_GPL(uv_possible_blades);
184ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
1857019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Andersonunsigned long sn_rtc_cycles_per_second;
1867019cc2dd6fafcdc6b104005482dc910dcdbb797Russ AndersonEXPORT_SYMBOL(sn_rtc_cycles_per_second);
1877019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson
188bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travisstatic const struct cpumask *uv_target_cpus(void)
189ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
1908447b360a3897bdfb0677107564d1dd9ab6e63beJack Steiner	return cpu_online_mask;
191ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
192ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
193bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travisstatic void uv_vector_allocation_domain(int cpu, struct cpumask *retmask)
194ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
195bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travis	cpumask_clear(retmask);
196bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travis	cpumask_set_cpu(cpu, retmask);
197ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
198ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
199667c5296cc76fefe0abcb79228952b28d9af45e3Cyrill Gorcunovstatic int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
200ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
2010b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#ifdef CONFIG_SMP
202ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	unsigned long val;
2039f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	int pnode;
204ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
2059f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	pnode = uv_apicid_to_pnode(phys_apicid);
2068191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich	phys_apicid |= uv_apicid_hibits;
207ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
208ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	    (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
2092b6163bf5772644068694583816fa41e8474239fYinghai Lu	    ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
21034d0559178393547505ec9492321255405f4e441Jack Steiner	    APIC_DM_INIT;
2119f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
21234d0559178393547505ec9492321255405f4e441Jack Steiner
21334d0559178393547505ec9492321255405f4e441Jack Steiner	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
21434d0559178393547505ec9492321255405f4e441Jack Steiner	    (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
2152b6163bf5772644068694583816fa41e8474239fYinghai Lu	    ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
21634d0559178393547505ec9492321255405f4e441Jack Steiner	    APIC_DM_STARTUP;
2179f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
2182b6163bf5772644068694583816fa41e8474239fYinghai Lu
2192b6163bf5772644068694583816fa41e8474239fYinghai Lu	atomic_set(&init_deasserted, 1);
2200b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar#endif
221ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	return 0;
222ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
223ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
224ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steinerstatic void uv_send_IPI_one(int cpu, int vector)
225ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
22666666e50fcd69d80117d7d243ce02e1f774cbaf5Jack Steiner	unsigned long apicid;
2279f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	int pnode;
228ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
2291e0b5d00b230ceffe1bb33284b46b8572e418423Jack Steiner	apicid = per_cpu(x86_cpu_to_apicid, cpu);
2309f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	pnode = uv_apicid_to_pnode(apicid);
23166666e50fcd69d80117d7d243ce02e1f774cbaf5Jack Steiner	uv_hub_send_ipi(pnode, apicid, vector);
232ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
233ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
234bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travisstatic void uv_send_IPI_mask(const struct cpumask *mask, int vector)
235ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
236ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	unsigned int cpu;
237ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
238bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travis	for_each_cpu(cpu, mask)
239e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis		uv_send_IPI_one(cpu, vector);
240e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis}
241e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis
242bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travisstatic void uv_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
243e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis{
244e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis	unsigned int this_cpu = smp_processor_id();
245dac5f4121df3c39fdb2ea57acd669a0ae19e46f8Ingo Molnar	unsigned int cpu;
246e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis
247dac5f4121df3c39fdb2ea57acd669a0ae19e46f8Ingo Molnar	for_each_cpu(cpu, mask) {
248e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis		if (cpu != this_cpu)
249ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner			uv_send_IPI_one(cpu, vector);
250dac5f4121df3c39fdb2ea57acd669a0ae19e46f8Ingo Molnar	}
251ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
252ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
253ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steinerstatic void uv_send_IPI_allbutself(int vector)
254ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
255e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis	unsigned int this_cpu = smp_processor_id();
256dac5f4121df3c39fdb2ea57acd669a0ae19e46f8Ingo Molnar	unsigned int cpu;
257ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
258dac5f4121df3c39fdb2ea57acd669a0ae19e46f8Ingo Molnar	for_each_online_cpu(cpu) {
259e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis		if (cpu != this_cpu)
260e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis			uv_send_IPI_one(cpu, vector);
261dac5f4121df3c39fdb2ea57acd669a0ae19e46f8Ingo Molnar	}
262ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
263ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
264ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steinerstatic void uv_send_IPI_all(int vector)
265ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
266bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travis	uv_send_IPI_mask(cpu_online_mask, vector);
267ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
268ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
269b7157acf429e6aef690646ba964b9ebd25049ec2Steffen Persvoldstatic int uv_apic_id_valid(int apicid)
270b7157acf429e6aef690646ba964b9ebd25049ec2Steffen Persvold{
271b7157acf429e6aef690646ba964b9ebd25049ec2Steffen Persvold	return 1;
272b7157acf429e6aef690646ba964b9ebd25049ec2Steffen Persvold}
273b7157acf429e6aef690646ba964b9ebd25049ec2Steffen Persvold
274ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steinerstatic int uv_apic_id_registered(void)
275ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
276ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	return 1;
277ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
278ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
279277d1f5846d84e16760131a93b7a67ebfa8eded4Suresh Siddhastatic void uv_init_apic_ldr(void)
2805c520a6724e912a7e6153b7597192edad6752750Suresh Siddha{
2815c520a6724e912a7e6153b7597192edad6752750Suresh Siddha}
2825c520a6724e912a7e6153b7597192edad6752750Suresh Siddha
283bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travisstatic unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask)
284ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
285ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	/*
286ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
287ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	 * May as well be the first.
288ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	 */
289debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar	int cpu = cpumask_first(cpumask);
290debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar
291247bc6ca0f691e4617e7bdb70cbaccc939f754ecMike Travis	if ((unsigned)cpu < nr_cpu_ids)
2928191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich		return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits;
293ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	else
294ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner		return BAD_APICID;
295ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
296ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
297debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnarstatic unsigned int
298debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnaruv_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
299debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar			  const struct cpumask *andmask)
30095d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis{
30195d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis	int cpu;
30295d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis
30395d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis	/*
30495d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
30595d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis	 * May as well be the first.
30695d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis	 */
307debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar	for_each_cpu_and(cpu, cpumask, andmask) {
308a775a38b1353161a6d7af86b667d6523c12c1a37Mike Travis		if (cpumask_test_cpu(cpu, cpu_online_mask))
309a775a38b1353161a6d7af86b667d6523c12c1a37Mike Travis			break;
310debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar	}
3118191c9f69202d4dbc66063cb92059b8a58640d34Dimitri Sivanich	return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits;
31295d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis}
31395d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis
314ca6c8ed4646f8ccaa4f7db618bf69b8b8fb49767Ingo Molnarstatic unsigned int x2apic_get_apic_id(unsigned long x)
3150c81c746f9bdbfaafe64322d540c8b7b59c27314Suresh Siddha{
3160c81c746f9bdbfaafe64322d540c8b7b59c27314Suresh Siddha	unsigned int id;
3170c81c746f9bdbfaafe64322d540c8b7b59c27314Suresh Siddha
3180c81c746f9bdbfaafe64322d540c8b7b59c27314Suresh Siddha	WARN_ON(preemptible() && num_online_cpus() > 1);
3190a3aee0da4402aa19b66e458038533c896fb80c6Tejun Heo	id = x | __this_cpu_read(x2apic_extra_bits);
3200c81c746f9bdbfaafe64322d540c8b7b59c27314Suresh Siddha
3210c81c746f9bdbfaafe64322d540c8b7b59c27314Suresh Siddha	return id;
3220c81c746f9bdbfaafe64322d540c8b7b59c27314Suresh Siddha}
3230c81c746f9bdbfaafe64322d540c8b7b59c27314Suresh Siddha
3241b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lustatic unsigned long set_apic_id(unsigned int id)
325f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu{
326f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu	unsigned long x;
327f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu
328f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu	/* maskout x2apic_extra_bits ? */
329f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu	x = id;
330f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu	return x;
331f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu}
332f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu
333f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lustatic unsigned int uv_read_apic_id(void)
334f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu{
335f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu
336ca6c8ed4646f8ccaa4f7db618bf69b8b8fb49767Ingo Molnar	return x2apic_get_apic_id(apic_read(APIC_ID));
337f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu}
338f910a9dc7c865896815e2a95fe33363e9522f277Yinghai Lu
339d4c9a9f3d416cfa1f5ffbe09d864d069467fe693Ingo Molnarstatic int uv_phys_pkg_id(int initial_apicid, int index_msb)
340ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
3410c81c746f9bdbfaafe64322d540c8b7b59c27314Suresh Siddha	return uv_read_apic_id() >> index_msb;
342ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
343ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
344ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steinerstatic void uv_send_IPI_self(int vector)
345ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
346ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	apic_write(APIC_SELF_IPI, vector);
347ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
348ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
3499ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddhastatic int uv_probe(void)
3509ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha{
3519ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha	return apic == &apic_x2apic_uv_x;
3529ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha}
3539ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha
3541a8880a14270814dae0d226a2ad065d30587e60aSuresh Siddhastatic struct apic __refdata apic_x2apic_uv_x = {
355c7967329911013a05920ef12832935c541bb8c9aIngo Molnar
356c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.name				= "UV large system",
3579ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha	.probe				= uv_probe,
358c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.acpi_madt_oem_check		= uv_acpi_madt_oem_check,
359b7157acf429e6aef690646ba964b9ebd25049ec2Steffen Persvold	.apic_id_valid			= uv_apic_id_valid,
360c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.apic_id_registered		= uv_apic_id_registered,
361c7967329911013a05920ef12832935c541bb8c9aIngo Molnar
362f8987a1093cc7a896137e264c24e04d4048e9f95Ingo Molnar	.irq_delivery_mode		= dest_Fixed,
363c5997fa8d7aca3c9876a6ff71bacf27c41095ce9Jack Steiner	.irq_dest_mode			= 0, /* physical */
364c7967329911013a05920ef12832935c541bb8c9aIngo Molnar
365c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.target_cpus			= uv_target_cpus,
36608125d3edab90644724652eedec3e219e3e0f2e7Ingo Molnar	.disable_esr			= 0,
367bdb1a9b62fc182d4da3143e346f7a0925d243352Ingo Molnar	.dest_logical			= APIC_DEST_LOGICAL,
368c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.check_apicid_used		= NULL,
369c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.check_apicid_present		= NULL,
370c7967329911013a05920ef12832935c541bb8c9aIngo Molnar
371c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.vector_allocation_domain	= uv_vector_allocation_domain,
372c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.init_apic_ldr			= uv_init_apic_ldr,
373c7967329911013a05920ef12832935c541bb8c9aIngo Molnar
374c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.ioapic_phys_id_map		= NULL,
375c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.setup_apic_routing		= NULL,
376c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.multi_timer_check		= NULL,
377a21769a4461801454930a06bc18bd8249cd9e993Ingo Molnar	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
378c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.apicid_to_cpu_present		= NULL,
379c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.setup_portio_remap		= NULL,
380a27a621001f4c3e57caf47feff4b014577fd01c6Ingo Molnar	.check_phys_apicid_present	= default_check_phys_apicid_present,
381c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.enable_apic_mode		= NULL,
382d4c9a9f3d416cfa1f5ffbe09d864d069467fe693Ingo Molnar	.phys_pkg_id			= uv_phys_pkg_id,
383c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.mps_oem_check			= NULL,
384c7967329911013a05920ef12832935c541bb8c9aIngo Molnar
385ca6c8ed4646f8ccaa4f7db618bf69b8b8fb49767Ingo Molnar	.get_apic_id			= x2apic_get_apic_id,
386c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.set_apic_id			= set_apic_id,
387c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.apic_id_mask			= 0xFFFFFFFFu,
388c7967329911013a05920ef12832935c541bb8c9aIngo Molnar
389c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.cpu_mask_to_apicid		= uv_cpu_mask_to_apicid,
390c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.cpu_mask_to_apicid_and		= uv_cpu_mask_to_apicid_and,
391c7967329911013a05920ef12832935c541bb8c9aIngo Molnar
392c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.send_IPI_mask			= uv_send_IPI_mask,
393c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.send_IPI_mask_allbutself	= uv_send_IPI_mask_allbutself,
394c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.send_IPI_allbutself		= uv_send_IPI_allbutself,
395c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.send_IPI_all			= uv_send_IPI_all,
396c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.send_IPI_self			= uv_send_IPI_self,
397c7967329911013a05920ef12832935c541bb8c9aIngo Molnar
3981f5bcabf1b997d6b76a09114b5a79423495a1263Ingo Molnar	.wakeup_secondary_cpu		= uv_wakeup_secondary,
399abfa584c8df8b691cf18f51c7d4af27e5b32be4aIngo Molnar	.trampoline_phys_low		= DEFAULT_TRAMPOLINE_PHYS_LOW,
400abfa584c8df8b691cf18f51c7d4af27e5b32be4aIngo Molnar	.trampoline_phys_high		= DEFAULT_TRAMPOLINE_PHYS_HIGH,
401c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.wait_for_init_deassert		= NULL,
402c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.smp_callin_clear_local_apic	= NULL,
403c7967329911013a05920ef12832935c541bb8c9aIngo Molnar	.inquire_remote_apic		= NULL,
404c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu
405c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu	.read				= native_apic_msr_read,
406c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu	.write				= native_apic_msr_write,
407c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu	.icr_read			= native_x2apic_icr_read,
408c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu	.icr_write			= native_x2apic_icr_write,
409c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu	.wait_icr_idle			= native_x2apic_wait_icr_idle,
410c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu	.safe_wait_icr_idle		= native_safe_x2apic_wait_icr_idle,
411ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner};
412ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
4139f5314fb4d556d3132c784d0df47352b2830ca53Jack Steinerstatic __cpuinit void set_x2apic_extra_bits(int pnode)
414ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
41516ee8db6a93ffbc021132599f33288613f042c3dLinus Torvalds	__this_cpu_write(x2apic_extra_bits, pnode << uvh_apicid.s.pnode_shift);
416ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
417ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
418ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner/*
419ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner * Called on boot cpu.
420ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner */
4219f5314fb4d556d3132c784d0df47352b2830ca53Jack Steinerstatic __init int boot_pnode_to_blade(int pnode)
4229f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner{
4239f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	int blade;
4249f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner
4259f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	for (blade = 0; blade < uv_num_possible_blades(); blade++)
4269f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		if (pnode == uv_blade_info[blade].pnode)
4279f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner			return blade;
4289f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	BUG();
4299f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner}
4309f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner
4319f5314fb4d556d3132c784d0df47352b2830ca53Jack Steinerstruct redir_addr {
4329f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	unsigned long redirect;
4339f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	unsigned long alias;
4349f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner};
4359f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner
4369f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT
4379f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner
4389f5314fb4d556d3132c784d0df47352b2830ca53Jack Steinerstatic __initdata struct redir_addr redir_addrs[] = {
43962b0cfc240b1d4601333912ef8760e0ca9ec2cecJack Steiner	{UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR},
44062b0cfc240b1d4601333912ef8760e0ca9ec2cecJack Steiner	{UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR},
44162b0cfc240b1d4601333912ef8760e0ca9ec2cecJack Steiner	{UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR},
4429f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner};
4439f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner
4449f5314fb4d556d3132c784d0df47352b2830ca53Jack Steinerstatic __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
4459f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner{
44662b0cfc240b1d4601333912ef8760e0ca9ec2cecJack Steiner	union uvh_rh_gam_alias210_overlay_config_2_mmr_u alias;
4479f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect;
4489f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	int i;
4499f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner
4509f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) {
4519f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		alias.v = uv_read_local_mmr(redir_addrs[i].alias);
452036ed8ba61b72c19dc5759446d4fe0844aa88255Robin Holt		if (alias.s.enable && alias.s.base == 0) {
4539f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner			*size = (1UL << alias.s.m_alias);
4549f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner			redirect.v = uv_read_local_mmr(redir_addrs[i].redirect);
4559f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner			*base = (unsigned long)redirect.s.dest_base << DEST_SHIFT;
4569f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner			return;
4579f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		}
4589f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	}
459036ed8ba61b72c19dc5759446d4fe0844aa88255Robin Holt	*base = *size = 0;
4609f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner}
4619f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner
46283f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steinerenum map_type {map_wb, map_uc};
46383f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner
464fcfbb2b5facd65efa7284cc315225bfe3d1856c2Mike Travisstatic __init void map_high(char *id, unsigned long base, int pshift,
465fcfbb2b5facd65efa7284cc315225bfe3d1856c2Mike Travis			int bshift, int max_pnode, enum map_type map_type)
46683f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner{
46783f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	unsigned long bytes, paddr;
46883f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner
469fcfbb2b5facd65efa7284cc315225bfe3d1856c2Mike Travis	paddr = base << pshift;
470fcfbb2b5facd65efa7284cc315225bfe3d1856c2Mike Travis	bytes = (1UL << bshift) * (max_pnode + 1);
47183f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr,
4720b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar						paddr + bytes);
47383f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	if (map_type == map_uc)
47483f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner		init_extra_mapping_uc(paddr, bytes);
47583f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	else
47683f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner		init_extra_mapping_wb(paddr, bytes);
47783f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner
47883f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner}
47983f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steinerstatic __init void map_gru_high(int max_pnode)
48083f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner{
48183f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	union uvh_rh_gam_gru_overlay_config_mmr_u gru;
48283f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT;
48383f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner
48483f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR);
485fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner	if (gru.s.enable) {
486fcfbb2b5facd65efa7284cc315225bfe3d1856c2Mike Travis		map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb);
487fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner		gru_start_paddr = ((u64)gru.s.base << shift);
488fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner		gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1);
489fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner
490fd12a0d69aee6d90fa9b9890db24368a897f8423Jack Steiner	}
49183f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner}
49283f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner
493daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steinerstatic __init void map_mmr_high(int max_pnode)
494daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steiner{
495daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steiner	union uvh_rh_gam_mmr_overlay_config_mmr_u mmr;
496daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steiner	int shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT;
497daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steiner
498daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steiner	mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR);
499daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steiner	if (mmr.s.enable)
500fcfbb2b5facd65efa7284cc315225bfe3d1856c2Mike Travis		map_high("MMR", mmr.s.base, shift, shift, max_pnode, map_uc);
501daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steiner}
502daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steiner
50383f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steinerstatic __init void map_mmioh_high(int max_pnode)
50483f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner{
50583f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh;
5062a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	int shift;
50783f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner
50883f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR);
5092a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	if (is_uv1_hub() && mmioh.s1.enable) {
5102a919596c16b4333af851ff473ebf96e289ab90cJack Steiner		shift = UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT;
5112a919596c16b4333af851ff473ebf96e289ab90cJack Steiner		map_high("MMIOH", mmioh.s1.base, shift, mmioh.s1.m_io,
5122a919596c16b4333af851ff473ebf96e289ab90cJack Steiner			max_pnode, map_uc);
5132a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	}
5142a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	if (is_uv2_hub() && mmioh.s2.enable) {
5152a919596c16b4333af851ff473ebf96e289ab90cJack Steiner		shift = UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT;
5162a919596c16b4333af851ff473ebf96e289ab90cJack Steiner		map_high("MMIOH", mmioh.s2.base, shift, mmioh.s2.m_io,
517fcfbb2b5facd65efa7284cc315225bfe3d1856c2Mike Travis			max_pnode, map_uc);
5182a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	}
51983f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner}
52083f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner
521918bc960dc630b1a79c0d2991a81985812ff69f5Jack Steinerstatic __init void map_low_mmrs(void)
522918bc960dc630b1a79c0d2991a81985812ff69f5Jack Steiner{
523918bc960dc630b1a79c0d2991a81985812ff69f5Jack Steiner	init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE);
524918bc960dc630b1a79c0d2991a81985812ff69f5Jack Steiner	init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE);
525918bc960dc630b1a79c0d2991a81985812ff69f5Jack Steiner}
526918bc960dc630b1a79c0d2991a81985812ff69f5Jack Steiner
5277019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Andersonstatic __init void uv_rtc_init(void)
5287019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson{
529922402f15a85f7a064926eb1db68cc52bc4d4a91Russ Anderson	long status;
530922402f15a85f7a064926eb1db68cc52bc4d4a91Russ Anderson	u64 ticks_per_sec;
5317019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson
532922402f15a85f7a064926eb1db68cc52bc4d4a91Russ Anderson	status = uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK,
533922402f15a85f7a064926eb1db68cc52bc4d4a91Russ Anderson					&ticks_per_sec);
534922402f15a85f7a064926eb1db68cc52bc4d4a91Russ Anderson	if (status != BIOS_STATUS_SUCCESS || ticks_per_sec < 100000) {
5357019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson		printk(KERN_WARNING
5367019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson			"unable to determine platform RTC clock frequency, "
5377019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson			"guessing.\n");
5387019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson		/* BIOS gives wrong value for clock freq. so guess */
5397019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson		sn_rtc_cycles_per_second = 1000000000000UL / 30000UL;
5407019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson	} else
5417019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson		sn_rtc_cycles_per_second = ticks_per_sec;
5427019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson}
5437019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson
5448da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner/*
5457f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis * percpu heartbeat timer
5467f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis */
5477f1baa063e2582dd52d83bb31508e9e84468c666Mike Travisstatic void uv_heartbeat(unsigned long ignored)
5487f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis{
5497f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	struct timer_list *timer = &uv_hub_info->scir.timer;
5507f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	unsigned char bits = uv_hub_info->scir.state;
5517f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
5527f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	/* flip heartbeat bit */
5537f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	bits ^= SCIR_CPU_HEARTBEAT;
5547f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
55569a72a0e9337aad8c730e8e9942d5aa022bc4c5cMike Travis	/* is this cpu idle? */
55669a72a0e9337aad8c730e8e9942d5aa022bc4c5cMike Travis	if (idle_cpu(raw_smp_processor_id()))
5577f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		bits &= ~SCIR_CPU_ACTIVITY;
5587f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	else
5597f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		bits |= SCIR_CPU_ACTIVITY;
5607f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
5617f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	/* update system controller interface reg */
5627f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	uv_set_scir_bits(bits);
5637f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
5647f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	/* enable next timer period */
5655c333864a6ba811052d52ef14fbed056b9ac3512Arun R Bharadwaj	mod_timer_pinned(timer, jiffies + SCIR_CPU_HB_INTERVAL);
5667f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis}
5677f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
5687f1baa063e2582dd52d83bb31508e9e84468c666Mike Travisstatic void __cpuinit uv_heartbeat_enable(int cpu)
5697f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis{
57099659a929d653d0c9ce458091870544768add871Roel Kluin	while (!uv_cpu_hub_info(cpu)->scir.enabled) {
5717f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		struct timer_list *timer = &uv_cpu_hub_info(cpu)->scir.timer;
5727f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
5737f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		uv_set_cpu_scir_bits(cpu, SCIR_CPU_HEARTBEAT|SCIR_CPU_ACTIVITY);
5747f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		setup_timer(timer, uv_heartbeat, cpu);
5757f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		timer->expires = jiffies + SCIR_CPU_HB_INTERVAL;
5767f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		add_timer_on(timer, cpu);
5777f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		uv_cpu_hub_info(cpu)->scir.enabled = 1;
5787f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
57999659a929d653d0c9ce458091870544768add871Roel Kluin		/* also ensure that boot cpu is enabled */
58099659a929d653d0c9ce458091870544768add871Roel Kluin		cpu = 0;
58199659a929d653d0c9ce458091870544768add871Roel Kluin	}
5827f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis}
5837f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
58477be80e437fec44f8b7a620314b7d7b605b8d93bRichard A. Holden III#ifdef CONFIG_HOTPLUG_CPU
5857f1baa063e2582dd52d83bb31508e9e84468c666Mike Travisstatic void __cpuinit uv_heartbeat_disable(int cpu)
5867f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis{
5877f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	if (uv_cpu_hub_info(cpu)->scir.enabled) {
5887f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		uv_cpu_hub_info(cpu)->scir.enabled = 0;
5897f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		del_timer(&uv_cpu_hub_info(cpu)->scir.timer);
5907f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	}
5917f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	uv_set_cpu_scir_bits(cpu, 0xff);
5927f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis}
5937f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
5947f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis/*
5957f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis * cpu hotplug notifier
5967f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis */
5977f1baa063e2582dd52d83bb31508e9e84468c666Mike Travisstatic __cpuinit int uv_scir_cpu_notify(struct notifier_block *self,
5987f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis				       unsigned long action, void *hcpu)
5997f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis{
6007f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	long cpu = (long)hcpu;
6017f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
6027f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	switch (action) {
6037f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	case CPU_ONLINE:
6047f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		uv_heartbeat_enable(cpu);
6057f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		break;
6067f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	case CPU_DOWN_PREPARE:
6077f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		uv_heartbeat_disable(cpu);
6087f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		break;
6097f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	default:
6107f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		break;
6117f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	}
6127f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	return NOTIFY_OK;
6137f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis}
6147f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
6157f1baa063e2582dd52d83bb31508e9e84468c666Mike Travisstatic __init void uv_scir_register_cpu_notifier(void)
6167f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis{
6177f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	hotcpu_notifier(uv_scir_cpu_notify, 0);
6187f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis}
6197f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
6207f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis#else /* !CONFIG_HOTPLUG_CPU */
6217f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
6227f1baa063e2582dd52d83bb31508e9e84468c666Mike Travisstatic __init void uv_scir_register_cpu_notifier(void)
6237f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis{
6247f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis}
6257f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
6267f1baa063e2582dd52d83bb31508e9e84468c666Mike Travisstatic __init int uv_init_heartbeat(void)
6277f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis{
6287f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	int cpu;
6297f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
6307f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	if (is_uv_system())
6317f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis		for_each_online_cpu(cpu)
6327f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis			uv_heartbeat_enable(cpu);
6337f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	return 0;
6347f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis}
6357f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
6367f1baa063e2582dd52d83bb31508e9e84468c666Mike Travislate_initcall(uv_init_heartbeat);
6377f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
6387f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis#endif /* !CONFIG_HOTPLUG_CPU */
6397f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis
640841582ea9e29a8f757c30c5377ce649586ba793aMike Travis/* Direct Legacy VGA I/O traffic to designated IOH */
641841582ea9e29a8f757c30c5377ce649586ba793aMike Travisint uv_set_vga_state(struct pci_dev *pdev, bool decode,
6427ad35cf288fd63a19bf50e490440a992de808b2bDave Airlie		      unsigned int command_bits, u32 flags)
643841582ea9e29a8f757c30c5377ce649586ba793aMike Travis{
644841582ea9e29a8f757c30c5377ce649586ba793aMike Travis	int domain, bus, rc;
645841582ea9e29a8f757c30c5377ce649586ba793aMike Travis
6467ad35cf288fd63a19bf50e490440a992de808b2bDave Airlie	PR_DEVEL("devfn %x decode %d cmd %x flags %d\n",
6477ad35cf288fd63a19bf50e490440a992de808b2bDave Airlie			pdev->devfn, decode, command_bits, flags);
648841582ea9e29a8f757c30c5377ce649586ba793aMike Travis
6497ad35cf288fd63a19bf50e490440a992de808b2bDave Airlie	if (!(flags & PCI_VGA_STATE_CHANGE_BRIDGE))
650841582ea9e29a8f757c30c5377ce649586ba793aMike Travis		return 0;
651841582ea9e29a8f757c30c5377ce649586ba793aMike Travis
652841582ea9e29a8f757c30c5377ce649586ba793aMike Travis	if ((command_bits & PCI_COMMAND_IO) == 0)
653841582ea9e29a8f757c30c5377ce649586ba793aMike Travis		return 0;
654841582ea9e29a8f757c30c5377ce649586ba793aMike Travis
655841582ea9e29a8f757c30c5377ce649586ba793aMike Travis	domain = pci_domain_nr(pdev->bus);
656841582ea9e29a8f757c30c5377ce649586ba793aMike Travis	bus = pdev->bus->number;
657841582ea9e29a8f757c30c5377ce649586ba793aMike Travis
658841582ea9e29a8f757c30c5377ce649586ba793aMike Travis	rc = uv_bios_set_legacy_vga_target(decode, domain, bus);
659841582ea9e29a8f757c30c5377ce649586ba793aMike Travis	PR_DEVEL("vga decode %d %x:%x, rc: %d\n", decode, domain, bus, rc);
660841582ea9e29a8f757c30c5377ce649586ba793aMike Travis
661841582ea9e29a8f757c30c5377ce649586ba793aMike Travis	return rc;
662841582ea9e29a8f757c30c5377ce649586ba793aMike Travis}
663841582ea9e29a8f757c30c5377ce649586ba793aMike Travis
6647f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis/*
6658da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner * Called on each cpu to initialize the per_cpu UV data area.
6660b1da1c8fc1a0cb71f17701efad06855a059f752Ingo Molnar * FIXME: hotplug not supported yet
6678da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner */
6688da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steinervoid __cpuinit uv_cpu_init(void)
6698da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner{
6708da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner	/* CPU 0 initilization will be done via uv_system_init. */
6718da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner	if (!uv_blade_info)
6728da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner		return;
6738da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner
6748da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner	uv_blade_info[uv_numa_blade_id()].nr_online_cpus++;
6758da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner
6768da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner	if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
6778da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner		set_x2apic_extra_bits(uv_hub_info->pnode);
6788da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner}
6798da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner
68078c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson/*
68178c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson * When NMI is received, print a stack trace.
68278c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson */
6839c48f1c629ecfa114850c03f875c6691003214deDon Zickusint uv_handle_nmi(unsigned int reason, struct pt_regs *regs)
68478c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson{
6851d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	unsigned long real_uv_nmi;
6861d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	int bid;
6871d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner
68878c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	/*
6891d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	 * Each blade has an MMR that indicates when an NMI has been sent
6901d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	 * to cpus on the blade. If an NMI is detected, atomically
6911d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	 * clear the MMR and update a per-blade NMI count used to
6921d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	 * cause each cpu on the blade to notice a new NMI.
6931d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	 */
6941d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	bid = uv_numa_blade_id();
6951d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	real_uv_nmi = (uv_read_local_mmr(UVH_NMI_MMR) & UV_NMI_PENDING_MASK);
6961d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner
6971d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	if (unlikely(real_uv_nmi)) {
6981d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner		spin_lock(&uv_blade_info[bid].nmi_lock);
6991d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner		real_uv_nmi = (uv_read_local_mmr(UVH_NMI_MMR) & UV_NMI_PENDING_MASK);
7001d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner		if (real_uv_nmi) {
7011d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner			uv_blade_info[bid].nmi_count++;
7021d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner			uv_write_local_mmr(UVH_NMI_MMR_CLEAR, UV_NMI_PENDING_MASK);
7031d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner		}
7041d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner		spin_unlock(&uv_blade_info[bid].nmi_lock);
7051d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	}
7061d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner
7071d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	if (likely(__get_cpu_var(cpu_last_nmi_count) == uv_blade_info[bid].nmi_count))
7089c48f1c629ecfa114850c03f875c6691003214deDon Zickus		return NMI_DONE;
7091d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner
7101d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	__get_cpu_var(cpu_last_nmi_count) = uv_blade_info[bid].nmi_count;
7111d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner
7121d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	/*
7131d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	 * Use a lock so only one cpu prints at a time.
7141d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	 * This prevents intermixed output.
71578c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	 */
71678c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	spin_lock(&uv_nmi_lock);
7171d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	pr_info("UV NMI stack dump cpu %u:\n", smp_processor_id());
71878c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	dump_stack();
71978c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	spin_unlock(&uv_nmi_lock);
72078c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson
7219c48f1c629ecfa114850c03f875c6691003214deDon Zickus	return NMI_HANDLED;
72278c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson}
72378c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson
72478c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Andersonvoid uv_register_nmi_notifier(void)
72578c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson{
7269c48f1c629ecfa114850c03f875c6691003214deDon Zickus	if (register_nmi_handler(NMI_UNKNOWN, uv_handle_nmi, 0, "uv"))
72778c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson		printk(KERN_WARNING "UV NMI handler failed to register\n");
72878c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson}
72978c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson
73078c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Andersonvoid uv_nmi_init(void)
73178c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson{
73278c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	unsigned int value;
73378c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson
73478c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	/*
73578c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	 * Unmask NMI on all cpus
73678c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	 */
73778c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	value = apic_read(APIC_LVT1) | APIC_DM_NMI;
73878c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	value &= ~APIC_LVT_MASKED;
73978c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	apic_write(APIC_LVT1, value);
74078c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson}
741c4bd1fdab0deec0f69aeabab22075cb22ac8ad44Marcin Slusarz
742c4bd1fdab0deec0f69aeabab22075cb22ac8ad44Marcin Slusarzvoid __init uv_system_init(void)
743ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner{
74462b0cfc240b1d4601333912ef8760e0ca9ec2cecJack Steiner	union uvh_rh_gam_config_mmr_u  m_n_config;
745d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh;
7469f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	union uvh_node_id_u node_id;
7479f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size;
748d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val, n_io;
749c4ed3f04ba9defe22aa729d1646f970f791c03d7Jack Steiner	int gnode_extra, max_pnode = 0;
7506a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner	unsigned long mmr_base, present, paddr;
751d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	unsigned short pnode_mask, pnode_io_mask;
752ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
7532a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	printk(KERN_INFO "UV: Found %s hub\n", is_uv1_hub() ? "UV1" : "UV2");
754918bc960dc630b1a79c0d2991a81985812ff69f5Jack Steiner	map_low_mmrs();
755918bc960dc630b1a79c0d2991a81985812ff69f5Jack Steiner
75662b0cfc240b1d4601333912ef8760e0ca9ec2cecJack Steiner	m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR );
7579f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	m_val = m_n_config.s.m_skt;
7589f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	n_val = m_n_config.s.n_skt;
759d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR);
7602a919596c16b4333af851ff473ebf96e289ab90cJack Steiner	n_io = is_uv1_hub() ? mmioh.s1.n_io : mmioh.s2.n_io;
761ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	mmr_base =
762ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	    uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
763ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	    ~UV_MMR_ENABLE;
764c4ed3f04ba9defe22aa729d1646f970f791c03d7Jack Steiner	pnode_mask = (1 << n_val) - 1;
765d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	pnode_io_mask = (1 << n_io) - 1;
766d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner
767c4ed3f04ba9defe22aa729d1646f970f791c03d7Jack Steiner	node_id.v = uv_read_local_mmr(UVH_NODE_ID);
768c4ed3f04ba9defe22aa729d1646f970f791c03d7Jack Steiner	gnode_extra = (node_id.s.node_id & ~((1 << n_val) - 1)) >> 1;
769c4ed3f04ba9defe22aa729d1646f970f791c03d7Jack Steiner	gnode_upper = ((unsigned long)gnode_extra  << m_val);
770d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	printk(KERN_INFO "UV: N %d, M %d, N_IO: %d, gnode_upper 0x%lx, gnode_extra 0x%x, pnode_mask 0x%x, pnode_io_mask 0x%x\n",
771d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner			n_val, m_val, n_io, gnode_upper, gnode_extra, pnode_mask, pnode_io_mask);
772c4ed3f04ba9defe22aa729d1646f970f791c03d7Jack Steiner
773ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base);
774ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
7759f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++)
7769f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		uv_possible_blades +=
7779f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		  hweight64(uv_read_local_mmr( UVH_NODE_PRESENT_TABLE + i * 8));
778da517a08ac5913cd80ce3507cddd00f2a091b13cJack Steiner
779da517a08ac5913cd80ce3507cddd00f2a091b13cJack Steiner	/* uv_num_possible_blades() is really the hub count */
780da517a08ac5913cd80ce3507cddd00f2a091b13cJack Steiner	printk(KERN_INFO "UV: Found %d blades, %d hubs\n",
781da517a08ac5913cd80ce3507cddd00f2a091b13cJack Steiner			is_uv1_hub() ? uv_num_possible_blades() :
782da517a08ac5913cd80ce3507cddd00f2a091b13cJack Steiner			(uv_num_possible_blades() + 1) / 2,
783da517a08ac5913cd80ce3507cddd00f2a091b13cJack Steiner			uv_num_possible_blades());
784ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
785ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades();
7861d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner	uv_blade_info = kzalloc(bytes, GFP_KERNEL);
7879a8709d44139748fe2e0ab56d20d8c384c8b65adCyrill Gorcunov	BUG_ON(!uv_blade_info);
7881d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner
7896c7184b77464261b7d55583a48accbd1350923a3Jack Steiner	for (blade = 0; blade < uv_num_possible_blades(); blade++)
7906c7184b77464261b7d55583a48accbd1350923a3Jack Steiner		uv_blade_info[blade].memory_nid = -1;
791ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
7929f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size);
7939f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner
794ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes();
795ef020ab0109aa5cd6eac2e93519b7641c9862828Cliff Wickman	uv_node_to_blade = kmalloc(bytes, GFP_KERNEL);
7969a8709d44139748fe2e0ab56d20d8c384c8b65adCyrill Gorcunov	BUG_ON(!uv_node_to_blade);
797ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	memset(uv_node_to_blade, 255, bytes);
798ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
799ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus();
800ef020ab0109aa5cd6eac2e93519b7641c9862828Cliff Wickman	uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL);
8019a8709d44139748fe2e0ab56d20d8c384c8b65adCyrill Gorcunov	BUG_ON(!uv_cpu_to_blade);
802ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	memset(uv_cpu_to_blade, 255, bytes);
803ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
8049f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	blade = 0;
8059f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	for (i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) {
8069f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		present = uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8);
8079f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		for (j = 0; j < 64; j++) {
8089f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner			if (!test_bit(j, &present))
8099f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner				continue;
810d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner			pnode = (i * 64 + j) & pnode_mask;
81136ac4b987bea9a95217e1af552252f275ca7fc44Jack Steiner			uv_blade_info[blade].pnode = pnode;
8129f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner			uv_blade_info[blade].nr_possible_cpus = 0;
813ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner			uv_blade_info[blade].nr_online_cpus = 0;
8141d44e8288a0557c28c447d7e511f50d06ff93a34Jack Steiner			spin_lock_init(&uv_blade_info[blade].nmi_lock);
81536ac4b987bea9a95217e1af552252f275ca7fc44Jack Steiner			max_pnode = max(pnode, max_pnode);
8169f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner			blade++;
817ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner		}
8189f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	}
819ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
8207f5942329e0787087a5e4dced838cee711ac2b58Russ Anderson	uv_bios_init();
821b76365a18f7593c9df32a74bf2b4a39741b67bc6Russ Anderson	uv_bios_get_sn_info(0, &uv_type, &sn_partition_id, &sn_coherency_id,
822b76365a18f7593c9df32a74bf2b4a39741b67bc6Russ Anderson			    &sn_region_size, &system_serial_number);
8237019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson	uv_rtc_init();
8247019cc2dd6fafcdc6b104005482dc910dcdbb797Russ Anderson
8259f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner	for_each_present_cpu(cpu) {
82639d30770992895d55789de64bad2349510af68d0Mike Travis		int apicid = per_cpu(x86_cpu_to_apicid, cpu);
82739d30770992895d55789de64bad2349510af68d0Mike Travis
8289f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		nid = cpu_to_node(cpu);
829c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson		/*
830c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson		 * apic_pnode_shift must be set before calling uv_apicid_to_pnode();
831c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson		 */
832d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner		uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask;
833c8f730b1ab825f06733e1c074264f0078721f365Russ Anderson		uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift;
8342a919596c16b4333af851ff473ebf96e289ab90cJack Steiner		uv_cpu_hub_info(cpu)->hub_revision = uv_hub_info->hub_revision;
8352a919596c16b4333af851ff473ebf96e289ab90cJack Steiner
8366a469e4665bc158599de55d64388861d0a9f10f4Jack Steiner		uv_cpu_hub_info(cpu)->m_shift = 64 - m_val;
8376a469e4665bc158599de55d64388861d0a9f10f4Jack Steiner		uv_cpu_hub_info(cpu)->n_lshift = is_uv2_1_hub() ?
8386a469e4665bc158599de55d64388861d0a9f10f4Jack Steiner				(m_val == 40 ? 40 : 39) : m_val;
8396a469e4665bc158599de55d64388861d0a9f10f4Jack Steiner
84039d30770992895d55789de64bad2349510af68d0Mike Travis		pnode = uv_apicid_to_pnode(apicid);
8419f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		blade = boot_pnode_to_blade(pnode);
8429f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		lcpu = uv_blade_info[blade].nr_possible_cpus;
8439f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		uv_blade_info[blade].nr_possible_cpus++;
8449f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner
8456c7184b77464261b7d55583a48accbd1350923a3Jack Steiner		/* Any node on the blade, else will contain -1. */
8466c7184b77464261b7d55583a48accbd1350923a3Jack Steiner		uv_blade_info[blade].memory_nid = nid;
8476c7184b77464261b7d55583a48accbd1350923a3Jack Steiner
8489f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base;
849189f67c4408806563a1f061f5c8bf184a6658477Jack Steiner		uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size;
8509f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		uv_cpu_hub_info(cpu)->m_val = m_val;
851036ed8ba61b72c19dc5759446d4fe0844aa88255Robin Holt		uv_cpu_hub_info(cpu)->n_val = n_val;
852ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner		uv_cpu_hub_info(cpu)->numa_blade_id = blade;
853ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner		uv_cpu_hub_info(cpu)->blade_processor_id = lcpu;
8549f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		uv_cpu_hub_info(cpu)->pnode = pnode;
855036ed8ba61b72c19dc5759446d4fe0844aa88255Robin Holt		uv_cpu_hub_info(cpu)->gpa_mask = (1UL << (m_val + n_val)) - 1;
8569f5314fb4d556d3132c784d0df47352b2830ca53Jack Steiner		uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
857c4ed3f04ba9defe22aa729d1646f970f791c03d7Jack Steiner		uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
858ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner		uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
859b0f209898f1a177bd503d49215b8c6628797a81cRuss Anderson		uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
86039d30770992895d55789de64bad2349510af68d0Mike Travis		uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
861ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner		uv_node_to_blade[nid] = blade;
862ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner		uv_cpu_to_blade[cpu] = blade;
863ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner	}
86483f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner
8656a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner	/* Add blade/pnode info for nodes without cpus */
8666a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner	for_each_online_node(nid) {
8676a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner		if (uv_node_to_blade[nid] >= 0)
8686a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner			continue;
8696a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner		paddr = node_start_pfn(nid) << PAGE_SHIFT;
8706a469e4665bc158599de55d64388861d0a9f10f4Jack Steiner		pnode = uv_gpa_to_pnode(uv_soc_phys_ram_to_gpa(paddr));
8716a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner		blade = boot_pnode_to_blade(pnode);
8726a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner		uv_node_to_blade[nid] = blade;
8736a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner	}
8746a891a24e4d0056c365a90ff2d71c38fd366b0d0Jack Steiner
87583f5d894ca5280bfcd904dfeb1347c2da2b19aacJack Steiner	map_gru_high(max_pnode);
876daf7b9c9216e2b82e4c14b7248a85286dab021c3Jack Steiner	map_mmr_high(max_pnode);
877d8850ba425d9823d3184bd52f065899dac4689f9Jack Steiner	map_mmioh_high(max_pnode & pnode_io_mask);
878ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner
8798da077d6f31da291ee3a7dd559671cb8ca48cbe2Jack Steiner	uv_cpu_init();
8807f1baa063e2582dd52d83bb31508e9e84468c666Mike Travis	uv_scir_register_cpu_notifier();
88178c06176466cbd1b3f0f67709d3023c40dbebcbdRuss Anderson	uv_register_nmi_notifier();
882a3d732f93785da17e0137210deadb4616f5536fcCliff Wickman	proc_mkdir("sgi_uv", NULL);
883841582ea9e29a8f757c30c5377ce649586ba793aMike Travis
884841582ea9e29a8f757c30c5377ce649586ba793aMike Travis	/* register Legacy VGA I/O redirection handler */
885841582ea9e29a8f757c30c5377ce649586ba793aMike Travis	pci_register_set_vga_state(uv_set_vga_state);
886818987e9a19c52240ba9b1c20f28f047eef76072Cliff Wickman
887818987e9a19c52240ba9b1c20f28f047eef76072Cliff Wickman	/*
888818987e9a19c52240ba9b1c20f28f047eef76072Cliff Wickman	 * For a kdump kernel the reset must be BOOT_ACPI, not BOOT_EFI, as
889818987e9a19c52240ba9b1c20f28f047eef76072Cliff Wickman	 * EFI is not enabled in the kdump kernel.
890818987e9a19c52240ba9b1c20f28f047eef76072Cliff Wickman	 */
891818987e9a19c52240ba9b1c20f28f047eef76072Cliff Wickman	if (is_kdump_kernel())
892818987e9a19c52240ba9b1c20f28f047eef76072Cliff Wickman		reboot_type = BOOT_ACPI;
893ac23d4ee3f84de33c16ed7e68f9adee2386e74fbJack Steiner}
894107e0e0cd85beeee05af7ea374fda14d037ee500Suresh Siddha
895107e0e0cd85beeee05af7ea374fda14d037ee500Suresh Siddhaapic_driver(apic_x2apic_uv_x);
896