]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/QemuVideoDxe/Initialize.c
OvmfPkg/QemuVideoDxe/VbeShim: handle PAM1 register on Q35 correctly
[mirror_edk2.git] / OvmfPkg / QemuVideoDxe / Initialize.c
CommitLineData
eaf4f336 1/** @file\r
2 Graphics Output Protocol functions for the QEMU video controller.\r
3\r
4 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
c137d950 16#include <IndustryStandard/VmwareSvga.h>\r
eaf4f336 17#include "Qemu.h"\r
18\r
19\r
20///\r
21/// Generic Attribute Controller Register Settings\r
22///\r
23UINT8 AttributeController[21] = {\r
24 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\r
25 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,\r
26 0x41, 0x00, 0x0F, 0x00, 0x00\r
27};\r
28\r
29///\r
30/// Generic Graphics Controller Register Settings\r
31///\r
32UINT8 GraphicsController[9] = {\r
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF\r
34};\r
35\r
36//\r
37// 640 x 480 x 256 color @ 60 Hertz\r
38//\r
39UINT8 Crtc_640_480_256_60[28] = {\r
40 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,\r
41 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
42 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,\r
43 0xff, 0x00, 0x00, 0x22\r
44};\r
45\r
46UINT8 Crtc_640_480_32bpp_60[28] = {\r
47 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,\r
48 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
49 0xe1, 0x83, 0xdf, 0x40, 0x00, 0xe7, 0x04, 0xe3,\r
50 0xff, 0x00, 0x00, 0x32\r
51};\r
52\r
53UINT16 Seq_640_480_256_60[15] = {\r
54 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,\r
55 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e\r
56};\r
57\r
58UINT16 Seq_640_480_32bpp_60[15] = {\r
59 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,\r
60 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e\r
61};\r
62\r
63//\r
64// 800 x 600 x 256 color @ 60 Hertz\r
65//\r
66UINT8 Crtc_800_600_256_60[28] = {\r
67 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,\r
68 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
69 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,\r
70 0xFF, 0x00, 0x00, 0x22\r
71};\r
72\r
73UINT8 Crtc_800_600_32bpp_60[28] = {\r
74 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,\r
75 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
76 0x58, 0x8C, 0x57, 0x90, 0x00, 0x5F, 0x91, 0xE3,\r
77 0xFF, 0x00, 0x00, 0x32\r
78};\r
79\r
80UINT16 Seq_800_600_256_60[15] = {\r
81 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,\r
82 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e\r
83};\r
84\r
85UINT16 Seq_800_600_32bpp_60[15] = {\r
86 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,\r
87 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e\r
88};\r
89\r
90UINT8 Crtc_960_720_32bpp_60[28] = {\r
91 0xA3, 0x77, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,\r
92 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
93 0x02, 0x88, 0xCF, 0xe0, 0x00, 0x00, 0x64, 0xE3,\r
94 0xFF, 0x4A, 0x00, 0x32\r
95};\r
96\r
97UINT16 Seq_960_720_32bpp_60[15] = {\r
98 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,\r
99 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e\r
100};\r
101\r
102//\r
103// 1024 x 768 x 256 color @ 60 Hertz\r
104//\r
105UINT8 Crtc_1024_768_256_60[28] = {\r
106 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,\r
107 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
108 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,\r
109 0xFF, 0x4A, 0x00, 0x22\r
110};\r
111\r
112UINT16 Seq_1024_768_256_60[15] = {\r
113 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,\r
114 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e\r
115};\r
116\r
117//\r
118// 1024 x 768 x 24-bit color @ 60 Hertz\r
119//\r
120UINT8 Crtc_1024_768_24bpp_60[28] = {\r
121 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,\r
122 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
123 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,\r
124 0xFF, 0x4A, 0x00, 0x32\r
125};\r
126\r
127UINT16 Seq_1024_768_24bpp_60[15] = {\r
128 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1507, 0x0008, 0x4a0b,\r
129 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e\r
130};\r
131\r
132UINT8 Crtc_1024_768_32bpp_60[28] = {\r
133 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,\r
134 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
135 0x02, 0x88, 0xFF, 0xe0, 0x00, 0x00, 0x64, 0xE3,\r
136 0xFF, 0x4A, 0x00, 0x32\r
137};\r
138\r
139UINT16 Seq_1024_768_32bpp_60[15] = {\r
140 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,\r
141 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e\r
142};\r
143\r
144///\r
145/// Table of supported video modes\r
146///\r
212aac55 147QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[] = {\r
9ebb7ce8
LE
148// { 640, 480, 8, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },\r
149// { 800, 600, 8, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },\r
150 { 640, 480, 32, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef },\r
151 { 800, 600, 32, Crtc_800_600_32bpp_60, Seq_800_600_32bpp_60, 0xef },\r
152// { 1024, 768, 8, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }\r
153 { 1024, 768, 24, Crtc_1024_768_24bpp_60, Seq_1024_768_24bpp_60, 0xef }\r
154// { 1024, 768, 32, Crtc_1024_768_32bpp_60, Seq_1024_768_32bpp_60, 0xef }\r
155// { 960, 720, 32, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }\r
eaf4f336 156};\r
157\r
212aac55 158#define QEMU_VIDEO_CIRRUS_MODE_COUNT \\r
b1bc305c 159 (ARRAY_SIZE (QemuVideoCirrusModes))\r
eaf4f336 160\r
161/**\r
162 Construct the valid video modes for QemuVideo.\r
163\r
164**/\r
165EFI_STATUS\r
212aac55 166QemuVideoCirrusModeSetup (\r
eaf4f336 167 QEMU_VIDEO_PRIVATE_DATA *Private\r
168 )\r
169{\r
170 UINT32 Index;\r
171 QEMU_VIDEO_MODE_DATA *ModeData;\r
212aac55 172 QEMU_VIDEO_CIRRUS_MODES *VideoMode;\r
eaf4f336 173\r
174 //\r
175 // Setup Video Modes\r
176 //\r
177 Private->ModeData = AllocatePool (\r
212aac55 178 sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT\r
eaf4f336 179 );\r
d89186bc
LE
180 if (Private->ModeData == NULL) {\r
181 return EFI_OUT_OF_RESOURCES;\r
182 }\r
eaf4f336 183 ModeData = Private->ModeData;\r
212aac55 184 VideoMode = &QemuVideoCirrusModes[0];\r
185 for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) {\r
cd152610 186 ModeData->InternalModeIndex = Index;\r
eaf4f336 187 ModeData->HorizontalResolution = VideoMode->Width;\r
188 ModeData->VerticalResolution = VideoMode->Height;\r
189 ModeData->ColorDepth = VideoMode->ColorDepth;\r
eaf4f336 190 DEBUG ((EFI_D_INFO,\r
0ccc97e9 191 "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit\n",\r
cd152610
LE
192 (INT32) (ModeData - Private->ModeData),\r
193 ModeData->InternalModeIndex,\r
eaf4f336 194 ModeData->HorizontalResolution,\r
195 ModeData->VerticalResolution,\r
0ccc97e9 196 ModeData->ColorDepth\r
eaf4f336 197 ));\r
198\r
199 ModeData ++ ;\r
200 VideoMode ++;\r
201 }\r
ec88061e 202 Private->MaxMode = ModeData - Private->ModeData;\r
eaf4f336 203\r
204 return EFI_SUCCESS;\r
205}\r
206\r
54f9b9ac 207///\r
208/// Table of supported video modes\r
209///\r
210QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[] = {\r
bb97e788
LE
211 { 640, 480, 32 },\r
212 { 800, 480, 32 },\r
213 { 800, 600, 32 },\r
214 { 832, 624, 32 },\r
215 { 960, 640, 32 },\r
216 { 1024, 600, 32 },\r
217 { 1024, 768, 32 },\r
218 { 1152, 864, 32 },\r
219 { 1152, 870, 32 },\r
220 { 1280, 720, 32 },\r
221 { 1280, 760, 32 },\r
222 { 1280, 768, 32 },\r
223 { 1280, 800, 32 },\r
224 { 1280, 960, 32 },\r
225 { 1280, 1024, 32 },\r
226 { 1360, 768, 32 },\r
227 { 1366, 768, 32 },\r
228 { 1400, 1050, 32 },\r
229 { 1440, 900, 32 },\r
230 { 1600, 900, 32 },\r
231 { 1600, 1200, 32 },\r
232 { 1680, 1050, 32 },\r
233 { 1920, 1080, 32 },\r
234 { 1920, 1200, 32 },\r
235 { 1920, 1440, 32 },\r
236 { 2000, 2000, 32 },\r
237 { 2048, 1536, 32 },\r
238 { 2048, 2048, 32 },\r
239 { 2560, 1440, 32 },\r
240 { 2560, 1600, 32 },\r
241 { 2560, 2048, 32 },\r
242 { 2800, 2100, 32 },\r
243 { 3200, 2400, 32 },\r
244 { 3840, 2160, 32 },\r
245 { 4096, 2160, 32 },\r
246 { 7680, 4320, 32 },\r
247 { 8192, 4320, 32 }\r
54f9b9ac 248};\r
249\r
250#define QEMU_VIDEO_BOCHS_MODE_COUNT \\r
b1bc305c 251 (ARRAY_SIZE (QemuVideoBochsModes))\r
54f9b9ac 252\r
253EFI_STATUS\r
254QemuVideoBochsModeSetup (\r
b37bcfd6
LE
255 QEMU_VIDEO_PRIVATE_DATA *Private,\r
256 BOOLEAN IsQxl\r
54f9b9ac 257 )\r
258{\r
ec88061e 259 UINT32 AvailableFbSize;\r
54f9b9ac 260 UINT32 Index;\r
261 QEMU_VIDEO_MODE_DATA *ModeData;\r
262 QEMU_VIDEO_BOCHS_MODES *VideoMode;\r
263\r
ec88061e 264 //\r
b37bcfd6
LE
265 // Fetch the available framebuffer size.\r
266 //\r
267 // VBE_DISPI_INDEX_VIDEO_MEMORY_64K is expected to return the size of the\r
268 // drawable framebuffer. Up to and including qemu-2.1 however it used to\r
269 // return the size of PCI BAR 0 (ie. the full video RAM size).\r
270 //\r
271 // On stdvga the two concepts coincide with each other; the full memory size\r
272 // is usable for drawing.\r
ec88061e 273 //\r
b37bcfd6
LE
274 // On QXL however, only a leading segment, "surface 0", can be used for\r
275 // drawing; the rest of the video memory is used for the QXL guest-host\r
276 // protocol. VBE_DISPI_INDEX_VIDEO_MEMORY_64K should report the size of\r
277 // "surface 0", but since it doesn't (up to and including qemu-2.1), we\r
278 // retrieve the size of the drawable portion from a field in the QXL ROM BAR,\r
279 // where it is also available.\r
280 //\r
281 if (IsQxl) {\r
282 UINT32 Signature;\r
283 UINT32 DrawStart;\r
284\r
285 Signature = 0;\r
286 DrawStart = 0xFFFFFFFF;\r
287 AvailableFbSize = 0;\r
288 if (EFI_ERROR (\r
289 Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,\r
290 PCI_BAR_IDX2, 0, 1, &Signature)) ||\r
291 Signature != SIGNATURE_32 ('Q', 'X', 'R', 'O') ||\r
292 EFI_ERROR (\r
293 Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,\r
294 PCI_BAR_IDX2, 36, 1, &DrawStart)) ||\r
295 DrawStart != 0 ||\r
296 EFI_ERROR (\r
297 Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,\r
298 PCI_BAR_IDX2, 40, 1, &AvailableFbSize))) {\r
299 DEBUG ((EFI_D_ERROR, "%a: can't read size of drawable buffer from QXL "\r
300 "ROM\n", __FUNCTION__));\r
301 return EFI_NOT_FOUND;\r
302 }\r
303 } else {\r
304 AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);\r
305 AvailableFbSize *= SIZE_64KB;\r
306 }\r
4dd8787a 307 DEBUG ((EFI_D_INFO, "%a: AvailableFbSize=0x%x\n", __FUNCTION__,\r
ec88061e
LE
308 AvailableFbSize));\r
309\r
54f9b9ac 310 //\r
311 // Setup Video Modes\r
312 //\r
313 Private->ModeData = AllocatePool (\r
314 sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT\r
315 );\r
d89186bc
LE
316 if (Private->ModeData == NULL) {\r
317 return EFI_OUT_OF_RESOURCES;\r
318 }\r
54f9b9ac 319 ModeData = Private->ModeData;\r
320 VideoMode = &QemuVideoBochsModes[0];\r
321 for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) {\r
ec88061e
LE
322 UINTN RequiredFbSize;\r
323\r
324 ASSERT (VideoMode->ColorDepth % 8 == 0);\r
325 RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height *\r
326 (VideoMode->ColorDepth / 8);\r
327 if (RequiredFbSize <= AvailableFbSize) {\r
328 ModeData->InternalModeIndex = Index;\r
329 ModeData->HorizontalResolution = VideoMode->Width;\r
330 ModeData->VerticalResolution = VideoMode->Height;\r
331 ModeData->ColorDepth = VideoMode->ColorDepth;\r
ec88061e 332 DEBUG ((EFI_D_INFO,\r
0ccc97e9 333 "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit\n",\r
ec88061e
LE
334 (INT32) (ModeData - Private->ModeData),\r
335 ModeData->InternalModeIndex,\r
336 ModeData->HorizontalResolution,\r
337 ModeData->VerticalResolution,\r
0ccc97e9 338 ModeData->ColorDepth\r
ec88061e
LE
339 ));\r
340\r
341 ModeData ++ ;\r
342 }\r
54f9b9ac 343 VideoMode ++;\r
344 }\r
ec88061e 345 Private->MaxMode = ModeData - Private->ModeData;\r
54f9b9ac 346\r
347 return EFI_SUCCESS;\r
348}\r
349\r
c137d950
PDJ
350EFI_STATUS\r
351QemuVideoVmwareSvgaModeSetup (\r
352 QEMU_VIDEO_PRIVATE_DATA *Private\r
353 )\r
354{\r
355 EFI_STATUS Status;\r
356 UINT32 FbSize;\r
357 UINT32 MaxWidth, MaxHeight;\r
358 UINT32 Capabilities;\r
359 UINT32 BitsPerPixel;\r
360 UINT32 Index;\r
361 QEMU_VIDEO_MODE_DATA *ModeData;\r
362 QEMU_VIDEO_BOCHS_MODES *VideoMode;\r
363 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeInfo;\r
364\r
365 VmwareSvgaWrite (Private, VmwareSvgaRegEnable, 0);\r
366\r
367 Private->ModeData =\r
368 AllocatePool (sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT);\r
369 if (Private->ModeData == NULL) {\r
370 Status = EFI_OUT_OF_RESOURCES;\r
371 goto ModeDataAllocError;\r
372 }\r
373\r
374 Private->VmwareSvgaModeInfo =\r
375 AllocatePool (\r
376 sizeof (Private->VmwareSvgaModeInfo[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT\r
377 );\r
378 if (Private->VmwareSvgaModeInfo == NULL) {\r
379 Status = EFI_OUT_OF_RESOURCES;\r
380 goto ModeInfoAllocError;\r
381 }\r
382\r
383 FbSize = VmwareSvgaRead (Private, VmwareSvgaRegFbSize);\r
384 MaxWidth = VmwareSvgaRead (Private, VmwareSvgaRegMaxWidth);\r
385 MaxHeight = VmwareSvgaRead (Private, VmwareSvgaRegMaxHeight);\r
386 Capabilities = VmwareSvgaRead (Private, VmwareSvgaRegCapabilities);\r
387 if ((Capabilities & VMWARE_SVGA_CAP_8BIT_EMULATION) != 0) {\r
388 BitsPerPixel = VmwareSvgaRead (\r
389 Private,\r
390 VmwareSvgaRegHostBitsPerPixel\r
391 );\r
392 VmwareSvgaWrite (\r
393 Private,\r
394 VmwareSvgaRegBitsPerPixel,\r
395 BitsPerPixel\r
396 );\r
397 } else {\r
398 BitsPerPixel = VmwareSvgaRead (\r
399 Private,\r
400 VmwareSvgaRegBitsPerPixel\r
401 );\r
402 }\r
403\r
404 if (FbSize == 0 ||\r
405 MaxWidth == 0 ||\r
406 MaxHeight == 0 ||\r
407 BitsPerPixel == 0 ||\r
408 BitsPerPixel % 8 != 0) {\r
409 Status = EFI_DEVICE_ERROR;\r
410 goto Rollback;\r
411 }\r
412\r
413 ModeData = Private->ModeData;\r
414 ModeInfo = Private->VmwareSvgaModeInfo;\r
415 VideoMode = &QemuVideoBochsModes[0];\r
416 for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index++) {\r
417 UINTN RequiredFbSize;\r
418\r
419 RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height *\r
420 (BitsPerPixel / 8);\r
421 if (RequiredFbSize <= FbSize &&\r
422 VideoMode->Width <= MaxWidth &&\r
423 VideoMode->Height <= MaxHeight) {\r
424 UINT32 BytesPerLine;\r
425 UINT32 RedMask, GreenMask, BlueMask, PixelMask;\r
426\r
427 VmwareSvgaWrite (\r
428 Private,\r
429 VmwareSvgaRegWidth,\r
430 VideoMode->Width\r
431 );\r
432 VmwareSvgaWrite (\r
433 Private,\r
434 VmwareSvgaRegHeight,\r
435 VideoMode->Height\r
436 );\r
437\r
438 ModeData->InternalModeIndex = Index;\r
439 ModeData->HorizontalResolution = VideoMode->Width;\r
440 ModeData->VerticalResolution = VideoMode->Height;\r
441 ModeData->ColorDepth = BitsPerPixel;\r
442\r
443 //\r
444 // Setting VmwareSvgaRegWidth/VmwareSvgaRegHeight actually changes\r
445 // the device's display mode, so we save all properties of each mode up\r
446 // front to avoid inadvertent mode changes later.\r
447 //\r
448 ModeInfo->Version = 0;\r
449 ModeInfo->HorizontalResolution = ModeData->HorizontalResolution;\r
450 ModeInfo->VerticalResolution = ModeData->VerticalResolution;\r
451\r
452 ModeInfo->PixelFormat = PixelBitMask;\r
453\r
454 RedMask = VmwareSvgaRead (Private, VmwareSvgaRegRedMask);\r
455 ModeInfo->PixelInformation.RedMask = RedMask;\r
456\r
457 GreenMask = VmwareSvgaRead (Private, VmwareSvgaRegGreenMask);\r
458 ModeInfo->PixelInformation.GreenMask = GreenMask;\r
459\r
460 BlueMask = VmwareSvgaRead (Private, VmwareSvgaRegBlueMask);\r
461 ModeInfo->PixelInformation.BlueMask = BlueMask;\r
462\r
463 //\r
464 // Reserved mask is whatever bits in the pixel not containing RGB data,\r
465 // so start with binary 1s for every bit in the pixel, then mask off\r
466 // bits already used for RGB. Special case 32 to avoid undefined\r
467 // behaviour in the shift.\r
468 //\r
469 if (BitsPerPixel == 32) {\r
470 if (BlueMask == 0xff && GreenMask == 0xff00 && RedMask == 0xff0000) {\r
471 ModeInfo->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
472 } else if (BlueMask == 0xff0000 &&\r
473 GreenMask == 0xff00 &&\r
474 RedMask == 0xff) {\r
475 ModeInfo->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;\r
476 }\r
477 PixelMask = MAX_UINT32;\r
478 } else {\r
479 PixelMask = (1u << BitsPerPixel) - 1;\r
480 }\r
481 ModeInfo->PixelInformation.ReservedMask =\r
482 PixelMask & ~(RedMask | GreenMask | BlueMask);\r
483\r
484 BytesPerLine = VmwareSvgaRead (Private, VmwareSvgaRegBytesPerLine);\r
485 ModeInfo->PixelsPerScanLine = BytesPerLine / (BitsPerPixel / 8);\r
486\r
487 ModeData++;\r
488 ModeInfo++;\r
489 }\r
490 VideoMode++;\r
491 }\r
492 Private->MaxMode = ModeData - Private->ModeData;\r
493 return EFI_SUCCESS;\r
494\r
495Rollback:\r
496 FreePool (Private->VmwareSvgaModeInfo);\r
497 Private->VmwareSvgaModeInfo = NULL;\r
498\r
499ModeInfoAllocError:\r
500 FreePool (Private->ModeData);\r
501 Private->ModeData = NULL;\r
502\r
503ModeDataAllocError:\r
504 return Status;\r
505}\r