mirror of
https://github.com/opnsense/src.git
synced 2026-06-04 22:32:43 -04:00
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 0b01d45783)
This commit is contained in:
parent
56b90f8fc9
commit
05cf4dda59
3 changed files with 43 additions and 97 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue