git: 9a46a1439c46 - main - acpi_cpu: only report unmapped processor objects enabled in the MADT

From: Abdelkader Boudih <seuros_at_FreeBSD.org>
Date: Sun, 13 Sep 2026 20:48:52 UTC
The branch main has been updated by seuros:

URL: https://cgit.FreeBSD.org/src/commit/?id=9a46a1439c46045ecb33684d8fbdb1a841ccb425

commit 9a46a1439c46045ecb33684d8fbdb1a841ccb425
Author:     Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-09-13 20:48:26 +0000
Commit:     Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-09-13 20:48:26 +0000

    acpi_cpu: only report unmapped processor objects enabled in the MADT
    
    Firmware expose a DSDT sized for the largest SKU of the platform,
    so a verbose boot prints an "ignored" line for every vacant
    processor slot. A vacant slot has no enabled MADT entry; a CPU that
    failed to come online does.
    
    Reviewed by:    olce, adrian
    Differential Revision:  https://reviews.freebsd.org/D59551
---
 sys/dev/acpica/acpi_cpu.c | 65 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 62 insertions(+), 3 deletions(-)

diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index 48f6a27c1e89..d3ac92f920ab 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -163,6 +163,8 @@ static int	acpi_cpu_suspend(device_t dev);
 static int	acpi_cpu_resume(device_t dev);
 static int	acpi_pcpu_get_id(device_t dev, uint32_t acpi_id,
 		    u_int *cpu_id);
+static void	acpi_cpu_madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg);
+static bool	acpi_cpu_enabled_in_madt(uint32_t acpi_id);
 static struct resource_list *acpi_cpu_get_rlist(device_t dev, device_t child);
 static device_t	acpi_cpu_add_child(device_t dev, u_int order, const char *name,
 		    int unit);
@@ -284,9 +286,10 @@ acpi_cpu_probe(device_t dev)
 	}
     }
     if (acpi_pcpu_get_id(dev, acpi_id, &cpu_id) != 0) {
-	if (bootverbose && (type != ACPI_TYPE_PROCESSOR || acpi_id != 255))
-	    printf("ACPI: Processor %s (ACPI ID %u) ignored\n",
-		acpi_name(acpi_get_handle(dev)), acpi_id);
+	if (bootverbose && (type != ACPI_TYPE_PROCESSOR || acpi_id != 255) &&
+	    acpi_cpu_enabled_in_madt(acpi_id))
+	    printf("ACPI: Processor %s (ACPI ID %u) enabled but not online, "
+		"ignored\n", acpi_name(handle), acpi_id);
 	return (ENXIO);
     }
 
@@ -584,6 +587,62 @@ acpi_pcpu_get_id(device_t dev, uint32_t acpi_id, u_int *cpu_id)
     return (ESRCH);
 }
 
+struct acpi_cpu_madt_check {
+    uint32_t	acpi_id;
+    bool	enabled;
+};
+
+static void
+acpi_cpu_madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
+{
+    struct acpi_cpu_madt_check *check = arg;
+    uint32_t id, flags;
+
+    switch (entry->Type) {
+    case ACPI_MADT_TYPE_LOCAL_APIC:
+	id = ((ACPI_MADT_LOCAL_APIC *)entry)->ProcessorId;
+	flags = ((ACPI_MADT_LOCAL_APIC *)entry)->LapicFlags;
+	break;
+    case ACPI_MADT_TYPE_LOCAL_X2APIC:
+	id = ((ACPI_MADT_LOCAL_X2APIC *)entry)->Uid;
+	flags = ((ACPI_MADT_LOCAL_X2APIC *)entry)->LapicFlags;
+	break;
+    case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+	id = ((ACPI_MADT_GENERIC_INTERRUPT *)entry)->Uid;
+	flags = ((ACPI_MADT_GENERIC_INTERRUPT *)entry)->Flags;
+	break;
+    case ACPI_MADT_TYPE_RINTC:
+	id = ((ACPI_MADT_RINTC *)entry)->Uid;
+	flags = ((ACPI_MADT_RINTC *)entry)->Flags;
+	break;
+    default:
+	return;
+    }
+    if (id == check->acpi_id && (flags & ACPI_MADT_ENABLED) != 0)
+	check->enabled = true;
+}
+
+static bool
+acpi_cpu_enabled_in_madt(uint32_t acpi_id)
+{
+    static ACPI_TABLE_MADT *madt;
+    struct acpi_cpu_madt_check check = {
+	.acpi_id = acpi_id,
+    };
+    ACPI_TABLE_HEADER *hdr;
+
+    if (madt == NULL) {
+	if (ACPI_FAILURE(AcpiGetTable(ACPI_SIG_MADT, 1, &hdr)))
+	    return (false);
+	madt = (ACPI_TABLE_MADT *)hdr;
+	/* Retain the table reference for subsequent processor probes. */
+    }
+
+    acpi_walk_subtables(madt + 1,
+	(char *)madt + madt->Header.Length, acpi_cpu_madt_handler, &check);
+    return (check.enabled);
+}
+
 static struct resource_list *
 acpi_cpu_get_rlist(device_t dev, device_t child)
 {