1#include <acpi/acpi.h>
2#include <asm.h>
3#include <console/panic.h>
4#include <console/printf.h>
5#include <global.h>
6#include <log.h>
7#include <math/sort.h>
8#include <mem/alloc.h>
9#include <mem/numa.h>
10#include <mem/vmm.h>
11#include <uacpi/tables.h>
12
13#include "uacpi/acpi.h"
14#include "uacpi/status.h"
15
16LOG_HANDLE_DECLARE_PRINT(slit);
17
18void slit_init(void) {
19 struct uacpi_table slit_table;
20 size_t nodes = global.numa_node_count;
21
22 if (uacpi_table_find_by_signature(signature: "SLIT", out_table: &slit_table) != UACPI_STATUS_OK) {
23 log_warn_global(LOG_HANDLE(slit),
24 "SLIT table not found, assuming uniform distances");
25
26 /* distances_cnt is 0 with no SRAT, and `distance` is NULL there */
27 for (size_t i = 0; i < nodes; i++) {
28 struct numa_node *node = &global.numa_nodes[i];
29 for (size_t j = 0; j < node->distances_cnt; j++)
30 node->distance[j] = (i == j) ? 10 : 20;
31 }
32 } else {
33 struct acpi_slit *slit = slit_table.ptr;
34 size_t localities = slit->num_localities;
35
36 if (localities != nodes) {
37 log_warn_global(LOG_HANDLE(slit),
38 "Mismatch in SLIT nodes vs detected NUMA nodes");
39 }
40
41 /* The matrix is localities x localities, only detected nodes get rows
42 */
43 uint8_t *entry = slit->matrix;
44
45 for (size_t i = 0; i < nodes && i < localities; i++) {
46 struct numa_node *node = &global.numa_nodes[i];
47 for (size_t j = 0; j < node->distances_cnt && j < localities; j++)
48 node->distance[j] = entry[i * localities + j];
49 }
50 }
51
52 /* Every consumer of rel_dists treats it as present,
53 * and missing SLIT can happen */
54 for (size_t i = 0; i < nodes; i++) {
55 if (global.numa_nodes[i].distances_cnt)
56 numa_construct_relative_distances(node: &global.numa_nodes[i]);
57 }
58
59 numa_dump();
60}
61