1#ifndef _ASM_IA64_SN_MMZONE_SN1_H
2#define _ASM_IA64_SN_MMZONE_SN1_H
3
4/*
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License.  See the file "COPYING" in the main directory of this archive
7 * for more details.
8 *
9 * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
10 */
11
12#include <linux/config.h>
13
14
15/*
16 * SGI SN1 Arch defined values
17 *
18 * 	An SN1 physical address is broken down as follows:
19 *
20 *             +-----------------------------------------+
21 *             |         |    |      |   node offset     |
22 *             | unused  | AS | node |-------------------|
23 *             |         |    |      | cn | clump offset |
24 *             +-----------------------------------------+
25 *              6       4 4  4 3    3 3  3 2            0
26 *              3       4 3  0 9    3 2  0 9            0
27 *
28 *		bits 63-44	Unused - must be zero
29 *		bits 43-40	Address space ID. Cached memory has a value of 0.
30 *				Chipset & IO addresses have non-zero values.
31 *		bits 39-33	Node number. Note that some configurations do NOT
32 *				have a node zero.
33 *		bits 32-0	Node offset.
34 *
35 *	The node offset can be further broken down as:
36 *		bits 32-30	Clump (bank) number.
37 *		bits 29-0	Clump (bank) offset.
38 *
39 *	A node consists of up to 8 clumps (banks) of memory. A clump may be empty, or may be
40 *	populated with a single contiguous block of memory starting at clump
41 *	offset 0. The size of the block is (2**n) * 64MB, where 0<n<5.
42 *
43 *
44 * NOTE: This file exports symbols prefixed with "PLAT_". Symbols prefixed with
45 *	 "SN_" are intended for internal use only and should not be used in
46 *	 any platform independent code.
47 *
48 *	 This file is also responsible for exporting the following definitions:
49 *		cnodeid_t	Define a compact node id.
50 */
51
52typedef signed short cnodeid_t;
53
54#define SN1_BANKS_PER_NODE		8
55#define SN1_NODE_SIZE			(8UL*1024*1024*1024)	/* 8 GB per node */
56#define SN1_BANK_SIZE			(SN1_NODE_SIZE/SN1_BANKS_PER_NODE)
57#define SN1_NODE_SHIFT			33
58#define SN1_NODE_MASK			0x7fUL
59#define SN1_NODE_OFFSET_MASK		(SN1_NODE_SIZE-1)
60#define SN1_NODE_NUMBER(addr)		(((unsigned long)(addr) >> SN1_NODE_SHIFT) & SN1_NODE_MASK)
61#define SN1_NODE_CLUMP_NUMBER(addr)	(((unsigned long)(addr) >>30) & 7)
62#define SN1_NODE_OFFSET(addr)		(((unsigned long)(addr)) & SN1_NODE_OFFSET_MASK)
63#define SN1_KADDR(nasid, offset)	(((unsigned long)(nasid)<<SN1_NODE_SHIFT) | (offset) | PAGE_OFFSET)
64
65
66#define PLAT_MAX_NODE_NUMBER		128			/* Maximum node number +1 */
67#define PLAT_MAX_COMPACT_NODES		128			/* Maximum number of nodes in SSI */
68
69#define PLAT_MAX_PHYS_MEMORY		(1UL << 40)
70
71
72
73/*
74 * On the SN platforms, a clump is the same as a memory bank.
75 */
76#define PLAT_CLUMPS_PER_NODE		SN1_BANKS_PER_NODE
77#define PLAT_CLUMP_OFFSET(addr)		((unsigned long)(addr) & 0x3fffffffUL)
78#define PLAT_CLUMPSIZE                  (SN1_NODE_SIZE/PLAT_CLUMPS_PER_NODE)
79#define PLAT_MAXCLUMPS			(PLAT_CLUMPS_PER_NODE*PLAT_MAX_COMPACT_NODES)
80
81
82
83
84/*
85 * PLAT_VALID_MEM_KADDR returns a boolean to indicate if a kaddr is potentially a
86 * valid cacheable identity mapped RAM memory address.
87 * Note that the RAM may or may not actually be present!!
88 */
89#define SN1_VALID_KERN_ADDR_MASK	0xffffff0000000000UL
90#define SN1_VALID_KERN_ADDR_VALUE	0xe000000000000000UL
91#define PLAT_VALID_MEM_KADDR(kaddr)	(((unsigned long)(kaddr) & SN1_VALID_KERN_ADDR_MASK) == SN1_VALID_KERN_ADDR_VALUE)
92
93
94
95/*
96 * Memory is conceptually divided into chunks. A chunk is either
97 * completely present, or else the kernel assumes it is completely
98 * absent. Each node consists of a number of possibly discontiguous chunks.
99 */
100#define SN1_CHUNKSHIFT			26			/* 64 MB */
101#define PLAT_CHUNKSIZE			(1UL << SN1_CHUNKSHIFT)
102#define PLAT_CHUNKNUM(addr)		(((addr) & (PLAT_MAX_PHYS_MEMORY-1)) >> SN1_CHUNKSHIFT)
103
104
105/*
106 * Given a kaddr, find the nid (compact nodeid)
107 */
108#ifdef CONFIG_IA64_SGI_SN_DEBUG
109#define DISCONBUG(kaddr)		panic("DISCONTIG BUG: line %d, %s. kaddr 0x%lx",	 	\
110						__LINE__, __FILE__, (long)(kaddr))
111
112#define KVADDR_TO_NID(kaddr)		({long _ktn=(long)(kaddr);					\
113						kern_addr_valid(_ktn) ? 				\
114						local_node_data->physical_node_map[SN1_NODE_NUMBER(_ktn)] :\
115						(DISCONBUG(_ktn), 0UL);})
116#else
117#define KVADDR_TO_NID(kaddr)		(local_node_data->physical_node_map[SN1_NODE_NUMBER(kaddr)])
118#endif
119
120
121
122/*
123 * Given a kaddr, find the index into the clump_mem_map_base array of the page struct entry
124 * for the first page of the clump.
125 */
126#define PLAT_CLUMP_MEM_MAP_INDEX(kaddr)		({long _kmmi=(long)(kaddr);				\
127							KVADDR_TO_NID(_kmmi) * PLAT_CLUMPS_PER_NODE +	\
128							SN1_NODE_CLUMP_NUMBER(_kmmi);})
129
130
131/*
132 * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on
133 * nodes so that they dont alias to the same line in the cache as the previous allocated structure.
134 * This macro takes an address of the end of previous allocation, rounds it to a page boundary &
135 * changes the node number.
136 */
137#define PLAT_BOOTMEM_ALLOC_GOAL(cnode,kaddr)	__pa(SN1_KADDR(PLAT_PXM_TO_PHYS_NODE_NUMBER(nid_to_pxm_map[cnode]),		\
138						  (SN1_NODE_OFFSET(kaddr) + PAGE_SIZE - 1) >> PAGE_SHIFT << PAGE_SHIFT))
139
140
141
142
143/*
144 * Convert a proximity domain number (from the ACPI tables) into a physical node number.
145 */
146
147#define PLAT_PXM_TO_PHYS_NODE_NUMBER(pxm)	(pxm)
148
149#endif /* _ASM_IA64_SN_MMZONE_SN1_H */
150