/root/src/xen/xen/drivers/acpi/numa.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * acpi_numa.c - ACPI NUMA support |
3 | | * |
4 | | * Copyright (C) 2002 Takayoshi Kochi <t-kochi@bq.jp.nec.com> |
5 | | * |
6 | | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
7 | | * |
8 | | * This program is free software; you can redistribute it and/or modify |
9 | | * it under the terms of the GNU General Public License as published by |
10 | | * the Free Software Foundation; either version 2 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License |
19 | | * along with this program; If not, see <http://www.gnu.org/licenses/>. |
20 | | * |
21 | | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
22 | | * |
23 | | */ |
24 | | #include <xen/init.h> |
25 | | #include <xen/types.h> |
26 | | #include <xen/errno.h> |
27 | | #include <xen/acpi.h> |
28 | | #include <xen/numa.h> |
29 | | #include <acpi/acmacros.h> |
30 | | |
31 | | #define ACPI_NUMA 0x80000000 |
32 | | #define _COMPONENT ACPI_NUMA |
33 | | ACPI_MODULE_NAME("numa") |
34 | | |
35 | | int __initdata srat_rev; |
36 | | |
37 | | void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header) |
38 | 0 | { |
39 | 0 |
|
40 | 0 | ACPI_FUNCTION_NAME("acpi_table_print_srat_entry"); |
41 | 0 |
|
42 | 0 | if (!header) |
43 | 0 | return; |
44 | 0 |
|
45 | 0 | switch (header->type) { |
46 | 0 |
|
47 | 0 | case ACPI_SRAT_TYPE_CPU_AFFINITY: |
48 | 0 | #ifdef ACPI_DEBUG_OUTPUT |
49 | | { |
50 | | struct acpi_srat_cpu_affinity *p = |
51 | | container_of(header, struct acpi_srat_cpu_affinity, header); |
52 | | u32 proximity_domain = p->proximity_domain_lo; |
53 | | |
54 | | if (srat_rev >= 2) { |
55 | | proximity_domain |= p->proximity_domain_hi[0] << 8; |
56 | | proximity_domain |= p->proximity_domain_hi[1] << 16; |
57 | | proximity_domain |= p->proximity_domain_hi[2] << 24; |
58 | | } |
59 | | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
60 | | "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n", |
61 | | p->apic_id, p->local_sapic_eid, |
62 | | proximity_domain, |
63 | | p->flags & ACPI_SRAT_CPU_ENABLED |
64 | | ? "enabled" : "disabled")); |
65 | | } |
66 | | #endif /* ACPI_DEBUG_OUTPUT */ |
67 | 0 | break; |
68 | 0 |
|
69 | 0 | case ACPI_SRAT_TYPE_MEMORY_AFFINITY: |
70 | 0 | #ifdef ACPI_DEBUG_OUTPUT |
71 | | { |
72 | | struct acpi_srat_mem_affinity *p = |
73 | | container_of(header, struct acpi_srat_mem_affinity, header); |
74 | | u32 proximity_domain = p->proximity_domain; |
75 | | |
76 | | if (srat_rev < 2) |
77 | | proximity_domain &= 0xff; |
78 | | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
79 | | "SRAT Memory (%#"PRIx64 |
80 | | " length %#"PRIx64")" |
81 | | " in proximity domain %d %s%s\n", |
82 | | p->base_address, p->length, |
83 | | proximity_domain, |
84 | | p->flags & ACPI_SRAT_MEM_ENABLED |
85 | | ? "enabled" : "disabled", |
86 | | p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE |
87 | | ? " hot-pluggable" : "")); |
88 | | } |
89 | | #endif /* ACPI_DEBUG_OUTPUT */ |
90 | 0 | break; |
91 | 0 |
|
92 | 0 | case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: |
93 | 0 | #ifdef ACPI_DEBUG_OUTPUT |
94 | | { |
95 | | struct acpi_srat_x2apic_cpu_affinity *p = |
96 | | (struct acpi_srat_x2apic_cpu_affinity *)header; |
97 | | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
98 | | "SRAT Processor (x2apicid[0x%08x]) in" |
99 | | " proximity domain %d %s\n", |
100 | | p->apic_id, |
101 | | p->proximity_domain, |
102 | | (p->flags & ACPI_SRAT_CPU_ENABLED) ? |
103 | | "enabled" : "disabled")); |
104 | | } |
105 | | #endif /* ACPI_DEBUG_OUTPUT */ |
106 | 0 | break; |
107 | 0 | default: |
108 | 0 | printk(KERN_WARNING PREFIX |
109 | 0 | "Found unsupported SRAT entry (type = %#x)\n", |
110 | 0 | header->type); |
111 | 0 | break; |
112 | 0 | } |
113 | 0 | } |
114 | | |
115 | | static int __init acpi_parse_slit(struct acpi_table_header *table) |
116 | 0 | { |
117 | 0 | acpi_numa_slit_init((struct acpi_table_slit *)table); |
118 | 0 |
|
119 | 0 | return 0; |
120 | 0 | } |
121 | | |
122 | | static int __init |
123 | | acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, |
124 | | const unsigned long end) |
125 | 0 | { |
126 | 0 | const struct acpi_srat_x2apic_cpu_affinity *processor_affinity |
127 | 0 | = container_of(header, struct acpi_srat_x2apic_cpu_affinity, |
128 | 0 | header); |
129 | 0 |
|
130 | 0 | if (!header) |
131 | 0 | return -EINVAL; |
132 | 0 |
|
133 | 0 | acpi_table_print_srat_entry(header); |
134 | 0 |
|
135 | 0 | /* let architecture-dependent part to do it */ |
136 | 0 | acpi_numa_x2apic_affinity_init(processor_affinity); |
137 | 0 |
|
138 | 0 | return 0; |
139 | 0 | } |
140 | | |
141 | | static int __init |
142 | | acpi_parse_processor_affinity(struct acpi_subtable_header *header, |
143 | | const unsigned long end) |
144 | 0 | { |
145 | 0 | const struct acpi_srat_cpu_affinity *processor_affinity |
146 | 0 | = container_of(header, struct acpi_srat_cpu_affinity, header); |
147 | 0 |
|
148 | 0 | if (!header) |
149 | 0 | return -EINVAL; |
150 | 0 |
|
151 | 0 | acpi_table_print_srat_entry(header); |
152 | 0 |
|
153 | 0 | /* let architecture-dependent part to do it */ |
154 | 0 | acpi_numa_processor_affinity_init(processor_affinity); |
155 | 0 |
|
156 | 0 | return 0; |
157 | 0 | } |
158 | | |
159 | | static int __init |
160 | | acpi_parse_memory_affinity(struct acpi_subtable_header *header, |
161 | | const unsigned long end) |
162 | 0 | { |
163 | 0 | const struct acpi_srat_mem_affinity *memory_affinity |
164 | 0 | = container_of(header, struct acpi_srat_mem_affinity, header); |
165 | 0 |
|
166 | 0 | if (!header) |
167 | 0 | return -EINVAL; |
168 | 0 |
|
169 | 0 | acpi_table_print_srat_entry(header); |
170 | 0 |
|
171 | 0 | /* let architecture-dependent part to do it */ |
172 | 0 | acpi_numa_memory_affinity_init(memory_affinity); |
173 | 0 |
|
174 | 0 | return 0; |
175 | 0 | } |
176 | | |
177 | | int __init acpi_parse_srat(struct acpi_table_header *table) |
178 | 0 | { |
179 | 0 | if (!table) |
180 | 0 | return -EINVAL; |
181 | 0 |
|
182 | 0 | srat_rev = table->revision; |
183 | 0 |
|
184 | 0 | return 0; |
185 | 0 | } |
186 | | |
187 | | int __init |
188 | | acpi_table_parse_srat(int id, acpi_madt_entry_handler handler, |
189 | | unsigned int max_entries) |
190 | 0 | { |
191 | 0 | return acpi_table_parse_entries(ACPI_SIG_SRAT, |
192 | 0 | sizeof(struct acpi_table_srat), id, |
193 | 0 | handler, max_entries); |
194 | 0 | } |
195 | | |
196 | | int __init acpi_numa_init(void) |
197 | 1 | { |
198 | 1 | /* SRAT: Static Resource Affinity Table */ |
199 | 1 | if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { |
200 | 0 | acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY, |
201 | 0 | acpi_parse_x2apic_affinity, 0); |
202 | 0 | acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, |
203 | 0 | acpi_parse_processor_affinity, 0); |
204 | 0 | acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, |
205 | 0 | acpi_parse_memory_affinity, |
206 | 0 | NR_NODE_MEMBLKS); |
207 | 0 | } |
208 | 1 | |
209 | 1 | /* SLIT: System Locality Information Table */ |
210 | 1 | acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); |
211 | 1 | |
212 | 1 | acpi_numa_arch_fixup(); |
213 | 1 | return 0; |
214 | 1 | } |
215 | | |
216 | | #if 0 |
217 | | int acpi_get_pxm(acpi_handle h) |
218 | | { |
219 | | unsigned long pxm; |
220 | | acpi_status status; |
221 | | acpi_handle handle; |
222 | | acpi_handle phandle = h; |
223 | | |
224 | | do { |
225 | | handle = phandle; |
226 | | status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm); |
227 | | if (ACPI_SUCCESS(status)) |
228 | | return (int)pxm; |
229 | | status = acpi_get_parent(handle, &phandle); |
230 | | } while (ACPI_SUCCESS(status)); |
231 | | return -1; |
232 | | } |
233 | | |
234 | | EXPORT_SYMBOL(acpi_get_pxm); |
235 | | #endif |