Index: sys/boot/efi/loader/arch/amd64/elf64_freebsd.c =================================================================== --- sys/boot/efi/loader/arch/amd64/elf64_freebsd.c +++ sys/boot/efi/loader/arch/amd64/elf64_freebsd.c @@ -101,6 +101,17 @@ 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 @@ 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); } } Index: sys/boot/i386/libi386/biosacpi.c =================================================================== --- sys/boot/i386/libi386/biosacpi.c +++ sys/boot/i386/libi386/biosacpi.c @@ -60,25 +60,40 @@ 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); } } Index: sys/x86/acpica/OsdEnvironment.c =================================================================== --- sys/x86/acpica/OsdEnvironment.c +++ sys/x86/acpica/OsdEnvironment.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -59,6 +60,16 @@ { 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);