From 5106d422953a2a40ccfe51f0a8d779d50692b36e Mon Sep 17 00:00:00 2001 From: jljusten Date: Tue, 14 Jul 2009 23:32:32 +0000 Subject: Load video option ROM which is not embedded in system firmware image. 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 | 184 ++++++++++++++++++++++ OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h | 3 +- OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf | 3 + 3 files changed, 189 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c index 7c54fc5791..27ef7b90a5 100644 --- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c +++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c @@ -32,6 +32,17 @@ InstallDevicePathCallback ( VOID ); +STATIC +VOID +LoadVideoRom ( + ); + +STATIC +EFI_STATUS +PciRomLoadEfiDriversFromRomImage ( + IN EFI_PHYSICAL_ADDRESS Rom, + IN UINTN RomSize + ); // // BDS Platform Functions @@ -58,6 +69,7 @@ Returns: { DEBUG ((EFI_D_INFO, "PlatformBdsInit\n")); InstallDevicePathCallback (); + LoadVideoRom (); } @@ -1203,3 +1215,175 @@ LockKeyboards ( { return EFI_UNSUPPORTED; } + + +STATIC +VOID +LoadVideoRom ( + ) +{ + PCI_DATA_STRUCTURE *Pcir; + UINTN RomSize; + + // + // The virtual machines sometimes load the video rom image + // directly at the legacy video BIOS location of C000:0000, + // and do not implement the PCI expansion ROM feature. + // + Pcir = (PCI_DATA_STRUCTURE *) (UINTN) 0xc0000; + RomSize = Pcir->ImageLength * 512; + PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize); +} + + +STATIC +EFI_STATUS +PciRomLoadEfiDriversFromRomImage ( + IN EFI_PHYSICAL_ADDRESS Rom, + IN UINTN RomSize + ) +{ + CHAR16 *FileName; + EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader; + PCI_DATA_STRUCTURE *Pcir; + UINTN ImageIndex; + UINTN RomOffset; + UINT32 ImageSize; + UINT16 ImageOffset; + EFI_HANDLE ImageHandle; + EFI_STATUS Status; + EFI_STATUS retStatus; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + BOOLEAN SkipImage; + UINT32 DestinationSize; + UINT32 ScratchSize; + UINT8 *Scratch; + VOID *ImageBuffer; + VOID *DecompressedImageBuffer; + UINT32 ImageLength; + EFI_DECOMPRESS_PROTOCOL *Decompress; + + FileName = L"PciRomInMemory"; + + //FileName = L"PciRom Addr=0000000000000000"; + //HexToString (&FileName[12], Rom, 16); + + ImageIndex = 0; + retStatus = EFI_NOT_FOUND; + RomOffset = (UINTN) Rom; + + do { + + EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomOffset; + + if (EfiRomHeader->Signature != 0xaa55) { + return retStatus; + } + + Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomOffset + EfiRomHeader->PcirOffset); + ImageSize = Pcir->ImageLength * 512; + + if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && + (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) { + + if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) || + (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) { + + ImageOffset = EfiRomHeader->EfiImageHeaderOffset; + ImageSize = EfiRomHeader->InitializationSize * 512; + + ImageBuffer = (VOID *) (UINTN) (RomOffset + ImageOffset); + ImageLength = ImageSize - ImageOffset; + DecompressedImageBuffer = NULL; + + // + // decompress here if needed + // + SkipImage = FALSE; + if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { + SkipImage = TRUE; + } + + if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { + Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress); + if (EFI_ERROR (Status)) { + SkipImage = TRUE; + } else { + SkipImage = TRUE; + Status = Decompress->GetInfo ( + Decompress, + ImageBuffer, + ImageLength, + &DestinationSize, + &ScratchSize + ); + if (!EFI_ERROR (Status)) { + DecompressedImageBuffer = NULL; + DecompressedImageBuffer = AllocatePool (DestinationSize); + if (DecompressedImageBuffer != NULL) { + Scratch = AllocatePool (ScratchSize); + if (Scratch != NULL) { + Status = Decompress->Decompress ( + Decompress, + ImageBuffer, + ImageLength, + DecompressedImageBuffer, + DestinationSize, + Scratch, + ScratchSize + ); + if (!EFI_ERROR (Status)) { + ImageBuffer = DecompressedImageBuffer; + ImageLength = DestinationSize; + SkipImage = FALSE; + } + + gBS->FreePool (Scratch); + } + } + } + } + } + + if (!SkipImage) { + + // + // load image and start image + // + + FilePath = FileDevicePath (NULL, FileName); + + Status = gBS->LoadImage ( + FALSE, + gImageHandle, + FilePath, + ImageBuffer, + ImageLength, + &ImageHandle + ); + if (!EFI_ERROR (Status)) { + Status = gBS->StartImage (ImageHandle, NULL, NULL); + if (!EFI_ERROR (Status)) { + retStatus = Status; + } + } + if (FilePath != NULL) { + gBS->FreePool (FilePath); + } + } + + if (DecompressedImageBuffer != NULL) { + gBS->FreePool (DecompressedImageBuffer); + } + + } + } + + RomOffset = RomOffset + ImageSize; + ImageIndex++; + } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomOffset - (UINTN) Rom) < RomSize)); + + return retStatus; +} + + diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h index dc28515878..ef433c2370 100644 --- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h +++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h @@ -29,7 +29,7 @@ Abstract: #include #include #include -//#include +#include #include #include @@ -47,6 +47,7 @@ Abstract: #include #include +#include #include #include diff --git a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf index 1534ac8fc6..4689a79183 100644 --- a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf +++ b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf @@ -55,3 +55,6 @@ [Pcd.IA32, Pcd.X64] gEfiMdePkgTokenSpaceGuid.PcdFSBClock +[Protocols] + gEfiDecompressProtocolGuid + -- cgit v1.2.3