Пример #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;
}
Пример #2
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;
//  UINTN                             Count;
  BOOLEAN                    VideoModeChanged;

  Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);

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

  ModeData = &Private->ModeData[ModeNumber];

  if (Private->LineBuffer) {
    gBS->FreePool (Private->LineBuffer);
  }

  Private->LineBuffer = AllocatePool (4 * ModeData->HorizontalResolution);
  if (Private->LineBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  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);
    gBS->FreePool (Private->LineBuffer);
    Private->LineBuffer = NULL;
    return EFI_DEVICE_ERROR;
  }

  // Check if this is a new mode
  VideoModeChanged = (This->Mode->Mode != ModeNumber);

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

  BltLibConfigure (
    (VOID*)(UINTN) This->Mode->FrameBufferBase,
    This->Mode->Info
    );

  if (VideoModeChanged) {
    UINTN                    Index;
    UINTN                    HandleCount;
    EFI_HANDLE               *HandleBuffer;
    EFI_STATUS               Status;

    //
    // Set PCDs to Inform GraphicsConsole of video resolution.
    //    
    PcdSet32 (PcdVideoHorizontalResolution, This->Mode->Info->HorizontalResolution);
    PcdSet32 (PcdVideoVerticalResolution, This->Mode->Info->VerticalResolution);

    //
    // Video mode is changed, so restart graphics console driver and higher level driver.
    // Reconnect graphics console driver and higher level driver.
    // Locate all the handles with GOP protocol and reconnect it.
    //
    Status = gBS->LocateHandleBuffer (
                     ByProtocol,
                     &gEfiSimpleTextOutProtocolGuid,
                     NULL,
                     &HandleCount,
                     &HandleBuffer
                     );
    if (!EFI_ERROR (Status)) {
      for (Index = 0; Index < HandleCount; Index++) {
        gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
      }
      for (Index = 0; Index < HandleCount; Index++) {
        gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
      }
      if (HandleBuffer != NULL) {
        FreePool (HandleBuffer);
      }
    }
  }

  return EFI_SUCCESS;
}