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

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

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  |  44 +++
 OvmfPkg/QemuRamfbDxe/QemuRamfb.c                   | 308 +++++++++++++++++++++
 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              |  34 +++
 14 files changed, 423 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] 18+ messages in thread

* [PATCH 1/4] OvmfPkg: add QEMU_RAMFB_GUID
  2018-06-08 11:39 [PATCH 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
@ 2018-06-08 11:39 ` Gerd Hoffmann
  2018-06-11 13:06   ` Laszlo Ersek
  2018-06-08 11:39 ` [PATCH 2/4] OvmfPkg: add QemuRamfbDxe Gerd Hoffmann
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:39 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>
---
 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..878224599d
--- /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 \
+{0x837dca9e, 0xe874, 0x4d82, {0xb2, 0x9a, 0x23, 0xfe, 0x0e, 0x23, 0xd1, 0xe2}}
+
+extern EFI_GUID gQemuRamfbGuid;
+
+#endif
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index dc5597db41..a16c22a289 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                      = {0x837dca9e, 0xe874, 0x4d82, {0xb2, 0x9a, 0x23, 0xfe, 0x0e, 0x23, 0xd1, 0xe2}}
   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] 18+ messages in thread

* [PATCH 2/4] OvmfPkg: add QemuRamfbDxe
  2018-06-08 11:39 [PATCH 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
  2018-06-08 11:39 ` [PATCH 1/4] OvmfPkg: add QEMU_RAMFB_GUID Gerd Hoffmann
@ 2018-06-08 11:39 ` Gerd Hoffmann
  2018-06-10  5:57   ` Ard Biesheuvel
  2018-06-11 15:56   ` Laszlo Ersek
  2018-06-08 11:39 ` [PATCH 3/4] OvmfPkg: add QemuRamfb to platform console Gerd Hoffmann
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:39 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      | 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 <Uefi.h>
+#include <Protocol/GraphicsOutput.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/FrameBufferBltLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/QemuFwCfgLib.h>
+
+#include <Guid/QemuRamfb.h>
+
+#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



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

* [PATCH 3/4] OvmfPkg: add QemuRamfb to platform console
  2018-06-08 11:39 [PATCH 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
  2018-06-08 11:39 ` [PATCH 1/4] OvmfPkg: add QEMU_RAMFB_GUID Gerd Hoffmann
  2018-06-08 11:39 ` [PATCH 2/4] OvmfPkg: add QemuRamfbDxe Gerd Hoffmann
@ 2018-06-08 11:39 ` Gerd Hoffmann
  2018-06-11 16:24   ` Laszlo Ersek
  2018-06-08 11:39 ` [PATCH 4/4] ArmVirtPkg: add QemuRamfbDxe Gerd Hoffmann
  2018-06-11 16:35 ` [PATCH 0/4] Add QemuRamfbDxe driver Laszlo Ersek
  4 siblings, 1 reply; 18+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:39 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>
---
 .../Library/PlatformBootManagerLib/PlatformData.c  | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
index a50cd7bcaf..6202516971 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,34 @@ 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, 0, 0, 1, 0,
+                      ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL,
+                      0, 0)
+  },
+  gEndEntire
+};
+
 //
 // Predefined platform default console device path
 //
@@ -113,6 +153,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] 18+ messages in thread

* [PATCH 4/4] ArmVirtPkg: add QemuRamfbDxe
  2018-06-08 11:39 [PATCH 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2018-06-08 11:39 ` [PATCH 3/4] OvmfPkg: add QemuRamfb to platform console Gerd Hoffmann
@ 2018-06-08 11:39 ` Gerd Hoffmann
  2018-06-11 16:29   ` Laszlo Ersek
  2018-06-11 16:35 ` [PATCH 0/4] Add QemuRamfbDxe driver Laszlo Ersek
  4 siblings, 1 reply; 18+ messages in thread
From: Gerd Hoffmann @ 2018-06-08 11:39 UTC (permalink / raw)
  To: edk2-devel

Build wireup for ArmVirt.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Gerd Hoffmann <kraxel@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] 18+ messages in thread

* Re: [PATCH 2/4] OvmfPkg: add QemuRamfbDxe
  2018-06-08 11:39 ` [PATCH 2/4] OvmfPkg: add QemuRamfbDxe Gerd Hoffmann
@ 2018-06-10  5:57   ` Ard Biesheuvel
  2018-06-11 15:56   ` Laszlo Ersek
  1 sibling, 0 replies; 18+ messages in thread
From: Ard Biesheuvel @ 2018-06-10  5:57 UTC (permalink / raw)
  To: Gerd Hoffmann, Laszlo Ersek; +Cc: edk2-devel@lists.01.org

Hello Gerd,

Thanks a lot for contributing this code. I am quite pleased that we
finally have a solution for the EFI frame buffer for ARM systems
running under KVM.

One comment below.

On 8 June 2018 at 13:39, Gerd Hoffmann <kraxel@redhat.com> wrote:
> 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      | 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 <Uefi.h>
> +#include <Protocol/GraphicsOutput.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/FrameBufferBltLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootManagerLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/QemuFwCfgLib.h>
> +
> +#include <Guid/QemuRamfb.h>
> +
> +#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);

EfiRuntimeServicesMemory is special in the sense that it gets added to
the page tables that are installed while UEFI runtime services are
being invoked by the OS. Given that the runtime firmware does not care
about this frame buffer, this is unnecessary, and so I'd rather avoid
it. The proper fix /could/ be to use EfiRuntimeServicesMemory with the
EFI_MEMORY_RUNTIME attribute cleared, but sadly, edk2 does not
implement that at all. So instead, I recommend using
EfiReservedMemoryType here.

(The spec may argue that you should never use it, but it also
recommends that, e.g., SMBIOS tables are put in
EfiRuntimeServicesMemory with the EFI_MEMORY_RUNTIME attribute
cleared, so it is obviously not in sync with reality)

Thanks,
Ard.


> +  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
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


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

* Re: [PATCH 1/4] OvmfPkg: add QEMU_RAMFB_GUID
  2018-06-08 11:39 ` [PATCH 1/4] OvmfPkg: add QEMU_RAMFB_GUID Gerd Hoffmann
@ 2018-06-11 13:06   ` Laszlo Ersek
  0 siblings, 0 replies; 18+ messages in thread
From: Laszlo Ersek @ 2018-06-11 13:06 UTC (permalink / raw)
  To: Gerd Hoffmann, edk2-devel

Hi Gerd,

On 06/08/18 13:39, Gerd Hoffmann wrote:
> Add GUID header file for the QemuRamfbDxe driver.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Gerd Hoffmann <kraxel@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..878224599d
> --- /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 \
> +{0x837dca9e, 0xe874, 0x4d82, {0xb2, 0x9a, 0x23, 0xfe, 0x0e, 0x23, 0xd1, 0xe2}}
> +
> +extern EFI_GUID gQemuRamfbGuid;
> +
> +#endif
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index dc5597db41..a16c22a289 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                      = {0x837dca9e, 0xe874, 0x4d82, {0xb2, 0x9a, 0x23, 0xfe, 0x0e, 0x23, 0xd1, 0xe2}}
>    gXenBusRootDeviceGuid               = {0xa732241f, 0x383d, 0x4d9c, {0x8a, 0xe1, 0x8e, 0x09, 0x83, 0x75, 0x89, 0xd7}}
>    gRootBridgesConnectedEventGroupGuid = {0x24a2d66f, 0xeedd, 0x4086, {0x90, 0x42, 0xf2, 0x6e, 0x47, 0x97, 0xee, 0x69}}
>  
> 

this patch is all good, formally speaking, but you should please
generate a new GUID with "uuidgen", rather than using the one from
"VirtioMmioTransport.h" :)

Thanks!
Laszlo


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

* Re: [PATCH 2/4] OvmfPkg: add QemuRamfbDxe
  2018-06-08 11:39 ` [PATCH 2/4] OvmfPkg: add QemuRamfbDxe Gerd Hoffmann
  2018-06-10  5:57   ` Ard Biesheuvel
@ 2018-06-11 15:56   ` Laszlo Ersek
  2018-06-12  9:15     ` Gerd Hoffmann
  1 sibling, 1 reply; 18+ messages in thread
From: Laszlo Ersek @ 2018-06-11 15:56 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: edk2-devel

On 06/08/18 13:39, Gerd Hoffmann wrote:

> 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 <Uefi.h>

(1) I think we should be able to drop this. See the leading comment in
"MdePkg/Include/Uefi.h" -- and this is not a UEFI_DRIVER but a platform
DXE_DRIVER module.

> +#include <Protocol/GraphicsOutput.h>
> +
> +#include <Library/BaseMemoryLib.h>

OK, ZeroMem() is from this one.

> +#include <Library/DebugLib.h>

OK, DEBUG() needs this.

> +#include <Library/DevicePathLib.h>

OK, AppendDevicePathNode().

> +#include <Library/FrameBufferBltLib.h>

OK, FrameBufferBltConfigure().

> +#include <Library/MemoryAllocationLib.h>

OK, AllocateCopyPool().

> +#include <Library/UefiBootManagerLib.h>

(2) I think we can drop this. (Please also remove it from the
[LibraryClasses] section in the INF file.)

> +#include <Library/UefiBootServicesTableLib.h>

OK, gBS->InstallMultipleProtocolInterfaces().

> +#include <Library/UefiDriverEntryPoint.h>

(3) Well, strictly speaking, this isn't necessary as an #include -- the
corresponding lib class under [LibraryClasses] *is* necessary though.

I've grepped the tree for this #include directive, and usage is
inconsistent. In new drivers we introduce, I prefer that we not add the
include. Can you please drop it? (Again, do keep it in the INF file.)

> +#include <Library/UefiLib.h>

(4) I tried to see if we use anything from UefiLib.h, and came up empty.
Can you please attempt to drop it both here and from [LibraryClasses] in
the INF file?

> +#include <Library/QemuFwCfgLib.h>

Yup, needed.

> +
> +#include <Guid/QemuRamfb.h>
> +
> +#define RAMFB_FORMAT  0x34325258 /* DRM_FORMAT_XRGB8888 */
> +#define RAMFB_BPP     4
> +
> +EFI_GUID gQemuRamfbGuid = QEMU_RAMFB_GUID;

(5) Please drop this -- we have the declaration of gQemuRamfbGuid from
<Guid/QemuRamfb.h>, and the definition comes from source code
auto-generated by the build tools.

(I'll comment more on the usage below.)

> +
> +typedef struct RAMFB_CONFIG {
> +  UINT64 Address;
> +  UINT32 FourCC;
> +  UINT32 Flags;
> +  UINT32 Width;
> +  UINT32 Height;
> +  UINT32 Stride;
> +} RAMFB_CONFIG;

(6) Please wrap this in:

#pragma pack (1)
...
#pragma pack ()

(7) We could also add this type definition in a new file
"OvmfPkg/Include/IndustryStandard/QemuRamfbConfig.h". However, I do
realize that's somewhat overkill. Up to you; I don't mind if we keep it
here.

> +
> +EFI_HANDLE                    RamfbHandle;
> +EFI_HANDLE                    GopHandle;
> +FRAME_BUFFER_CONFIGURE        *QemuRamfbFrameBufferBltConfigure;
> +UINTN                         QemuRamfbFrameBufferBltConfigureSize;

(8) Please make all these variables STATIC, and also prepend an "m"
prefix to their names (it stands for "module"):

STATIC EFI_HANDLE                    mRamfbHandle;

> +
> +EFI_GRAPHICS_OUTPUT_MODE_INFORMATION QemuRamfbModeInfo[] = {

(9) Same comment as (8).

> +  {
> +    .HorizontalResolution  = 640,
> +    .VerticalResolution    = 480,
> +  },{
> +    .HorizontalResolution  = 800,
> +    .VerticalResolution    = 600,
> +  },{
> +    .HorizontalResolution  = 1024,
> +    .VerticalResolution    = 768,
> +  }
> +};

(10) In edk2 we cannot use designated initializers. I suggest (for
example) assigning these values in the entry point function.

Alternatively, please use the C90-style syntax for aggregate
initialization (i.e. just insert enough zeros):

STATIC EFI_GRAPHICS_OUTPUT_MODE_INFORMATION QemuRamfbModeInfo[] = {
  {
    0,   // Version
    640, // HorizontalResolution
    400, // VerticalResolution
    0,   // PixelFormat -- filled in later
    0,   // PixelInformation -- will be ignored
    0    // PixelsPerScanLine -- filled in later
  },
  ...
};

> +#define QemuRamfbModeCount (sizeof(QemuRamfbModeInfo)/sizeof(QemuRamfbModeInfo[0]))

(11) Please use ARRAY_SIZE() instead, wherever necessary.

> +
> +EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE QemuRamfbMode = {
> +  .MaxMode               = QemuRamfbModeCount,
> +  .Mode                  = 0,
> +  .Info                  = QemuRamfbModeInfo,
> +  .SizeOfInfo            = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
> +};

(12) See (10).

(13) Please insert a space between "sizeof" and "(". In edk2, we put one
space between function identifier / function-like macro name, and the
opening paren, in function calls / macro invocations.

(Obviously, I know that "sizeof" is neither a function nor a macro; it
is an operator. In fact my preferred style is just "sizeof object", no
parens. However, if we use the parens, which is indeed required for
typenames, then we should use one space.)

> +
> +EFI_STATUS
> +EFIAPI
> +QemuRamfbGraphicsOutputQueryMode (

(14) Please also make all functions STATIC, except InitializeQemuRamfb().

> +  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) {

(15) I think the ModeNumber comparison is off-by-one; equality should be
rejected too.

> +    return EFI_INVALID_PARAMETER;
> +  }
> +  ModeInfo = &QemuRamfbModeInfo[ModeNumber];
> +
> +  *Info = AllocateCopyPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
> +                            ModeInfo);

(16) The indentation is incorrect; "ModeInfo" should start 2 colums to
the right of the "A" in AllocateCopyPool().

In general, in edk2 there are two accepted indentation styles for
function calls that extend to multiple lines:

variant #1: all arguments (including the first one) on separate lines,
with the closing paren also on a separate line:

  Status = StructPointer->Function (
                            Arg1,
                            Arg2,
                            Arg3
                            );

variant #2: filling horizontal space with arguments up to column 80; and
whenever a line break is needed, stick with the same indentation as seen
in variant #1. The closing paren is not broken to a separate line.

  Status = StructPointer->Function (LongArgumentOne, LongArgumentTwo,
                            LongArgumentThree, LongArgumentFour);

For both styles, if StructPointer doesn't exist, then the indentation
remains the same, relatively speaking, anchored to "Function".

> +  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;

(17) We generally call such variables "Status".

> +  FIRMWARE_CONFIG_ITEM                  Item;
> +  UINTN                                 Size;
> +
> +  if (ModeNumber > QemuRamfbMode.MaxMode) {
> +    return EFI_UNSUPPORTED;
> +  }

(18) See (15).

> +  ModeInfo = &QemuRamfbModeInfo[ModeNumber];
> +
> +  DEBUG ((EFI_D_INFO, "Ramfb: SetMode %d (%dx%d)\n", ModeNumber,

(19) We've stopped adding EFI_D_* macros; instead we use DEBUG_* macros
in new code.

(20) Please print UINT32 values with "%u" rather than "%d".

> +          ModeInfo->HorizontalResolution,
> +          ModeInfo->VerticalResolution));

(21) Please see (16).

> +
> +  QemuRamfbMode.Mode = ModeNumber;
> +  QemuRamfbMode.Info = ModeInfo;
> +
> +  Config.Address = SwapBytes64( QemuRamfbMode.FrameBufferBase );

(22) Please #include <BaseLib.h> for SwapBytes*(); also please add it to
[LibraryClasses] in the INF file.

(23) The space characters near the parens are not idiomatic; we'd use

  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);

(24) You perform the same lookup in the entry point function; can you
please cache the selector value ("Item") in a new

  STATIC FIRMWARE_CONFIG_ITEM mRamFbFwCfgItem;

global variable? And then use that here.

Furthermore, instead of Size, you can use "sizeof Config".

> +  QemuFwCfgSelectItem(Item);
> +  QemuFwCfgWriteBytes(sizeof(Config), &Config);

(25) (several counts:) please see (13).

> +
> +  Ret = FrameBufferBltConfigure (
> +    (VOID*)(UINTN)QemuRamfbMode.FrameBufferBase,
> +    ModeInfo,
> +    QemuRamfbFrameBufferBltConfigure,
> +    &QemuRamfbFrameBufferBltConfigureSize);

(26) Please see (16).

> +
> +  if (Ret == RETURN_BUFFER_TOO_SMALL) {
> +    if (QemuRamfbFrameBufferBltConfigure != NULL) {
> +      FreePool(QemuRamfbFrameBufferBltConfigure);

(27) Please see (13).

> +    }
> +    QemuRamfbFrameBufferBltConfigure =
> +      AllocatePool(QemuRamfbFrameBufferBltConfigureSize);

(28) Please see (13).

(29) Please reorganize the function as follows: this AllocatePool() call
should be moved near the top, so that, if it fails, we can return
EFI_OUT_OF_RESOURCES without actually changing fw_cfg or any of the
GOP-related data structures. Then, please check the return value for NULL.

My understanding is that QemuRamfbMode.FrameBufferBase is invariant (=
independent of the mode requested), after the initial setup, so this
should be possible.

> +
> +    Ret = FrameBufferBltConfigure (
> +      (VOID*)(UINTN)QemuRamfbMode.FrameBufferBase,
> +      ModeInfo,
> +      QemuRamfbFrameBufferBltConfigure,
> +      &QemuRamfbFrameBufferBltConfigureSize);
> +  }

(30) Please see (16).

(31) At this point, "Ret" (well, "Status") must either be RETURN_SUCCESS
or RETURN_UNSUPPORTED. Please add:

  if (RETURN_ERROR (Status)) {
    ASSERT (Status == RETURN_UNSUPPORTED);
    return Status;
  }

> +
> +  /* clear screen */

(32) The edk2 style for such comments is:

  //
  // clear screen
  //

> +  ZeroMem (&Black, sizeof (Black));
> +  Ret = FrameBufferBlt (
> +    QemuRamfbFrameBufferBltConfigure,
> +    &Black,
> +    EfiBltVideoFill,
> +    0, 0,
> +    0, 0,
> +    ModeInfo->HorizontalResolution,
> +    ModeInfo->VerticalResolution,
> +    0
> +    );

(33) We've got a load of arguments here, can we please do:

  Status = FrameBufferBlt (
             QemuRamfbFrameBufferBltConfigure,
             &Black,
             EfiBltVideoFill,
             0,                                // SourceX -- ignored
             0,                                // SourceY -- ignored
             0,                                // DestinationX
             0,                                // DestinationY
             ModeInfo->HorizontalResolution,   // Width
             ModeInfo->VerticalResolution,     // Height
             0                                 // Delta -- ignored
             );

(34) I agree that this call should never fail, and even if it does, we
should still return EFI_SUCCESS about the mode change. But, it might be
nice to log a debug message on failure, such as:

  DEBUG ((DEBUG_WARN, "%a: clearing the screen failed: %r\n",
    __FUNCTION__, Status));

> +
> +  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);
> +}

(35) Please see (16).

> +
> +EFI_GRAPHICS_OUTPUT_PROTOCOL QemuRamfbGraphicsOutput = {
> +  .QueryMode        = QemuRamfbGraphicsOutputQueryMode,
> +  .SetMode          = QemuRamfbGraphicsOutputSetMode,
> +  .Blt              = QemuRamfbGraphicsOutputBlt,
> +  .Mode             = &QemuRamfbMode,
> +};

(36) Please see (10).

> +
> +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;

Another background story... EFI_STATUS is for (a) anything defined in
the Platform Init and UEFI specifications, (b) library classes that are
meant to be used *solely* in modules defined by those specifications.

RETURN_STATUS is for libraries that are lower-level than those, at least
conceptually; in other words, if they provide functionality that is
independent of client module type ("BASE" libraries). In theory such
libraries are OK to use in SEC modules even.

Technically, there isn't any difference between these types and their
values, however. Thus, if you have a function in which you already have
an EFI_STATUS local variable (for storing EFI_STATUS values), you can
freely store RETURN_STATUS retvals to it as well. If you only assign
RETURN_STATUS values, then it's more idiomatic to use RETURN_STATUS.
(Which is what you do in QemuRamfbGraphicsOutputSetMode(), correctly.)

For RETURN_STATUS variables, we have macros such as:
- RETURN_ERROR (Status)
- ASSERT_RETURN_ERROR (Status)

For EFI_STATUS variables, we have the same, just replace RETURN with EFI.

(37) So, I suggest dropping "Ret", and just using Status.

> +  FIRMWARE_CONFIG_ITEM      Item;

(38) See (24).

> +  EFI_PHYSICAL_ADDRESS      FbBase;
> +  UINTN                     Size, FbSize, MaxFbSize, Pages, Index;

(39) I know it's annoying, but please break at least *some* of those to
separate declarations. I guess keeping "FbSize" and "MaxFbSize" on the
same line makes sense.

Furthermore, "Size" should be called "FwCfgSize" (for clarity).

> +
> +  DEBUG ((EFI_D_INFO, "InitializeQemuRamfb\n"));

(40) Please see (19). (There are some more occurrences below.)

(41) Also, I suggest using "%a" with __FUNCTION__.

> +
> +  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;
> +  }

(42) For whatever reason, the idiomatic spelling for the comparison is

  if (EFI_ERROR (Status)) {
    ...
  }

(43) You might want to drop the debug message for this case, as in most
setups, I expect ramfb will not be present; plus, if the driver exits
with an error code, the DXE core will log that anyway. If you'd really
like to keep the message, I suggest DEBUG_VERBOSE.

(44) If the lookup succeeds, please compare "FwCfgSize" against sizeof
(RAMFB_CONFIG). In case of mismatch, log an error (DEBUG_ERROR) and exit.

> +
> +  MaxFbSize = 0;
> +  for (Index = 0; Index < QemuRamfbModeCount; Index++) {
> +    QemuRamfbModeInfo[Index].PixelsPerScanLine =
> +      QemuRamfbModeInfo[Index].HorizontalResolution;
> +    QemuRamfbModeInfo[Index].PixelFormat =
> +      PixelBlueGreenRedReserved8BitPerColor,

(45) Nice use of the comma operator :) but I think it may not be
intended. Please let's stick with the semicolon.

> +    FbSize = RAMFB_BPP *
> +      QemuRamfbModeInfo[Index].HorizontalResolution *
> +      QemuRamfbModeInfo[Index].VerticalResolution;
> +    if (MaxFbSize < FbSize)
> +      MaxFbSize = FbSize;

(46) The edk2 coding style requires braces.

> +    DEBUG ((EFI_D_INFO, "Ramfb: Mode %d: %dx%d, %d kB\n", Index,
> +            QemuRamfbModeInfo[Index].HorizontalResolution,
> +            QemuRamfbModeInfo[Index].VerticalResolution,
> +            FbSize / 1024));
> +  }

(47) indentation, please see (16).

(48) For printing UINTN values portably across 32-bit and 64-bit builds,
the safest way is to cast the variable to UINT64, and then print it with
"%Lu" (or, if you like hex, "%Lx").

This refers to both "Index" and "FbSize".

(Also, feel free to use lower-case "l" in place of my suggested
upper-case "L"; in edk2 they are interchangeable for printing integers.
I just dislike lower-case "l" because in ISO C, it stands for "long",
whereas "L" is not defined in ISO C for integers. I think that makes "L"
a better fit for a non-standard purpose such as "print UINT64". And, no,
edk2 does not have PRIx64.)

(49) EFI_D_*, please see (19)

(50) Please see (20) as well, for printing the resolutions.

> +
> +  Pages = EFI_SIZE_TO_PAGES(MaxFbSize);
> +  MaxFbSize = EFI_PAGES_TO_SIZE(Pages);
> +  FbBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRuntimePages(Pages);

(51) Multiple instances of (13).

(52) What Ard said about runtime allocations.

Please call AllocateReservedPages() instead.

> +  if (!FbBase) {

(53) In edk2, we only use the logical negation operator (!) for
BOOLEANs. Please compare FbBase against 0 explicitly.

> +    DEBUG ((EFI_D_INFO, "Ramfb: memory allocation failed\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }

(54) please see (19).

> +  DEBUG ((EFI_D_INFO, "Ramfb: Framebuffer at 0x%lx, %d kB, %d pages\n",
> +          FbBase, MaxFbSize / 1024, Pages));

(55) Please see (48) for "MaxFbSize / 1024" and "Pages".

> +  QemuRamfbMode.FrameBufferSize = MaxFbSize;
> +  QemuRamfbMode.FrameBufferBase = FbBase;
> +
> +  /* 800 x 600 */
> +  QemuRamfbGraphicsOutputSetMode (&QemuRamfbGraphicsOutput, 1);
> +
> +  /* ramfb vendor devpath */

(56) Please refer to (32); two instances above.

> +  ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));
> +  VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;
> +  VendorDeviceNode.Header.SubType = HW_VENDOR_DP;
> +  VendorDeviceNode.Guid = gQemuRamfbGuid;

(57) Unfortunately, structure assignment is forbidden in edk2; please
use the CopyGuid() function from BaseMemoryLib. See more below.

> +  SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));

(58) This line seems overlong (82 characters); please stick with 80 chars.

(59) I think you've filled in all members of VendorDeviceNode; can you
drop the ZeroMem()?

> +
> +  RamfbDevicePath = AppendDevicePathNode (
> +    NULL,
> +    (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode);
> +

(60) Please see (16).

(61) Please check the return value. AppendDevicePathNode() allocates
memory dynamically. If it fails, we should roll back earlier operations
(if any) and exit with EFI_OUT_OF_RESOURCES.

> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +    &RamfbHandle,
> +    &gEfiDevicePathProtocolGuid, RamfbDevicePath,
> +    NULL);

(62) Please see (16).

> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_INFO, "Ramfb: install Ramfb Vendor DevicePath failed\n"));

(63) We should use DEBUG_ERROR here.

(64) In such cases it is helpful to print Status too; please use the
"%r" format specifier for that.

> +    FreePool((VOID*)(UINTN)QemuRamfbMode.FrameBufferBase);

(65) Please see (13).

> +    return Status;

(65) This leaks two objects:

- the RamfbHandle handle created with
gBS->InstallMultipleProtocolInterfaces(),

- the RamfbDevicePath devpath created with AppendDevicePathNode().

In edk2 we like the "cascading error path", with several labels and goto
statements; I suggest we put it to use as well. On the error path, we
should tear down resources in reverse order of construction, as usual:

- in UEFI, a handle is created when the first protocol interface is
installed on an initially NULL handle; and a handle destroyed when the
last protocol interface is uninstalled from it.

Common pitfall: InstallMultipleProtocolInterfaces() takes a *pointer to*
a handle (because if the handle is NULL on input, the function wants to
store the new handle on output); however,
UninstallMultipleProtocolInterfaces() takes the handle itself! Be
careful with the address-of ("&") operator.

- "RamfbDevicePath" should be freed with FreePool().

> +  }
> +
> +  /* gop devpath + protocol */

(66) please see (32).

> +  ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));

(67) Does (59) apply here?

> +  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);

(68) Please add comments to the individual arguments. Example:
"OvmfPkg/VirtioGpuDxe/DriverBinding.c", the initializer of "mAcpiAdr".

> +  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;
> +  }

(69) Same comments as (60) through (65).

> +
> +  gBS->OpenProtocol (
> +    RamfbHandle,
> +    &gEfiDevicePathProtocolGuid,
> +    &DevicePath,
> +    gImageHandle,
> +    GopHandle,
> +    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);

(70) Please see (16).

(71) Please check the return status. If the call fails, please roll back
the earlier actions and propagate the error out of the entry point function.

> +
> +  return EFI_SUCCESS;
> +}

> 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 @@

(72) Here's a shared request for both new files ("QemuRamfb.c" and
"QemuRamfbDxe.inf"): please refer to the standard .c and .inf file
"banners" for example under OvmfPkg/VirtioGpuDxe. Files should start with:
- a @file comment that briefly states what the file is good for,
- a list of copyright notices,
- the copyright license / reference (2-clause BSDL usually).

> +[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

(73) We can simply say [Sources] here.

> +
> +[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

(74) The "BY_START" protocol usage comment is incorrect here, because
we're not producing instances of the protocol in a DriverBindingStart()
function. (In other words, the driver is not a UEFI_DRIVER that conforms
to the UEFI driver model, instead it's a platform DXE driver.) Please
use the comment "## PRODUCES" (you can also drop "PROTOCOL").

(75) In turn, is where I refer back to (5) and (57). Please add a
section like this:

[Guids]
  gQemuRamfbGuid

This will ensure that the build utilities generate a "gQemuRamfbGuid"
*definition* (not just a declaration) for you.

> +
> +[Depex]
> +  TRUE
> 

I realize this review ended up quite long and tedious. I think (hope!)
that you're going to contribute to edk2 in the longer term, thus I
intended to use this opportunity to spell out idioms and such that might
apply to your future patches too.

Thank you!
Laszlo


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

* Re: [PATCH 3/4] OvmfPkg: add QemuRamfb to platform console
  2018-06-08 11:39 ` [PATCH 3/4] OvmfPkg: add QemuRamfb to platform console Gerd Hoffmann
@ 2018-06-11 16:24   ` Laszlo Ersek
  2018-06-11 16:58     ` Laszlo Ersek
  0 siblings, 1 reply; 18+ messages in thread
From: Laszlo Ersek @ 2018-06-11 16:24 UTC (permalink / raw)
  To: Gerd Hoffmann, edk2-devel

On 06/08/18 13:39, Gerd Hoffmann wrote:
> 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.

This explanation is not wrong, but I'll list more details, just in case.

By adding the devpath to "gPlatformConsole" with CONSOLE_OUT,
technically we push the devpath into the ConOut UEFI variable, as
follows:

  BdsEntry()                                  [MdeModulePkg/Universal/BdsDxe/BdsEntry.c]
    PlatformBootManagerBeforeConsole()        [OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c]
      PlatformInitializeConsole()             [OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c]
        EfiBootManagerUpdateConsoleVariable() [MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c]

After this, BdsEntry goes on to actually connect the device (i.e., it
makes the QemuRamfbDxe driver bind the device):

  BdsEntry()                                  [MdeModulePkg/Universal/BdsDxe/BdsEntry.c]
    EfiBootManagerConnectAllDefaultConsoles() [MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c]

Binding drivers to keyboard, serial and graphics devices, so that text
input, text output, and graphics output protocols are produced, isn't
per se sufficient for ConSplitterDxe to multiplex to/from those
protocols. For that, ConPlatformDxe needs to "tag" the handles with
EfiConsole(In|Out)DeviceGuid|EfiStandardErrorDeviceGuid --
ConSplitterDxe depends on those protocols. It's ConPlatformDxe that
needs the devpath to be in ConIn/ConOut/ErrOut, for the "tagging" to
occur.

In total, we add the ramfb devpath to "gPlatformConsole" so that our
PlatformInitializeConsole() function puts it in ConOut, despite ramfb
not being a PCI display device. Binding the device to QemuRamFbDxe, and
multiplexing from/to it happen "automatically" from there, thanks to
BdsDxe, and ConPlatformDxe/ConSplitterDxe respectively.

(1) I don't mind if you stick with the current commit message; I just
wanted to provide more details for this discussion.

More comments below:

>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  .../Library/PlatformBootManagerLib/PlatformData.c  | 44 ++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
>
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
> index a50cd7bcaf..6202516971 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()

(2) Please add a space character between each "pack" and "(".

> +
>  ACPI_HID_DEVICE_PATH       gPnpPs2KeyboardDeviceNode  = gPnpPs2Keyboard;
>  ACPI_HID_DEVICE_PATH       gPnp16550ComPortDeviceNode = gPnp16550ComPort;
>  UART_DEVICE_PATH           gUartDeviceNode            = gUart;
> @@ -100,6 +112,34 @@ 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, 0, 0, 1, 0,
> +                      ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL,
> +                      0, 0)

(3) Urgh. On one hand, I dislike this dump of constants; on the other
hand, I don't want to ask you to repeat all the parameter comments that
I asked for in the previous patch.

OK, let's stick with the dump of constants, just make sure the
indentation is idiomatic.

> +  },
> +  gEndEntire
> +};
> +
>  //
>  // Predefined platform default console device path
>  //
> @@ -113,6 +153,10 @@ PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {
>      CONSOLE_IN
>    },
>    {
> +    (EFI_DEVICE_PATH_PROTOCOL *)&gQemuRamfbDevicePath,
> +    CONSOLE_OUT
> +  },

Right, this is consistent with PreparePciDisplayDevicePath().

Thanks,
Laszlo

> +  {
>      NULL,
>      0
>    }
>



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

* Re: [PATCH 4/4] ArmVirtPkg: add QemuRamfbDxe
  2018-06-08 11:39 ` [PATCH 4/4] ArmVirtPkg: add QemuRamfbDxe Gerd Hoffmann
@ 2018-06-11 16:29   ` Laszlo Ersek
  0 siblings, 0 replies; 18+ messages in thread
From: Laszlo Ersek @ 2018-06-11 16:29 UTC (permalink / raw)
  To: Gerd Hoffmann, edk2-devel

On 06/08/18 13:39, Gerd Hoffmann wrote:
> Build wireup for ArmVirt.

Ard requested earlier that we include the meaning of the subject line in
the body of the commit message as well, so that the commit message can
be sensibly read without looking at the subject line.

With a bit more elaboration like that:

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

Thanks!
Laszlo

> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Gerd Hoffmann <kraxel@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
>  
> 



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

* Re: [PATCH 0/4] Add QemuRamfbDxe driver
  2018-06-08 11:39 [PATCH 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2018-06-08 11:39 ` [PATCH 4/4] ArmVirtPkg: add QemuRamfbDxe Gerd Hoffmann
@ 2018-06-11 16:35 ` Laszlo Ersek
  2018-06-12  9:21   ` Gerd Hoffmann
  4 siblings, 1 reply; 18+ messages in thread
From: Laszlo Ersek @ 2018-06-11 16:35 UTC (permalink / raw)
  To: Gerd Hoffmann, edk2-devel

On 06/08/18 13:39, Gerd Hoffmann wrote:
> This is the efi driver for qemu ramfb, a simple boot framebuffer.
> Qemu patches just have been posted to qemu-devel.
> 
> 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  |  44 +++
>  OvmfPkg/QemuRamfbDxe/QemuRamfb.c                   | 308 +++++++++++++++++++++
>  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              |  34 +++
>  14 files changed, 423 insertions(+)
>  create mode 100644 OvmfPkg/Include/Guid/QemuRamfb.h
>  create mode 100644 OvmfPkg/QemuRamfbDxe/QemuRamfb.c
>  create mode 100644 OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
> 

Some testing related questions:

- What happens in the UEFI shell if you do recursive connect/disconnect
cycles for all handles in the system? (Preferably initiated from serial.)

- What happens if you locate the parent handle (with the VenHw node)
and/or the child handle (with the GOP on it), and try to disconnect them?

- Have you tested mode changes with the MODE command?

Expected results:

- recursive connect / disconnect should not break, as far as the entire
system is concerned; the procedure should simply skip ramfb.

- targeted connect / disconnect for ramfb should fail (produce an error
message), but nothing should crash or stop working.

- mode changes should work.

I expect the first two behaviors because the driver is a platform DXE
driver, not a UEFI driver that conforms to the UEFI driver model -- we
don't install an EFI_DRIVER_BINDING_PROTOCOL instance, hence the driver
should be "invisible" to the connect / disconnect UEFI shell commands
(they should fail gracefully).

Thanks,
Laszlo


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

* Re: [PATCH 3/4] OvmfPkg: add QemuRamfb to platform console
  2018-06-11 16:24   ` Laszlo Ersek
@ 2018-06-11 16:58     ` Laszlo Ersek
  0 siblings, 0 replies; 18+ messages in thread
From: Laszlo Ersek @ 2018-06-11 16:58 UTC (permalink / raw)
  To: Gerd Hoffmann, edk2-devel

On 06/11/18 18:24, Laszlo Ersek wrote:
> On 06/08/18 13:39, Gerd Hoffmann wrote:
>> 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.
> 
> This explanation is not wrong, but I'll list more details, just in case.
> 
> By adding the devpath to "gPlatformConsole" with CONSOLE_OUT,
> technically we push the devpath into the ConOut UEFI variable, as
> follows:
> 
>   BdsEntry()                                  [MdeModulePkg/Universal/BdsDxe/BdsEntry.c]
>     PlatformBootManagerBeforeConsole()        [OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c]
>       PlatformInitializeConsole()             [OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c]
>         EfiBootManagerUpdateConsoleVariable() [MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c]
> 
> After this, BdsEntry goes on to actually connect the device (i.e., it
> makes the QemuRamfbDxe driver bind the device):
> 
>   BdsEntry()                                  [MdeModulePkg/Universal/BdsDxe/BdsEntry.c]
>     EfiBootManagerConnectAllDefaultConsoles() [MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c]
> 
> Binding drivers to keyboard, serial and graphics devices, so that text
> input, text output, and graphics output protocols are produced, isn't
> per se sufficient for ConSplitterDxe to multiplex to/from those
> protocols. For that, ConPlatformDxe needs to "tag" the handles with
> EfiConsole(In|Out)DeviceGuid|EfiStandardErrorDeviceGuid --
> ConSplitterDxe depends on those protocols. It's ConPlatformDxe that
> needs the devpath to be in ConIn/ConOut/ErrOut, for the "tagging" to
> occur.
> 
> In total, we add the ramfb devpath to "gPlatformConsole" so that our
> PlatformInitializeConsole() function puts it in ConOut, despite ramfb
> not being a PCI display device. Binding the device to QemuRamFbDxe, and
> multiplexing from/to it happen "automatically" from there, thanks to
> BdsDxe, and ConPlatformDxe/ConSplitterDxe respectively.

Whoops, managed to confuse myself a little here; some correction should
be in order:

The ramfb driver does not follow the UEFI driver model. The GOP is
produced right in the entry point of the driver, not when platform BDS
connects the device.

It remains true however that ConPlatformDxe / ConSplitterDxe, which do
follow the UEFI driver model, bind the GOP in
EfiBootManagerConnectAllDefaultConsoles(). I guess I would re-formulate,

"""
In total, we add the ramfb devpath to "gPlatformConsole" so that our
PlatformInitializeConsole() function puts it in ConOut, despite ramfb
not being a PCI display device. Multiplexing from/to the ramfb GOP
happens "automatically" from there, thanks to
ConPlatformDxe/ConSplitterDxe.
"""

Which is basically what the current commit message says. :)

Sorry for any confusion caused!
Laszlo

> 
> (1) I don't mind if you stick with the current commit message; I just
> wanted to provide more details for this discussion.
> 
> More comments below:
> 
>>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>> ---
>>  .../Library/PlatformBootManagerLib/PlatformData.c  | 44 ++++++++++++++++++++++
>>  1 file changed, 44 insertions(+)
>>
>> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c
>> index a50cd7bcaf..6202516971 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()
> 
> (2) Please add a space character between each "pack" and "(".
> 
>> +
>>  ACPI_HID_DEVICE_PATH       gPnpPs2KeyboardDeviceNode  = gPnpPs2Keyboard;
>>  ACPI_HID_DEVICE_PATH       gPnp16550ComPortDeviceNode = gPnp16550ComPort;
>>  UART_DEVICE_PATH           gUartDeviceNode            = gUart;
>> @@ -100,6 +112,34 @@ 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, 0, 0, 1, 0,
>> +                      ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL,
>> +                      0, 0)
> 
> (3) Urgh. On one hand, I dislike this dump of constants; on the other
> hand, I don't want to ask you to repeat all the parameter comments that
> I asked for in the previous patch.
> 
> OK, let's stick with the dump of constants, just make sure the
> indentation is idiomatic.
> 
>> +  },
>> +  gEndEntire
>> +};
>> +
>>  //
>>  // Predefined platform default console device path
>>  //
>> @@ -113,6 +153,10 @@ PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {
>>      CONSOLE_IN
>>    },
>>    {
>> +    (EFI_DEVICE_PATH_PROTOCOL *)&gQemuRamfbDevicePath,
>> +    CONSOLE_OUT
>> +  },
> 
> Right, this is consistent with PreparePciDisplayDevicePath().
> 
> Thanks,
> Laszlo
> 
>> +  {
>>      NULL,
>>      0
>>    }
>>
> 



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

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

  Hi,

> > +  {
> > +    .HorizontalResolution  = 640,
> > +    .VerticalResolution    = 480,
> > +  },{
> > +    .HorizontalResolution  = 800,
> > +    .VerticalResolution    = 600,
> > +  },{
> > +    .HorizontalResolution  = 1024,
> > +    .VerticalResolution    = 768,
> > +  }
> > +};
> 
> (10) In edk2 we cannot use designated initializers. I suggest (for
> example) assigning these values in the entry point function.

Really?  C99 is almost 20 years old now ...
Are there compilers left without C99 support which edk2 still supports?

> In general, in edk2 there are two accepted indentation styles for
> function calls that extend to multiple lines:
> 
> variant #1: all arguments (including the first one) on separate lines,
> with the closing paren also on a separate line:
> 
>   Status = StructPointer->Function (
>                             Arg1,
>                             Arg2,
>                             Arg3
>                             );

Hmm, pretty unusual, which is bad for editor auto-indent support.
Anyone knows tricks to teack emacs that style?

cheers,
  Gerd



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

* Re: [PATCH 0/4] Add QemuRamfbDxe driver
  2018-06-11 16:35 ` [PATCH 0/4] Add QemuRamfbDxe driver Laszlo Ersek
@ 2018-06-12  9:21   ` Gerd Hoffmann
  2018-06-12 12:53     ` Laszlo Ersek
  0 siblings, 1 reply; 18+ messages in thread
From: Gerd Hoffmann @ 2018-06-12  9:21 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel

  Hi,

> - What happens in the UEFI shell if you do recursive connect/disconnect
> cycles for all handles in the system? (Preferably initiated from serial.)

Seems to work fine (tried "disconnect -a" and "connect").

> - What happens if you locate the parent handle (with the VenHw node)
> and/or the child handle (with the GOP on it), and try to disconnect them?

How can I do that?

> - Have you tested mode changes with the MODE command?

Yes, works.

cheers,
  Gerd



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

* Re: [PATCH 0/4] Add QemuRamfbDxe driver
  2018-06-12  9:21   ` Gerd Hoffmann
@ 2018-06-12 12:53     ` Laszlo Ersek
  2018-06-13  7:40       ` Gerd Hoffmann
  0 siblings, 1 reply; 18+ messages in thread
From: Laszlo Ersek @ 2018-06-12 12:53 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: edk2-devel

On 06/12/18 11:21, Gerd Hoffmann wrote:
>   Hi,
> 
>> - What happens in the UEFI shell if you do recursive connect/disconnect
>> cycles for all handles in the system? (Preferably initiated from serial.)
> 
> Seems to work fine (tried "disconnect -a" and "connect").

Cool.

> 
>> - What happens if you locate the parent handle (with the VenHw node)
>> and/or the child handle (with the GOP on it), and try to disconnect them?
> 
> How can I do that?

Run "dh -d -v -p GraphicsOutput". The listing will include all handles
(represented by hex identifiers) that carry a GOP. Each handle will also
have its device path protocol instance displayed, in textual
representation, so if there are multiple GOPs, you'll be able to locate
the one produced by QemuRamfbDxe. The listing should also reference the
parent controller handle.

Knowing the hex identifiers for parent and child, experiment with the
"disconnect" command. (See "help disconnect" for syntax.)

>> - Have you tested mode changes with the MODE command?
> 
> Yes, works.

Nice!

Thansk
Laszlo


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

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

On 06/12/18 11:15, Gerd Hoffmann wrote:
>   Hi,
> 
>>> +  {
>>> +    .HorizontalResolution  = 640,
>>> +    .VerticalResolution    = 480,
>>> +  },{
>>> +    .HorizontalResolution  = 800,
>>> +    .VerticalResolution    = 600,
>>> +  },{
>>> +    .HorizontalResolution  = 1024,
>>> +    .VerticalResolution    = 768,
>>> +  }
>>> +};
>>
>> (10) In edk2 we cannot use designated initializers. I suggest (for
>> example) assigning these values in the entry point function.
> 
> Really?  C99 is almost 20 years old now ...
> Are there compilers left without C99 support which edk2 still supports?

Visual Studio has never committed to *full* C99 support, to my
knowledge. I don't know whether VS happens to support designated
initializers specifically; either way, we can't use them in edk2.

... After some googling, I see "signs" that VS >=2013 supports
designated initializers.

However, edk2 targets VS 2003, 2005, 2008, 2010, and 2012 too, before
2013. Refer to "Supported Tool Chains" in
"BaseTools/Conf/tools_def.template".

> 
>> In general, in edk2 there are two accepted indentation styles for
>> function calls that extend to multiple lines:
>>
>> variant #1: all arguments (including the first one) on separate lines,
>> with the closing paren also on a separate line:
>>
>>   Status = StructPointer->Function (
>>                             Arg1,
>>                             Arg2,
>>                             Arg3
>>                             );
> 
> Hmm, pretty unusual,

Yes, very much. I believe this indentation style might originate from
Windows, but I'm not sure.

> which is bad for editor auto-indent support.
> Anyone knows tricks to teack emacs that style?

I don't use emacs, apologies!
Laszlo


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

* Re: [PATCH 0/4] Add QemuRamfbDxe driver
  2018-06-12 12:53     ` Laszlo Ersek
@ 2018-06-13  7:40       ` Gerd Hoffmann
  2018-06-13 16:16         ` Laszlo Ersek
  0 siblings, 1 reply; 18+ messages in thread
From: Gerd Hoffmann @ 2018-06-13  7:40 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel

  Hi,

> >> - What happens if you locate the parent handle (with the VenHw node)
> >> and/or the child handle (with the GOP on it), and try to disconnect them?
> > 
> > How can I do that?
> 
> Run "dh -d -v -p GraphicsOutput". The listing will include all handles
> (represented by hex identifiers) that carry a GOP. Each handle will also
> have its device path protocol instance displayed, in textual
> representation, so if there are multiple GOPs, you'll be able to locate
> the one produced by QemuRamfbDxe. The listing should also reference the
> parent controller handle.
> 
> Knowing the hex identifiers for parent and child, experiment with the
> "disconnect" command. (See "help disconnect" for syntax.)

Shell> dh -p GraphicsOutput
Handle dump by protocol 'GraphicsOutput'
44: ConsoleOut SimpleTextOut GraphicsOutput(GraphicsOutput) DevicePath(..C08C457)/AcpiAdr(0x80010300)) 
6D: GraphicsOutput(GraphicsOutput) SimpleTextOut 
Shell> disconnect 6d
Disconnect - (6D,3E643560,3E5C3A03) Result Success.
Shell> disconnect 44
Disconnect - (44,3E643560,3E5C3A03) Result Success.
Shell> 

The second disconnect makes ovmf stop using ramfb as console (serial continues
to work).

cheers,
  Gerd



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

* Re: [PATCH 0/4] Add QemuRamfbDxe driver
  2018-06-13  7:40       ` Gerd Hoffmann
@ 2018-06-13 16:16         ` Laszlo Ersek
  0 siblings, 0 replies; 18+ messages in thread
From: Laszlo Ersek @ 2018-06-13 16:16 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: edk2-devel

On 06/13/18 09:40, Gerd Hoffmann wrote:
>   Hi,
> 
>>>> - What happens if you locate the parent handle (with the VenHw node)
>>>> and/or the child handle (with the GOP on it), and try to disconnect them?
>>>
>>> How can I do that?
>>
>> Run "dh -d -v -p GraphicsOutput". The listing will include all handles
>> (represented by hex identifiers) that carry a GOP. Each handle will also
>> have its device path protocol instance displayed, in textual
>> representation, so if there are multiple GOPs, you'll be able to locate
>> the one produced by QemuRamfbDxe. The listing should also reference the
>> parent controller handle.
>>
>> Knowing the hex identifiers for parent and child, experiment with the
>> "disconnect" command. (See "help disconnect" for syntax.)
> 
> Shell> dh -p GraphicsOutput
> Handle dump by protocol 'GraphicsOutput'
> 44: ConsoleOut SimpleTextOut GraphicsOutput(GraphicsOutput) DevicePath(..C08C457)/AcpiAdr(0x80010300)) 
> 6D: GraphicsOutput(GraphicsOutput) SimpleTextOut 
> Shell> disconnect 6d
> Disconnect - (6D,3E643560,3E5C3A03) Result Success.
> Shell> disconnect 44
> Disconnect - (44,3E643560,3E5C3A03) Result Success.
> Shell> 
> 
> The second disconnect makes ovmf stop using ramfb as console (serial continues
> to work).

I'll follow up under your v3 series:

  [edk2] [PATCH v3 0/4] Add QemuRamfbDxe driver
  http://mid.mail-archive.com/20180613072936.12480-1-kraxel@redhat.com

Thanks,
Laszlo


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

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

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-08 11:39 [PATCH 0/4] Add QemuRamfbDxe driver Gerd Hoffmann
2018-06-08 11:39 ` [PATCH 1/4] OvmfPkg: add QEMU_RAMFB_GUID Gerd Hoffmann
2018-06-11 13:06   ` Laszlo Ersek
2018-06-08 11:39 ` [PATCH 2/4] OvmfPkg: add QemuRamfbDxe Gerd Hoffmann
2018-06-10  5:57   ` Ard Biesheuvel
2018-06-11 15:56   ` Laszlo Ersek
2018-06-12  9:15     ` Gerd Hoffmann
2018-06-12 13:01       ` Laszlo Ersek
2018-06-08 11:39 ` [PATCH 3/4] OvmfPkg: add QemuRamfb to platform console Gerd Hoffmann
2018-06-11 16:24   ` Laszlo Ersek
2018-06-11 16:58     ` Laszlo Ersek
2018-06-08 11:39 ` [PATCH 4/4] ArmVirtPkg: add QemuRamfbDxe Gerd Hoffmann
2018-06-11 16:29   ` Laszlo Ersek
2018-06-11 16:35 ` [PATCH 0/4] Add QemuRamfbDxe driver Laszlo Ersek
2018-06-12  9:21   ` Gerd Hoffmann
2018-06-12 12:53     ` Laszlo Ersek
2018-06-13  7:40       ` Gerd Hoffmann
2018-06-13 16:16         ` Laszlo Ersek

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