diff options
author | jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> | 2009-07-14 23:32:32 +0000 |
---|---|---|
committer | jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> | 2009-07-14 23:32:32 +0000 |
commit | 5106d422953a2a40ccfe51f0a8d779d50692b36e (patch) | |
tree | 9f69d2f4c9d99fcdc9cd91e0334adcc55fd3aaaf | |
parent | 347bbfc6ed99df8865f8281caf2b946bf52d8931 (diff) | |
download | edk2-platforms-5106d422953a2a40ccfe51f0a8d779d50692b36e.tar.xz |
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.c | 184 | ||||
-rw-r--r-- | OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h | 3 | ||||
-rw-r--r-- | OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf | 3 |
3 files changed, 189 insertions, 1 deletions
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 <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 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
+
|