]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/QemuVideoDxe/Driver.c
QemuVideo: prepare to support more hardware
[mirror_edk2.git] / OvmfPkg / QemuVideoDxe / Driver.c
CommitLineData
eaf4f336 1/** @file\r
2 This driver is a sample implementation of the Graphics Output Protocol for\r
3 the QEMU (Cirrus Logic 5446) video controller.\r
4\r
5 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
6\r
7 This program and the accompanying materials\r
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "Qemu.h"\r
18\r
19EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {\r
20 QemuVideoControllerDriverSupported,\r
21 QemuVideoControllerDriverStart,\r
22 QemuVideoControllerDriverStop,\r
23 0x10,\r
24 NULL,\r
25 NULL\r
26};\r
27\r
212aac55 28QEMU_VIDEO_CARD gQemuVideoCardList[] = {\r
29 {\r
30 CIRRUS_LOGIC_VENDOR_ID,\r
31 CIRRUS_LOGIC_5430_DEVICE_ID,\r
32 QEMU_VIDEO_CIRRUS_5430,\r
33 L"Cirrus 5430"\r
34 },{\r
35 CIRRUS_LOGIC_VENDOR_ID,\r
36 CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID,\r
37 QEMU_VIDEO_CIRRUS_5430,\r
38 L"Cirrus 5430"\r
39 },{\r
40 CIRRUS_LOGIC_VENDOR_ID,\r
41 CIRRUS_LOGIC_5446_DEVICE_ID,\r
42 QEMU_VIDEO_CIRRUS_5446,\r
43 L"Cirrus 5446"\r
44 },{\r
45 0 /* end of list */\r
46 }\r
47};\r
48\r
49static QEMU_VIDEO_CARD*\r
50QemuVideoDetect(\r
51 IN UINT16 VendorId,\r
52 IN UINT16 DeviceId\r
53 )\r
54{\r
55 UINTN Index = 0;\r
56\r
57 while (gQemuVideoCardList[Index].VendorId != 0) {\r
58 if (gQemuVideoCardList[Index].VendorId == VendorId &&\r
59 gQemuVideoCardList[Index].DeviceId == DeviceId) {\r
60 return gQemuVideoCardList + Index;\r
61 }\r
62 Index++;\r
63 }\r
64 return NULL;\r
65}\r
66\r
eaf4f336 67/**\r
68 Check if this device is supported.\r
69\r
70 @param This The driver binding protocol.\r
71 @param Controller The controller handle to check.\r
72 @param RemainingDevicePath The remaining device path.\r
73\r
74 @retval EFI_SUCCESS The bus supports this controller.\r
75 @retval EFI_UNSUPPORTED This device isn't supported.\r
76\r
77**/\r
78EFI_STATUS\r
79EFIAPI\r
80QemuVideoControllerDriverSupported (\r
81 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
82 IN EFI_HANDLE Controller,\r
83 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
84 )\r
85{\r
86 EFI_STATUS Status;\r
87 EFI_PCI_IO_PROTOCOL *PciIo;\r
88 PCI_TYPE00 Pci;\r
89 EFI_DEV_PATH *Node;\r
212aac55 90 QEMU_VIDEO_CARD *Card;\r
eaf4f336 91\r
92 //\r
93 // Open the PCI I/O Protocol\r
94 //\r
95 Status = gBS->OpenProtocol (\r
96 Controller,\r
97 &gEfiPciIoProtocolGuid,\r
98 (VOID **) &PciIo,\r
99 This->DriverBindingHandle,\r
100 Controller,\r
101 EFI_OPEN_PROTOCOL_BY_DRIVER\r
102 );\r
103 if (EFI_ERROR (Status)) {\r
104 return Status;\r
105 }\r
106\r
107 //\r
108 // Read the PCI Configuration Header from the PCI Device\r
109 //\r
110 Status = PciIo->Pci.Read (\r
111 PciIo,\r
112 EfiPciIoWidthUint32,\r
113 0,\r
114 sizeof (Pci) / sizeof (UINT32),\r
115 &Pci\r
116 );\r
117 if (EFI_ERROR (Status)) {\r
118 goto Done;\r
119 }\r
120\r
121 Status = EFI_UNSUPPORTED;\r
122 //\r
123 // See if the I/O enable is on. Most systems only allow one VGA device to be turned on\r
124 // at a time, so see if this is one that is turned on.\r
125 //\r
126 // if (((Pci.Hdr.Command & 0x01) == 0x01)) {\r
127 //\r
128 // See if this is a Cirrus Logic PCI controller\r
129 //\r
212aac55 130 Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
131 if (Card != NULL) {\r
132 DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name));\r
133 Status = EFI_SUCCESS;\r
eaf4f336 134 //\r
212aac55 135 // If this is an Intel 945 graphics controller,\r
136 // go further check RemainingDevicePath validation\r
eaf4f336 137 //\r
212aac55 138 if (RemainingDevicePath != NULL) {\r
139 Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
eaf4f336 140 //\r
212aac55 141 // Check if RemainingDevicePath is the End of Device Path Node, \r
142 // if yes, return EFI_SUCCESS\r
eaf4f336 143 //\r
212aac55 144 if (!IsDevicePathEnd (Node)) {\r
eaf4f336 145 //\r
212aac55 146 // If RemainingDevicePath isn't the End of Device Path Node,\r
147 // check its validation\r
eaf4f336 148 //\r
212aac55 149 if (Node->DevPath.Type != ACPI_DEVICE_PATH ||\r
150 Node->DevPath.SubType != ACPI_ADR_DP ||\r
151 DevicePathNodeLength(&Node->DevPath) != sizeof(ACPI_ADR_DEVICE_PATH)) {\r
152 Status = EFI_UNSUPPORTED;\r
eaf4f336 153 }\r
154 }\r
155 }\r
156 }\r
157\r
158Done:\r
159 //\r
160 // Close the PCI I/O Protocol\r
161 //\r
162 gBS->CloseProtocol (\r
163 Controller,\r
164 &gEfiPciIoProtocolGuid,\r
165 This->DriverBindingHandle,\r
166 Controller\r
167 );\r
168\r
169 return Status;\r
170}\r
171\r
172/**\r
173 Start to process the controller.\r
174\r
175 @param This The USB bus driver binding instance.\r
176 @param Controller The controller to check.\r
177 @param RemainingDevicePath The remaining device patch.\r
178\r
179 @retval EFI_SUCCESS The controller is controlled by the usb bus.\r
180 @retval EFI_ALREADY_STARTED The controller is already controlled by the usb\r
181 bus.\r
182 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.\r
183\r
184**/\r
185EFI_STATUS\r
186EFIAPI\r
187QemuVideoControllerDriverStart (\r
188 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
189 IN EFI_HANDLE Controller,\r
190 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
191 )\r
192{\r
193 EFI_STATUS Status;\r
194 QEMU_VIDEO_PRIVATE_DATA *Private;\r
195 BOOLEAN PciAttributesSaved;\r
196 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
197 ACPI_ADR_DEVICE_PATH AcpiDeviceNode;\r
212aac55 198 PCI_TYPE00 Pci;\r
199 QEMU_VIDEO_CARD *Card;\r
200 \r
eaf4f336 201 PciAttributesSaved = FALSE;\r
202 //\r
203 // Allocate Private context data for GOP inteface.\r
204 //\r
205 Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA));\r
206 if (Private == NULL) {\r
207 Status = EFI_OUT_OF_RESOURCES;\r
208 goto Error;\r
209 }\r
210\r
211 //\r
212 // Set up context record\r
213 //\r
214 Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE;\r
215 Private->Handle = NULL;\r
216\r
217 //\r
218 // Open PCI I/O Protocol\r
219 //\r
220 Status = gBS->OpenProtocol (\r
221 Controller,\r
222 &gEfiPciIoProtocolGuid,\r
223 (VOID **) &Private->PciIo,\r
224 This->DriverBindingHandle,\r
225 Controller,\r
226 EFI_OPEN_PROTOCOL_BY_DRIVER\r
227 );\r
228 if (EFI_ERROR (Status)) {\r
229 goto Error;\r
230 }\r
231\r
212aac55 232 //\r
233 // Read the PCI Configuration Header from the PCI Device\r
234 //\r
235 Status = Private->PciIo->Pci.Read (\r
236 Private->PciIo,\r
237 EfiPciIoWidthUint32,\r
238 0,\r
239 sizeof (Pci) / sizeof (UINT32),\r
240 &Pci\r
241 );\r
242 if (EFI_ERROR (Status)) {\r
243 goto Error;\r
244 }\r
245\r
246 Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
247 if (Card == NULL) {\r
248 Status = EFI_DEVICE_ERROR;\r
249 goto Error;\r
250 }\r
251 Private->Variant = Card->Variant;\r
252\r
eaf4f336 253 //\r
254 // Save original PCI attributes\r
255 //\r
256 Status = Private->PciIo->Attributes (\r
257 Private->PciIo,\r
258 EfiPciIoAttributeOperationGet,\r
259 0,\r
260 &Private->OriginalPciAttributes\r
261 );\r
262\r
263 if (EFI_ERROR (Status)) {\r
264 goto Error;\r
265 }\r
266 PciAttributesSaved = TRUE;\r
267\r
268 Status = Private->PciIo->Attributes (\r
269 Private->PciIo,\r
270 EfiPciIoAttributeOperationEnable,\r
271 EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r
272 NULL\r
273 );\r
274 if (EFI_ERROR (Status)) {\r
275 goto Error;\r
276 }\r
277\r
278 //\r
279 // Get ParentDevicePath\r
280 //\r
281 Status = gBS->HandleProtocol (\r
282 Controller,\r
283 &gEfiDevicePathProtocolGuid,\r
284 (VOID **) &ParentDevicePath\r
285 );\r
286 if (EFI_ERROR (Status)) {\r
287 goto Error;\r
288 }\r
289\r
290 //\r
291 // Set Gop Device Path\r
292 //\r
293 if (RemainingDevicePath == NULL) {\r
294 ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));\r
295 AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;\r
296 AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;\r
297 AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);\r
298 SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
299\r
300 Private->GopDevicePath = AppendDevicePathNode (\r
301 ParentDevicePath,\r
302 (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
303 );\r
304 } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
305 //\r
306 // If RemainingDevicePath isn't the End of Device Path Node, \r
307 // only scan the specified device by RemainingDevicePath\r
308 //\r
309 Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);\r
310 } else {\r
311 //\r
312 // If RemainingDevicePath is the End of Device Path Node, \r
313 // don't create child device and return EFI_SUCCESS\r
314 //\r
315 Private->GopDevicePath = NULL;\r
316 }\r
317 \r
318 if (Private->GopDevicePath != NULL) {\r
319 //\r
320 // Creat child handle and device path protocol firstly\r
321 //\r
322 Private->Handle = NULL;\r
323 Status = gBS->InstallMultipleProtocolInterfaces (\r
324 &Private->Handle,\r
325 &gEfiDevicePathProtocolGuid,\r
326 Private->GopDevicePath,\r
327 NULL\r
328 );\r
329 }\r
330\r
331 //\r
332 // Construct video mode buffer\r
333 //\r
212aac55 334 switch (Private->Variant) {\r
335 case QEMU_VIDEO_CIRRUS_5430:\r
336 case QEMU_VIDEO_CIRRUS_5446:\r
337 Status = QemuVideoCirrusModeSetup (Private);\r
338 break;\r
339 default:\r
340 ASSERT (FALSE);\r
341 Status = EFI_DEVICE_ERROR;\r
342 break;\r
343 }\r
eaf4f336 344 if (EFI_ERROR (Status)) {\r
345 goto Error;\r
346 }\r
347\r
348 if (Private->GopDevicePath == NULL) {\r
349 //\r
350 // If RemainingDevicePath is the End of Device Path Node, \r
351 // don't create child device and return EFI_SUCCESS\r
352 //\r
353 Status = EFI_SUCCESS;\r
354 } else {\r
355\r
356 //\r
357 // Start the GOP software stack.\r
358 //\r
359 Status = QemuVideoGraphicsOutputConstructor (Private);\r
360 ASSERT_EFI_ERROR (Status);\r
361\r
362 Status = gBS->InstallMultipleProtocolInterfaces (\r
363 &Private->Handle,\r
364 &gEfiGraphicsOutputProtocolGuid,\r
365 &Private->GraphicsOutput,\r
366 NULL\r
367 );\r
368 }\r
369\r
370Error:\r
371 if (EFI_ERROR (Status)) {\r
372 if (Private) {\r
373 if (Private->PciIo) {\r
374 if (PciAttributesSaved == TRUE) {\r
375 //\r
376 // Restore original PCI attributes\r
377 //\r
378 Private->PciIo->Attributes (\r
379 Private->PciIo,\r
380 EfiPciIoAttributeOperationSet,\r
381 Private->OriginalPciAttributes,\r
382 NULL\r
383 );\r
384 }\r
385 //\r
386 // Close the PCI I/O Protocol\r
387 //\r
388 gBS->CloseProtocol (\r
389 Private->Handle,\r
390 &gEfiPciIoProtocolGuid,\r
391 This->DriverBindingHandle,\r
392 Private->Handle\r
393 );\r
394 }\r
395\r
396 gBS->FreePool (Private);\r
397 }\r
398 }\r
399\r
400 return Status;\r
401}\r
402\r
403/**\r
404 Stop this device\r
405\r
406 @param This The USB bus driver binding protocol.\r
407 @param Controller The controller to release.\r
408 @param NumberOfChildren The number of children of this device that\r
409 opened the controller BY_CHILD.\r
410 @param ChildHandleBuffer The array of child handle.\r
411\r
412 @retval EFI_SUCCESS The controller or children are stopped.\r
413 @retval EFI_DEVICE_ERROR Failed to stop the driver.\r
414\r
415**/\r
416EFI_STATUS\r
417EFIAPI\r
418QemuVideoControllerDriverStop (\r
419 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
420 IN EFI_HANDLE Controller,\r
421 IN UINTN NumberOfChildren,\r
422 IN EFI_HANDLE *ChildHandleBuffer\r
423 )\r
424{\r
425 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
426\r
427 EFI_STATUS Status;\r
428 QEMU_VIDEO_PRIVATE_DATA *Private;\r
429\r
430 Status = gBS->OpenProtocol (\r
431 Controller,\r
432 &gEfiGraphicsOutputProtocolGuid,\r
433 (VOID **) &GraphicsOutput,\r
434 This->DriverBindingHandle,\r
435 Controller,\r
436 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
437 );\r
438 if (EFI_ERROR (Status)) {\r
439 return Status;\r
440 }\r
441\r
442 //\r
443 // Get our private context information\r
444 //\r
445 Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);\r
446\r
447 QemuVideoGraphicsOutputDestructor (Private);\r
448 //\r
449 // Remove the GOP protocol interface from the system\r
450 //\r
451 Status = gBS->UninstallMultipleProtocolInterfaces (\r
452 Private->Handle,\r
453 &gEfiGraphicsOutputProtocolGuid,\r
454 &Private->GraphicsOutput,\r
455 NULL\r
456 );\r
457\r
458 if (EFI_ERROR (Status)) {\r
459 return Status;\r
460 }\r
461\r
462 //\r
463 // Restore original PCI attributes\r
464 //\r
465 Private->PciIo->Attributes (\r
466 Private->PciIo,\r
467 EfiPciIoAttributeOperationSet,\r
468 Private->OriginalPciAttributes,\r
469 NULL\r
470 );\r
471\r
472 //\r
473 // Close the PCI I/O Protocol\r
474 //\r
475 gBS->CloseProtocol (\r
476 Controller,\r
477 &gEfiPciIoProtocolGuid,\r
478 This->DriverBindingHandle,\r
479 Controller\r
480 );\r
481\r
482 //\r
483 // Free our instance data\r
484 //\r
485 gBS->FreePool (Private);\r
486\r
487 return EFI_SUCCESS;\r
488}\r
489\r
490/**\r
491 TODO: Add function description\r
492\r
493 @param Private TODO: add argument description\r
494 @param Address TODO: add argument description\r
495 @param Data TODO: add argument description\r
496\r
497 TODO: add return values\r
498\r
499**/\r
500VOID\r
501outb (\r
502 QEMU_VIDEO_PRIVATE_DATA *Private,\r
503 UINTN Address,\r
504 UINT8 Data\r
505 )\r
506{\r
507 Private->PciIo->Io.Write (\r
508 Private->PciIo,\r
509 EfiPciIoWidthUint8,\r
510 EFI_PCI_IO_PASS_THROUGH_BAR,\r
511 Address,\r
512 1,\r
513 &Data\r
514 );\r
515}\r
516\r
517/**\r
518 TODO: Add function description\r
519\r
520 @param Private TODO: add argument description\r
521 @param Address TODO: add argument description\r
522 @param Data TODO: add argument description\r
523\r
524 TODO: add return values\r
525\r
526**/\r
527VOID\r
528outw (\r
529 QEMU_VIDEO_PRIVATE_DATA *Private,\r
530 UINTN Address,\r
531 UINT16 Data\r
532 )\r
533{\r
534 Private->PciIo->Io.Write (\r
535 Private->PciIo,\r
536 EfiPciIoWidthUint16,\r
537 EFI_PCI_IO_PASS_THROUGH_BAR,\r
538 Address,\r
539 1,\r
540 &Data\r
541 );\r
542}\r
543\r
544/**\r
545 TODO: Add function description\r
546\r
547 @param Private TODO: add argument description\r
548 @param Address TODO: add argument description\r
549\r
550 TODO: add return values\r
551\r
552**/\r
553UINT8\r
554inb (\r
555 QEMU_VIDEO_PRIVATE_DATA *Private,\r
556 UINTN Address\r
557 )\r
558{\r
559 UINT8 Data;\r
560\r
561 Private->PciIo->Io.Read (\r
562 Private->PciIo,\r
563 EfiPciIoWidthUint8,\r
564 EFI_PCI_IO_PASS_THROUGH_BAR,\r
565 Address,\r
566 1,\r
567 &Data\r
568 );\r
569 return Data;\r
570}\r
571\r
572/**\r
573 TODO: Add function description\r
574\r
575 @param Private TODO: add argument description\r
576 @param Address TODO: add argument description\r
577\r
578 TODO: add return values\r
579\r
580**/\r
581UINT16\r
582inw (\r
583 QEMU_VIDEO_PRIVATE_DATA *Private,\r
584 UINTN Address\r
585 )\r
586{\r
587 UINT16 Data;\r
588\r
589 Private->PciIo->Io.Read (\r
590 Private->PciIo,\r
591 EfiPciIoWidthUint16,\r
592 EFI_PCI_IO_PASS_THROUGH_BAR,\r
593 Address,\r
594 1,\r
595 &Data\r
596 );\r
597 return Data;\r
598}\r
599\r
600/**\r
601 TODO: Add function description\r
602\r
603 @param Private TODO: add argument description\r
604 @param Index TODO: add argument description\r
605 @param Red TODO: add argument description\r
606 @param Green TODO: add argument description\r
607 @param Blue TODO: add argument description\r
608\r
609 TODO: add return values\r
610\r
611**/\r
612VOID\r
613SetPaletteColor (\r
614 QEMU_VIDEO_PRIVATE_DATA *Private,\r
615 UINTN Index,\r
616 UINT8 Red,\r
617 UINT8 Green,\r
618 UINT8 Blue\r
619 )\r
620{\r
621 outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);\r
622 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));\r
623 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));\r
624 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));\r
625}\r
626\r
627/**\r
628 TODO: Add function description\r
629\r
630 @param Private TODO: add argument description\r
631\r
632 TODO: add return values\r
633\r
634**/\r
635VOID\r
636SetDefaultPalette (\r
637 QEMU_VIDEO_PRIVATE_DATA *Private\r
638 )\r
639{\r
640 UINTN Index;\r
641 UINTN RedIndex;\r
642 UINTN GreenIndex;\r
643 UINTN BlueIndex;\r
644\r
645 Index = 0;\r
646 for (RedIndex = 0; RedIndex < 8; RedIndex++) {\r
647 for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {\r
648 for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {\r
649 SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));\r
650 Index++;\r
651 }\r
652 }\r
653 }\r
654}\r
655\r
656/**\r
657 TODO: Add function description\r
658\r
659 @param Private TODO: add argument description\r
660\r
661 TODO: add return values\r
662\r
663**/\r
664VOID\r
665ClearScreen (\r
666 QEMU_VIDEO_PRIVATE_DATA *Private\r
667 )\r
668{\r
669 UINT32 Color;\r
670\r
671 Color = 0;\r
672 Private->PciIo->Mem.Write (\r
673 Private->PciIo,\r
674 EfiPciIoWidthFillUint32,\r
675 0,\r
676 0,\r
677 0x400000 >> 2,\r
678 &Color\r
679 );\r
680}\r
681\r
682/**\r
683 TODO: Add function description\r
684\r
685 @param Private TODO: add argument description\r
686\r
687 TODO: add return values\r
688\r
689**/\r
690VOID\r
691DrawLogo (\r
692 QEMU_VIDEO_PRIVATE_DATA *Private,\r
693 UINTN ScreenWidth,\r
694 UINTN ScreenHeight\r
695 )\r
696{\r
697}\r
698\r
699/**\r
700 TODO: Add function description\r
701\r
702 @param Private TODO: add argument description\r
703 @param ModeData TODO: add argument description\r
704\r
705 TODO: add return values\r
706\r
707**/\r
708VOID\r
212aac55 709InitializeCirrusGraphicsMode (\r
eaf4f336 710 QEMU_VIDEO_PRIVATE_DATA *Private,\r
212aac55 711 QEMU_VIDEO_CIRRUS_MODES *ModeData\r
eaf4f336 712 )\r
713{\r
714 UINT8 Byte;\r
715 UINTN Index;\r
eaf4f336 716\r
717 outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);\r
718 outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);\r
719\r
720 for (Index = 0; Index < 15; Index++) {\r
721 outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);\r
722 }\r
723\r
212aac55 724 if (Private->Variant == QEMU_VIDEO_CIRRUS_5430) {\r
eaf4f336 725 outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);\r
726 Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);\r
727 outb (Private, SEQ_DATA_REGISTER, Byte);\r
728 }\r
729\r
730 outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);\r
731 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);\r
732 outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);\r
733 outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);\r
734\r
735 for (Index = 0; Index < 28; Index++) {\r
736 outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));\r
737 }\r
738\r
739 for (Index = 0; Index < 9; Index++) {\r
740 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));\r
741 }\r
742\r
743 inb (Private, INPUT_STATUS_1_REGISTER);\r
744\r
745 for (Index = 0; Index < 21; Index++) {\r
746 outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);\r
747 outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);\r
748 }\r
749\r
750 outb (Private, ATT_ADDRESS_REGISTER, 0x20);\r
751\r
752 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);\r
753 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);\r
754 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);\r
755 outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);\r
756\r
757 SetDefaultPalette (Private);\r
758 ClearScreen (Private);\r
759}\r
760\r
761EFI_STATUS\r
762EFIAPI\r
763InitializeQemuVideo (\r
764 IN EFI_HANDLE ImageHandle,\r
765 IN EFI_SYSTEM_TABLE *SystemTable\r
766 )\r
767{\r
768 EFI_STATUS Status;\r
769\r
770 Status = EfiLibInstallDriverBindingComponentName2 (\r
771 ImageHandle,\r
772 SystemTable,\r
773 &gQemuVideoDriverBinding,\r
774 ImageHandle,\r
775 &gQemuVideoComponentName,\r
776 &gQemuVideoComponentName2\r
777 );\r
778 ASSERT_EFI_ERROR (Status);\r
779\r
780 //\r
781 // Install EFI Driver Supported EFI Version Protocol required for\r
782 // EFI drivers that are on PCI and other plug in cards.\r
783 //\r
784 gQemuVideoDriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);\r
785 Status = gBS->InstallMultipleProtocolInterfaces (\r
786 &ImageHandle,\r
787 &gEfiDriverSupportedEfiVersionProtocolGuid,\r
788 &gQemuVideoDriverSupportedEfiVersion,\r
789 NULL\r
790 );\r
791 ASSERT_EFI_ERROR (Status);\r
792\r
793 return Status;\r
794}\r