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
6 * Copyright (c) 1992-1999,2001-2004 Silicon Graphics, Inc. All rights reserved.
9 #ifndef _ASM_IA64_SN_ADDRS_H
10 #define _ASM_IA64_SN_ADDRS_H
13 /* McKinley Address Format:
17 * +-+---------+----+--------------+
18 * |0| Node ID | AS | Node Offset |
19 * +-+---------+----+--------------+
21 * Node ID: If bit 38 = 1, is ICE, else is SHUB
22 * AS: Address Space Identifier. Used only if bit 38 = 0.
23 * b'00: Local Resources and MMR space
25 * 0: Local resources space
27 * 0: IA64/NT compatibility space
29 * 4: Local memory, regardless of local node id
33 * b'11: Cacheable memory space.
35 * NodeOffset: byte offset
38 /* TIO address format:
41 * +-+----------+-+---+--------------+
42 * |0| Node ID |0|CID| Node offset |
43 * +-+----------+-+---+--------------+
45 * Node ID: if bit 38 == 1, is ICE.
46 * Bit 37: Must be zero.
48 * b'01: TIO LB (Indicates TIO MMR access.)
49 * b'11: TIO ICE (indicates coretalk space access.)
50 * Node offset: byte offest.
54 * Note that in both of the above address formats, bit
55 * 35 set indicates that the reference is to the
60 typedef union ia64_sn2_pa {
62 unsigned long off : 36;
64 unsigned long nasid: 11;
65 unsigned long fill : 15;
72 #define TO_PHYS_MASK 0x0001ffcfffffffffUL /* Note - clear AS bits */
75 /* Regions determined by AS */
76 #define LOCAL_MMR_SPACE 0xc000008000000000UL /* Local MMR space */
77 #define LOCAL_PHYS_MMR_SPACE 0x8000008000000000UL /* Local PhysicalMMR space */
78 #define LOCAL_MEM_SPACE 0xc000010000000000UL /* Local Memory space */
79 /* It so happens that setting bit 35 indicates a reference to the SHUB or TIO
82 #define GLOBAL_MMR_SPACE 0xc000000800000000UL /* Global MMR space */
83 #define TIO_MMR_SPACE 0xc000000800000000UL /* TIO MMR space */
84 #define ICE_MMR_SPACE 0xc000000000000000UL /* ICE MMR space */
85 #define GLOBAL_PHYS_MMR_SPACE 0x0000000800000000UL /* Global Physical MMR space */
86 #define GET_SPACE 0xe000001000000000UL /* GET space */
87 #define AMO_SPACE 0xc000002000000000UL /* AMO space */
88 #define CACHEABLE_MEM_SPACE 0xe000003000000000UL /* Cacheable memory space */
89 #define UNCACHED 0xc000000000000000UL /* UnCacheable memory space */
90 #define UNCACHED_PHYS 0x8000000000000000UL /* UnCacheable physical memory space */
92 #define PHYS_MEM_SPACE 0x0000003000000000UL /* physical memory space */
94 /* SN2 address macros */
95 /* NID_SHFT has the right value for both SHUB and TIO addresses.*/
97 #define LOCAL_MMR_ADDR(a) (UNCACHED | LOCAL_MMR_SPACE | (a))
98 #define LOCAL_MMR_PHYS_ADDR(a) (UNCACHED_PHYS | LOCAL_PHYS_MMR_SPACE | (a))
99 #define LOCAL_MEM_ADDR(a) (LOCAL_MEM_SPACE | (a))
100 #define REMOTE_ADDR(n,a) ((((unsigned long)(n))<<NID_SHFT) | (a))
101 #define GLOBAL_MMR_ADDR(n,a) (UNCACHED | GLOBAL_MMR_SPACE | REMOTE_ADDR(n,a))
102 #define GLOBAL_MMR_PHYS_ADDR(n,a) (UNCACHED_PHYS | GLOBAL_PHYS_MMR_SPACE | REMOTE_ADDR(n,a))
103 #define GET_ADDR(n,a) (GET_SPACE | REMOTE_ADDR(n,a))
104 #define AMO_ADDR(n,a) (UNCACHED | AMO_SPACE | REMOTE_ADDR(n,a))
105 #define GLOBAL_MEM_ADDR(n,a) (CACHEABLE_MEM_SPACE | REMOTE_ADDR(n,a))
107 /* non-II mmr's start at top of big window space (4G) */
108 #define BWIN_TOP 0x0000000100000000UL
111 * general address defines - for code common to SN0/SN1/SN2
113 #define CAC_BASE CACHEABLE_MEM_SPACE /* cacheable memory space */
114 #define IO_BASE (UNCACHED | GLOBAL_MMR_SPACE) /* lower 4G maps II's XIO space */
115 #define TIO_BASE (UNCACHED | ICE_MMR_SPACE) /* lower 4G maps TIO space */
116 #define AMO_BASE (UNCACHED | AMO_SPACE) /* fetch & op space */
117 #define MSPEC_BASE AMO_BASE /* fetch & op space */
118 #define UNCAC_BASE (UNCACHED | CACHEABLE_MEM_SPACE) /* uncached global memory */
119 #define GET_BASE GET_SPACE /* momentarily coherent remote mem. */
120 #define CALIAS_BASE LOCAL_CACHEABLE_BASE /* cached node-local memory */
121 #define UALIAS_BASE (UNCACHED | LOCAL_CACHEABLE_BASE) /* uncached node-local memory */
123 #define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
124 #define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
125 #define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK))
126 #define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK))
127 #define TO_GET(x) (GET_BASE | ((x) & TO_PHYS_MASK))
128 #define TO_CALIAS(x) (CALIAS_BASE | TO_NODE_ADDRSPACE(x))
129 #define TO_UALIAS(x) (UALIAS_BASE | TO_NODE_ADDRSPACE(x))
130 #define NODE_SIZE_BITS 36 /* node offset : bits <35:0> */
131 #define BWIN_SIZE_BITS 29 /* big window size: 512M */
132 #define TIO_BWIN_SIZE_BITS 30 /* big window size: 1G */
133 #define NASID_BITS 11 /* bits <48:38> */
134 #define NASID_BITMASK (0x7ffULL)
135 #define NASID_SHFT NID_SHFT
136 #define NASID_META_BITS 0 /* ???? */
137 #define NASID_LOCAL_BITS 7 /* same router as SN1 */
139 #define NODE_ADDRSPACE_SIZE (1UL << NODE_SIZE_BITS)
140 #define NASID_MASK ((uint64_t) NASID_BITMASK << NASID_SHFT)
141 #define NASID_GET(_pa) (int) (((uint64_t) (_pa) >> \
142 NASID_SHFT) & NASID_BITMASK)
143 #define PHYS_TO_DMA(x) ( ((x & NASID_MASK) >> 2) | \
144 (x & (NODE_ADDRSPACE_SIZE - 1)) )
147 * This address requires a chiplet id in bits 38-39. For DMA to memory,
148 * the chiplet id is zero. If we implement TIO-TIO dma, we might need
149 * to insert a chiplet id into this macro. However, it is our belief
150 * right now that this chiplet id will be ICE, which is also zero.
152 #define PHYS_TO_TIODMA(x) ( ((x & NASID_MASK) << 2) | \
153 (x & (NODE_ADDRSPACE_SIZE - 1)) )
155 #define CHANGE_NASID(n,x) ({ia64_sn2_pa_t _v; _v.l = (long) (x); _v.f.nasid = n; _v.p;})
159 #define NODE_SWIN_BASE(nasid, widget) \
160 ((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN) \
161 : RAW_NODE_SWIN_BASE(nasid, widget))
163 #define NODE_SWIN_BASE(nasid, widget) \
164 (NODE_IO_BASE(nasid) + ((uint64_t) (widget) << SWIN_SIZE_BITS))
165 #define LOCAL_SWIN_BASE(widget) \
166 (UNCACHED | LOCAL_MMR_SPACE | (((uint64_t) (widget) << SWIN_SIZE_BITS)))
167 #endif /* __ASSEMBLY__ */
170 * The following definitions pertain to the IO special address
171 * space. They define the location of the big and little windows
175 #define BWIN_SIZE (1UL << BWIN_SIZE_BITS)
176 #define BWIN_SIZEMASK (BWIN_SIZE - 1)
177 #define BWIN_WIDGET_MASK 0x7
178 #define NODE_BWIN_BASE0(nasid) (NODE_IO_BASE(nasid) + BWIN_SIZE)
179 #define NODE_BWIN_BASE(nasid, bigwin) (NODE_BWIN_BASE0(nasid) + \
180 ((uint64_t) (bigwin) << BWIN_SIZE_BITS))
182 #define BWIN_WIDGETADDR(addr) ((addr) & BWIN_SIZEMASK)
183 #define BWIN_WINDOWNUM(addr) (((addr) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
185 #define TIO_BWIN_WINDOW_SELECT_MASK 0x7
186 #define TIO_BWIN_WINDOWNUM(addr) (((addr) >> TIO_BWIN_SIZE_BITS) & TIO_BWIN_WINDOW_SELECT_MASK)
190 #include <asm/sn/types.h>
194 * The following macros are used to index to the beginning of a specific
195 * node's address space.
198 #define NODE_OFFSET(_n) ((uint64_t) (_n) << NASID_SHFT)
200 #define NODE_CAC_BASE(_n) (CAC_BASE + NODE_OFFSET(_n))
201 #define NODE_HSPEC_BASE(_n) (HSPEC_BASE + NODE_OFFSET(_n))
202 #define NODE_IO_BASE(_n) (IO_BASE + NODE_OFFSET(_n))
203 #define NODE_MSPEC_BASE(_n) (MSPEC_BASE + NODE_OFFSET(_n))
204 #define NODE_UNCAC_BASE(_n) (UNCAC_BASE + NODE_OFFSET(_n))
206 #define TO_NODE_CAC(_n, _x) (NODE_CAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
208 #define RAW_NODE_SWIN_BASE(nasid, widget) \
209 (NODE_IO_BASE(nasid) + ((uint64_t) (widget) << SWIN_SIZE_BITS))
213 * The following definitions pertain to the IO special address
214 * space. They define the location of the big and little windows
218 #define SWIN_SIZE_BITS 24
219 #define SWIN_SIZE (1UL << 24)
220 #define SWIN_SIZEMASK (SWIN_SIZE - 1)
221 #define SWIN_WIDGET_MASK 0xF
223 #define TIO_SWIN_SIZE_BITS 28
224 #define TIO_SWIN_SIZE (1UL << 28)
225 #define TIO_SWIN_SIZEMASK (SWIN_SIZE - 1)
226 #define TIO_SWIN_WIDGET_MASK 0x3
229 * Convert smallwindow address to xtalk address.
231 * 'addr' can be physical or virtual address, but will be converted
232 * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
234 #define SWIN_WIDGETNUM(addr) (((addr) >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
236 #define TIO_SWIN_WIDGETNUM(addr) (((addr) >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK)
239 * The following macros produce the correct base virtual address for
240 * the hub registers. The LOCAL_HUB_* macros produce the appropriate
241 * address for the local registers. The REMOTE_HUB_* macro produce
242 * the address for the specified hub's registers. The intent is
243 * that the appropriate PI, MD, NI, or II register would be substituted
249 * SN2 has II mmr's located inside small window space.
250 * As all other non-II mmr's located at the top of big window
253 #define REMOTE_HUB_BASE(_x) \
254 (UNCACHED | GLOBAL_MMR_SPACE | \
255 (((~(_x)) & BWIN_TOP)>>8) | \
256 (((~(_x)) & BWIN_TOP)>>9) | (_x))
258 #define REMOTE_HUB(_n, _x) \
259 ((uint64_t *)(REMOTE_HUB_BASE(_x) | ((((long)(_n))<<NASID_SHFT))))
264 * When certain Hub chip workaround are defined, it's not sufficient
265 * to dereference the *_HUB_ADDR() macros. You should instead use
266 * HUB_L() and HUB_S() if you must deal with pointers to hub registers.
267 * Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
268 * They're always safe.
271 * LOCAL_HUB_ADDR doesn't need to be changed for TIO, since, by definition,
272 * there are no "local" TIOs.
274 #define LOCAL_HUB_ADDR(_x) \
275 (((_x) & BWIN_TOP) ? ((volatile uint64_t *)(LOCAL_MMR_ADDR(_x))) \
276 : ((volatile uint64_t *)(IALIAS_BASE + (_x))))
277 #define REMOTE_HUB_ADDR(_n, _x) \
280 ((volatile uint64_t *)(GLOBAL_MMR_ADDR(_n, _x))) \
282 (((_x) & BWIN_TOP) ? ((volatile uint64_t *)(GLOBAL_MMR_ADDR(_n, _x))) \
283 : ((volatile uint64_t *)(NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x)))))
287 #define HUB_L(_a) (*((volatile typeof(*_a) *)_a))
288 #define HUB_S(_a, _d) (*((volatile typeof(*_a) *)_a) = (_d))
290 #define LOCAL_HUB_L(_r) HUB_L(LOCAL_HUB_ADDR(_r))
291 #define LOCAL_HUB_S(_r, _d) HUB_S(LOCAL_HUB_ADDR(_r), (_d))
292 #define REMOTE_HUB_L(_n, _r) HUB_L(REMOTE_HUB_ADDR((_n), (_r)))
293 #define REMOTE_HUB_S(_n, _r, _d) HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d))
294 #define REMOTE_HUB_PI_L(_n, _sn, _r) HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
295 #define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
297 #endif /* __ASSEMBLY__ */
300 * The following macros are used to get to a hub/bridge register, given
301 * the base of the register space.
303 #define HUB_REG_PTR(_base, _off) \
304 (volatile uint64_t *)((unsigned long)(_base) + (__psunsigned_t)(_off)))
306 #define HUB_REG_PTR_L(_base, _off) \
307 HUB_L(HUB_REG_PTR((_base), (_off)))
309 #define HUB_REG_PTR_S(_base, _off, _data) \
310 HUB_S(HUB_REG_PTR((_base), (_off)), (_data))
312 #endif /* _ASM_IA64_SN_ADDRS_H */