From nobody Sun Jul 13 02:37:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1528457995074100.13801309849623; Fri, 8 Jun 2018 04:39:55 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 49AE52112A280; Fri, 8 Jun 2018 04:39:50 -0700 (PDT) Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id AF0E22110C800 for ; Fri, 8 Jun 2018 04:39:48 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7827F40252ED for ; Fri, 8 Jun 2018 11:39:47 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-117-155.ams2.redhat.com [10.36.117.155]) by smtp.corp.redhat.com (Postfix) with ESMTP id A95F62166BC7; Fri, 8 Jun 2018 11:39:46 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id B7B40422B8; Fri, 8 Jun 2018 13:39:45 +0200 (CEST) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=kraxel@redhat.com; receiver=edk2-devel@lists.01.org From: Gerd Hoffmann To: edk2-devel@lists.01.org Date: Fri, 8 Jun 2018 13:39:40 +0200 Message-Id: <20180608113942.17009-3-kraxel@redhat.com> In-Reply-To: <20180608113942.17009-1-kraxel@redhat.com> References: <20180608113942.17009-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 08 Jun 2018 11:39:47 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 08 Jun 2018 11:39:47 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kraxel@redhat.com' RCPT:'' Subject: [edk2] [PATCH 2/4] OvmfPkg: add QemuRamfbDxe X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add a driver for the qemu ramfb display device. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Gerd Hoffmann --- OvmfPkg/QemuRamfbDxe/QemuRamfb.c | 308 ++++++++++++++++++++++++++++++= ++++ OvmfPkg/OvmfPkgIa32.dsc | 1 + OvmfPkg/OvmfPkgIa32.fdf | 1 + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + OvmfPkg/OvmfPkgIa32X64.fdf | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + OvmfPkg/OvmfPkgX64.fdf | 1 + OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf | 34 ++++ 8 files changed, 348 insertions(+) create mode 100644 OvmfPkg/QemuRamfbDxe/QemuRamfb.c create mode 100644 OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf diff --git a/OvmfPkg/QemuRamfbDxe/QemuRamfb.c b/OvmfPkg/QemuRamfbDxe/QemuRa= mfb.c new file mode 100644 index 0000000000..f04a314c24 --- /dev/null +++ b/OvmfPkg/QemuRamfbDxe/QemuRamfb.c @@ -0,0 +1,308 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define RAMFB_FORMAT 0x34325258 /* DRM_FORMAT_XRGB8888 */ +#define RAMFB_BPP 4 + +EFI_GUID gQemuRamfbGuid =3D QEMU_RAMFB_GUID; + +typedef struct RAMFB_CONFIG { + UINT64 Address; + UINT32 FourCC; + UINT32 Flags; + UINT32 Width; + UINT32 Height; + UINT32 Stride; +} RAMFB_CONFIG; + +EFI_HANDLE RamfbHandle; +EFI_HANDLE GopHandle; +FRAME_BUFFER_CONFIGURE *QemuRamfbFrameBufferBltConfigure; +UINTN QemuRamfbFrameBufferBltConfigureSize; + +EFI_GRAPHICS_OUTPUT_MODE_INFORMATION QemuRamfbModeInfo[] =3D { + { + .HorizontalResolution =3D 640, + .VerticalResolution =3D 480, + },{ + .HorizontalResolution =3D 800, + .VerticalResolution =3D 600, + },{ + .HorizontalResolution =3D 1024, + .VerticalResolution =3D 768, + } +}; +#define QemuRamfbModeCount (sizeof(QemuRamfbModeInfo)/sizeof(QemuRamfbMode= Info[0])) + +EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE QemuRamfbMode =3D { + .MaxMode =3D QemuRamfbModeCount, + .Mode =3D 0, + .Info =3D QemuRamfbModeInfo, + .SizeOfInfo =3D sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), +}; + +EFI_STATUS +EFIAPI +QemuRamfbGraphicsOutputQueryMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +{ + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeInfo; + + if (Info =3D=3D NULL || SizeOfInfo =3D=3D NULL || ModeNumber > QemuRamfb= Mode.MaxMode) { + return EFI_INVALID_PARAMETER; + } + ModeInfo =3D &QemuRamfbModeInfo[ModeNumber]; + + *Info =3D AllocateCopyPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION= ), + ModeInfo); + if (*Info =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + *SizeOfInfo =3D sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +QemuRamfbGraphicsOutputSetMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber + ) +{ + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeInfo; + RAMFB_CONFIG Config; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; + RETURN_STATUS Ret; + FIRMWARE_CONFIG_ITEM Item; + UINTN Size; + + if (ModeNumber > QemuRamfbMode.MaxMode) { + return EFI_UNSUPPORTED; + } + ModeInfo =3D &QemuRamfbModeInfo[ModeNumber]; + + DEBUG ((EFI_D_INFO, "Ramfb: SetMode %d (%dx%d)\n", ModeNumber, + ModeInfo->HorizontalResolution, + ModeInfo->VerticalResolution)); + + QemuRamfbMode.Mode =3D ModeNumber; + QemuRamfbMode.Info =3D ModeInfo; + + Config.Address =3D SwapBytes64( QemuRamfbMode.FrameBufferBase ); + Config.FourCC =3D SwapBytes32( RAMFB_FORMAT ); + Config.Flags =3D SwapBytes32( 0 ); + Config.Width =3D SwapBytes32( ModeInfo->HorizontalResolution ); + Config.Height =3D SwapBytes32( ModeInfo->VerticalResolution ); + Config.Stride =3D SwapBytes32( ModeInfo->HorizontalResolution * RAMFB_B= PP ); + + QemuFwCfgFindFile("etc/ramfb", &Item, &Size); + QemuFwCfgSelectItem(Item); + QemuFwCfgWriteBytes(sizeof(Config), &Config); + + Ret =3D FrameBufferBltConfigure ( + (VOID*)(UINTN)QemuRamfbMode.FrameBufferBase, + ModeInfo, + QemuRamfbFrameBufferBltConfigure, + &QemuRamfbFrameBufferBltConfigureSize); + + if (Ret =3D=3D RETURN_BUFFER_TOO_SMALL) { + if (QemuRamfbFrameBufferBltConfigure !=3D NULL) { + FreePool(QemuRamfbFrameBufferBltConfigure); + } + QemuRamfbFrameBufferBltConfigure =3D + AllocatePool(QemuRamfbFrameBufferBltConfigureSize); + + Ret =3D FrameBufferBltConfigure ( + (VOID*)(UINTN)QemuRamfbMode.FrameBufferBase, + ModeInfo, + QemuRamfbFrameBufferBltConfigure, + &QemuRamfbFrameBufferBltConfigureSize); + } + + /* clear screen */ + ZeroMem (&Black, sizeof (Black)); + Ret =3D FrameBufferBlt ( + QemuRamfbFrameBufferBltConfigure, + &Black, + EfiBltVideoFill, + 0, 0, + 0, 0, + ModeInfo->HorizontalResolution, + ModeInfo->VerticalResolution, + 0 + ); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +QemuRamfbGraphicsOutputBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +{ + return FrameBufferBlt ( + QemuRamfbFrameBufferBltConfigure, + BltBuffer, + BltOperation, + SourceX, + SourceY, + DestinationX, + DestinationY, + Width, + Height, + Delta); +} + +EFI_GRAPHICS_OUTPUT_PROTOCOL QemuRamfbGraphicsOutput =3D { + .QueryMode =3D QemuRamfbGraphicsOutputQueryMode, + .SetMode =3D QemuRamfbGraphicsOutputSetMode, + .Blt =3D QemuRamfbGraphicsOutputBlt, + .Mode =3D &QemuRamfbMode, +}; + +EFI_STATUS +EFIAPI +InitializeQemuRamfb ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_DEVICE_PATH_PROTOCOL *RamfbDevicePath; + EFI_DEVICE_PATH_PROTOCOL *GopDevicePath; + VOID *DevicePath; + VENDOR_DEVICE_PATH VendorDeviceNode; + ACPI_ADR_DEVICE_PATH AcpiDeviceNode; + EFI_STATUS Status; + RETURN_STATUS Ret; + FIRMWARE_CONFIG_ITEM Item; + EFI_PHYSICAL_ADDRESS FbBase; + UINTN Size, FbSize, MaxFbSize, Pages, Index; + + DEBUG ((EFI_D_INFO, "InitializeQemuRamfb\n")); + + if (!QemuFwCfgIsAvailable()) { + DEBUG ((EFI_D_INFO, "Ramfb: no FwCfg\n")); + return EFI_NOT_FOUND; + } + + Ret =3D QemuFwCfgFindFile("etc/ramfb", &Item, &Size); + if (Ret !=3D RETURN_SUCCESS) { + DEBUG ((EFI_D_INFO, "Ramfb: no etc/ramfb in FwCfg\n")); + return EFI_NOT_FOUND; + } + + MaxFbSize =3D 0; + for (Index =3D 0; Index < QemuRamfbModeCount; Index++) { + QemuRamfbModeInfo[Index].PixelsPerScanLine =3D + QemuRamfbModeInfo[Index].HorizontalResolution; + QemuRamfbModeInfo[Index].PixelFormat =3D + PixelBlueGreenRedReserved8BitPerColor, + FbSize =3D RAMFB_BPP * + QemuRamfbModeInfo[Index].HorizontalResolution * + QemuRamfbModeInfo[Index].VerticalResolution; + if (MaxFbSize < FbSize) + MaxFbSize =3D FbSize; + DEBUG ((EFI_D_INFO, "Ramfb: Mode %d: %dx%d, %d kB\n", Index, + QemuRamfbModeInfo[Index].HorizontalResolution, + QemuRamfbModeInfo[Index].VerticalResolution, + FbSize / 1024)); + } + + Pages =3D EFI_SIZE_TO_PAGES(MaxFbSize); + MaxFbSize =3D EFI_PAGES_TO_SIZE(Pages); + FbBase =3D (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRuntimePages(Pages); + if (!FbBase) { + DEBUG ((EFI_D_INFO, "Ramfb: memory allocation failed\n")); + return EFI_OUT_OF_RESOURCES; + } + DEBUG ((EFI_D_INFO, "Ramfb: Framebuffer at 0x%lx, %d kB, %d pages\n", + FbBase, MaxFbSize / 1024, Pages)); + QemuRamfbMode.FrameBufferSize =3D MaxFbSize; + QemuRamfbMode.FrameBufferBase =3D FbBase; + + /* 800 x 600 */ + QemuRamfbGraphicsOutputSetMode (&QemuRamfbGraphicsOutput, 1); + + /* ramfb vendor devpath */ + ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH)); + VendorDeviceNode.Header.Type =3D HARDWARE_DEVICE_PATH; + VendorDeviceNode.Header.SubType =3D HW_VENDOR_DP; + VendorDeviceNode.Guid =3D gQemuRamfbGuid; + SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE= _PATH)); + + RamfbDevicePath =3D AppendDevicePathNode ( + NULL, + (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode); + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &RamfbHandle, + &gEfiDevicePathProtocolGuid, RamfbDevicePath, + NULL); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "Ramfb: install Ramfb Vendor DevicePath failed\n")= ); + FreePool((VOID*)(UINTN)QemuRamfbMode.FrameBufferBase); + return Status; + } + + /* gop devpath + protocol */ + ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH)); + AcpiDeviceNode.Header.Type =3D ACPI_DEVICE_PATH; + AcpiDeviceNode.Header.SubType =3D ACPI_ADR_DP; + AcpiDeviceNode.ADR =3D ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, + ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DI= GITAL, + 0, 0); + SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE= _PATH)); + + GopDevicePath =3D AppendDevicePathNode ( + RamfbDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode); + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &GopHandle, + &gEfiDevicePathProtocolGuid, GopDevicePath, + &gEfiGraphicsOutputProtocolGuid, &QemuRamfbGraphicsOutput, + NULL); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "Ramfb: install GOP DevicePath failed\n")); + FreePool((VOID*)(UINTN)QemuRamfbMode.FrameBufferBase); + return Status; + } + + gBS->OpenProtocol ( + RamfbHandle, + &gEfiDevicePathProtocolGuid, + &DevicePath, + gImageHandle, + GopHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER); + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index a2c995b910..7ddda89999 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -745,6 +745,7 @@ MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf =20 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf + OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf OvmfPkg/VirtioGpuDxe/VirtioGpu.inf =20 # diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index b199713925..52b8b1fea1 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -351,6 +351,7 @@ INF RuleOverride=3DCSM OvmfPkg/Csm/Csm16/Csm16.inf !endif =20 INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf +INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf INF OvmfPkg/PlatformDxe/Platform.inf INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index bc7db229d2..3481cdc36b 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -754,6 +754,7 @@ MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf =20 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf + OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf OvmfPkg/VirtioGpuDxe/VirtioGpu.inf =20 # diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 4ebf64b2b9..70845d6972 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -357,6 +357,7 @@ INF RuleOverride=3DCSM OvmfPkg/Csm/Csm16/Csm16.inf !endif =20 INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf +INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf INF OvmfPkg/PlatformDxe/Platform.inf INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 0767b34d18..8b0895b0ff 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -752,6 +752,7 @@ MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf =20 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf + OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf OvmfPkg/VirtioGpuDxe/VirtioGpu.inf =20 # diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 9ca96f9282..1eb46ac9a2 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -357,6 +357,7 @@ INF RuleOverride=3DCSM OvmfPkg/Csm/Csm16/Csm16.inf !endif =20 INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf +INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf INF OvmfPkg/PlatformDxe/Platform.inf INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf diff --git a/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf b/OvmfPkg/QemuRamfbDxe/Q= emuRamfbDxe.inf new file mode 100644 index 0000000000..75a7d86832 --- /dev/null +++ b/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf @@ -0,0 +1,34 @@ +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D QemuRamfbDxe + FILE_GUID =3D dce1b094-7dc6-45d0-9fdd-d7fc3cc3e4ef + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + + ENTRY_POINT =3D InitializeQemuRamfb + +[Sources.common] + QemuRamfb.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + DevicePathLib + FrameBufferBltLib + MemoryAllocationLib + UefiBootManagerLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + QemuFwCfgLib + +[Protocols] + gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START + +[Depex] + TRUE --=20 2.9.3 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel