Attention is currently required from: Lance Zhao, Tim Wawrzynczak.
Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/69225 )
Change subject: acpi/acpi.c: Follow spec more closely for MADT ......................................................................
acpi/acpi.c: Follow spec more closely for MADT
Secondary threads need to be added after the primary threads.
Change-Id: I3a98560760b662a7ba7efb46f5f7882fb0f7bb1f Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/acpi/acpi.c 1 file changed, 41 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/25/69225/1
diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index e211558..c233274 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -141,20 +141,41 @@ return lapic->length; }
+/* Increase if necessary. Currently all x86 CPUs only have 2 SMP threads */ +#define MAX_THREAD_ID 1 +/* + * From ACPI 6.4 spec: + * "The advent of multi-threaded processors yielded multiple logical processors + * executing on common processor hardware. ACPI defines logical processors in + * an identical manner as physical processors. To ensure that non + * multi-threading aware OSPM implementations realize optimal performance on + * platforms containing multi-threaded processors, two guidelines should be + * followed. The first is the same as above, that is, OSPM should initialize + * processors in the order that they appear in the MADT. The second is that + * platform firmware should list the first logical processor of each of the + * individual multi-threaded processors in the MADT before listing any of the + * second logical processors. This approach should be used for all successive + * logical processors." + */ unsigned long acpi_create_madt_lapics(unsigned long current) { struct device *cpu; int index, apic_ids[CONFIG_MAX_CPUS] = {0}, num_cpus = 0;
- for (cpu = all_devices; cpu; cpu = cpu->next) { - if (!is_enabled_cpu(cpu)) - continue; - if (num_cpus >= ARRAY_SIZE(apic_ids)) - break; - apic_ids[num_cpus++] = cpu->path.apic.apic_id; + unsigned int sort_start = 0; + for (unsigned int thread_id; thread_id <= MAX_THREAD_ID; thread_id++) { + for (cpu = all_devices; cpu; cpu = cpu->next) { + if (!is_enabled_cpu(cpu)) + continue; + if (num_cpus >= ARRAY_SIZE(apic_ids)) + break; + if (cpu->path.apic.thread_id != thread_id) + continue; + apic_ids[num_cpus++] = cpu->path.apic.apic_id; + } + bubblesort(&apic_ids[sort_start], num_cpus - sort_start, NUM_ASCENDING); + sort_start = num_cpus; } - if (num_cpus > 1) - bubblesort(apic_ids, num_cpus, NUM_ASCENDING); for (index = 0; index < num_cpus; index++) { if (apic_ids[index] < 0xff) current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current,