From nobody Fri Mar 31 12:59:33 2023 X-Original-To: virtualization@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Pp0kg20q8z42T2V for ; Fri, 31 Mar 2023 13:00:11 +0000 (UTC) (envelope-from marietto2008@gmail.com) Received: from mail-yw1-x1133.google.com (mail-yw1-x1133.google.com [IPv6:2607:f8b0:4864:20::1133]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1D4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Pp0kg060zz3vZq; Fri, 31 Mar 2023 13:00:11 +0000 (UTC) (envelope-from marietto2008@gmail.com) Authentication-Results: mx1.freebsd.org; none Received: by mail-yw1-x1133.google.com with SMTP id 00721157ae682-53d277c1834so413076067b3.10; Fri, 31 Mar 2023 06:00:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680267610; x=1682859610; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=tPrw9n8qgh7rJuURM0S1iopAJZvqRhM5JnBLiPszCN0=; b=dPHW5eri5DIf4vCZpApHgLVhTOaJ5sOxIfDdFDSXqmQ1pHMJqv+Ge6WBp5Dkte6z4r J9pqsxzIsxzRE5FB4zJ47W2qukQX2faqwBSO/5b+QbD3zkLoBzcY1BaOkuU/Gx0emsMe YUX12q7io6v6M9mYC+3VyO3r9g7r3OzHnkRkSR8tl2oCzdj3zE9KUZZfRGqDPjk67GxJ JvsYTWGdKCF9U0lm+KyWk3qI90Faydx0EhMu/MsOKb6kNer3/UUTTD6GhvygISJW6q3y PCv6DmUnWLBO11x88cp3nfJHX8F5GUm9VB9A38xeot+JZXyu7Z3y1qWpPF4aUuKg6Ngt sDYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680267610; x=1682859610; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=tPrw9n8qgh7rJuURM0S1iopAJZvqRhM5JnBLiPszCN0=; b=Vqq03A3vn9GShlWHVl0zD28rBjtd5hFo+Nrxk2TUqGMf0kztoMAEfR5sUcRbg1OelL HdWnCH5JJSWcauWNiaOqupUm04hAyrvtGjrm31+TtTCFHwbrqJk1enmY8nkA38w4FaxN m0lyKZUa2ciyd3sJQwQrDXbcbdpoSDDSkgjoSY8o+SE2XrS26a0Qx1dagzs4r//J2mZv KKNrBoCyaFUWtgrA1SPMc2HVEldQBjySJKYDKOZ+WEVADpMRbgRmgByc2MrE6NNM2pI0 +H/T35yGZHrJy2wYnGcDaYg/1bASTjfuYZ74uATJ+2W2somId3X43MxRCgkuIcoDcNzr Sa7g== X-Gm-Message-State: AAQBX9fEC0reRBkyGv1M5zdmAtCrUTiLl+iREsemVz9JXdZQ5qJ9ejtC nXkK8QcLp9fGB5kLwJWkF88XRAsGSN1qqG3lnIuMhWxO4UU= X-Google-Smtp-Source: AKy350bk8jNCQxThQsthBVegbZ3KgqKlMCwZY5E7QG22Tumcwv6V+DKzqJyKcNvl9bbrZrpYETBsfePKWUtceweDxK8= X-Received: by 2002:a81:b721:0:b0:545:3f42:2d97 with SMTP id v33-20020a81b721000000b005453f422d97mr12594095ywh.3.1680267609695; Fri, 31 Mar 2023 06:00:09 -0700 (PDT) List-Id: Discussion List-Archive: https://lists.freebsd.org/archives/freebsd-virtualization List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-virtualization@freebsd.org X-BeenThere: freebsd-virtualization@freebsd.org MIME-Version: 1.0 References: <20230331123936.540020-1-corvink@FreeBSD.org> In-Reply-To: <20230331123936.540020-1-corvink@FreeBSD.org> From: Mario Marietto Date: Fri, 31 Mar 2023 14:59:33 +0200 Message-ID: Subject: Re: [PATCH] OvmfPkg/BhyveBhf: install bhyve's ACPI tables To: =?UTF-8?Q?Corvin_K=C3=B6hne?= Cc: virtualization@freebsd.org Content-Type: multipart/alternative; boundary="00000000000000eace05f831cab3" X-Rspamd-Queue-Id: 4Pp0kg060zz3vZq X-Spamd-Bar: ---- X-Spamd-Result: default: False [-4.00 / 15.00]; REPLY(-4.00)[]; ASN(0.00)[asn:15169, ipnet:2607:f8b0::/32, country:US] X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-ThisMailContainsUnwantedMimeParts: N --00000000000000eace05f831cab3 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hello Corvin. I will try your patch very soon if you want to write carefully all the commands that I should issue. Thanks. On Fri, Mar 31, 2023 at 2:40=E2=80=AFPM Corvin K=C3=B6hne wrote: > Hi, > > I would like to send the following patch to the EDKII project. > Therefore, I'd like to get some feedback from the bhyve community before > sending them to EDKII. > > At the moment, UEFI guests are using static ACPI tables. Modifying them > is not easy because we need to patch them in the EDKII repo. > Additionally, ACPI tables should be configuration dependent. If one > assigns a TPM device to one guest, this guest requires different ACPI > tables than other guests. > > Bhyve already builds it own set of ACPI tables. This patch picks them up > an installs them in the UEFI guest. This will overcome the mentioned > limitations. > > Note that this patch is required to easily implement features like > qemu's fwcfg or a tpm device emulation. > > Here's the patch: > > It's much easier to create configuration dependend ACPI tables for bhyve > than for OVMF. For this reason, don't use the statically created ACPI > tables provided by OVMF. Instead prefer the dynamically created ACPI > tables of bhyve. If bhyve provides no ACPI tables or we are unable to > detect those, fall back to OVMF tables. > > Implementation is similar to OvmfPkg/XenAcpiPlatformDxe/Xen.c. > --- > MdePkg/Include/Uefi/UefiBaseType.h | 2 + > OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c | 15 ++ > OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h | 6 + > OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c | 266 +++++++++++++++++++ > 4 files changed, 289 insertions(+) > > diff --git a/MdePkg/Include/Uefi/UefiBaseType.h > b/MdePkg/Include/Uefi/UefiBaseType.h > index 83975a08eb..b18a0760ee 100644 > --- a/MdePkg/Include/Uefi/UefiBaseType.h > +++ b/MdePkg/Include/Uefi/UefiBaseType.h > @@ -54,6 +54,8 @@ typedef UINT64 EFI_PHYSICAL_ADDRESS; > /// > typedef UINT64 EFI_VIRTUAL_ADDRESS; > > +#define NUMERIC_VALUE_AS_POINTER(Type, Value) ((Type *) ((UINTN)(Value)= )) > + > /// > /// EFI Time Abstraction: > /// Year: 1900 - 9999 > diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c > b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c > index 999e9f151e..34d9fc80d0 100644 > --- a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c > +++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c > @@ -243,6 +243,21 @@ InstallAcpiTables ( > { > EFI_STATUS Status; > > + Status =3D InstallBhyveTables (AcpiTable); > + if (!EFI_ERROR (Status)) { > + return EFI_SUCCESS; > + } > + > + if (Status !=3D EFI_NOT_FOUND) { > + DEBUG (( > + DEBUG_INFO, > + "%a: unable to install bhyve's ACPI tables (%r)\n", > + __FUNCTION__, > + Status > + )); > + return Status; > + } > + > Status =3D InstallOvmfFvTables (AcpiTable); > > return Status; > diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h > b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h > index 54d1af073e..b2724135d0 100644 > --- a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h > +++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h > @@ -46,6 +46,12 @@ BhyveInstallAcpiTable ( > OUT UINTN *TableKey > ); > > +EFI_STATUS > +EFIAPI > +InstallBhyveTables ( > + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol > + ); > + > EFI_STATUS > EFIAPI > InstallXenTables ( > diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c > b/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c > index e216a21bfa..5e1b759c01 100644 > --- a/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c > +++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c > @@ -13,6 +13,18 @@ > #include > #include // QemuFwCfgFindFile() > > +#define BHYVE_ACPI_PHYSICAL_ADDRESS ((UINTN)0x000F2400) > +#define BHYVE_BIOS_PHYSICAL_END ((UINTN)0x00100000) > + > +#pragma pack (1) > + > +typedef struct { > + EFI_ACPI_DESCRIPTION_HEADER Header; > + UINT64 Tables[0]; > +} EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE; > + > +#pragma pack () > + > STATIC > EFI_STATUS > EFIAPI > @@ -164,3 +176,257 @@ BhyveInstallAcpiTable ( > TableKey > ); > } > + > +/** > + Get the address of bhyve's ACPI Root System Description Pointer (RSDP)= . > + > + @param RsdpPtr Return pointer to RSDP. > + > + @return EFI_SUCCESS Bhyve's RSDP successfully found. > + @return EFI_NOT_FOUND Couldn't find bhyve's RSDP. > + @return EFI_UNSUPPORTED Revision is lower than 2. > + @return EFI_PROTOCOL_ERROR Invalid RSDP found. > + > +**/ > +EFI_STATUS > +EFIAPI > +BhyveGetAcpiRsdp ( > + OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr > + ) > +{ > + UINTN RsdpAddress; > + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; > + > + if (RsdpPtr =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Detect the RSDP > + // > + for (RsdpAddress =3D BHYVE_ACPI_PHYSICAL_ADDRESS; > + RsdpAddress < BHYVE_BIOS_PHYSICAL_END; > + RsdpAddress +=3D 0x10) > + { > + Rsdp =3D NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER, > + RsdpAddress > + ); > + if (Rsdp->Signature !=3D > EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) { > + continue; > + } > + > + if (Rsdp->Revision < 2) { > + DEBUG ((DEBUG_INFO, "%a: unsupported RSDP found\n", __FUNCTION__))= ; > + return EFI_UNSUPPORTED; > + } > + > + // > + // For ACPI 1.0/2.0/3.0 the checksum of first 20 bytes should be 0. > + // For ACPI 2.0/3.0 the checksum of the entire table should be 0. > + // > + UINT8 Sum =3D CalculateCheckSum8 ( > + (CONST UINT8 *)Rsdp, > + sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) > + ); > + if (Sum !=3D 0) { > + DEBUG (( > + DEBUG_INFO, > + "%a: RSDP header checksum not valid: 0x%02x\n", > + __FUNCTION__, > + Sum > + )); > + return EFI_PROTOCOL_ERROR; > + } > + > + Sum =3D CalculateCheckSum8 ( > + (CONST UINT8 *)Rsdp, > + sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER) > + ); > + if (Sum !=3D 0) { > + DEBUG (( > + DEBUG_INFO, > + "%a: RSDP table checksum not valid: 0x%02x\n", > + __FUNCTION__, > + Sum > + )); > + return EFI_PROTOCOL_ERROR; > + } > + > + // > + // RSDP was found and is valid > + // > + *RsdpPtr =3D Rsdp; > + > + return EFI_SUCCESS; > + } > + > + DEBUG ((DEBUG_INFO, "%a: RSDP not found\n", __FUNCTION__)); > + return EFI_NOT_FOUND; > +} > + > +/** > + Get bhyve's ACPI tables from the RSDP. And install bhyve's ACPI tables > + into the RSDT/XSDT using InstallAcpiTable. > + > + @param AcpiProtocol Protocol instance pointer. > + > + @return EFI_SUCCESS All tables were successfully inserted. > + @return EFI_UNSUPPORTED Bhyve's ACPI tables doesn't include a XSDT= . > + @return EFI_PROTOCOL_ERROR Invalid XSDT found. > + > + @return Error codes propagated from underlying > functions. > +**/ > +EFI_STATUS > +EFIAPI > +InstallBhyveTables ( > + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol > + ) > +{ > + EFI_STATUS Status; > + UINTN TableHandle; > + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; > + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs; > + EFI_ACPI_DESCRIPTION_HEADER *Dsdt; > + > + Rsdp =3D NULL; > + Facs =3D NULL; > + Dsdt =3D NULL; > + > + // > + // Try to find bhyve ACPI tables > + // > + Status =3D BhyveGetAcpiRsdp (&Rsdp); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_INFO, "%a: can't get RSDP (%r)\n", __FUNCTION__, > Status)); > + return Status; > + } > + > + // > + // Bhyve should always provide a XSDT > + // > + EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE *CONST Xsdt =3D > + NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE, > + Rsdp->XsdtAddress > + ); > + > + if (Xsdt =3D=3D NULL) { > + DEBUG ((DEBUG_INFO, "%a: XSDT not found\n", __FUNCTION__)); > + return EFI_UNSUPPORTED; > + } > + > + if (Xsdt->Header.Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) { > + DEBUG ((DEBUG_INFO, "%a: invalid XSDT length\n", __FUNCTION__)); > + return EFI_PROTOCOL_ERROR; > + } > + > + // > + // Install ACPI tables > + // > + CONST UINTN NumberOfTableEntries =3D > + (Xsdt->Header.Length - sizeof (Xsdt->Header)) / sizeof (UINT64); > + > + for (UINTN Index =3D 0; Index < NumberOfTableEntries; Index++) { > + EFI_ACPI_DESCRIPTION_HEADER *CONST CurrentTable =3D > + NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_DESCRIPTION_HEADER, > + Xsdt->Tables[Index] > + ); > + Status =3D AcpiProtocol->InstallAcpiTable ( > + AcpiProtocol, > + CurrentTable, > + CurrentTable->Length, > + &TableHandle > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_INFO, > + "%a: failed to install ACPI table %c%c%c%c (%r)\n", > + __FUNCTION__, > + NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[0], > + NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[1], > + NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[2], > + NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[3], > + Status > + )); > + return Status; > + } > + > + if (CurrentTable->Signature =3D=3D > EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) { > + EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *CONST Fadt =3D > + (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *CONST)CurrentTable; > + if (Fadt->XFirmwareCtrl) { > + Facs =3D NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE, > + Fadt->XFirmwareCtrl > + ); > + } else { > + Facs =3D NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE, > + Fadt->FirmwareCtrl > + ); > + } > + > + if (Fadt->XDsdt) { > + Dsdt =3D NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_DESCRIPTION_HEADER, > + Fadt->XDsdt > + ); > + } else { > + Dsdt =3D NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_DESCRIPTION_HEADER, > + Fadt->Dsdt > + ); > + } > + } > + } > + > + // > + // Install FACS > + // > + if (Facs !=3D NULL) { > + Status =3D AcpiProtocol->InstallAcpiTable ( > + AcpiProtocol, > + Facs, > + Facs->Length, > + &TableHandle > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_INFO, > + "%a: failed to install FACS (%r)\n", > + __FUNCTION__, > + Status > + )); > + return Status; > + } > + } > + > + // > + // Install DSDT > + // If it's not found, something bad happened. Don't continue execution= . > + // > + if (Dsdt =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "%a: failed to find DSDT\n", __FUNCTION__)); > + CpuDeadLoop (); > + } > + > + Status =3D AcpiProtocol->InstallAcpiTable ( > + AcpiProtocol, > + Dsdt, > + Dsdt->Length, > + &TableHandle > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_INFO, > + "%a: failed to install DSDT (%r)\n", > + __FUNCTION__, > + Status > + )); > + return Status; > + } > + > + return EFI_SUCCESS; > +} > -- > 2.40.0 > > > --=20 Mario. --00000000000000eace05f831cab3 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello Corvin.

I will try you= r patch very soon if you=C2=A0 want to write carefully all the commands tha= t I should issue. Thanks.

On Fri, Mar 31, 2023 at 2:40=E2=80=AFPM Corv= in K=C3=B6hne <corvink@freebsd.or= g> wrote:
Hi,

I would like to send the following patch to the EDKII project.
Therefore, I'd like to get some feedback from the bhyve community befor= e
sending them to EDKII.

At the moment, UEFI guests are using static ACPI tables. Modifying them
is not easy because we need to patch them in the EDKII repo.
Additionally, ACPI tables should be configuration dependent. If one
assigns a TPM device to one guest, this guest requires different ACPI
tables than other guests.

Bhyve already builds it own set of ACPI tables. This patch picks them up an installs them in the UEFI guest. This will overcome the mentioned
limitations.

Note that this patch is required to easily implement features like
qemu's fwcfg or a tpm device emulation.

Here's the patch:

It's much easier to create configuration dependend ACPI tables for bhyv= e
than for OVMF. For this reason, don't use the statically created ACPI tables provided by OVMF. Instead prefer the dynamically created ACPI
tables of bhyve. If bhyve provides no ACPI tables or we are unable to
detect those, fall back to OVMF tables.

Implementation is similar to OvmfPkg/XenAcpiPlatformDxe/Xen.c.
---
=C2=A0MdePkg/Include/Uefi/UefiBaseType.h=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0|=C2=A0 =C2=A02 +
=C2=A0OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c |=C2=A0 15 ++
=C2=A0OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h |=C2=A0 =C2=A06 +
=C2=A0OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c=C2=A0 =C2=A0 =C2=A0 =C2=A0 | 26= 6 +++++++++++++++++++
=C2=A04 files changed, 289 insertions(+)

diff --git a/MdePkg/Include/Uefi/UefiBaseType.h b/MdePkg/Include/Uefi/UefiB= aseType.h
index 83975a08eb..b18a0760ee 100644
--- a/MdePkg/Include/Uefi/UefiBaseType.h
+++ b/MdePkg/Include/Uefi/UefiBaseType.h
@@ -54,6 +54,8 @@ typedef UINT64 EFI_PHYSICAL_ADDRESS;
=C2=A0///
=C2=A0typedef UINT64 EFI_VIRTUAL_ADDRESS;

+#define NUMERIC_VALUE_AS_POINTER(Type, Value)=C2=A0 ((Type *) ((UINTN)(Val= ue)))
+
=C2=A0///
=C2=A0/// EFI Time Abstraction:
=C2=A0///=C2=A0 Year:=C2=A0 =C2=A0 =C2=A0 =C2=A01900 - 9999
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c b/OvmfPkg/Bhyve/A= cpiPlatformDxe/AcpiPlatform.c
index 999e9f151e..34d9fc80d0 100644
--- a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c
+++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c
@@ -243,6 +243,21 @@ InstallAcpiTables (
=C2=A0{
=C2=A0 =C2=A0EFI_STATUS=C2=A0 Status;

+=C2=A0 Status =3D InstallBhyveTables (AcpiTable);
+=C2=A0 if (!EFI_ERROR (Status)) {
+=C2=A0 =C2=A0 return EFI_SUCCESS;
+=C2=A0 }
+
+=C2=A0 if (Status !=3D EFI_NOT_FOUND) {
+=C2=A0 =C2=A0 DEBUG ((
+=C2=A0 =C2=A0 =C2=A0 DEBUG_INFO,
+=C2=A0 =C2=A0 =C2=A0 "%a: unable to install bhyve's ACPI tables (= %r)\n",
+=C2=A0 =C2=A0 =C2=A0 __FUNCTION__,
+=C2=A0 =C2=A0 =C2=A0 Status
+=C2=A0 =C2=A0 =C2=A0 ));
+=C2=A0 =C2=A0 return Status;
+=C2=A0 }
+
=C2=A0 =C2=A0Status =3D InstallOvmfFvTables (AcpiTable);

=C2=A0 =C2=A0return Status;
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h b/OvmfPkg/Bhyve/A= cpiPlatformDxe/AcpiPlatform.h
index 54d1af073e..b2724135d0 100644
--- a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h
+++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h
@@ -46,6 +46,12 @@ BhyveInstallAcpiTable (
=C2=A0 =C2=A0OUT=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 *TableKey
=C2=A0 =C2=A0);

+EFI_STATUS
+EFIAPI
+InstallBhyveTables (
+=C2=A0 IN=C2=A0 =C2=A0EFI_ACPI_TABLE_PROTOCOL=C2=A0 *AcpiProtocol
+=C2=A0 );
+
=C2=A0EFI_STATUS
=C2=A0EFIAPI
=C2=A0InstallXenTables (
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c b/OvmfPkg/Bhyve/AcpiPlat= formDxe/Bhyve.c
index e216a21bfa..5e1b759c01 100644
--- a/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c
+++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c
@@ -13,6 +13,18 @@
=C2=A0#include <Library/MemoryAllocationLib.h>
=C2=A0#include <Library/QemuFwCfgLib.h>=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0// QemuFwCfgFindFile()

+#define BHYVE_ACPI_PHYSICAL_ADDRESS=C2=A0 ((UINTN)0x000F2400)
+#define BHYVE_BIOS_PHYSICAL_END=C2=A0 =C2=A0 =C2=A0 ((UINTN)0x00100000) +
+#pragma pack (1)
+
+typedef struct {
+=C2=A0 EFI_ACPI_DESCRIPTION_HEADER=C2=A0 =C2=A0 Header;
+=C2=A0 UINT64=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Tables[0];
+} EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE;
+
+#pragma pack ()
+
=C2=A0STATIC
=C2=A0EFI_STATUS
=C2=A0EFIAPI
@@ -164,3 +176,257 @@ BhyveInstallAcpiTable (
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 TableKey
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 );
=C2=A0}
+
+/**
+=C2=A0 Get the address of bhyve's ACPI Root System Description Pointer= (RSDP).
+
+=C2=A0 @param=C2=A0 RsdpPtr=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0Return pointer to RSDP.
+
+=C2=A0 @return EFI_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Bhyve's RS= DP successfully found.
+=C2=A0 @return EFI_NOT_FOUND=C2=A0 =C2=A0 =C2=A0 =C2=A0Couldn't find b= hyve's RSDP.
+=C2=A0 @return EFI_UNSUPPORTED=C2=A0 =C2=A0 =C2=A0Revision is lower than 2= .
+=C2=A0 @return EFI_PROTOCOL_ERROR=C2=A0 Invalid RSDP found.
+
+**/
+EFI_STATUS
+EFIAPI
+BhyveGetAcpiRsdp (
+=C2=A0 OUT=C2=A0 =C2=A0EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER=C2=A0 = **RsdpPtr
+=C2=A0 )
+{
+=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0RsdpAddress;
+=C2=A0 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER=C2=A0 *Rsdp;
+
+=C2=A0 if (RsdpPtr =3D=3D NULL) {
+=C2=A0 =C2=A0 return EFI_INVALID_PARAMETER;
+=C2=A0 }
+
+=C2=A0 //
+=C2=A0 // Detect the RSDP
+=C2=A0 //
+=C2=A0 for (RsdpAddress =3D BHYVE_ACPI_PHYSICAL_ADDRESS;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0RsdpAddress < BHYVE_BIOS_PHYSICAL_END;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0RsdpAddress +=3D 0x10)
+=C2=A0 {
+=C2=A0 =C2=A0 Rsdp =3D NUMERIC_VALUE_AS_POINTER (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_ACPI_2_0_ROOT_SYSTEM_D= ESCRIPTION_POINTER,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RsdpAddress
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0);
+=C2=A0 =C2=A0 if (Rsdp->Signature !=3D EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIP= TION_POINTER_SIGNATURE) {
+=C2=A0 =C2=A0 =C2=A0 continue;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 if (Rsdp->Revision < 2) {
+=C2=A0 =C2=A0 =C2=A0 DEBUG ((DEBUG_INFO, "%a: unsupported RSDP found\= n", __FUNCTION__));
+=C2=A0 =C2=A0 =C2=A0 return EFI_UNSUPPORTED;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 //
+=C2=A0 =C2=A0 // For ACPI 1.0/2.0/3.0 the checksum of first 20 bytes shoul= d be 0.
+=C2=A0 =C2=A0 // For ACPI 2.0/3.0 the checksum of the entire table should = be 0.
+=C2=A0 =C2=A0 //
+=C2=A0 =C2=A0 UINT8=C2=A0 Sum =3D CalculateCheckSum8 (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(CONS= T UINT8 *)Rsdp,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeo= f (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0); +=C2=A0 =C2=A0 if (Sum !=3D 0) {
+=C2=A0 =C2=A0 =C2=A0 DEBUG ((
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DEBUG_INFO,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 "%a: RSDP header checksum not valid: 0x%0= 2x\n",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 __FUNCTION__,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 Sum
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ));
+=C2=A0 =C2=A0 =C2=A0 return EFI_PROTOCOL_ERROR;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 Sum =3D CalculateCheckSum8 (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (CONST UINT8 *)Rsdp,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM= _DESCRIPTION_POINTER)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 );
+=C2=A0 =C2=A0 if (Sum !=3D 0) {
+=C2=A0 =C2=A0 =C2=A0 DEBUG ((
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DEBUG_INFO,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 "%a: RSDP table checksum not valid: 0x%02= x\n",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 __FUNCTION__,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 Sum
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ));
+=C2=A0 =C2=A0 =C2=A0 return EFI_PROTOCOL_ERROR;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 //
+=C2=A0 =C2=A0 // RSDP was found and is valid
+=C2=A0 =C2=A0 //
+=C2=A0 =C2=A0 *RsdpPtr =3D Rsdp;
+
+=C2=A0 =C2=A0 return EFI_SUCCESS;
+=C2=A0 }
+
+=C2=A0 DEBUG ((DEBUG_INFO, "%a: RSDP not found\n", __FUNCTION__)= );
+=C2=A0 return EFI_NOT_FOUND;
+}
+
+/**
+=C2=A0 Get bhyve's ACPI tables from the RSDP. And install bhyve's = ACPI tables
+=C2=A0 into the RSDT/XSDT using InstallAcpiTable.
+
+=C2=A0 @param=C2=A0 AcpiProtocol=C2=A0 =C2=A0 =C2=A0 =C2=A0 Protocol insta= nce pointer.
+
+=C2=A0 @return EFI_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0All tables wer= e successfully inserted.
+=C2=A0 @return EFI_UNSUPPORTED=C2=A0 =C2=A0 =C2=A0Bhyve's ACPI tables = doesn't include a XSDT.
+=C2=A0 @return EFI_PROTOCOL_ERROR=C2=A0 Invalid XSDT found.
+
+=C2=A0 @return=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0Error codes propagated from underlying functions.
+**/
+EFI_STATUS
+EFIAPI
+InstallBhyveTables (
+=C2=A0 IN=C2=A0 =C2=A0EFI_ACPI_TABLE_PROTOCOL=C2=A0 *AcpiProtocol
+=C2=A0 )
+{
+=C2=A0 EFI_STATUS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Statu= s;
+=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0TableHandle;
+=C2=A0 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER=C2=A0 *Rsdp;
+=C2=A0 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE=C2=A0 *Facs;
+=C2=A0 EFI_ACPI_DESCRIPTION_HEADER=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*Dsdt;
+
+=C2=A0 Rsdp =3D NULL;
+=C2=A0 Facs =3D NULL;
+=C2=A0 Dsdt =3D NULL;
+
+=C2=A0 //
+=C2=A0 // Try to find bhyve ACPI tables
+=C2=A0 //
+=C2=A0 Status =3D BhyveGetAcpiRsdp (&Rsdp);
+=C2=A0 if (EFI_ERROR (Status)) {
+=C2=A0 =C2=A0 DEBUG ((DEBUG_INFO, "%a: can't get RSDP (%r)\n"= ;, __FUNCTION__, Status));
+=C2=A0 =C2=A0 return Status;
+=C2=A0 }
+
+=C2=A0 //
+=C2=A0 // Bhyve should always provide a XSDT
+=C2=A0 //
+=C2=A0 EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE *CONST=C2=A0 Xsdt = =3D
+=C2=A0 =C2=A0 NUMERIC_VALUE_AS_POINTER (
+=C2=A0 =C2=A0 =C2=A0 EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE,
+=C2=A0 =C2=A0 =C2=A0 Rsdp->XsdtAddress
+=C2=A0 =C2=A0 =C2=A0 );
+
+=C2=A0 if (Xsdt =3D=3D NULL) {
+=C2=A0 =C2=A0 DEBUG ((DEBUG_INFO, "%a: XSDT not found\n", __FUNC= TION__));
+=C2=A0 =C2=A0 return EFI_UNSUPPORTED;
+=C2=A0 }
+
+=C2=A0 if (Xsdt->Header.Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER= )) {
+=C2=A0 =C2=A0 DEBUG ((DEBUG_INFO, "%a: invalid XSDT length\n", _= _FUNCTION__));
+=C2=A0 =C2=A0 return EFI_PROTOCOL_ERROR;
+=C2=A0 }
+
+=C2=A0 //
+=C2=A0 // Install ACPI tables
+=C2=A0 //
+=C2=A0 CONST UINTN=C2=A0 NumberOfTableEntries =3D
+=C2=A0 =C2=A0 (Xsdt->Header.Length - sizeof (Xsdt->Header)) / sizeof= (UINT64);
+
+=C2=A0 for (UINTN Index =3D 0; Index < NumberOfTableEntries; Index++) {=
+=C2=A0 =C2=A0 EFI_ACPI_DESCRIPTION_HEADER *CONST=C2=A0 CurrentTable =3D +=C2=A0 =C2=A0 =C2=A0 NUMERIC_VALUE_AS_POINTER (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 EFI_ACPI_DESCRIPTION_HEADER,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 Xsdt->Tables[Index]
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 );
+=C2=A0 =C2=A0 Status =3D AcpiProtocol->InstallAcpiTable (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0AcpiProtocol,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0CurrentTable,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0CurrentTable->Length,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&TableHandle
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0);
+=C2=A0 =C2=A0 if (EFI_ERROR (Status)) {
+=C2=A0 =C2=A0 =C2=A0 DEBUG ((
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DEBUG_INFO,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 "%a: failed to install ACPI table %c%c%c%= c (%r)\n",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 __FUNCTION__,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable-= >Signature)[0],
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable-= >Signature)[1],
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable-= >Signature)[2],
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable-= >Signature)[3],
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 Status
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ));
+=C2=A0 =C2=A0 =C2=A0 return Status;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 if (CurrentTable->Signature =3D=3D EFI_ACPI_2_0_FIXED_ACP= I_DESCRIPTION_TABLE_SIGNATURE) {
+=C2=A0 =C2=A0 =C2=A0 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *CONST=C2= =A0 Fadt =3D
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *CO= NST)CurrentTable;
+=C2=A0 =C2=A0 =C2=A0 if (Fadt->XFirmwareCtrl) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 Facs =3D NUMERIC_VALUE_AS_POINTER (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_ACPI_2_0= _FIRMWARE_ACPI_CONTROL_STRUCTURE,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Fadt->XFi= rmwareCtrl
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0);
+=C2=A0 =C2=A0 =C2=A0 } else {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 Facs =3D NUMERIC_VALUE_AS_POINTER (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_ACPI_2_0= _FIRMWARE_ACPI_CONTROL_STRUCTURE,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Fadt->Fir= mwareCtrl
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0);
+=C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 if (Fadt->XDsdt) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 Dsdt =3D NUMERIC_VALUE_AS_POINTER (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_ACPI_DES= CRIPTION_HEADER,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Fadt->XDs= dt
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0);
+=C2=A0 =C2=A0 =C2=A0 } else {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 Dsdt =3D NUMERIC_VALUE_AS_POINTER (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_ACPI_DES= CRIPTION_HEADER,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Fadt->Dsd= t
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0);
+=C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 }
+=C2=A0 }
+
+=C2=A0 //
+=C2=A0 // Install FACS
+=C2=A0 //
+=C2=A0 if (Facs !=3D NULL) {
+=C2=A0 =C2=A0 Status =3D AcpiProtocol->InstallAcpiTable (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0AcpiProtocol,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Facs,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Facs->Length,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&TableHandle
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0);
+=C2=A0 =C2=A0 if (EFI_ERROR (Status)) {
+=C2=A0 =C2=A0 =C2=A0 DEBUG ((
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DEBUG_INFO,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 "%a: failed to install FACS (%r)\n",=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 __FUNCTION__,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 Status
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ));
+=C2=A0 =C2=A0 =C2=A0 return Status;
+=C2=A0 =C2=A0 }
+=C2=A0 }
+
+=C2=A0 //
+=C2=A0 // Install DSDT
+=C2=A0 // If it's not found, something bad happened. Don't continu= e execution.
+=C2=A0 //
+=C2=A0 if (Dsdt =3D=3D NULL) {
+=C2=A0 =C2=A0 DEBUG ((DEBUG_ERROR, "%a: failed to find DSDT\n", = __FUNCTION__));
+=C2=A0 =C2=A0 CpuDeadLoop ();
+=C2=A0 }
+
+=C2=A0 Status =3D AcpiProtocol->InstallAcpiTable (
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0AcpiProtocol,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0Dsdt,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0Dsdt->Length,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0&TableHandle
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0);
+=C2=A0 if (EFI_ERROR (Status)) {
+=C2=A0 =C2=A0 DEBUG ((
+=C2=A0 =C2=A0 =C2=A0 DEBUG_INFO,
+=C2=A0 =C2=A0 =C2=A0 "%a: failed to install DSDT (%r)\n",
+=C2=A0 =C2=A0 =C2=A0 __FUNCTION__,
+=C2=A0 =C2=A0 =C2=A0 Status
+=C2=A0 =C2=A0 =C2=A0 ));
+=C2=A0 =C2=A0 return Status;
+=C2=A0 }
+
+=C2=A0 return EFI_SUCCESS;
+}
--
2.40.0




--
Mario.
--00000000000000eace05f831cab3--