git: 5f3192b3fddd - main - amd64/acpica/acpi_wakeup.c: do not store to WARMBOOT_OFF in efi_boot case
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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))