18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 38c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 48c2ecf20Sopenharmony_ci * for more details. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * SGI UV architectural definitions 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifndef __ASM_IA64_UV_HUB_H__ 128c2ecf20Sopenharmony_ci#define __ASM_IA64_UV_HUB_H__ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <linux/numa.h> 158c2ecf20Sopenharmony_ci#include <linux/percpu.h> 168c2ecf20Sopenharmony_ci#include <asm/types.h> 178c2ecf20Sopenharmony_ci#include <asm/percpu.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* 218c2ecf20Sopenharmony_ci * Addressing Terminology 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * M - The low M bits of a physical address represent the offset 248c2ecf20Sopenharmony_ci * into the blade local memory. RAM memory on a blade is physically 258c2ecf20Sopenharmony_ci * contiguous (although various IO spaces may punch holes in 268c2ecf20Sopenharmony_ci * it).. 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * N - Number of bits in the node portion of a socket physical 298c2ecf20Sopenharmony_ci * address. 308c2ecf20Sopenharmony_ci * 318c2ecf20Sopenharmony_ci * NASID - network ID of a router, Mbrick or Cbrick. Nasid values of 328c2ecf20Sopenharmony_ci * routers always have low bit of 1, C/MBricks have low bit 338c2ecf20Sopenharmony_ci * equal to 0. Most addressing macros that target UV hub chips 348c2ecf20Sopenharmony_ci * right shift the NASID by 1 to exclude the always-zero bit. 358c2ecf20Sopenharmony_ci * NASIDs contain up to 15 bits. 368c2ecf20Sopenharmony_ci * 378c2ecf20Sopenharmony_ci * GNODE - NASID right shifted by 1 bit. Most mmrs contain gnodes instead 388c2ecf20Sopenharmony_ci * of nasids. 398c2ecf20Sopenharmony_ci * 408c2ecf20Sopenharmony_ci * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant 418c2ecf20Sopenharmony_ci * of the nasid for socket usage. 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * 448c2ecf20Sopenharmony_ci * NumaLink Global Physical Address Format: 458c2ecf20Sopenharmony_ci * +--------------------------------+---------------------+ 468c2ecf20Sopenharmony_ci * |00..000| GNODE | NodeOffset | 478c2ecf20Sopenharmony_ci * +--------------------------------+---------------------+ 488c2ecf20Sopenharmony_ci * |<-------53 - M bits --->|<--------M bits -----> 498c2ecf20Sopenharmony_ci * 508c2ecf20Sopenharmony_ci * M - number of node offset bits (35 .. 40) 518c2ecf20Sopenharmony_ci * 528c2ecf20Sopenharmony_ci * 538c2ecf20Sopenharmony_ci * Memory/UV-HUB Processor Socket Address Format: 548c2ecf20Sopenharmony_ci * +----------------+---------------+---------------------+ 558c2ecf20Sopenharmony_ci * |00..000000000000| PNODE | NodeOffset | 568c2ecf20Sopenharmony_ci * +----------------+---------------+---------------------+ 578c2ecf20Sopenharmony_ci * <--- N bits --->|<--------M bits -----> 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * M - number of node offset bits (35 .. 40) 608c2ecf20Sopenharmony_ci * N - number of PNODE bits (0 .. 10) 618c2ecf20Sopenharmony_ci * 628c2ecf20Sopenharmony_ci * Note: M + N cannot currently exceed 44 (x86_64) or 46 (IA64). 638c2ecf20Sopenharmony_ci * The actual values are configuration dependent and are set at 648c2ecf20Sopenharmony_ci * boot time. M & N values are set by the hardware/BIOS at boot. 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* 698c2ecf20Sopenharmony_ci * Maximum number of bricks in all partitions and in all coherency domains. 708c2ecf20Sopenharmony_ci * This is the total number of bricks accessible in the numalink fabric. It 718c2ecf20Sopenharmony_ci * includes all C & M bricks. Routers are NOT included. 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci * This value is also the value of the maximum number of non-router NASIDs 748c2ecf20Sopenharmony_ci * in the numalink fabric. 758c2ecf20Sopenharmony_ci * 768c2ecf20Sopenharmony_ci * NOTE: a brick may contain 1 or 2 OS nodes. Don't get these confused. 778c2ecf20Sopenharmony_ci */ 788c2ecf20Sopenharmony_ci#define UV_MAX_NUMALINK_BLADES 16384 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci/* 818c2ecf20Sopenharmony_ci * Maximum number of C/Mbricks within a software SSI (hardware may support 828c2ecf20Sopenharmony_ci * more). 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci#define UV_MAX_SSI_BLADES 1 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* 878c2ecf20Sopenharmony_ci * The largest possible NASID of a C or M brick (+ 2) 888c2ecf20Sopenharmony_ci */ 898c2ecf20Sopenharmony_ci#define UV_MAX_NASID_VALUE (UV_MAX_NUMALINK_NODES * 2) 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci/* 928c2ecf20Sopenharmony_ci * The following defines attributes of the HUB chip. These attributes are 938c2ecf20Sopenharmony_ci * frequently referenced and are kept in the per-cpu data areas of each cpu. 948c2ecf20Sopenharmony_ci * They are kept together in a struct to minimize cache misses. 958c2ecf20Sopenharmony_ci */ 968c2ecf20Sopenharmony_cistruct uv_hub_info_s { 978c2ecf20Sopenharmony_ci unsigned long global_mmr_base; 988c2ecf20Sopenharmony_ci unsigned long gpa_mask; 998c2ecf20Sopenharmony_ci unsigned long gnode_upper; 1008c2ecf20Sopenharmony_ci unsigned long lowmem_remap_top; 1018c2ecf20Sopenharmony_ci unsigned long lowmem_remap_base; 1028c2ecf20Sopenharmony_ci unsigned short pnode; 1038c2ecf20Sopenharmony_ci unsigned short pnode_mask; 1048c2ecf20Sopenharmony_ci unsigned short coherency_domain_number; 1058c2ecf20Sopenharmony_ci unsigned short numa_blade_id; 1068c2ecf20Sopenharmony_ci unsigned char blade_processor_id; 1078c2ecf20Sopenharmony_ci unsigned char m_val; 1088c2ecf20Sopenharmony_ci unsigned char n_val; 1098c2ecf20Sopenharmony_ci}; 1108c2ecf20Sopenharmony_ciDECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); 1118c2ecf20Sopenharmony_ci#define uv_hub_info this_cpu_ptr(&__uv_hub_info) 1128c2ecf20Sopenharmony_ci#define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci/* 1158c2ecf20Sopenharmony_ci * Local & Global MMR space macros. 1168c2ecf20Sopenharmony_ci * Note: macros are intended to be used ONLY by inline functions 1178c2ecf20Sopenharmony_ci * in this file - not by other kernel code. 1188c2ecf20Sopenharmony_ci * n - NASID (full 15-bit global nasid) 1198c2ecf20Sopenharmony_ci * g - GNODE (full 15-bit global nasid, right shifted 1) 1208c2ecf20Sopenharmony_ci * p - PNODE (local part of nsids, right shifted 1) 1218c2ecf20Sopenharmony_ci */ 1228c2ecf20Sopenharmony_ci#define UV_NASID_TO_PNODE(n) (((n) >> 1) & uv_hub_info->pnode_mask) 1238c2ecf20Sopenharmony_ci#define UV_PNODE_TO_NASID(p) (((p) << 1) | uv_hub_info->gnode_upper) 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci#define UV_LOCAL_MMR_BASE 0xf4000000UL 1268c2ecf20Sopenharmony_ci#define UV_GLOBAL_MMR32_BASE 0xf8000000UL 1278c2ecf20Sopenharmony_ci#define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base) 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci#define UV_GLOBAL_MMR32_PNODE_SHIFT 15 1308c2ecf20Sopenharmony_ci#define UV_GLOBAL_MMR64_PNODE_SHIFT 26 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci#define UV_GLOBAL_MMR32_PNODE_BITS(p) ((p) << (UV_GLOBAL_MMR32_PNODE_SHIFT)) 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci#define UV_GLOBAL_MMR64_PNODE_BITS(p) \ 1358c2ecf20Sopenharmony_ci ((unsigned long)(p) << UV_GLOBAL_MMR64_PNODE_SHIFT) 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci/* 1388c2ecf20Sopenharmony_ci * Macros for converting between kernel virtual addresses, socket local physical 1398c2ecf20Sopenharmony_ci * addresses, and UV global physical addresses. 1408c2ecf20Sopenharmony_ci * Note: use the standard __pa() & __va() macros for converting 1418c2ecf20Sopenharmony_ci * between socket virtual and socket physical addresses. 1428c2ecf20Sopenharmony_ci */ 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci/* socket phys RAM --> UV global physical address */ 1458c2ecf20Sopenharmony_cistatic inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr) 1468c2ecf20Sopenharmony_ci{ 1478c2ecf20Sopenharmony_ci if (paddr < uv_hub_info->lowmem_remap_top) 1488c2ecf20Sopenharmony_ci paddr += uv_hub_info->lowmem_remap_base; 1498c2ecf20Sopenharmony_ci return paddr | uv_hub_info->gnode_upper; 1508c2ecf20Sopenharmony_ci} 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci/* socket virtual --> UV global physical address */ 1548c2ecf20Sopenharmony_cistatic inline unsigned long uv_gpa(void *v) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci return __pa(v) | uv_hub_info->gnode_upper; 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci/* socket virtual --> UV global physical address */ 1608c2ecf20Sopenharmony_cistatic inline void *uv_vgpa(void *v) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci return (void *)uv_gpa(v); 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* UV global physical address --> socket virtual */ 1668c2ecf20Sopenharmony_cistatic inline void *uv_va(unsigned long gpa) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci return __va(gpa & uv_hub_info->gpa_mask); 1698c2ecf20Sopenharmony_ci} 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci/* pnode, offset --> socket virtual */ 1728c2ecf20Sopenharmony_cistatic inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci return __va(((unsigned long)pnode << uv_hub_info->m_val) | offset); 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci/* 1798c2ecf20Sopenharmony_ci * Access global MMRs using the low memory MMR32 space. This region supports 1808c2ecf20Sopenharmony_ci * faster MMR access but not all MMRs are accessible in this space. 1818c2ecf20Sopenharmony_ci */ 1828c2ecf20Sopenharmony_cistatic inline unsigned long *uv_global_mmr32_address(int pnode, 1838c2ecf20Sopenharmony_ci unsigned long offset) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci return __va(UV_GLOBAL_MMR32_BASE | 1868c2ecf20Sopenharmony_ci UV_GLOBAL_MMR32_PNODE_BITS(pnode) | offset); 1878c2ecf20Sopenharmony_ci} 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cistatic inline void uv_write_global_mmr32(int pnode, unsigned long offset, 1908c2ecf20Sopenharmony_ci unsigned long val) 1918c2ecf20Sopenharmony_ci{ 1928c2ecf20Sopenharmony_ci *uv_global_mmr32_address(pnode, offset) = val; 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_cistatic inline unsigned long uv_read_global_mmr32(int pnode, 1968c2ecf20Sopenharmony_ci unsigned long offset) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci return *uv_global_mmr32_address(pnode, offset); 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci/* 2028c2ecf20Sopenharmony_ci * Access Global MMR space using the MMR space located at the top of physical 2038c2ecf20Sopenharmony_ci * memory. 2048c2ecf20Sopenharmony_ci */ 2058c2ecf20Sopenharmony_cistatic inline unsigned long *uv_global_mmr64_address(int pnode, 2068c2ecf20Sopenharmony_ci unsigned long offset) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci return __va(UV_GLOBAL_MMR64_BASE | 2098c2ecf20Sopenharmony_ci UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset); 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic inline void uv_write_global_mmr64(int pnode, unsigned long offset, 2138c2ecf20Sopenharmony_ci unsigned long val) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci *uv_global_mmr64_address(pnode, offset) = val; 2168c2ecf20Sopenharmony_ci} 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_cistatic inline unsigned long uv_read_global_mmr64(int pnode, 2198c2ecf20Sopenharmony_ci unsigned long offset) 2208c2ecf20Sopenharmony_ci{ 2218c2ecf20Sopenharmony_ci return *uv_global_mmr64_address(pnode, offset); 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci/* 2258c2ecf20Sopenharmony_ci * Access hub local MMRs. Faster than using global space but only local MMRs 2268c2ecf20Sopenharmony_ci * are accessible. 2278c2ecf20Sopenharmony_ci */ 2288c2ecf20Sopenharmony_cistatic inline unsigned long *uv_local_mmr_address(unsigned long offset) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci return __va(UV_LOCAL_MMR_BASE | offset); 2318c2ecf20Sopenharmony_ci} 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_cistatic inline unsigned long uv_read_local_mmr(unsigned long offset) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci return *uv_local_mmr_address(offset); 2368c2ecf20Sopenharmony_ci} 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cistatic inline void uv_write_local_mmr(unsigned long offset, unsigned long val) 2398c2ecf20Sopenharmony_ci{ 2408c2ecf20Sopenharmony_ci *uv_local_mmr_address(offset) = val; 2418c2ecf20Sopenharmony_ci} 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci/* 2448c2ecf20Sopenharmony_ci * Structures and definitions for converting between cpu, node, pnode, and blade 2458c2ecf20Sopenharmony_ci * numbers. 2468c2ecf20Sopenharmony_ci */ 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci/* Blade-local cpu number of current cpu. Numbered 0 .. <# cpus on the blade> */ 2498c2ecf20Sopenharmony_cistatic inline int uv_blade_processor_id(void) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci return smp_processor_id(); 2528c2ecf20Sopenharmony_ci} 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci/* Blade number of current cpu. Numnbered 0 .. <#blades -1> */ 2558c2ecf20Sopenharmony_cistatic inline int uv_numa_blade_id(void) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci return 0; 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci/* Convert a cpu number to the the UV blade number */ 2618c2ecf20Sopenharmony_cistatic inline int uv_cpu_to_blade_id(int cpu) 2628c2ecf20Sopenharmony_ci{ 2638c2ecf20Sopenharmony_ci return 0; 2648c2ecf20Sopenharmony_ci} 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci/* Convert linux node number to the UV blade number */ 2678c2ecf20Sopenharmony_cistatic inline int uv_node_to_blade_id(int nid) 2688c2ecf20Sopenharmony_ci{ 2698c2ecf20Sopenharmony_ci return 0; 2708c2ecf20Sopenharmony_ci} 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci/* Convert a blade id to the PNODE of the blade */ 2738c2ecf20Sopenharmony_cistatic inline int uv_blade_to_pnode(int bid) 2748c2ecf20Sopenharmony_ci{ 2758c2ecf20Sopenharmony_ci return 0; 2768c2ecf20Sopenharmony_ci} 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci/* Determine the number of possible cpus on a blade */ 2798c2ecf20Sopenharmony_cistatic inline int uv_blade_nr_possible_cpus(int bid) 2808c2ecf20Sopenharmony_ci{ 2818c2ecf20Sopenharmony_ci return num_possible_cpus(); 2828c2ecf20Sopenharmony_ci} 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci/* Determine the number of online cpus on a blade */ 2858c2ecf20Sopenharmony_cistatic inline int uv_blade_nr_online_cpus(int bid) 2868c2ecf20Sopenharmony_ci{ 2878c2ecf20Sopenharmony_ci return num_online_cpus(); 2888c2ecf20Sopenharmony_ci} 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci/* Convert a cpu id to the PNODE of the blade containing the cpu */ 2918c2ecf20Sopenharmony_cistatic inline int uv_cpu_to_pnode(int cpu) 2928c2ecf20Sopenharmony_ci{ 2938c2ecf20Sopenharmony_ci return 0; 2948c2ecf20Sopenharmony_ci} 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci/* Convert a linux node number to the PNODE of the blade */ 2978c2ecf20Sopenharmony_cistatic inline int uv_node_to_pnode(int nid) 2988c2ecf20Sopenharmony_ci{ 2998c2ecf20Sopenharmony_ci return 0; 3008c2ecf20Sopenharmony_ci} 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci/* Maximum possible number of blades */ 3038c2ecf20Sopenharmony_cistatic inline int uv_num_possible_blades(void) 3048c2ecf20Sopenharmony_ci{ 3058c2ecf20Sopenharmony_ci return 1; 3068c2ecf20Sopenharmony_ci} 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_cistatic inline void uv_hub_send_ipi(int pnode, int apicid, int vector) 3098c2ecf20Sopenharmony_ci{ 3108c2ecf20Sopenharmony_ci /* not currently needed on ia64 */ 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci#endif /* __ASM_IA64_UV_HUB__ */ 3158c2ecf20Sopenharmony_ci 316