#ifndef _ASM_IA64_SN_MMZONE_SN2_H #define _ASM_IA64_SN_MMZONE_SN2_H /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (c) 2000-2002 Silicon Graphics, Inc. All rights reserved. */ #include /* * SGI SN2 Arch defined values * * An SN2 physical address is broken down as follows: * * +-----------------------------------------+ * | | | | node offset | * | unused | node | AS |-------------------| * | | | | cn | clump offset | * +-----------------------------------------+ * 6 4 4 3 3 3 3 3 3 0 * 3 9 8 8 7 6 5 4 3 0 * * bits 63-49 Unused - must be zero * bits 48-38 Node number. Note that some configurations do NOT * have a node zero. * bits 37-36 Address space ID. Cached memory has a value of 3 (!!!). * Chipset & IO addresses have other values. * (Yikes!! The hardware folks hate us...) * bits 35-0 Node offset. * * The node offset can be further broken down as: * bits 35-34 Clump (bank) number. * bits 33-0 Clump (bank) offset. * * A node consists of up to 4 clumps (banks) of memory. A clump may be empty, or may be * populated with a single contiguous block of memory starting at clump * offset 0. The size of the block is (2**n) * 64MB, where 0> SN2_NODE_SHIFT) & SN2_NODE_MASK) #define SN2_NODE_CLUMP_NUMBER(kaddr) (((unsigned long)(kaddr) >>34) & 3) #define SN2_NODE_OFFSET(addr) (((unsigned long)(addr)) & SN2_NODE_OFFSET_MASK) #define SN2_KADDR(nasid, offset) (((unsigned long)(nasid)<>2) | \ (_p&SN2_NODE_OFFSET_MASK)) >>SN2_CHUNKSHIFT;}) /* * Given a kaddr, find the nid (compact nodeid) */ #ifdef CONFIG_IA64_SGI_SN_DEBUG #define DISCONBUG(kaddr) panic("DISCONTIG BUG: line %d, %s. kaddr 0x%lx", \ __LINE__, __FILE__, (long)(kaddr)) #define KVADDR_TO_NID(kaddr) ({long _ktn=(long)(kaddr); \ kern_addr_valid(_ktn) ? \ local_node_data->physical_node_map[SN2_NODE_NUMBER(_ktn)] : \ (DISCONBUG(_ktn), 0UL);}) #else #define KVADDR_TO_NID(kaddr) (local_node_data->physical_node_map[SN2_NODE_NUMBER(kaddr)]) #endif /* * Given a kaddr, find the index into the clump_mem_map_base array of the page struct entry * for the first page of the clump. */ #define PLAT_CLUMP_MEM_MAP_INDEX(kaddr) ({long _kmmi=(long)(kaddr); \ KVADDR_TO_NID(_kmmi) * PLAT_CLUMPS_PER_NODE + \ SN2_NODE_CLUMP_NUMBER(_kmmi);}) /* * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on * nodes so that they dont alias to the same line in the cache as the previous allocated structure. * This macro takes an address of the end of previous allocation, rounds it to a page boundary & * changes the node number. */ #define PLAT_BOOTMEM_ALLOC_GOAL(cnode,kaddr) __pa(SN2_KADDR(PLAT_PXM_TO_PHYS_NODE_NUMBER(nid_to_pxm_map[cnode]), \ (SN2_NODE_OFFSET(kaddr) + PAGE_SIZE - 1) >> PAGE_SHIFT << PAGE_SHIFT)) /* * Convert a proximity domain number (from the ACPI tables) into a physical node number. * Note: on SN2, the promity domain number is the same as bits [8:1] of the NASID. The following * algorithm relies on: * - bit 0 of the NASID for cpu nodes is always 0 * - bits [10:9] of all NASIDs in a partition are always the same * - hard_smp_processor_id return the SAPIC of the current cpu & * bits 0..11 contain the NASID. * * All of this complexity is because MS architectually limited proximity domain numbers to * 8 bits. */ #define PLAT_PXM_TO_PHYS_NODE_NUMBER(pxm) (((pxm)<<1) | (hard_smp_processor_id() & 0x300)) #endif /* _ASM_IA64_SN_MMZONE_SN2_H */