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