TianoCore EDK2 master
Loading...
Searching...
No Matches
Initialize.c
Go to the documentation of this file.
1
10#include "Qemu.h"
11
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
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
26};
27
28//
29// 640 x 480 x 256 color @ 60 Hertz
30//
31UINT8 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
38UINT8 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
45UINT16 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
50UINT16 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//
58UINT8 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
65UINT8 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
72UINT16 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
77UINT16 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
82UINT8 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
89UINT16 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//
97UINT8 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
104UINT16 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//
112UINT8 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
119UINT16 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
124UINT8 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
131UINT16 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
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
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
206 { 640, 480 },
207 { 800, 480 },
208 { 800, 600 },
209 { 832, 624 },
210 { 960, 640 },
211 { 1024, 600 },
212 { 1024, 768 },
213 { 1152, 864 },
214 { 1152, 870 },
215 { 1280, 720 },
216 { 1280, 760 },
217 { 1280, 768 },
218 { 1280, 800 },
219 { 1280, 960 },
220 { 1280, 1024 },
221 { 1360, 768 },
222 { 1366, 768 },
223 { 1400, 1050 },
224 { 1440, 900 },
225 { 1600, 900 },
226 { 1600, 1200 },
227 { 1680, 1050 },
228 { 1920, 1080 },
229 { 1920, 1200 },
230 { 1920, 1440 },
231 { 2000, 2000 },
232 { 2048, 1536 },
233 { 2048, 2048 },
234 { 2560, 1440 },
235 { 2560, 1600 },
236 { 2560, 2048 },
237 { 2800, 2100 },
238 { 3200, 2400 },
239 { 3840, 2160 },
240 { 4096, 2160 },
241 { 7680, 4320 },
242 { 8192, 4320 }
243};
244
245#define QEMU_VIDEO_BOCHS_MODE_COUNT \
246 (ARRAY_SIZE (QemuVideoBochsModes))
247
248STATIC
249VOID
250QemuVideoBochsAddMode (
252 UINT32 AvailableFbSize,
253 UINT32 Width,
254 UINT32 Height
255 )
256{
257 QEMU_VIDEO_MODE_DATA *ModeData = Private->ModeData + Private->MaxMode;
258 UINTN RequiredFbSize;
259
260 RequiredFbSize = (UINTN)Width * Height * 4;
261 if (RequiredFbSize > AvailableFbSize) {
262 DEBUG ((
263 DEBUG_INFO,
264 "Skipping Bochs Mode %dx%d, 32-bit (not enough vram)\n",
265 Width,
266 Height
267 ));
268 return;
269 }
270
271 ModeData->InternalModeIndex = (UINT32)Private->MaxMode;
272 ModeData->HorizontalResolution = Width;
273 ModeData->VerticalResolution = Height;
274 ModeData->ColorDepth = 32;
275 DEBUG ((
276 DEBUG_INFO,
277 "Adding Bochs Internal Mode %d: %dx%d, %d-bit\n",
278 ModeData->InternalModeIndex,
279 ModeData->HorizontalResolution,
280 ModeData->VerticalResolution,
281 ModeData->ColorDepth
282 ));
283
284 Private->MaxMode++;
285}
286
287STATIC
288VOID
289QemuVideoBochsEdid (
291 UINT32 *XRes,
292 UINT32 *YRes
293 )
294{
295 EFI_STATUS Status;
296 UINT32 X;
297 UINT32 Y;
298
299 if (Private->Variant != QEMU_VIDEO_BOCHS_MMIO) {
300 return;
301 }
302
303 Status = Private->PciIo->Mem.Read (
304 Private->PciIo,
305 EfiPciIoWidthUint8,
306 PCI_BAR_IDX2,
307 0,
308 sizeof (Private->Edid),
309 Private->Edid
310 );
311 if (Status != EFI_SUCCESS) {
312 DEBUG ((
313 DEBUG_INFO,
314 "%a: mmio read failed\n",
315 __func__
316 ));
317 return;
318 }
319
320 if ((Private->Edid[0] != 0x00) ||
321 (Private->Edid[1] != 0xff))
322 {
323 DEBUG ((
324 DEBUG_INFO,
325 "%a: magic check failed\n",
326 __func__
327 ));
328 return;
329 }
330
331 DEBUG ((
332 DEBUG_INFO,
333 "%a: blob found (extensions: %d)\n",
334 __func__,
335 Private->Edid[126]
336 ));
337
338 if ((Private->Edid[54] == 0x00) &&
339 (Private->Edid[55] == 0x00))
340 {
341 DEBUG ((
342 DEBUG_INFO,
343 "%a: no detailed timing descriptor\n",
344 __func__
345 ));
346 return;
347 }
348
349 X = Private->Edid[56] | ((Private->Edid[58] & 0xf0) << 4);
350 Y = Private->Edid[59] | ((Private->Edid[61] & 0xf0) << 4);
351 DEBUG ((
352 DEBUG_INFO,
353 "%a: default resolution: %dx%d\n",
354 __func__,
355 X,
356 Y
357 ));
358
359 if ((X < 640) || (Y < 480)) {
360 /* ignore hint, GraphicsConsoleDxe needs 640x480 or larger */
361 return;
362 }
363
364 *XRes = X;
365 *YRes = Y;
366
367 if (PcdGet8 (PcdVideoResolutionSource) == 0) {
368 Status = PcdSet32S (PcdVideoHorizontalResolution, *XRes);
369 ASSERT_RETURN_ERROR (Status);
370 Status = PcdSet32S (PcdVideoVerticalResolution, *YRes);
371 ASSERT_RETURN_ERROR (Status);
372 Status = PcdSet8S (PcdVideoResolutionSource, 2);
373 ASSERT_RETURN_ERROR (Status);
374 }
375
376 // TODO: register edid as gEfiEdidDiscoveredProtocolGuid ?
377}
378
380QemuVideoBochsModeSetup (
382 BOOLEAN IsQxl
383 )
384{
385 UINT32 AvailableFbSize;
386 UINT32 Index, XRes = 0, YRes = 0;
387
388 //
389 // Fetch the available framebuffer size.
390 //
391 // VBE_DISPI_INDEX_VIDEO_MEMORY_64K is expected to return the size of the
392 // drawable framebuffer. Up to and including qemu-2.1 however it used to
393 // return the size of PCI BAR 0 (ie. the full video RAM size).
394 //
395 // On stdvga the two concepts coincide with each other; the full memory size
396 // is usable for drawing.
397 //
398 // On QXL however, only a leading segment, "surface 0", can be used for
399 // drawing; the rest of the video memory is used for the QXL guest-host
400 // protocol. VBE_DISPI_INDEX_VIDEO_MEMORY_64K should report the size of
401 // "surface 0", but since it doesn't (up to and including qemu-2.1), we
402 // retrieve the size of the drawable portion from a field in the QXL ROM BAR,
403 // where it is also available.
404 //
405 if (IsQxl) {
406 UINT32 Signature;
407 UINT32 DrawStart;
408
409 Signature = 0;
410 DrawStart = 0xFFFFFFFF;
411 AvailableFbSize = 0;
412 if (EFI_ERROR (
413 Private->PciIo->Mem.Read (
414 Private->PciIo,
415 EfiPciIoWidthUint32,
416 PCI_BAR_IDX2,
417 0,
418 1,
419 &Signature
420 )
421 ) ||
422 (Signature != SIGNATURE_32 ('Q', 'X', 'R', 'O')) ||
423 EFI_ERROR (
424 Private->PciIo->Mem.Read (
425 Private->PciIo,
426 EfiPciIoWidthUint32,
427 PCI_BAR_IDX2,
428 36,
429 1,
430 &DrawStart
431 )
432 ) ||
433 (DrawStart != 0) ||
434 EFI_ERROR (
435 Private->PciIo->Mem.Read (
436 Private->PciIo,
437 EfiPciIoWidthUint32,
438 PCI_BAR_IDX2,
439 40,
440 1,
441 &AvailableFbSize
442 )
443 ))
444 {
445 DEBUG ((
446 DEBUG_ERROR,
447 "%a: can't read size of drawable buffer from QXL "
448 "ROM\n",
449 __func__
450 ));
451 return EFI_NOT_FOUND;
452 }
453 } else {
454 AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
455 AvailableFbSize *= SIZE_64KB;
456 }
457
458 DEBUG ((
459 DEBUG_INFO,
460 "%a: AvailableFbSize=0x%x\n",
461 __func__,
462 AvailableFbSize
463 ));
464
465 //
466 // Setup Video Modes
467 //
468 Private->ModeData = AllocatePool (
469 sizeof (Private->ModeData[0]) * (QEMU_VIDEO_BOCHS_MODE_COUNT+1)
470 );
471 if (Private->ModeData == NULL) {
472 return EFI_OUT_OF_RESOURCES;
473 }
474
475 QemuVideoBochsEdid (Private, &XRes, &YRes);
476 if (XRes && YRes) {
477 QemuVideoBochsAddMode (
478 Private,
479 AvailableFbSize,
480 XRes,
481 YRes
482 );
483 }
484
485 for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index++) {
486 if ((QemuVideoBochsModes[Index].Width == XRes) &&
487 (QemuVideoBochsModes[Index].Height == YRes))
488 {
489 continue; // duplicate with edid resolution
490 }
491
492 QemuVideoBochsAddMode (
493 Private,
494 AvailableFbSize,
495 QemuVideoBochsModes[Index].Width,
496 QemuVideoBochsModes[Index].Height
497 );
498 }
499
500 return EFI_SUCCESS;
501}
UINT64 UINTN
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define SIGNATURE_32(A, B, C, D)
Definition: Base.h:1310
#define ASSERT_RETURN_ERROR(StatusParameter)
Definition: DebugLib.h:493
#define DEBUG(Expression)
Definition: DebugLib.h:434
QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[]
Definition: Initialize.c:139
UINT8 GraphicsController[9]
Definition: Initialize.c:24
EFI_STATUS QemuVideoCirrusModeSetup(QEMU_VIDEO_PRIVATE_DATA *Private)
Definition: Initialize.c:158
UINT8 AttributeController[21]
Definition: Initialize.c:15
STATIC QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[]
Definition: Initialize.c:205
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
#define PcdSet32S(TokenName, Value)
Definition: PcdLib.h:497
#define PcdSet8S(TokenName, Value)
Definition: PcdLib.h:469
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_PCI_IO_PROTOCOL_IO_MEM Read
Definition: PciIo.h:193