From nobody Fri Mar 31 12:39:36 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 4Pp0HJ0TKDz42Rck for ; Fri, 31 Mar 2023 12:39:56 +0000 (UTC) (envelope-from corvink@FreeBSD.org) Received: from smtp.freebsd.org (smtp.freebsd.org [IPv6:2610:1c1:1:606c::24b:4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Pp0HH6nnRz3rQD; Fri, 31 Mar 2023 12:39:55 +0000 (UTC) (envelope-from corvink@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1680266396; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=oW+u3ZaA4hAXvsT0cz+xJenwrQKzKQdffQyv0zMGjgw=; b=m35WiPbF4WyPB6tQaf11nxotTHkqiwRYwAlmDY+4K7BIpkiZBfLQ5A7E7nSBY+ZamgdkfA 4UMpMMHzKAs/ocml5db5XAquRNHU+m6b6DRBZyuhlCN6Z2jOtcUpe2wsU1kgYWrDovNMXv CN8EbnDhMneZD3Qyfxzg4ja3iounuHSSwfLA4r1xqR7eIVQ//x4WoltOQ67NgE/fqcG4Ie 5y5A84MC/1sUPRhDccXmMdBYETMqEaEj4hJ/UIc2ycAWPreHrpu3NY6wuHrURNIrRnI0ug gbZqxmxWvjoS0RpoC78/vQBzT6v0vT8ousacMBB/i2SbGWlgNPBNbYEbDILZbQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1680266395; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=oW+u3ZaA4hAXvsT0cz+xJenwrQKzKQdffQyv0zMGjgw=; b=yplPFYC0Py0IextvEZudfUirzkeJBl4RPcxtpUVIs/PMZFpYdoNjzvrrFKKoImWPLXPDzZ 9KCn/6U5yIPks/ybqFqjkgZIIpCprVvMCQglm+Nj8ety8VXzcjoJoK9Nl5owvi06aWHQ6s QCTytcNiM8ZeontbKEV8iz8Z3NQ7pXUHVbn+vL5vRnS2GD4bxJb6c8xoliNK6fH4kmyrV8 pvWVJT1d4C2VI1mcA1tSQYmlB9T8FMZyF2aZh2rdtvsVOzPF3F+McYqmpC+IxD7Zb/amjL CdIXeu9KltbALTQ18jDrV0EKcn47doLKKvuSG2s45iZ50Jr6SPpAiH3AZfw5rg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1680266396; a=rsa-sha256; cv=none; b=H2T7PSoUDKwV61jHScHh9p5++q1B+Chypz4WotN1NySya1ulpBvaAISnVvzx44xXh7Gwya Y1thy23T6DFt6L2LYIygv1ExBcleeWsX76eqHkFPfhn6G6IGgllpZ5xA4XBGfLaqKjpq1W mWYCyQkMLdCYsotxX4kHjdkNtjLBO+ogPt2o+jpuIWpzE1hZRq2xyJqFwOwcg7i68AU7Yj B6YwoLq1STJt0VjcX/9iAJlAz6pB2mRO8RgMWsd1fEwhDYy5ECIjRqfLR5H6jKmFkN9kdP phOqstV06/n2In6pjo0p8yfDWHei6F/bA2TKDQbi52m7LJR1iwZayEMkRAWtSg== Received: from corvink-nb.beckhoff.com (unknown [IPv6:2001:9e8:da7c:e100:6c2:e97e:dcc:5135]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: corvink) by smtp.freebsd.org (Postfix) with ESMTPSA id 4Pp0HH30V0z12Y5; Fri, 31 Mar 2023 12:39:55 +0000 (UTC) (envelope-from corvink@FreeBSD.org) From: =?UTF-8?q?Corvin=20K=C3=B6hne?= To: virtualization@FreeBSD.org Cc: =?UTF-8?q?Corvin=20K=C3=B6hne?= Subject: [PATCH] OvmfPkg/BhyveBhf: install bhyve's ACPI tables Date: Fri, 31 Mar 2023 14:39:36 +0200 Message-Id: <20230331123936.540020-1-corvink@FreeBSD.org> X-Mailer: git-send-email 2.40.0 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 Content-Transfer-Encoding: quoted-printable X-ThisMailContainsUnwantedMimeParts: N 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/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; ///=0D typedef UINT64 EFI_VIRTUAL_ADDRESS;=0D =0D +#define NUMERIC_VALUE_AS_POINTER(Type, Value) ((Type *) ((UINTN)(Value)))= =0D +=0D ///=0D /// EFI Time Abstraction:=0D /// Year: 1900 - 9999=0D 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 ( {=0D EFI_STATUS Status;=0D =0D + Status =3D InstallBhyveTables (AcpiTable);=0D + if (!EFI_ERROR (Status)) {=0D + return EFI_SUCCESS;=0D + }=0D +=0D + if (Status !=3D EFI_NOT_FOUND) {=0D + DEBUG ((=0D + DEBUG_INFO,=0D + "%a: unable to install bhyve's ACPI tables (%r)\n",=0D + __FUNCTION__,=0D + Status=0D + ));=0D + return Status;=0D + }=0D +=0D Status =3D InstallOvmfFvTables (AcpiTable);=0D =0D return Status;=0D 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 ( OUT UINTN *TableKey=0D );=0D =0D +EFI_STATUS=0D +EFIAPI=0D +InstallBhyveTables (=0D + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol=0D + );=0D +=0D EFI_STATUS=0D EFIAPI=0D InstallXenTables (=0D 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 @@ #include =0D #include // QemuFwCfgFindFile()=0D =0D +#define BHYVE_ACPI_PHYSICAL_ADDRESS ((UINTN)0x000F2400)=0D +#define BHYVE_BIOS_PHYSICAL_END ((UINTN)0x00100000)=0D +=0D +#pragma pack (1)=0D +=0D +typedef struct {=0D + EFI_ACPI_DESCRIPTION_HEADER Header;=0D + UINT64 Tables[0];=0D +} EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE;=0D +=0D +#pragma pack ()=0D +=0D STATIC=0D EFI_STATUS=0D EFIAPI=0D @@ -164,3 +176,257 @@ BhyveInstallAcpiTable ( TableKey=0D );=0D }=0D +=0D +/**=0D + Get the address of bhyve's ACPI Root System Description Pointer (RSDP).= =0D +=0D + @param RsdpPtr Return pointer to RSDP.=0D +=0D + @return EFI_SUCCESS Bhyve's RSDP successfully found.=0D + @return EFI_NOT_FOUND Couldn't find bhyve's RSDP.=0D + @return EFI_UNSUPPORTED Revision is lower than 2.=0D + @return EFI_PROTOCOL_ERROR Invalid RSDP found.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +BhyveGetAcpiRsdp (=0D + OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr=0D + )=0D +{=0D + UINTN RsdpAddress;=0D + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;=0D +=0D + if (RsdpPtr =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Detect the RSDP=0D + //=0D + for (RsdpAddress =3D BHYVE_ACPI_PHYSICAL_ADDRESS;=0D + RsdpAddress < BHYVE_BIOS_PHYSICAL_END;=0D + RsdpAddress +=3D 0x10)=0D + {=0D + Rsdp =3D NUMERIC_VALUE_AS_POINTER (=0D + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER,=0D + RsdpAddress=0D + );=0D + if (Rsdp->Signature !=3D EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_= SIGNATURE) {=0D + continue;=0D + }=0D +=0D + if (Rsdp->Revision < 2) {=0D + DEBUG ((DEBUG_INFO, "%a: unsupported RSDP found\n", __FUNCTION__));= =0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + //=0D + // For ACPI 1.0/2.0/3.0 the checksum of first 20 bytes should be 0.=0D + // For ACPI 2.0/3.0 the checksum of the entire table should be 0.=0D + //=0D + UINT8 Sum =3D CalculateCheckSum8 (=0D + (CONST UINT8 *)Rsdp,=0D + sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)=0D + );=0D + if (Sum !=3D 0) {=0D + DEBUG ((=0D + DEBUG_INFO,=0D + "%a: RSDP header checksum not valid: 0x%02x\n",=0D + __FUNCTION__,=0D + Sum=0D + ));=0D + return EFI_PROTOCOL_ERROR;=0D + }=0D +=0D + Sum =3D CalculateCheckSum8 (=0D + (CONST UINT8 *)Rsdp,=0D + sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)=0D + );=0D + if (Sum !=3D 0) {=0D + DEBUG ((=0D + DEBUG_INFO,=0D + "%a: RSDP table checksum not valid: 0x%02x\n",=0D + __FUNCTION__,=0D + Sum=0D + ));=0D + return EFI_PROTOCOL_ERROR;=0D + }=0D +=0D + //=0D + // RSDP was found and is valid=0D + //=0D + *RsdpPtr =3D Rsdp;=0D +=0D + return EFI_SUCCESS;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "%a: RSDP not found\n", __FUNCTION__));=0D + return EFI_NOT_FOUND;=0D +}=0D +=0D +/**=0D + Get bhyve's ACPI tables from the RSDP. And install bhyve's ACPI tables=0D + into the RSDT/XSDT using InstallAcpiTable.=0D +=0D + @param AcpiProtocol Protocol instance pointer.=0D +=0D + @return EFI_SUCCESS All tables were successfully inserted.=0D + @return EFI_UNSUPPORTED Bhyve's ACPI tables doesn't include a XSDT.= =0D + @return EFI_PROTOCOL_ERROR Invalid XSDT found.=0D +=0D + @return Error codes propagated from underlying funct= ions.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +InstallBhyveTables (=0D + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINTN TableHandle;=0D + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;=0D + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;=0D + EFI_ACPI_DESCRIPTION_HEADER *Dsdt;=0D +=0D + Rsdp =3D NULL;=0D + Facs =3D NULL;=0D + Dsdt =3D NULL;=0D +=0D + //=0D + // Try to find bhyve ACPI tables=0D + //=0D + Status =3D BhyveGetAcpiRsdp (&Rsdp);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_INFO, "%a: can't get RSDP (%r)\n", __FUNCTION__, Status)= );=0D + return Status;=0D + }=0D +=0D + //=0D + // Bhyve should always provide a XSDT=0D + //=0D + EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE *CONST Xsdt =3D=0D + NUMERIC_VALUE_AS_POINTER (=0D + EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE,=0D + Rsdp->XsdtAddress=0D + );=0D +=0D + if (Xsdt =3D=3D NULL) {=0D + DEBUG ((DEBUG_INFO, "%a: XSDT not found\n", __FUNCTION__));=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (Xsdt->Header.Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {=0D + DEBUG ((DEBUG_INFO, "%a: invalid XSDT length\n", __FUNCTION__));=0D + return EFI_PROTOCOL_ERROR;=0D + }=0D +=0D + //=0D + // Install ACPI tables=0D + //=0D + CONST UINTN NumberOfTableEntries =3D=0D + (Xsdt->Header.Length - sizeof (Xsdt->Header)) / sizeof (UINT64);=0D +=0D + for (UINTN Index =3D 0; Index < NumberOfTableEntries; Index++) {=0D + EFI_ACPI_DESCRIPTION_HEADER *CONST CurrentTable =3D=0D + NUMERIC_VALUE_AS_POINTER (=0D + EFI_ACPI_DESCRIPTION_HEADER,=0D + Xsdt->Tables[Index]=0D + );=0D + Status =3D AcpiProtocol->InstallAcpiTable (=0D + AcpiProtocol,=0D + CurrentTable,=0D + CurrentTable->Length,=0D + &TableHandle=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((=0D + DEBUG_INFO,=0D + "%a: failed to install ACPI table %c%c%c%c (%r)\n",=0D + __FUNCTION__,=0D + NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[0],=0D + NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[1],=0D + NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[2],=0D + NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[3],=0D + Status=0D + ));=0D + return Status;=0D + }=0D +=0D + if (CurrentTable->Signature =3D=3D EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION= _TABLE_SIGNATURE) {=0D + EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *CONST Fadt =3D=0D + (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *CONST)CurrentTable;=0D + if (Fadt->XFirmwareCtrl) {=0D + Facs =3D NUMERIC_VALUE_AS_POINTER (=0D + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE,=0D + Fadt->XFirmwareCtrl=0D + );=0D + } else {=0D + Facs =3D NUMERIC_VALUE_AS_POINTER (=0D + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE,=0D + Fadt->FirmwareCtrl=0D + );=0D + }=0D +=0D + if (Fadt->XDsdt) {=0D + Dsdt =3D NUMERIC_VALUE_AS_POINTER (=0D + EFI_ACPI_DESCRIPTION_HEADER,=0D + Fadt->XDsdt=0D + );=0D + } else {=0D + Dsdt =3D NUMERIC_VALUE_AS_POINTER (=0D + EFI_ACPI_DESCRIPTION_HEADER,=0D + Fadt->Dsdt=0D + );=0D + }=0D + }=0D + }=0D +=0D + //=0D + // Install FACS=0D + //=0D + if (Facs !=3D NULL) {=0D + Status =3D AcpiProtocol->InstallAcpiTable (=0D + AcpiProtocol,=0D + Facs,=0D + Facs->Length,=0D + &TableHandle=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((=0D + DEBUG_INFO,=0D + "%a: failed to install FACS (%r)\n",=0D + __FUNCTION__,=0D + Status=0D + ));=0D + return Status;=0D + }=0D + }=0D +=0D + //=0D + // Install DSDT=0D + // If it's not found, something bad happened. Don't continue execution.= =0D + //=0D + if (Dsdt =3D=3D NULL) {=0D + DEBUG ((DEBUG_ERROR, "%a: failed to find DSDT\n", __FUNCTION__));=0D + CpuDeadLoop ();=0D + }=0D +=0D + Status =3D AcpiProtocol->InstallAcpiTable (=0D + AcpiProtocol,=0D + Dsdt,=0D + Dsdt->Length,=0D + &TableHandle=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((=0D + DEBUG_INFO,=0D + "%a: failed to install DSDT (%r)\n",=0D + __FUNCTION__,=0D + Status=0D + ));=0D + return Status;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D --=20 2.40.0