public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v3 0/4] Add QemuRamfbDxe driver
@ 2018-06-13  7:29 Gerd Hoffmann
  2018-06-13  7:29 ` [PATCH v3 1/4] OvmfPkg: add QEMU_RAMFB_GUID Gerd Hoffmann
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-06-13  7:29 UTC (permalink / raw)
  To: edk2-devel

  Hi,

This is the efi driver for qemu ramfb, a simple boot framebuffer.  Qemu
patches just have been posted to qemu-devel.

v3: fix leftovers from v2.
v2: tons of codestyle fixes, some control flow tweaks.

cheers,
  Gerd

Gerd Hoffmann (4):
  OvmfPkg: add QEMU_RAMFB_GUID
  OvmfPkg: add QemuRamfbDxe
  OvmfPkg: add QemuRamfb to platform console
  ArmVirtPkg: add QemuRamfbDxe

 OvmfPkg/Include/Guid/QemuRamfb.h                   |  25 ++
 .../Library/PlatformBootManagerLib/PlatformData.c  |  51 +++
 OvmfPkg/QemuRamfbDxe/QemuRamfb.c                   | 399 +++++++++++++++++++++
 ArmVirtPkg/ArmVirtQemu.dsc                         |   2 +
 ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc               |   1 +
 ArmVirtPkg/ArmVirtQemuKernel.dsc                   |   2 +
 OvmfPkg/OvmfPkg.dec                                |   1 +
 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              |  52 +++
 14 files changed, 539 insertions(+)
 create mode 100644 OvmfPkg/Include/Guid/QemuRamfb.h
 create mode 100644 OvmfPkg/QemuRamfbDxe/QemuRamfb.c
 create mode 100644 OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf

-- 
2.9.3



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/4] OvmfPkg: add QEMU_RAMFB_GUID
  2018-06-13  7:29 [PATCH v3 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
@ 2018-06-13  7:29 ` Gerd Hoffmann
  2018-06-13  7:29 ` [PATCH v3 2/4] OvmfPkg: add QemuRamfbDxe Gerd Hoffmann
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-06-13  7:29 UTC (permalink / raw)
  To: edk2-devel

Add GUID header file for the QemuRamfbDxe driver.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
 OvmfPkg/Include/Guid/QemuRamfb.h | 25 +++++++++++++++++++++++++
 OvmfPkg/OvmfPkg.dec              |  1 +
 2 files changed, 26 insertions(+)
 create mode 100644 OvmfPkg/Include/Guid/QemuRamfb.h

diff --git a/OvmfPkg/Include/Guid/QemuRamfb.h b/OvmfPkg/Include/Guid/QemuRamfb.h
new file mode 100644
index 0000000000..5c9dffb1f0
--- /dev/null
+++ b/OvmfPkg/Include/Guid/QemuRamfb.h
@@ -0,0 +1,25 @@
+/** @file
+  Recommended GUID to be used in the Vendor Hardware device path nodes that
+  identify qemu ramfb devices.
+
+  Copyright (C) 2018, Red Hat, Inc.
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License that accompanies this
+  distribution. The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __QEMU_RAMFB_H__
+#define __QEMU_RAMFB_H__
+
+#define QEMU_RAMFB_GUID \
+{0x557423a1, 0x63ab, 0x406c, {0xbe, 0x7e, 0x91, 0xcd, 0xbc, 0x08, 0xc4, 0x57}}
+
+extern EFI_GUID gQemuRamfbGuid;
+
+#endif
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index dc5597db41..7666297cf8 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -75,6 +75,7 @@
   gEfiXenInfoGuid                     = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
   gOvmfPlatformConfigGuid             = {0x7235c51c, 0x0c80, 0x4cab, {0x87, 0xac, 0x3b, 0x08, 0x4a, 0x63, 0x04, 0xb1}}
   gVirtioMmioTransportGuid            = {0x837dca9e, 0xe874, 0x4d82, {0xb2, 0x9a, 0x23, 0xfe, 0x0e, 0x23, 0xd1, 0xe2}}
+  gQemuRamfbGuid                      = {0x557423a1, 0x63ab, 0x406c, {0xbe, 0x7e, 0x91, 0xcd, 0xbc, 0x08, 0xc4, 0x57}}
   gXenBusRootDeviceGuid               = {0xa732241f, 0x383d, 0x4d9c, {0x8a, 0xe1, 0x8e, 0x09, 0x83, 0x75, 0x89, 0xd7}}
   gRootBridgesConnectedEventGroupGuid = {0x24a2d66f, 0xeedd, 0x4086, {0x90, 0x42, 0xf2, 0x6e, 0x47, 0x97, 0xee, 0x69}}
 
-- 
2.9.3



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/4] OvmfPkg: add QemuRamfbDxe
  2018-06-13  7:29 [PATCH v3 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
  2018-06-13  7:29 ` [PATCH v3 1/4] OvmfPkg: add QEMU_RAMFB_GUID Gerd Hoffmann
@ 2018-06-13  7:29 ` Gerd Hoffmann
  2018-06-13 18:20   ` Laszlo Ersek
  2018-06-13  7:29 ` [PATCH v3 3/4] OvmfPkg: add QemuRamfb to platform console Gerd Hoffmann
  2018-06-13  7:29 ` [PATCH v3 4/4] ArmVirtPkg: add QemuRamfbDxe Gerd Hoffmann
  3 siblings, 1 reply; 9+ messages in thread
From: Gerd Hoffmann @ 2018-06-13  7:29 UTC (permalink / raw)
  To: edk2-devel

Add a driver for the qemu ramfb display device.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 OvmfPkg/QemuRamfbDxe/QemuRamfb.c      | 399 ++++++++++++++++++++++++++++++++++
 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 |  52 +++++
 8 files changed, 457 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..d5025a1cee
--- /dev/null
+++ b/OvmfPkg/QemuRamfbDxe/QemuRamfb.c
@@ -0,0 +1,399 @@
+/** @file
+  This driver is a implementation of the Graphics Output Protocol
+  for the QEMU ramfb device.
+
+  Copyright (c) 2018, Red Hat Inc.
+
+  This program and the accompanying materials are licensed and made
+  available under the terms and conditions of the BSD License which
+  accompanies this distribution. The full text of the license may be
+  found at http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
+  BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
+  EXPRESS OR IMPLIED.
+
+**/
+
+#include <Protocol/GraphicsOutput.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/FrameBufferBltLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/QemuFwCfgLib.h>
+
+#include <Guid/QemuRamfb.h>
+
+#define RAMFB_FORMAT  0x34325258 /* DRM_FORMAT_XRGB8888 */
+#define RAMFB_BPP     4
+
+#pragma pack (1)
+typedef struct RAMFB_CONFIG {
+  UINT64 Address;
+  UINT32 FourCC;
+  UINT32 Flags;
+  UINT32 Width;
+  UINT32 Height;
+  UINT32 Stride;
+} RAMFB_CONFIG;
+#pragma pack ()
+
+STATIC EFI_HANDLE                    mRamfbHandle;
+STATIC EFI_HANDLE                    mGopHandle;
+STATIC FRAME_BUFFER_CONFIGURE        *mQemuRamfbFrameBufferBltConfigure;
+STATIC UINTN                         mQemuRamfbFrameBufferBltConfigureSize;
+STATIC FIRMWARE_CONFIG_ITEM          mRamfbFwCfgItem;
+
+STATIC EFI_GRAPHICS_OUTPUT_MODE_INFORMATION mQemuRamfbModeInfo[] = {
+  {
+    0,    // Version
+    640,  // HorizontalResolution
+    480,  // VerticalResolution
+  },{
+    0,    // Version
+    800,  // HorizontalResolution
+    600,  // VerticalResolution
+  },{
+    0,    // Version
+    1024, // HorizontalResolution
+    768,  // VerticalResolution
+  }
+};
+
+STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE mQemuRamfbMode = {
+  ARRAY_SIZE (mQemuRamfbModeInfo),                // MaxMode
+  0,                                              // Mode
+  mQemuRamfbModeInfo,                             // Info
+  sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),  // SizeOfInfo
+};
+
+STATIC
+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 >= mQemuRamfbMode.MaxMode) {
+    return EFI_INVALID_PARAMETER;
+  }
+  ModeInfo = &mQemuRamfbModeInfo[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;
+}
+
+STATIC
+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                         Status;
+
+  if (ModeNumber >= mQemuRamfbMode.MaxMode) {
+    return EFI_UNSUPPORTED;
+  }
+  ModeInfo = &mQemuRamfbModeInfo[ModeNumber];
+
+  DEBUG ((DEBUG_INFO, "Ramfb: SetMode %u (%ux%u)\n", ModeNumber,
+    ModeInfo->HorizontalResolution, ModeInfo->VerticalResolution));
+
+  Config.Address = SwapBytes64 (mQemuRamfbMode.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);
+
+  Status = FrameBufferBltConfigure (
+             (VOID*)(UINTN)mQemuRamfbMode.FrameBufferBase,
+             ModeInfo,
+             mQemuRamfbFrameBufferBltConfigure,
+             &mQemuRamfbFrameBufferBltConfigureSize
+             );
+
+  if (Status == RETURN_BUFFER_TOO_SMALL) {
+    if (mQemuRamfbFrameBufferBltConfigure != NULL) {
+      FreePool (mQemuRamfbFrameBufferBltConfigure);
+    }
+    mQemuRamfbFrameBufferBltConfigure =
+      AllocatePool (mQemuRamfbFrameBufferBltConfigureSize);
+    if (mQemuRamfbFrameBufferBltConfigure == NULL) {
+      mQemuRamfbFrameBufferBltConfigureSize = 0;
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    Status = FrameBufferBltConfigure (
+               (VOID*)(UINTN)mQemuRamfbMode.FrameBufferBase,
+               ModeInfo,
+               mQemuRamfbFrameBufferBltConfigure,
+               &mQemuRamfbFrameBufferBltConfigureSize
+               );
+  }
+  if (RETURN_ERROR (Status)) {
+    ASSERT (Status == RETURN_UNSUPPORTED);
+    return Status;
+  }
+
+  mQemuRamfbMode.Mode = ModeNumber;
+  mQemuRamfbMode.Info = ModeInfo;
+
+  QemuFwCfgSelectItem (mRamfbFwCfgItem);
+  QemuFwCfgWriteBytes (sizeof (Config), &Config);
+
+  //
+  // clear screen
+  //
+  ZeroMem (&Black, sizeof (Black));
+  Status = FrameBufferBlt (
+             mQemuRamfbFrameBufferBltConfigure,
+             &Black,
+             EfiBltVideoFill,
+             0,                               // SourceX -- ignored
+             0,                               // SourceY -- ignored
+             0,                               // DestinationX
+             0,                               // DestinationY
+             ModeInfo->HorizontalResolution,  // Width
+             ModeInfo->VerticalResolution,    // Height
+             0                                // Delta -- ignored
+             );
+  if (RETURN_ERROR (Status)) {
+    DEBUG ((DEBUG_WARN, "%a: clearing the screen failed: %r\n",
+      __FUNCTION__, Status));
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+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 (
+           mQemuRamfbFrameBufferBltConfigure,
+           BltBuffer,
+           BltOperation,
+           SourceX,
+           SourceY,
+           DestinationX,
+           DestinationY,
+           Width,
+           Height,
+           Delta
+           );
+}
+
+STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL mQemuRamfbGraphicsOutput = {
+  QemuRamfbGraphicsOutputQueryMode,
+  QemuRamfbGraphicsOutputSetMode,
+  QemuRamfbGraphicsOutputBlt,
+  &mQemuRamfbMode,
+};
+
+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;
+  EFI_PHYSICAL_ADDRESS      FbBase;
+  UINTN                     FbSize, MaxFbSize;
+  UINTN                     FwCfgSize, Pages, Index;
+
+  if (!QemuFwCfgIsAvailable ()) {
+    DEBUG ((DEBUG_INFO, "Ramfb: no FwCfg\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  Status = QemuFwCfgFindFile ("etc/ramfb", &mRamfbFwCfgItem, &FwCfgSize);
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+  if (FwCfgSize != sizeof (RAMFB_CONFIG)) {
+    DEBUG ((DEBUG_ERROR, "Ramfb: FwCfg size mismatch (expected %lu, got %lu)\n",
+      (UINT64)sizeof (RAMFB_CONFIG), (UINT64)FwCfgSize));
+    return EFI_PROTOCOL_ERROR;
+  }
+
+  MaxFbSize = 0;
+  for (Index = 0; Index < ARRAY_SIZE (mQemuRamfbModeInfo); Index++) {
+    mQemuRamfbModeInfo[Index].PixelsPerScanLine =
+      mQemuRamfbModeInfo[Index].HorizontalResolution;
+    mQemuRamfbModeInfo[Index].PixelFormat =
+      PixelBlueGreenRedReserved8BitPerColor;
+    FbSize = RAMFB_BPP *
+      mQemuRamfbModeInfo[Index].HorizontalResolution *
+      mQemuRamfbModeInfo[Index].VerticalResolution;
+    if (MaxFbSize < FbSize) {
+      MaxFbSize = FbSize;
+    }
+    DEBUG ((DEBUG_INFO, "Ramfb: Mode %lu: %ux%u, %lu kB\n", (UINT64)Index,
+      mQemuRamfbModeInfo[Index].HorizontalResolution,
+      mQemuRamfbModeInfo[Index].VerticalResolution,
+      (UINT64)(FbSize / 1024)));
+  }
+
+  Pages = EFI_SIZE_TO_PAGES (MaxFbSize);
+  MaxFbSize = EFI_PAGES_TO_SIZE (Pages);
+  FbBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedPages (Pages);
+  if (FbBase == 0) {
+    DEBUG ((DEBUG_ERROR, "Ramfb: memory allocation failed\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  DEBUG ((DEBUG_INFO, "Ramfb: Framebuffer at 0x%lx, %lu kB, %lu pages\n",
+    (UINT64)FbBase, (UINT64)(MaxFbSize / 1024), (UINT64)Pages));
+  mQemuRamfbMode.FrameBufferSize = MaxFbSize;
+  mQemuRamfbMode.FrameBufferBase = FbBase;
+
+  //
+  // 800 x 600
+  //
+  QemuRamfbGraphicsOutputSetMode (&mQemuRamfbGraphicsOutput, 1);
+
+  //
+  // ramfb vendor devpath
+  //
+  VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;
+  VendorDeviceNode.Header.SubType = HW_VENDOR_DP;
+  CopyGuid (&VendorDeviceNode.Guid, &gQemuRamfbGuid);
+  SetDevicePathNodeLength (&VendorDeviceNode.Header,
+    sizeof (VENDOR_DEVICE_PATH));
+
+  RamfbDevicePath = AppendDevicePathNode (NULL,
+    (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode);
+  if (RamfbDevicePath == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeFramebuffer;
+  }
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mRamfbHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  RamfbDevicePath,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Ramfb: install Ramfb Vendor DevicePath failed: %r\n",
+      Status));
+    goto FreeRamfbDevicePath;
+  }
+
+  //
+  // gop devpath + protocol
+  //
+  AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
+  AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
+  AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (
+    1,                                       // DeviceIdScheme
+    0,                                       // HeadId
+    0,                                       // NonVgaOutput
+    1,                                       // BiosCanDetect
+    0,                                       // VendorInfo
+    ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL,  // Type
+    0,                                       // Port
+    0                                        // Index
+    );
+  SetDevicePathNodeLength (&AcpiDeviceNode.Header,
+    sizeof (ACPI_ADR_DEVICE_PATH));
+
+  GopDevicePath = AppendDevicePathNode (RamfbDevicePath,
+    (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode);
+  if (GopDevicePath == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeRamfbHandle;
+  }
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mGopHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  GopDevicePath,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  &mQemuRamfbGraphicsOutput,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Ramfb: install GOP DevicePath failed: %r\n",
+      Status));
+    goto FreeGopDevicePath;
+  }
+
+  Status = gBS->OpenProtocol (
+                  mRamfbHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &DevicePath,
+                  gImageHandle,
+                  mGopHandle,
+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Ramfb: OpenProtocol failed: %r\n", Status));
+    goto FreeGopHandle;
+  }
+
+  return EFI_SUCCESS;
+
+FreeGopHandle:
+  gBS->UninstallMultipleProtocolInterfaces (
+         mGopHandle,
+         &gEfiDevicePathProtocolGuid,
+         GopDevicePath,
+         &gEfiGraphicsOutputProtocolGuid,
+         &mQemuRamfbGraphicsOutput,
+         NULL
+         );
+FreeGopDevicePath:
+  FreePool (GopDevicePath);
+FreeRamfbHandle:
+  gBS->UninstallMultipleProtocolInterfaces (
+         mRamfbHandle,
+         &gEfiDevicePathProtocolGuid,
+         RamfbDevicePath,
+         NULL
+         );
+FreeRamfbDevicePath:
+  FreePool (RamfbDevicePath);
+FreeFramebuffer:
+  FreePages ((VOID*)(UINTN)mQemuRamfbMode.FrameBufferBase, Pages);
+  return Status;
+}
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..a91fabd4d8
--- /dev/null
+++ b/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
@@ -0,0 +1,52 @@
+## @file
+#  This driver is a implementation of the Graphics Output Protocol
+#  for the QEMU ramfb device.
+#
+#  Copyright (c) 2018, Red Hat Inc.
+#
+#  This program and the accompanying materials are licensed and made
+#  available under the terms and conditions of the BSD License which
+#  accompanies this distribution. The full text of the license may be
+#  found at http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
+#  BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
+#  EXPRESS OR IMPLIED.
+#
+
+[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]
+  QemuRamfb.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  FrameBufferBltLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  QemuFwCfgLib
+
+[Protocols]
+  gEfiGraphicsOutputProtocolGuid                ## PRODUCES
+
+[Guids]
+  gQemuRamfbGuid
+
+[Depex]
+  TRUE
-- 
2.9.3



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 3/4] OvmfPkg: add QemuRamfb to platform console
  2018-06-13  7:29 [PATCH v3 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
  2018-06-13  7:29 ` [PATCH v3 1/4] OvmfPkg: add QEMU_RAMFB_GUID Gerd Hoffmann
  2018-06-13  7:29 ` [PATCH v3 2/4] OvmfPkg: add QemuRamfbDxe Gerd Hoffmann
@ 2018-06-13  7:29 ` Gerd Hoffmann
  2018-06-13  7:29 ` [PATCH v3 4/4] ArmVirtPkg: add QemuRamfbDxe Gerd Hoffmann
  3 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-06-13  7:29 UTC (permalink / raw)
  To: edk2-devel

Add QemuRamfbDxe device path to the list of platform console devices,
so ConSplitter will pick up the device even though it isn't a PCI GPU.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
 .../Library/PlatformBootManagerLib/PlatformData.c  | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
index a50cd7bcaf..1250a6d351 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
@@ -14,6 +14,7 @@
 **/
 
 #include "BdsPlatform.h"
+#include <Guid/QemuRamfb.h>
 
 //
 // Debug Agent UART Device Path structure
@@ -37,6 +38,17 @@ typedef struct {
 } USB_KEYBOARD_DEVICE_PATH;
 #pragma pack ()
 
+//
+// QemuRamfb Device Path structure
+//
+#pragma pack (1)
+typedef struct {
+  VENDOR_DEVICE_PATH        Vendor;
+  ACPI_ADR_DEVICE_PATH      AcpiAdr;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} VENDOR_RAMFB_DEVICE_PATH;
+#pragma pack ()
+
 ACPI_HID_DEVICE_PATH       gPnpPs2KeyboardDeviceNode  = gPnpPs2Keyboard;
 ACPI_HID_DEVICE_PATH       gPnp16550ComPortDeviceNode = gPnp16550ComPort;
 UART_DEVICE_PATH           gUartDeviceNode            = gUart;
@@ -100,6 +112,41 @@ STATIC USB_KEYBOARD_DEVICE_PATH gUsbKeyboardDevicePath = {
   gEndEntire
 };
 
+STATIC VENDOR_RAMFB_DEVICE_PATH gQemuRamfbDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    QEMU_RAMFB_GUID,
+  },
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_ADR_DP,
+      {
+        (UINT8) (sizeof (ACPI_ADR_DEVICE_PATH)),
+        (UINT8) ((sizeof (ACPI_ADR_DEVICE_PATH)) >> 8)
+      }
+    },
+    ACPI_DISPLAY_ADR (
+      1,                                       // DeviceIdScheme
+      0,                                       // HeadId
+      0,                                       // NonVgaOutput
+      1,                                       // BiosCanDetect
+      0,                                       // VendorInfo
+      ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL,  // Type
+      0,                                       // Port
+      0                                        // Index
+      ),
+  },
+  gEndEntire
+};
+
 //
 // Predefined platform default console device path
 //
@@ -113,6 +160,10 @@ PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {
     CONSOLE_IN
   },
   {
+    (EFI_DEVICE_PATH_PROTOCOL *)&gQemuRamfbDevicePath,
+    CONSOLE_OUT
+  },
+  {
     NULL,
     0
   }
-- 
2.9.3



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 4/4] ArmVirtPkg: add QemuRamfbDxe
  2018-06-13  7:29 [PATCH v3 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2018-06-13  7:29 ` [PATCH v3 3/4] OvmfPkg: add QemuRamfb to platform console Gerd Hoffmann
@ 2018-06-13  7:29 ` Gerd Hoffmann
  3 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-06-13  7:29 UTC (permalink / raw)
  To: edk2-devel

Add QemuRamfbDxe to dsc and fdf files for ArmVirt package.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
 ArmVirtPkg/ArmVirtQemu.dsc           | 2 ++
 ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 1 +
 ArmVirtPkg/ArmVirtQemuKernel.dsc     | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index d74feb709c..744d127a10 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -57,6 +57,7 @@
   BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
   PlatformBootManagerLib|ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+  FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
   QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
   PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
@@ -391,6 +392,7 @@
   #
   # Video support
   #
+  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
   OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
   OvmfPkg/PlatformDxe/Platform.inf
 
diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
index 89f95b2d99..63a202c788 100644
--- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
+++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
@@ -175,6 +175,7 @@ READ_LOCK_STATUS   = TRUE
   #
   # Video support
   #
+  INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
   INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
   INF OvmfPkg/PlatformDxe/Platform.inf
 
diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
index 1e823aeab7..e59f53b728 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -57,6 +57,7 @@
   BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
   PlatformBootManagerLib|ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+  FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
   QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
   FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
   PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
@@ -380,6 +381,7 @@
   #
   # Video support
   #
+  OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
   OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
   OvmfPkg/PlatformDxe/Platform.inf
 
-- 
2.9.3



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/4] OvmfPkg: add QemuRamfbDxe
  2018-06-13  7:29 ` [PATCH v3 2/4] OvmfPkg: add QemuRamfbDxe Gerd Hoffmann
@ 2018-06-13 18:20   ` Laszlo Ersek
  2018-06-13 19:03     ` Laszlo Ersek
  0 siblings, 1 reply; 9+ messages in thread
From: Laszlo Ersek @ 2018-06-13 18:20 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: edk2-devel, Ard Biesheuvel

On 06/13/18 09:29, Gerd Hoffmann wrote:

> +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;
> +  EFI_PHYSICAL_ADDRESS      FbBase;
> +  UINTN                     FbSize, MaxFbSize;
> +  UINTN                     FwCfgSize, Pages, Index;

(1) Lol, you really disliked point (15) from my previous review :) OK,
I'll fix this up before pushing.

> diff --git a/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf b/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
> new file mode 100644
> index 0000000000..a91fabd4d8
> --- /dev/null
> +++ b/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
> @@ -0,0 +1,52 @@
> +## @file
> +#  This driver is a implementation of the Graphics Output Protocol
> +#  for the QEMU ramfb device.
> +#
> +#  Copyright (c) 2018, Red Hat Inc.
> +#
> +#  This program and the accompanying materials are licensed and made
> +#  available under the terms and conditions of the BSD License which
> +#  accompanies this distribution. The full text of the license may be
> +#  found at http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> +#  BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> +#  EXPRESS OR IMPLIED.
> +#

(2) Whatever editor you used to rewrap this removed the trailing "##".
But, I'll fix that up for you.

So here's the patch I'm going to squash into yours:

> diff --git a/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf b/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
> index a91fabd4d8f7..013edef72b59 100644
> --- a/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
> +++ b/OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
> @@ -13,6 +13,7 @@
>  #  BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
>  #  EXPRESS OR IMPLIED.
>  #
> +##
>
>  [Defines]
>    INF_VERSION                    = 0x00010005
> diff --git a/OvmfPkg/QemuRamfbDxe/QemuRamfb.c b/OvmfPkg/QemuRamfbDxe/QemuRamfb.c
> index 044e5c325e80..b49f2ca6e891 100644
> --- a/OvmfPkg/QemuRamfbDxe/QemuRamfb.c
> +++ b/OvmfPkg/QemuRamfbDxe/QemuRamfb.c
> @@ -238,8 +238,9 @@ InitializeQemuRamfb (
>    ACPI_ADR_DEVICE_PATH      AcpiDeviceNode;
>    EFI_STATUS                Status;
>    EFI_PHYSICAL_ADDRESS      FbBase;
> -  UINTN                     FbSize, MaxFbSize;
> -  UINTN                     FwCfgSize, Pages, Index;
> +  UINTN                     FbSize, MaxFbSize, Pages;
> +  UINTN                     FwCfgSize;
> +  UINTN                     Index;
>
>    if (!QemuFwCfgIsAvailable ()) {
>      DEBUG ((DEBUG_INFO, "Ramfb: no FwCfg\n"));

[lersek@redhat.com: fix INF banner typo]
[lersek@redhat.com: make some local variable definitions more idiomatic]

With that:
Reviewed-by: Laszlo Ersek <lersek@redhat.com>

--*--

I've also tested the series, against your "sirius/ramfb" QEMU branch
(currently at commit 778450b87275) that you noted in:

  [Qemu-devel] [PATCH v5 0/4] ramfb: simple boot framebuffer
  http://mid.mail-archive.com/20180613122948.18149-1-kraxel@redhat.com

I used the plain "ramfb" device model.

* testing on x86_64/KVM:

I booted a Fedora 27 ISO, and verified that efifb worked fine (including
X11/GDM).

Furthermore, in

  Re: [edk2] [PATCH 0/4] Add QemuRamfbDxe driver
  http://mid.mail-archive.com/20180613074006.pawpkylp5ok76qdz@sirius.home.kraxel.org

we discussed disconnecting the child handle and the parent handle. For
my QEMU cmdline, the "dh -d -v -p GraphicsOutput" UEFI shell command
lists two handles; from those, this driver produces the following
(child) handle:

> 44: ConsoleOut(0) SimpleTextOut(7ED59830)   Address: 7ED59830 Attrib 07
>      mode 0: Col 80 Row 25
>      mode 1: Col -1 Row -1
>      mode 2: Col 100 Row 31
>   *  mode 3: Col 128 Row 40
> GraphicsOutput(7E6822E0)
>   Max Mode..............: 0x00000003
>   Current Mode..........: 0x00000002
>   Frame Buffer Base.....: 0x000000007E37A000
>   Frame Buffer Size.....: 0x0000000000300000
>   Mode Info Size........: 0x0000000000000024
>   Information
>     Version.............: 0x00000000
>     HorizontalResolution: 1024
>     VerticalResolution..: 768
>     Pixel Format........: PixelBlueGreenRedReserved8BitPerColor
>     Pixels / Scan Line..: 1024
>     Pixel Info
>       RedMask...........: 0x00000000
>       GreenMask.........: 0x00000000
>       BlueMask..........: 0x00000000
>   Supported Resolution List
>     Resolution[0]:
>       Horizontal........: 640
>       Vertical..........: 480
>     Resolution[1]:
>       Horizontal........: 800
>       Vertical..........: 600
>     Resolution[2]:
>       Horizontal........: 1024
>       Vertical..........: 768
> DevicePath(7ED7D598)
>   VenHw(557423A1-63AB-406C-BE7E-91CDBC08C457)/AcpiAdr(0x80010300)
>    Controller Name    : VenHw(557423A1-63AB-406C-BE7E-91CDBC08C457)/AcpiAdr(0x80010300)
>    Device Path        : VenHw(557423A1-63AB-406C-BE7E-91CDBC08C457)/AcpiAdr(0x80010300)
>    Controller Type    : BUS
>    Configuration      : NO
>    Diagnostics        : NO
>    Managed by         :
>      Drv[6C]          : Platform Console Management Driver
>      Drv[70]          : Console Splitter Driver
>      Drv[75]          : Graphics Console Driver
>    Parent Controllers :
>      Parent[43]       : VenHw(557423A1-63AB-406C-BE7E-91CDBC08C457)
>    Child Controllers  :
>      Child[73]        : Primary Console Output Device

The parent handle is, in turn:

> 43: 7ED7D118
> DevicePath(7ED7D998)
>   VenHw(557423A1-63AB-406C-BE7E-91CDBC08C457)

When we try to disconnect all drivers from the parent handle, we get:

> Shell> disconnect 43
> Disconnect - (43,7FE6F0C0,7EBBB898) Result Success.

and nothing changes in behavior. This is a good result -- the parent
handle is not bound by any UEFI driver that follows the UEFI driver
model, so there's nothing to disconnect from it.

When we try to disconnect all drivers from the child handle, we get:

> Shell> disconnect 44
> Disconnect - (44,7FE6F0C0,7EB9D598) Result Success.

and graphical updates stop (serial continues to work). In addition, the
dump for handle 44 now says:

> 44: 7ED7D698
> GraphicsOutput(7E6822E0)
>   Max Mode..............: 0x00000003
>   Current Mode..........: 0x00000002
>   Frame Buffer Base.....: 0x000000007E37A000
>   Frame Buffer Size.....: 0x0000000000300000
>   Mode Info Size........: 0x0000000000000024
>   Information
>     Version.............: 0x00000000
>     HorizontalResolution: 1024
>     VerticalResolution..: 768
>     Pixel Format........: PixelBlueGreenRedReserved8BitPerColor
>     Pixels / Scan Line..: 1024
>     Pixel Info
>       RedMask...........: 0x00000000
>       GreenMask.........: 0x00000000
>       BlueMask..........: 0x00000000
>   Supported Resolution List
>     Resolution[0]:
>       Horizontal........: 640
>       Vertical..........: 480
>     Resolution[1]:
>       Horizontal........: 800
>       Vertical..........: 600
>     Resolution[2]:
>       Horizontal........: 1024
>       Vertical..........: 768
> DevicePath(7ED7D598)
>   VenHw(557423A1-63AB-406C-BE7E-91CDBC08C457)/AcpiAdr(0x80010300)
>    Controller Name    : VenHw(557423A1-63AB-406C-BE7E-91CDBC08C457)/AcpiAdr(0x80010300)
>    Device Path        : VenHw(557423A1-63AB-406C-BE7E-91CDBC08C457)/AcpiAdr(0x80010300)
>    Controller Type    : DEVICE
>    Configuration      : NO
>    Diagnostics        : NO
>    Managed by         : <None>
>    Parent Controllers :
>      Parent[43]       : VenHw(557423A1-63AB-406C-BE7E-91CDBC08C457)
>    Child Controllers  : <None>

We see that ConPlatformDxe unbound the GOP --> the ConsoleOut protocol
interface disappeared; GraphicsConsoleDxe unbound the GOP --> the
SimpleTextOut protocol interface disappeared; and ConSplitterDxe unbound
the GOP and both afore-mentioned protocol interfaces. The GOP and the
devpath themselves remain installed though; they come from this driver
(a platform DXE driver). So, this is a good result.

After running "connect 44", the graphics window comes to life again.

I checked the absence of ramfb too, using one of my long-term
libvirtd-managed guests. The OVMF debug log says:

> Loading driver at 0x0007DAC2000 EntryPoint=0x0007DAC61DC QemuRamfbDxe.efi
> ...
> Error: Image at 0007DAC2000 start failed: Not Found

Which is good.

* testing on aarch64/KVM:

The graphics output looks great as long as I'm in the UEFI shell / the
setup TUI / the grub menu. However, once I boot a Fedora 28 Server ISO,
and the graphical Anacona Welcome screen appears, I get the exact same
display corruption as before, with QemuVideoDxe + the VGA device model.
I don't have the slightest idea why that is the case, but it's very
visible, if I quickly move the thick blue line cursor around the
language and keyboard layout selection lists. It's visible to the naked
eye how dirty memory is gradually flushed to the display.

Here's my setup:

- host hardware: APM Mustang A3
- host kernel: 4.14.0-49.2.2.el7a.aarch64
- edk2: built at cbba5ca104fb, plus your v3 (present) patches applied,
  plus the above small changes squashed
- QEMU: built at commit 778450b from your branch (see above)
- QEMU command line:

  qemu-system-aarch64 \
    -nodefaults \
    -m 2048 \
    -machine virt,accel=kvm \
    -cpu host \
    -device ramfb \
    -drive if=pflash,readonly,format=raw,file=/root/QEMU_EFI.fd.padded \
    -drive if=pflash,format=raw,file=vars21.fd \
    -chardev stdio,signal=off,mux=on,id=char0 \
    -mon chardev=char0,mode=readline \
    -serial chardev:char0 \
    -drive if=none,readonly=on,format=raw,id=cd0,file=/home/virt-images/isos/Fedora-Server-dvd-aarch64-28-1.1.iso \
    -device virtio-scsi-pci,id=scsi0 \
    -device scsi-cd,drive=cd0,bus=scsi0.0 \
    -device qemu-xhci,id=xhci1 \
    -device usb-kbd,bus=xhci1.0

If it matters, I used the SDL display type (I usually don't build the
GTK one), and I forwarded the graphics from my Mustang to my laptop via
"ssh -X -Y".

The guest kernel dmesg includes:

> [    7.330898] efifb: probing for efifb
> [    7.331670] efifb: framebuffer at 0xb8450000, using 1876k, total 1875k
> [    7.332999] efifb: mode is 800x600x32, linelength=3200, pages=1
> [    7.334177] efifb: scrolling: redraw
> [    7.334893] efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
> [    7.338207] Console: switching to colour frame buffer device 100x37
> [    7.341113] fb0: EFI VGA frame buffer device

The address b8450000 is consistent with the ArmVirtQemu log (and the
related QEMU debug message).


There's another small wart (I guess this relates more to the QEMU
series): on aarch64, I get the following warning at startup:

> Could not open option rom 'vgabios-ramfb.bin': No such file or directory


Argh, this is so frustrating! I was getting ready to push this version!
:(

Laszlo


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/4] OvmfPkg: add QemuRamfbDxe
  2018-06-13 18:20   ` Laszlo Ersek
@ 2018-06-13 19:03     ` Laszlo Ersek
  2018-06-13 19:15       ` Laszlo Ersek
  0 siblings, 1 reply; 9+ messages in thread
From: Laszlo Ersek @ 2018-06-13 19:03 UTC (permalink / raw)
  To: Gerd Hoffmann, Ard Biesheuvel; +Cc: edk2-devel

On 06/13/18 20:20, Laszlo Ersek wrote:

> * testing on aarch64/KVM:
>
> The graphics output looks great as long as I'm in the UEFI shell / the
> setup TUI / the grub menu. However, once I boot a Fedora 28 Server
> ISO, and the graphical Anacona Welcome screen appears, I get the exact
> same display corruption as before, with QemuVideoDxe + the VGA device
> model. I don't have the slightest idea why that is the case, but it's
> very visible, if I quickly move the thick blue line cursor around the
> language and keyboard layout selection lists. It's visible to the
> naked eye how dirty memory is gradually flushed to the display.

Wait, I see "efifb" has a parameter called "nowc", and it disables
write-combining, according to "Documentation/fb/efifb.txt".

Looking at the source code ("drivers/video/fbdev/efifb.c"), "nowc"
decides between:

> 	if (nowc)
> 		info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
> 	else
> 		info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);

Am I right to think that *both* of these ioremap() variants map the
phsyical address range as uncache-able? ("nowc" defaults to "false", and
I didn't specify "nowc" at all on the kernel command line.)

Quoting "arch/arm/include/asm/io.h":

>  * Function             Memory type     Cacheability    Cache hint
>  * ioremap()            Device          n/a             n/a
>  * ioremap_nocache()    Device          n/a             n/a
>  * ioremap_cache()      Normal          Writeback       Read allocate
>  * ioremap_wc()         Normal          Non-cacheable   n/a
>  * ioremap_wt()         Normal          Non-cacheable   n/a

ioremap() implies "device memory" (by definition uncacheable only),
while ioremap_wc() is normal memory, but UC. Sigh.

The include file "arch/arm64/include/asm/io.h" doesn't have such helpful
comments, but it does declare ioremap_cache() at least:

> extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);

Now, I *guess* if I rebuilt the efifb driver to use ioremap_cache() --
dependent on a new module parameter or some such --, the Linux guest
would start working as expected. Unfortunately, the Linux guest is
already pretty happy with virtio-gpu-pci; the question is how the
Windows guest would map the EFI framebuffer!

Unfortunately, I cannot test ARM64 Windows guests ATM.

So... If the consensus is that the edk2 code simply cannot get better
than this, and everything else is up to the guest OS(es), then I'm 100%
willing to push this version (with my minimal updates squashed).

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/4] OvmfPkg: add QemuRamfbDxe
  2018-06-13 19:03     ` Laszlo Ersek
@ 2018-06-13 19:15       ` Laszlo Ersek
  2018-06-13 20:30         ` Ard Biesheuvel
  0 siblings, 1 reply; 9+ messages in thread
From: Laszlo Ersek @ 2018-06-13 19:15 UTC (permalink / raw)
  To: Gerd Hoffmann, Ard Biesheuvel; +Cc: edk2-devel

On 06/13/18 21:03, Laszlo Ersek wrote:
> On 06/13/18 20:20, Laszlo Ersek wrote:
> 
>> * testing on aarch64/KVM:
>>
>> The graphics output looks great as long as I'm in the UEFI shell / the
>> setup TUI / the grub menu. However, once I boot a Fedora 28 Server
>> ISO, and the graphical Anacona Welcome screen appears, I get the exact
>> same display corruption as before, with QemuVideoDxe + the VGA device
>> model. I don't have the slightest idea why that is the case, but it's
>> very visible, if I quickly move the thick blue line cursor around the
>> language and keyboard layout selection lists. It's visible to the
>> naked eye how dirty memory is gradually flushed to the display.

Small (or not so small) technical correction: the problem is that the
guest OS writes directly to DRAM, but QEMU reads from the CPU cache. So
I guess the gradual process that is visible to the naked eye is not
"flushing" but "invalidation"; i.e. as the CPU caches become invalid,
QEMU is gradually forced to reach out to DRAM and finally see what the
guest OS put there. I guess.

More below:

> 
> Wait, I see "efifb" has a parameter called "nowc", and it disables
> write-combining, according to "Documentation/fb/efifb.txt".
> 
> Looking at the source code ("drivers/video/fbdev/efifb.c"), "nowc"
> decides between:
> 
>> 	if (nowc)
>> 		info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
>> 	else
>> 		info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
> 
> Am I right to think that *both* of these ioremap() variants map the
> phsyical address range as uncache-able? ("nowc" defaults to "false", and
> I didn't specify "nowc" at all on the kernel command line.)
> 
> Quoting "arch/arm/include/asm/io.h":
> 
>>  * Function             Memory type     Cacheability    Cache hint
>>  * ioremap()            Device          n/a             n/a
>>  * ioremap_nocache()    Device          n/a             n/a
>>  * ioremap_cache()      Normal          Writeback       Read allocate
>>  * ioremap_wc()         Normal          Non-cacheable   n/a
>>  * ioremap_wt()         Normal          Non-cacheable   n/a
> 
> ioremap() implies "device memory" (by definition uncacheable only),
> while ioremap_wc() is normal memory, but UC. Sigh.
> 
> The include file "arch/arm64/include/asm/io.h" doesn't have such helpful
> comments, but it does declare ioremap_cache() at least:
> 
>> extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
> 
> Now, I *guess* if I rebuilt the efifb driver to use ioremap_cache() --
> dependent on a new module parameter or some such --, the Linux guest
> would start working as expected. Unfortunately, the Linux guest is
> already pretty happy with virtio-gpu-pci; the question is how the
> Windows guest would map the EFI framebuffer!
> 
> Unfortunately, I cannot test ARM64 Windows guests ATM.
> 
> So... If the consensus is that the edk2 code simply cannot get better
> than this, and everything else is up to the guest OS(es), then I'm 100%
> willing to push this version (with my minimal updates squashed).

I've just remembered that Drew drew our attention earlier to:

  [PATCH 0/4] KVM/arm64: Cache maintenance relaxations
  http://mid.mail-archive.com/20180517103548.5622-1-marc.zyngier@arm.com

I believe this means that, on an ARMv8.4 host, the ramfb device model
will automatically work, in all guest OSes. If that's the case, I
suggest we merge this series.

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/4] OvmfPkg: add QemuRamfbDxe
  2018-06-13 19:15       ` Laszlo Ersek
@ 2018-06-13 20:30         ` Ard Biesheuvel
  0 siblings, 0 replies; 9+ messages in thread
From: Ard Biesheuvel @ 2018-06-13 20:30 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: Gerd Hoffmann, edk2-devel@lists.01.org

On 13 June 2018 at 21:15, Laszlo Ersek <lersek@redhat.com> wrote:
> On 06/13/18 21:03, Laszlo Ersek wrote:
>> On 06/13/18 20:20, Laszlo Ersek wrote:
>>
>>> * testing on aarch64/KVM:
>>>
>>> The graphics output looks great as long as I'm in the UEFI shell / the
>>> setup TUI / the grub menu. However, once I boot a Fedora 28 Server
>>> ISO, and the graphical Anacona Welcome screen appears, I get the exact
>>> same display corruption as before, with QemuVideoDxe + the VGA device
>>> model. I don't have the slightest idea why that is the case, but it's
>>> very visible, if I quickly move the thick blue line cursor around the
>>> language and keyboard layout selection lists. It's visible to the
>>> naked eye how dirty memory is gradually flushed to the display.
>
> Small (or not so small) technical correction: the problem is that the
> guest OS writes directly to DRAM, but QEMU reads from the CPU cache. So
> I guess the gradual process that is visible to the naked eye is not
> "flushing" but "invalidation"; i.e. as the CPU caches become invalid,
> QEMU is gradually forced to reach out to DRAM and finally see what the
> guest OS put there. I guess.
>
> More below:
>
>>
>> Wait, I see "efifb" has a parameter called "nowc", and it disables
>> write-combining, according to "Documentation/fb/efifb.txt".
>>
>> Looking at the source code ("drivers/video/fbdev/efifb.c"), "nowc"
>> decides between:
>>
>>>      if (nowc)
>>>              info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
>>>      else
>>>              info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
>>
>> Am I right to think that *both* of these ioremap() variants map the
>> phsyical address range as uncache-able? ("nowc" defaults to "false", and
>> I didn't specify "nowc" at all on the kernel command line.)
>>
>> Quoting "arch/arm/include/asm/io.h":
>>
>>>  * Function             Memory type     Cacheability    Cache hint
>>>  * ioremap()            Device          n/a             n/a
>>>  * ioremap_nocache()    Device          n/a             n/a
>>>  * ioremap_cache()      Normal          Writeback       Read allocate
>>>  * ioremap_wc()         Normal          Non-cacheable   n/a
>>>  * ioremap_wt()         Normal          Non-cacheable   n/a
>>
>> ioremap() implies "device memory" (by definition uncacheable only),
>> while ioremap_wc() is normal memory, but UC. Sigh.
>>
>> The include file "arch/arm64/include/asm/io.h" doesn't have such helpful
>> comments, but it does declare ioremap_cache() at least:
>>
>>> extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
>>
>> Now, I *guess* if I rebuilt the efifb driver to use ioremap_cache() --
>> dependent on a new module parameter or some such --, the Linux guest
>> would start working as expected. Unfortunately, the Linux guest is
>> already pretty happy with virtio-gpu-pci; the question is how the
>> Windows guest would map the EFI framebuffer!
>>
>> Unfortunately, I cannot test ARM64 Windows guests ATM.
>>
>> So... If the consensus is that the edk2 code simply cannot get better
>> than this, and everything else is up to the guest OS(es), then I'm 100%
>> willing to push this version (with my minimal updates squashed).
>
> I've just remembered that Drew drew our attention earlier to:
>
>   [PATCH 0/4] KVM/arm64: Cache maintenance relaxations
>   http://mid.mail-archive.com/20180517103548.5622-1-marc.zyngier@arm.com
>
> I believe this means that, on an ARMv8.4 host, the ramfb device model
> will automatically work, in all guest OSes. If that's the case, I
> suggest we merge this series.
>

I am not sure how I managed to confuse myself into thinking that ramfb
would solve the coherency issue on ARM, but unfortunately, the
observed behavior is exactly as expected. The framebuffer is still
located in RAM that is mapped cacheable by the host and non-cacheable
by the guest.

There is a notable difference though: this time, the efifb framebuffer
is identifiable as ordinary [although reserved] memory by the guest,
and so I think it is reasonable for the efifb driver to check whether
the memory is covered by a region in the UEFI memory map that has the
EFI_MEMORY_WB attribute, in which case it is permitted to use a
cacheable mapping.


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-06-13 20:30 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-13  7:29 [PATCH v3 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
2018-06-13  7:29 ` [PATCH v3 1/4] OvmfPkg: add QEMU_RAMFB_GUID Gerd Hoffmann
2018-06-13  7:29 ` [PATCH v3 2/4] OvmfPkg: add QemuRamfbDxe Gerd Hoffmann
2018-06-13 18:20   ` Laszlo Ersek
2018-06-13 19:03     ` Laszlo Ersek
2018-06-13 19:15       ` Laszlo Ersek
2018-06-13 20:30         ` Ard Biesheuvel
2018-06-13  7:29 ` [PATCH v3 3/4] OvmfPkg: add QemuRamfb to platform console Gerd Hoffmann
2018-06-13  7:29 ` [PATCH v3 4/4] ArmVirtPkg: add QemuRamfbDxe Gerd Hoffmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox