|
@@ -1939,13 +1939,15 @@ build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
|
|
|
#define HOLE_640K_START (640 * KiB)
|
|
|
#define HOLE_640K_END (1 * MiB)
|
|
|
|
|
|
+/*
|
|
|
+ * ACPI spec, Revision 3.0
|
|
|
+ * 5.2.15 System Resource Affinity Table (SRAT)
|
|
|
+ */
|
|
|
static void
|
|
|
build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
|
|
{
|
|
|
- AcpiSratMemoryAffinity *numamem;
|
|
|
-
|
|
|
int i;
|
|
|
- int numa_start, slots;
|
|
|
+ int numa_mem_start, slots;
|
|
|
uint64_t mem_len, mem_base, next_base;
|
|
|
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
|
|
X86MachineState *x86ms = X86_MACHINE(machine);
|
|
@@ -1968,34 +1970,41 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
|
|
uint32_t apic_id = apic_ids->cpus[i].arch_id;
|
|
|
|
|
|
if (apic_id < 255) {
|
|
|
- AcpiSratProcessorAffinity *core;
|
|
|
-
|
|
|
- core = acpi_data_push(table_data, sizeof *core);
|
|
|
- core->type = ACPI_SRAT_PROCESSOR_APIC;
|
|
|
- core->length = sizeof(*core);
|
|
|
- core->local_apic_id = apic_id;
|
|
|
- core->proximity_lo = node_id;
|
|
|
- memset(core->proximity_hi, 0, 3);
|
|
|
- core->local_sapic_eid = 0;
|
|
|
- core->flags = cpu_to_le32(1);
|
|
|
+ /* 5.2.15.1 Processor Local APIC/SAPIC Affinity Structure */
|
|
|
+ build_append_int_noprefix(table_data, 0, 1); /* Type */
|
|
|
+ build_append_int_noprefix(table_data, 16, 1); /* Length */
|
|
|
+ /* Proximity Domain [7:0] */
|
|
|
+ build_append_int_noprefix(table_data, node_id, 1);
|
|
|
+ build_append_int_noprefix(table_data, apic_id, 1); /* APIC ID */
|
|
|
+ /* Flags, Table 5-36 */
|
|
|
+ build_append_int_noprefix(table_data, 1, 4);
|
|
|
+ build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */
|
|
|
+ /* Proximity Domain [31:8] */
|
|
|
+ build_append_int_noprefix(table_data, 0, 3);
|
|
|
+ build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
|
|
} else {
|
|
|
- AcpiSratProcessorX2ApicAffinity *core;
|
|
|
-
|
|
|
- core = acpi_data_push(table_data, sizeof *core);
|
|
|
- core->type = ACPI_SRAT_PROCESSOR_x2APIC;
|
|
|
- core->length = sizeof(*core);
|
|
|
- core->x2apic_id = cpu_to_le32(apic_id);
|
|
|
- core->proximity_domain = cpu_to_le32(node_id);
|
|
|
- core->flags = cpu_to_le32(1);
|
|
|
+ /*
|
|
|
+ * ACPI spec, Revision 4.0
|
|
|
+ * 5.2.16.3 Processor Local x2APIC Affinity Structure
|
|
|
+ */
|
|
|
+ build_append_int_noprefix(table_data, 2, 1); /* Type */
|
|
|
+ build_append_int_noprefix(table_data, 24, 1); /* Length */
|
|
|
+ build_append_int_noprefix(table_data, 0, 2); /* Reserved */
|
|
|
+ /* Proximity Domain */
|
|
|
+ build_append_int_noprefix(table_data, node_id, 4);
|
|
|
+ build_append_int_noprefix(table_data, apic_id, 4); /* X2APIC ID */
|
|
|
+ /* Flags, Table 5-39 */
|
|
|
+ build_append_int_noprefix(table_data, 1 /* Enabled */, 4);
|
|
|
+ build_append_int_noprefix(table_data, 0, 4); /* Clock Domain */
|
|
|
+ build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/* the memory map is a bit tricky, it contains at least one hole
|
|
|
* from 640k-1M and possibly another one from 3.5G-4G.
|
|
|
*/
|
|
|
next_base = 0;
|
|
|
- numa_start = table_data->len;
|
|
|
+ numa_mem_start = table_data->len;
|
|
|
|
|
|
for (i = 1; i < nb_numa_nodes + 1; ++i) {
|
|
|
mem_base = next_base;
|
|
@@ -2007,8 +2016,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
|
|
next_base > HOLE_640K_START) {
|
|
|
mem_len -= next_base - HOLE_640K_START;
|
|
|
if (mem_len > 0) {
|
|
|
- numamem = acpi_data_push(table_data, sizeof *numamem);
|
|
|
- build_srat_memory(numamem, mem_base, mem_len, i - 1,
|
|
|
+ build_srat_memory(table_data, mem_base, mem_len, i - 1,
|
|
|
MEM_AFFINITY_ENABLED);
|
|
|
}
|
|
|
|
|
@@ -2026,8 +2034,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
|
|
next_base > x86ms->below_4g_mem_size) {
|
|
|
mem_len -= next_base - x86ms->below_4g_mem_size;
|
|
|
if (mem_len > 0) {
|
|
|
- numamem = acpi_data_push(table_data, sizeof *numamem);
|
|
|
- build_srat_memory(numamem, mem_base, mem_len, i - 1,
|
|
|
+ build_srat_memory(table_data, mem_base, mem_len, i - 1,
|
|
|
MEM_AFFINITY_ENABLED);
|
|
|
}
|
|
|
mem_base = 1ULL << 32;
|
|
@@ -2036,8 +2043,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
|
|
}
|
|
|
|
|
|
if (mem_len > 0) {
|
|
|
- numamem = acpi_data_push(table_data, sizeof *numamem);
|
|
|
- build_srat_memory(numamem, mem_base, mem_len, i - 1,
|
|
|
+ build_srat_memory(table_data, mem_base, mem_len, i - 1,
|
|
|
MEM_AFFINITY_ENABLED);
|
|
|
}
|
|
|
}
|
|
@@ -2046,10 +2052,15 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
|
|
nvdimm_build_srat(table_data);
|
|
|
}
|
|
|
|
|
|
- slots = (table_data->len - numa_start) / sizeof *numamem;
|
|
|
+ /*
|
|
|
+ * TODO: this part is not in ACPI spec and current linux kernel boots fine
|
|
|
+ * without these entries. But I recall there were issues the last time I
|
|
|
+ * tried to remove it with some ancient guest OS, however I can't remember
|
|
|
+ * what that was so keep this around for now
|
|
|
+ */
|
|
|
+ slots = (table_data->len - numa_mem_start) / 40 /* mem affinity len */;
|
|
|
for (; slots < nb_numa_nodes + 2; slots++) {
|
|
|
- numamem = acpi_data_push(table_data, sizeof *numamem);
|
|
|
- build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
|
|
|
+ build_srat_memory(table_data, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -2061,8 +2072,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
|
|
* providing _PXM method if necessary.
|
|
|
*/
|
|
|
if (hotpluggable_address_space_size) {
|
|
|
- numamem = acpi_data_push(table_data, sizeof *numamem);
|
|
|
- build_srat_memory(numamem, machine->device_memory->base,
|
|
|
+ build_srat_memory(table_data, machine->device_memory->base,
|
|
|
hotpluggable_address_space_size, nb_numa_nodes - 1,
|
|
|
MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
|
|
|
}
|