]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - OvmfPkg/QemuVideoDxe/Initialize.c
OvmfPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / OvmfPkg / QemuVideoDxe / Initialize.c
... / ...
CommitLineData
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 SPDX-License-Identifier: BSD-2-Clause-Patent\r
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
140QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[] = {\r
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
149};\r
150\r
151#define QEMU_VIDEO_CIRRUS_MODE_COUNT \\r
152 (ARRAY_SIZE (QemuVideoCirrusModes))\r
153\r
154/**\r
155 Construct the valid video modes for QemuVideo.\r
156\r
157**/\r
158EFI_STATUS\r
159QemuVideoCirrusModeSetup (\r
160 QEMU_VIDEO_PRIVATE_DATA *Private\r
161 )\r
162{\r
163 UINT32 Index;\r
164 QEMU_VIDEO_MODE_DATA *ModeData;\r
165 QEMU_VIDEO_CIRRUS_MODES *VideoMode;\r
166\r
167 //\r
168 // Setup Video Modes\r
169 //\r
170 Private->ModeData = AllocatePool (\r
171 sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT\r
172 );\r
173 if (Private->ModeData == NULL) {\r
174 return EFI_OUT_OF_RESOURCES;\r
175 }\r
176 ModeData = Private->ModeData;\r
177 VideoMode = &QemuVideoCirrusModes[0];\r
178 for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) {\r
179 ModeData->InternalModeIndex = Index;\r
180 ModeData->HorizontalResolution = VideoMode->Width;\r
181 ModeData->VerticalResolution = VideoMode->Height;\r
182 ModeData->ColorDepth = VideoMode->ColorDepth;\r
183 DEBUG ((EFI_D_INFO,\r
184 "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit\n",\r
185 (INT32) (ModeData - Private->ModeData),\r
186 ModeData->InternalModeIndex,\r
187 ModeData->HorizontalResolution,\r
188 ModeData->VerticalResolution,\r
189 ModeData->ColorDepth\r
190 ));\r
191\r
192 ModeData ++ ;\r
193 VideoMode ++;\r
194 }\r
195 Private->MaxMode = ModeData - Private->ModeData;\r
196\r
197 return EFI_SUCCESS;\r
198}\r
199\r
200///\r
201/// Table of supported video modes\r
202///\r
203QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[] = {\r
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
241};\r
242\r
243#define QEMU_VIDEO_BOCHS_MODE_COUNT \\r
244 (ARRAY_SIZE (QemuVideoBochsModes))\r
245\r
246EFI_STATUS\r
247QemuVideoBochsModeSetup (\r
248 QEMU_VIDEO_PRIVATE_DATA *Private,\r
249 BOOLEAN IsQxl\r
250 )\r
251{\r
252 UINT32 AvailableFbSize;\r
253 UINT32 Index;\r
254 QEMU_VIDEO_MODE_DATA *ModeData;\r
255 QEMU_VIDEO_BOCHS_MODES *VideoMode;\r
256\r
257 //\r
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
266 //\r
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
300 DEBUG ((EFI_D_INFO, "%a: AvailableFbSize=0x%x\n", __FUNCTION__,\r
301 AvailableFbSize));\r
302\r
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
309 if (Private->ModeData == NULL) {\r
310 return EFI_OUT_OF_RESOURCES;\r
311 }\r
312 ModeData = Private->ModeData;\r
313 VideoMode = &QemuVideoBochsModes[0];\r
314 for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) {\r
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
325 DEBUG ((EFI_D_INFO,\r
326 "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit\n",\r
327 (INT32) (ModeData - Private->ModeData),\r
328 ModeData->InternalModeIndex,\r
329 ModeData->HorizontalResolution,\r
330 ModeData->VerticalResolution,\r
331 ModeData->ColorDepth\r
332 ));\r
333\r
334 ModeData ++ ;\r
335 }\r
336 VideoMode ++;\r
337 }\r
338 Private->MaxMode = ModeData - Private->ModeData;\r
339\r
340 return EFI_SUCCESS;\r
341}\r
342\r