From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 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) 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: [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: , X-List-Received-Date: Fri, 08 Jun 2018 11:39:49 -0000 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/QemuRamfb.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 = 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[] = { + { + .HorizontalResolution = 640, + .VerticalResolution = 480, + },{ + .HorizontalResolution = 800, + .VerticalResolution = 600, + },{ + .HorizontalResolution = 1024, + .VerticalResolution = 768, + } +}; +#define QemuRamfbModeCount (sizeof(QemuRamfbModeInfo)/sizeof(QemuRamfbModeInfo[0])) + +EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE QemuRamfbMode = { + .MaxMode = QemuRamfbModeCount, + .Mode = 0, + .Info = QemuRamfbModeInfo, + .SizeOfInfo = 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 == NULL || SizeOfInfo == NULL || ModeNumber > QemuRamfbMode.MaxMode) { + return EFI_INVALID_PARAMETER; + } + ModeInfo = &QemuRamfbModeInfo[ModeNumber]; + + *Info = AllocateCopyPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), + ModeInfo); + if (*Info == NULL) { + return EFI_OUT_OF_RESOURCES; + } + *SizeOfInfo = 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 = &QemuRamfbModeInfo[ModeNumber]; + + DEBUG ((EFI_D_INFO, "Ramfb: SetMode %d (%dx%d)\n", ModeNumber, + ModeInfo->HorizontalResolution, + ModeInfo->VerticalResolution)); + + QemuRamfbMode.Mode = ModeNumber; + QemuRamfbMode.Info = ModeInfo; + + Config.Address = SwapBytes64( QemuRamfbMode.FrameBufferBase ); + Config.FourCC = SwapBytes32( RAMFB_FORMAT ); + Config.Flags = SwapBytes32( 0 ); + Config.Width = SwapBytes32( ModeInfo->HorizontalResolution ); + Config.Height = SwapBytes32( ModeInfo->VerticalResolution ); + Config.Stride = SwapBytes32( ModeInfo->HorizontalResolution * RAMFB_BPP ); + + QemuFwCfgFindFile("etc/ramfb", &Item, &Size); + QemuFwCfgSelectItem(Item); + QemuFwCfgWriteBytes(sizeof(Config), &Config); + + Ret = FrameBufferBltConfigure ( + (VOID*)(UINTN)QemuRamfbMode.FrameBufferBase, + ModeInfo, + QemuRamfbFrameBufferBltConfigure, + &QemuRamfbFrameBufferBltConfigureSize); + + if (Ret == RETURN_BUFFER_TOO_SMALL) { + if (QemuRamfbFrameBufferBltConfigure != NULL) { + FreePool(QemuRamfbFrameBufferBltConfigure); + } + QemuRamfbFrameBufferBltConfigure = + AllocatePool(QemuRamfbFrameBufferBltConfigureSize); + + Ret = FrameBufferBltConfigure ( + (VOID*)(UINTN)QemuRamfbMode.FrameBufferBase, + ModeInfo, + QemuRamfbFrameBufferBltConfigure, + &QemuRamfbFrameBufferBltConfigureSize); + } + + /* clear screen */ + ZeroMem (&Black, sizeof (Black)); + Ret = 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 = { + .QueryMode = QemuRamfbGraphicsOutputQueryMode, + .SetMode = QemuRamfbGraphicsOutputSetMode, + .Blt = QemuRamfbGraphicsOutputBlt, + .Mode = &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 = QemuFwCfgFindFile("etc/ramfb", &Item, &Size); + if (Ret != RETURN_SUCCESS) { + DEBUG ((EFI_D_INFO, "Ramfb: no etc/ramfb in FwCfg\n")); + return EFI_NOT_FOUND; + } + + MaxFbSize = 0; + for (Index = 0; Index < QemuRamfbModeCount; Index++) { + QemuRamfbModeInfo[Index].PixelsPerScanLine = + QemuRamfbModeInfo[Index].HorizontalResolution; + QemuRamfbModeInfo[Index].PixelFormat = + PixelBlueGreenRedReserved8BitPerColor, + FbSize = RAMFB_BPP * + QemuRamfbModeInfo[Index].HorizontalResolution * + QemuRamfbModeInfo[Index].VerticalResolution; + if (MaxFbSize < FbSize) + MaxFbSize = FbSize; + DEBUG ((EFI_D_INFO, "Ramfb: Mode %d: %dx%d, %d kB\n", Index, + QemuRamfbModeInfo[Index].HorizontalResolution, + QemuRamfbModeInfo[Index].VerticalResolution, + FbSize / 1024)); + } + + Pages = EFI_SIZE_TO_PAGES(MaxFbSize); + MaxFbSize = EFI_PAGES_TO_SIZE(Pages); + FbBase = (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 = MaxFbSize; + QemuRamfbMode.FrameBufferBase = FbBase; + + /* 800 x 600 */ + QemuRamfbGraphicsOutputSetMode (&QemuRamfbGraphicsOutput, 1); + + /* ramfb vendor devpath */ + ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH)); + VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH; + VendorDeviceNode.Header.SubType = HW_VENDOR_DP; + VendorDeviceNode.Guid = gQemuRamfbGuid; + SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH)); + + RamfbDevicePath = AppendDevicePathNode ( + NULL, + (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode); + + Status = 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 = ACPI_DEVICE_PATH; + AcpiDeviceNode.Header.SubType = ACPI_ADR_DP; + AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, + ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, + 0, 0); + SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH)); + + GopDevicePath = AppendDevicePathNode ( + RamfbDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode); + + Status = 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 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf + OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf OvmfPkg/VirtioGpuDxe/VirtioGpu.inf # 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=CSM OvmfPkg/Csm/Csm16/Csm16.inf !endif 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 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf + OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf OvmfPkg/VirtioGpuDxe/VirtioGpu.inf # 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=CSM OvmfPkg/Csm/Csm16/Csm16.inf !endif 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 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf + OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf OvmfPkg/VirtioGpuDxe/VirtioGpu.inf # 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=CSM OvmfPkg/Csm/Csm16/Csm16.inf !endif 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/QemuRamfbDxe.inf new file mode 100644 index 0000000000..75a7d86832 --- /dev/null +++ b/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf @@ -0,0 +1,34 @@ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = QemuRamfbDxe + FILE_GUID = dce1b094-7dc6-45d0-9fdd-d7fc3cc3e4ef + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = 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 -- 2.9.3