]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/QemuVideoDxe/Initialize.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / QemuVideoDxe / Initialize.c
1 /** @file
2 Graphics Output Protocol functions for the QEMU video controller.
3
4 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "Qemu.h"
11
12 ///
13 /// Generic Attribute Controller Register Settings
14 ///
15 UINT8 AttributeController[21] = {
16 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
17 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
18 0x41, 0x00, 0x0F, 0x00, 0x00
19 };
20
21 ///
22 /// Generic Graphics Controller Register Settings
23 ///
24 UINT8 GraphicsController[9] = {
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
26 };
27
28 //
29 // 640 x 480 x 256 color @ 60 Hertz
30 //
31 UINT8 Crtc_640_480_256_60[28] = {
32 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
33 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
35 0xff, 0x00, 0x00, 0x22
36 };
37
38 UINT8 Crtc_640_480_32bpp_60[28] = {
39 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
40 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0xe1, 0x83, 0xdf, 0x40, 0x00, 0xe7, 0x04, 0xe3,
42 0xff, 0x00, 0x00, 0x32
43 };
44
45 UINT16 Seq_640_480_256_60[15] = {
46 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
47 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
48 };
49
50 UINT16 Seq_640_480_32bpp_60[15] = {
51 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
52 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
53 };
54
55 //
56 // 800 x 600 x 256 color @ 60 Hertz
57 //
58 UINT8 Crtc_800_600_256_60[28] = {
59 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
60 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
62 0xFF, 0x00, 0x00, 0x22
63 };
64
65 UINT8 Crtc_800_600_32bpp_60[28] = {
66 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
67 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x58, 0x8C, 0x57, 0x90, 0x00, 0x5F, 0x91, 0xE3,
69 0xFF, 0x00, 0x00, 0x32
70 };
71
72 UINT16 Seq_800_600_256_60[15] = {
73 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
74 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
75 };
76
77 UINT16 Seq_800_600_32bpp_60[15] = {
78 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
79 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
80 };
81
82 UINT8 Crtc_960_720_32bpp_60[28] = {
83 0xA3, 0x77, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
84 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x02, 0x88, 0xCF, 0xe0, 0x00, 0x00, 0x64, 0xE3,
86 0xFF, 0x4A, 0x00, 0x32
87 };
88
89 UINT16 Seq_960_720_32bpp_60[15] = {
90 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
91 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
92 };
93
94 //
95 // 1024 x 768 x 256 color @ 60 Hertz
96 //
97 UINT8 Crtc_1024_768_256_60[28] = {
98 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
99 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
101 0xFF, 0x4A, 0x00, 0x22
102 };
103
104 UINT16 Seq_1024_768_256_60[15] = {
105 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
106 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
107 };
108
109 //
110 // 1024 x 768 x 24-bit color @ 60 Hertz
111 //
112 UINT8 Crtc_1024_768_24bpp_60[28] = {
113 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
114 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
116 0xFF, 0x4A, 0x00, 0x32
117 };
118
119 UINT16 Seq_1024_768_24bpp_60[15] = {
120 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1507, 0x0008, 0x4a0b,
121 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
122 };
123
124 UINT8 Crtc_1024_768_32bpp_60[28] = {
125 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
126 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x02, 0x88, 0xFF, 0xe0, 0x00, 0x00, 0x64, 0xE3,
128 0xFF, 0x4A, 0x00, 0x32
129 };
130
131 UINT16 Seq_1024_768_32bpp_60[15] = {
132 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
133 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
134 };
135
136 ///
137 /// Table of supported video modes
138 ///
139 QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[] = {
140 // { 640, 480, 8, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },
141 // { 800, 600, 8, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },
142 { 640, 480, 32, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef },
143 { 800, 600, 32, Crtc_800_600_32bpp_60, Seq_800_600_32bpp_60, 0xef },
144 // { 1024, 768, 8, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }
145 { 1024, 768, 24, Crtc_1024_768_24bpp_60, Seq_1024_768_24bpp_60, 0xef }
146 // { 1024, 768, 32, Crtc_1024_768_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
147 // { 960, 720, 32, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
148 };
149
150 #define QEMU_VIDEO_CIRRUS_MODE_COUNT \
151 (ARRAY_SIZE (QemuVideoCirrusModes))
152
153 /**
154 Construct the valid video modes for QemuVideo.
155
156 **/
157 EFI_STATUS
158 QemuVideoCirrusModeSetup (
159 QEMU_VIDEO_PRIVATE_DATA *Private
160 )
161 {
162 UINT32 Index;
163 QEMU_VIDEO_MODE_DATA *ModeData;
164 QEMU_VIDEO_CIRRUS_MODES *VideoMode;
165
166 //
167 // Setup Video Modes
168 //
169 Private->ModeData = AllocatePool (
170 sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT
171 );
172 if (Private->ModeData == NULL) {
173 return EFI_OUT_OF_RESOURCES;
174 }
175
176 ModeData = Private->ModeData;
177 VideoMode = &QemuVideoCirrusModes[0];
178 for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index++) {
179 ModeData->InternalModeIndex = Index;
180 ModeData->HorizontalResolution = VideoMode->Width;
181 ModeData->VerticalResolution = VideoMode->Height;
182 ModeData->ColorDepth = VideoMode->ColorDepth;
183 DEBUG ((
184 DEBUG_INFO,
185 "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit\n",
186 (INT32)(ModeData - Private->ModeData),
187 ModeData->InternalModeIndex,
188 ModeData->HorizontalResolution,
189 ModeData->VerticalResolution,
190 ModeData->ColorDepth
191 ));
192
193 ModeData++;
194 VideoMode++;
195 }
196
197 Private->MaxMode = ModeData - Private->ModeData;
198
199 return EFI_SUCCESS;
200 }
201
202 ///
203 /// Table of supported video modes
204 ///
205 QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[] = {
206 { 640, 480, 32 },
207 { 800, 480, 32 },
208 { 800, 600, 32 },
209 { 832, 624, 32 },
210 { 960, 640, 32 },
211 { 1024, 600, 32 },
212 { 1024, 768, 32 },
213 { 1152, 864, 32 },
214 { 1152, 870, 32 },
215 { 1280, 720, 32 },
216 { 1280, 760, 32 },
217 { 1280, 768, 32 },
218 { 1280, 800, 32 },
219 { 1280, 960, 32 },
220 { 1280, 1024, 32 },
221 { 1360, 768, 32 },
222 { 1366, 768, 32 },
223 { 1400, 1050, 32 },
224 { 1440, 900, 32 },
225 { 1600, 900, 32 },
226 { 1600, 1200, 32 },
227 { 1680, 1050, 32 },
228 { 1920, 1080, 32 },
229 { 1920, 1200, 32 },
230 { 1920, 1440, 32 },
231 { 2000, 2000, 32 },
232 { 2048, 1536, 32 },
233 { 2048, 2048, 32 },
234 { 2560, 1440, 32 },
235 { 2560, 1600, 32 },
236 { 2560, 2048, 32 },
237 { 2800, 2100, 32 },
238 { 3200, 2400, 32 },
239 { 3840, 2160, 32 },
240 { 4096, 2160, 32 },
241 { 7680, 4320, 32 },
242 { 8192, 4320, 32 }
243 };
244
245 #define QEMU_VIDEO_BOCHS_MODE_COUNT \
246 (ARRAY_SIZE (QemuVideoBochsModes))
247
248 EFI_STATUS
249 QemuVideoBochsModeSetup (
250 QEMU_VIDEO_PRIVATE_DATA *Private,
251 BOOLEAN IsQxl
252 )
253 {
254 UINT32 AvailableFbSize;
255 UINT32 Index;
256 QEMU_VIDEO_MODE_DATA *ModeData;
257 QEMU_VIDEO_BOCHS_MODES *VideoMode;
258
259 //
260 // Fetch the available framebuffer size.
261 //
262 // VBE_DISPI_INDEX_VIDEO_MEMORY_64K is expected to return the size of the
263 // drawable framebuffer. Up to and including qemu-2.1 however it used to
264 // return the size of PCI BAR 0 (ie. the full video RAM size).
265 //
266 // On stdvga the two concepts coincide with each other; the full memory size
267 // is usable for drawing.
268 //
269 // On QXL however, only a leading segment, "surface 0", can be used for
270 // drawing; the rest of the video memory is used for the QXL guest-host
271 // protocol. VBE_DISPI_INDEX_VIDEO_MEMORY_64K should report the size of
272 // "surface 0", but since it doesn't (up to and including qemu-2.1), we
273 // retrieve the size of the drawable portion from a field in the QXL ROM BAR,
274 // where it is also available.
275 //
276 if (IsQxl) {
277 UINT32 Signature;
278 UINT32 DrawStart;
279
280 Signature = 0;
281 DrawStart = 0xFFFFFFFF;
282 AvailableFbSize = 0;
283 if (EFI_ERROR (
284 Private->PciIo->Mem.Read (
285 Private->PciIo,
286 EfiPciIoWidthUint32,
287 PCI_BAR_IDX2,
288 0,
289 1,
290 &Signature
291 )
292 ) ||
293 (Signature != SIGNATURE_32 ('Q', 'X', 'R', 'O')) ||
294 EFI_ERROR (
295 Private->PciIo->Mem.Read (
296 Private->PciIo,
297 EfiPciIoWidthUint32,
298 PCI_BAR_IDX2,
299 36,
300 1,
301 &DrawStart
302 )
303 ) ||
304 (DrawStart != 0) ||
305 EFI_ERROR (
306 Private->PciIo->Mem.Read (
307 Private->PciIo,
308 EfiPciIoWidthUint32,
309 PCI_BAR_IDX2,
310 40,
311 1,
312 &AvailableFbSize
313 )
314 ))
315 {
316 DEBUG ((
317 DEBUG_ERROR,
318 "%a: can't read size of drawable buffer from QXL "
319 "ROM\n",
320 __FUNCTION__
321 ));
322 return EFI_NOT_FOUND;
323 }
324 } else {
325 AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
326 AvailableFbSize *= SIZE_64KB;
327 }
328
329 DEBUG ((
330 DEBUG_INFO,
331 "%a: AvailableFbSize=0x%x\n",
332 __FUNCTION__,
333 AvailableFbSize
334 ));
335
336 //
337 // Setup Video Modes
338 //
339 Private->ModeData = AllocatePool (
340 sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT
341 );
342 if (Private->ModeData == NULL) {
343 return EFI_OUT_OF_RESOURCES;
344 }
345
346 ModeData = Private->ModeData;
347 VideoMode = &QemuVideoBochsModes[0];
348 for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index++) {
349 UINTN RequiredFbSize;
350
351 ASSERT (VideoMode->ColorDepth % 8 == 0);
352 RequiredFbSize = (UINTN)VideoMode->Width * VideoMode->Height *
353 (VideoMode->ColorDepth / 8);
354 if (RequiredFbSize <= AvailableFbSize) {
355 ModeData->InternalModeIndex = Index;
356 ModeData->HorizontalResolution = VideoMode->Width;
357 ModeData->VerticalResolution = VideoMode->Height;
358 ModeData->ColorDepth = VideoMode->ColorDepth;
359 DEBUG ((
360 DEBUG_INFO,
361 "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit\n",
362 (INT32)(ModeData - Private->ModeData),
363 ModeData->InternalModeIndex,
364 ModeData->HorizontalResolution,
365 ModeData->VerticalResolution,
366 ModeData->ColorDepth
367 ));
368
369 ModeData++;
370 }
371
372 VideoMode++;
373 }
374
375 Private->MaxMode = ModeData - Private->ModeData;
376
377 return EFI_SUCCESS;
378 }