Beispiel #1
0
EFI_STATUS
EFIAPI
QemuVideoGraphicsOutputSetMode (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
  IN  UINT32                       ModeNumber
  )
/*++

Routine Description:

  Graphics Output protocol interface to set video mode

  Arguments:
    This             - Protocol instance pointer.
    ModeNumber       - The mode number to be set.

  Returns:
    EFI_SUCCESS      - Graphics mode was changed.
    EFI_DEVICE_ERROR - The device had an error and could not complete the request.
    EFI_UNSUPPORTED  - ModeNumber is not supported by this device.

--*/
{
  QEMU_VIDEO_PRIVATE_DATA    *Private;
  QEMU_VIDEO_MODE_DATA       *ModeData;
  RETURN_STATUS              Status;

  Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);

  if (ModeNumber >= This->Mode->MaxMode) {
    return EFI_UNSUPPORTED;
  }

  ModeData = &Private->ModeData[ModeNumber];

  switch (Private->Variant) {
  case QEMU_VIDEO_CIRRUS_5430:
  case QEMU_VIDEO_CIRRUS_5446:
    InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->InternalModeIndex]);
    break;
  case QEMU_VIDEO_BOCHS_MMIO:
  case QEMU_VIDEO_BOCHS:
    InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->InternalModeIndex]);
    break;
  default:
    ASSERT (FALSE);
    return EFI_DEVICE_ERROR;
  }

  This->Mode->Mode = ModeNumber;
  This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
  This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
  This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);

  QemuVideoCompleteModeData (Private, This->Mode);

  //
  // Allocate when using first time.
  //
  if (Private->FrameBufferBltConfigure == NULL) {
    Status = FrameBufferBltConfigure (
               (VOID*) (UINTN) This->Mode->FrameBufferBase,
               This->Mode->Info,
               Private->FrameBufferBltConfigure,
               &Private->FrameBufferBltConfigureSize
               );
    ASSERT (Status == RETURN_BUFFER_TOO_SMALL);
    Private->FrameBufferBltConfigure =
      AllocatePool (Private->FrameBufferBltConfigureSize);
  }

  //
  // Create the configuration for FrameBufferBltLib
  //
  ASSERT (Private->FrameBufferBltConfigure != NULL);
  Status = FrameBufferBltConfigure (
              (VOID*) (UINTN) This->Mode->FrameBufferBase,
              This->Mode->Info,
              Private->FrameBufferBltConfigure,
              &Private->FrameBufferBltConfigureSize
              );
  ASSERT (Status == RETURN_SUCCESS);

  return EFI_SUCCESS;
}
Beispiel #2
0
STATIC
EFI_STATUS
EFIAPI
QemuRamfbGraphicsOutputSetMode (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
  IN  UINT32                       ModeNumber
  )
{
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *ModeInfo;
  RAMFB_CONFIG                          Config;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         Black;
  RETURN_STATUS                         Status;

  if (ModeNumber >= mQemuRamfbMode.MaxMode) {
    return EFI_UNSUPPORTED;
  }
  ModeInfo = &mQemuRamfbModeInfo[ModeNumber];

  DEBUG ((DEBUG_INFO, "Ramfb: SetMode %u (%ux%u)\n", ModeNumber,
    ModeInfo->HorizontalResolution, ModeInfo->VerticalResolution));

  Config.Address = SwapBytes64 (mQemuRamfbMode.FrameBufferBase);
  Config.FourCC  = SwapBytes32 (RAMFB_FORMAT);
  Config.Flags   = SwapBytes32 (0);
  Config.Width   = SwapBytes32 (ModeInfo->HorizontalResolution);
  Config.Height  = SwapBytes32 (ModeInfo->VerticalResolution);
  Config.Stride  = SwapBytes32 (ModeInfo->HorizontalResolution * RAMFB_BPP);

  Status = FrameBufferBltConfigure (
             (VOID*)(UINTN)mQemuRamfbMode.FrameBufferBase,
             ModeInfo,
             mQemuRamfbFrameBufferBltConfigure,
             &mQemuRamfbFrameBufferBltConfigureSize
             );

  if (Status == RETURN_BUFFER_TOO_SMALL) {
    if (mQemuRamfbFrameBufferBltConfigure != NULL) {
      FreePool (mQemuRamfbFrameBufferBltConfigure);
    }
    mQemuRamfbFrameBufferBltConfigure =
      AllocatePool (mQemuRamfbFrameBufferBltConfigureSize);
    if (mQemuRamfbFrameBufferBltConfigure == NULL) {
      mQemuRamfbFrameBufferBltConfigureSize = 0;
      return EFI_OUT_OF_RESOURCES;
    }

    Status = FrameBufferBltConfigure (
               (VOID*)(UINTN)mQemuRamfbMode.FrameBufferBase,
               ModeInfo,
               mQemuRamfbFrameBufferBltConfigure,
               &mQemuRamfbFrameBufferBltConfigureSize
               );
  }
  if (RETURN_ERROR (Status)) {
    ASSERT (Status == RETURN_UNSUPPORTED);
    return Status;
  }

  mQemuRamfbMode.Mode = ModeNumber;
  mQemuRamfbMode.Info = ModeInfo;

  QemuFwCfgSelectItem (mRamfbFwCfgItem);
  QemuFwCfgWriteBytes (sizeof (Config), &Config);

  //
  // clear screen
  //
  ZeroMem (&Black, sizeof (Black));
  Status = FrameBufferBlt (
             mQemuRamfbFrameBufferBltConfigure,
             &Black,
             EfiBltVideoFill,
             0,                               // SourceX -- ignored
             0,                               // SourceY -- ignored
             0,                               // DestinationX
             0,                               // DestinationY
             ModeInfo->HorizontalResolution,  // Width
             ModeInfo->VerticalResolution,    // Height
             0                                // Delta -- ignored
             );
  if (RETURN_ERROR (Status)) {
    DEBUG ((DEBUG_WARN, "%a: clearing the screen failed: %r\n",
      __FUNCTION__, Status));
  }

  return EFI_SUCCESS;
}