From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from wout5-smtp.messagingengine.com (wout5-smtp.messagingengine.com [64.147.123.21]) by mx.groups.io with SMTP id smtpd.web11.9964.1683081158801065866 for ; Tue, 02 May 2023 19:32:38 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@bsdio.com header.s=fm1 header.b=ruEuuwUu; spf=pass (domain: bsdio.com, ip: 64.147.123.21, mailfrom: rebecca@bsdio.com) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 7C7693200AA2; Tue, 2 May 2023 22:32:37 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Tue, 02 May 2023 22:32:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bsdio.com; h=cc :cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to; s=fm1; t= 1683081157; x=1683167557; bh=YDLkKnCNCCCYMCgBTSHqjWmFzJCZDUhnzc2 /qluYNoQ=; b=ruEuuwUuoh3fqyYTxVMwwBSPv65Q5+OXNkeWmS5cBQNJKg+knYE 59yzc7p2nhL/TmeGK7MnNDH8yRn6clwNI1S9hCzLQaWd3Mx8nU3ddIzNSXdp+7vm Pab3ac8AUFK3XyNFc116mZ+Q1ZZGt17n6t9XOTRkq+JzqEXmob8kifEmUtkQuqRV IeATTays9IBgN6un/DiqboYelPCvhIYejJ265z1rwI+x+nbxEXIURs+PYoMYngRE elqocxZ7HVSphmtdCLmGzkIiw2WvMn9bKJB3CmcNitb89v8ynn6fg+bWn5V3cYov iwtwOh9G4/ZPYsLqf4jFueH9/1k1IN4Kkeg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t= 1683081157; x=1683167557; bh=YDLkKnCNCCCYMCgBTSHqjWmFzJCZDUhnzc2 /qluYNoQ=; b=PgLjf4/DpFo7tRx0bdQrwd51H43fPZpJPYm8bPXhjeXvz3s1q/Y P5WITaWplh/xTokbrf9JtCKgd6PafRwYtPZI3PCsn/sH16mhUnmJ5tdGtXlJp+kD YfDYv2wpEt1dbsWPD8pkn4THL5LmUCxhoXA8FdIEFfkH36VgaK+gkuiOAjct8yRb bpb052TsBcWf2krdm8FMjTMVCEJ1LmSGyxzg1mcc5PxQhTSGe+4bPMVF5sNRyZNe PlCrqhSMdhetEQbOo9Rk3jzab32vMT24wo1dii2sSMMlZq6bCpFEp5dN1up5Oxah AluuguUdJcZhSKqZX/yC+jiC+waxEwIRHkw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrfedvjedgheekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepkfffgggfuffvvehfhfgjtgfgsehtkeertddtfeejnecuhfhrohhmpeftvggs vggttggrucevrhgrnhcuoehrvggsvggttggrsegsshguihhordgtohhmqeenucggtffrrg htthgvrhhnpeegfeegveduheejgfduffefhfehleehiefghfetvdejvdelhfeukefhhfdv geehveenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpe hrvggsvggttggrsegsshguihhordgtohhm X-ME-Proxy: Feedback-ID: i5b994698:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 2 May 2023 22:32:35 -0400 (EDT) Message-ID: Date: Tue, 2 May 2023 20:32:34 -0600 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.10.0 Subject: Re: [edk2-devel] [PATCH v2 1/1] OvmfPkg/BhyveBhf: install bhyve's ACPI tables To: devel@edk2.groups.io, corvink@FreeBSD.org Cc: Michael D Kinney , Liming Gao , Zhiguang Liu , Ard Biesheuvel , Jiewen Yao , Jordan Justen , Gerd Hoffmann , Peter Grehan References: <20230417121141.428598-1-corvink@FreeBSD.org> From: "Rebecca Cran" In-Reply-To: <20230417121141.428598-1-corvink@FreeBSD.org> Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Reviewed-by: Rebecca Cran On 4/17/23 06:11, Corvin Köhne wrote: > 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. > > Ideally, we use the qemu fwcfg interface to pass the ACPI tables from > bhyve to OVMF. bhyve will support this in the future. However, current > bhyve executables don't support passing ACPI tables by the qemu fwcfg > interface. They just copy the ACPI into main memory. For that reason, > pick up the ACPI tables from main memory. > > Implementation is similar to OvmfPkg/XenAcpiPlatformDxe/Xen.c. > > Signed-off-by: Corvin Köhne > Cc: Michael D Kinney > Cc: Liming Gao > Cc: Zhiguang Liu > Cc: Ard Biesheuvel > Cc: Jiewen Yao > Cc: Jordan Justen > Cc: Gerd Hoffmann > Cc: Rebecca Cran > Cc: Peter Grehan > --- > MdePkg/Include/Uefi/UefiBaseType.h | 2 + > OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h | 6 + > OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c | 17 ++ > OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c | 258 +++++++++++++++++++ > 4 files changed, 283 insertions(+) > > diff --git a/MdePkg/Include/Uefi/UefiBaseType.h b/MdePkg/Include/Uefi/UefiBaseType.h > index 83975a08eb4c..b18a0760ee61 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.h b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h > index 54d1af073eab..b2724135d09f 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/AcpiPlatform.c b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c > index 999e9f151ebb..6077d4d313a3 100644 > --- a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c > +++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c > @@ -243,6 +243,23 @@ InstallAcpiTables ( > { > EFI_STATUS Status; > > + Status = InstallBhyveTables (AcpiTable); > + if (!EFI_ERROR (Status)) { > + return EFI_SUCCESS; > + } > + > + if (Status != EFI_NOT_FOUND) { > + DEBUG ( > + ( > + DEBUG_WARN, > + "%a: unable to install bhyve's ACPI tables (%r)\n", > + __func__, > + Status > + ) > + ); > + return Status; > + } > + > Status = InstallOvmfFvTables (AcpiTable); > > return Status; > diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c b/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c > index e216a21bfaed..fa5e79bfe3b4 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,249 @@ BhyveInstallAcpiTable ( > TableKey > ); > } > + > +/** > + Get the address of bhyve's ACPI Root System Description Pointer (RSDP). > + > + @param RsdpPtr Return pointer to RSDP. > + > + @retval EFI_SUCCESS Bhyve's RSDP successfully found. > + @retval EFI_NOT_FOUND Couldn't find bhyve's RSDP. > + @retval EFI_UNSUPPORTED Revision is lower than 2. > + @retval 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; > + UINT8 Sum; > + > + if (RsdpPtr == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Detect the RSDP > + // > + for (RsdpAddress = BHYVE_ACPI_PHYSICAL_ADDRESS; > + RsdpAddress < BHYVE_BIOS_PHYSICAL_END; > + RsdpAddress += 0x10) > + { > + Rsdp = NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER, > + RsdpAddress > + ); > + if (Rsdp->Signature != EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) { > + continue; > + } > + > + if (Rsdp->Revision < 2) { > + DEBUG ((DEBUG_WARN, "%a: unsupported RSDP found\n", __func__)); > + 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. > + // > + Sum = CalculateCheckSum8 ( > + (CONST UINT8 *)Rsdp, > + sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) > + ); > + if (Sum != 0) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: RSDP header checksum not valid: 0x%02x\n", > + __func__, > + Sum > + )); > + return EFI_PROTOCOL_ERROR; > + } > + > + Sum = CalculateCheckSum8 ( > + (CONST UINT8 *)Rsdp, > + sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER) > + ); > + if (Sum != 0) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: RSDP table checksum not valid: 0x%02x\n", > + __func__, > + Sum > + )); > + return EFI_PROTOCOL_ERROR; > + } > + > + // > + // RSDP was found and is valid > + // > + *RsdpPtr = Rsdp; > + > + return EFI_SUCCESS; > + } > + > + DEBUG ((DEBUG_WARN, "%a: RSDP not found\n", __func__)); > + 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. > + > + @retval EFI_SUCCESS All tables were successfully inserted. > + @retval EFI_UNSUPPORTED Bhyve's ACPI tables doesn't include a XSDT. > + @retval EFI_PROTOCOL_ERROR Invalid XSDT found. > + > + @retval Error codes propagated from underlying functions. > +**/ > +EFI_STATUS > +EFIAPI > +InstallBhyveTables ( > + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol > + ) > +{ > + EFI_STATUS Status; > + UINTN TableHandle; > + UINTN NumberOfTableEntries; > + EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE *Xsdt; > + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; > + EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt; > + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs; > + EFI_ACPI_DESCRIPTION_HEADER *Dsdt; > + EFI_ACPI_DESCRIPTION_HEADER *CurrentTable; > + > + Rsdp = NULL; > + Facs = NULL; > + Dsdt = NULL; > + > + // > + // Try to find bhyve ACPI tables > + // > + Status = BhyveGetAcpiRsdp (&Rsdp); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_WARN, "%a: can't get RSDP (%r)\n", __func__, Status)); > + return Status; > + } > + > + // > + // Bhyve should always provide a XSDT > + // > + Xsdt = NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE, > + Rsdp->XsdtAddress > + ); > + > + if (Xsdt == NULL) { > + DEBUG ((DEBUG_WARN, "%a: XSDT not found\n", __func__)); > + return EFI_UNSUPPORTED; > + } > + > + if (Xsdt->Header.Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) { > + DEBUG ((DEBUG_ERROR, "%a: invalid XSDT length\n", __func__)); > + return EFI_PROTOCOL_ERROR; > + } > + > + // > + // Install ACPI tables > + // > + NumberOfTableEntries = (Xsdt->Header.Length - sizeof (Xsdt->Header)) / sizeof (UINT64); > + > + for (UINTN Index = 0; Index < NumberOfTableEntries; Index++) { > + CurrentTable = NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_DESCRIPTION_HEADER, > + Xsdt->Tables[Index] > + ); > + Status = AcpiProtocol->InstallAcpiTable ( > + AcpiProtocol, > + CurrentTable, > + CurrentTable->Length, > + &TableHandle > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: failed to install ACPI table %c%c%c%c (%r)\n", > + __func__, > + 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 == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) { > + Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *CONST)CurrentTable; > + if (Fadt->XFirmwareCtrl) { > + Facs = NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE, > + Fadt->XFirmwareCtrl > + ); > + } else { > + Facs = NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE, > + Fadt->FirmwareCtrl > + ); > + } > + > + if (Fadt->XDsdt) { > + Dsdt = NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_DESCRIPTION_HEADER, > + Fadt->XDsdt > + ); > + } else { > + Dsdt = NUMERIC_VALUE_AS_POINTER ( > + EFI_ACPI_DESCRIPTION_HEADER, > + Fadt->Dsdt > + ); > + } > + } > + } > + > + // > + // Install FACS > + // > + if (Facs != NULL) { > + Status = AcpiProtocol->InstallAcpiTable ( > + AcpiProtocol, > + Facs, > + Facs->Length, > + &TableHandle > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ( > + (DEBUG_ERROR, "%a: failed to install FACS (%r)\n", __func__, Status)); > + return Status; > + } > + } > + > + // > + // Install DSDT > + // If it's not found, something bad happened. Don't continue execution. > + // > + if (Dsdt == NULL) { > + DEBUG ((DEBUG_ERROR, "%a: failed to find DSDT\n", __func__)); > + CpuDeadLoop (); > + } > + > + Status = AcpiProtocol->InstallAcpiTable ( > + AcpiProtocol, > + Dsdt, > + Dsdt->Length, > + &TableHandle > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to install DSDT (%r)\n", __func__, Status)); > + return Status; > + } > + > + return EFI_SUCCESS; > +}