git: 5f3192b3fddd - main - amd64/acpica/acpi_wakeup.c: do not store to WARMBOOT_OFF in efi_boot case

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 10 Feb 2026 02:44:23 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=5f3192b3fddd974db36af0279403aba1371c68ec

commit 5f3192b3fddd974db36af0279403aba1371c68ec
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-02-10 01:37:18 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-02-10 02:38:33 +0000

    amd64/acpica/acpi_wakeup.c: do not store to WARMBOOT_OFF in efi_boot case
    
    Split acpi_wakeup_cpus() into acpi_wakeup_cpus_bios() and
    acpi_wakeup_cpus_efi().  The former needs to manipulate zero page and
    CMOS state, the later does not.
    
    Referenced commit left the write to WARMBOOT_OFF in case of
    acpi_wakeup_ap() failed.
    
    Fixes:  e99255c8a6cae324aeede7f5013d080a2d361e3f
    Reviewed by:    imp
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D55205
---
 sys/amd64/acpica/acpi_wakeup.c | 58 ++++++++++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 22 deletions(-)

diff --git a/sys/amd64/acpica/acpi_wakeup.c b/sys/amd64/acpica/acpi_wakeup.c
index 6e6b9ac618dd..1200d20f14c2 100644
--- a/sys/amd64/acpica/acpi_wakeup.c
+++ b/sys/amd64/acpica/acpi_wakeup.c
@@ -75,9 +75,7 @@ extern struct susppcb	**susppcbs;
 static cpuset_t		suspcpus;
 
 static void		acpi_stop_beep(void *, enum power_stype);
-
 static int		acpi_wakeup_ap(struct acpi_softc *, int);
-static void		acpi_wakeup_cpus(struct acpi_softc *);
 
 #define	ACPI_WAKEPT_PAGES	7
 
@@ -129,24 +127,22 @@ acpi_wakeup_ap(struct acpi_softc *sc, int cpu)
 #define	BIOS_WARM		(0x0a)
 
 static void
-acpi_wakeup_cpus(struct acpi_softc *sc)
+acpi_wakeup_cpus_bios(struct acpi_softc *sc)
 {
 	uint32_t	mpbioswarmvec;
 	int		cpu;
 	u_char		mpbiosreason;
 
-	if (!efi_boot) {
-		/* save the current value of the warm-start vector */
-		mpbioswarmvec = *((uint32_t *)WARMBOOT_OFF);
-		outb(CMOS_REG, BIOS_RESET);
-		mpbiosreason = inb(CMOS_DATA);
-
-		/* setup a vector to our boot code */
-		*((volatile u_short *)WARMBOOT_OFF) = WARMBOOT_TARGET;
-		*((volatile u_short *)WARMBOOT_SEG) = sc->acpi_wakephys >> 4;
-		outb(CMOS_REG, BIOS_RESET);
-		outb(CMOS_DATA, BIOS_WARM);	/* 'warm-start' */
-	}
+	/* save the current value of the warm-start vector */
+	mpbioswarmvec = *((uint32_t *)WARMBOOT_OFF);
+	outb(CMOS_REG, BIOS_RESET);
+	mpbiosreason = inb(CMOS_DATA);
+
+	/* setup a vector to our boot code */
+	*((volatile u_short *)WARMBOOT_OFF) = WARMBOOT_TARGET;
+	*((volatile u_short *)WARMBOOT_SEG) = sc->acpi_wakephys >> 4;
+	outb(CMOS_REG, BIOS_RESET);
+	outb(CMOS_DATA, BIOS_WARM);	/* 'warm-start' */
 
 	/* Wake up each AP. */
 	for (cpu = 1; cpu < mp_ncpus; cpu++) {
@@ -160,12 +156,26 @@ acpi_wakeup_cpus(struct acpi_softc *sc)
 		}
 	}
 
-	if (!efi_boot) {
-		/* restore the warmstart vector */
-		*(uint32_t *)WARMBOOT_OFF = mpbioswarmvec;
+	/* restore the warmstart vector */
+	*(uint32_t *)WARMBOOT_OFF = mpbioswarmvec;
+
+	outb(CMOS_REG, BIOS_RESET);
+	outb(CMOS_DATA, mpbiosreason);
+}
+
+static void
+acpi_wakeup_cpus_efi(struct acpi_softc *sc)
+{
+	int		cpu;
 
-		outb(CMOS_REG, BIOS_RESET);
-		outb(CMOS_DATA, mpbiosreason);
+	/* Wake up each AP. */
+	for (cpu = 1; cpu < mp_ncpus; cpu++) {
+		if (!CPU_ISSET(cpu, &suspcpus))
+			continue;
+		if (acpi_wakeup_ap(sc, cpu) == 0) {
+			panic("acpi_wakeup: failed to resume AP #%d (PHY #%d)",
+			    cpu, cpu_apic_ids[cpu]);
+		}
 	}
 }
 
@@ -264,8 +274,12 @@ acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result,
 			PCPU_SET(switchtime, 0);
 			PCPU_SET(switchticks, ticks);
 			lapic_xapic_mode();
-			if (!CPU_EMPTY(&suspcpus))
-				acpi_wakeup_cpus(sc);
+			if (!CPU_EMPTY(&suspcpus)) {
+				if (efi_boot)
+					acpi_wakeup_cpus_efi(sc);
+				else
+					acpi_wakeup_cpus_bios(sc);
+			}
 		}
 
 		if (!CPU_EMPTY(&suspcpus))