Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
145e6642 AW |
13 | /* generic non-linear memory support: |
14 | * | |
15 | * 1) we will not split memory into more chunks than will fit into the | |
16 | * flags field of the struct page | |
17 | */ | |
18 | ||
19 | ||
20 | #ifdef CONFIG_NEED_MULTIPLE_NODES | |
1da177e4 LT |
21 | |
22 | extern struct pglist_data *node_data[]; | |
145e6642 AW |
23 | /* |
24 | * Return a pointer to the node data for node n. | |
25 | */ | |
26 | #define NODE_DATA(nid) (node_data[nid]) | |
1da177e4 LT |
27 | |
28 | /* | |
29 | * Following are specific to this numa platform. | |
30 | */ | |
31 | ||
32 | extern int numa_cpu_lookup_table[]; | |
33 | extern char *numa_memory_lookup_table; | |
34 | extern cpumask_t numa_cpumask_lookup_table[]; | |
35 | extern int nr_cpus_in_node[]; | |
36 | ||
37 | /* 16MB regions */ | |
38 | #define MEMORY_INCREMENT_SHIFT 24 | |
39 | #define MEMORY_INCREMENT (1UL << MEMORY_INCREMENT_SHIFT) | |
40 | ||
41 | /* NUMA debugging, will not work on a DLPAR machine */ | |
42 | #undef DEBUG_NUMA | |
43 | ||
44 | static inline int pa_to_nid(unsigned long pa) | |
45 | { | |
46 | int nid; | |
47 | ||
48 | nid = numa_memory_lookup_table[pa >> MEMORY_INCREMENT_SHIFT]; | |
49 | ||
50 | #ifdef DEBUG_NUMA | |
51 | /* the physical address passed in is not in the map for the system */ | |
52 | if (nid == -1) { | |
53 | printk("bad address: %lx\n", pa); | |
54 | BUG(); | |
55 | } | |
56 | #endif | |
57 | ||
58 | return nid; | |
59 | } | |
60 | ||
1da177e4 LT |
61 | #define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn) |
62 | ||
63 | /* | |
64 | * Following are macros that each numa implmentation must define. | |
65 | */ | |
66 | ||
1da177e4 LT |
67 | #define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) |
68 | #define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn) | |
69 | ||
70 | #define local_mapnr(kvaddr) \ | |
71 | ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) | |
72 | ||
145e6642 AW |
73 | #ifdef CONFIG_DISCONTIGMEM |
74 | ||
75 | /* | |
76 | * Given a kernel address, find the home node of the underlying memory. | |
77 | */ | |
78 | #define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr)) | |
79 | ||
80 | #define pfn_to_nid(pfn) pa_to_nid((unsigned long)(pfn) << PAGE_SHIFT) | |
81 | ||
1da177e4 LT |
82 | /* Written this way to avoid evaluating arguments twice */ |
83 | #define discontigmem_pfn_to_page(pfn) \ | |
84 | ({ \ | |
85 | unsigned long __tmp = pfn; \ | |
408fde81 | 86 | (NODE_DATA(pfn_to_nid(__tmp))->node_mem_map + \ |
1da177e4 LT |
87 | node_localnr(__tmp, pfn_to_nid(__tmp))); \ |
88 | }) | |
89 | ||
90 | #define discontigmem_page_to_pfn(p) \ | |
91 | ({ \ | |
92 | struct page *__tmp = p; \ | |
93 | (((__tmp) - page_zone(__tmp)->zone_mem_map) + \ | |
94 | page_zone(__tmp)->zone_start_pfn); \ | |
95 | }) | |
96 | ||
97 | /* XXX fix for discontiguous physical memory */ | |
98 | #define discontigmem_pfn_valid(pfn) ((pfn) < num_physpages) | |
99 | ||
100 | #endif /* CONFIG_DISCONTIGMEM */ | |
510f8fa7 | 101 | |
145e6642 AW |
102 | #endif /* CONFIG_NEED_MULTIPLE_NODES */ |
103 | ||
510f8fa7 AW |
104 | #ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID |
105 | #define early_pfn_to_nid(pfn) pa_to_nid(((unsigned long)pfn) << PAGE_SHIFT) | |
106 | #endif | |
107 | ||
1da177e4 | 108 | #endif /* _ASM_MMZONE_H_ */ |