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