diff options
author | Arthur Heymans <arthur@aheymans.xyz> | 2022-11-04 14:00:35 +0100 |
---|---|---|
committer | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2023-04-14 08:32:46 +0000 |
commit | 8547429d396a68fc82cc6aff5b7fa61ae8235834 (patch) | |
tree | aa7b4d7843ca0da8f4a8c359f7e40e6f96a633c9 | |
parent | b885be4d2a44e2d8ad2dde05cd72bbf117edf76b (diff) |
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>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/69225
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
-rw-r--r-- | src/acpi/acpi.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index f4b6d20e50..de5abe09a4 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -157,20 +157,39 @@ unsigned long acpi_create_madt_one_lapic(unsigned long current, u32 index, u32 l return current; } +/* 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." + */ static 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; + int index, apic_ids[CONFIG_MAX_CPUS] = {0}, num_cpus = 0, sort_start = 0; + for (unsigned int thread_id = 0; 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++) current = acpi_create_madt_one_lapic(current, index, apic_ids[index]); |