git: 05cf4dda599a - stable/14 - loader: fix EFI ACPI detection

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 16 Apr 2024 02:34:38 UTC
The branch stable/14 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=05cf4dda599a920ffbfb39edc6b01c32dd178f46

commit 05cf4dda599a920ffbfb39edc6b01c32dd178f46
Author:     R. Christian McDonald <rcm@FreeBSD.org>
AuthorDate: 2023-11-20 17:02:24 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-04-16 02:32:04 +0000

    loader: fix EFI ACPI detection
    
    lua was previously unable to determine ACPI presence because this
    probing was postponed until the final loading and execution of the
    kernel.
    
    This patch resolves that by detecting ACPI early (similar to
    the order of operations in the legacy i386 loader).
    
    Reviewed by:    kevans
    Approved by:    kp
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D42459
    
    (cherry picked from commit 0b01d45783c3ee5a544c882d1b147e4a60382c41)
---
 stand/efi/loader/arch/amd64/elf64_freebsd.c | 44 -----------------------
 stand/efi/loader/arch/arm64/exec.c          | 54 +----------------------------
 stand/efi/loader/main.c                     | 42 ++++++++++++++++++++++
 3 files changed, 43 insertions(+), 97 deletions(-)

diff --git a/stand/efi/loader/arch/amd64/elf64_freebsd.c b/stand/efi/loader/arch/amd64/elf64_freebsd.c
index 196efb048064..5a41ea99867e 100644
--- a/stand/efi/loader/arch/amd64/elf64_freebsd.c
+++ b/stand/efi/loader/arch/amd64/elf64_freebsd.c
@@ -41,17 +41,8 @@
 
 #include "bootstrap.h"
 
-#include "platform/acfreebsd.h"
-#include "acconfig.h"
-#define ACPI_SYSTEM_XFACE
-#include "actypes.h"
-#include "actbl.h"
-
 #include "loader_efi.h"
 
-static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
-static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
-
 extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
     bool exit_bs);
 
@@ -104,9 +95,6 @@ elf64_exec(struct preloaded_file *fp)
 	Elf_Ehdr 		*ehdr;
 	vm_offset_t		modulep, kernend, trampcode, trampstack;
 	int			err, i;
-	ACPI_TABLE_RSDP		*rsdp;
-	char			buf[24];
-	int			revision;
 	bool			copy_auto;
 
 	copy_auto = copy_staging == COPY_STAGING_AUTO;
@@ -114,38 +102,6 @@ elf64_exec(struct preloaded_file *fp)
 		copy_staging = fp->f_kernphys_relocatable ?
 		    COPY_STAGING_DISABLE : COPY_STAGING_ENABLE;
 
-	/*
-	 * Report the RSDP to the kernel. While this can be found with
-	 * a BIOS boot, the RSDP may be elsewhere when booted from UEFI.
-	 */
-
-	rsdp = efi_get_table(&acpi20_guid);
-	if (rsdp == NULL) {
-		rsdp = efi_get_table(&acpi_guid);
-	}
-	if (rsdp != NULL) {
-		sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
-		setenv("acpi.rsdp", buf, 1);
-		revision = rsdp->Revision;
-		if (revision == 0)
-			revision = 1;
-		sprintf(buf, "%d", revision);
-		setenv("acpi.revision", buf, 1);
-		strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
-		buf[sizeof(rsdp->OemId)] = '\0';
-		setenv("acpi.oem", buf, 1);
-		sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
-		setenv("acpi.rsdt", buf, 1);
-		if (revision >= 2) {
-			/* XXX extended checksum? */
-			sprintf(buf, "0x%016llx",
-			    (unsigned long long)rsdp->XsdtPhysicalAddress);
-			setenv("acpi.xsdt", buf, 1);
-			sprintf(buf, "%d", rsdp->Length);
-			setenv("acpi.xsdt_length", buf, 1);
-		}
-	}
-
 	if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
 		return (EFTYPE);
 	ehdr = (Elf_Ehdr *)&(md->md_data);
diff --git a/stand/efi/loader/arch/arm64/exec.c b/stand/efi/loader/arch/arm64/exec.c
index 09be15b2b6f3..ef410a7d556c 100644
--- a/stand/efi/loader/arch/arm64/exec.c
+++ b/stand/efi/loader/arch/arm64/exec.c
@@ -40,16 +40,6 @@
 #include "loader_efi.h"
 #include "cache.h"
 
-#include "platform/acfreebsd.h"
-#include "acconfig.h"
-#define ACPI_SYSTEM_XFACE
-#define ACPI_USE_SYSTEM_INTTYPES
-#include "actypes.h"
-#include "actbl.h"
-
-static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
-static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
-
 static int elf64_exec(struct preloaded_file *amp);
 static int elf64_obj_exec(struct preloaded_file *amp);
 
@@ -73,52 +63,10 @@ elf64_exec(struct preloaded_file *fp)
 	vm_offset_t clean_addr;
 	size_t clean_size;
 	struct file_metadata *md;
-	ACPI_TABLE_RSDP *rsdp;
 	Elf_Ehdr *ehdr;
-	char buf[24];
-	int err, revision;
+	int err;
 	void (*entry)(vm_offset_t);
 
-	/*
-	 * Report the RSDP to the kernel. The old code used the 'hints' method
-	 * to communicate this to the kernel, but this is now considered legacy.
-	 * Instead, move to setting different tunables that start with acpi.
-	 * The old 'hints' can be removed before we branch for FreeBSD 15.
-	 */
-
-	rsdp = efi_get_table(&acpi20_guid);
-	if (rsdp == NULL) {
-		rsdp = efi_get_table(&acpi_guid);
-	}
-	if (rsdp != NULL) {
-		sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
-		setenv("hint.acpi.0.rsdp", buf, 1);
-		setenv("acpi.rsdp", buf, 1);
-		revision = rsdp->Revision;
-		if (revision == 0)
-			revision = 1;
-		sprintf(buf, "%d", revision);
-		setenv("hint.acpi.0.revision", buf, 1);
-		setenv("acpi.revision", buf, 1);
-		strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
-		buf[sizeof(rsdp->OemId)] = '\0';
-		setenv("hint.acpi.0.oem", buf, 1);
-		setenv("acpi.oem", buf, 1);
-		sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
-		setenv("hint.acpi.0.rsdt", buf, 1);
-		setenv("acpi.rsdt", buf, 1);
-		if (revision >= 2) {
-			/* XXX extended checksum? */
-			sprintf(buf, "0x%016llx",
-			    (unsigned long long)rsdp->XsdtPhysicalAddress);
-			setenv("hint.acpi.0.xsdt", buf, 1);
-			setenv("acpi.xsdt", buf, 1);
-			sprintf(buf, "%d", rsdp->Length);
-			setenv("hint.acpi.0.xsdt_length", buf, 1);
-			setenv("acpi.xsdt_length", buf, 1);
-		}
-	}
-
 	if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
         	return(EFTYPE);
 
diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c
index ca39c242afc3..4100c0680b7f 100644
--- a/stand/efi/loader/main.c
+++ b/stand/efi/loader/main.c
@@ -60,6 +60,12 @@
 #include "efizfs.h"
 #include "framebuffer.h"
 
+#include "platform/acfreebsd.h"
+#include "acconfig.h"
+#define ACPI_SYSTEM_XFACE
+#include "actypes.h"
+#include "actbl.h"
+
 #include "loader_efi.h"
 
 struct arch_switch archsw;	/* MI/MD interface boundary */
@@ -901,6 +907,39 @@ ptov(uintptr_t x)
 	return ((caddr_t)x);
 }
 
+static void
+acpi_detect(void)
+{
+	ACPI_TABLE_RSDP *rsdp;
+	char buf[24];
+	int revision;
+
+	if ((rsdp = efi_get_table(&acpi20)) == NULL)
+		if ((rsdp = efi_get_table(&acpi)) == NULL)
+			return;
+
+	sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
+	setenv("acpi.rsdp", buf, 1);
+	revision = rsdp->Revision;
+	if (revision == 0)
+		revision = 1;
+	sprintf(buf, "%d", revision);
+	setenv("acpi.revision", buf, 1);
+	strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
+	buf[sizeof(rsdp->OemId)] = '\0';
+	setenv("acpi.oem", buf, 1);
+	sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
+	setenv("acpi.rsdt", buf, 1);
+	if (revision >= 2) {
+		/* XXX extended checksum? */
+		sprintf(buf, "0x%016llx",
+		    (unsigned long long)rsdp->XsdtPhysicalAddress);
+		setenv("acpi.xsdt", buf, 1);
+		sprintf(buf, "%d", rsdp->Length);
+		setenv("acpi.xsdt_length", buf, 1);
+	}
+}
+
 EFI_STATUS
 main(int argc, CHAR16 *argv[])
 {
@@ -947,6 +986,9 @@ main(int argc, CHAR16 *argv[])
         /* Get our loaded image protocol interface structure. */
 	(void) OpenProtocolByHandle(IH, &imgid, (void **)&boot_img);
 
+	/* Report the RSDP early. */
+	acpi_detect();
+
 	/*
 	 * Chicken-and-egg problem; we want to have console output early, but
 	 * some console attributes may depend on reading from eg. the boot