x86/uv: provide a System Activity Indicator driver
[linux-2.6-block.git] / arch / x86 / include / asm / uv / uv_hub.h
CommitLineData
952cf6d7
JS
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 *
9f5314fb 8 * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
952cf6d7
JS
9 */
10
05e4d316
PA
11#ifndef _ASM_X86_UV_UV_HUB_H
12#define _ASM_X86_UV_UV_HUB_H
952cf6d7
JS
13
14#include <linux/numa.h>
15#include <linux/percpu.h>
16#include <asm/types.h>
17#include <asm/percpu.h>
18
19
20/*
21 * Addressing Terminology
22 *
9f5314fb
JS
23 * M - The low M bits of a physical address represent the offset
24 * into the blade local memory. RAM memory on a blade is physically
25 * contiguous (although various IO spaces may punch holes in
26 * it)..
952cf6d7 27 *
9f5314fb
JS
28 * N - Number of bits in the node portion of a socket physical
29 * address.
30 *
31 * NASID - network ID of a router, Mbrick or Cbrick. Nasid values of
32 * routers always have low bit of 1, C/MBricks have low bit
33 * equal to 0. Most addressing macros that target UV hub chips
34 * right shift the NASID by 1 to exclude the always-zero bit.
35 * NASIDs contain up to 15 bits.
36 *
37 * GNODE - NASID right shifted by 1 bit. Most mmrs contain gnodes instead
38 * of nasids.
39 *
40 * PNODE - the low N bits of the GNODE. The PNODE is the most useful variant
41 * of the nasid for socket usage.
42 *
43 *
44 * NumaLink Global Physical Address Format:
45 * +--------------------------------+---------------------+
46 * |00..000| GNODE | NodeOffset |
47 * +--------------------------------+---------------------+
48 * |<-------53 - M bits --->|<--------M bits ----->
49 *
50 * M - number of node offset bits (35 .. 40)
952cf6d7
JS
51 *
52 *
53 * Memory/UV-HUB Processor Socket Address Format:
9f5314fb
JS
54 * +----------------+---------------+---------------------+
55 * |00..000000000000| PNODE | NodeOffset |
56 * +----------------+---------------+---------------------+
57 * <--- N bits --->|<--------M bits ----->
952cf6d7 58 *
9f5314fb
JS
59 * M - number of node offset bits (35 .. 40)
60 * N - number of PNODE bits (0 .. 10)
952cf6d7
JS
61 *
62 * Note: M + N cannot currently exceed 44 (x86_64) or 46 (IA64).
63 * The actual values are configuration dependent and are set at
9f5314fb
JS
64 * boot time. M & N values are set by the hardware/BIOS at boot.
65 *
952cf6d7
JS
66 *
67 * APICID format
68 * NOTE!!!!!! This is the current format of the APICID. However, code
69 * should assume that this will change in the future. Use functions
70 * in this file for all APICID bit manipulations and conversion.
71 *
72 * 1111110000000000
73 * 5432109876543210
9f5314fb 74 * pppppppppplc0cch
952cf6d7
JS
75 * sssssssssss
76 *
9f5314fb 77 * p = pnode bits
952cf6d7
JS
78 * l = socket number on board
79 * c = core
80 * h = hyperthread
9f5314fb 81 * s = bits that are in the SOCKET_ID CSR
952cf6d7
JS
82 *
83 * Note: Processor only supports 12 bits in the APICID register. The ACPI
84 * tables hold all 16 bits. Software needs to be aware of this.
85 *
86 * Unless otherwise specified, all references to APICID refer to
87 * the FULL value contained in ACPI tables, not the subset in the
88 * processor APICID register.
89 */
90
91
92/*
93 * Maximum number of bricks in all partitions and in all coherency domains.
94 * This is the total number of bricks accessible in the numalink fabric. It
95 * includes all C & M bricks. Routers are NOT included.
96 *
97 * This value is also the value of the maximum number of non-router NASIDs
98 * in the numalink fabric.
99 *
9f5314fb 100 * NOTE: a brick may contain 1 or 2 OS nodes. Don't get these confused.
952cf6d7
JS
101 */
102#define UV_MAX_NUMALINK_BLADES 16384
103
104/*
105 * Maximum number of C/Mbricks within a software SSI (hardware may support
106 * more).
107 */
108#define UV_MAX_SSI_BLADES 256
109
110/*
111 * The largest possible NASID of a C or M brick (+ 2)
112 */
113#define UV_MAX_NASID_VALUE (UV_MAX_NUMALINK_NODES * 2)
114
7f1baa06
MT
115struct uv_scir_s {
116 struct timer_list timer;
117 unsigned long offset;
118 unsigned long last;
119 unsigned long idle_on;
120 unsigned long idle_off;
121 unsigned char state;
122 unsigned char enabled;
123};
124
952cf6d7
JS
125/*
126 * The following defines attributes of the HUB chip. These attributes are
127 * frequently referenced and are kept in the per-cpu data areas of each cpu.
128 * They are kept together in a struct to minimize cache misses.
129 */
130struct uv_hub_info_s {
131 unsigned long global_mmr_base;
9f5314fb
JS
132 unsigned long gpa_mask;
133 unsigned long gnode_upper;
134 unsigned long lowmem_remap_top;
135 unsigned long lowmem_remap_base;
136 unsigned short pnode;
137 unsigned short pnode_mask;
952cf6d7
JS
138 unsigned short coherency_domain_number;
139 unsigned short numa_blade_id;
140 unsigned char blade_processor_id;
141 unsigned char m_val;
142 unsigned char n_val;
7f1baa06 143 struct uv_scir_s scir;
952cf6d7 144};
7f1baa06 145
952cf6d7
JS
146DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
147#define uv_hub_info (&__get_cpu_var(__uv_hub_info))
148#define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu))
149
150/*
151 * Local & Global MMR space macros.
152 * Note: macros are intended to be used ONLY by inline functions
153 * in this file - not by other kernel code.
9f5314fb
JS
154 * n - NASID (full 15-bit global nasid)
155 * g - GNODE (full 15-bit global nasid, right shifted 1)
156 * p - PNODE (local part of nsids, right shifted 1)
952cf6d7 157 */
9f5314fb
JS
158#define UV_NASID_TO_PNODE(n) (((n) >> 1) & uv_hub_info->pnode_mask)
159#define UV_PNODE_TO_NASID(p) (((p) << 1) | uv_hub_info->gnode_upper)
952cf6d7
JS
160
161#define UV_LOCAL_MMR_BASE 0xf4000000UL
162#define UV_GLOBAL_MMR32_BASE 0xf8000000UL
163#define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base)
83f5d894
JS
164#define UV_LOCAL_MMR_SIZE (64UL * 1024 * 1024)
165#define UV_GLOBAL_MMR32_SIZE (64UL * 1024 * 1024)
952cf6d7 166
9f5314fb
JS
167#define UV_GLOBAL_MMR32_PNODE_SHIFT 15
168#define UV_GLOBAL_MMR64_PNODE_SHIFT 26
952cf6d7 169
9f5314fb 170#define UV_GLOBAL_MMR32_PNODE_BITS(p) ((p) << (UV_GLOBAL_MMR32_PNODE_SHIFT))
952cf6d7 171
9f5314fb
JS
172#define UV_GLOBAL_MMR64_PNODE_BITS(p) \
173 ((unsigned long)(p) << UV_GLOBAL_MMR64_PNODE_SHIFT)
174
175#define UV_APIC_PNODE_SHIFT 6
176
7f1baa06
MT
177/* Local Bus from cpu's perspective */
178#define LOCAL_BUS_BASE 0x1c00000
179#define LOCAL_BUS_SIZE (4 * 1024 * 1024)
180
181/*
182 * System Controller Interface Reg
183 *
184 * Note there are NO leds on a UV system. This register is only
185 * used by the system controller to monitor system-wide operation.
186 * There are 64 regs per node. With Nahelem cpus (2 cores per node,
187 * 8 cpus per core, 2 threads per cpu) there are 32 cpu threads on
188 * a node.
189 *
190 * The window is located at top of ACPI MMR space
191 */
192#define SCIR_WINDOW_COUNT 64
193#define SCIR_LOCAL_MMR_BASE (LOCAL_BUS_BASE + \
194 LOCAL_BUS_SIZE - \
195 SCIR_WINDOW_COUNT)
196
197#define SCIR_CPU_HEARTBEAT 0x01 /* timer interrupt */
198#define SCIR_CPU_ACTIVITY 0x02 /* not idle */
199#define SCIR_CPU_HB_INTERVAL (HZ) /* once per second */
200
9f5314fb
JS
201/*
202 * Macros for converting between kernel virtual addresses, socket local physical
203 * addresses, and UV global physical addresses.
204 * Note: use the standard __pa() & __va() macros for converting
205 * between socket virtual and socket physical addresses.
206 */
207
208/* socket phys RAM --> UV global physical address */
209static inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr)
210{
211 if (paddr < uv_hub_info->lowmem_remap_top)
212 paddr += uv_hub_info->lowmem_remap_base;
213 return paddr | uv_hub_info->gnode_upper;
214}
215
216
217/* socket virtual --> UV global physical address */
218static inline unsigned long uv_gpa(void *v)
219{
220 return __pa(v) | uv_hub_info->gnode_upper;
221}
222
223/* socket virtual --> UV global physical address */
224static inline void *uv_vgpa(void *v)
225{
226 return (void *)uv_gpa(v);
227}
228
229/* UV global physical address --> socket virtual */
230static inline void *uv_va(unsigned long gpa)
231{
232 return __va(gpa & uv_hub_info->gpa_mask);
233}
234
235/* pnode, offset --> socket virtual */
236static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
237{
238 return __va(((unsigned long)pnode << uv_hub_info->m_val) | offset);
239}
952cf6d7 240
952cf6d7
JS
241
242/*
9f5314fb 243 * Extract a PNODE from an APICID (full apicid, not processor subset)
952cf6d7 244 */
9f5314fb 245static inline int uv_apicid_to_pnode(int apicid)
952cf6d7 246{
9f5314fb 247 return (apicid >> UV_APIC_PNODE_SHIFT);
952cf6d7
JS
248}
249
250/*
251 * Access global MMRs using the low memory MMR32 space. This region supports
252 * faster MMR access but not all MMRs are accessible in this space.
253 */
9f5314fb 254static inline unsigned long *uv_global_mmr32_address(int pnode,
952cf6d7
JS
255 unsigned long offset)
256{
257 return __va(UV_GLOBAL_MMR32_BASE |
9f5314fb 258 UV_GLOBAL_MMR32_PNODE_BITS(pnode) | offset);
952cf6d7
JS
259}
260
9f5314fb 261static inline void uv_write_global_mmr32(int pnode, unsigned long offset,
952cf6d7
JS
262 unsigned long val)
263{
9f5314fb 264 *uv_global_mmr32_address(pnode, offset) = val;
952cf6d7
JS
265}
266
9f5314fb 267static inline unsigned long uv_read_global_mmr32(int pnode,
952cf6d7
JS
268 unsigned long offset)
269{
9f5314fb 270 return *uv_global_mmr32_address(pnode, offset);
952cf6d7
JS
271}
272
273/*
274 * Access Global MMR space using the MMR space located at the top of physical
275 * memory.
276 */
9f5314fb 277static inline unsigned long *uv_global_mmr64_address(int pnode,
952cf6d7
JS
278 unsigned long offset)
279{
280 return __va(UV_GLOBAL_MMR64_BASE |
9f5314fb 281 UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset);
952cf6d7
JS
282}
283
9f5314fb 284static inline void uv_write_global_mmr64(int pnode, unsigned long offset,
952cf6d7
JS
285 unsigned long val)
286{
9f5314fb 287 *uv_global_mmr64_address(pnode, offset) = val;
952cf6d7
JS
288}
289
9f5314fb 290static inline unsigned long uv_read_global_mmr64(int pnode,
952cf6d7
JS
291 unsigned long offset)
292{
9f5314fb 293 return *uv_global_mmr64_address(pnode, offset);
952cf6d7
JS
294}
295
296/*
9f5314fb 297 * Access hub local MMRs. Faster than using global space but only local MMRs
952cf6d7
JS
298 * are accessible.
299 */
300static inline unsigned long *uv_local_mmr_address(unsigned long offset)
301{
302 return __va(UV_LOCAL_MMR_BASE | offset);
303}
304
305static inline unsigned long uv_read_local_mmr(unsigned long offset)
306{
307 return *uv_local_mmr_address(offset);
308}
309
310static inline void uv_write_local_mmr(unsigned long offset, unsigned long val)
311{
312 *uv_local_mmr_address(offset) = val;
313}
314
7f1baa06
MT
315static inline unsigned char uv_read_local_mmr8(unsigned long offset)
316{
317 return *((unsigned char *)uv_local_mmr_address(offset));
318}
319
320static inline void uv_write_local_mmr8(unsigned long offset, unsigned char val)
321{
322 *((unsigned char *)uv_local_mmr_address(offset)) = val;
323}
324
8400def8 325/*
9f5314fb 326 * Structures and definitions for converting between cpu, node, pnode, and blade
8400def8
JS
327 * numbers.
328 */
329struct uv_blade_info {
9f5314fb 330 unsigned short nr_possible_cpus;
8400def8 331 unsigned short nr_online_cpus;
9f5314fb 332 unsigned short pnode;
8400def8 333};
9f5314fb 334extern struct uv_blade_info *uv_blade_info;
8400def8
JS
335extern short *uv_node_to_blade;
336extern short *uv_cpu_to_blade;
337extern short uv_possible_blades;
338
339/* Blade-local cpu number of current cpu. Numbered 0 .. <# cpus on the blade> */
340static inline int uv_blade_processor_id(void)
341{
342 return uv_hub_info->blade_processor_id;
343}
344
345/* Blade number of current cpu. Numnbered 0 .. <#blades -1> */
346static inline int uv_numa_blade_id(void)
347{
348 return uv_hub_info->numa_blade_id;
349}
350
351/* Convert a cpu number to the the UV blade number */
352static inline int uv_cpu_to_blade_id(int cpu)
353{
354 return uv_cpu_to_blade[cpu];
355}
356
357/* Convert linux node number to the UV blade number */
358static inline int uv_node_to_blade_id(int nid)
359{
360 return uv_node_to_blade[nid];
361}
362
9f5314fb
JS
363/* Convert a blade id to the PNODE of the blade */
364static inline int uv_blade_to_pnode(int bid)
8400def8 365{
9f5314fb 366 return uv_blade_info[bid].pnode;
8400def8
JS
367}
368
369/* Determine the number of possible cpus on a blade */
370static inline int uv_blade_nr_possible_cpus(int bid)
371{
9f5314fb 372 return uv_blade_info[bid].nr_possible_cpus;
8400def8
JS
373}
374
375/* Determine the number of online cpus on a blade */
376static inline int uv_blade_nr_online_cpus(int bid)
377{
378 return uv_blade_info[bid].nr_online_cpus;
379}
380
9f5314fb
JS
381/* Convert a cpu id to the PNODE of the blade containing the cpu */
382static inline int uv_cpu_to_pnode(int cpu)
8400def8 383{
9f5314fb 384 return uv_blade_info[uv_cpu_to_blade_id(cpu)].pnode;
8400def8
JS
385}
386
9f5314fb
JS
387/* Convert a linux node number to the PNODE of the blade */
388static inline int uv_node_to_pnode(int nid)
8400def8 389{
9f5314fb 390 return uv_blade_info[uv_node_to_blade_id(nid)].pnode;
8400def8
JS
391}
392
393/* Maximum possible number of blades */
394static inline int uv_num_possible_blades(void)
395{
396 return uv_possible_blades;
397}
398
7f1baa06
MT
399/* Update SCIR state */
400static inline void uv_set_scir_bits(unsigned char value)
401{
402 if (uv_hub_info->scir.state != value) {
403 uv_hub_info->scir.state = value;
404 uv_write_local_mmr8(uv_hub_info->scir.offset, value);
405 }
406}
407static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
408{
409 if (uv_cpu_hub_info(cpu)->scir.state != value) {
410 uv_cpu_hub_info(cpu)->scir.state = value;
411 uv_write_local_mmr8(uv_cpu_hub_info(cpu)->scir.offset, value);
412 }
413}
952cf6d7 414
7f1baa06 415#endif /* _ASM_X86_UV_UV_HUB_H */