]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
Updating ArmLib.h to add functions needed to turn on paging in CpuDxe. Also added...
[mirror_edk2.git] / OptionRomPkg / CirrusLogic5430Dxe / CirrusLogic5430.c
index bfa121b0191bc1bedeed721885e430e3c982d48c..789b23358df603e60f8975ac31fc54494497889a 100644 (file)
@@ -4,21 +4,21 @@
   Protocols for the Cirrus Logic 5430 family of PCI video controllers.\r
   This driver is only usable in the EFI pre-boot environment.\r
   This sample is intended to show how the UGA Draw and Graphics output Protocol\r
-  is able to function. \r
+  is able to function.\r
   The UGA I/O Protocol is not implemented in this sample.\r
   A fully compliant EFI UGA driver requires both\r
   the UGA Draw and the UGA I/O Protocol.  Please refer to Microsoft's\r
   documentation on UGA for details on how to write a UGA driver that is able\r
   to function both in the EFI pre-boot environment and from the OS runtime.\r
 \r
-  Copyright (c) 2006, Intel Corporation                                                         \r
-  All rights reserved. This program and the accompanying materials                          \r
-  are licensed and made available under the terms and conditions of the BSD License         \r
-  which accompanies this distribution.  The full text of the license may be found at        \r
-  http://opensource.org/licenses/bsd-license.php                                            \r
+  Copyright (c) 2006 - 2009, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
 \r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
 \r
@@ -40,8 +40,8 @@ EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = {
 /// Generic Attribute Controller Register Settings\r
 ///\r
 UINT8  AttributeController[21] = {\r
-  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \r
-  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, \r
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\r
+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,\r
   0x41, 0x00, 0x0F, 0x00, 0x00\r
 };\r
 \r
@@ -57,13 +57,13 @@ UINT8 GraphicsController[9] = {
 //\r
 UINT8 Crtc_640_480_256_60[28] = {\r
   0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,\r
-  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
+  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
   0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,\r
   0xff, 0x00, 0x00, 0x22\r
 };\r
 \r
 UINT16 Seq_640_480_256_60[15] = {\r
-  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, \r
+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,\r
   0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e\r
 };\r
 \r
@@ -71,14 +71,14 @@ UINT16 Seq_640_480_256_60[15] = {
 // 800 x 600 x 256 color @ 60 Hertz\r
 //\r
 UINT8 Crtc_800_600_256_60[28] = {\r
-  0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0, \r
-  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
+  0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,\r
+  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
   0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,\r
   0xFF, 0x00, 0x00, 0x22\r
 };\r
 \r
 UINT16 Seq_800_600_256_60[15] = {\r
-  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, \r
+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,\r
   0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e\r
 };\r
 \r
@@ -86,14 +86,14 @@ UINT16 Seq_800_600_256_60[15] = {
 // 1024 x 768 x 256 color @ 60 Hertz\r
 //\r
 UINT8 Crtc_1024_768_256_60[28] = {\r
-  0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, \r
-  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
+  0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,\r
+  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
   0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,\r
   0xFF, 0x4A, 0x00, 0x22\r
 };\r
 \r
 UINT16 Seq_1024_768_256_60[15] = {\r
-  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, \r
+  0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,\r
   0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e\r
 };\r
 \r
@@ -102,10 +102,11 @@ UINT16 Seq_1024_768_256_60[15] = {
 ///\r
 CIRRUS_LOGIC_5430_VIDEO_MODES  CirrusLogic5430VideoModes[] = {\r
   {  640, 480, 8, 60, Crtc_640_480_256_60,  Seq_640_480_256_60,  0xe3 },\r
-  {  800, 600, 8, 60, Crtc_800_600_256_60,  Seq_800_600_256_60,  0xef }, \r
-  { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef } \r
+  {  800, 600, 8, 60, Crtc_800_600_256_60,  Seq_800_600_256_60,  0xef },\r
+  { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }\r
 };\r
 \r
+\r
 /**\r
   CirrusLogic5430ControllerDriverSupported\r
 \r
@@ -124,6 +125,7 @@ CirrusLogic5430ControllerDriverSupported (
   EFI_STATUS          Status;\r
   EFI_PCI_IO_PROTOCOL *PciIo;\r
   PCI_TYPE00          Pci;\r
+  EFI_DEV_PATH        *Node;\r
 \r
   //\r
   // Open the PCI I/O Protocol\r
@@ -167,16 +169,33 @@ CirrusLogic5430ControllerDriverSupported (
     //\r
     // See if this is a 5430 or a 5446 PCI controller\r
     //\r
-    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID) {\r
-      Status = EFI_SUCCESS;\r
-    }\r
-\r
-    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID) {\r
-      Status = EFI_SUCCESS;\r
-    }\r
-\r
-    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {\r
+    if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID || \r
+        Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID ||\r
+        Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {\r
+        \r
       Status = EFI_SUCCESS;\r
+      //\r
+      // If this is an Intel 945 graphics controller,\r
+      // go further check RemainingDevicePath validation\r
+      //\r
+      if (RemainingDevicePath != NULL) {\r
+        Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+        //\r
+        // Check if RemainingDevicePath is the End of Device Path Node, \r
+        // if yes, return EFI_SUCCESS\r
+        //\r
+        if (!IsDevicePathEnd (Node)) {\r
+          //\r
+          // If RemainingDevicePath isn't the End of Device Path Node,\r
+          // check its validation\r
+          //\r
+          if (Node->DevPath.Type != ACPI_DEVICE_PATH ||\r
+              Node->DevPath.SubType != ACPI_ADR_DP ||\r
+              DevicePathNodeLength(&Node->DevPath) != sizeof(ACPI_ADR_DEVICE_PATH)) {\r
+            Status = EFI_UNSUPPORTED;\r
+          }\r
+        }\r
+      }\r
     }\r
   }\r
 \r
@@ -211,7 +230,11 @@ CirrusLogic5430ControllerDriverStart (
 {\r
   EFI_STATUS                      Status;\r
   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;\r
+  BOOLEAN                         PciAttributesSaved;\r
+  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;\r
+  ACPI_ADR_DEVICE_PATH            AcpiDeviceNode;\r
 \r
+  PciAttributesSaved = FALSE;\r
   //\r
   // Allocate Private context data for UGA Draw inteface.\r
   //\r
@@ -225,23 +248,38 @@ CirrusLogic5430ControllerDriverStart (
   // Set up context record\r
   //\r
   Private->Signature  = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE;\r
-  Private->Handle     = Controller;\r
+  Private->Handle     = NULL;\r
 \r
   //\r
   // Open PCI I/O Protocol\r
   //\r
   Status = gBS->OpenProtocol (\r
-                  Private->Handle,\r
+                  Controller,\r
                   &gEfiPciIoProtocolGuid,\r
                   (VOID **) &Private->PciIo,\r
                   This->DriverBindingHandle,\r
-                  Private->Handle,\r
+                  Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     goto Error;\r
   }\r
 \r
+  //\r
+  // Save original PCI attributes\r
+  //\r
+  Status = Private->PciIo->Attributes (\r
+                    Private->PciIo,\r
+                    EfiPciIoAttributeOperationGet,\r
+                    0,\r
+                    &Private->OriginalPciAttributes\r
+                    );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+  PciAttributesSaved = TRUE;\r
+\r
   Status = Private->PciIo->Attributes (\r
                             Private->PciIo,\r
                             EfiPciIoAttributeOperationEnable,\r
@@ -252,78 +290,147 @@ CirrusLogic5430ControllerDriverStart (
     goto Error;\r
   }\r
 \r
-  if (FeaturePcdGet (PcdSupportUga)) {\r
+  //\r
+  // Get ParentDevicePath\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  if (FeaturePcdGet (PcdSupportGop)) {\r
     //\r
-    // Start the UGA Draw software stack.\r
+    // Set Gop Device Path\r
     //\r
-    Status = CirrusLogic5430UgaDrawConstructor (Private);\r
-    ASSERT_EFI_ERROR (Status);\r
-    if (FeaturePcdGet (PcdSupportGop)) {\r
-      Status = CirrusLogic5430GraphicsOutputConstructor (Private);\r
-      ASSERT_EFI_ERROR (Status);\r
-\r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      &Private->Handle,\r
-                      &gEfiUgaDrawProtocolGuid,\r
-                      &Private->UgaDraw,\r
-                      &gEfiGraphicsOutputProtocolGuid,\r
-                      &Private->GraphicsOutput,\r
-                      NULL\r
-                      );\r
+    if (RemainingDevicePath == NULL) {\r
+      ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));\r
+      AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;\r
+      AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;\r
+      AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);\r
+      SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
+\r
+      Private->GopDevicePath = AppendDevicePathNode (\r
+                                          ParentDevicePath,\r
+                                          (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
+                                          );\r
+    } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
+      //\r
+      // If RemainingDevicePath isn't the End of Device Path Node, \r
+      // only scan the specified device by RemainingDevicePath\r
+      //\r
+      Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);\r
     } else {\r
+      //\r
+      // If RemainingDevicePath is the End of Device Path Node, \r
+      // don't create child device and return EFI_SUCCESS\r
+      //\r
+      Private->GopDevicePath = NULL;\r
+    }\r
+      \r
+    if (Private->GopDevicePath != NULL) {\r
+      //\r
+      // Creat child handle and device path protocol firstly\r
+      //\r
+      Private->Handle = NULL;\r
       Status = gBS->InstallMultipleProtocolInterfaces (\r
                       &Private->Handle,\r
-                      &gEfiUgaDrawProtocolGuid,\r
-                      &Private->UgaDraw,\r
+                      &gEfiDevicePathProtocolGuid,\r
+                      Private->GopDevicePath,\r
                       NULL\r
                       );\r
-\r
     }\r
-  } else {\r
-    if (FeaturePcdGet (PcdSupportGop)) {\r
+  }\r
+\r
+  //\r
+  // Construct video mode buffer\r
+  //\r
+  Status = CirrusLogic5430VideoModeSetup (Private);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  if (FeaturePcdGet (PcdSupportUga)) {\r
+    //\r
+    // Start the UGA Draw software stack.\r
+    //\r
+    Status = CirrusLogic5430UgaDrawConstructor (Private);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Private->UgaDevicePath = ParentDevicePath;\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &Controller,\r
+                    &gEfiUgaDrawProtocolGuid,\r
+                    &Private->UgaDraw,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    Private->UgaDevicePath,\r
+                    NULL\r
+                    );\r
+\r
+  } else if (FeaturePcdGet (PcdSupportGop)) {\r
+    if (Private->GopDevicePath == NULL) {\r
+      //\r
+      // If RemainingDevicePath is the End of Device Path Node, \r
+      // don't create child device and return EFI_SUCCESS\r
+      //\r
+      Status = EFI_SUCCESS;\r
+    } else {\r
+  \r
+      //\r
+      // Start the GOP software stack.\r
+      //\r
       Status = CirrusLogic5430GraphicsOutputConstructor (Private);\r
       ASSERT_EFI_ERROR (Status);\r
-\r
+  \r
       Status = gBS->InstallMultipleProtocolInterfaces (\r
                       &Private->Handle,\r
                       &gEfiGraphicsOutputProtocolGuid,\r
                       &Private->GraphicsOutput,\r
+                      &gEfiEdidDiscoveredProtocolGuid,\r
+                      &Private->EdidDiscovered,\r
+                      &gEfiEdidActiveProtocolGuid,\r
+                      &Private->EdidActive,\r
                       NULL\r
                       );\r
-      \r
-    } else {\r
-      //\r
-      // This driver must support eithor GOP or UGA or both.\r
-      // \r
-      ASSERT (FALSE);\r
-      Status = EFI_UNSUPPORTED;\r
     }\r
+  } else {\r
+    //\r
+    // This driver must support eithor GOP or UGA or both.\r
+    //\r
+    ASSERT (FALSE);\r
+    Status = EFI_UNSUPPORTED;\r
   }\r
-  \r
+\r
 \r
 Error:\r
   if (EFI_ERROR (Status)) {\r
     if (Private) {\r
       if (Private->PciIo) {\r
-        Private->PciIo->Attributes (\r
+        if (PciAttributesSaved == TRUE) {\r
+          //\r
+          // Restore original PCI attributes\r
+          //\r
+          Private->PciIo->Attributes (\r
                           Private->PciIo,\r
-                          EfiPciIoAttributeOperationDisable,\r
-                          EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r
+                          EfiPciIoAttributeOperationSet,\r
+                          Private->OriginalPciAttributes,\r
                           NULL\r
                           );\r
+        }\r
+        //\r
+        // Close the PCI I/O Protocol\r
+        //\r
+        gBS->CloseProtocol (\r
+              Private->Handle,\r
+              &gEfiPciIoProtocolGuid,\r
+              This->DriverBindingHandle,\r
+              Private->Handle\r
+              );\r
       }\r
-    }\r
 \r
-    //\r
-    // Close the PCI I/O Protocol\r
-    //\r
-    gBS->CloseProtocol (\r
-          Private->Handle,\r
-          &gEfiPciIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Private->Handle\r
-          );\r
-    if (Private) {\r
       gBS->FreePool (Private);\r
     }\r
   }\r
@@ -433,16 +540,15 @@ CirrusLogic5430ControllerDriverStop (
     return Status;\r
   }\r
 \r
-\r
   //\r
-  // Shutdown the hardware\r
+  // Restore original PCI attributes\r
   //\r
   Private->PciIo->Attributes (\r
-                    Private->PciIo,\r
-                    EfiPciIoAttributeOperationDisable,\r
-                    EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r
-                    NULL\r
-                    );\r
+                  Private->PciIo,\r
+                  EfiPciIoAttributeOperationSet,\r
+                  Private->OriginalPciAttributes,\r
+                  NULL\r
+                  );\r
 \r
   //\r
   // Close the PCI I/O Protocol\r
@@ -650,7 +756,6 @@ SetDefaultPalette (
   TODO: add return values\r
 \r
 **/\r
-STATIC\r
 VOID\r
 ClearScreen (\r
   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private\r
@@ -684,27 +789,6 @@ DrawLogo (
   UINTN                           ScreenHeight\r
   )\r
 {\r
-  UINTN Offset;\r
-  UINTN X;\r
-  UINTN Y;\r
-  UINT8 Color;\r
-\r
-  Offset        = 0;\r
-  for (Y = 0; Y < ScreenHeight; Y++) {\r
-    for (X = 0; X < ScreenWidth; X++) {\r
-      Color                   = (UINT8) (256 * (X + Y) / (ScreenWidth + ScreenHeight));\r
-      Private->LineBuffer[X]  = Color;\r
-    }\r
-\r
-    Private->PciIo->Mem.Write (\r
-                          Private->PciIo,\r
-                          EfiPciIoWidthUint32,\r
-                          0,\r
-                          Offset + (Y * ScreenWidth),\r
-                          ScreenWidth >> 2,\r
-                          Private->LineBuffer\r
-                          );\r
-  }\r
 }\r
 \r
 /**\r
@@ -724,6 +808,20 @@ InitializeGraphicsMode (
 {\r
   UINT8 Byte;\r
   UINTN Index;\r
+  UINT16 DeviceId;\r
+  EFI_STATUS Status;\r
+\r
+  Status = Private->PciIo->Pci.Read (\r
+             Private->PciIo,\r
+             EfiPciIoWidthUint16,\r
+             PCI_DEVICE_ID_OFFSET,\r
+             1,\r
+             &DeviceId\r
+             );\r
+  //\r
+  // Read the PCI Configuration Header from the PCI Device\r
+  //\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);\r
   outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);\r
@@ -732,9 +830,11 @@ InitializeGraphicsMode (
     outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);\r
   }\r
 \r
-  outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);\r
-  Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);\r
-  outb (Private, SEQ_DATA_REGISTER, Byte);\r
+  if (DeviceId != CIRRUS_LOGIC_5446_DEVICE_ID) {\r
+    outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);\r
+    Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);\r
+    outb (Private, SEQ_DATA_REGISTER, Byte);\r
+  }\r
 \r
   outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);\r
   outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);\r
@@ -787,7 +887,7 @@ InitializeCirrusLogic5430 (
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
-  // Install EFI Driver Supported EFI Version Protocol required for \r
+  // Install EFI Driver Supported EFI Version Protocol required for\r
   // EFI drivers that are on PCI and other plug in cards.\r
   //\r
   gCirrusLogic5430DriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);\r