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