Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99 |
| 3 | * |
| 4 | * PowerPC64 port: |
| 5 | * Copyright (C) 2002 Anton Blanchard, IBM Corp. |
| 6 | */ |
| 7 | #ifndef _ASM_MMZONE_H_ |
| 8 | #define _ASM_MMZONE_H_ |
| 9 | |
| 10 | #include <linux/config.h> |
| 11 | #include <asm/smp.h> |
| 12 | |
| 13 | #ifdef CONFIG_DISCONTIGMEM |
| 14 | |
| 15 | extern struct pglist_data *node_data[]; |
| 16 | |
| 17 | /* |
| 18 | * Following are specific to this numa platform. |
| 19 | */ |
| 20 | |
| 21 | extern int numa_cpu_lookup_table[]; |
| 22 | extern char *numa_memory_lookup_table; |
| 23 | extern cpumask_t numa_cpumask_lookup_table[]; |
| 24 | extern int nr_cpus_in_node[]; |
| 25 | |
| 26 | /* 16MB regions */ |
| 27 | #define MEMORY_INCREMENT_SHIFT 24 |
| 28 | #define MEMORY_INCREMENT (1UL << MEMORY_INCREMENT_SHIFT) |
| 29 | |
| 30 | /* NUMA debugging, will not work on a DLPAR machine */ |
| 31 | #undef DEBUG_NUMA |
| 32 | |
| 33 | static inline int pa_to_nid(unsigned long pa) |
| 34 | { |
| 35 | int nid; |
| 36 | |
| 37 | nid = numa_memory_lookup_table[pa >> MEMORY_INCREMENT_SHIFT]; |
| 38 | |
| 39 | #ifdef DEBUG_NUMA |
| 40 | /* the physical address passed in is not in the map for the system */ |
| 41 | if (nid == -1) { |
| 42 | printk("bad address: %lx\n", pa); |
| 43 | BUG(); |
| 44 | } |
| 45 | #endif |
| 46 | |
| 47 | return nid; |
| 48 | } |
| 49 | |
| 50 | #define pfn_to_nid(pfn) pa_to_nid((pfn) << PAGE_SHIFT) |
| 51 | |
| 52 | /* |
| 53 | * Return a pointer to the node data for node n. |
| 54 | */ |
| 55 | #define NODE_DATA(nid) (node_data[nid]) |
| 56 | |
| 57 | #define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn) |
| 58 | |
| 59 | /* |
| 60 | * Following are macros that each numa implmentation must define. |
| 61 | */ |
| 62 | |
| 63 | /* |
| 64 | * Given a kernel address, find the home node of the underlying memory. |
| 65 | */ |
| 66 | #define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr)) |
| 67 | |
| 68 | #define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map) |
| 69 | #define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) |
| 70 | #define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn) |
| 71 | |
| 72 | #define local_mapnr(kvaddr) \ |
| 73 | ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) |
| 74 | |
| 75 | /* Written this way to avoid evaluating arguments twice */ |
| 76 | #define discontigmem_pfn_to_page(pfn) \ |
| 77 | ({ \ |
| 78 | unsigned long __tmp = pfn; \ |
| 79 | (node_mem_map(pfn_to_nid(__tmp)) + \ |
| 80 | node_localnr(__tmp, pfn_to_nid(__tmp))); \ |
| 81 | }) |
| 82 | |
| 83 | #define discontigmem_page_to_pfn(p) \ |
| 84 | ({ \ |
| 85 | struct page *__tmp = p; \ |
| 86 | (((__tmp) - page_zone(__tmp)->zone_mem_map) + \ |
| 87 | page_zone(__tmp)->zone_start_pfn); \ |
| 88 | }) |
| 89 | |
| 90 | /* XXX fix for discontiguous physical memory */ |
| 91 | #define discontigmem_pfn_valid(pfn) ((pfn) < num_physpages) |
| 92 | |
| 93 | #endif /* CONFIG_DISCONTIGMEM */ |
| 94 | #endif /* _ASM_MMZONE_H_ */ |