\r
Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
/// Table of supported video modes\r
///\r
QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[] = {\r
-// { 640, 480, 8, 60, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },\r
-// { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },\r
- { 640, 480, 32, 60, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef },\r
- { 800, 600, 32, 60, Crtc_800_600_32bpp_60, Seq_800_600_32bpp_60, 0xef },\r
-// { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }\r
- { 1024, 768, 24, 60, Crtc_1024_768_24bpp_60, Seq_1024_768_24bpp_60, 0xef }\r
-// { 1024, 768, 32, 60, Crtc_1024_768_32bpp_60, Seq_1024_768_32bpp_60, 0xef }\r
-// { 960, 720, 32, 60, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }\r
+// { 640, 480, 8, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },\r
+// { 800, 600, 8, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },\r
+ { 640, 480, 32, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef },\r
+ { 800, 600, 32, Crtc_800_600_32bpp_60, Seq_800_600_32bpp_60, 0xef },\r
+// { 1024, 768, 8, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }\r
+ { 1024, 768, 24, Crtc_1024_768_24bpp_60, Seq_1024_768_24bpp_60, 0xef }\r
+// { 1024, 768, 32, Crtc_1024_768_32bpp_60, Seq_1024_768_32bpp_60, 0xef }\r
+// { 960, 720, 32, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }\r
};\r
\r
#define QEMU_VIDEO_CIRRUS_MODE_COUNT \\r
- (sizeof (QemuVideoCirrusModes) / sizeof (QemuVideoCirrusModes[0]))\r
+ (ARRAY_SIZE (QemuVideoCirrusModes))\r
\r
/**\r
Construct the valid video modes for QemuVideo.\r
ModeData->HorizontalResolution = VideoMode->Width;\r
ModeData->VerticalResolution = VideoMode->Height;\r
ModeData->ColorDepth = VideoMode->ColorDepth;\r
- ModeData->RefreshRate = VideoMode->RefreshRate;\r
DEBUG ((EFI_D_INFO,\r
- "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit, %d Hz\n",\r
+ "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit\n",\r
(INT32) (ModeData - Private->ModeData),\r
ModeData->InternalModeIndex,\r
ModeData->HorizontalResolution,\r
ModeData->VerticalResolution,\r
- ModeData->ColorDepth,\r
- ModeData->RefreshRate\r
+ ModeData->ColorDepth\r
));\r
\r
ModeData ++ ;\r
};\r
\r
#define QEMU_VIDEO_BOCHS_MODE_COUNT \\r
- (sizeof (QemuVideoBochsModes) / sizeof (QemuVideoBochsModes[0]))\r
+ (ARRAY_SIZE (QemuVideoBochsModes))\r
\r
EFI_STATUS\r
QemuVideoBochsModeSetup (\r
- QEMU_VIDEO_PRIVATE_DATA *Private\r
+ QEMU_VIDEO_PRIVATE_DATA *Private,\r
+ BOOLEAN IsQxl\r
)\r
{\r
UINT32 AvailableFbSize;\r
QEMU_VIDEO_BOCHS_MODES *VideoMode;\r
\r
//\r
- // fetch available framebuffer size\r
+ // Fetch the available framebuffer size.\r
+ //\r
+ // VBE_DISPI_INDEX_VIDEO_MEMORY_64K is expected to return the size of the\r
+ // drawable framebuffer. Up to and including qemu-2.1 however it used to\r
+ // return the size of PCI BAR 0 (ie. the full video RAM size).\r
+ //\r
+ // On stdvga the two concepts coincide with each other; the full memory size\r
+ // is usable for drawing.\r
//\r
- AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);\r
- AvailableFbSize *= SIZE_64KB;\r
- DEBUG ((EFI_D_VERBOSE, "%a: AvailableFbSize=0x%x\n", __FUNCTION__,\r
+ // On QXL however, only a leading segment, "surface 0", can be used for\r
+ // drawing; the rest of the video memory is used for the QXL guest-host\r
+ // protocol. VBE_DISPI_INDEX_VIDEO_MEMORY_64K should report the size of\r
+ // "surface 0", but since it doesn't (up to and including qemu-2.1), we\r
+ // retrieve the size of the drawable portion from a field in the QXL ROM BAR,\r
+ // where it is also available.\r
+ //\r
+ if (IsQxl) {\r
+ UINT32 Signature;\r
+ UINT32 DrawStart;\r
+\r
+ Signature = 0;\r
+ DrawStart = 0xFFFFFFFF;\r
+ AvailableFbSize = 0;\r
+ if (EFI_ERROR (\r
+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,\r
+ PCI_BAR_IDX2, 0, 1, &Signature)) ||\r
+ Signature != SIGNATURE_32 ('Q', 'X', 'R', 'O') ||\r
+ EFI_ERROR (\r
+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,\r
+ PCI_BAR_IDX2, 36, 1, &DrawStart)) ||\r
+ DrawStart != 0 ||\r
+ EFI_ERROR (\r
+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,\r
+ PCI_BAR_IDX2, 40, 1, &AvailableFbSize))) {\r
+ DEBUG ((EFI_D_ERROR, "%a: can't read size of drawable buffer from QXL "\r
+ "ROM\n", __FUNCTION__));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ } else {\r
+ AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);\r
+ AvailableFbSize *= SIZE_64KB;\r
+ }\r
+ DEBUG ((EFI_D_INFO, "%a: AvailableFbSize=0x%x\n", __FUNCTION__,\r
AvailableFbSize));\r
\r
//\r
ModeData->HorizontalResolution = VideoMode->Width;\r
ModeData->VerticalResolution = VideoMode->Height;\r
ModeData->ColorDepth = VideoMode->ColorDepth;\r
- ModeData->RefreshRate = 60;\r
DEBUG ((EFI_D_INFO,\r
- "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit, %d Hz\n",\r
+ "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit\n",\r
(INT32) (ModeData - Private->ModeData),\r
ModeData->InternalModeIndex,\r
ModeData->HorizontalResolution,\r
ModeData->VerticalResolution,\r
- ModeData->ColorDepth,\r
- ModeData->RefreshRate\r
+ ModeData->ColorDepth\r
));\r
\r
ModeData ++ ;\r