upgrade to linux 2.6.9-1.11_FC2
[linux-2.6.git] / include / asm-ia64 / sn / addrs.h
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  * Copyright (c) 1992-1999,2001-2004 Silicon Graphics, Inc. All rights reserved.
7  */
8
9 #ifndef _ASM_IA64_SN_ADDRS_H
10 #define _ASM_IA64_SN_ADDRS_H
11
12
13 /* McKinley Address Format:
14  *
15  *   4 4       3 3  3 3
16  *   9 8       8 7  6 5             0
17  *  +-+---------+----+--------------+
18  *  |0| Node ID | AS | Node Offset  |
19  *  +-+---------+----+--------------+
20  *
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
24  *           bit 35
25  *               0: Local resources space
26  *                  node id:
27  *                        0: IA64/NT compatibility space
28  *                        2: Local MMR Space
29  *                        4: Local memory, regardless of local node id
30  *               1: Global MMR space
31  *     b'01: GET space.
32  *     b'10: AMO space.
33  *     b'11: Cacheable memory space.
34  *
35  *   NodeOffset: byte offset
36  */
37
38 /* TIO address format:
39  *  4 4        3 3 3 3 3             0
40  *  9 8        8 7 6 5 4
41  * +-+----------+-+---+--------------+
42  * |0| Node ID  |0|CID| Node offset  |
43  * +-+----------+-+---+--------------+
44  *
45  * Node ID: if bit 38 == 1, is ICE.
46  * Bit 37: Must be zero.
47  * CID: Chiplet ID:
48  *     b'01: TIO LB (Indicates TIO MMR access.)
49  *     b'11: TIO ICE (indicates coretalk space access.)
50  * Node offset: byte offest.
51  */
52
53 /*
54  * Note that in both of the above address formats, bit
55  * 35 set indicates that the reference is to the 
56  * shub or tio MMRs.
57  */
58
59 #ifndef __ASSEMBLY__
60 typedef union ia64_sn2_pa {
61         struct {
62                 unsigned long off  : 36;
63                 unsigned long as   : 2;
64                 unsigned long nasid: 11;
65                 unsigned long fill : 15;
66         } f;
67         unsigned long l;
68         void *p;
69 } ia64_sn2_pa_t;
70 #endif
71
72 #define TO_PHYS_MASK            0x0001ffcfffffffffUL    /* Note - clear AS bits */
73
74
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
80  * MMR space.  
81  */
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 */
91
92 #define PHYS_MEM_SPACE          0x0000003000000000UL    /* physical memory space */
93
94 /* SN2 address macros */
95 /* NID_SHFT has the right value for both SHUB and TIO addresses.*/
96 #define NID_SHFT                38
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))
106
107 /* non-II mmr's start at top of big window space (4G) */
108 #define BWIN_TOP                0x0000000100000000UL
109
110 /*
111  * general address defines - for code common to SN0/SN1/SN2
112  */
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 */
122
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 */
138
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)) )
145
146 /*
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.
151  */
152 #define PHYS_TO_TIODMA(x)     ( ((x & NASID_MASK) << 2) |             \
153                                  (x & (NODE_ADDRSPACE_SIZE - 1)) )
154
155 #define CHANGE_NASID(n,x)       ({ia64_sn2_pa_t _v; _v.l = (long) (x); _v.f.nasid = n; _v.p;})
156
157
158 #ifndef __ASSEMBLY__
159 #define NODE_SWIN_BASE(nasid, widget)                                   \
160         ((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN)          \
161         : RAW_NODE_SWIN_BASE(nasid, widget))
162 #else
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__ */
168
169 /*
170  * The following definitions pertain to the IO special address
171  * space.  They define the location of the big and little windows
172  * of any given node.
173  */
174
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))
181
182 #define BWIN_WIDGETADDR(addr)   ((addr) & BWIN_SIZEMASK)
183 #define BWIN_WINDOWNUM(addr)    (((addr) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
184
185 #define TIO_BWIN_WINDOW_SELECT_MASK 0x7
186 #define TIO_BWIN_WINDOWNUM(addr)    (((addr) >> TIO_BWIN_SIZE_BITS) & TIO_BWIN_WINDOW_SELECT_MASK)
187
188
189 #ifndef __ASSEMBLY__
190 #include <asm/sn/types.h>
191 #endif 
192
193 /*
194  * The following macros are used to index to the beginning of a specific
195  * node's address space.
196  */
197
198 #define NODE_OFFSET(_n)         ((uint64_t) (_n) << NASID_SHFT)
199
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))
205
206 #define TO_NODE_CAC(_n, _x)     (NODE_CAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
207
208 #define RAW_NODE_SWIN_BASE(nasid, widget)                               \
209         (NODE_IO_BASE(nasid) + ((uint64_t) (widget) << SWIN_SIZE_BITS))
210
211
212 /*
213  * The following definitions pertain to the IO special address
214  * space.  They define the location of the big and little windows
215  * of any given node.
216  */
217
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
222
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
227
228 /*
229  * Convert smallwindow address to xtalk address.
230  *
231  * 'addr' can be physical or virtual address, but will be converted
232  * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
233  */
234 #define SWIN_WIDGETNUM(addr)    (((addr)  >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
235
236 #define TIO_SWIN_WIDGETNUM(addr)        (((addr)  >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK)
237
238 /*
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
244  * for _x.
245  */
246
247
248 /*
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
251  * space.
252  */
253 #define REMOTE_HUB_BASE(_x)                                             \
254         (UNCACHED | GLOBAL_MMR_SPACE |                                  \
255         (((~(_x)) & BWIN_TOP)>>8)    |                                       \
256         (((~(_x)) & BWIN_TOP)>>9)    | (_x))
257
258 #define REMOTE_HUB(_n, _x)                                              \
259         ((uint64_t *)(REMOTE_HUB_BASE(_x) | ((((long)(_n))<<NASID_SHFT))))
260
261
262 /*
263  * WARNING:
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.
269  */
270 /*
271  * LOCAL_HUB_ADDR doesn't need to be changed for TIO, since, by definition,
272  * there are no "local" TIOs.
273  */
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)                                         \
278         ((_n & 1) ?                                                     \
279         /* TIO: */                                                      \
280         ((volatile uint64_t *)(GLOBAL_MMR_ADDR(_n, _x)))                                \
281         : /* SHUB: */                                                   \
282         (((_x) & BWIN_TOP) ? ((volatile uint64_t *)(GLOBAL_MMR_ADDR(_n, _x)))   \
283         : ((volatile uint64_t *)(NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x)))))
284
285 #ifndef __ASSEMBLY__
286
287 #define HUB_L(_a)                       (*((volatile typeof(*_a) *)_a))
288 #define HUB_S(_a, _d)                   (*((volatile typeof(*_a) *)_a) = (_d))
289
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))
296
297 #endif /* __ASSEMBLY__ */
298
299 /*
300  * The following macros are used to get to a hub/bridge register, given
301  * the base of the register space.
302  */
303 #define HUB_REG_PTR(_base, _off)        \
304         (volatile uint64_t *)((unsigned long)(_base) + (__psunsigned_t)(_off)))
305
306 #define HUB_REG_PTR_L(_base, _off)      \
307         HUB_L(HUB_REG_PTR((_base), (_off)))
308
309 #define HUB_REG_PTR_S(_base, _off, _data)       \
310         HUB_S(HUB_REG_PTR((_base), (_off)), (_data))
311
312 #endif /* _ASM_IA64_SN_ADDRS_H */