uv_hub.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * SGI UV architectural definitions
  7. *
  8. * Copyright (C) 2007 Silicon Graphics, Inc. All rights reserved.
  9. */
  10. #ifndef __ASM_X86_UV_HUB_H__
  11. #define __ASM_X86_UV_HUB_H__
  12. #include <linux/numa.h>
  13. #include <linux/percpu.h>
  14. #include <asm/types.h>
  15. #include <asm/percpu.h>
  16. /*
  17. * Addressing Terminology
  18. *
  19. * NASID - network ID of a router, Mbrick or Cbrick. Nasid values of
  20. * routers always have low bit of 1, C/MBricks have low bit
  21. * equal to 0. Most addressing macros that target UV hub chips
  22. * right shift the NASID by 1 to exclude the always-zero bit.
  23. *
  24. * SNASID - NASID right shifted by 1 bit.
  25. *
  26. *
  27. * Memory/UV-HUB Processor Socket Address Format:
  28. * +--------+---------------+---------------------+
  29. * |00..0000| SNASID | NodeOffset |
  30. * +--------+---------------+---------------------+
  31. * <--- N bits --->|<--------M bits ----->
  32. *
  33. * M number of node offset bits (35 .. 40)
  34. * N number of SNASID bits (0 .. 10)
  35. *
  36. * Note: M + N cannot currently exceed 44 (x86_64) or 46 (IA64).
  37. * The actual values are configuration dependent and are set at
  38. * boot time
  39. *
  40. * APICID format
  41. * NOTE!!!!!! This is the current format of the APICID. However, code
  42. * should assume that this will change in the future. Use functions
  43. * in this file for all APICID bit manipulations and conversion.
  44. *
  45. * 1111110000000000
  46. * 5432109876543210
  47. * nnnnnnnnnnlc0cch
  48. * sssssssssss
  49. *
  50. * n = snasid bits
  51. * l = socket number on board
  52. * c = core
  53. * h = hyperthread
  54. * s = bits that are in the socket CSR
  55. *
  56. * Note: Processor only supports 12 bits in the APICID register. The ACPI
  57. * tables hold all 16 bits. Software needs to be aware of this.
  58. *
  59. * Unless otherwise specified, all references to APICID refer to
  60. * the FULL value contained in ACPI tables, not the subset in the
  61. * processor APICID register.
  62. */
  63. /*
  64. * Maximum number of bricks in all partitions and in all coherency domains.
  65. * This is the total number of bricks accessible in the numalink fabric. It
  66. * includes all C & M bricks. Routers are NOT included.
  67. *
  68. * This value is also the value of the maximum number of non-router NASIDs
  69. * in the numalink fabric.
  70. *
  71. * NOTE: a brick may be 1 or 2 OS nodes. Don't get these confused.
  72. */
  73. #define UV_MAX_NUMALINK_BLADES 16384
  74. /*
  75. * Maximum number of C/Mbricks within a software SSI (hardware may support
  76. * more).
  77. */
  78. #define UV_MAX_SSI_BLADES 256
  79. /*
  80. * The largest possible NASID of a C or M brick (+ 2)
  81. */
  82. #define UV_MAX_NASID_VALUE (UV_MAX_NUMALINK_NODES * 2)
  83. /*
  84. * The following defines attributes of the HUB chip. These attributes are
  85. * frequently referenced and are kept in the per-cpu data areas of each cpu.
  86. * They are kept together in a struct to minimize cache misses.
  87. */
  88. struct uv_hub_info_s {
  89. unsigned long global_mmr_base;
  90. unsigned short local_nasid;
  91. unsigned short gnode_upper;
  92. unsigned short coherency_domain_number;
  93. unsigned short numa_blade_id;
  94. unsigned char blade_processor_id;
  95. unsigned char m_val;
  96. unsigned char n_val;
  97. };
  98. DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
  99. #define uv_hub_info (&__get_cpu_var(__uv_hub_info))
  100. #define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu))
  101. /*
  102. * Local & Global MMR space macros.
  103. * Note: macros are intended to be used ONLY by inline functions
  104. * in this file - not by other kernel code.
  105. */
  106. #define UV_SNASID(n) ((n) >> 1)
  107. #define UV_NASID(n) ((n) << 1)
  108. #define UV_LOCAL_MMR_BASE 0xf4000000UL
  109. #define UV_GLOBAL_MMR32_BASE 0xf8000000UL
  110. #define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base)
  111. #define UV_GLOBAL_MMR32_SNASID_MASK 0x3ff
  112. #define UV_GLOBAL_MMR32_SNASID_SHIFT 15
  113. #define UV_GLOBAL_MMR64_SNASID_SHIFT 26
  114. #define UV_GLOBAL_MMR32_NASID_BITS(n) \
  115. (((UV_SNASID(n) & UV_GLOBAL_MMR32_SNASID_MASK)) << \
  116. (UV_GLOBAL_MMR32_SNASID_SHIFT))
  117. #define UV_GLOBAL_MMR64_NASID_BITS(n) \
  118. ((unsigned long)UV_SNASID(n) << UV_GLOBAL_MMR64_SNASID_SHIFT)
  119. #define UV_APIC_NASID_SHIFT 6
  120. /*
  121. * Extract a NASID from an APICID (full apicid, not processor subset)
  122. */
  123. static inline int uv_apicid_to_nasid(int apicid)
  124. {
  125. return (UV_NASID(apicid >> UV_APIC_NASID_SHIFT));
  126. }
  127. /*
  128. * Access global MMRs using the low memory MMR32 space. This region supports
  129. * faster MMR access but not all MMRs are accessible in this space.
  130. */
  131. static inline unsigned long *uv_global_mmr32_address(int nasid,
  132. unsigned long offset)
  133. {
  134. return __va(UV_GLOBAL_MMR32_BASE |
  135. UV_GLOBAL_MMR32_NASID_BITS(nasid) | offset);
  136. }
  137. static inline void uv_write_global_mmr32(int nasid, unsigned long offset,
  138. unsigned long val)
  139. {
  140. *uv_global_mmr32_address(nasid, offset) = val;
  141. }
  142. static inline unsigned long uv_read_global_mmr32(int nasid,
  143. unsigned long offset)
  144. {
  145. return *uv_global_mmr32_address(nasid, offset);
  146. }
  147. /*
  148. * Access Global MMR space using the MMR space located at the top of physical
  149. * memory.
  150. */
  151. static inline unsigned long *uv_global_mmr64_address(int nasid,
  152. unsigned long offset)
  153. {
  154. return __va(UV_GLOBAL_MMR64_BASE |
  155. UV_GLOBAL_MMR64_NASID_BITS(nasid) | offset);
  156. }
  157. static inline void uv_write_global_mmr64(int nasid, unsigned long offset,
  158. unsigned long val)
  159. {
  160. *uv_global_mmr64_address(nasid, offset) = val;
  161. }
  162. static inline unsigned long uv_read_global_mmr64(int nasid,
  163. unsigned long offset)
  164. {
  165. return *uv_global_mmr64_address(nasid, offset);
  166. }
  167. /*
  168. * Access node local MMRs. Faster than using global space but only local MMRs
  169. * are accessible.
  170. */
  171. static inline unsigned long *uv_local_mmr_address(unsigned long offset)
  172. {
  173. return __va(UV_LOCAL_MMR_BASE | offset);
  174. }
  175. static inline unsigned long uv_read_local_mmr(unsigned long offset)
  176. {
  177. return *uv_local_mmr_address(offset);
  178. }
  179. static inline void uv_write_local_mmr(unsigned long offset, unsigned long val)
  180. {
  181. *uv_local_mmr_address(offset) = val;
  182. }
  183. /*
  184. * Structures and definitions for converting between cpu, node, and blade
  185. * numbers.
  186. */
  187. struct uv_blade_info {
  188. unsigned short nr_posible_cpus;
  189. unsigned short nr_online_cpus;
  190. unsigned short nasid;
  191. };
  192. struct uv_blade_info *uv_blade_info;
  193. extern short *uv_node_to_blade;
  194. extern short *uv_cpu_to_blade;
  195. extern short uv_possible_blades;
  196. /* Blade-local cpu number of current cpu. Numbered 0 .. <# cpus on the blade> */
  197. static inline int uv_blade_processor_id(void)
  198. {
  199. return uv_hub_info->blade_processor_id;
  200. }
  201. /* Blade number of current cpu. Numnbered 0 .. <#blades -1> */
  202. static inline int uv_numa_blade_id(void)
  203. {
  204. return uv_hub_info->numa_blade_id;
  205. }
  206. /* Convert a cpu number to the the UV blade number */
  207. static inline int uv_cpu_to_blade_id(int cpu)
  208. {
  209. return uv_cpu_to_blade[cpu];
  210. }
  211. /* Convert linux node number to the UV blade number */
  212. static inline int uv_node_to_blade_id(int nid)
  213. {
  214. return uv_node_to_blade[nid];
  215. }
  216. /* Convert a blade id to the NASID of the blade */
  217. static inline int uv_blade_to_nasid(int bid)
  218. {
  219. return uv_blade_info[bid].nasid;
  220. }
  221. /* Determine the number of possible cpus on a blade */
  222. static inline int uv_blade_nr_possible_cpus(int bid)
  223. {
  224. return uv_blade_info[bid].nr_posible_cpus;
  225. }
  226. /* Determine the number of online cpus on a blade */
  227. static inline int uv_blade_nr_online_cpus(int bid)
  228. {
  229. return uv_blade_info[bid].nr_online_cpus;
  230. }
  231. /* Convert a cpu id to the NASID of the blade containing the cpu */
  232. static inline int uv_cpu_to_nasid(int cpu)
  233. {
  234. return uv_blade_info[uv_cpu_to_blade_id(cpu)].nasid;
  235. }
  236. /* Convert a node number to the NASID of the blade */
  237. static inline int uv_node_to_nasid(int nid)
  238. {
  239. return uv_blade_info[uv_node_to_blade_id(nid)].nasid;
  240. }
  241. /* Maximum possible number of blades */
  242. static inline int uv_num_possible_blades(void)
  243. {
  244. return uv_possible_blades;
  245. }
  246. #endif /* __ASM_X86_UV_HUB__ */