svn commit: r297954 - in head/sys: boot/efi/loader/arch/amd64 boot/i386/libi386 x86/acpica

Warner Losh imp at FreeBSD.org
Thu Apr 14 04:59:52 UTC 2016


Author: imp
Date: Thu Apr 14 04:59:51 2016
New Revision: 297954
URL: https://svnweb.freebsd.org/changeset/base/297954

Log:
  Deprecate using hints.acpi.0.rsdp to communicate the RSDP to the
  system. This uses the hints mechnanism. This mostly works today
  because when there's no static hints (the default), this value can be
  fetched from the hint. When there is a static hints file, the hint
  passed from the boot loader to the kernel is ignored, but for the BIOS
  case we're able to find it anyway. However, with UEFI, the fallback
  doesn't work, so we get a panic instead.
  
  Switch to acpi.rsdp and use TUNABLE_ULONG_FETCH instead. Continue to
  generate the old values to allow for transitions. In addition, fall
  back to the old method if the new method isn't present.
  
  Add comments about all this.
  
  Differential Revision: https://reviews.freebsd.org/D5866

Modified:
  head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c
  head/sys/boot/i386/libi386/biosacpi.c
  head/sys/x86/acpica/OsdEnvironment.c

Modified: head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c
==============================================================================
--- head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c	Thu Apr 14 04:54:47 2016	(r297953)
+++ head/sys/boot/efi/loader/arch/amd64/elf64_freebsd.c	Thu Apr 14 04:59:51 2016	(r297954)
@@ -101,6 +101,17 @@ elf64_exec(struct preloaded_file *fp)
 	char			buf[24];
 	int			revision;
 
+	/*
+	 * Report the RSDP to the kernel. While this can be found with
+	 * a BIOS boot, the RSDP may be elsewhere when booted from UEFI.
+	 * The old code used the 'hints' method to communite this to
+	 * the kernel. However, while convenient, the 'hints' method
+	 * is fragile and does not work when static hints are compiled
+	 * into the kernel. Instead, move to setting different tunables
+	 * that start with acpi. The old 'hints' can be removed before
+	 * we branch for FreeBSD 12.
+	 */
+
 	rsdp = efi_get_table(&acpi20_guid);
 	if (rsdp == NULL) {
 		rsdp = efi_get_table(&acpi_guid);
@@ -108,23 +119,29 @@ elf64_exec(struct preloaded_file *fp)
 	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);
 		}
 	}
 

Modified: head/sys/boot/i386/libi386/biosacpi.c
==============================================================================
--- head/sys/boot/i386/libi386/biosacpi.c	Thu Apr 14 04:54:47 2016	(r297953)
+++ head/sys/boot/i386/libi386/biosacpi.c	Thu Apr 14 04:59:51 2016	(r297954)
@@ -60,25 +60,40 @@ biosacpi_detect(void)
     if ((rsdp = biosacpi_find_rsdp()) == NULL)
 	return;
 
-    /* export values from the RSDP */
+    /*
+     * Report the RSDP to the kernel. While this can be found with
+     * a BIOS boot, the RSDP may be elsewhere when booted from UEFI.
+     * The old code used the 'hints' method to communite this to
+     * the kernel. However, while convenient, the 'hints' method
+     * is fragile and does not work when static hints are compiled
+     * into the kernel. Instead, move to setting different tunables
+     * that start with acpi. The old 'hints' can be removed before
+     * we branch for FreeBSD 12.
+     */
     sprintf(buf, "0x%08x", VTOP(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%08x", rsdp->RsdtPhysicalAddress);
     setenv("hint.acpi.0.rsdt", buf, 1);
+    setenv("acpi.rsdt", buf, 1);
     if (revision >= 2) {
 	/* XXX extended checksum? */
 	sprintf(buf, "0x%016llx", 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);
     }
 }
 

Modified: head/sys/x86/acpica/OsdEnvironment.c
==============================================================================
--- head/sys/x86/acpica/OsdEnvironment.c	Thu Apr 14 04:54:47 2016	(r297953)
+++ head/sys/x86/acpica/OsdEnvironment.c	Thu Apr 14 04:59:51 2016	(r297954)
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
 #include <sys/bus.h>
+#include <sys/kernel.h>
 #include <sys/sysctl.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
@@ -59,6 +60,16 @@ acpi_get_root_from_loader(void)
 {
 	long acpi_root;
 
+	if (TUNABLE_ULONG_FETCH("acpi.rsdp", &acpi_root))
+		return (acpi_root);
+
+	/*
+	 * The hints mechanism is unreliable (it fails if anybody ever
+	 * compiled in hints to the kernel). It has been replaced
+	 * by the tunable method, but is used here as a fallback to
+	 * retain maximum compatibility between old loaders and new
+	 * kernels. It can be removed after 11.0R.
+	 */
 	if (resource_long_value("acpi", 0, "rsdp", &acpi_root) == 0)
 		return (acpi_root);
 


More information about the svn-src-head mailing list