summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2009-07-14 23:32:32 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2009-07-14 23:32:32 +0000
commit5106d422953a2a40ccfe51f0a8d779d50692b36e (patch)
tree9f69d2f4c9d99fcdc9cd91e0334adcc55fd3aaaf
parent347bbfc6ed99df8865f8281caf2b946bf52d8931 (diff)
downloadedk2-5106d422953a2a40ccfe51f0a8d779d50692b36e.zip
edk2-5106d422953a2a40ccfe51f0a8d779d50692b36e.tar.gz
edk2-5106d422953a2a40ccfe51f0a8d779d50692b36e.tar.bz2
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
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c184
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h3
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf3
3 files changed, 189 insertions, 1 deletions
diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
index 7c54fc5..27ef7b9 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 dc28515..ef433c2 100644
--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h
@@ -29,7 +29,7 @@ Abstract:
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/SmBios.h>
-//#include <IndustryStandard/LegacyBiosMpTable.h>
+#include <IndustryStandard/PeImage.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
@@ -47,6 +47,7 @@ Abstract:
#include <Library/DevicePathLib.h>
#include <Library/IoLib.h>
+#include <Protocol/Decompress.h>
#include <Protocol/PciIo.h>
#include <Protocol/FirmwareVolume2.h>
diff --git a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
index 1534ac8..4689a79 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
+