]> git.proxmox.com Git - mirror_edk2.git/commitdiff
QemuVideo: prepare to support more hardware
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 27 Nov 2012 19:11:11 +0000 (19:11 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 27 Nov 2012 19:11:11 +0000 (19:11 +0000)
Move to a table-driven hardware detection.  Add a table with PCI IDs,
card name and variant enum.  Use the table for hardware detection and
initialization.  Rename Cirrus-specific data and code to carry "cirrus"
in the name.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13967 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/QemuVideoDxe/Driver.c
OvmfPkg/QemuVideoDxe/Gop.c
OvmfPkg/QemuVideoDxe/Initialize.c
OvmfPkg/QemuVideoDxe/Qemu.h
OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf

index cb3e34970dc0e1efe7f9d449230d150a1758ed8e..51929803b582e007727729497b57870c716c4e59 100644 (file)
@@ -25,6 +25,45 @@ EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {
   NULL\r
 };\r
 \r
+QEMU_VIDEO_CARD gQemuVideoCardList[] = {\r
+    {\r
+        CIRRUS_LOGIC_VENDOR_ID,\r
+        CIRRUS_LOGIC_5430_DEVICE_ID,\r
+        QEMU_VIDEO_CIRRUS_5430,\r
+        L"Cirrus 5430"\r
+    },{\r
+        CIRRUS_LOGIC_VENDOR_ID,\r
+        CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID,\r
+        QEMU_VIDEO_CIRRUS_5430,\r
+        L"Cirrus 5430"\r
+    },{\r
+        CIRRUS_LOGIC_VENDOR_ID,\r
+        CIRRUS_LOGIC_5446_DEVICE_ID,\r
+        QEMU_VIDEO_CIRRUS_5446,\r
+        L"Cirrus 5446"\r
+    },{\r
+        0 /* end of list */\r
+    }\r
+};\r
+\r
+static QEMU_VIDEO_CARD*\r
+QemuVideoDetect(\r
+  IN UINT16 VendorId,\r
+  IN UINT16 DeviceId\r
+  )\r
+{\r
+  UINTN Index = 0;\r
+\r
+  while (gQemuVideoCardList[Index].VendorId != 0) {\r
+    if (gQemuVideoCardList[Index].VendorId == VendorId &&\r
+        gQemuVideoCardList[Index].DeviceId == DeviceId) {\r
+      return gQemuVideoCardList + Index;\r
+    }\r
+    Index++;\r
+  }\r
+  return NULL;\r
+}\r
+\r
 /**\r
   Check if this device is supported.\r
 \r
@@ -48,6 +87,7 @@ QemuVideoControllerDriverSupported (
   EFI_PCI_IO_PROTOCOL *PciIo;\r
   PCI_TYPE00          Pci;\r
   EFI_DEV_PATH        *Node;\r
+  QEMU_VIDEO_CARD     *Card;\r
 \r
   //\r
   // Open the PCI I/O Protocol\r
@@ -87,35 +127,29 @@ QemuVideoControllerDriverSupported (
   //\r
   // See if this is a Cirrus Logic PCI controller\r
   //\r
-  if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) {\r
+  Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
+  if (Card != NULL) {\r
+    DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name));\r
+    Status = EFI_SUCCESS;\r
     //\r
-    // See if this is a 5430 or a 5446 PCI controller\r
+    // If this is an Intel 945 graphics controller,\r
+    // go further check RemainingDevicePath validation\r
     //\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
+    if (RemainingDevicePath != NULL) {\r
+      Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
       //\r
-      // If this is an Intel 945 graphics controller,\r
-      // go further check RemainingDevicePath validation\r
+      // Check if RemainingDevicePath is the End of Device Path Node, \r
+      // if yes, return EFI_SUCCESS\r
       //\r
-      if (RemainingDevicePath != NULL) {\r
-        Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+      if (!IsDevicePathEnd (Node)) {\r
         //\r
-        // Check if RemainingDevicePath is the End of Device Path Node, \r
-        // if yes, return EFI_SUCCESS\r
+        // If RemainingDevicePath isn't the End of Device Path Node,\r
+        // check its validation\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
+        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
@@ -161,7 +195,9 @@ QemuVideoControllerDriverStart (
   BOOLEAN                         PciAttributesSaved;\r
   EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;\r
   ACPI_ADR_DEVICE_PATH            AcpiDeviceNode;\r
-\r
+  PCI_TYPE00                      Pci;\r
+  QEMU_VIDEO_CARD                 *Card;\r
+  \r
   PciAttributesSaved = FALSE;\r
   //\r
   // Allocate Private context data for GOP inteface.\r
@@ -193,6 +229,27 @@ QemuVideoControllerDriverStart (
     goto Error;\r
   }\r
 \r
+  //\r
+  // Read the PCI Configuration Header from the PCI Device\r
+  //\r
+  Status = Private->PciIo->Pci.Read (\r
+                        Private->PciIo,\r
+                        EfiPciIoWidthUint32,\r
+                        0,\r
+                        sizeof (Pci) / sizeof (UINT32),\r
+                        &Pci\r
+                        );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
+  if (Card == NULL) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Error;\r
+  }\r
+  Private->Variant = Card->Variant;\r
+\r
   //\r
   // Save original PCI attributes\r
   //\r
@@ -274,7 +331,16 @@ QemuVideoControllerDriverStart (
   //\r
   // Construct video mode buffer\r
   //\r
-  Status = QemuVideoVideoModeSetup (Private);\r
+  switch (Private->Variant) {\r
+  case QEMU_VIDEO_CIRRUS_5430:\r
+  case QEMU_VIDEO_CIRRUS_5446:\r
+    Status = QemuVideoCirrusModeSetup (Private);\r
+    break;\r
+  default:\r
+    ASSERT (FALSE);\r
+    Status = EFI_DEVICE_ERROR;\r
+    break;\r
+  }\r
   if (EFI_ERROR (Status)) {\r
     goto Error;\r
   }\r
@@ -640,27 +706,13 @@ DrawLogo (
 \r
 **/\r
 VOID\r
-InitializeGraphicsMode (\r
+InitializeCirrusGraphicsMode (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private,\r
-  QEMU_VIDEO_VIDEO_MODES   *ModeData\r
+  QEMU_VIDEO_CIRRUS_MODES  *ModeData\r
   )\r
 {\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
@@ -669,7 +721,7 @@ InitializeGraphicsMode (
     outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);\r
   }\r
 \r
-  if (DeviceId != CIRRUS_LOGIC_5446_DEVICE_ID) {\r
+  if (Private->Variant == QEMU_VIDEO_CIRRUS_5430) {\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
index d364630c47609407a1062d84a35557bea4570474..bd49ee91391fb6e995465b8868a5eb258e9c5ff8 100644 (file)
@@ -181,7 +181,17 @@ Routine Description:
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  InitializeGraphicsMode (Private, &QemuVideoVideoModes[ModeData->ModeNumber]);\r
+  switch (Private->Variant) {\r
+  case QEMU_VIDEO_CIRRUS_5430:\r
+  case QEMU_VIDEO_CIRRUS_5446:\r
+    InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->ModeNumber]);\r
+    break;\r
+  default:\r
+    ASSERT (FALSE);\r
+    gBS->FreePool (Private->LineBuffer);\r
+    Private->LineBuffer = NULL;\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
   This->Mode->Mode = ModeNumber;\r
   This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
index 2491733df9762c6220d75c5b3bdf2f00b6c48719..a369e229883b1ebb446c1af3f7124a63192ed10d 100644 (file)
@@ -143,7 +143,7 @@ UINT16 Seq_1024_768_32bpp_60[15] = {
 ///\r
 /// Table of supported video modes\r
 ///\r
-QEMU_VIDEO_VIDEO_MODES  QemuVideoVideoModes[] = {\r
+QEMU_VIDEO_CIRRUS_MODES  QemuVideoCirrusModes[] = {\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
   {  640, 480, 32, 60, Crtc_640_480_32bpp_60,  Seq_640_480_32bpp_60,  0xef },\r
@@ -154,38 +154,38 @@ QEMU_VIDEO_VIDEO_MODES  QemuVideoVideoModes[] = {
 //  { 960, 720, 32, 60, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }\r
 };\r
 \r
-#define QEMU_VIDEO_MODE_COUNT \\r
-  (sizeof (QemuVideoVideoModes) / sizeof (QemuVideoVideoModes[0]))\r
+#define QEMU_VIDEO_CIRRUS_MODE_COUNT \\r
+  (sizeof (QemuVideoCirrusModes) / sizeof (QemuVideoCirrusModes[0]))\r
 \r
 /**\r
   Construct the valid video modes for QemuVideo.\r
 \r
 **/\r
 EFI_STATUS\r
-QemuVideoVideoModeSetup (\r
+QemuVideoCirrusModeSetup (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private\r
   )\r
 {\r
   UINT32                                 Index;\r
   QEMU_VIDEO_MODE_DATA                   *ModeData;\r
-  QEMU_VIDEO_VIDEO_MODES                 *VideoMode;\r
+  QEMU_VIDEO_CIRRUS_MODES                *VideoMode;\r
 \r
   //\r
   // Setup Video Modes\r
   //\r
   Private->ModeData = AllocatePool (\r
-                        sizeof (Private->ModeData[0]) * QEMU_VIDEO_MODE_COUNT\r
+                        sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT\r
                         );\r
   ModeData = Private->ModeData;\r
-  VideoMode = &QemuVideoVideoModes[0];\r
-  for (Index = 0; Index < QEMU_VIDEO_MODE_COUNT; Index ++) {\r
+  VideoMode = &QemuVideoCirrusModes[0];\r
+  for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) {\r
     ModeData->ModeNumber = Index;\r
     ModeData->HorizontalResolution          = VideoMode->Width;\r
     ModeData->VerticalResolution            = VideoMode->Height;\r
     ModeData->ColorDepth                    = VideoMode->ColorDepth;\r
     ModeData->RefreshRate                   = VideoMode->RefreshRate;\r
     DEBUG ((EFI_D_INFO,\r
-      "Adding Video Mode %d: %dx%d, %d-bit, %d Hz\n",\r
+      "Adding Cirrus Video Mode %d: %dx%d, %d-bit, %d Hz\n",\r
       ModeData->ModeNumber,\r
       ModeData->HorizontalResolution,\r
       ModeData->VerticalResolution,\r
@@ -196,7 +196,7 @@ QemuVideoVideoModeSetup (
     ModeData ++ ;\r
     VideoMode ++;\r
   }\r
-  Private->MaxMode = QEMU_VIDEO_MODE_COUNT;\r
+  Private->MaxMode = QEMU_VIDEO_CIRRUS_MODE_COUNT;\r
 \r
   return EFI_SUCCESS;\r
 }\r
index 1c24a58bd527d8411df339198550c6bd631f69b3..f294901fa6a14c6140d05241989f3b29c849aa4b 100644 (file)
@@ -86,6 +86,18 @@ typedef struct {
 //\r
 #define QEMU_VIDEO_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('Q', 'V', 'I', 'D')\r
 \r
+typedef enum {\r
+  QEMU_VIDEO_CIRRUS_5430 = 1,\r
+  QEMU_VIDEO_CIRRUS_5446,\r
+} QEMU_VIDEO_VARIANT;\r
+\r
+typedef struct {\r
+  UINT16                                VendorId;\r
+  UINT16                                DeviceId;\r
+  QEMU_VIDEO_VARIANT                    Variant;\r
+  CHAR16                                *Name;\r
+} QEMU_VIDEO_CARD;\r
+\r
 typedef struct {\r
   UINT64                                Signature;\r
   EFI_HANDLE                            Handle;\r
@@ -98,6 +110,7 @@ typedef struct {
   QEMU_VIDEO_MODE_DATA                  *ModeData;\r
   UINT8                                 *LineBuffer;\r
   BOOLEAN                               HardwareNeedsStarting;\r
+  QEMU_VIDEO_VARIANT                    Variant;\r
 } QEMU_VIDEO_PRIVATE_DATA;\r
 \r
 ///\r
@@ -111,7 +124,7 @@ typedef struct {
   UINT8   *CrtcSettings;\r
   UINT16  *SeqSettings;\r
   UINT8   MiscSetting;\r
-} QEMU_VIDEO_VIDEO_MODES;\r
+} QEMU_VIDEO_CIRRUS_MODES;\r
 \r
 #define QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \\r
   CR(a, QEMU_VIDEO_PRIVATE_DATA, GraphicsOutput, QEMU_VIDEO_PRIVATE_DATA_SIGNATURE)\r
@@ -128,7 +141,7 @@ extern UINT8                                      Crtc_800_600_256_60[];
 extern UINT16                                     Seq_800_600_256_60[];\r
 extern UINT8                                      Crtc_1024_768_256_60[];\r
 extern UINT16                                     Seq_1024_768_256_60[];\r
-extern QEMU_VIDEO_VIDEO_MODES              QemuVideoVideoModes[];\r
+extern QEMU_VIDEO_CIRRUS_MODES                    QemuVideoCirrusModes[];\r
 extern EFI_DRIVER_BINDING_PROTOCOL                gQemuVideoDriverBinding;\r
 extern EFI_COMPONENT_NAME_PROTOCOL                gQemuVideoComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL               gQemuVideoComponentName2;\r
@@ -358,9 +371,9 @@ QemuVideoComponentNameGetControllerName (
 // Local Function Prototypes\r
 //\r
 VOID\r
-InitializeGraphicsMode (\r
+InitializeCirrusGraphicsMode (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private,\r
-  QEMU_VIDEO_VIDEO_MODES   *ModeData\r
+  QEMU_VIDEO_CIRRUS_MODES  *ModeData\r
   );\r
 \r
 VOID\r
@@ -411,7 +424,7 @@ inw (
   );\r
 \r
 EFI_STATUS\r
-QemuVideoVideoModeSetup (\r
+QemuVideoCirrusModeSetup (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private\r
   );\r
 \r
index fde743b048c8fa19c05c5727073b36f9ed2e8ed7..30284fcce0f12f9263644c54af4a13a5dc5bb5b3 100644 (file)
 \r
   ENTRY_POINT                    = InitializeQemuVideo\r
 \r
-  PCI_VENDOR_ID  = 0x1013\r
-  PCI_DEVICE_ID  = 0x00A8\r
-  PCI_CLASS_CODE = 0x030000\r
-  PCI_REVISION   = 0x00\r
-  PCI_COMPRESS   = TRUE\r
-\r
 #\r
 # The following information is for reference only and not required by the build tools.\r
 #\r