2 Cirrus Logic 5430 Controller Driver.
3 This driver is a sample implementation of the UGA Draw and Graphics Output
4 Protocols for the Cirrus Logic 5430 family of PCI video controllers.
5 This driver is only usable in the EFI pre-boot environment.
6 This sample is intended to show how the UGA Draw and Graphics output Protocol
8 The UGA I/O Protocol is not implemented in this sample.
9 A fully compliant EFI UGA driver requires both
10 the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's
11 documentation on UGA for details on how to write a UGA driver that is able
12 to function both in the EFI pre-boot environment and from the OS runtime.
14 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
15 SPDX-License-Identifier: BSD-2-Clause-Patent
20 // Cirrus Logic 5430 Controller Driver
22 #include "CirrusLogic5430.h"
24 EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding
= {
25 CirrusLogic5430ControllerDriverSupported
,
26 CirrusLogic5430ControllerDriverStart
,
27 CirrusLogic5430ControllerDriverStop
,
34 /// Generic Attribute Controller Register Settings
36 UINT8 AttributeController
[21] = {
37 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
38 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
39 0x41, 0x00, 0x0F, 0x00, 0x00
43 /// Generic Graphics Controller Register Settings
45 UINT8 GraphicsController
[9] = {
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
50 // 640 x 480 x 256 color @ 60 Hertz
52 UINT8 Crtc_640_480_256_60
[28] = {
53 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
54 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
56 0xff, 0x00, 0x00, 0x22
59 UINT16 Seq_640_480_256_60
[15] = {
60 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
61 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
65 // 800 x 600 x 256 color @ 60 Hertz
67 UINT8 Crtc_800_600_256_60
[28] = {
68 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
69 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
71 0xFF, 0x00, 0x00, 0x22
74 UINT16 Seq_800_600_256_60
[15] = {
75 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
76 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
80 // 1024 x 768 x 256 color @ 60 Hertz
82 UINT8 Crtc_1024_768_256_60
[28] = {
83 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
84 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
86 0xFF, 0x4A, 0x00, 0x22
89 UINT16 Seq_1024_768_256_60
[15] = {
90 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
91 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
95 /// Table of supported video modes
97 CIRRUS_LOGIC_5430_VIDEO_MODES CirrusLogic5430VideoModes
[] = {
98 { 640, 480, 8, 60, Crtc_640_480_256_60
, Seq_640_480_256_60
, 0xe3 },
99 { 800, 600, 8, 60, Crtc_800_600_256_60
, Seq_800_600_256_60
, 0xef },
100 { 1024, 768, 8, 60, Crtc_1024_768_256_60
, Seq_1024_768_256_60
, 0xef }
105 CirrusLogic5430ControllerDriverSupported
107 TODO: This - add argument and description to function comment
108 TODO: Controller - add argument and description to function comment
109 TODO: RemainingDevicePath - add argument and description to function comment
113 CirrusLogic5430ControllerDriverSupported (
114 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
115 IN EFI_HANDLE Controller
,
116 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
120 EFI_PCI_IO_PROTOCOL
*PciIo
;
125 // Open the PCI I/O Protocol
127 Status
= gBS
->OpenProtocol (
129 &gEfiPciIoProtocolGuid
,
131 This
->DriverBindingHandle
,
133 EFI_OPEN_PROTOCOL_BY_DRIVER
135 if (EFI_ERROR (Status
)) {
140 // Read the PCI Configuration Header from the PCI Device
142 Status
= PciIo
->Pci
.Read (
146 sizeof (Pci
) / sizeof (UINT32
),
149 if (EFI_ERROR (Status
)) {
153 Status
= EFI_UNSUPPORTED
;
155 // See if the I/O enable is on. Most systems only allow one VGA device to be turned on
156 // at a time, so see if this is one that is turned on.
158 // if (((Pci.Hdr.Command & 0x01) == 0x01)) {
160 // See if this is a Cirrus Logic PCI controller
162 if (Pci
.Hdr
.VendorId
== CIRRUS_LOGIC_VENDOR_ID
) {
164 // See if this is a 5430 or a 5446 PCI controller
166 if (Pci
.Hdr
.DeviceId
== CIRRUS_LOGIC_5430_DEVICE_ID
||
167 Pci
.Hdr
.DeviceId
== CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID
||
168 Pci
.Hdr
.DeviceId
== CIRRUS_LOGIC_5446_DEVICE_ID
) {
170 Status
= EFI_SUCCESS
;
172 // If this is an Intel 945 graphics controller,
173 // go further check RemainingDevicePath validation
175 if (RemainingDevicePath
!= NULL
) {
176 Node
= (EFI_DEV_PATH
*) RemainingDevicePath
;
178 // Check if RemainingDevicePath is the End of Device Path Node,
179 // if yes, return EFI_SUCCESS
181 if (!IsDevicePathEnd (Node
)) {
183 // If RemainingDevicePath isn't the End of Device Path Node,
184 // check its validation
186 if (Node
->DevPath
.Type
!= ACPI_DEVICE_PATH
||
187 Node
->DevPath
.SubType
!= ACPI_ADR_DP
||
188 DevicePathNodeLength(&Node
->DevPath
) != sizeof(ACPI_ADR_DEVICE_PATH
)) {
189 Status
= EFI_UNSUPPORTED
;
198 // Close the PCI I/O Protocol
202 &gEfiPciIoProtocolGuid
,
203 This
->DriverBindingHandle
,
211 CirrusLogic5430ControllerDriverStart
213 TODO: This - add argument and description to function comment
214 TODO: Controller - add argument and description to function comment
215 TODO: RemainingDevicePath - add argument and description to function comment
219 CirrusLogic5430ControllerDriverStart (
220 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
221 IN EFI_HANDLE Controller
,
222 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
226 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
227 BOOLEAN PciAttributesSaved
;
228 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
229 ACPI_ADR_DEVICE_PATH AcpiDeviceNode
;
232 PciAttributesSaved
= FALSE
;
234 // Allocate Private context data for UGA Draw inteface.
236 Private
= AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA
));
237 if (Private
== NULL
) {
238 Status
= EFI_OUT_OF_RESOURCES
;
243 // Set up context record
245 Private
->Signature
= CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE
;
246 Private
->Handle
= NULL
;
249 // Open PCI I/O Protocol
251 Status
= gBS
->OpenProtocol (
253 &gEfiPciIoProtocolGuid
,
254 (VOID
**) &Private
->PciIo
,
255 This
->DriverBindingHandle
,
257 EFI_OPEN_PROTOCOL_BY_DRIVER
259 if (EFI_ERROR (Status
)) {
264 // Get supported PCI attributes
266 Status
= Private
->PciIo
->Attributes (
268 EfiPciIoAttributeOperationSupported
,
272 if (EFI_ERROR (Status
)) {
276 Supports
&= (EFI_PCI_IO_ATTRIBUTE_VGA_IO
| EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
);
277 if (Supports
== 0 || Supports
== (EFI_PCI_IO_ATTRIBUTE_VGA_IO
| EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
)) {
278 Status
= EFI_UNSUPPORTED
;
283 // Save original PCI attributes
285 Status
= Private
->PciIo
->Attributes (
287 EfiPciIoAttributeOperationGet
,
289 &Private
->OriginalPciAttributes
292 if (EFI_ERROR (Status
)) {
295 PciAttributesSaved
= TRUE
;
297 Status
= Private
->PciIo
->Attributes (
299 EfiPciIoAttributeOperationEnable
,
300 EFI_PCI_DEVICE_ENABLE
| EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
| Supports
,
303 if (EFI_ERROR (Status
)) {
308 // Get ParentDevicePath
310 Status
= gBS
->HandleProtocol (
312 &gEfiDevicePathProtocolGuid
,
313 (VOID
**) &ParentDevicePath
315 if (EFI_ERROR (Status
)) {
319 if (FeaturePcdGet (PcdSupportGop
)) {
321 // Set Gop Device Path
323 if (RemainingDevicePath
== NULL
) {
324 ZeroMem (&AcpiDeviceNode
, sizeof (ACPI_ADR_DEVICE_PATH
));
325 AcpiDeviceNode
.Header
.Type
= ACPI_DEVICE_PATH
;
326 AcpiDeviceNode
.Header
.SubType
= ACPI_ADR_DP
;
327 AcpiDeviceNode
.ADR
= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA
, 0, 0);
328 SetDevicePathNodeLength (&AcpiDeviceNode
.Header
, sizeof (ACPI_ADR_DEVICE_PATH
));
330 Private
->GopDevicePath
= AppendDevicePathNode (
332 (EFI_DEVICE_PATH_PROTOCOL
*) &AcpiDeviceNode
334 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
336 // If RemainingDevicePath isn't the End of Device Path Node,
337 // only scan the specified device by RemainingDevicePath
339 Private
->GopDevicePath
= AppendDevicePathNode (ParentDevicePath
, RemainingDevicePath
);
342 // If RemainingDevicePath is the End of Device Path Node,
343 // don't create child device and return EFI_SUCCESS
345 Private
->GopDevicePath
= NULL
;
348 if (Private
->GopDevicePath
!= NULL
) {
350 // Creat child handle and device path protocol firstly
352 Private
->Handle
= NULL
;
353 Status
= gBS
->InstallMultipleProtocolInterfaces (
355 &gEfiDevicePathProtocolGuid
,
356 Private
->GopDevicePath
,
363 // Construct video mode buffer
365 Status
= CirrusLogic5430VideoModeSetup (Private
);
366 if (EFI_ERROR (Status
)) {
370 if (FeaturePcdGet (PcdSupportUga
)) {
372 // Start the UGA Draw software stack.
374 Status
= CirrusLogic5430UgaDrawConstructor (Private
);
375 ASSERT_EFI_ERROR (Status
);
377 Private
->UgaDevicePath
= ParentDevicePath
;
378 Status
= gBS
->InstallMultipleProtocolInterfaces (
380 &gEfiUgaDrawProtocolGuid
,
382 &gEfiDevicePathProtocolGuid
,
383 Private
->UgaDevicePath
,
387 } else if (FeaturePcdGet (PcdSupportGop
)) {
388 if (Private
->GopDevicePath
== NULL
) {
390 // If RemainingDevicePath is the End of Device Path Node,
391 // don't create child device and return EFI_SUCCESS
393 Status
= EFI_SUCCESS
;
397 // Start the GOP software stack.
399 Status
= CirrusLogic5430GraphicsOutputConstructor (Private
);
400 ASSERT_EFI_ERROR (Status
);
402 Status
= gBS
->InstallMultipleProtocolInterfaces (
404 &gEfiGraphicsOutputProtocolGuid
,
405 &Private
->GraphicsOutput
,
406 &gEfiEdidDiscoveredProtocolGuid
,
407 &Private
->EdidDiscovered
,
408 &gEfiEdidActiveProtocolGuid
,
409 &Private
->EdidActive
,
415 // This driver must support eithor GOP or UGA or both.
418 Status
= EFI_UNSUPPORTED
;
423 if (EFI_ERROR (Status
)) {
425 if (Private
->PciIo
) {
426 if (PciAttributesSaved
== TRUE
) {
428 // Restore original PCI attributes
430 Private
->PciIo
->Attributes (
432 EfiPciIoAttributeOperationSet
,
433 Private
->OriginalPciAttributes
,
438 // Close the PCI I/O Protocol
442 &gEfiPciIoProtocolGuid
,
443 This
->DriverBindingHandle
,
448 gBS
->FreePool (Private
);
456 CirrusLogic5430ControllerDriverStop
458 TODO: This - add argument and description to function comment
459 TODO: Controller - add argument and description to function comment
460 TODO: NumberOfChildren - add argument and description to function comment
461 TODO: ChildHandleBuffer - add argument and description to function comment
462 TODO: EFI_SUCCESS - add return value to function comment
466 CirrusLogic5430ControllerDriverStop (
467 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
468 IN EFI_HANDLE Controller
,
469 IN UINTN NumberOfChildren
,
470 IN EFI_HANDLE
*ChildHandleBuffer
473 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
474 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
477 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
479 if (FeaturePcdGet (PcdSupportUga
)) {
480 Status
= gBS
->OpenProtocol (
482 &gEfiUgaDrawProtocolGuid
,
484 This
->DriverBindingHandle
,
486 EFI_OPEN_PROTOCOL_GET_PROTOCOL
488 if (EFI_ERROR (Status
)) {
492 // Get our private context information
494 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw
);
495 CirrusLogic5430UgaDrawDestructor (Private
);
497 if (FeaturePcdGet (PcdSupportGop
)) {
498 CirrusLogic5430GraphicsOutputDestructor (Private
);
500 // Remove the UGA and GOP protocol interface from the system
502 Status
= gBS
->UninstallMultipleProtocolInterfaces (
504 &gEfiUgaDrawProtocolGuid
,
506 &gEfiGraphicsOutputProtocolGuid
,
507 &Private
->GraphicsOutput
,
512 // Remove the UGA Draw interface from the system
514 Status
= gBS
->UninstallMultipleProtocolInterfaces (
516 &gEfiUgaDrawProtocolGuid
,
522 Status
= gBS
->OpenProtocol (
524 &gEfiGraphicsOutputProtocolGuid
,
525 (VOID
**) &GraphicsOutput
,
526 This
->DriverBindingHandle
,
528 EFI_OPEN_PROTOCOL_GET_PROTOCOL
530 if (EFI_ERROR (Status
)) {
535 // Get our private context information
537 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput
);
539 CirrusLogic5430GraphicsOutputDestructor (Private
);
541 // Remove the GOP protocol interface from the system
543 Status
= gBS
->UninstallMultipleProtocolInterfaces (
545 &gEfiUgaDrawProtocolGuid
,
547 &gEfiGraphicsOutputProtocolGuid
,
548 &Private
->GraphicsOutput
,
553 if (EFI_ERROR (Status
)) {
558 // Restore original PCI attributes
560 Private
->PciIo
->Attributes (
562 EfiPciIoAttributeOperationSet
,
563 Private
->OriginalPciAttributes
,
568 // Close the PCI I/O Protocol
572 &gEfiPciIoProtocolGuid
,
573 This
->DriverBindingHandle
,
578 // Free our instance data
580 gBS
->FreePool (Private
);
586 CirrusLogic5430UgaDrawDestructor
588 TODO: Private - add argument and description to function comment
589 TODO: EFI_SUCCESS - add return value to function comment
592 CirrusLogic5430UgaDrawDestructor (
593 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
600 TODO: Add function description
602 @param Private TODO: add argument description
603 @param Address TODO: add argument description
604 @param Data TODO: add argument description
606 TODO: add return values
611 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
616 Private
->PciIo
->Io
.Write (
619 EFI_PCI_IO_PASS_THROUGH_BAR
,
627 TODO: Add function description
629 @param Private TODO: add argument description
630 @param Address TODO: add argument description
631 @param Data TODO: add argument description
633 TODO: add return values
638 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
643 Private
->PciIo
->Io
.Write (
646 EFI_PCI_IO_PASS_THROUGH_BAR
,
654 TODO: Add function description
656 @param Private TODO: add argument description
657 @param Address TODO: add argument description
659 TODO: add return values
664 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
670 Private
->PciIo
->Io
.Read (
673 EFI_PCI_IO_PASS_THROUGH_BAR
,
682 TODO: Add function description
684 @param Private TODO: add argument description
685 @param Address TODO: add argument description
687 TODO: add return values
692 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
698 Private
->PciIo
->Io
.Read (
701 EFI_PCI_IO_PASS_THROUGH_BAR
,
710 TODO: Add function description
712 @param Private TODO: add argument description
713 @param Index TODO: add argument description
714 @param Red TODO: add argument description
715 @param Green TODO: add argument description
716 @param Blue TODO: add argument description
718 TODO: add return values
723 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
730 outb (Private
, PALETTE_INDEX_REGISTER
, (UINT8
) Index
);
731 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Red
>> 2));
732 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Green
>> 2));
733 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Blue
>> 2));
737 TODO: Add function description
739 @param Private TODO: add argument description
741 TODO: add return values
746 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
755 for (RedIndex
= 0; RedIndex
< 8; RedIndex
++) {
756 for (GreenIndex
= 0; GreenIndex
< 8; GreenIndex
++) {
757 for (BlueIndex
= 0; BlueIndex
< 4; BlueIndex
++) {
758 SetPaletteColor (Private
, Index
, (UINT8
) (RedIndex
<< 5), (UINT8
) (GreenIndex
<< 5), (UINT8
) (BlueIndex
<< 6));
766 TODO: Add function description
768 @param Private TODO: add argument description
770 TODO: add return values
775 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
781 Private
->PciIo
->Mem
.Write (
783 EfiPciIoWidthFillUint32
,
792 TODO: Add function description
794 @param Private TODO: add argument description
796 TODO: add return values
801 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
809 TODO: Add function description
811 @param Private TODO: add argument description
812 @param ModeData TODO: add argument description
814 TODO: add return values
818 InitializeGraphicsMode (
819 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
820 CIRRUS_LOGIC_5430_VIDEO_MODES
*ModeData
828 Status
= Private
->PciIo
->Pci
.Read (
831 PCI_DEVICE_ID_OFFSET
,
836 // Read the PCI Configuration Header from the PCI Device
838 ASSERT_EFI_ERROR (Status
);
840 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x1206);
841 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x0012);
843 for (Index
= 0; Index
< 15; Index
++) {
844 outw (Private
, SEQ_ADDRESS_REGISTER
, ModeData
->SeqSettings
[Index
]);
847 if (DeviceId
!= CIRRUS_LOGIC_5446_DEVICE_ID
) {
848 outb (Private
, SEQ_ADDRESS_REGISTER
, 0x0f);
849 Byte
= (UINT8
) ((inb (Private
, SEQ_DATA_REGISTER
) & 0xc7) ^ 0x30);
850 outb (Private
, SEQ_DATA_REGISTER
, Byte
);
853 outb (Private
, MISC_OUTPUT_REGISTER
, ModeData
->MiscSetting
);
854 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0506);
855 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x0300);
856 outw (Private
, CRTC_ADDRESS_REGISTER
, 0x2011);
858 for (Index
= 0; Index
< 28; Index
++) {
859 outw (Private
, CRTC_ADDRESS_REGISTER
, (UINT16
) ((ModeData
->CrtcSettings
[Index
] << 8) | Index
));
862 for (Index
= 0; Index
< 9; Index
++) {
863 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((GraphicsController
[Index
] << 8) | Index
));
866 inb (Private
, INPUT_STATUS_1_REGISTER
);
868 for (Index
= 0; Index
< 21; Index
++) {
869 outb (Private
, ATT_ADDRESS_REGISTER
, (UINT8
) Index
);
870 outb (Private
, ATT_ADDRESS_REGISTER
, AttributeController
[Index
]);
873 outb (Private
, ATT_ADDRESS_REGISTER
, 0x20);
875 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0009);
876 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x000a);
877 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x000b);
878 outb (Private
, DAC_PIXEL_MASK_REGISTER
, 0xff);
880 SetDefaultPalette (Private
);
881 ClearScreen (Private
);
886 InitializeCirrusLogic5430 (
887 IN EFI_HANDLE ImageHandle
,
888 IN EFI_SYSTEM_TABLE
*SystemTable
893 Status
= EfiLibInstallDriverBindingComponentName2 (
896 &gCirrusLogic5430DriverBinding
,
898 &gCirrusLogic5430ComponentName
,
899 &gCirrusLogic5430ComponentName2
901 ASSERT_EFI_ERROR (Status
);
904 // Install EFI Driver Supported EFI Version Protocol required for
905 // EFI drivers that are on PCI and other plug in cards.
907 gCirrusLogic5430DriverSupportedEfiVersion
.FirmwareVersion
= PcdGet32 (PcdDriverSupportedEfiVersion
);
908 Status
= gBS
->InstallMultipleProtocolInterfaces (
910 &gEfiDriverSupportedEfiVersionProtocolGuid
,
911 &gCirrusLogic5430DriverSupportedEfiVersion
,
914 ASSERT_EFI_ERROR (Status
);