1
2/*
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License.  See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (c) 1992-1999,2001 Silicon Graphics, Inc.  All rights reserved.
9 */
10
11
12#ifndef _ASM_IA64_SN_ADDRS_H
13#define _ASM_IA64_SN_ADDRS_H
14
15#include <linux/config.h>
16
17#if defined(CONFIG_IA64_SGI_SN1)
18#include <asm/sn/sn1/addrs.h>
19#elif defined(CONFIG_IA64_SGI_SN2)
20#include <asm/sn/sn2/addrs.h>
21#else
22#error <<<BOMB! addrs.h defined only for SN1, or SN2 >>>
23#endif /* !SN1 && !SN2 */
24
25#ifndef __ASSEMBLY__
26#include <asm/sn/types.h>
27#endif
28
29#ifndef __ASSEMBLY__
30
31#define PS_UINT_CAST		(__psunsigned_t)
32#define UINT64_CAST		(uint64_t)
33#ifdef CONFIG_IA64_SGI_SN2
34#define HUBREG_CAST		(volatile mmr_t *)
35#else
36#define HUBREG_CAST		(volatile hubreg_t *)
37#endif
38
39#elif __ASSEMBLY__
40
41#define PS_UINT_CAST
42#define UINT64_CAST
43#define HUBREG_CAST
44
45#endif
46
47
48
49
50/*
51 * The following macros are used to index to the beginning of a specific
52 * node's address space.
53 */
54
55#ifdef CONFIG_IA64_SGI_SN2	    /* SN2 has an extra AS field between node offset and node id (nasid) */
56#define NODE_OFFSET(_n)		(UINT64_CAST (_n) << NASID_SHFT)
57#else
58#define NODE_OFFSET(_n)		(UINT64_CAST (_n) << NODE_SIZE_BITS)
59#endif
60
61#define NODE_CAC_BASE(_n)	(CAC_BASE   + NODE_OFFSET(_n))
62#define NODE_HSPEC_BASE(_n)	(HSPEC_BASE + NODE_OFFSET(_n))
63#define NODE_IO_BASE(_n)	(IO_BASE    + NODE_OFFSET(_n))
64#define NODE_MSPEC_BASE(_n)	(MSPEC_BASE + NODE_OFFSET(_n))
65#define NODE_UNCAC_BASE(_n)	(UNCAC_BASE + NODE_OFFSET(_n))
66
67#define TO_NODE(_n, _x)		(NODE_OFFSET(_n)     | ((_x)		   ))
68#define TO_NODE_CAC(_n, _x)	(NODE_CAC_BASE(_n)   | ((_x) & TO_PHYS_MASK))
69#define TO_NODE_UNCAC(_n, _x)	(NODE_UNCAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
70#define TO_NODE_MSPEC(_n, _x)	(NODE_MSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
71#define TO_NODE_HSPEC(_n, _x)	(NODE_HSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
72
73
74#define RAW_NODE_SWIN_BASE(nasid, widget)				\
75	(NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS))
76
77#define WIDGETID_GET(addr)	((unsigned char)((addr >> SWIN_SIZE_BITS) & 0xff))
78
79/*
80 * The following definitions pertain to the IO special address
81 * space.  They define the location of the big and little windows
82 * of any given node.
83 */
84
85#define SWIN_SIZE_BITS		24
86#define SWIN_SIZE		(UINT64_CAST 1 << 24)
87#define	SWIN_SIZEMASK		(SWIN_SIZE - 1)
88#define	SWIN_WIDGET_MASK	0xF
89
90/*
91 * Convert smallwindow address to xtalk address.
92 *
93 * 'addr' can be physical or virtual address, but will be converted
94 * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
95 */
96#define	SWIN_WIDGETADDR(addr)	((addr) & SWIN_SIZEMASK)
97#define	SWIN_WIDGETNUM(addr)	(((addr)  >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
98/*
99 * Verify if addr belongs to small window address on node with "nasid"
100 *
101 *
102 * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
103 * address
104 *
105 *
106 */
107#define	NODE_SWIN_ADDR(nasid, addr)	\
108		(((addr) >= NODE_SWIN_BASE(nasid, 0))  && \
109		 ((addr) <  (NODE_SWIN_BASE(nasid, HUB_NUM_WIDGET) + SWIN_SIZE)\
110		 ))
111
112/*
113 * The following define the major position-independent aliases used
114 * in SN.
115 *	LBOOT  -- 256MB in size, reads in the LBOOT area result in
116 *			uncached references to the local hub's boot prom and
117 *			other directory-bus connected devices.
118 *	IALIAS -- 8MB in size, reads in the IALIAS result in uncached
119 *			references to the local hub's registers.
120 */
121
122#if defined CONFIG_IA64_SGI_SN1
123#define LREG_BASE		(HSPEC_BASE + 0x10000000)
124#define LREG_SIZE		0x8000000  /* 128 MB */
125#define LREG_LIMIT		(LREG_BASE + LREG_SIZE)
126#define LBOOT_BASE		(LREG_LIMIT)
127#define LBOOT_SIZE		0x8000000   /* 128 MB */
128#define LBOOT_LIMIT		(LBOOT_BASE + LBOOT_SIZE)
129#define LBOOT_STRIDE		0x2000000    /* two PROMs, on 32M boundaries */
130#endif
131
132#define	HUB_REGISTER_WIDGET	1
133#ifdef CONFIG_IA64_SGI_SN2
134#define IALIAS_BASE		LOCAL_SWIN_BASE(HUB_REGISTER_WIDGET)
135#else
136#define IALIAS_BASE		NODE_SWIN_BASE(0, HUB_REGISTER_WIDGET)
137#endif
138#define IALIAS_SIZE		0x800000	/* 8 Megabytes */
139#define IS_IALIAS(_a)		(((_a) >= IALIAS_BASE) &&		\
140				 ((_a) < (IALIAS_BASE + IALIAS_SIZE)))
141
142/*
143 * Macro for referring to Hub's RBOOT space
144 */
145
146#if defined CONFIG_IA64_SGI_SN1
147
148#define NODE_LREG_BASE(_n)	(NODE_HSPEC_BASE(_n) + 0x30000000)
149#define NODE_LREG_LIMIT(_n)	(NODE_LREG_BASE(_n) + LREG_SIZE)
150#define RREG_BASE(_n)		(NODE_LREG_BASE(_n))
151#define RREG_LIMIT(_n)		(NODE_LREG_LIMIT(_n))
152#define RBOOT_SIZE		0x8000000	/* 128 Megabytes */
153#define NODE_RBOOT_BASE(_n)	(NODE_HSPEC_BASE(_n) + 0x38000000)
154#define NODE_RBOOT_LIMIT(_n)	(NODE_RBOOT_BASE(_n) + RBOOT_SIZE)
155
156#endif
157
158
159/*
160 * The following macros produce the correct base virtual address for
161 * the hub registers.  The LOCAL_HUB_* macros produce the appropriate
162 * address for the local registers.  The REMOTE_HUB_* macro produce
163 * the address for the specified hub's registers.  The intent is
164 * that the appropriate PI, MD, NI, or II register would be substituted
165 * for _x.
166 */
167
168
169#ifdef CONFIG_IA64_SGI_SN2
170/*
171 * SN2 has II mmr's located inside small window space like SN0 & SN1,
172 * but has all other non-II mmr's located at the top of big window
173 * space, unlike SN0 & SN1.
174 */
175#define LOCAL_HUB_BASE(_x)	(LOCAL_MMR_ADDR(_x) | (((~(_x)) & BWIN_TOP)>>8))
176#define REMOTE_HUB_BASE(_x)						\
177        (UNCACHED | GLOBAL_MMR_SPACE |                                  \
178        (((~(_x)) & BWIN_TOP)>>8)    |                                       \
179        (((~(_x)) & BWIN_TOP)>>9)    | (_x))
180
181#define LOCAL_HUB(_x) (HUBREG_CAST LOCAL_HUB_BASE(_x))
182#define REMOTE_HUB(_n, _x)						\
183	(HUBREG_CAST (REMOTE_HUB_BASE(_x) | ((((long)(_n))<<NASID_SHFT))))
184
185#else	/* not CONFIG_IA64_SGI_SN2 */
186
187#define LOCAL_HUB(_x)		(HUBREG_CAST (IALIAS_BASE + (_x)))
188#define REMOTE_HUB(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
189					      0x800000 + (_x)))
190#endif
191
192#ifdef CONFIG_IA64_SGI_SN1
193#define LOCAL_HSPEC(_x)		(HUBREG_CAST (LREG_BASE + (_x)))
194#define REMOTE_HSPEC(_n, _x)		(HUBREG_CAST (RREG_BASE(_n) + (_x)))
195#endif /* CONFIG_IA64_SGI_SN1 */
196
197
198#ifdef CONFIG_IA64_SGI_SN2
199#define LOCAL_HUB_ADDR(_x)							\
200	(((_x) & BWIN_TOP) ? (HUBREG_CAST (LOCAL_MMR_ADDR(_x)))		\
201	: (HUBREG_CAST (IALIAS_BASE + (_x))))
202#define REMOTE_HUB_ADDR(_n, _x)						\
203	(((_x) & BWIN_TOP) ? (HUBREG_CAST (GLOBAL_MMR_ADDR(_n, _x)))	\
204	: (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x))))
205#else
206#define LOCAL_HUB_ADDR(_x)	(HUBREG_CAST (IALIAS_BASE + (_x)))
207#define REMOTE_HUB_ADDR(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
208					      0x800000 + (_x)))
209#endif
210#if CONFIG_IA64_SGI_SN1
211#define REMOTE_HUB_PI_ADDR(_n, _sn, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
212					      0x800000 + PIREG(_x, _sn)))
213#endif
214
215#ifdef CONFIG_IA64_SGI_SN1
216#define LOCAL_HSPEC_ADDR(_x)		(HUBREG_CAST (LREG_BASE + (_x)))
217#define REMOTE_HSPEC_ADDR(_n, _x)	(HUBREG_CAST (RREG_BASE(_n) + (_x)))
218#endif /* CONFIG_IA64_SGI_SN1 */
219
220#ifndef __ASSEMBLY__
221
222#define HUB_L(_a)			*(_a)
223#define	HUB_S(_a, _d)			*(_a) = (_d)
224
225#define LOCAL_HUB_L(_r)			HUB_L(LOCAL_HUB_ADDR(_r))
226#define LOCAL_HUB_S(_r, _d)		HUB_S(LOCAL_HUB_ADDR(_r), (_d))
227#define REMOTE_HUB_L(_n, _r)		HUB_L(REMOTE_HUB_ADDR((_n), (_r)))
228#define REMOTE_HUB_S(_n, _r, _d)	HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d))
229#define REMOTE_HUB_PI_L(_n, _sn, _r)	HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
230#define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
231
232#ifdef CONFIG_IA64_SGI_SN1
233#define LOCAL_HSPEC_L(_r)	     HUB_L(LOCAL_HSPEC_ADDR(_r))
234#define LOCAL_HSPEC_S(_r, _d)	     HUB_S(LOCAL_HSPEC_ADDR(_r), (_d))
235#define REMOTE_HSPEC_L(_n, _r)	     HUB_L(REMOTE_HSPEC_ADDR((_n), (_r)))
236#define REMOTE_HSPEC_S(_n, _r, _d)   HUB_S(REMOTE_HSPEC_ADDR((_n), (_r)), (_d))
237#endif /* CONFIG_IA64_SGI_SN1 */
238
239#endif /* __ASSEMBLY__ */
240
241/*
242 * The following macros are used to get to a hub/bridge register, given
243 * the base of the register space.
244 */
245#define HUB_REG_PTR(_base, _off)	\
246	(HUBREG_CAST ((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
247
248#define HUB_REG_PTR_L(_base, _off)	\
249	HUB_L(HUB_REG_PTR((_base), (_off)))
250
251#define HUB_REG_PTR_S(_base, _off, _data)	\
252	HUB_S(HUB_REG_PTR((_base), (_off)), (_data))
253
254/*
255 * Software structure locations -- permanently fixed
256 *    See diagram in kldir.h
257 */
258
259#define PHYS_RAMBASE		0x0
260#define K0_RAMBASE		PHYS_TO_K0(PHYS_RAMBASE)
261
262#define ARCS_SPB_OFFSET		0x1000
263#define ARCS_SPB_ADDR(nasid)						\
264	PHYS_TO_K0(NODE_OFFSET(nasid) | ARCS_SPB_OFFSET)
265#define ARCS_SPB_SIZE		0x0400
266
267#define KLDIR_OFFSET		0x2000
268#define KLDIR_ADDR(nasid)						\
269	TO_NODE_CAC((nasid), KLDIR_OFFSET)
270#define KLDIR_SIZE		0x0400
271
272
273/*
274 * Software structure locations -- indirected through KLDIR
275 *    See diagram in kldir.h
276 *
277 * Important:	All low memory structures must only be accessed
278 *		uncached, except for the symmon stacks.
279 */
280
281#define KLI_LAUNCH		0		/* Dir. entries */
282#define KLI_KLCONFIG		1
283#define	KLI_NMI			2
284#define KLI_GDA			3
285#define KLI_FREEMEM		4
286#define	KLI_SYMMON_STK		5
287#define KLI_PI_ERROR		6
288#define KLI_KERN_VARS		7
289#define	KLI_KERN_XP		8
290#define	KLI_KERN_PARTID		9
291
292#ifndef __ASSEMBLY__
293
294#define KLD_BASE(nasid)		((kldir_ent_t *) KLDIR_ADDR(nasid))
295#define KLD_LAUNCH(nasid)	(KLD_BASE(nasid) + KLI_LAUNCH)
296#define KLD_NMI(nasid)		(KLD_BASE(nasid) + KLI_NMI)
297#define KLD_KLCONFIG(nasid)	(KLD_BASE(nasid) + KLI_KLCONFIG)
298#define KLD_PI_ERROR(nasid)	(KLD_BASE(nasid) + KLI_PI_ERROR)
299#define KLD_GDA(nasid)		(KLD_BASE(nasid) + KLI_GDA)
300#define KLD_SYMMON_STK(nasid)	(KLD_BASE(nasid) + KLI_SYMMON_STK)
301#define KLD_FREEMEM(nasid)	(KLD_BASE(nasid) + KLI_FREEMEM)
302#define KLD_KERN_VARS(nasid)	(KLD_BASE(nasid) + KLI_KERN_VARS)
303#define	KLD_KERN_XP(nasid)	(KLD_BASE(nasid) + KLI_KERN_XP)
304#define	KLD_KERN_PARTID(nasid)	(KLD_BASE(nasid) + KLI_KERN_PARTID)
305
306#ifndef CONFIG_IA64_SGI_SN2
307#define KLCONFIG_OFFSET(nasid)	KLD_KLCONFIG(nasid)->offset
308#else
309#define KLCONFIG_OFFSET(nasid) \
310	ia64_sn_get_klconfig_addr(nasid)
311#endif /* CONFIG_IA64_SGI_SN2 */
312
313#define KLCONFIG_ADDR(nasid)						\
314	TO_NODE_CAC((nasid), KLCONFIG_OFFSET(nasid))
315#define KLCONFIG_SIZE(nasid)	KLD_KLCONFIG(nasid)->size
316
317#define GDA_ADDR(nasid)		KLD_GDA(nasid)->pointer
318#define GDA_SIZE(nasid)		KLD_GDA(nasid)->size
319
320#define NODE_OFFSET_TO_K0(_nasid, _off)					\
321	(PAGE_OFFSET | NODE_OFFSET(_nasid) | (_off))
322
323#endif /* __ASSEMBLY__ */
324
325#endif /* _ASM_IA64_SN_ADDRS_H */
326