]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Load video option ROM which is not embedded in system firmware image.
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 14 Jul 2009 23:32:32 +0000 (23:32 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 14 Jul 2009 23:32:32 +0000 (23:32 +0000)
QEMU will automatically fill the video BIOS image into memory at the
legacy video BIOS memory location (0xc0000).  This code will look
there for a EFI option rom image, and load it if it found.  This
allows the video option ROM to be separated out from the main system
firmware image.

QEMU does not appear to emulate the PCI rom expansion method
for making the video BIOS available to the system.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8942 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h
OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf

index 7c54fc5791cbc7e757e95f9cc2cf7ba8a33b6a1d..27ef7b90a5afedc7d0fc35ce41735d13b3f36375 100644 (file)
@@ -32,6 +32,17 @@ InstallDevicePathCallback (
   VOID\r
   );\r
 \r
+STATIC\r
+VOID\r
+LoadVideoRom (\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS\r
+PciRomLoadEfiDriversFromRomImage (\r
+  IN EFI_PHYSICAL_ADDRESS    Rom,\r
+  IN UINTN                   RomSize\r
+  );\r
 \r
 //\r
 // BDS Platform Functions\r
@@ -58,6 +69,7 @@ Returns:
 {\r
   DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));\r
   InstallDevicePathCallback ();\r
+  LoadVideoRom ();\r
 }\r
 \r
 \r
@@ -1203,3 +1215,175 @@ LockKeyboards (
 {\r
     return EFI_UNSUPPORTED;\r
 }\r
+\r
+\r
+STATIC\r
+VOID\r
+LoadVideoRom (\r
+  )\r
+{\r
+  PCI_DATA_STRUCTURE            *Pcir;\r
+  UINTN                         RomSize;\r
+\r
+  //\r
+  // The virtual machines sometimes load the video rom image\r
+  // directly at the legacy video BIOS location of C000:0000,\r
+  // and do not implement the PCI expansion ROM feature.\r
+  //\r
+  Pcir = (PCI_DATA_STRUCTURE *) (UINTN) 0xc0000;\r
+  RomSize = Pcir->ImageLength * 512;\r
+  PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize);\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+PciRomLoadEfiDriversFromRomImage (\r
+  IN EFI_PHYSICAL_ADDRESS    Rom,\r
+  IN UINTN                   RomSize\r
+  )\r
+{\r
+  CHAR16                        *FileName;\r
+  EFI_PCI_EXPANSION_ROM_HEADER  *EfiRomHeader;\r
+  PCI_DATA_STRUCTURE            *Pcir;\r
+  UINTN                         ImageIndex;\r
+  UINTN                         RomOffset;\r
+  UINT32                        ImageSize;\r
+  UINT16                        ImageOffset;\r
+  EFI_HANDLE                    ImageHandle;\r
+  EFI_STATUS                    Status;\r
+  EFI_STATUS                    retStatus;\r
+  EFI_DEVICE_PATH_PROTOCOL      *FilePath;\r
+  BOOLEAN                       SkipImage;\r
+  UINT32                        DestinationSize;\r
+  UINT32                        ScratchSize;\r
+  UINT8                         *Scratch;\r
+  VOID                          *ImageBuffer;\r
+  VOID                          *DecompressedImageBuffer;\r
+  UINT32                        ImageLength;\r
+  EFI_DECOMPRESS_PROTOCOL       *Decompress;\r
+\r
+  FileName = L"PciRomInMemory";\r
+\r
+  //FileName = L"PciRom Addr=0000000000000000";\r
+  //HexToString (&FileName[12], Rom, 16);\r
+\r
+  ImageIndex    = 0;\r
+  retStatus     = EFI_NOT_FOUND;\r
+  RomOffset  = (UINTN) Rom;\r
+\r
+  do {\r
+\r
+    EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomOffset;\r
+\r
+    if (EfiRomHeader->Signature != 0xaa55) {\r
+      return retStatus;\r
+    }\r
+\r
+    Pcir      = (PCI_DATA_STRUCTURE *) (UINTN) (RomOffset + EfiRomHeader->PcirOffset);\r
+    ImageSize = Pcir->ImageLength * 512;\r
+\r
+    if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
+        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {\r
+\r
+      if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
+          (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {\r
+\r
+        ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;\r
+        ImageSize               = EfiRomHeader->InitializationSize * 512;\r
+\r
+        ImageBuffer             = (VOID *) (UINTN) (RomOffset + ImageOffset);\r
+        ImageLength             = ImageSize - ImageOffset;\r
+        DecompressedImageBuffer = NULL;\r
+\r
+        //\r
+        // decompress here if needed\r
+        //\r
+        SkipImage = FALSE;\r
+        if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+          SkipImage = TRUE;\r
+        }\r
+\r
+        if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+          Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
+          if (EFI_ERROR (Status)) {\r
+            SkipImage = TRUE;\r
+          } else {\r
+            SkipImage = TRUE;\r
+            Status = Decompress->GetInfo (\r
+                                  Decompress,\r
+                                  ImageBuffer,\r
+                                  ImageLength,\r
+                                  &DestinationSize,\r
+                                  &ScratchSize\r
+                                  );\r
+            if (!EFI_ERROR (Status)) {\r
+              DecompressedImageBuffer = NULL;\r
+              DecompressedImageBuffer = AllocatePool (DestinationSize);\r
+              if (DecompressedImageBuffer != NULL) {\r
+                Scratch = AllocatePool (ScratchSize);\r
+                if (Scratch != NULL) {\r
+                  Status = Decompress->Decompress (\r
+                                        Decompress,\r
+                                        ImageBuffer,\r
+                                        ImageLength,\r
+                                        DecompressedImageBuffer,\r
+                                        DestinationSize,\r
+                                        Scratch,\r
+                                        ScratchSize\r
+                                        );\r
+                  if (!EFI_ERROR (Status)) {\r
+                    ImageBuffer = DecompressedImageBuffer;\r
+                    ImageLength = DestinationSize;\r
+                    SkipImage   = FALSE;\r
+                  }\r
+\r
+                  gBS->FreePool (Scratch);\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+\r
+        if (!SkipImage) {\r
+\r
+          //\r
+          // load image and start image\r
+          //\r
+\r
+          FilePath = FileDevicePath (NULL, FileName);\r
+\r
+          Status = gBS->LoadImage (\r
+                          FALSE,\r
+                          gImageHandle,\r
+                          FilePath,\r
+                          ImageBuffer,\r
+                          ImageLength,\r
+                          &ImageHandle\r
+                          );\r
+          if (!EFI_ERROR (Status)) {\r
+            Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+            if (!EFI_ERROR (Status)) {\r
+              retStatus = Status;\r
+            }\r
+          }\r
+          if (FilePath != NULL) {\r
+            gBS->FreePool (FilePath);\r
+          }\r
+        }\r
+\r
+        if (DecompressedImageBuffer != NULL) {\r
+          gBS->FreePool (DecompressedImageBuffer);\r
+        }\r
+\r
+      }\r
+    }\r
+\r
+    RomOffset = RomOffset + ImageSize;\r
+    ImageIndex++;\r
+  } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomOffset - (UINTN) Rom) < RomSize));\r
+\r
+  return retStatus;\r
+}\r
+\r
+\r
index dc2851587882a3ce76c7eeeb1e9a021308c616c6..ef433c2370662af910802e3cba7dd5d248e43a54 100644 (file)
@@ -29,7 +29,7 @@ Abstract:
 #include <IndustryStandard/Pci.h>\r
 #include <IndustryStandard/Acpi.h>\r
 #include <IndustryStandard/SmBios.h>\r
-//#include <IndustryStandard/LegacyBiosMpTable.h>\r
+#include <IndustryStandard/PeImage.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
@@ -47,6 +47,7 @@ Abstract:
 #include <Library/DevicePathLib.h>\r
 #include <Library/IoLib.h>\r
 \r
+#include <Protocol/Decompress.h>\r
 #include <Protocol/PciIo.h>\r
 #include <Protocol/FirmwareVolume2.h>\r
 \r
index 1534ac8fc60c1fdaf9b2fae2e6a2e07286fcddb2..4689a79183043d9f4ccb9f8284251e81add795f2 100644 (file)
@@ -55,3 +55,6 @@
 [Pcd.IA32, Pcd.X64]\r
   gEfiMdePkgTokenSpaceGuid.PcdFSBClock\r
 \r
+[Protocols]\r
+  gEfiDecompressProtocolGuid\r
+\r