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