Port CirrusLogic5430 from EDK II code base.
Add GOP, Component Name 2, Efi driver supported EFI version protocol support.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4322 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
new file mode 100644
index 0000000..bfa121b
--- /dev/null
+++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
@@ -0,0 +1,803 @@
+/** @file

+  Cirrus Logic 5430 Controller Driver.

+  This driver is a sample implementation of the UGA Draw and Graphics Output

+  Protocols for the Cirrus Logic 5430 family of PCI video controllers.

+  This driver is only usable in the EFI pre-boot environment.

+  This sample is intended to show how the UGA Draw and Graphics output Protocol

+  is able to function. 

+  The UGA I/O Protocol is not implemented in this sample.

+  A fully compliant EFI UGA driver requires both

+  the UGA Draw and the UGA I/O Protocol.  Please refer to Microsoft's

+  documentation on UGA for details on how to write a UGA driver that is able

+  to function both in the EFI pre-boot environment and from the OS runtime.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. This program and the accompanying materials                          

+  are licensed and made available under the terms and conditions of the BSD License         

+  which accompanies this distribution.  The full text of the license may be found at        

+  http://opensource.org/licenses/bsd-license.php                                            

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

+

+**/

+

+//

+// Cirrus Logic 5430 Controller Driver

+//

+#include "CirrusLogic5430.h"

+

+EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = {

+  CirrusLogic5430ControllerDriverSupported,

+  CirrusLogic5430ControllerDriverStart,

+  CirrusLogic5430ControllerDriverStop,

+  0x10,

+  NULL,

+  NULL

+};

+

+///

+/// Generic Attribute Controller Register Settings

+///

+UINT8  AttributeController[21] = {

+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 

+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 

+  0x41, 0x00, 0x0F, 0x00, 0x00

+};

+

+///

+/// Generic Graphics Controller Register Settings

+///

+UINT8 GraphicsController[9] = {

+  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF

+};

+

+//

+// 640 x 480 x 256 color @ 60 Hertz

+//

+UINT8 Crtc_640_480_256_60[28] = {

+  0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,

+  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+  0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,

+  0xff, 0x00, 0x00, 0x22

+};

+

+UINT16 Seq_640_480_256_60[15] = {

+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, 

+  0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e

+};

+

+//

+// 800 x 600 x 256 color @ 60 Hertz

+//

+UINT8 Crtc_800_600_256_60[28] = {

+  0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0, 

+  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+  0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,

+  0xFF, 0x00, 0x00, 0x22

+};

+

+UINT16 Seq_800_600_256_60[15] = {

+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, 

+  0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e

+};

+

+//

+// 1024 x 768 x 256 color @ 60 Hertz

+//

+UINT8 Crtc_1024_768_256_60[28] = {

+  0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, 

+  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

+  0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,

+  0xFF, 0x4A, 0x00, 0x22

+};

+

+UINT16 Seq_1024_768_256_60[15] = {

+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, 

+  0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e

+};

+

+///

+/// Table of supported video modes

+///

+CIRRUS_LOGIC_5430_VIDEO_MODES  CirrusLogic5430VideoModes[] = {

+  {  640, 480, 8, 60, Crtc_640_480_256_60,  Seq_640_480_256_60,  0xe3 },

+  {  800, 600, 8, 60, Crtc_800_600_256_60,  Seq_800_600_256_60,  0xef }, 

+  { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef } 

+};

+

+/**

+  CirrusLogic5430ControllerDriverSupported

+

+  TODO:    This - add argument and description to function comment

+  TODO:    Controller - add argument and description to function comment

+  TODO:    RemainingDevicePath - add argument and description to function comment

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+{

+  EFI_STATUS          Status;

+  EFI_PCI_IO_PROTOCOL *PciIo;

+  PCI_TYPE00          Pci;

+

+  //

+  // Open the PCI I/O Protocol

+  //

+  Status = gBS->OpenProtocol (

+                  Controller,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIo,

+                  This->DriverBindingHandle,

+                  Controller,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Read the PCI Configuration Header from the PCI Device

+  //

+  Status = PciIo->Pci.Read (

+                        PciIo,

+                        EfiPciIoWidthUint32,

+                        0,

+                        sizeof (Pci) / sizeof (UINT32),

+                        &Pci

+                        );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  Status = EFI_UNSUPPORTED;

+  //

+  // See if the I/O enable is on.  Most systems only allow one VGA device to be turned on

+  // at a time, so see if this is one that is turned on.

+  //

+  //  if (((Pci.Hdr.Command & 0x01) == 0x01)) {

+  //

+  // See if this is a Cirrus Logic PCI controller

+  //

+  if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) {

+    //

+    // See if this is a 5430 or a 5446 PCI controller

+    //

+    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID) {

+      Status = EFI_SUCCESS;

+    }

+

+    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID) {

+      Status = EFI_SUCCESS;

+    }

+

+    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {

+      Status = EFI_SUCCESS;

+    }

+  }

+

+Done:

+  //

+  // Close the PCI I/O Protocol

+  //

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  return Status;

+}

+

+/**

+  CirrusLogic5430ControllerDriverStart

+

+  TODO:    This - add argument and description to function comment

+  TODO:    Controller - add argument and description to function comment

+  TODO:    RemainingDevicePath - add argument and description to function comment

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath

+  )

+{

+  EFI_STATUS                      Status;

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+

+  //

+  // Allocate Private context data for UGA Draw inteface.

+  //

+  Private = AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA));

+  if (Private == NULL) {

+    Status = EFI_OUT_OF_RESOURCES;

+    goto Error;

+  }

+

+  //

+  // Set up context record

+  //

+  Private->Signature  = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE;

+  Private->Handle     = Controller;

+

+  //

+  // Open PCI I/O Protocol

+  //

+  Status = gBS->OpenProtocol (

+                  Private->Handle,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &Private->PciIo,

+                  This->DriverBindingHandle,

+                  Private->Handle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  Status = Private->PciIo->Attributes (

+                            Private->PciIo,

+                            EfiPciIoAttributeOperationEnable,

+                            EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,

+                            NULL

+                            );

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  if (FeaturePcdGet (PcdSupportUga)) {

+    //

+    // Start the UGA Draw software stack.

+    //

+    Status = CirrusLogic5430UgaDrawConstructor (Private);

+    ASSERT_EFI_ERROR (Status);

+    if (FeaturePcdGet (PcdSupportGop)) {

+      Status = CirrusLogic5430GraphicsOutputConstructor (Private);

+      ASSERT_EFI_ERROR (Status);

+

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &Private->Handle,

+                      &gEfiUgaDrawProtocolGuid,

+                      &Private->UgaDraw,

+                      &gEfiGraphicsOutputProtocolGuid,

+                      &Private->GraphicsOutput,

+                      NULL

+                      );

+    } else {

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &Private->Handle,

+                      &gEfiUgaDrawProtocolGuid,

+                      &Private->UgaDraw,

+                      NULL

+                      );

+

+    }

+  } else {

+    if (FeaturePcdGet (PcdSupportGop)) {

+      Status = CirrusLogic5430GraphicsOutputConstructor (Private);

+      ASSERT_EFI_ERROR (Status);

+

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &Private->Handle,

+                      &gEfiGraphicsOutputProtocolGuid,

+                      &Private->GraphicsOutput,

+                      NULL

+                      );

+      

+    } else {

+      //

+      // This driver must support eithor GOP or UGA or both.

+      // 

+      ASSERT (FALSE);

+      Status = EFI_UNSUPPORTED;

+    }

+  }

+  

+

+Error:

+  if (EFI_ERROR (Status)) {

+    if (Private) {

+      if (Private->PciIo) {

+        Private->PciIo->Attributes (

+                          Private->PciIo,

+                          EfiPciIoAttributeOperationDisable,

+                          EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,

+                          NULL

+                          );

+      }

+    }

+

+    //

+    // Close the PCI I/O Protocol

+    //

+    gBS->CloseProtocol (

+          Private->Handle,

+          &gEfiPciIoProtocolGuid,

+          This->DriverBindingHandle,

+          Private->Handle

+          );

+    if (Private) {

+      gBS->FreePool (Private);

+    }

+  }

+

+  return Status;

+}

+

+/**

+  CirrusLogic5430ControllerDriverStop

+

+  TODO:    This - add argument and description to function comment

+  TODO:    Controller - add argument and description to function comment

+  TODO:    NumberOfChildren - add argument and description to function comment

+  TODO:    ChildHandleBuffer - add argument and description to function comment

+  TODO:    EFI_SUCCESS - add return value to function comment

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverStop (

+  IN EFI_DRIVER_BINDING_PROTOCOL    *This,

+  IN EFI_HANDLE                     Controller,

+  IN UINTN                          NumberOfChildren,

+  IN EFI_HANDLE                     *ChildHandleBuffer

+  )

+{

+  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;

+  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;

+

+  EFI_STATUS                      Status;

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+

+  if (FeaturePcdGet (PcdSupportUga)) {

+    Status = gBS->OpenProtocol (

+                    Controller,

+                    &gEfiUgaDrawProtocolGuid,

+                    (VOID **) &UgaDraw,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    //

+    // Get our private context information

+    //

+    Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw);

+    CirrusLogic5430UgaDrawDestructor (Private);

+

+    if (FeaturePcdGet (PcdSupportGop)) {

+      CirrusLogic5430GraphicsOutputDestructor (Private);

+      //

+      // Remove the UGA and GOP protocol interface from the system

+      //

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      Private->Handle,

+                      &gEfiUgaDrawProtocolGuid,

+                      &Private->UgaDraw,

+                      &gEfiGraphicsOutputProtocolGuid,

+                      &Private->GraphicsOutput,

+                      NULL

+                      );

+    } else {

+      //

+      // Remove the UGA Draw interface from the system

+      //

+      Status = gBS->UninstallMultipleProtocolInterfaces (

+                      Private->Handle,

+                      &gEfiUgaDrawProtocolGuid,

+                      &Private->UgaDraw,

+                      NULL

+                      );

+    }

+  } else {

+    Status = gBS->OpenProtocol (

+                    Controller,

+                    &gEfiGraphicsOutputProtocolGuid,

+                    (VOID **) &GraphicsOutput,

+                    This->DriverBindingHandle,

+                    Controller,

+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                    );

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+

+    //

+    // Get our private context information

+    //

+    Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);

+

+    CirrusLogic5430GraphicsOutputDestructor (Private);

+    //

+    // Remove the GOP protocol interface from the system

+    //

+    Status = gBS->UninstallMultipleProtocolInterfaces (

+                    Private->Handle,

+                    &gEfiUgaDrawProtocolGuid,

+                    &Private->UgaDraw,

+                    &gEfiGraphicsOutputProtocolGuid,

+                    &Private->GraphicsOutput,

+                    NULL

+                    );

+  }

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+

+  //

+  // Shutdown the hardware

+  //

+  Private->PciIo->Attributes (

+                    Private->PciIo,

+                    EfiPciIoAttributeOperationDisable,

+                    EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,

+                    NULL

+                    );

+

+  //

+  // Close the PCI I/O Protocol

+  //

+  gBS->CloseProtocol (

+        Controller,

+        &gEfiPciIoProtocolGuid,

+        This->DriverBindingHandle,

+        Controller

+        );

+

+  //

+  // Free our instance data

+  //

+  gBS->FreePool (Private);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  CirrusLogic5430UgaDrawDestructor

+

+  TODO:    Private - add argument and description to function comment

+  TODO:    EFI_SUCCESS - add return value to function comment

+**/

+EFI_STATUS

+CirrusLogic5430UgaDrawDestructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+{

+  return EFI_SUCCESS;

+}

+

+/**

+  TODO: Add function description

+

+  @param  Private TODO: add argument description

+  @param  Address TODO: add argument description

+  @param  Data TODO: add argument description

+

+  TODO: add return values

+

+**/

+VOID

+outb (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address,

+  UINT8                           Data

+  )

+{

+  Private->PciIo->Io.Write (

+                      Private->PciIo,

+                      EfiPciIoWidthUint8,

+                      EFI_PCI_IO_PASS_THROUGH_BAR,

+                      Address,

+                      1,

+                      &Data

+                      );

+}

+

+/**

+  TODO: Add function description

+

+  @param  Private TODO: add argument description

+  @param  Address TODO: add argument description

+  @param  Data TODO: add argument description

+

+  TODO: add return values

+

+**/

+VOID

+outw (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address,

+  UINT16                          Data

+  )

+{

+  Private->PciIo->Io.Write (

+                      Private->PciIo,

+                      EfiPciIoWidthUint16,

+                      EFI_PCI_IO_PASS_THROUGH_BAR,

+                      Address,

+                      1,

+                      &Data

+                      );

+}

+

+/**

+  TODO: Add function description

+

+  @param  Private TODO: add argument description

+  @param  Address TODO: add argument description

+

+  TODO: add return values

+

+**/

+UINT8

+inb (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address

+  )

+{

+  UINT8 Data;

+

+  Private->PciIo->Io.Read (

+                      Private->PciIo,

+                      EfiPciIoWidthUint8,

+                      EFI_PCI_IO_PASS_THROUGH_BAR,

+                      Address,

+                      1,

+                      &Data

+                      );

+  return Data;

+}

+

+/**

+  TODO: Add function description

+

+  @param  Private TODO: add argument description

+  @param  Address TODO: add argument description

+

+  TODO: add return values

+

+**/

+UINT16

+inw (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address

+  )

+{

+  UINT16  Data;

+

+  Private->PciIo->Io.Read (

+                      Private->PciIo,

+                      EfiPciIoWidthUint16,

+                      EFI_PCI_IO_PASS_THROUGH_BAR,

+                      Address,

+                      1,

+                      &Data

+                      );

+  return Data;

+}

+

+/**

+  TODO: Add function description

+

+  @param  Private TODO: add argument description

+  @param  Index TODO: add argument description

+  @param  Red TODO: add argument description

+  @param  Green TODO: add argument description

+  @param  Blue TODO: add argument description

+

+  TODO: add return values

+

+**/

+VOID

+SetPaletteColor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Index,

+  UINT8                           Red,

+  UINT8                           Green,

+  UINT8                           Blue

+  )

+{

+  outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);

+  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));

+  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));

+  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));

+}

+

+/**

+  TODO: Add function description

+

+  @param  Private TODO: add argument description

+

+  TODO: add return values

+

+**/

+VOID

+SetDefaultPalette (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+{

+  UINTN Index;

+  UINTN RedIndex;

+  UINTN GreenIndex;

+  UINTN BlueIndex;

+

+  Index = 0;

+  for (RedIndex = 0; RedIndex < 8; RedIndex++) {

+    for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {

+      for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {

+        SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));

+        Index++;

+      }

+    }

+  }

+}

+

+/**

+  TODO: Add function description

+

+  @param  Private TODO: add argument description

+

+  TODO: add return values

+

+**/

+STATIC

+VOID

+ClearScreen (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+{

+  UINT32  Color;

+

+  Color = 0;

+  Private->PciIo->Mem.Write (

+                        Private->PciIo,

+                        EfiPciIoWidthFillUint32,

+                        0,

+                        0,

+                        0x100000 >> 2,

+                        &Color

+                        );

+}

+

+/**

+  TODO: Add function description

+

+  @param  Private TODO: add argument description

+

+  TODO: add return values

+

+**/

+VOID

+DrawLogo (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           ScreenWidth,

+  UINTN                           ScreenHeight

+  )

+{

+  UINTN Offset;

+  UINTN X;

+  UINTN Y;

+  UINT8 Color;

+

+  Offset        = 0;

+  for (Y = 0; Y < ScreenHeight; Y++) {

+    for (X = 0; X < ScreenWidth; X++) {

+      Color                   = (UINT8) (256 * (X + Y) / (ScreenWidth + ScreenHeight));

+      Private->LineBuffer[X]  = Color;

+    }

+

+    Private->PciIo->Mem.Write (

+                          Private->PciIo,

+                          EfiPciIoWidthUint32,

+                          0,

+                          Offset + (Y * ScreenWidth),

+                          ScreenWidth >> 2,

+                          Private->LineBuffer

+                          );

+  }

+}

+

+/**

+  TODO: Add function description

+

+  @param  Private TODO: add argument description

+  @param  ModeData TODO: add argument description

+

+  TODO: add return values

+

+**/

+VOID

+InitializeGraphicsMode (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  CIRRUS_LOGIC_5430_VIDEO_MODES   *ModeData

+  )

+{

+  UINT8 Byte;

+  UINTN Index;

+

+  outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);

+  outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);

+

+  for (Index = 0; Index < 15; Index++) {

+    outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);

+  }

+

+  outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);

+  Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);

+  outb (Private, SEQ_DATA_REGISTER, Byte);

+

+  outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);

+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);

+  outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);

+  outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);

+

+  for (Index = 0; Index < 28; Index++) {

+    outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));

+  }

+

+  for (Index = 0; Index < 9; Index++) {

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));

+  }

+

+  inb (Private, INPUT_STATUS_1_REGISTER);

+

+  for (Index = 0; Index < 21; Index++) {

+    outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);

+    outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);

+  }

+

+  outb (Private, ATT_ADDRESS_REGISTER, 0x20);

+

+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);

+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);

+  outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);

+  outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);

+

+  SetDefaultPalette (Private);

+  ClearScreen (Private);

+}

+

+EFI_STATUS

+EFIAPI

+InitializeCirrusLogic5430 (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+{

+  EFI_STATUS              Status;

+

+  Status = EfiLibInstallDriverBindingComponentName2 (

+             ImageHandle,

+             SystemTable,

+             &gCirrusLogic5430DriverBinding,

+             ImageHandle,

+             &gCirrusLogic5430ComponentName,

+             &gCirrusLogic5430ComponentName2

+             );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Install EFI Driver Supported EFI Version Protocol required for 

+  // EFI drivers that are on PCI and other plug in cards.

+  //

+  gCirrusLogic5430DriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &ImageHandle,

+                  &gEfiDriverSupportedEfiVersionProtocolGuid,

+                  &gCirrusLogic5430DriverSupportedEfiVersion,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
new file mode 100644
index 0000000..c8fcd70
--- /dev/null
+++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
@@ -0,0 +1,409 @@
+/** @file

+  Cirrus Logic 5430 Controller Driver

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. This program and the accompanying materials                          

+  are licensed and made available under the terms and conditions of the BSD License         

+  which accompanies this distribution.  The full text of the license may be found at        

+  http://opensource.org/licenses/bsd-license.php                                            

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

+

+**/

+

+//

+// Cirrus Logic 5430 Controller Driver

+//

+

+#ifndef _CIRRUS_LOGIC_5430_H_

+#define _CIRRUS_LOGIC_5430_H_

+

+

+#include <Uefi.h>

+#include <Protocol/UgaDraw.h>

+#include <Protocol/GraphicsOutput.h>

+#include <Protocol/PciIo.h>

+#include <Protocol/DriverSupportedEfiVersion.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiDriverEntryPoint.h>

+#include <Library/UefiLib.h>

+#include <Library/PcdLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+

+#include <IndustryStandard/pci22.h>

+//

+// Cirrus Logic 5430 PCI Configuration Header values

+//

+#define CIRRUS_LOGIC_VENDOR_ID                0x1013

+#define CIRRUS_LOGIC_5430_DEVICE_ID           0x00a8

+#define CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID 0x00a0

+#define CIRRUS_LOGIC_5446_DEVICE_ID           0x00b8

+

+//

+// Cirrus Logic Graphical Mode Data

+//

+#define CIRRUS_LOGIC_5430_MODE_COUNT         3

+

+typedef struct {

+  UINT32  HorizontalResolution;

+  UINT32  VerticalResolution;

+  UINT32  ColorDepth;

+  UINT32  RefreshRate;

+} CIRRUS_LOGIC_5430_MODE_DATA;

+

+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER  0xffff

+

+//

+// Cirrus Logic 5440 Private Data Structure

+//

+#define CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('C', 'L', '5', '4')

+

+typedef struct {

+  UINT64                                Signature;

+  EFI_HANDLE                            Handle;

+  EFI_PCI_IO_PROTOCOL                   *PciIo;

+  EFI_UGA_DRAW_PROTOCOL                 UgaDraw;

+  EFI_GRAPHICS_OUTPUT_PROTOCOL          GraphicsOutput;

+  UINTN                                 CurrentMode;

+  UINTN                                 MaxMode;

+  CIRRUS_LOGIC_5430_MODE_DATA           ModeData[CIRRUS_LOGIC_5430_MODE_COUNT];

+  UINT8                                 *LineBuffer;

+  BOOLEAN                               HardwareNeedsStarting;

+} CIRRUS_LOGIC_5430_PRIVATE_DATA;

+

+///

+/// Video Mode structure

+///

+typedef struct {

+  UINT32  Width;

+  UINT32  Height;

+  UINT32  ColorDepth;

+  UINT32  RefreshRate;

+  UINT8   *CrtcSettings;

+  UINT16  *SeqSettings;

+  UINT8   MiscSetting;

+} CIRRUS_LOGIC_5430_VIDEO_MODES;

+

+#define CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS(a) \

+  CR(a, CIRRUS_LOGIC_5430_PRIVATE_DATA, UgaDraw, CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE)

+

+#define CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \

+  CR(a, CIRRUS_LOGIC_5430_PRIVATE_DATA, GraphicsOutput, CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE)

+

+

+//

+// Global Variables

+//

+extern UINT8                                      AttributeController[];

+extern UINT8                                      GraphicsController[];

+extern UINT8                                      Crtc_640_480_256_60[];

+extern UINT16                                     Seq_640_480_256_60[];

+extern UINT8                                      Crtc_800_600_256_60[];

+extern UINT16                                     Seq_800_600_256_60[];

+extern UINT8                                      Crtc_1024_768_256_60[];

+extern UINT16                                     Seq_1024_768_256_60[];

+extern CIRRUS_LOGIC_5430_VIDEO_MODES              CirrusLogic5430VideoModes[];

+extern EFI_DRIVER_BINDING_PROTOCOL                gCirrusLogic5430DriverBinding;

+extern EFI_COMPONENT_NAME_PROTOCOL                gCirrusLogic5430ComponentName;

+extern EFI_COMPONENT_NAME2_PROTOCOL               gCirrusLogic5430ComponentName2;

+extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL  gCirrusLogic5430DriverSupportedEfiVersion;

+

+//

+// Io Registers defined by VGA

+//

+#define CRTC_ADDRESS_REGISTER   0x3d4

+#define CRTC_DATA_REGISTER      0x3d5

+#define SEQ_ADDRESS_REGISTER    0x3c4

+#define SEQ_DATA_REGISTER       0x3c5

+#define GRAPH_ADDRESS_REGISTER  0x3ce

+#define GRAPH_DATA_REGISTER     0x3cf

+#define ATT_ADDRESS_REGISTER    0x3c0

+#define MISC_OUTPUT_REGISTER    0x3c2

+#define INPUT_STATUS_1_REGISTER 0x3da

+#define DAC_PIXEL_MASK_REGISTER 0x3c6

+#define PALETTE_INDEX_REGISTER  0x3c8

+#define PALETTE_DATA_REGISTER   0x3c9

+

+//

+// UGA Draw Hardware abstraction internal worker functions

+//

+EFI_STATUS

+CirrusLogic5430UgaDrawConstructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+;

+

+EFI_STATUS

+CirrusLogic5430UgaDrawDestructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+;

+

+//

+// Graphics Output Hardware abstraction internal worker functions

+//

+EFI_STATUS

+CirrusLogic5430GraphicsOutputConstructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+;

+

+EFI_STATUS

+CirrusLogic5430GraphicsOutputDestructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+;

+

+

+//

+// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface

+//

+/**

+  TODO: Add function description

+

+  @param  This TODO: add argument description

+  @param  Controller TODO: add argument description

+  @param  RemainingDevicePath TODO: add argument description

+

+  TODO: add return values

+

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverSupported (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+;

+

+/**

+  TODO: Add function description

+

+  @param  This TODO: add argument description

+  @param  Controller TODO: add argument description

+  @param  RemainingDevicePath TODO: add argument description

+

+  TODO: add return values

+

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverStart (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath

+  )

+;

+

+/**

+  TODO: Add function description

+

+  @param  This TODO: add argument description

+  @param  Controller TODO: add argument description

+  @param  NumberOfChildren TODO: add argument description

+  @param  ChildHandleBuffer TODO: add argument description

+

+  TODO: add return values

+

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ControllerDriverStop (

+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,

+  IN EFI_HANDLE                   Controller,

+  IN UINTN                        NumberOfChildren,

+  IN EFI_HANDLE                   *ChildHandleBuffer

+  )

+;

+

+//

+// EFI Component Name Functions

+//

+/**

+  Retrieves a Unicode string that is the user readable name of the driver.

+

+  This function retrieves the user readable name of a driver in the form of a

+  Unicode string. If the driver specified by This has a user readable name in

+  the language specified by Language, then a pointer to the driver name is

+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified

+  by This does not support the language specified by Language,

+  then EFI_UNSUPPORTED is returned.

+

+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+

+  @param  Language[in]          A pointer to a Null-terminated ASCII string

+                                array indicating the language. This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified

+                                in RFC 3066 or ISO 639-2 language code format.

+

+  @param  DriverName[out]       A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                driver specified by This in the language

+                                specified by Language.

+

+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by

+                                This and the language specified by Language was

+                                returned in DriverName.

+

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+

+  @retval EFI_INVALID_PARAMETER DriverName is NULL.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  );

+

+

+/**

+  Retrieves a Unicode string that is the user readable name of the controller

+  that is being managed by a driver.

+

+  This function retrieves the user readable name of the controller specified by

+  ControllerHandle and ChildHandle in the form of a Unicode string. If the

+  driver specified by This has a user readable name in the language specified by

+  Language, then a pointer to the controller name is returned in ControllerName,

+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently

+  managing the controller specified by ControllerHandle and ChildHandle,

+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not

+  support the language specified by Language, then EFI_UNSUPPORTED is returned.

+

+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+

+  @param  ControllerHandle[in]  The handle of a controller that the driver

+                                specified by This is managing.  This handle

+                                specifies the controller whose name is to be

+                                returned.

+

+  @param  ChildHandle[in]       The handle of the child controller to retrieve

+                                the name of.  This is an optional parameter that

+                                may be NULL.  It will be NULL for device

+                                drivers.  It will also be NULL for a bus drivers

+                                that wish to retrieve the name of the bus

+                                controller.  It will not be NULL for a bus

+                                driver that wishes to retrieve the name of a

+                                child controller.

+

+  @param  Language[in]          A pointer to a Null-terminated ASCII string

+                                array indicating the language.  This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified in

+                                RFC 3066 or ISO 639-2 language code format.

+

+  @param  ControllerName[out]   A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                controller specified by ControllerHandle and

+                                ChildHandle in the language specified by

+                                Language from the point of view of the driver

+                                specified by This.

+

+  @retval EFI_SUCCESS           The Unicode string for the user readable name in

+                                the language specified by Language for the

+                                driver specified by This was returned in

+                                DriverName.

+

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.

+

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid

+                                EFI_HANDLE.

+

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+

+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently

+                                managing the controller specified by

+                                ControllerHandle and ChildHandle.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  );

+

+

+//

+// Local Function Prototypes

+//

+VOID

+InitializeGraphicsMode (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  CIRRUS_LOGIC_5430_VIDEO_MODES   *ModeData

+  );

+

+VOID

+SetPaletteColor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Index,

+  UINT8                           Red,

+  UINT8                           Green,

+  UINT8                           Blue

+  );

+

+VOID

+SetDefaultPalette (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  );

+

+VOID

+DrawLogo (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           ScreenWidth,

+  UINTN                           ScreenHeight

+  );

+

+VOID

+outb (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address,

+  UINT8                           Data

+  );

+

+VOID

+outw (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address,

+  UINT16                          Data

+  );

+

+UINT8

+inb (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address

+  );

+

+UINT16

+inw (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,

+  UINTN                           Address

+  );

+

+#endif

diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
new file mode 100644
index 0000000..a540fef
--- /dev/null
+++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
@@ -0,0 +1,75 @@
+#/** @file

+# Component description file for CirrusLogic5430 module

+#

+# Cirrus Logic 5430 Controller Driver.This driver is a sample implementation

+#  of the UGA Draw Protocol for the Cirrus Logic 5430 family of PCI video controllers.

+#  This driver is only usable in the EFI pre-boot environment. This sample is

+#  intended to show how the UGA Draw Protocol is able to function. The UGA I/O

+#  Protocol is not implemented in this sample. A fully compliant EFI UGA driver

+#  requires both the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's

+#  documentation on UGA for details on how to write a UGA driver that is able

+#  to function both in the EFI pre-boot environment and from the OS runtime.

+# Copyright (c) 2006 - 2007, Intel Corporation

+#

+#  All rights reserved. This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+#**/

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = CirrusLogic5430UgaDraw

+  FILE_GUID                      = 555F76EA-785F-40d7-9174-153C43636C68

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  EDK_RELEASE_VERSION            = 0x00020000

+  EFI_SPECIFICATION_VERSION      = 0x00020000

+

+  ENTRY_POINT                    = InitializeCirrusLogic5430

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+#  DRIVER_BINDING                =  gCirrusLogic5430DriverBinding                

+#  COMPONENT_NAME                =  gCirrusLogic5430ComponentName                

+#

+

+[Sources.common]

+  ComponentName.c

+  DriverSupportedEfiVersion.c

+  CirrusLogic5430UgaDraw.c

+  CirrusLogic5430GraphicsOutput.c

+  CirrusLogic5430.c

+  CirrusLogic5430.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+  OptionRomPkg/OptionRomPkg.dec

+

+[LibraryClasses]

+  UefiBootServicesTableLib

+  MemoryAllocationLib

+  UefiLib

+  UefiDriverEntryPoint

+  DebugLib

+

+

+[Protocols]

+  gEfiDriverSupportedEfiVersionProtocolGuid     # PROTOCOL ALWAYS_PRODUCED

+  gEfiUgaDrawProtocolGuid                       # PROTOCOL BY_START

+  gEfiGraphicsOutputProtocolGuid                # PROTOCOL BY_START

+  gEfiPciIoProtocolGuid                         # PROTOCOL TO_START

+  

+[FeaturePcd.common]

+  gOptionRomPkgTokenSpaceGuid.PcdSupportGop

+  gOptionRomPkgTokenSpaceGuid.PcdSupportUga

+

+[Pcd]

+  gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion

diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c
new file mode 100644
index 0000000..7fdb3e0
--- /dev/null
+++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c
@@ -0,0 +1,525 @@
+/*++

+

+Copyright (c) 2007, Intel Corporation                                                         

+All rights reserved. This program and the accompanying materials                          

+are licensed and made available under the terms and conditions of the BSD License         

+which accompanies this distribution.  The full text of the license may be found at        

+http://opensource.org/licenses/bsd-license.php                                            

+                                                                                          

+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     

+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

+

+Module Name:

+

+  UefiCirrusLogic5430GraphicsOutput.c

+

+Abstract:

+

+  This file produces the graphics abstration of Graphics Output Protocol. It is called by 

+  CirrusLogic5430.c file which deals with the EFI 1.1 driver model. 

+  This file just does graphics.

+

+--*/

+

+#include "CirrusLogic5430.h"

+

+//

+// Graphics Output Protocol Member Functions

+//

+EFI_STATUS

+EFIAPI

+CirrusLogic5430GraphicsOutputQueryMode (

+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,

+  IN  UINT32                                ModeNumber,

+  OUT UINTN                                 *SizeOfInfo,

+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info

+  )

+/*++

+

+Routine Description:

+

+  Graphics Output protocol interface to query video mode

+

+  Arguments:

+    This                  - Protocol instance pointer.

+    ModeNumber            - The mode number to return information on.

+    Info                  - Caller allocated buffer that returns information about ModeNumber.

+    SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.

+

+  Returns:

+    EFI_SUCCESS           - Mode information returned.

+    EFI_BUFFER_TOO_SMALL  - The Info buffer was too small.

+    EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the video mode.

+    EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()

+    EFI_INVALID_PARAMETER - One of the input args was NULL.

+

+--*/

+{

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);

+

+  if (Private->HardwareNeedsStarting) {

+    return EFI_NOT_STARTED;

+  }

+

+  if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));

+  if (*Info == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);

+

+  (*Info)->Version = 0;

+  (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;

+  (*Info)->VerticalResolution   = Private->ModeData[ModeNumber].VerticalResolution;

+  (*Info)->PixelFormat = PixelBltOnly;

+  (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430GraphicsOutputSetMode (

+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,

+  IN  UINT32                       ModeNumber

+  )

+/*++

+

+Routine Description:

+

+  Graphics Output protocol interface to set video mode

+

+  Arguments:

+    This             - Protocol instance pointer.

+    ModeNumber       - The mode number to be set.

+

+  Returns:

+    EFI_SUCCESS      - Graphics mode was changed.

+    EFI_DEVICE_ERROR - The device had an error and could not complete the request.

+    EFI_UNSUPPORTED  - ModeNumber is not supported by this device.

+

+--*/

+{

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+  CIRRUS_LOGIC_5430_MODE_DATA     *ModeData;

+

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);

+

+  if (ModeNumber >= This->Mode->MaxMode) {

+    return EFI_UNSUPPORTED;

+  }

+

+  ModeData = &Private->ModeData[ModeNumber];

+

+  if (Private->LineBuffer) {

+    gBS->FreePool (Private->LineBuffer);

+  }

+

+  Private->LineBuffer = NULL;

+  Private->LineBuffer = AllocatePool (ModeData->HorizontalResolution);

+  if (Private->LineBuffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[ModeNumber]);

+

+  This->Mode->Mode = ModeNumber;

+  This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;

+  This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;

+  This->Mode->Info->PixelFormat = PixelBltOnly;

+  This->Mode->Info->PixelsPerScanLine =  ModeData->HorizontalResolution;

+  This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);

+

+  This->Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS)(UINTN)NULL;

+  This->Mode->FrameBufferSize = 0;

+

+  Private->HardwareNeedsStarting  = FALSE;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430GraphicsOutputBlt (

+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,

+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL

+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,

+  IN  UINTN                                 SourceX,

+  IN  UINTN                                 SourceY,

+  IN  UINTN                                 DestinationX,

+  IN  UINTN                                 DestinationY,

+  IN  UINTN                                 Width,

+  IN  UINTN                                 Height,

+  IN  UINTN                                 Delta

+  )

+/*++

+

+Routine Description:

+

+  Graphics Output protocol instance to block transfer for CirrusLogic device

+

+Arguments:

+

+  This          - Pointer to Graphics Output protocol instance

+  BltBuffer     - The data to transfer to screen

+  BltOperation  - The operation to perform

+  SourceX       - The X coordinate of the source for BltOperation

+  SourceY       - The Y coordinate of the source for BltOperation

+  DestinationX  - The X coordinate of the destination for BltOperation

+  DestinationY  - The Y coordinate of the destination for BltOperation

+  Width         - The width of a rectangle in the blt rectangle in pixels

+  Height        - The height of a rectangle in the blt rectangle in pixels

+  Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.

+                  If a Delta of 0 is used, the entire BltBuffer will be operated on.

+                  If a subrectangle of the BltBuffer is used, then Delta represents

+                  the number of bytes in a row of the BltBuffer.

+

+Returns:

+

+  EFI_INVALID_PARAMETER - Invalid parameter passed in

+  EFI_SUCCESS - Blt operation success

+

+--*/

+{

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+  EFI_TPL                         OriginalTPL;

+  UINTN                           DstY;

+  UINTN                           SrcY;

+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;

+  UINTN                           X;

+  UINT8                           Pixel;

+  UINT32                          WidePixel;

+  UINTN                           ScreenWidth;

+  UINTN                           Offset;

+  UINTN                           SourceOffset;

+  UINT32                          CurrentMode;

+

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);

+

+  if ((BltOperation < 0) || (BltOperation >= EfiGraphicsOutputBltOperationMax)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Width == 0 || Height == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If Delta is zero, then the entire BltBuffer is being used, so Delta

+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,

+  // the number of bytes in each row can be computed.

+  //

+  if (Delta == 0) {

+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);

+  }

+

+  //

+  // We need to fill the Virtual Screen buffer with the blt data.

+  // The virtual screen is upside down, as the first row is the bootom row of

+  // the image.

+  //

+

+  CurrentMode = This->Mode->Mode;

+  //

+  // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters

+  // are valid for the operation and the current screen geometry.

+  //

+  if (BltOperation == EfiBltVideoToBltBuffer) {

+    //

+    // Video to BltBuffer: Source is Video, destination is BltBuffer

+    //

+    if (SourceY + Height > Private->ModeData[CurrentMode].VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (SourceX + Width > Private->ModeData[CurrentMode].HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+  } else {

+    //

+    // BltBuffer to Video: Source is BltBuffer, destination is Video

+    //

+    if (DestinationY + Height > Private->ModeData[CurrentMode].VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (DestinationX + Width > Private->ModeData[CurrentMode].HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // We have to raise to TPL Notify, so we make an atomic write the frame buffer.

+  // We would not want a timer based event (Cursor, ...) to come in while we are

+  // doing this operation.

+  //

+  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);

+

+  switch (BltOperation) {

+  case EfiBltVideoToBltBuffer:

+    //

+    // Video to BltBuffer: Source is Video, destination is BltBuffer

+    //

+    for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {

+

+      Offset = (SrcY * Private->ModeData[CurrentMode].HorizontalResolution) + SourceX;

+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {

+        Private->PciIo->Mem.Read (

+                              Private->PciIo,

+                              EfiPciIoWidthUint32,

+                              0,

+                              Offset,

+                              Width >> 2,

+                              Private->LineBuffer

+                              );

+      } else {

+        Private->PciIo->Mem.Read (

+                              Private->PciIo,

+                              EfiPciIoWidthUint8,

+                              0,

+                              Offset,

+                              Width,

+                              Private->LineBuffer

+                              );

+      }

+

+      for (X = 0; X < Width; X++) {

+        Blt         = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));

+

+        Blt->Red    = (UINT8) (Private->LineBuffer[X] & 0xe0);

+        Blt->Green  = (UINT8) ((Private->LineBuffer[X] & 0x1c) << 3);

+        Blt->Blue   = (UINT8) ((Private->LineBuffer[X] & 0x03) << 6);

+      }

+    }

+    break;

+

+  case EfiBltVideoToVideo:

+    //

+    // Perform hardware acceleration for Video to Video operations

+    //

+    ScreenWidth   = Private->ModeData[CurrentMode].HorizontalResolution;

+    SourceOffset  = (SourceY * Private->ModeData[CurrentMode].HorizontalResolution) + (SourceX);

+    Offset        = (DestinationY * Private->ModeData[CurrentMode].HorizontalResolution) + (DestinationX);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e));

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);

+

+    outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);

+    while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)

+      ;

+    break;

+

+  case EfiBltVideoFill:

+    Blt       = BltBuffer;

+    Pixel     = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));

+    WidePixel = (Pixel << 8) | Pixel;

+    WidePixel = (WidePixel << 16) | WidePixel;

+

+    if (DestinationX == 0 && Width == Private->ModeData[CurrentMode].HorizontalResolution) {

+      Offset = DestinationY * Private->ModeData[CurrentMode].HorizontalResolution;

+      if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthFillUint32,

+                              0,

+                              Offset,

+                              (Width * Height) >> 2,

+                              &WidePixel

+                              );

+      } else {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthFillUint8,

+                              0,

+                              Offset,

+                              Width * Height,

+                              &Pixel

+                              );

+      }

+    } else {

+      for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {

+        Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX;

+        if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {

+          Private->PciIo->Mem.Write (

+                                Private->PciIo,

+                                EfiPciIoWidthFillUint32,

+                                0,

+                                Offset,

+                                Width >> 2,

+                                &WidePixel

+                                );

+        } else {

+          Private->PciIo->Mem.Write (

+                                Private->PciIo,

+                                EfiPciIoWidthFillUint8,

+                                0,

+                                Offset,

+                                Width,

+                                &Pixel

+                                );

+        }

+      }

+    }

+    break;

+

+  case EfiBltBufferToVideo:

+    for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {

+

+      for (X = 0; X < Width; X++) {

+        Blt                     = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + (SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));

+        Private->LineBuffer[X]  = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));

+      }

+

+      Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX;

+

+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthUint32,

+                              0,

+                              Offset,

+                              Width >> 2,

+                              Private->LineBuffer

+                              );

+      } else {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthUint8,

+                              0,

+                              Offset,

+                              Width,

+                              Private->LineBuffer

+                              );

+      }

+    }

+    break;

+  default:

+    ASSERT (FALSE);

+  }

+

+  gBS->RestoreTPL (OriginalTPL);

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CirrusLogic5430GraphicsOutputConstructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+{

+  EFI_STATUS                   Status;

+  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;

+  UINTN                        Index;

+

+

+  GraphicsOutput            = &Private->GraphicsOutput;

+  GraphicsOutput->QueryMode = CirrusLogic5430GraphicsOutputQueryMode;

+  GraphicsOutput->SetMode   = CirrusLogic5430GraphicsOutputSetMode;

+  GraphicsOutput->Blt       = CirrusLogic5430GraphicsOutputBlt;

+

+  //

+  // Initialize the private data

+  //

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),

+                  (VOID **) &Private->GraphicsOutput.Mode

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  Status = gBS->AllocatePool (

+                  EfiBootServicesData,

+                  sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),

+                  (VOID **) &Private->GraphicsOutput.Mode->Info

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+  Private->GraphicsOutput.Mode->MaxMode = CIRRUS_LOGIC_5430_MODE_COUNT;

+  Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;

+  for (Index = 0; Index < Private->GraphicsOutput.Mode->MaxMode; Index++) {

+    Private->ModeData[Index].HorizontalResolution = CirrusLogic5430VideoModes[Index].Width;

+    Private->ModeData[Index].VerticalResolution   = CirrusLogic5430VideoModes[Index].Height;

+    Private->ModeData[Index].ColorDepth           = 32;

+    Private->ModeData[Index].RefreshRate          = CirrusLogic5430VideoModes[Index].RefreshRate;

+  }

+

+  Private->HardwareNeedsStarting  = TRUE;

+  Private->LineBuffer             = NULL;

+

+  //

+  // Initialize the hardware

+  //

+  GraphicsOutput->SetMode (GraphicsOutput, 0);

+  DrawLogo (

+    Private,

+    Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,

+    Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution

+    );

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+CirrusLogic5430GraphicsOutputDestructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+/*++

+

+Routine Description:

+

+Arguments:

+

+Returns:

+

+  None

+

+--*/

+{

+  if (Private->GraphicsOutput.Mode != NULL) {

+    if (Private->GraphicsOutput.Mode->Info != NULL) {

+      gBS->FreePool (Private->GraphicsOutput.Mode->Info);

+    }

+    gBS->FreePool (Private->GraphicsOutput.Mode);

+  }

+

+  return EFI_SUCCESS;

+}

+

+

diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
new file mode 100644
index 0000000..75b1d24
--- /dev/null
+++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
@@ -0,0 +1,427 @@
+/** @file

+  This file produces the graphics abstration of UGA Draw. It is called by 

+  CirrusLogic5430.c file which deals with the EFI 1.1 driver model. 

+  This file just does graphics.

+

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. This program and the accompanying materials                          

+  are licensed and made available under the terms and conditions of the BSD License         

+  which accompanies this distribution.  The full text of the license may be found at        

+  http://opensource.org/licenses/bsd-license.php                                            

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

+

+**/

+

+#include "CirrusLogic5430.h"

+

+//

+// UGA Draw Protocol Member Functions

+//

+EFI_STATUS

+EFIAPI

+CirrusLogic5430UgaDrawGetMode (

+  IN  EFI_UGA_DRAW_PROTOCOL *This,

+  OUT UINT32                *HorizontalResolution,

+  OUT UINT32                *VerticalResolution,

+  OUT UINT32                *ColorDepth,

+  OUT UINT32                *RefreshRate

+  )

+{

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);

+

+  if (Private->HardwareNeedsStarting) {

+    return EFI_NOT_STARTED;

+  }

+

+  if ((HorizontalResolution == NULL) ||

+      (VerticalResolution == NULL)   ||

+      (ColorDepth == NULL)           ||

+      (RefreshRate == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *HorizontalResolution = Private->ModeData[Private->CurrentMode].HorizontalResolution;

+  *VerticalResolution   = Private->ModeData[Private->CurrentMode].VerticalResolution;

+  *ColorDepth           = Private->ModeData[Private->CurrentMode].ColorDepth;

+  *RefreshRate          = Private->ModeData[Private->CurrentMode].RefreshRate;

+

+  return EFI_SUCCESS;

+}

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430UgaDrawSetMode (

+  IN  EFI_UGA_DRAW_PROTOCOL *This,

+  IN  UINT32                HorizontalResolution,

+  IN  UINT32                VerticalResolution,

+  IN  UINT32                ColorDepth,

+  IN  UINT32                RefreshRate

+  )

+{

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+  UINTN                           Index;

+

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);

+

+  for (Index = 0; Index < Private->MaxMode; Index++) {

+

+    if (HorizontalResolution != Private->ModeData[Index].HorizontalResolution) {

+      continue;

+    }

+

+    if (VerticalResolution != Private->ModeData[Index].VerticalResolution) {

+      continue;

+    }

+

+    if (ColorDepth != Private->ModeData[Index].ColorDepth) {

+      continue;

+    }

+

+    if (RefreshRate != Private->ModeData[Index].RefreshRate) {

+      continue;

+    }

+

+    if (Private->LineBuffer) {

+      gBS->FreePool (Private->LineBuffer);

+    }

+

+    Private->LineBuffer = NULL;

+    Private->LineBuffer = AllocatePool (HorizontalResolution);

+    if (Private->LineBuffer == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+

+    InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[Index]);

+

+    Private->CurrentMode            = Index;

+

+    Private->HardwareNeedsStarting  = FALSE;

+

+    return EFI_SUCCESS;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+EFI_STATUS

+EFIAPI

+CirrusLogic5430UgaDrawBlt (

+  IN  EFI_UGA_DRAW_PROTOCOL     *This,

+  IN  EFI_UGA_PIXEL             *BltBuffer, OPTIONAL

+  IN  EFI_UGA_BLT_OPERATION     BltOperation,

+  IN  UINTN                     SourceX,

+  IN  UINTN                     SourceY,

+  IN  UINTN                     DestinationX,

+  IN  UINTN                     DestinationY,

+  IN  UINTN                     Width,

+  IN  UINTN                     Height,

+  IN  UINTN                     Delta

+  )

+{

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;

+  EFI_TPL                         OriginalTPL;

+  UINTN                           DstY;

+  UINTN                           SrcY;

+  EFI_UGA_PIXEL                   *Blt;

+  UINTN                           X;

+  UINT8                           Pixel;

+  UINT32                          WidePixel;

+  UINTN                           ScreenWidth;

+  UINTN                           Offset;

+  UINTN                           SourceOffset;

+

+  Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);

+

+  if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  if (Width == 0 || Height == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If Delta is zero, then the entire BltBuffer is being used, so Delta

+  // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,

+  // the number of bytes in each row can be computed.

+  //

+  if (Delta == 0) {

+    Delta = Width * sizeof (EFI_UGA_PIXEL);

+  }

+

+  //

+  // We need to fill the Virtual Screen buffer with the blt data.

+  // The virtual screen is upside down, as the first row is the bootom row of

+  // the image.

+  //

+

+  //

+  // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters

+  // are valid for the operation and the current screen geometry.

+  //

+  if (BltOperation == EfiUgaVideoToBltBuffer) {

+    //

+    // Video to BltBuffer: Source is Video, destination is BltBuffer

+    //

+    if (SourceY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (SourceX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+  } else {

+    //

+    // BltBuffer to Video: Source is BltBuffer, destination is Video

+    //

+    if (DestinationY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    if (DestinationX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {

+      return EFI_INVALID_PARAMETER;

+    }

+  }

+  //

+  // We have to raise to TPL Notify, so we make an atomic write the frame buffer.

+  // We would not want a timer based event (Cursor, ...) to come in while we are

+  // doing this operation.

+  //

+  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);

+

+  switch (BltOperation) {

+  case EfiUgaVideoToBltBuffer:

+    //

+    // Video to BltBuffer: Source is Video, destination is BltBuffer

+    //

+    for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {

+

+      Offset = (SrcY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + SourceX;

+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {

+        Private->PciIo->Mem.Read (

+                              Private->PciIo,

+                              EfiPciIoWidthUint32,

+                              0,

+                              Offset,

+                              Width >> 2,

+                              Private->LineBuffer

+                              );

+      } else {

+        Private->PciIo->Mem.Read (

+                              Private->PciIo,

+                              EfiPciIoWidthUint8,

+                              0,

+                              Offset,

+                              Width,

+                              Private->LineBuffer

+                              );

+      }

+

+      for (X = 0; X < Width; X++) {

+        Blt         = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_UGA_PIXEL));

+

+        Blt->Red    = (UINT8) (Private->LineBuffer[X] & 0xe0);

+        Blt->Green  = (UINT8) ((Private->LineBuffer[X] & 0x1c) << 3);

+        Blt->Blue   = (UINT8) ((Private->LineBuffer[X] & 0x03) << 6);

+      }

+    }

+    break;

+

+  case EfiUgaVideoToVideo:

+    //

+    // Perform hardware acceleration for Video to Video operations

+    //

+    ScreenWidth   = Private->ModeData[Private->CurrentMode].HorizontalResolution;

+    SourceOffset  = (SourceY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (SourceX);

+    Offset        = (DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (DestinationX);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d));

+    outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e));

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);

+

+    outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);

+

+    outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);

+    while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)

+      ;

+    break;

+

+  case EfiUgaVideoFill:

+    Blt       = BltBuffer;

+    Pixel     = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));

+    WidePixel = (Pixel << 8) | Pixel;

+    WidePixel = (WidePixel << 16) | WidePixel;

+

+    if (DestinationX == 0 && Width == Private->ModeData[Private->CurrentMode].HorizontalResolution) {

+      Offset = DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution;

+      if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthFillUint32,

+                              0,

+                              Offset,

+                              (Width * Height) >> 2,

+                              &WidePixel

+                              );

+      } else {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthFillUint8,

+                              0,

+                              Offset,

+                              Width * Height,

+                              &Pixel

+                              );

+      }

+    } else {

+      for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {

+        Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;

+        if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {

+          Private->PciIo->Mem.Write (

+                                Private->PciIo,

+                                EfiPciIoWidthFillUint32,

+                                0,

+                                Offset,

+                                Width >> 2,

+                                &WidePixel

+                                );

+        } else {

+          Private->PciIo->Mem.Write (

+                                Private->PciIo,

+                                EfiPciIoWidthFillUint8,

+                                0,

+                                Offset,

+                                Width,

+                                &Pixel

+                                );

+        }

+      }

+    }

+    break;

+

+  case EfiUgaBltBufferToVideo:

+    for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {

+

+      for (X = 0; X < Width; X++) {

+        Blt                     = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + (SourceX + X) * sizeof (EFI_UGA_PIXEL));

+        Private->LineBuffer[X]  = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));

+      }

+

+      Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;

+

+      if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthUint32,

+                              0,

+                              Offset,

+                              Width >> 2,

+                              Private->LineBuffer

+                              );

+      } else {

+        Private->PciIo->Mem.Write (

+                              Private->PciIo,

+                              EfiPciIoWidthUint8,

+                              0,

+                              Offset,

+                              Width,

+                              Private->LineBuffer

+                              );

+      }

+    }

+    break;

+

+  default:

+    break;

+  }

+

+  gBS->RestoreTPL (OriginalTPL);

+

+  return EFI_SUCCESS;

+}

+

+//

+// Construction and Destruction functions

+//

+EFI_STATUS

+CirrusLogic5430UgaDrawConstructor (

+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private

+  )

+{

+  EFI_UGA_DRAW_PROTOCOL *UgaDraw;

+  UINTN                 Index;

+

+  //

+  // Fill in Private->UgaDraw protocol

+  //

+  UgaDraw           = &Private->UgaDraw;

+

+  UgaDraw->GetMode  = CirrusLogic5430UgaDrawGetMode;

+  UgaDraw->SetMode  = CirrusLogic5430UgaDrawSetMode;

+  UgaDraw->Blt      = CirrusLogic5430UgaDrawBlt;

+

+  //

+  // Initialize the private data

+  //

+  Private->MaxMode      = CIRRUS_LOGIC_5430_MODE_COUNT;

+  Private->CurrentMode  = 0;

+  for (Index = 0; Index < Private->MaxMode; Index++) {

+    Private->ModeData[Index].HorizontalResolution = CirrusLogic5430VideoModes[Index].Width;

+    Private->ModeData[Index].VerticalResolution   = CirrusLogic5430VideoModes[Index].Height;

+    Private->ModeData[Index].ColorDepth           = 32;

+    Private->ModeData[Index].RefreshRate          = CirrusLogic5430VideoModes[Index].RefreshRate;

+  }

+

+  Private->HardwareNeedsStarting  = TRUE;

+  Private->LineBuffer             = NULL;

+

+  //

+  // Initialize the hardware

+  //

+  UgaDraw->SetMode (

+            UgaDraw,

+            Private->ModeData[Private->CurrentMode].HorizontalResolution,

+            Private->ModeData[Private->CurrentMode].VerticalResolution,

+            Private->ModeData[Private->CurrentMode].ColorDepth,

+            Private->ModeData[Private->CurrentMode].RefreshRate

+            );

+  DrawLogo (

+    Private,

+    Private->ModeData[Private->CurrentMode].HorizontalResolution,

+    Private->ModeData[Private->CurrentMode].VerticalResolution

+    );

+

+  return EFI_SUCCESS;

+}

+

diff --git a/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c b/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
new file mode 100644
index 0000000..8fddfc5
--- /dev/null
+++ b/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c
@@ -0,0 +1,240 @@
+/** @file

+  Copyright (c) 2006, Intel Corporation                                                         

+  All rights reserved. This program and the accompanying materials                          

+  are licensed and made available under the terms and conditions of the BSD License         

+  which accompanies this distribution.  The full text of the license may be found at        

+  http://opensource.org/licenses/bsd-license.php                                            

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

+

+**/

+

+#include "CirrusLogic5430.h"

+

+//

+// EFI Component Name Protocol

+//

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gCirrusLogic5430ComponentName = {

+  CirrusLogic5430ComponentNameGetDriverName,

+  CirrusLogic5430ComponentNameGetControllerName,

+  "eng"

+};

+

+//

+// EFI Component Name 2 Protocol

+//

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gCirrusLogic5430ComponentName2 = {

+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) CirrusLogic5430ComponentNameGetDriverName,

+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) CirrusLogic5430ComponentNameGetControllerName,

+  "en"

+};

+

+

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mCirrusLogic5430DriverNameTable[] = {

+  { "eng;en", L"Cirrus Logic 5430 Driver" },

+  { NULL , NULL }

+};

+

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mCirrusLogic5430ControllerNameTable[] = {

+  { "eng;en", L"Cirrus Logic 5430 PCI Adapter" },

+  { NULL , NULL }

+};

+

+/**

+  Retrieves a Unicode string that is the user readable name of the driver.

+

+  This function retrieves the user readable name of a driver in the form of a

+  Unicode string. If the driver specified by This has a user readable name in

+  the language specified by Language, then a pointer to the driver name is

+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified

+  by This does not support the language specified by Language,

+  then EFI_UNSUPPORTED is returned.

+

+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+

+  @param  Language[in]          A pointer to a Null-terminated ASCII string

+                                array indicating the language. This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified

+                                in RFC 3066 or ISO 639-2 language code format.

+

+  @param  DriverName[out]       A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                driver specified by This in the language

+                                specified by Language.

+

+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by

+                                This and the language specified by Language was

+                                returned in DriverName.

+

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+

+  @retval EFI_INVALID_PARAMETER DriverName is NULL.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ComponentNameGetDriverName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,

+  IN  CHAR8                        *Language,

+  OUT CHAR16                       **DriverName

+  )

+{

+  return LookupUnicodeString2 (

+           Language,

+           This->SupportedLanguages,

+           mCirrusLogic5430DriverNameTable,

+           DriverName,

+           (BOOLEAN)(This == &gCirrusLogic5430ComponentName)

+           );

+}

+

+/**

+  Retrieves a Unicode string that is the user readable name of the controller

+  that is being managed by a driver.

+

+  This function retrieves the user readable name of the controller specified by

+  ControllerHandle and ChildHandle in the form of a Unicode string. If the

+  driver specified by This has a user readable name in the language specified by

+  Language, then a pointer to the controller name is returned in ControllerName,

+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently

+  managing the controller specified by ControllerHandle and ChildHandle,

+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not

+  support the language specified by Language, then EFI_UNSUPPORTED is returned.

+

+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or

+                                EFI_COMPONENT_NAME_PROTOCOL instance.

+

+  @param  ControllerHandle[in]  The handle of a controller that the driver

+                                specified by This is managing.  This handle

+                                specifies the controller whose name is to be

+                                returned.

+

+  @param  ChildHandle[in]       The handle of the child controller to retrieve

+                                the name of.  This is an optional parameter that

+                                may be NULL.  It will be NULL for device

+                                drivers.  It will also be NULL for a bus drivers

+                                that wish to retrieve the name of the bus

+                                controller.  It will not be NULL for a bus

+                                driver that wishes to retrieve the name of a

+                                child controller.

+

+  @param  Language[in]          A pointer to a Null-terminated ASCII string

+                                array indicating the language.  This is the

+                                language of the driver name that the caller is

+                                requesting, and it must match one of the

+                                languages specified in SupportedLanguages. The

+                                number of languages supported by a driver is up

+                                to the driver writer. Language is specified in

+                                RFC 3066 or ISO 639-2 language code format.

+

+  @param  ControllerName[out]   A pointer to the Unicode string to return.

+                                This Unicode string is the name of the

+                                controller specified by ControllerHandle and

+                                ChildHandle in the language specified by

+                                Language from the point of view of the driver

+                                specified by This.

+

+  @retval EFI_SUCCESS           The Unicode string for the user readable name in

+                                the language specified by Language for the

+                                driver specified by This was returned in

+                                DriverName.

+

+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.

+

+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid

+                                EFI_HANDLE.

+

+  @retval EFI_INVALID_PARAMETER Language is NULL.

+

+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently

+                                managing the controller specified by

+                                ControllerHandle and ChildHandle.

+

+  @retval EFI_UNSUPPORTED       The driver specified by This does not support

+                                the language specified by Language.

+

+**/

+EFI_STATUS

+EFIAPI

+CirrusLogic5430ComponentNameGetControllerName (

+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,

+  IN  EFI_HANDLE                                      ControllerHandle,

+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,

+  IN  CHAR8                                           *Language,

+  OUT CHAR16                                          **ControllerName

+  )

+{

+  EFI_UGA_DRAW_PROTOCOL           *UgaDraw;

+  EFI_STATUS                      Status;

+  EFI_PCI_IO_PROTOCOL             *PciIoProtocol;

+

+  //

+  // This is a device driver, so ChildHandle must be NULL.

+  //

+  if (ChildHandle != NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Check Controller's handle

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiPciIoProtocolGuid,

+                  (VOID **) &PciIoProtocol,

+                  gCirrusLogic5430DriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+          ControllerHandle,

+          &gEfiPciIoProtocolGuid,

+          gCirrusLogic5430DriverBinding.DriverBindingHandle,

+          ControllerHandle

+          );

+

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Status != EFI_ALREADY_STARTED) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get the UGA Draw Protocol on Controller

+  //

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  &gEfiUgaDrawProtocolGuid,

+                  (VOID **) &UgaDraw,

+                  gCirrusLogic5430DriverBinding.DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Get the Cirrus Logic 5430's Device structure

+  //

+  return LookupUnicodeString2 (

+           Language,

+           This->SupportedLanguages,

+           mCirrusLogic5430ControllerNameTable,

+           ControllerName,

+           (BOOLEAN)(This == &gCirrusLogic5430ComponentName)

+           );

+}

diff --git a/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c b/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
new file mode 100644
index 0000000..77ed007
--- /dev/null
+++ b/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c
@@ -0,0 +1,20 @@
+/** @file

+  Copyright (c) 2007, Intel Corporation                                                         

+  All rights reserved. This program and the accompanying materials                          

+  are licensed and made available under the terms and conditions of the BSD License         

+  which accompanies this distribution.  The full text of the license may be found at        

+  http://opensource.org/licenses/bsd-license.php                                            

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

+

+  Module Name:  DriverSupportEfiVersion.c

+

+**/

+#include "CirrusLogic5430.h"

+

+EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gCirrusLogic5430DriverSupportedEfiVersion = {

+  sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure.

+  0                                                   // Version number to be filled at start up.

+};

+

diff --git a/OptionRomPkg/OptionRomPkg.dec b/OptionRomPkg/OptionRomPkg.dec
index b6993d7..d626d18 100644
--- a/OptionRomPkg/OptionRomPkg.dec
+++ b/OptionRomPkg/OptionRomPkg.dec
@@ -27,6 +27,8 @@
 [PcdsFeatureFlag.common]

   gOptionRomPkgTokenSpaceGuid.PcdSupportScsiPassThru|TRUE|BOOLEAN|0x00010001

   gOptionRomPkgTokenSpaceGuid.PcdSupportExtScsiPassThru|TRUE|BOOLEAN|0x00010002

+  gOptionRomPkgTokenSpaceGuid.PcdSupportGop|TRUE|BOOLEAN|0x00010004

+  gOptionRomPkgTokenSpaceGuid.PcdSupportUga|TRUE|BOOLEAN|0x00010005

 

 [PcdsFixedAtBuild.common]

   gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion|0x0002000a|UINT32|0x00010003

diff --git a/OptionRomPkg/OptionRomPkg.dsc b/OptionRomPkg/OptionRomPkg.dsc
index a65e5ce..9a19b79 100644
--- a/OptionRomPkg/OptionRomPkg.dsc
+++ b/OptionRomPkg/OptionRomPkg.dsc
@@ -90,4 +90,5 @@
 

 [Components.common]

   OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf

+  OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf

   

diff --git a/OptionRomPkg/ReadMe.txt b/OptionRomPkg/ReadMe.txt
index a6c160a..dc51fbc 100644
--- a/OptionRomPkg/ReadMe.txt
+++ b/OptionRomPkg/ReadMe.txt
@@ -1,14 +1,16 @@
-For now, AtapiPassThru driver in this package is to test Scsi Bus support:

-ScsiBus driver should support both/either ScsiPassThru and ExtScsiPassThru

-installed on a controller handle.

- 

-AtapiPassThru driver in this package can selectively produce ScsiPassThru

-and/or ExtScsiPassThru protocol based on feature flags of PcdSupportScsiPassThru

-and PcdExtScsiPassThru.

+AtapiPassThru:

+  For now, AtapiPassThru driver in this package is to test Scsi Bus support:

+  ScsiBus driver should support both/either ScsiPassThru and ExtScsiPassThru

+  installed on a controller handle.

+   

+  AtapiPassThru driver in this package can selectively produce ScsiPassThru

+  and/or ExtScsiPassThru protocol based on feature flags of PcdSupportScsiPassThru

+  and PcdExtScsiPassThru.

 

-Please note that AtapiPassThru driver has not been tuned to size optimal.

-Neither is it feature complete: several driver model protocols required

-by option ROM driver, e.g. EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL Protocol. 

+CirrusLogic5430:

+  Sample implementation of UGA Draw or Graphics Output Protocol for the Cirrus

+  Logic 5430 family of PCI video card. It provides reference code for the GOP/UGA,

+  Component Name (2), EFI driver supported Verison protocol.

 

 Build Validation:

 MYTOOLS(VS2005) IA32 X64 IPF EBC