12224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner/* 22224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner * This file is subject to the terms and conditions of the GNU General Public 32224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner * License. See the file "COPYING" in the main directory of this archive 42224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner * for more details. 52224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner * 62224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner * SGI UV Core Functions 72224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner * 82224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. 92224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner */ 102224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 112224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner#include <linux/module.h> 122224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner#include <linux/percpu.h> 132224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner#include <asm/sn/simulator.h> 142224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner#include <asm/uv/uv_mmrs.h> 152224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner#include <asm/uv/uv_hub.h> 162224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 172224661494278bfc1c35b392cf6ee6f58e1d5e64Jack SteinerDEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); 182224661494278bfc1c35b392cf6ee6f58e1d5e64Jack SteinerEXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info); 192224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 20732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner#ifdef CONFIG_IA64_SGI_UV 21732a675a6303156d1a197dc780b0712bd4b49d46Jack Steinerint sn_prom_type; 229ac8d3fb22b593d39d161dcd716af0f1f7546837Russ Andersonlong sn_partition_id; 239ac8d3fb22b593d39d161dcd716af0f1f7546837Russ AndersonEXPORT_SYMBOL(sn_partition_id); 249ac8d3fb22b593d39d161dcd716af0f1f7546837Russ Andersonlong sn_coherency_id; 259ac8d3fb22b593d39d161dcd716af0f1f7546837Russ AndersonEXPORT_SYMBOL_GPL(sn_coherency_id); 269ac8d3fb22b593d39d161dcd716af0f1f7546837Russ Andersonlong sn_region_size; 279ac8d3fb22b593d39d161dcd716af0f1f7546837Russ AndersonEXPORT_SYMBOL(sn_region_size); 28732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner#endif 292224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 302224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steinerstruct redir_addr { 312224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner unsigned long redirect; 322224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner unsigned long alias; 332224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner}; 342224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 352224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT 362224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 372224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steinerstatic __initdata struct redir_addr redir_addrs[] = { 382224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG}, 392224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG}, 402224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG}, 412224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner}; 422224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 432224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steinerstatic __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) 442224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner{ 452224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner union uvh_si_alias0_overlay_config_u alias; 462224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; 472224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner int i; 482224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 492224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) { 502224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner alias.v = uv_read_local_mmr(redir_addrs[i].alias); 512224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner if (alias.s.base == 0) { 522224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner *size = (1UL << alias.s.m_alias); 532224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner redirect.v = uv_read_local_mmr(redir_addrs[i].redirect); 542224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner *base = (unsigned long)redirect.s.dest_base << DEST_SHIFT; 552224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner return; 562224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner } 572224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner } 582224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner BUG(); 592224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner} 602224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 612224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steinervoid __init uv_setup(char **cmdline_p) 622224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner{ 632224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner union uvh_si_addr_map_config_u m_n_config; 642224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner union uvh_node_id_u node_id; 652224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner unsigned long gnode_upper; 662224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner int nid, cpu, m_val, n_val; 672224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner unsigned long mmr_base, lowmem_redir_base, lowmem_redir_size; 682224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 692224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner if (IS_MEDUSA()) { 702224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner lowmem_redir_base = 0; 712224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner lowmem_redir_size = 0; 722224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner node_id.v = 0; 732224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner m_n_config.s.m_skt = 37; 742224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner m_n_config.s.n_skt = 0; 752224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner mmr_base = 0; 76732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner#if 0 77732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner /* Need BIOS calls - TDB */ 78732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner if (!ia64_sn_is_fake_prom()) 79732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner sn_prom_type = 1; 80732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner else 81732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner#endif 82732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner sn_prom_type = 2; 83732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner printk(KERN_INFO "Running on medusa with %s PROM\n", 84732a675a6303156d1a197dc780b0712bd4b49d46Jack Steiner (sn_prom_type == 1) ? "real" : "fake"); 852224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner } else { 862224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); 872224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner node_id.v = uv_read_local_mmr(UVH_NODE_ID); 882224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); 892224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner mmr_base = 902224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & 912224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner ~UV_MMR_ENABLE; 922224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner } 932224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 942224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner m_val = m_n_config.s.m_skt; 952224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner n_val = m_n_config.s.n_skt; 962224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base); 972224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 982224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner gnode_upper = (((unsigned long)node_id.s.node_id) & 992224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner ~((1 << n_val) - 1)) << m_val; 1002224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 1012224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner for_each_present_cpu(cpu) { 1022224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner nid = cpu_to_node(cpu); 1032224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base; 1042224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner uv_cpu_hub_info(cpu)->lowmem_remap_top = 1052224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner lowmem_redir_base + lowmem_redir_size; 1062224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner uv_cpu_hub_info(cpu)->m_val = m_val; 107b6dcefdef49000fc871a851cba4b48454343cde5Roel Kluin uv_cpu_hub_info(cpu)->n_val = n_val; 1082224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner uv_cpu_hub_info(cpu)->pnode_mask = (1 << n_val) -1; 1092224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; 1102224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; 1112224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; 1122224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */ 1132224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner printk(KERN_DEBUG "UV cpu %d, nid %d\n", cpu, nid); 1142224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner } 1152224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner} 1162224661494278bfc1c35b392cf6ee6f58e1d5e64Jack Steiner 117