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