1 /*
2  * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99
3  * Adapted for the alpha wildfire architecture Jan 2001.
4  */
5 #ifndef _ASM_MMZONE_H_
6 #define _ASM_MMZONE_H_
7 
8 #include <linux/config.h>
9 #ifdef CONFIG_NUMA_SCHED
10 #include <linux/numa_sched.h>
11 #endif
12 #ifdef NOTYET
13 #include <asm/sn/types.h>
14 #include <asm/sn/addrs.h>
15 #include <asm/sn/arch.h>
16 #include <asm/sn/klkernvars.h>
17 #endif /* NOTYET */
18 
19 typedef struct plat_pglist_data {
20 	pg_data_t	gendata;
21 #ifdef NOTYET
22 	kern_vars_t	kern_vars;
23 #endif
24 #if defined(CONFIG_NUMA) && defined(CONFIG_NUMA_SCHED)
25 	struct numa_schedule_data schedule_data;
26 #endif
27 } plat_pg_data_t;
28 
29 struct bootmem_data_t; /* stupid forward decl. */
30 
31 /*
32  * Following are macros that are specific to this numa platform.
33  */
34 
35 extern plat_pg_data_t *plat_node_data[];
36 
37 #define ALPHA_PA_TO_NID(pa)		\
38         (alpha_mv.pa_to_nid 		\
39 	 ? alpha_mv.pa_to_nid(pa)	\
40 	 : (0))
41 #define NODE_MEM_START(nid)		\
42         (alpha_mv.node_mem_start 	\
43 	 ? alpha_mv.node_mem_start(nid) \
44 	 : (0UL))
45 #define NODE_MEM_SIZE(nid)		\
46         (alpha_mv.node_mem_size 	\
47 	 ? alpha_mv.node_mem_size(nid) 	\
48 	 : ((nid) ? (0UL) : (~0UL)))
49 #define MAX_NUMNODES		128		/* marvel */
50 
51 #define PHYSADDR_TO_NID(pa)		ALPHA_PA_TO_NID(pa)
52 #define PLAT_NODE_DATA(n)		(plat_node_data[(n)])
53 #define PLAT_NODE_DATA_STARTNR(n)	\
54 	(PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
55 #define PLAT_NODE_DATA_SIZE(n)		(PLAT_NODE_DATA(n)->gendata.node_size)
56 
57 #if 1
58 #define PLAT_NODE_DATA_LOCALNR(p, n)	\
59 	(((p) - PLAT_NODE_DATA(n)->gendata.node_start_paddr) >> PAGE_SHIFT)
60 #else
61 static inline unsigned long
PLAT_NODE_DATA_LOCALNR(unsigned long p,int n)62 PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
63 {
64 	unsigned long temp;
65 	temp = p - PLAT_NODE_DATA(n)->gendata.node_start_paddr;
66 	return (temp >> PAGE_SHIFT);
67 }
68 #endif
69 
70 #ifdef CONFIG_DISCONTIGMEM
71 
72 /*
73  * Following are macros that each numa implmentation must define.
74  */
75 
76 /*
77  * Given a kernel address, find the home node of the underlying memory.
78  */
79 #define KVADDR_TO_NID(kaddr)	PHYSADDR_TO_NID(__pa(kaddr))
80 
81 /*
82  * Return a pointer to the node data for node n.
83  */
84 #define NODE_DATA(n)	(&((PLAT_NODE_DATA(n))->gendata))
85 
86 /*
87  * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
88  */
89 #define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
90 
91 /*
92  * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
93  * and returns the mem_map of that node.
94  */
95 #define ADDR_TO_MAPBASE(kaddr) \
96 			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
97 
98 /*
99  * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
100  * and returns the kaddr corresponding to first physical page in the
101  * node's mem_map.
102  */
103 #define LOCAL_BASE_ADDR(kaddr)	((unsigned long)__va(NODE_DATA(KVADDR_TO_NID(kaddr))->node_start_paddr))
104 
105 #define LOCAL_MAP_NR(kvaddr) \
106 	(((unsigned long)(kvaddr)-LOCAL_BASE_ADDR(kvaddr)) >> PAGE_SHIFT)
107 
108 #define kern_addr_valid(kaddr)	test_bit(LOCAL_MAP_NR(kaddr), \
109 					 NODE_DATA(KVADDR_TO_NID(kaddr))->valid_addr_bitmap)
110 
111 #define virt_to_page(kaddr)	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
112 #define VALID_PAGE(page)	(((page) - mem_map) < max_mapnr)
113 
114 #ifdef CONFIG_NUMA
115 #ifdef CONFIG_NUMA_SCHED
116 #define NODE_SCHEDULE_DATA(nid)	(&((PLAT_NODE_DATA(nid))->schedule_data))
117 #endif
118 
119 #define cputonode(cpu) 	\
120         (alpha_mv.cpuid_to_nid ? alpha_mv.cpuid_to_nid(cpu) : 0)
121 
122 #define numa_node_id()	cputonode(smp_processor_id())
123 #endif /* CONFIG_NUMA */
124 
125 #endif /* CONFIG_DISCONTIGMEM */
126 
127 #endif /* _ASM_MMZONE_H_ */
128