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