srat.c (70d8f36aa445e4556ead4de32f9b7b4687d95098) srat.c (289908743e527620c74ecdbbd814eb1f88fcaee0)
1/*-
2 * Copyright (c) 2010 Advanced Computing Technologies LLC
3 * Written by: John H. Baldwin <jhb@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 31 unchanged lines hidden (view full) ---

40#include <contrib/dev/acpica/include/acpi.h>
41#include <contrib/dev/acpica/include/actables.h>
42
43#include <machine/intr_machdep.h>
44#include <machine/apicvar.h>
45
46#include <dev/acpica/acpivar.h>
47
1/*-
2 * Copyright (c) 2010 Advanced Computing Technologies LLC
3 * Written by: John H. Baldwin <jhb@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 31 unchanged lines hidden (view full) ---

40#include <contrib/dev/acpica/include/acpi.h>
41#include <contrib/dev/acpica/include/actables.h>
42
43#include <machine/intr_machdep.h>
44#include <machine/apicvar.h>
45
46#include <dev/acpica/acpivar.h>
47
48#if VM_NDOMAIN > 1
48struct cpu_info {
49 int enabled:1;
50 int has_memory:1;
51 int domain;
52} cpus[MAX_APIC_ID + 1];
53
54struct mem_affinity mem_info[VM_PHYSSEG_MAX + 1];
55int num_mem;

--- 176 unchanged lines hidden (view full) ---

232 }
233 printf("SRAT: No memory region found for %jx - %jx\n",
234 (uintmax_t)phys_avail[j], (uintmax_t)phys_avail[j + 1]);
235 return (ENXIO);
236}
237
238/*
239 * Renumber the memory domains to be compact and zero-based if not
49struct cpu_info {
50 int enabled:1;
51 int has_memory:1;
52 int domain;
53} cpus[MAX_APIC_ID + 1];
54
55struct mem_affinity mem_info[VM_PHYSSEG_MAX + 1];
56int num_mem;

--- 176 unchanged lines hidden (view full) ---

233 }
234 printf("SRAT: No memory region found for %jx - %jx\n",
235 (uintmax_t)phys_avail[j], (uintmax_t)phys_avail[j + 1]);
236 return (ENXIO);
237}
238
239/*
240 * Renumber the memory domains to be compact and zero-based if not
240 * already.
241 * already. Returns an error if there are too many domains.
241 */
242 */
242static void
243static int
243renumber_domains(void)
244{
245 int domains[VM_PHYSSEG_MAX];
246 int ndomain, i, j, slot;
247
248 /* Enumerate all the domains. */
249 ndomain = 0;
250 for (i = 0; i < num_mem; i++) {

--- 5 unchanged lines hidden (view full) ---

256 if (j < ndomain && domains[j] == mem_info[i].domain)
257 continue;
258
259 /* Insert the new domain at slot 'j'. */
260 slot = j;
261 for (j = ndomain; j > slot; j--)
262 domains[j] = domains[j - 1];
263 domains[slot] = mem_info[i].domain;
244renumber_domains(void)
245{
246 int domains[VM_PHYSSEG_MAX];
247 int ndomain, i, j, slot;
248
249 /* Enumerate all the domains. */
250 ndomain = 0;
251 for (i = 0; i < num_mem; i++) {

--- 5 unchanged lines hidden (view full) ---

257 if (j < ndomain && domains[j] == mem_info[i].domain)
258 continue;
259
260 /* Insert the new domain at slot 'j'. */
261 slot = j;
262 for (j = ndomain; j > slot; j--)
263 domains[j] = domains[j - 1];
264 domains[slot] = mem_info[i].domain;
265 ndomain++;
266 if (ndomain > VM_NDOMAIN) {
267 printf("SRAT: Too many memory domains\n");
268 return (EFBIG);
269 }
264 }
265
266 /* Renumber each domain to its index in the sorted 'domains' list. */
267 for (i = 0; i < ndomain; i++) {
268 /*
269 * If the domain is already the right value, no need
270 * to renumber.
271 */
272 if (domains[i] == i)
273 continue;
274
275 /* Walk the cpu[] and mem_info[] arrays to renumber. */
276 for (j = 0; j < num_mem; j++)
277 if (mem_info[j].domain == domains[i])
278 mem_info[j].domain = i;
279 for (j = 0; j <= MAX_APIC_ID; j++)
280 if (cpus[j].enabled && cpus[j].domain == domains[i])
281 cpus[j].domain = i;
282 }
270 }
271
272 /* Renumber each domain to its index in the sorted 'domains' list. */
273 for (i = 0; i < ndomain; i++) {
274 /*
275 * If the domain is already the right value, no need
276 * to renumber.
277 */
278 if (domains[i] == i)
279 continue;
280
281 /* Walk the cpu[] and mem_info[] arrays to renumber. */
282 for (j = 0; j < num_mem; j++)
283 if (mem_info[j].domain == domains[i])
284 mem_info[j].domain = i;
285 for (j = 0; j <= MAX_APIC_ID; j++)
286 if (cpus[j].enabled && cpus[j].domain == domains[i])
287 cpus[j].domain = i;
288 }
289 return (0);
283}
284
285/*
286 * Look for an ACPI System Resource Affinity Table ("SRAT")
287 */
288static void
289parse_srat(void *dummy)
290{

--- 10 unchanged lines hidden (view full) ---

301 * Make a pass over the table to populate the cpus[] and
302 * mem_info[] tables.
303 */
304 srat = acpi_map_table(srat_physaddr, ACPI_SIG_SRAT);
305 error = 0;
306 srat_walk_table(srat_parse_entry, &error);
307 acpi_unmap_table(srat);
308 srat = NULL;
290}
291
292/*
293 * Look for an ACPI System Resource Affinity Table ("SRAT")
294 */
295static void
296parse_srat(void *dummy)
297{

--- 10 unchanged lines hidden (view full) ---

308 * Make a pass over the table to populate the cpus[] and
309 * mem_info[] tables.
310 */
311 srat = acpi_map_table(srat_physaddr, ACPI_SIG_SRAT);
312 error = 0;
313 srat_walk_table(srat_parse_entry, &error);
314 acpi_unmap_table(srat);
315 srat = NULL;
309 if (error || check_domains() != 0 || check_phys_avail() != 0) {
316 if (error || check_domains() != 0 || check_phys_avail() != 0 ||
317 renumber_domains() != 0) {
310 srat_physaddr = 0;
311 return;
312 }
313
318 srat_physaddr = 0;
319 return;
320 }
321
314 renumber_domains();
315
316 /* Point vm_phys at our memory affinity table. */
317 mem_affinity = mem_info;
318}
319SYSINIT(parse_srat, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_srat, NULL);
320
321static void
322srat_walk_table(acpi_subtable_handler *handler, void *arg)
323{

--- 25 unchanged lines hidden (view full) ---

349 pc->pc_apic_id);
350 pc->pc_domain = cpu->domain;
351 if (bootverbose)
352 printf("SRAT: CPU %u has memory domain %d\n", i,
353 cpu->domain);
354 }
355}
356SYSINIT(srat_set_cpus, SI_SUB_CPU, SI_ORDER_ANY, srat_set_cpus, NULL);
322 /* Point vm_phys at our memory affinity table. */
323 mem_affinity = mem_info;
324}
325SYSINIT(parse_srat, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_srat, NULL);
326
327static void
328srat_walk_table(acpi_subtable_handler *handler, void *arg)
329{

--- 25 unchanged lines hidden (view full) ---

355 pc->pc_apic_id);
356 pc->pc_domain = cpu->domain;
357 if (bootverbose)
358 printf("SRAT: CPU %u has memory domain %d\n", i,
359 cpu->domain);
360 }
361}
362SYSINIT(srat_set_cpus, SI_SUB_CPU, SI_ORDER_ANY, srat_set_cpus, NULL);
363#endif /* VM_NDOMAIN > 1 */